diff --git a/public/Chart.bundle.js b/public/Chart.bundle.js
new file mode 100644
index 0000000..2e27e28
--- /dev/null
+++ b/public/Chart.bundle.js
@@ -0,0 +1,24043 @@
+/*!
+ * Chart.js v4.4.8
+ * https://www.chartjs.org
+ * (c) 2025 Chart.js Contributors
+ * Released under the MIT License
+ *
+ * @kurkle/color v0.3.2
+ * https://github.com/kurkle/color#readme
+ * (c) 2023 Jukka Kurkela
+ * Released under the MIT License
+ *
+ * chartjs-adapter-date-fns v3.0.0
+ * https://www.chartjs.org
+ * (c) 2022 chartjs-adapter-date-fns Contributors
+ * Released under the MIT license
+ *
+ * date-fns v2.30.0
+ * https://date-fns.org
+ * (c) 2021 Sasha Koss and Lesha Koss
+ * Released under the MIT License
+ */
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory());
+})(this, (function () { 'use strict';
+
+ function _arrayLikeToArray$1(r, a) {
+ (null == a || a > r.length) && (a = r.length);
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
+ return n;
+ }
+ function _arrayWithHoles(r) {
+ if (Array.isArray(r)) return r;
+ }
+ function _arrayWithoutHoles(r) {
+ if (Array.isArray(r)) return _arrayLikeToArray$1(r);
+ }
+ function _assertThisInitialized$1(e) {
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ return e;
+ }
+ function _callSuper(t, o, e) {
+ return o = _getPrototypeOf$1(o), _possibleConstructorReturn$1(t, _isNativeReflectConstruct$1() ? Reflect.construct(o, e || [], _getPrototypeOf$1(t).constructor) : o.apply(t, e));
+ }
+ function _classCallCheck$1(a, n) {
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
+ }
+ function _defineProperties$1(e, r) {
+ for (var t = 0; t < r.length; t++) {
+ var o = r[t];
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
+ }
+ }
+ function _createClass$1(e, r, t) {
+ return r && _defineProperties$1(e.prototype, r), t && _defineProperties$1(e, t), Object.defineProperty(e, "prototype", {
+ writable: !1
+ }), e;
+ }
+ function _createForOfIteratorHelper$1(r, e) {
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
+ if (!t) {
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray$1(r)) || e && r && "number" == typeof r.length) {
+ t && (r = t);
+ var n = 0,
+ F = function () {};
+ return {
+ s: F,
+ n: function () {
+ return n >= r.length ? {
+ done: !0
+ } : {
+ done: !1,
+ value: r[n++]
+ };
+ },
+ e: function (r) {
+ throw r;
+ },
+ f: F
+ };
+ }
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+ var o,
+ a = !0,
+ u = !1;
+ return {
+ s: function () {
+ t = t.call(r);
+ },
+ n: function () {
+ var r = t.next();
+ return a = r.done, r;
+ },
+ e: function (r) {
+ u = !0, o = r;
+ },
+ f: function () {
+ try {
+ a || null == t.return || t.return();
+ } finally {
+ if (u) throw o;
+ }
+ }
+ };
+ }
+ function _defineProperty$1(e, r, t) {
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
+ value: t,
+ enumerable: !0,
+ configurable: !0,
+ writable: !0
+ }) : e[r] = t, e;
+ }
+ function _get() {
+ return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) {
+ var p = _superPropBase(e, t);
+ if (p) {
+ var n = Object.getOwnPropertyDescriptor(p, t);
+ return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
+ }
+ }, _get.apply(null, arguments);
+ }
+ function _getPrototypeOf$1(t) {
+ return _getPrototypeOf$1 = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
+ return t.__proto__ || Object.getPrototypeOf(t);
+ }, _getPrototypeOf$1(t);
+ }
+ function _inherits$1(t, e) {
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
+ t.prototype = Object.create(e && e.prototype, {
+ constructor: {
+ value: t,
+ writable: !0,
+ configurable: !0
+ }
+ }), Object.defineProperty(t, "prototype", {
+ writable: !1
+ }), e && _setPrototypeOf$1(t, e);
+ }
+ function _isNativeReflectConstruct$1() {
+ try {
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
+ } catch (t) {}
+ return (_isNativeReflectConstruct$1 = function () {
+ return !!t;
+ })();
+ }
+ function _iterableToArray(r) {
+ if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
+ }
+ function _iterableToArrayLimit(r, l) {
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
+ if (null != t) {
+ var e,
+ n,
+ i,
+ u,
+ a = [],
+ f = !0,
+ o = !1;
+ try {
+ if (i = (t = t.call(r)).next, 0 === l) {
+ if (Object(t) !== t) return;
+ f = !1;
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
+ } catch (r) {
+ o = !0, n = r;
+ } finally {
+ try {
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
+ } finally {
+ if (o) throw n;
+ }
+ }
+ return a;
+ }
+ }
+ function _nonIterableRest() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+ function _nonIterableSpread() {
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+ function ownKeys(e, r) {
+ var t = Object.keys(e);
+ if (Object.getOwnPropertySymbols) {
+ var o = Object.getOwnPropertySymbols(e);
+ r && (o = o.filter(function (r) {
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
+ })), t.push.apply(t, o);
+ }
+ return t;
+ }
+ function _objectSpread2(e) {
+ for (var r = 1; r < arguments.length; r++) {
+ var t = null != arguments[r] ? arguments[r] : {};
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
+ _defineProperty$1(e, r, t[r]);
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
+ });
+ }
+ return e;
+ }
+ function _possibleConstructorReturn$1(t, e) {
+ if (e && ("object" == typeof e || "function" == typeof e)) return e;
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
+ return _assertThisInitialized$1(t);
+ }
+ function _setPrototypeOf$1(t, e) {
+ return _setPrototypeOf$1 = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
+ return t.__proto__ = e, t;
+ }, _setPrototypeOf$1(t, e);
+ }
+ function _slicedToArray(r, e) {
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray$1(r, e) || _nonIterableRest();
+ }
+ function _superPropBase(t, o) {
+ for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf$1(t)););
+ return t;
+ }
+ function _superPropGet(t, o, e, r) {
+ var p = _get(_getPrototypeOf$1(1 & r ? t.prototype : t), o, e);
+ return 2 & r && "function" == typeof p ? function (t) {
+ return p.apply(e, t);
+ } : p;
+ }
+ function _toConsumableArray(r) {
+ return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray$1(r) || _nonIterableSpread();
+ }
+ function _toPrimitive(t, r) {
+ if ("object" != typeof t || !t) return t;
+ var e = t[Symbol.toPrimitive];
+ if (void 0 !== e) {
+ var i = e.call(t, r || "default");
+ if ("object" != typeof i) return i;
+ throw new TypeError("@@toPrimitive must return a primitive value.");
+ }
+ return ("string" === r ? String : Number)(t);
+ }
+ function _toPropertyKey(t) {
+ var i = _toPrimitive(t, "string");
+ return "symbol" == typeof i ? i : i + "";
+ }
+ function _typeof$1(o) {
+ "@babel/helpers - typeof";
+
+ return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
+ return typeof o;
+ } : function (o) {
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
+ }, _typeof$1(o);
+ }
+ function _unsupportedIterableToArray$1(r, a) {
+ if (r) {
+ if ("string" == typeof r) return _arrayLikeToArray$1(r, a);
+ var t = {}.toString.call(r).slice(8, -1);
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$1(r, a) : void 0;
+ }
+ }
+
+ /*!
+ * @kurkle/color v0.3.2
+ * https://github.com/kurkle/color#readme
+ * (c) 2023 Jukka Kurkela
+ * Released under the MIT License
+ */
+ function round(v) {
+ return v + 0.5 | 0;
+ }
+ var lim = function lim(v, l, h) {
+ return Math.max(Math.min(v, h), l);
+ };
+ function p2b(v) {
+ return lim(round(v * 2.55), 0, 255);
+ }
+ function n2b(v) {
+ return lim(round(v * 255), 0, 255);
+ }
+ function b2n(v) {
+ return lim(round(v / 2.55) / 100, 0, 1);
+ }
+ function n2p(v) {
+ return lim(round(v * 100), 0, 100);
+ }
+ var map$1 = {
+ 0: 0,
+ 1: 1,
+ 2: 2,
+ 3: 3,
+ 4: 4,
+ 5: 5,
+ 6: 6,
+ 7: 7,
+ 8: 8,
+ 9: 9,
+ A: 10,
+ B: 11,
+ C: 12,
+ D: 13,
+ E: 14,
+ F: 15,
+ a: 10,
+ b: 11,
+ c: 12,
+ d: 13,
+ e: 14,
+ f: 15
+ };
+ var hex = _toConsumableArray('0123456789ABCDEF');
+ var h1 = function h1(b) {
+ return hex[b & 0xF];
+ };
+ var h2 = function h2(b) {
+ return hex[(b & 0xF0) >> 4] + hex[b & 0xF];
+ };
+ var eq = function eq(b) {
+ return (b & 0xF0) >> 4 === (b & 0xF);
+ };
+ var isShort = function isShort(v) {
+ return eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
+ };
+ function hexParse(str) {
+ var len = str.length;
+ var ret;
+ if (str[0] === '#') {
+ if (len === 4 || len === 5) {
+ ret = {
+ r: 255 & map$1[str[1]] * 17,
+ g: 255 & map$1[str[2]] * 17,
+ b: 255 & map$1[str[3]] * 17,
+ a: len === 5 ? map$1[str[4]] * 17 : 255
+ };
+ } else if (len === 7 || len === 9) {
+ ret = {
+ r: map$1[str[1]] << 4 | map$1[str[2]],
+ g: map$1[str[3]] << 4 | map$1[str[4]],
+ b: map$1[str[5]] << 4 | map$1[str[6]],
+ a: len === 9 ? map$1[str[7]] << 4 | map$1[str[8]] : 255
+ };
+ }
+ }
+ return ret;
+ }
+ var alpha = function alpha(a, f) {
+ return a < 255 ? f(a) : '';
+ };
+ function _hexString(v) {
+ var f = isShort(v) ? h1 : h2;
+ return v ? '#' + f(v.r) + f(v.g) + f(v.b) + alpha(v.a, f) : undefined;
+ }
+ var HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
+ function hsl2rgbn(h, s, l) {
+ var a = s * Math.min(l, 1 - l);
+ var f = function f(n) {
+ var k = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (n + h / 30) % 12;
+ return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
+ };
+ return [f(0), f(8), f(4)];
+ }
+ function hsv2rgbn(h, s, v) {
+ var f = function f(n) {
+ var k = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (n + h / 60) % 6;
+ return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
+ };
+ return [f(5), f(3), f(1)];
+ }
+ function hwb2rgbn(h, w, b) {
+ var rgb = hsl2rgbn(h, 1, 0.5);
+ var i;
+ if (w + b > 1) {
+ i = 1 / (w + b);
+ w *= i;
+ b *= i;
+ }
+ for (i = 0; i < 3; i++) {
+ rgb[i] *= 1 - w - b;
+ rgb[i] += w;
+ }
+ return rgb;
+ }
+ function hueValue(r, g, b, d, max) {
+ if (r === max) {
+ return (g - b) / d + (g < b ? 6 : 0);
+ }
+ if (g === max) {
+ return (b - r) / d + 2;
+ }
+ return (r - g) / d + 4;
+ }
+ function rgb2hsl(v) {
+ var range = 255;
+ var r = v.r / range;
+ var g = v.g / range;
+ var b = v.b / range;
+ var max = Math.max(r, g, b);
+ var min = Math.min(r, g, b);
+ var l = (max + min) / 2;
+ var h, s, d;
+ if (max !== min) {
+ d = max - min;
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ h = hueValue(r, g, b, d, max);
+ h = h * 60 + 0.5;
+ }
+ return [h | 0, s || 0, l];
+ }
+ function calln(f, a, b, c) {
+ return (Array.isArray(a) ? f(a[0], a[1], a[2]) : f(a, b, c)).map(n2b);
+ }
+ function hsl2rgb(h, s, l) {
+ return calln(hsl2rgbn, h, s, l);
+ }
+ function hwb2rgb(h, w, b) {
+ return calln(hwb2rgbn, h, w, b);
+ }
+ function hsv2rgb(h, s, v) {
+ return calln(hsv2rgbn, h, s, v);
+ }
+ function hue(h) {
+ return (h % 360 + 360) % 360;
+ }
+ function hueParse(str) {
+ var m = HUE_RE.exec(str);
+ var a = 255;
+ var v;
+ if (!m) {
+ return;
+ }
+ if (m[5] !== v) {
+ a = m[6] ? p2b(+m[5]) : n2b(+m[5]);
+ }
+ var h = hue(+m[2]);
+ var p1 = +m[3] / 100;
+ var p2 = +m[4] / 100;
+ if (m[1] === 'hwb') {
+ v = hwb2rgb(h, p1, p2);
+ } else if (m[1] === 'hsv') {
+ v = hsv2rgb(h, p1, p2);
+ } else {
+ v = hsl2rgb(h, p1, p2);
+ }
+ return {
+ r: v[0],
+ g: v[1],
+ b: v[2],
+ a: a
+ };
+ }
+ function _rotate(v, deg) {
+ var h = rgb2hsl(v);
+ h[0] = hue(h[0] + deg);
+ h = hsl2rgb(h);
+ v.r = h[0];
+ v.g = h[1];
+ v.b = h[2];
+ }
+ function _hslString(v) {
+ if (!v) {
+ return;
+ }
+ var a = rgb2hsl(v);
+ var h = a[0];
+ var s = n2p(a[1]);
+ var l = n2p(a[2]);
+ return v.a < 255 ? "hsla(".concat(h, ", ").concat(s, "%, ").concat(l, "%, ").concat(b2n(v.a), ")") : "hsl(".concat(h, ", ").concat(s, "%, ").concat(l, "%)");
+ }
+ var map$2 = {
+ x: 'dark',
+ Z: 'light',
+ Y: 're',
+ X: 'blu',
+ W: 'gr',
+ V: 'medium',
+ U: 'slate',
+ A: 'ee',
+ T: 'ol',
+ S: 'or',
+ B: 'ra',
+ C: 'lateg',
+ D: 'ights',
+ R: 'in',
+ Q: 'turquois',
+ E: 'hi',
+ P: 'ro',
+ O: 'al',
+ N: 'le',
+ M: 'de',
+ L: 'yello',
+ F: 'en',
+ K: 'ch',
+ G: 'arks',
+ H: 'ea',
+ I: 'ightg',
+ J: 'wh'
+ };
+ var names$1 = {
+ OiceXe: 'f0f8ff',
+ antiquewEte: 'faebd7',
+ aqua: 'ffff',
+ aquamarRe: '7fffd4',
+ azuY: 'f0ffff',
+ beige: 'f5f5dc',
+ bisque: 'ffe4c4',
+ black: '0',
+ blanKedOmond: 'ffebcd',
+ Xe: 'ff',
+ XeviTet: '8a2be2',
+ bPwn: 'a52a2a',
+ burlywood: 'deb887',
+ caMtXe: '5f9ea0',
+ KartYuse: '7fff00',
+ KocTate: 'd2691e',
+ cSO: 'ff7f50',
+ cSnflowerXe: '6495ed',
+ cSnsilk: 'fff8dc',
+ crimson: 'dc143c',
+ cyan: 'ffff',
+ xXe: '8b',
+ xcyan: '8b8b',
+ xgTMnPd: 'b8860b',
+ xWay: 'a9a9a9',
+ xgYF: '6400',
+ xgYy: 'a9a9a9',
+ xkhaki: 'bdb76b',
+ xmagFta: '8b008b',
+ xTivegYF: '556b2f',
+ xSange: 'ff8c00',
+ xScEd: '9932cc',
+ xYd: '8b0000',
+ xsOmon: 'e9967a',
+ xsHgYF: '8fbc8f',
+ xUXe: '483d8b',
+ xUWay: '2f4f4f',
+ xUgYy: '2f4f4f',
+ xQe: 'ced1',
+ xviTet: '9400d3',
+ dAppRk: 'ff1493',
+ dApskyXe: 'bfff',
+ dimWay: '696969',
+ dimgYy: '696969',
+ dodgerXe: '1e90ff',
+ fiYbrick: 'b22222',
+ flSOwEte: 'fffaf0',
+ foYstWAn: '228b22',
+ fuKsia: 'ff00ff',
+ gaRsbSo: 'dcdcdc',
+ ghostwEte: 'f8f8ff',
+ gTd: 'ffd700',
+ gTMnPd: 'daa520',
+ Way: '808080',
+ gYF: '8000',
+ gYFLw: 'adff2f',
+ gYy: '808080',
+ honeyMw: 'f0fff0',
+ hotpRk: 'ff69b4',
+ RdianYd: 'cd5c5c',
+ Rdigo: '4b0082',
+ ivSy: 'fffff0',
+ khaki: 'f0e68c',
+ lavFMr: 'e6e6fa',
+ lavFMrXsh: 'fff0f5',
+ lawngYF: '7cfc00',
+ NmoncEffon: 'fffacd',
+ ZXe: 'add8e6',
+ ZcSO: 'f08080',
+ Zcyan: 'e0ffff',
+ ZgTMnPdLw: 'fafad2',
+ ZWay: 'd3d3d3',
+ ZgYF: '90ee90',
+ ZgYy: 'd3d3d3',
+ ZpRk: 'ffb6c1',
+ ZsOmon: 'ffa07a',
+ ZsHgYF: '20b2aa',
+ ZskyXe: '87cefa',
+ ZUWay: '778899',
+ ZUgYy: '778899',
+ ZstAlXe: 'b0c4de',
+ ZLw: 'ffffe0',
+ lime: 'ff00',
+ limegYF: '32cd32',
+ lRF: 'faf0e6',
+ magFta: 'ff00ff',
+ maPon: '800000',
+ VaquamarRe: '66cdaa',
+ VXe: 'cd',
+ VScEd: 'ba55d3',
+ VpurpN: '9370db',
+ VsHgYF: '3cb371',
+ VUXe: '7b68ee',
+ VsprRggYF: 'fa9a',
+ VQe: '48d1cc',
+ VviTetYd: 'c71585',
+ midnightXe: '191970',
+ mRtcYam: 'f5fffa',
+ mistyPse: 'ffe4e1',
+ moccasR: 'ffe4b5',
+ navajowEte: 'ffdead',
+ navy: '80',
+ Tdlace: 'fdf5e6',
+ Tive: '808000',
+ TivedBb: '6b8e23',
+ Sange: 'ffa500',
+ SangeYd: 'ff4500',
+ ScEd: 'da70d6',
+ pOegTMnPd: 'eee8aa',
+ pOegYF: '98fb98',
+ pOeQe: 'afeeee',
+ pOeviTetYd: 'db7093',
+ papayawEp: 'ffefd5',
+ pHKpuff: 'ffdab9',
+ peru: 'cd853f',
+ pRk: 'ffc0cb',
+ plum: 'dda0dd',
+ powMrXe: 'b0e0e6',
+ purpN: '800080',
+ YbeccapurpN: '663399',
+ Yd: 'ff0000',
+ Psybrown: 'bc8f8f',
+ PyOXe: '4169e1',
+ saddNbPwn: '8b4513',
+ sOmon: 'fa8072',
+ sandybPwn: 'f4a460',
+ sHgYF: '2e8b57',
+ sHshell: 'fff5ee',
+ siFna: 'a0522d',
+ silver: 'c0c0c0',
+ skyXe: '87ceeb',
+ UXe: '6a5acd',
+ UWay: '708090',
+ UgYy: '708090',
+ snow: 'fffafa',
+ sprRggYF: 'ff7f',
+ stAlXe: '4682b4',
+ tan: 'd2b48c',
+ teO: '8080',
+ tEstN: 'd8bfd8',
+ tomato: 'ff6347',
+ Qe: '40e0d0',
+ viTet: 'ee82ee',
+ JHt: 'f5deb3',
+ wEte: 'ffffff',
+ wEtesmoke: 'f5f5f5',
+ Lw: 'ffff00',
+ LwgYF: '9acd32'
+ };
+ function unpack() {
+ var unpacked = {};
+ var keys = Object.keys(names$1);
+ var tkeys = Object.keys(map$2);
+ var i, j, k, ok, nk;
+ for (i = 0; i < keys.length; i++) {
+ ok = nk = keys[i];
+ for (j = 0; j < tkeys.length; j++) {
+ k = tkeys[j];
+ nk = nk.replace(k, map$2[k]);
+ }
+ k = parseInt(names$1[ok], 16);
+ unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF];
+ }
+ return unpacked;
+ }
+ var names;
+ function nameParse(str) {
+ if (!names) {
+ names = unpack();
+ names.transparent = [0, 0, 0, 0];
+ }
+ var a = names[str.toLowerCase()];
+ return a && {
+ r: a[0],
+ g: a[1],
+ b: a[2],
+ a: a.length === 4 ? a[3] : 255
+ };
+ }
+ var RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
+ function rgbParse(str) {
+ var m = RGB_RE.exec(str);
+ var a = 255;
+ var r, g, b;
+ if (!m) {
+ return;
+ }
+ if (m[7] !== r) {
+ var v = +m[7];
+ a = m[8] ? p2b(v) : lim(v * 255, 0, 255);
+ }
+ r = +m[1];
+ g = +m[3];
+ b = +m[5];
+ r = 255 & (m[2] ? p2b(r) : lim(r, 0, 255));
+ g = 255 & (m[4] ? p2b(g) : lim(g, 0, 255));
+ b = 255 & (m[6] ? p2b(b) : lim(b, 0, 255));
+ return {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+ }
+ function _rgbString(v) {
+ return v && (v.a < 255 ? "rgba(".concat(v.r, ", ").concat(v.g, ", ").concat(v.b, ", ").concat(b2n(v.a), ")") : "rgb(".concat(v.r, ", ").concat(v.g, ", ").concat(v.b, ")"));
+ }
+ var to = function to(v) {
+ return v <= 0.0031308 ? v * 12.92 : Math.pow(v, 1.0 / 2.4) * 1.055 - 0.055;
+ };
+ var from = function from(v) {
+ return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
+ };
+ function _interpolate(rgb1, rgb2, t) {
+ var r = from(b2n(rgb1.r));
+ var g = from(b2n(rgb1.g));
+ var b = from(b2n(rgb1.b));
+ return {
+ r: n2b(to(r + t * (from(b2n(rgb2.r)) - r))),
+ g: n2b(to(g + t * (from(b2n(rgb2.g)) - g))),
+ b: n2b(to(b + t * (from(b2n(rgb2.b)) - b))),
+ a: rgb1.a + t * (rgb2.a - rgb1.a)
+ };
+ }
+ function modHSL(v, i, ratio) {
+ if (v) {
+ var tmp = rgb2hsl(v);
+ tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1));
+ tmp = hsl2rgb(tmp);
+ v.r = tmp[0];
+ v.g = tmp[1];
+ v.b = tmp[2];
+ }
+ }
+ function clone$1(v, proto) {
+ return v ? Object.assign(proto || {}, v) : v;
+ }
+ function fromObject(input) {
+ var v = {
+ r: 0,
+ g: 0,
+ b: 0,
+ a: 255
+ };
+ if (Array.isArray(input)) {
+ if (input.length >= 3) {
+ v = {
+ r: input[0],
+ g: input[1],
+ b: input[2],
+ a: 255
+ };
+ if (input.length > 3) {
+ v.a = n2b(input[3]);
+ }
+ }
+ } else {
+ v = clone$1(input, {
+ r: 0,
+ g: 0,
+ b: 0,
+ a: 1
+ });
+ v.a = n2b(v.a);
+ }
+ return v;
+ }
+ function functionParse(str) {
+ if (str.charAt(0) === 'r') {
+ return rgbParse(str);
+ }
+ return hueParse(str);
+ }
+ var Color = /*#__PURE__*/function () {
+ function Color(input) {
+ _classCallCheck$1(this, Color);
+ if (input instanceof Color) {
+ return input;
+ }
+ var type = _typeof$1(input);
+ var v;
+ if (type === 'object') {
+ v = fromObject(input);
+ } else if (type === 'string') {
+ v = hexParse(input) || nameParse(input) || functionParse(input);
+ }
+ this._rgb = v;
+ this._valid = !!v;
+ }
+ return _createClass$1(Color, [{
+ key: "valid",
+ get: function get() {
+ return this._valid;
+ }
+ }, {
+ key: "rgb",
+ get: function get() {
+ var v = clone$1(this._rgb);
+ if (v) {
+ v.a = b2n(v.a);
+ }
+ return v;
+ },
+ set: function set(obj) {
+ this._rgb = fromObject(obj);
+ }
+ }, {
+ key: "rgbString",
+ value: function rgbString() {
+ return this._valid ? _rgbString(this._rgb) : undefined;
+ }
+ }, {
+ key: "hexString",
+ value: function hexString() {
+ return this._valid ? _hexString(this._rgb) : undefined;
+ }
+ }, {
+ key: "hslString",
+ value: function hslString() {
+ return this._valid ? _hslString(this._rgb) : undefined;
+ }
+ }, {
+ key: "mix",
+ value: function mix(color, weight) {
+ if (color) {
+ var c1 = this.rgb;
+ var c2 = color.rgb;
+ var w2;
+ var p = weight === w2 ? 0.5 : weight;
+ var w = 2 * p - 1;
+ var a = c1.a - c2.a;
+ var w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ w2 = 1 - w1;
+ c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5;
+ c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5;
+ c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5;
+ c1.a = p * c1.a + (1 - p) * c2.a;
+ this.rgb = c1;
+ }
+ return this;
+ }
+ }, {
+ key: "interpolate",
+ value: function interpolate(color, t) {
+ if (color) {
+ this._rgb = _interpolate(this._rgb, color._rgb, t);
+ }
+ return this;
+ }
+ }, {
+ key: "clone",
+ value: function clone() {
+ return new Color(this.rgb);
+ }
+ }, {
+ key: "alpha",
+ value: function alpha(a) {
+ this._rgb.a = n2b(a);
+ return this;
+ }
+ }, {
+ key: "clearer",
+ value: function clearer(ratio) {
+ var rgb = this._rgb;
+ rgb.a *= 1 - ratio;
+ return this;
+ }
+ }, {
+ key: "greyscale",
+ value: function greyscale() {
+ var rgb = this._rgb;
+ var val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);
+ rgb.r = rgb.g = rgb.b = val;
+ return this;
+ }
+ }, {
+ key: "opaquer",
+ value: function opaquer(ratio) {
+ var rgb = this._rgb;
+ rgb.a *= 1 + ratio;
+ return this;
+ }
+ }, {
+ key: "negate",
+ value: function negate() {
+ var v = this._rgb;
+ v.r = 255 - v.r;
+ v.g = 255 - v.g;
+ v.b = 255 - v.b;
+ return this;
+ }
+ }, {
+ key: "lighten",
+ value: function lighten(ratio) {
+ modHSL(this._rgb, 2, ratio);
+ return this;
+ }
+ }, {
+ key: "darken",
+ value: function darken(ratio) {
+ modHSL(this._rgb, 2, -ratio);
+ return this;
+ }
+ }, {
+ key: "saturate",
+ value: function saturate(ratio) {
+ modHSL(this._rgb, 1, ratio);
+ return this;
+ }
+ }, {
+ key: "desaturate",
+ value: function desaturate(ratio) {
+ modHSL(this._rgb, 1, -ratio);
+ return this;
+ }
+ }, {
+ key: "rotate",
+ value: function rotate(deg) {
+ _rotate(this._rgb, deg);
+ return this;
+ }
+ }]);
+ }();
+
+ /**
+ * @namespace Chart.helpers
+ */ /**
+ * An empty function that can be used, for example, for optional callback.
+ */
+ function noop() {
+ /* noop */}
+ /**
+ * Returns a unique id, sequentially generated from a global variable.
+ */
+ var uid = function () {
+ var id = 0;
+ return function () {
+ return id++;
+ };
+ }();
+ /**
+ * Returns true if `value` is neither null nor undefined, else returns false.
+ * @param value - The value to test.
+ * @since 2.7.0
+ */
+ function isNullOrUndef(value) {
+ return value === null || value === undefined;
+ }
+ /**
+ * Returns true if `value` is an array (including typed arrays), else returns false.
+ * @param value - The value to test.
+ * @function
+ */
+ function isArray(value) {
+ if (Array.isArray && Array.isArray(value)) {
+ return true;
+ }
+ var type = Object.prototype.toString.call(value);
+ if (type.slice(0, 7) === '[object' && type.slice(-6) === 'Array]') {
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Returns true if `value` is an object (excluding null), else returns false.
+ * @param value - The value to test.
+ * @since 2.7.0
+ */
+ function isObject(value) {
+ return value !== null && Object.prototype.toString.call(value) === '[object Object]';
+ }
+ /**
+ * Returns true if `value` is a finite number, else returns false
+ * @param value - The value to test.
+ */
+ function isNumberFinite(value) {
+ return (typeof value === 'number' || value instanceof Number) && isFinite(+value);
+ }
+ /**
+ * Returns `value` if finite, else returns `defaultValue`.
+ * @param value - The value to return if defined.
+ * @param defaultValue - The value to return if `value` is not finite.
+ */
+ function finiteOrDefault(value, defaultValue) {
+ return isNumberFinite(value) ? value : defaultValue;
+ }
+ /**
+ * Returns `value` if defined, else returns `defaultValue`.
+ * @param value - The value to return if defined.
+ * @param defaultValue - The value to return if `value` is undefined.
+ */
+ function valueOrDefault(value, defaultValue) {
+ return typeof value === 'undefined' ? defaultValue : value;
+ }
+ var toPercentage = function toPercentage(value, dimension) {
+ return typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 : +value / dimension;
+ };
+ var toDimension = function toDimension(value, dimension) {
+ return typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 * dimension : +value;
+ };
+ /**
+ * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
+ * value returned by `fn`. If `fn` is not a function, this method returns undefined.
+ * @param fn - The function to call.
+ * @param args - The arguments with which `fn` should be called.
+ * @param [thisArg] - The value of `this` provided for the call to `fn`.
+ */
+ function callback(fn, args, thisArg) {
+ if (fn && typeof fn.call === 'function') {
+ return fn.apply(thisArg, args);
+ }
+ }
+ function each(loopable, fn, thisArg, reverse) {
+ var i, len, keys;
+ if (isArray(loopable)) {
+ len = loopable.length;
+ if (reverse) {
+ for (i = len - 1; i >= 0; i--) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ }
+ } else if (isObject(loopable)) {
+ keys = Object.keys(loopable);
+ len = keys.length;
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[keys[i]], keys[i]);
+ }
+ }
+ }
+ /**
+ * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
+ * @param a0 - The array to compare
+ * @param a1 - The array to compare
+ * @private
+ */
+ function _elementsEqual(a0, a1) {
+ var i, ilen, v0, v1;
+ if (!a0 || !a1 || a0.length !== a1.length) {
+ return false;
+ }
+ for (i = 0, ilen = a0.length; i < ilen; ++i) {
+ v0 = a0[i];
+ v1 = a1[i];
+ if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Returns a deep copy of `source` without keeping references on objects and arrays.
+ * @param source - The value to clone.
+ */
+ function clone(source) {
+ if (isArray(source)) {
+ return source.map(clone);
+ }
+ if (isObject(source)) {
+ var target = Object.create(null);
+ var keys = Object.keys(source);
+ var klen = keys.length;
+ var k = 0;
+ for (; k < klen; ++k) {
+ target[keys[k]] = clone(source[keys[k]]);
+ }
+ return target;
+ }
+ return source;
+ }
+ function isValidKey(key) {
+ return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1;
+ }
+ /**
+ * The default merger when Chart.helpers.merge is called without merger option.
+ * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback.
+ * @private
+ */
+ function _merger(key, target, source, options) {
+ if (!isValidKey(key)) {
+ return;
+ }
+ var tval = target[key];
+ var sval = source[key];
+ if (isObject(tval) && isObject(sval)) {
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ merge(tval, sval, options);
+ } else {
+ target[key] = clone(sval);
+ }
+ }
+ function merge(target, source, options) {
+ var sources = isArray(source) ? source : [source];
+ var ilen = sources.length;
+ if (!isObject(target)) {
+ return target;
+ }
+ options = options || {};
+ var merger = options.merger || _merger;
+ var current;
+ for (var i = 0; i < ilen; ++i) {
+ current = sources[i];
+ if (!isObject(current)) {
+ continue;
+ }
+ var keys = Object.keys(current);
+ for (var k = 0, klen = keys.length; k < klen; ++k) {
+ merger(keys[k], target, current, options);
+ }
+ }
+ return target;
+ }
+ function mergeIf(target, source) {
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ return merge(target, source, {
+ merger: _mergerIf
+ });
+ }
+ /**
+ * Merges source[key] in target[key] only if target[key] is undefined.
+ * @private
+ */
+ function _mergerIf(key, target, source) {
+ if (!isValidKey(key)) {
+ return;
+ }
+ var tval = target[key];
+ var sval = source[key];
+ if (isObject(tval) && isObject(sval)) {
+ mergeIf(tval, sval);
+ } else if (!Object.prototype.hasOwnProperty.call(target, key)) {
+ target[key] = clone(sval);
+ }
+ }
+ /**
+ * @private
+ */
+ function _deprecated(scope, value, previous, current) {
+ if (value !== undefined) {
+ console.warn(scope + ': "' + previous + '" is deprecated. Please use "' + current + '" instead');
+ }
+ }
+ // resolveObjectKey resolver cache
+ var keyResolvers = {
+ // Chart.helpers.core resolveObjectKey should resolve empty key to root object
+ '': function _(v) {
+ return v;
+ },
+ // default resolvers
+ x: function x(o) {
+ return o.x;
+ },
+ y: function y(o) {
+ return o.y;
+ }
+ };
+ /**
+ * @private
+ */
+ function _splitKey(key) {
+ var parts = key.split('.');
+ var keys = [];
+ var tmp = '';
+ var _iterator = _createForOfIteratorHelper$1(parts),
+ _step;
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var part = _step.value;
+ tmp += part;
+ if (tmp.endsWith('\\')) {
+ tmp = tmp.slice(0, -1) + '.';
+ } else {
+ keys.push(tmp);
+ tmp = '';
+ }
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+ return keys;
+ }
+ function _getKeyResolver(key) {
+ var keys = _splitKey(key);
+ return function (obj) {
+ var _iterator2 = _createForOfIteratorHelper$1(keys),
+ _step2;
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ var k = _step2.value;
+ if (k === '') {
+ break;
+ }
+ obj = obj && obj[k];
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
+ return obj;
+ };
+ }
+ function resolveObjectKey(obj, key) {
+ var resolver = keyResolvers[key] || (keyResolvers[key] = _getKeyResolver(key));
+ return resolver(obj);
+ }
+ /**
+ * @private
+ */
+ function _capitalize(str) {
+ return str.charAt(0).toUpperCase() + str.slice(1);
+ }
+ var defined = function defined(value) {
+ return typeof value !== 'undefined';
+ };
+ var isFunction = function isFunction(value) {
+ return typeof value === 'function';
+ };
+ // Adapted from https://stackoverflow.com/questions/31128855/comparing-ecma6-sets-for-equality#31129384
+ var setsEqual = function setsEqual(a, b) {
+ if (a.size !== b.size) {
+ return false;
+ }
+ var _iterator3 = _createForOfIteratorHelper$1(a),
+ _step3;
+ try {
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
+ var item = _step3.value;
+ if (!b.has(item)) {
+ return false;
+ }
+ }
+ } catch (err) {
+ _iterator3.e(err);
+ } finally {
+ _iterator3.f();
+ }
+ return true;
+ };
+ /**
+ * @param e - The event
+ * @private
+ */
+ function _isClickEvent(e) {
+ return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu';
+ }
+
+ /**
+ * @alias Chart.helpers.math
+ * @namespace
+ */
+ var PI = Math.PI;
+ var TAU = 2 * PI;
+ var PITAU = TAU + PI;
+ var INFINITY = Number.POSITIVE_INFINITY;
+ var RAD_PER_DEG = PI / 180;
+ var HALF_PI = PI / 2;
+ var QUARTER_PI = PI / 4;
+ var TWO_THIRDS_PI = PI * 2 / 3;
+ var log10 = Math.log10;
+ var sign = Math.sign;
+ function almostEquals(x, y, epsilon) {
+ return Math.abs(x - y) < epsilon;
+ }
+ /**
+ * Implementation of the nice number algorithm used in determining where axis labels will go
+ */
+ function niceNum(range) {
+ var roundedRange = Math.round(range);
+ range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range;
+ var niceRange = Math.pow(10, Math.floor(log10(range)));
+ var fraction = range / niceRange;
+ var niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;
+ return niceFraction * niceRange;
+ }
+ /**
+ * Returns an array of factors sorted from 1 to sqrt(value)
+ * @private
+ */
+ function _factorize(value) {
+ var result = [];
+ var sqrt = Math.sqrt(value);
+ var i;
+ for (i = 1; i < sqrt; i++) {
+ if (value % i === 0) {
+ result.push(i);
+ result.push(value / i);
+ }
+ }
+ if (sqrt === (sqrt | 0)) {
+ result.push(sqrt);
+ }
+ result.sort(function (a, b) {
+ return a - b;
+ }).pop();
+ return result;
+ }
+ /**
+ * Verifies that attempting to coerce n to string or number won't throw a TypeError.
+ */
+ function isNonPrimitive(n) {
+ return _typeof$1(n) === 'symbol' || _typeof$1(n) === 'object' && n !== null && !(Symbol.toPrimitive in n || 'toString' in n || 'valueOf' in n);
+ }
+ function isNumber(n) {
+ return !isNonPrimitive(n) && !isNaN(parseFloat(n)) && isFinite(n);
+ }
+ function almostWhole(x, epsilon) {
+ var rounded = Math.round(x);
+ return rounded - epsilon <= x && rounded + epsilon >= x;
+ }
+ /**
+ * @private
+ */
+ function _setMinAndMaxByKey(array, target, property) {
+ var i, ilen, value;
+ for (i = 0, ilen = array.length; i < ilen; i++) {
+ value = array[i][property];
+ if (!isNaN(value)) {
+ target.min = Math.min(target.min, value);
+ target.max = Math.max(target.max, value);
+ }
+ }
+ }
+ function toRadians(degrees) {
+ return degrees * (PI / 180);
+ }
+ function toDegrees(radians) {
+ return radians * (180 / PI);
+ }
+ /**
+ * Returns the number of decimal places
+ * i.e. the number of digits after the decimal point, of the value of this Number.
+ * @param x - A number.
+ * @returns The number of decimal places.
+ * @private
+ */
+ function _decimalPlaces(x) {
+ if (!isNumberFinite(x)) {
+ return;
+ }
+ var e = 1;
+ var p = 0;
+ while (Math.round(x * e) / e !== x) {
+ e *= 10;
+ p++;
+ }
+ return p;
+ }
+ // Gets the angle from vertical upright to the point about a centre.
+ function getAngleFromPoint(centrePoint, anglePoint) {
+ var distanceFromXCenter = anglePoint.x - centrePoint.x;
+ var distanceFromYCenter = anglePoint.y - centrePoint.y;
+ var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
+ var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
+ if (angle < -0.5 * PI) {
+ angle += TAU; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
+ }
+ return {
+ angle: angle,
+ distance: radialDistanceFromCenter
+ };
+ }
+ function distanceBetweenPoints(pt1, pt2) {
+ return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
+ }
+ /**
+ * Shortest distance between angles, in either direction.
+ * @private
+ */
+ function _angleDiff(a, b) {
+ return (a - b + PITAU) % TAU - PI;
+ }
+ /**
+ * Normalize angle to be between 0 and 2*PI
+ * @private
+ */
+ function _normalizeAngle(a) {
+ return (a % TAU + TAU) % TAU;
+ }
+ /**
+ * @private
+ */
+ function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
+ var a = _normalizeAngle(angle);
+ var s = _normalizeAngle(start);
+ var e = _normalizeAngle(end);
+ var angleToStart = _normalizeAngle(s - a);
+ var angleToEnd = _normalizeAngle(e - a);
+ var startToAngle = _normalizeAngle(a - s);
+ var endToAngle = _normalizeAngle(a - e);
+ return a === s || a === e || sameAngleIsFullCircle && s === e || angleToStart > angleToEnd && startToAngle < endToAngle;
+ }
+ /**
+ * Limit `value` between `min` and `max`
+ * @param value
+ * @param min
+ * @param max
+ * @private
+ */
+ function _limitValue(value, min, max) {
+ return Math.max(min, Math.min(max, value));
+ }
+ /**
+ * @param {number} value
+ * @private
+ */
+ function _int16Range(value) {
+ return _limitValue(value, -32768, 32767);
+ }
+ /**
+ * @param value
+ * @param start
+ * @param end
+ * @param [epsilon]
+ * @private
+ */
+ function _isBetween(value, start, end) {
+ var epsilon = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1e-6;
+ return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
+ }
+ function _lookup(table, value, cmp) {
+ cmp = cmp || function (index) {
+ return table[index] < value;
+ };
+ var hi = table.length - 1;
+ var lo = 0;
+ var mid;
+ while (hi - lo > 1) {
+ mid = lo + hi >> 1;
+ if (cmp(mid)) {
+ lo = mid;
+ } else {
+ hi = mid;
+ }
+ }
+ return {
+ lo: lo,
+ hi: hi
+ };
+ }
+ /**
+ * Binary search
+ * @param table - the table search. must be sorted!
+ * @param key - property name for the value in each entry
+ * @param value - value to find
+ * @param last - lookup last index
+ * @private
+ */
+ var _lookupByKey = function _lookupByKey(table, key, value, last) {
+ return _lookup(table, value, last ? function (index) {
+ var ti = table[index][key];
+ return ti < value || ti === value && table[index + 1][key] === value;
+ } : function (index) {
+ return table[index][key] < value;
+ });
+ };
+ /**
+ * Reverse binary search
+ * @param table - the table search. must be sorted!
+ * @param key - property name for the value in each entry
+ * @param value - value to find
+ * @private
+ */
+ var _rlookupByKey = function _rlookupByKey(table, key, value) {
+ return _lookup(table, value, function (index) {
+ return table[index][key] >= value;
+ });
+ };
+ /**
+ * Return subset of `values` between `min` and `max` inclusive.
+ * Values are assumed to be in sorted order.
+ * @param values - sorted array of values
+ * @param min - min value
+ * @param max - max value
+ */
+ function _filterBetween(values, min, max) {
+ var start = 0;
+ var end = values.length;
+ while (start < end && values[start] < min) {
+ start++;
+ }
+ while (end > start && values[end - 1] > max) {
+ end--;
+ }
+ return start > 0 || end < values.length ? values.slice(start, end) : values;
+ }
+ var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
+ function listenArrayEvents(array, listener) {
+ if (array._chartjs) {
+ array._chartjs.listeners.push(listener);
+ return;
+ }
+ Object.defineProperty(array, '_chartjs', {
+ configurable: true,
+ enumerable: false,
+ value: {
+ listeners: [listener]
+ }
+ });
+ arrayEvents.forEach(function (key) {
+ var method = '_onData' + _capitalize(key);
+ var base = array[key];
+ Object.defineProperty(array, key, {
+ configurable: true,
+ enumerable: false,
+ value: function value() {
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ var res = base.apply(this, args);
+ array._chartjs.listeners.forEach(function (object) {
+ if (typeof object[method] === 'function') {
+ object[method].apply(object, args);
+ }
+ });
+ return res;
+ }
+ });
+ });
+ }
+ function unlistenArrayEvents(array, listener) {
+ var stub = array._chartjs;
+ if (!stub) {
+ return;
+ }
+ var listeners = stub.listeners;
+ var index = listeners.indexOf(listener);
+ if (index !== -1) {
+ listeners.splice(index, 1);
+ }
+ if (listeners.length > 0) {
+ return;
+ }
+ arrayEvents.forEach(function (key) {
+ delete array[key];
+ });
+ delete array._chartjs;
+ }
+ /**
+ * @param items
+ */
+ function _arrayUnique(items) {
+ var set = new Set(items);
+ if (set.size === items.length) {
+ return items;
+ }
+ return Array.from(set);
+ }
+ function fontString(pixelSize, fontStyle, fontFamily) {
+ return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
+ }
+ /**
+ * Request animation polyfill
+ */
+ var requestAnimFrame = function () {
+ if (typeof window === 'undefined') {
+ return function (callback) {
+ return callback();
+ };
+ }
+ return window.requestAnimationFrame;
+ }();
+ /**
+ * Throttles calling `fn` once per animation frame
+ * Latest arguments are used on the actual call
+ */
+ function throttled(fn, thisArg) {
+ var argsToUse = [];
+ var ticking = false;
+ return function () {
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args[_key2] = arguments[_key2];
+ }
+ // Save the args for use later
+ argsToUse = args;
+ if (!ticking) {
+ ticking = true;
+ requestAnimFrame.call(window, function () {
+ ticking = false;
+ fn.apply(thisArg, argsToUse);
+ });
+ }
+ };
+ }
+ /**
+ * Debounces calling `fn` for `delay` ms
+ */
+ function debounce(fn, delay) {
+ var timeout;
+ return function () {
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
+ args[_key3] = arguments[_key3];
+ }
+ if (delay) {
+ clearTimeout(timeout);
+ timeout = setTimeout(fn, delay, args);
+ } else {
+ fn.apply(this, args);
+ }
+ return delay;
+ };
+ }
+ /**
+ * Converts 'start' to 'left', 'end' to 'right' and others to 'center'
+ * @private
+ */
+ var _toLeftRightCenter = function _toLeftRightCenter(align) {
+ return align === 'start' ? 'left' : align === 'end' ? 'right' : 'center';
+ };
+ /**
+ * Returns `start`, `end` or `(start + end) / 2` depending on `align`. Defaults to `center`
+ * @private
+ */
+ var _alignStartEnd = function _alignStartEnd(align, start, end) {
+ return align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
+ };
+ /**
+ * Returns `left`, `right` or `(left + right) / 2` depending on `align`. Defaults to `left`
+ * @private
+ */
+ var _textX = function _textX(align, left, right, rtl) {
+ var check = rtl ? 'left' : 'right';
+ return align === check ? right : align === 'center' ? (left + right) / 2 : left;
+ };
+ /**
+ * Return start and count of visible points.
+ * @private
+ */
+ function _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) {
+ var pointCount = points.length;
+ var start = 0;
+ var count = pointCount;
+ if (meta._sorted) {
+ var iScale = meta.iScale,
+ vScale = meta.vScale,
+ _parsed = meta._parsed;
+ var spanGaps = meta.dataset ? meta.dataset.options ? meta.dataset.options.spanGaps : null : null;
+ var axis = iScale.axis;
+ var _iScale$getUserBounds = iScale.getUserBounds(),
+ min = _iScale$getUserBounds.min,
+ max = _iScale$getUserBounds.max,
+ minDefined = _iScale$getUserBounds.minDefined,
+ maxDefined = _iScale$getUserBounds.maxDefined;
+ if (minDefined) {
+ start = Math.min(
+ // @ts-expect-error Need to type _parsed
+ _lookupByKey(_parsed, axis, min).lo,
+ // @ts-expect-error Need to fix types on _lookupByKey
+ animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo);
+ if (spanGaps) {
+ var distanceToDefinedLo = _parsed.slice(0, start + 1).reverse().findIndex(function (point) {
+ return !isNullOrUndef(point[vScale.axis]);
+ });
+ start -= Math.max(0, distanceToDefinedLo);
+ }
+ start = _limitValue(start, 0, pointCount - 1);
+ }
+ if (maxDefined) {
+ var end = Math.max(
+ // @ts-expect-error Need to type _parsed
+ _lookupByKey(_parsed, iScale.axis, max, true).hi + 1,
+ // @ts-expect-error Need to fix types on _lookupByKey
+ animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max), true).hi + 1);
+ if (spanGaps) {
+ var distanceToDefinedHi = _parsed.slice(end - 1).findIndex(function (point) {
+ return !isNullOrUndef(point[vScale.axis]);
+ });
+ end += Math.max(0, distanceToDefinedHi);
+ }
+ count = _limitValue(end, start, pointCount) - start;
+ } else {
+ count = pointCount - start;
+ }
+ }
+ return {
+ start: start,
+ count: count
+ };
+ }
+ /**
+ * Checks if the scale ranges have changed.
+ * @param {object} meta - dataset meta.
+ * @returns {boolean}
+ * @private
+ */
+ function _scaleRangesChanged(meta) {
+ var xScale = meta.xScale,
+ yScale = meta.yScale,
+ _scaleRanges = meta._scaleRanges;
+ var newRanges = {
+ xmin: xScale.min,
+ xmax: xScale.max,
+ ymin: yScale.min,
+ ymax: yScale.max
+ };
+ if (!_scaleRanges) {
+ meta._scaleRanges = newRanges;
+ return true;
+ }
+ var changed = _scaleRanges.xmin !== xScale.min || _scaleRanges.xmax !== xScale.max || _scaleRanges.ymin !== yScale.min || _scaleRanges.ymax !== yScale.max;
+ Object.assign(_scaleRanges, newRanges);
+ return changed;
+ }
+ var atEdge = function atEdge(t) {
+ return t === 0 || t === 1;
+ };
+ var elasticIn = function elasticIn(t, s, p) {
+ return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p));
+ };
+ var elasticOut = function elasticOut(t, s, p) {
+ return Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1;
+ };
+ /**
+ * Easing functions adapted from Robert Penner's easing equations.
+ * @namespace Chart.helpers.easing.effects
+ * @see http://www.robertpenner.com/easing/
+ */
+ var effects = {
+ linear: function linear(t) {
+ return t;
+ },
+ easeInQuad: function easeInQuad(t) {
+ return t * t;
+ },
+ easeOutQuad: function easeOutQuad(t) {
+ return -t * (t - 2);
+ },
+ easeInOutQuad: function easeInOutQuad(t) {
+ return (t /= 0.5) < 1 ? 0.5 * t * t : -0.5 * (--t * (t - 2) - 1);
+ },
+ easeInCubic: function easeInCubic(t) {
+ return t * t * t;
+ },
+ easeOutCubic: function easeOutCubic(t) {
+ return (t -= 1) * t * t + 1;
+ },
+ easeInOutCubic: function easeInOutCubic(t) {
+ return (t /= 0.5) < 1 ? 0.5 * t * t * t : 0.5 * ((t -= 2) * t * t + 2);
+ },
+ easeInQuart: function easeInQuart(t) {
+ return t * t * t * t;
+ },
+ easeOutQuart: function easeOutQuart(t) {
+ return -((t -= 1) * t * t * t - 1);
+ },
+ easeInOutQuart: function easeInOutQuart(t) {
+ return (t /= 0.5) < 1 ? 0.5 * t * t * t * t : -0.5 * ((t -= 2) * t * t * t - 2);
+ },
+ easeInQuint: function easeInQuint(t) {
+ return t * t * t * t * t;
+ },
+ easeOutQuint: function easeOutQuint(t) {
+ return (t -= 1) * t * t * t * t + 1;
+ },
+ easeInOutQuint: function easeInOutQuint(t) {
+ return (t /= 0.5) < 1 ? 0.5 * t * t * t * t * t : 0.5 * ((t -= 2) * t * t * t * t + 2);
+ },
+ easeInSine: function easeInSine(t) {
+ return -Math.cos(t * HALF_PI) + 1;
+ },
+ easeOutSine: function easeOutSine(t) {
+ return Math.sin(t * HALF_PI);
+ },
+ easeInOutSine: function easeInOutSine(t) {
+ return -0.5 * (Math.cos(PI * t) - 1);
+ },
+ easeInExpo: function easeInExpo(t) {
+ return t === 0 ? 0 : Math.pow(2, 10 * (t - 1));
+ },
+ easeOutExpo: function easeOutExpo(t) {
+ return t === 1 ? 1 : -Math.pow(2, -10 * t) + 1;
+ },
+ easeInOutExpo: function easeInOutExpo(t) {
+ return atEdge(t) ? t : t < 0.5 ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2);
+ },
+ easeInCirc: function easeInCirc(t) {
+ return t >= 1 ? t : -(Math.sqrt(1 - t * t) - 1);
+ },
+ easeOutCirc: function easeOutCirc(t) {
+ return Math.sqrt(1 - (t -= 1) * t);
+ },
+ easeInOutCirc: function easeInOutCirc(t) {
+ return (t /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);
+ },
+ easeInElastic: function easeInElastic(t) {
+ return atEdge(t) ? t : elasticIn(t, 0.075, 0.3);
+ },
+ easeOutElastic: function easeOutElastic(t) {
+ return atEdge(t) ? t : elasticOut(t, 0.075, 0.3);
+ },
+ easeInOutElastic: function easeInOutElastic(t) {
+ var s = 0.1125;
+ var p = 0.45;
+ return atEdge(t) ? t : t < 0.5 ? 0.5 * elasticIn(t * 2, s, p) : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p);
+ },
+ easeInBack: function easeInBack(t) {
+ var s = 1.70158;
+ return t * t * ((s + 1) * t - s);
+ },
+ easeOutBack: function easeOutBack(t) {
+ var s = 1.70158;
+ return (t -= 1) * t * ((s + 1) * t + s) + 1;
+ },
+ easeInOutBack: function easeInOutBack(t) {
+ var s = 1.70158;
+ if ((t /= 0.5) < 1) {
+ return 0.5 * (t * t * (((s *= 1.525) + 1) * t - s));
+ }
+ return 0.5 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2);
+ },
+ easeInBounce: function easeInBounce(t) {
+ return 1 - effects.easeOutBounce(1 - t);
+ },
+ easeOutBounce: function easeOutBounce(t) {
+ var m = 7.5625;
+ var d = 2.75;
+ if (t < 1 / d) {
+ return m * t * t;
+ }
+ if (t < 2 / d) {
+ return m * (t -= 1.5 / d) * t + 0.75;
+ }
+ if (t < 2.5 / d) {
+ return m * (t -= 2.25 / d) * t + 0.9375;
+ }
+ return m * (t -= 2.625 / d) * t + 0.984375;
+ },
+ easeInOutBounce: function easeInOutBounce(t) {
+ return t < 0.5 ? effects.easeInBounce(t * 2) * 0.5 : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;
+ }
+ };
+ function isPatternOrGradient(value) {
+ if (value && _typeof$1(value) === 'object') {
+ var type = value.toString();
+ return type === '[object CanvasPattern]' || type === '[object CanvasGradient]';
+ }
+ return false;
+ }
+ function color(value) {
+ return isPatternOrGradient(value) ? value : new Color(value);
+ }
+ function getHoverColor(value) {
+ return isPatternOrGradient(value) ? value : new Color(value).saturate(0.5).darken(0.1).hexString();
+ }
+ var numbers = ['x', 'y', 'borderWidth', 'radius', 'tension'];
+ var colors = ['color', 'borderColor', 'backgroundColor'];
+ function applyAnimationsDefaults(defaults) {
+ defaults.set('animation', {
+ delay: undefined,
+ duration: 1000,
+ easing: 'easeOutQuart',
+ fn: undefined,
+ from: undefined,
+ loop: undefined,
+ to: undefined,
+ type: undefined
+ });
+ defaults.describe('animation', {
+ _fallback: false,
+ _indexable: false,
+ _scriptable: function _scriptable(name) {
+ return name !== 'onProgress' && name !== 'onComplete' && name !== 'fn';
+ }
+ });
+ defaults.set('animations', {
+ colors: {
+ type: 'color',
+ properties: colors
+ },
+ numbers: {
+ type: 'number',
+ properties: numbers
+ }
+ });
+ defaults.describe('animations', {
+ _fallback: 'animation'
+ });
+ defaults.set('transitions', {
+ active: {
+ animation: {
+ duration: 400
+ }
+ },
+ resize: {
+ animation: {
+ duration: 0
+ }
+ },
+ show: {
+ animations: {
+ colors: {
+ from: 'transparent'
+ },
+ visible: {
+ type: 'boolean',
+ duration: 0
+ }
+ }
+ },
+ hide: {
+ animations: {
+ colors: {
+ to: 'transparent'
+ },
+ visible: {
+ type: 'boolean',
+ easing: 'linear',
+ fn: function fn(v) {
+ return v | 0;
+ }
+ }
+ }
+ }
+ });
+ }
+ function applyLayoutsDefaults(defaults) {
+ defaults.set('layout', {
+ autoPadding: true,
+ padding: {
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ }
+ });
+ }
+ var intlCache = new Map();
+ function getNumberFormat(locale, options) {
+ options = options || {};
+ var cacheKey = locale + JSON.stringify(options);
+ var formatter = intlCache.get(cacheKey);
+ if (!formatter) {
+ formatter = new Intl.NumberFormat(locale, options);
+ intlCache.set(cacheKey, formatter);
+ }
+ return formatter;
+ }
+ function formatNumber(num, locale, options) {
+ return getNumberFormat(locale, options).format(num);
+ }
+ var formatters$4 = {
+ values: function values(value) {
+ return isArray(value) ? value : '' + value;
+ },
+ numeric: function numeric(tickValue, index, ticks) {
+ if (tickValue === 0) {
+ return '0';
+ }
+ var locale = this.chart.options.locale;
+ var notation;
+ var delta = tickValue;
+ if (ticks.length > 1) {
+ var maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
+ if (maxTick < 1e-4 || maxTick > 1e+15) {
+ notation = 'scientific';
+ }
+ delta = calculateDelta(tickValue, ticks);
+ }
+ var logDelta = log10(Math.abs(delta));
+ var numDecimal = isNaN(logDelta) ? 1 : Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0);
+ var options = {
+ notation: notation,
+ minimumFractionDigits: numDecimal,
+ maximumFractionDigits: numDecimal
+ };
+ Object.assign(options, this.options.ticks.format);
+ return formatNumber(tickValue, locale, options);
+ },
+ logarithmic: function logarithmic(tickValue, index, ticks) {
+ if (tickValue === 0) {
+ return '0';
+ }
+ var remain = ticks[index].significand || tickValue / Math.pow(10, Math.floor(log10(tickValue)));
+ if ([1, 2, 3, 5, 10, 15].includes(remain) || index > 0.8 * ticks.length) {
+ return formatters$4.numeric.call(this, tickValue, index, ticks);
+ }
+ return '';
+ }
+ };
+ function calculateDelta(tickValue, ticks) {
+ var delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
+ if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) {
+ delta = tickValue - Math.floor(tickValue);
+ }
+ return delta;
+ }
+ var Ticks = {
+ formatters: formatters$4
+ };
+ function applyScaleDefaults(defaults) {
+ defaults.set('scale', {
+ display: true,
+ offset: false,
+ reverse: false,
+ beginAtZero: false,
+ bounds: 'ticks',
+ clip: true,
+ grace: 0,
+ grid: {
+ display: true,
+ lineWidth: 1,
+ drawOnChartArea: true,
+ drawTicks: true,
+ tickLength: 8,
+ tickWidth: function tickWidth(_ctx, options) {
+ return options.lineWidth;
+ },
+ tickColor: function tickColor(_ctx, options) {
+ return options.color;
+ },
+ offset: false
+ },
+ border: {
+ display: true,
+ dash: [],
+ dashOffset: 0.0,
+ width: 1
+ },
+ title: {
+ display: false,
+ text: '',
+ padding: {
+ top: 4,
+ bottom: 4
+ }
+ },
+ ticks: {
+ minRotation: 0,
+ maxRotation: 50,
+ mirror: false,
+ textStrokeWidth: 0,
+ textStrokeColor: '',
+ padding: 3,
+ display: true,
+ autoSkip: true,
+ autoSkipPadding: 3,
+ labelOffset: 0,
+ callback: Ticks.formatters.values,
+ minor: {},
+ major: {},
+ align: 'center',
+ crossAlign: 'near',
+ showLabelBackdrop: false,
+ backdropColor: 'rgba(255, 255, 255, 0.75)',
+ backdropPadding: 2
+ }
+ });
+ defaults.route('scale.ticks', 'color', '', 'color');
+ defaults.route('scale.grid', 'color', '', 'borderColor');
+ defaults.route('scale.border', 'color', '', 'borderColor');
+ defaults.route('scale.title', 'color', '', 'color');
+ defaults.describe('scale', {
+ _fallback: false,
+ _scriptable: function _scriptable(name) {
+ return !name.startsWith('before') && !name.startsWith('after') && name !== 'callback' && name !== 'parser';
+ },
+ _indexable: function _indexable(name) {
+ return name !== 'borderDash' && name !== 'tickBorderDash' && name !== 'dash';
+ }
+ });
+ defaults.describe('scales', {
+ _fallback: 'scale'
+ });
+ defaults.describe('scale.ticks', {
+ _scriptable: function _scriptable(name) {
+ return name !== 'backdropPadding' && name !== 'callback';
+ },
+ _indexable: function _indexable(name) {
+ return name !== 'backdropPadding';
+ }
+ });
+ }
+ var overrides = Object.create(null);
+ var descriptors = Object.create(null);
+ function getScope$1(node, key) {
+ if (!key) {
+ return node;
+ }
+ var keys = key.split('.');
+ for (var i = 0, n = keys.length; i < n; ++i) {
+ var k = keys[i];
+ node = node[k] || (node[k] = Object.create(null));
+ }
+ return node;
+ }
+ function _set(root, scope, values) {
+ if (typeof scope === 'string') {
+ return merge(getScope$1(root, scope), values);
+ }
+ return merge(getScope$1(root, ''), scope);
+ }
+ var Defaults = /*#__PURE__*/function () {
+ function Defaults(_descriptors, _appliers) {
+ _classCallCheck$1(this, Defaults);
+ this.animation = undefined;
+ this.backgroundColor = 'rgba(0,0,0,0.1)';
+ this.borderColor = 'rgba(0,0,0,0.1)';
+ this.color = '#666';
+ this.datasets = {};
+ this.devicePixelRatio = function (context) {
+ return context.chart.platform.getDevicePixelRatio();
+ };
+ this.elements = {};
+ this.events = ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'];
+ this.font = {
+ family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+ size: 12,
+ style: 'normal',
+ lineHeight: 1.2,
+ weight: null
+ };
+ this.hover = {};
+ this.hoverBackgroundColor = function (ctx, options) {
+ return getHoverColor(options.backgroundColor);
+ };
+ this.hoverBorderColor = function (ctx, options) {
+ return getHoverColor(options.borderColor);
+ };
+ this.hoverColor = function (ctx, options) {
+ return getHoverColor(options.color);
+ };
+ this.indexAxis = 'x';
+ this.interaction = {
+ mode: 'nearest',
+ intersect: true,
+ includeInvisible: false
+ };
+ this.maintainAspectRatio = true;
+ this.onHover = null;
+ this.onClick = null;
+ this.parsing = true;
+ this.plugins = {};
+ this.responsive = true;
+ this.scale = undefined;
+ this.scales = {};
+ this.showLine = true;
+ this.drawActiveElementsOnTop = true;
+ this.describe(_descriptors);
+ this.apply(_appliers);
+ }
+ return _createClass$1(Defaults, [{
+ key: "set",
+ value: function set(scope, values) {
+ return _set(this, scope, values);
+ }
+ }, {
+ key: "get",
+ value: function get(scope) {
+ return getScope$1(this, scope);
+ }
+ }, {
+ key: "describe",
+ value: function describe(scope, values) {
+ return _set(descriptors, scope, values);
+ }
+ }, {
+ key: "override",
+ value: function override(scope, values) {
+ return _set(overrides, scope, values);
+ }
+ }, {
+ key: "route",
+ value: function route(scope, name, targetScope, targetName) {
+ var scopeObject = getScope$1(this, scope);
+ var targetScopeObject = getScope$1(this, targetScope);
+ var privateName = '_' + name;
+ Object.defineProperties(scopeObject, _defineProperty$1(_defineProperty$1({}, privateName, {
+ value: scopeObject[name],
+ writable: true
+ }), name, {
+ enumerable: true,
+ get: function get() {
+ var local = this[privateName];
+ var target = targetScopeObject[targetName];
+ if (isObject(local)) {
+ return Object.assign({}, target, local);
+ }
+ return valueOrDefault(local, target);
+ },
+ set: function set(value) {
+ this[privateName] = value;
+ }
+ }));
+ }
+ }, {
+ key: "apply",
+ value: function apply(appliers) {
+ var _this = this;
+ appliers.forEach(function (apply) {
+ return apply(_this);
+ });
+ }
+ }]);
+ }();
+ var defaults = /* #__PURE__ */new Defaults({
+ _scriptable: function _scriptable(name) {
+ return !name.startsWith('on');
+ },
+ _indexable: function _indexable(name) {
+ return name !== 'events';
+ },
+ hover: {
+ _fallback: 'interaction'
+ },
+ interaction: {
+ _scriptable: false,
+ _indexable: false
+ }
+ }, [applyAnimationsDefaults, applyLayoutsDefaults, applyScaleDefaults]);
+
+ /**
+ * Converts the given font object into a CSS font string.
+ * @param font - A font object.
+ * @return The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font
+ * @private
+ */
+ function toFontString(font) {
+ if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) {
+ return null;
+ }
+ return (font.style ? font.style + ' ' : '') + (font.weight ? font.weight + ' ' : '') + font.size + 'px ' + font.family;
+ }
+ /**
+ * @private
+ */
+ function _measureText(ctx, data, gc, longest, string) {
+ var textWidth = data[string];
+ if (!textWidth) {
+ textWidth = data[string] = ctx.measureText(string).width;
+ gc.push(string);
+ }
+ if (textWidth > longest) {
+ longest = textWidth;
+ }
+ return longest;
+ }
+ /**
+ * @private
+ */ // eslint-disable-next-line complexity
+ function _longestText(ctx, font, arrayOfThings, cache) {
+ cache = cache || {};
+ var data = cache.data = cache.data || {};
+ var gc = cache.garbageCollect = cache.garbageCollect || [];
+ if (cache.font !== font) {
+ data = cache.data = {};
+ gc = cache.garbageCollect = [];
+ cache.font = font;
+ }
+ ctx.save();
+ ctx.font = font;
+ var longest = 0;
+ var ilen = arrayOfThings.length;
+ var i, j, jlen, thing, nestedThing;
+ for (i = 0; i < ilen; i++) {
+ thing = arrayOfThings[i];
+ // Undefined strings and arrays should not be measured
+ if (thing !== undefined && thing !== null && !isArray(thing)) {
+ longest = _measureText(ctx, data, gc, longest, thing);
+ } else if (isArray(thing)) {
+ // if it is an array lets measure each element
+ // to do maybe simplify this function a bit so we can do this more recursively?
+ for (j = 0, jlen = thing.length; j < jlen; j++) {
+ nestedThing = thing[j];
+ // Undefined strings and arrays should not be measured
+ if (nestedThing !== undefined && nestedThing !== null && !isArray(nestedThing)) {
+ longest = _measureText(ctx, data, gc, longest, nestedThing);
+ }
+ }
+ }
+ }
+ ctx.restore();
+ var gcLen = gc.length / 2;
+ if (gcLen > arrayOfThings.length) {
+ for (i = 0; i < gcLen; i++) {
+ delete data[gc[i]];
+ }
+ gc.splice(0, gcLen);
+ }
+ return longest;
+ }
+ /**
+ * Returns the aligned pixel value to avoid anti-aliasing blur
+ * @param chart - The chart instance.
+ * @param pixel - A pixel value.
+ * @param width - The width of the element.
+ * @returns The aligned pixel value.
+ * @private
+ */
+ function _alignPixel(chart, pixel, width) {
+ var devicePixelRatio = chart.currentDevicePixelRatio;
+ var halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0;
+ return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;
+ }
+ /**
+ * Clears the entire canvas.
+ */
+ function clearCanvas(canvas, ctx) {
+ if (!ctx && !canvas) {
+ return;
+ }
+ ctx = ctx || canvas.getContext('2d');
+ ctx.save();
+ // canvas.width and canvas.height do not consider the canvas transform,
+ // while clearRect does
+ ctx.resetTransform();
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.restore();
+ }
+ function drawPoint(ctx, options, x, y) {
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ drawPointLegend(ctx, options, x, y, null);
+ }
+ // eslint-disable-next-line complexity
+ function drawPointLegend(ctx, options, x, y, w) {
+ var type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW;
+ var style = options.pointStyle;
+ var rotation = options.rotation;
+ var radius = options.radius;
+ var rad = (rotation || 0) * RAD_PER_DEG;
+ if (style && _typeof$1(style) === 'object') {
+ type = style.toString();
+ if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
+ ctx.save();
+ ctx.translate(x, y);
+ ctx.rotate(rad);
+ ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);
+ ctx.restore();
+ return;
+ }
+ }
+ if (isNaN(radius) || radius <= 0) {
+ return;
+ }
+ ctx.beginPath();
+ switch (style) {
+ // Default includes circle
+ default:
+ if (w) {
+ ctx.ellipse(x, y, w / 2, radius, 0, 0, TAU);
+ } else {
+ ctx.arc(x, y, radius, 0, TAU);
+ }
+ ctx.closePath();
+ break;
+ case 'triangle':
+ width = w ? w / 2 : radius;
+ ctx.moveTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);
+ rad += TWO_THIRDS_PI;
+ ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);
+ rad += TWO_THIRDS_PI;
+ ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius);
+ ctx.closePath();
+ break;
+ case 'rectRounded':
+ // NOTE: the rounded rect implementation changed to use `arc` instead of
+ // `quadraticCurveTo` since it generates better results when rect is
+ // almost a circle. 0.516 (instead of 0.5) produces results with visually
+ // closer proportion to the previous impl and it is inscribed in the
+ // circle with `radius`. For more details, see the following PRs:
+ // https://github.com/chartjs/Chart.js/issues/5597
+ // https://github.com/chartjs/Chart.js/issues/5858
+ cornerRadius = radius * 0.516;
+ size = radius - cornerRadius;
+ xOffset = Math.cos(rad + QUARTER_PI) * size;
+ xOffsetW = Math.cos(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size);
+ yOffset = Math.sin(rad + QUARTER_PI) * size;
+ yOffsetW = Math.sin(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size);
+ ctx.arc(x - xOffsetW, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);
+ ctx.arc(x + yOffsetW, y - xOffset, cornerRadius, rad - HALF_PI, rad);
+ ctx.arc(x + xOffsetW, y + yOffset, cornerRadius, rad, rad + HALF_PI);
+ ctx.arc(x - yOffsetW, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);
+ ctx.closePath();
+ break;
+ case 'rect':
+ if (!rotation) {
+ size = Math.SQRT1_2 * radius;
+ width = w ? w / 2 : size;
+ ctx.rect(x - width, y - size, 2 * width, 2 * size);
+ break;
+ }
+ rad += QUARTER_PI;
+ /* falls through */
+ case 'rectRot':
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
+ ctx.moveTo(x - xOffsetW, y - yOffset);
+ ctx.lineTo(x + yOffsetW, y - xOffset);
+ ctx.lineTo(x + xOffsetW, y + yOffset);
+ ctx.lineTo(x - yOffsetW, y + xOffset);
+ ctx.closePath();
+ break;
+ case 'crossRot':
+ rad += QUARTER_PI;
+ /* falls through */
+ case 'cross':
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
+ ctx.moveTo(x - xOffsetW, y - yOffset);
+ ctx.lineTo(x + xOffsetW, y + yOffset);
+ ctx.moveTo(x + yOffsetW, y - xOffset);
+ ctx.lineTo(x - yOffsetW, y + xOffset);
+ break;
+ case 'star':
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
+ ctx.moveTo(x - xOffsetW, y - yOffset);
+ ctx.lineTo(x + xOffsetW, y + yOffset);
+ ctx.moveTo(x + yOffsetW, y - xOffset);
+ ctx.lineTo(x - yOffsetW, y + xOffset);
+ rad += QUARTER_PI;
+ xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ yOffsetW = Math.sin(rad) * (w ? w / 2 : radius);
+ ctx.moveTo(x - xOffsetW, y - yOffset);
+ ctx.lineTo(x + xOffsetW, y + yOffset);
+ ctx.moveTo(x + yOffsetW, y - xOffset);
+ ctx.lineTo(x - yOffsetW, y + xOffset);
+ break;
+ case 'line':
+ xOffset = w ? w / 2 : Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ break;
+ case 'dash':
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + Math.cos(rad) * (w ? w / 2 : radius), y + Math.sin(rad) * radius);
+ break;
+ case false:
+ ctx.closePath();
+ break;
+ }
+ ctx.fill();
+ if (options.borderWidth > 0) {
+ ctx.stroke();
+ }
+ }
+ /**
+ * Returns true if the point is inside the rectangle
+ * @param point - The point to test
+ * @param area - The rectangle
+ * @param margin - allowed margin
+ * @private
+ */
+ function _isPointInArea(point, area, margin) {
+ margin = margin || 0.5; // margin - default is to match rounded decimals
+ return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin;
+ }
+ function clipArea(ctx, area) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
+ ctx.clip();
+ }
+ function unclipArea(ctx) {
+ ctx.restore();
+ }
+ /**
+ * @private
+ */
+ function _steppedLineTo(ctx, previous, target, flip, mode) {
+ if (!previous) {
+ return ctx.lineTo(target.x, target.y);
+ }
+ if (mode === 'middle') {
+ var midpoint = (previous.x + target.x) / 2.0;
+ ctx.lineTo(midpoint, previous.y);
+ ctx.lineTo(midpoint, target.y);
+ } else if (mode === 'after' !== !!flip) {
+ ctx.lineTo(previous.x, target.y);
+ } else {
+ ctx.lineTo(target.x, previous.y);
+ }
+ ctx.lineTo(target.x, target.y);
+ }
+ /**
+ * @private
+ */
+ function _bezierCurveTo(ctx, previous, target, flip) {
+ if (!previous) {
+ return ctx.lineTo(target.x, target.y);
+ }
+ ctx.bezierCurveTo(flip ? previous.cp1x : previous.cp2x, flip ? previous.cp1y : previous.cp2y, flip ? target.cp2x : target.cp1x, flip ? target.cp2y : target.cp1y, target.x, target.y);
+ }
+ function setRenderOpts(ctx, opts) {
+ if (opts.translation) {
+ ctx.translate(opts.translation[0], opts.translation[1]);
+ }
+ if (!isNullOrUndef(opts.rotation)) {
+ ctx.rotate(opts.rotation);
+ }
+ if (opts.color) {
+ ctx.fillStyle = opts.color;
+ }
+ if (opts.textAlign) {
+ ctx.textAlign = opts.textAlign;
+ }
+ if (opts.textBaseline) {
+ ctx.textBaseline = opts.textBaseline;
+ }
+ }
+ function decorateText(ctx, x, y, line, opts) {
+ if (opts.strikethrough || opts.underline) {
+ /**
+ * Now that IE11 support has been dropped, we can use more
+ * of the TextMetrics object. The actual bounding boxes
+ * are unflagged in Chrome, Firefox, Edge, and Safari so they
+ * can be safely used.
+ * See https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics#Browser_compatibility
+ */
+ var metrics = ctx.measureText(line);
+ var left = x - metrics.actualBoundingBoxLeft;
+ var right = x + metrics.actualBoundingBoxRight;
+ var top = y - metrics.actualBoundingBoxAscent;
+ var bottom = y + metrics.actualBoundingBoxDescent;
+ var yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
+ ctx.strokeStyle = ctx.fillStyle;
+ ctx.beginPath();
+ ctx.lineWidth = opts.decorationWidth || 2;
+ ctx.moveTo(left, yDecoration);
+ ctx.lineTo(right, yDecoration);
+ ctx.stroke();
+ }
+ }
+ function drawBackdrop(ctx, opts) {
+ var oldColor = ctx.fillStyle;
+ ctx.fillStyle = opts.color;
+ ctx.fillRect(opts.left, opts.top, opts.width, opts.height);
+ ctx.fillStyle = oldColor;
+ }
+ /**
+ * Render text onto the canvas
+ */
+ function renderText(ctx, text, x, y, font) {
+ var opts = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
+ var lines = isArray(text) ? text : [text];
+ var stroke = opts.strokeWidth > 0 && opts.strokeColor !== '';
+ var i, line;
+ ctx.save();
+ ctx.font = font.string;
+ setRenderOpts(ctx, opts);
+ for (i = 0; i < lines.length; ++i) {
+ line = lines[i];
+ if (opts.backdrop) {
+ drawBackdrop(ctx, opts.backdrop);
+ }
+ if (stroke) {
+ if (opts.strokeColor) {
+ ctx.strokeStyle = opts.strokeColor;
+ }
+ if (!isNullOrUndef(opts.strokeWidth)) {
+ ctx.lineWidth = opts.strokeWidth;
+ }
+ ctx.strokeText(line, x, y, opts.maxWidth);
+ }
+ ctx.fillText(line, x, y, opts.maxWidth);
+ decorateText(ctx, x, y, line, opts);
+ y += Number(font.lineHeight);
+ }
+ ctx.restore();
+ }
+ /**
+ * Add a path of a rectangle with rounded corners to the current sub-path
+ * @param ctx - Context
+ * @param rect - Bounding rect
+ */
+ function addRoundedRectPath(ctx, rect) {
+ var x = rect.x,
+ y = rect.y,
+ w = rect.w,
+ h = rect.h,
+ radius = rect.radius;
+ // top left arc
+ ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, 1.5 * PI, PI, true);
+ // line from top left to bottom left
+ ctx.lineTo(x, y + h - radius.bottomLeft);
+ // bottom left arc
+ ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true);
+ // line from bottom left to bottom right
+ ctx.lineTo(x + w - radius.bottomRight, y + h);
+ // bottom right arc
+ ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true);
+ // line from bottom right to top right
+ ctx.lineTo(x + w, y + radius.topRight);
+ // top right arc
+ ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true);
+ // line from top right to top left
+ ctx.lineTo(x + radius.topLeft, y);
+ }
+ var LINE_HEIGHT = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/;
+ var FONT_STYLE = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;
+ /**
+ * @alias Chart.helpers.options
+ * @namespace
+ */ /**
+ * Converts the given line height `value` in pixels for a specific font `size`.
+ * @param value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').
+ * @param size - The font size (in pixels) used to resolve relative `value`.
+ * @returns The effective line height in pixels (size * 1.2 if value is invalid).
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
+ * @since 2.7.0
+ */
+ function toLineHeight(value, size) {
+ var matches = ('' + value).match(LINE_HEIGHT);
+ if (!matches || matches[1] === 'normal') {
+ return size * 1.2;
+ }
+ value = +matches[2];
+ switch (matches[3]) {
+ case 'px':
+ return value;
+ case '%':
+ value /= 100;
+ break;
+ }
+ return size * value;
+ }
+ var numberOrZero = function numberOrZero(v) {
+ return +v || 0;
+ };
+ function _readValueToProps(value, props) {
+ var ret = {};
+ var objProps = isObject(props);
+ var keys = objProps ? Object.keys(props) : props;
+ var read = isObject(value) ? objProps ? function (prop) {
+ return valueOrDefault(value[prop], value[props[prop]]);
+ } : function (prop) {
+ return value[prop];
+ } : function () {
+ return value;
+ };
+ var _iterator4 = _createForOfIteratorHelper$1(keys),
+ _step4;
+ try {
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
+ var prop = _step4.value;
+ ret[prop] = numberOrZero(read(prop));
+ }
+ } catch (err) {
+ _iterator4.e(err);
+ } finally {
+ _iterator4.f();
+ }
+ return ret;
+ }
+ /**
+ * Converts the given value into a TRBL object.
+ * @param value - If a number, set the value to all TRBL component,
+ * else, if an object, use defined properties and sets undefined ones to 0.
+ * x / y are shorthands for same value for left/right and top/bottom.
+ * @returns The padding values (top, right, bottom, left)
+ * @since 3.0.0
+ */
+ function toTRBL(value) {
+ return _readValueToProps(value, {
+ top: 'y',
+ right: 'x',
+ bottom: 'y',
+ left: 'x'
+ });
+ }
+ /**
+ * Converts the given value into a TRBL corners object (similar with css border-radius).
+ * @param value - If a number, set the value to all TRBL corner components,
+ * else, if an object, use defined properties and sets undefined ones to 0.
+ * @returns The TRBL corner values (topLeft, topRight, bottomLeft, bottomRight)
+ * @since 3.0.0
+ */
+ function toTRBLCorners(value) {
+ return _readValueToProps(value, ['topLeft', 'topRight', 'bottomLeft', 'bottomRight']);
+ }
+ /**
+ * Converts the given value into a padding object with pre-computed width/height.
+ * @param value - If a number, set the value to all TRBL component,
+ * else, if an object, use defined properties and sets undefined ones to 0.
+ * x / y are shorthands for same value for left/right and top/bottom.
+ * @returns The padding values (top, right, bottom, left, width, height)
+ * @since 2.7.0
+ */
+ function toPadding(value) {
+ var obj = toTRBL(value);
+ obj.width = obj.left + obj.right;
+ obj.height = obj.top + obj.bottom;
+ return obj;
+ }
+ /**
+ * Parses font options and returns the font object.
+ * @param options - A object that contains font options to be parsed.
+ * @param fallback - A object that contains fallback font options.
+ * @return The font object.
+ * @private
+ */
+ function toFont(options, fallback) {
+ options = options || {};
+ fallback = fallback || defaults.font;
+ var size = valueOrDefault(options.size, fallback.size);
+ if (typeof size === 'string') {
+ size = parseInt(size, 10);
+ }
+ var style = valueOrDefault(options.style, fallback.style);
+ if (style && !('' + style).match(FONT_STYLE)) {
+ console.warn('Invalid font style specified: "' + style + '"');
+ style = undefined;
+ }
+ var font = {
+ family: valueOrDefault(options.family, fallback.family),
+ lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size),
+ size: size,
+ style: style,
+ weight: valueOrDefault(options.weight, fallback.weight),
+ string: ''
+ };
+ font.string = toFontString(font);
+ return font;
+ }
+ /**
+ * Evaluates the given `inputs` sequentially and returns the first defined value.
+ * @param inputs - An array of values, falling back to the last value.
+ * @param context - If defined and the current value is a function, the value
+ * is called with `context` as first argument and the result becomes the new input.
+ * @param index - If defined and the current value is an array, the value
+ * at `index` become the new input.
+ * @param info - object to return information about resolution in
+ * @param info.cacheable - Will be set to `false` if option is not cacheable.
+ * @since 2.7.0
+ */
+ function resolve(inputs, context, index, info) {
+ var cacheable = true;
+ var i, ilen, value;
+ for (i = 0, ilen = inputs.length; i < ilen; ++i) {
+ value = inputs[i];
+ if (value === undefined) {
+ continue;
+ }
+ if (context !== undefined && typeof value === 'function') {
+ value = value(context);
+ cacheable = false;
+ }
+ if (index !== undefined && isArray(value)) {
+ value = value[index % value.length];
+ cacheable = false;
+ }
+ if (value !== undefined) {
+ if (info && !cacheable) {
+ info.cacheable = false;
+ }
+ return value;
+ }
+ }
+ }
+ /**
+ * @param minmax
+ * @param grace
+ * @param beginAtZero
+ * @private
+ */
+ function _addGrace(minmax, grace, beginAtZero) {
+ var min = minmax.min,
+ max = minmax.max;
+ var change = toDimension(grace, (max - min) / 2);
+ var keepZero = function keepZero(value, add) {
+ return beginAtZero && value === 0 ? 0 : value + add;
+ };
+ return {
+ min: keepZero(min, -Math.abs(change)),
+ max: keepZero(max, change)
+ };
+ }
+ function createContext(parentContext, context) {
+ return Object.assign(Object.create(parentContext), context);
+ }
+
+ /**
+ * Creates a Proxy for resolving raw values for options.
+ * @param scopes - The option scopes to look for values, in resolution order
+ * @param prefixes - The prefixes for values, in resolution order.
+ * @param rootScopes - The root option scopes
+ * @param fallback - Parent scopes fallback
+ * @param getTarget - callback for getting the target for changed values
+ * @returns Proxy
+ * @private
+ */
+ function _createResolver(scopes) {
+ var prefixes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [''];
+ var rootScopes = arguments.length > 2 ? arguments[2] : undefined;
+ var fallback = arguments.length > 3 ? arguments[3] : undefined;
+ var getTarget = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : function () {
+ return scopes[0];
+ };
+ var finalRootScopes = rootScopes || scopes;
+ if (typeof fallback === 'undefined') {
+ fallback = _resolve('_fallback', scopes);
+ }
+ var cache = _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1({}, Symbol.toStringTag, 'Object'), "_cacheable", true), "_scopes", scopes), "_rootScopes", finalRootScopes), "_fallback", fallback), "_getTarget", getTarget), "override", function override(scope) {
+ return _createResolver([scope].concat(_toConsumableArray(scopes)), prefixes, finalRootScopes, fallback);
+ });
+ return new Proxy(cache, {
+ /**
+ * A trap for the delete operator.
+ */
+ deleteProperty: function deleteProperty(target, prop) {
+ delete target[prop]; // remove from cache
+ delete target._keys; // remove cached keys
+ delete scopes[0][prop]; // remove from top level scope
+ return true;
+ },
+ /**
+ * A trap for getting property values.
+ */
+ get: function get(target, prop) {
+ return _cached(target, prop, function () {
+ return _resolveWithPrefixes(prop, prefixes, scopes, target);
+ });
+ },
+ /**
+ * A trap for Object.getOwnPropertyDescriptor.
+ * Also used by Object.hasOwnProperty.
+ */
+ getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, prop) {
+ return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop);
+ },
+ /**
+ * A trap for Object.getPrototypeOf.
+ */
+ getPrototypeOf: function getPrototypeOf() {
+ return Reflect.getPrototypeOf(scopes[0]);
+ },
+ /**
+ * A trap for the in operator.
+ */
+ has: function has(target, prop) {
+ return getKeysFromAllScopes(target).includes(prop);
+ },
+ /**
+ * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols.
+ */
+ ownKeys: function ownKeys(target) {
+ return getKeysFromAllScopes(target);
+ },
+ /**
+ * A trap for setting property values.
+ */
+ set: function set(target, prop, value) {
+ var storage = target._storage || (target._storage = getTarget());
+ target[prop] = storage[prop] = value; // set to top level scope + cache
+ delete target._keys; // remove cached keys
+ return true;
+ }
+ });
+ }
+ /**
+ * Returns an Proxy for resolving option values with context.
+ * @param proxy - The Proxy returned by `_createResolver`
+ * @param context - Context object for scriptable/indexable options
+ * @param subProxy - The proxy provided for scriptable options
+ * @param descriptorDefaults - Defaults for descriptors
+ * @private
+ */
+ function _attachContext(proxy, context, subProxy, descriptorDefaults) {
+ var cache = {
+ _cacheable: false,
+ _proxy: proxy,
+ _context: context,
+ _subProxy: subProxy,
+ _stack: new Set(),
+ _descriptors: _descriptors(proxy, descriptorDefaults),
+ setContext: function setContext(ctx) {
+ return _attachContext(proxy, ctx, subProxy, descriptorDefaults);
+ },
+ override: function override(scope) {
+ return _attachContext(proxy.override(scope), context, subProxy, descriptorDefaults);
+ }
+ };
+ return new Proxy(cache, {
+ /**
+ * A trap for the delete operator.
+ */
+ deleteProperty: function deleteProperty(target, prop) {
+ delete target[prop]; // remove from cache
+ delete proxy[prop]; // remove from proxy
+ return true;
+ },
+ /**
+ * A trap for getting property values.
+ */
+ get: function get(target, prop, receiver) {
+ return _cached(target, prop, function () {
+ return _resolveWithContext(target, prop, receiver);
+ });
+ },
+ /**
+ * A trap for Object.getOwnPropertyDescriptor.
+ * Also used by Object.hasOwnProperty.
+ */
+ getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, prop) {
+ return target._descriptors.allKeys ? Reflect.has(proxy, prop) ? {
+ enumerable: true,
+ configurable: true
+ } : undefined : Reflect.getOwnPropertyDescriptor(proxy, prop);
+ },
+ /**
+ * A trap for Object.getPrototypeOf.
+ */
+ getPrototypeOf: function getPrototypeOf() {
+ return Reflect.getPrototypeOf(proxy);
+ },
+ /**
+ * A trap for the in operator.
+ */
+ has: function has(target, prop) {
+ return Reflect.has(proxy, prop);
+ },
+ /**
+ * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols.
+ */
+ ownKeys: function ownKeys() {
+ return Reflect.ownKeys(proxy);
+ },
+ /**
+ * A trap for setting property values.
+ */
+ set: function set(target, prop, value) {
+ proxy[prop] = value; // set to proxy
+ delete target[prop]; // remove from cache
+ return true;
+ }
+ });
+ }
+ /**
+ * @private
+ */
+ function _descriptors(proxy) {
+ var defaults = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
+ scriptable: true,
+ indexable: true
+ };
+ var _proxy$_scriptable = proxy._scriptable,
+ _scriptable = _proxy$_scriptable === void 0 ? defaults.scriptable : _proxy$_scriptable,
+ _proxy$_indexable = proxy._indexable,
+ _indexable = _proxy$_indexable === void 0 ? defaults.indexable : _proxy$_indexable,
+ _proxy$_allKeys = proxy._allKeys,
+ _allKeys = _proxy$_allKeys === void 0 ? defaults.allKeys : _proxy$_allKeys;
+ return {
+ allKeys: _allKeys,
+ scriptable: _scriptable,
+ indexable: _indexable,
+ isScriptable: isFunction(_scriptable) ? _scriptable : function () {
+ return _scriptable;
+ },
+ isIndexable: isFunction(_indexable) ? _indexable : function () {
+ return _indexable;
+ }
+ };
+ }
+ var readKey = function readKey(prefix, name) {
+ return prefix ? prefix + _capitalize(name) : name;
+ };
+ var needsSubResolver = function needsSubResolver(prop, value) {
+ return isObject(value) && prop !== 'adapters' && (Object.getPrototypeOf(value) === null || value.constructor === Object);
+ };
+ function _cached(target, prop, resolve) {
+ if (Object.prototype.hasOwnProperty.call(target, prop) || prop === 'constructor') {
+ return target[prop];
+ }
+ var value = resolve();
+ // cache the resolved value
+ target[prop] = value;
+ return value;
+ }
+ function _resolveWithContext(target, prop, receiver) {
+ var _proxy = target._proxy,
+ _context = target._context,
+ _subProxy = target._subProxy,
+ descriptors = target._descriptors;
+ var value = _proxy[prop]; // resolve from proxy
+ // resolve with context
+ if (isFunction(value) && descriptors.isScriptable(prop)) {
+ value = _resolveScriptable(prop, value, target, receiver);
+ }
+ if (isArray(value) && value.length) {
+ value = _resolveArray(prop, value, target, descriptors.isIndexable);
+ }
+ if (needsSubResolver(prop, value)) {
+ // if the resolved value is an object, create a sub resolver for it
+ value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors);
+ }
+ return value;
+ }
+ function _resolveScriptable(prop, getValue, target, receiver) {
+ var _proxy = target._proxy,
+ _context = target._context,
+ _subProxy = target._subProxy,
+ _stack = target._stack;
+ if (_stack.has(prop)) {
+ throw new Error('Recursion detected: ' + Array.from(_stack).join('->') + '->' + prop);
+ }
+ _stack.add(prop);
+ var value = getValue(_context, _subProxy || receiver);
+ _stack["delete"](prop);
+ if (needsSubResolver(prop, value)) {
+ // When scriptable option returns an object, create a resolver on that.
+ value = createSubResolver(_proxy._scopes, _proxy, prop, value);
+ }
+ return value;
+ }
+ function _resolveArray(prop, value, target, isIndexable) {
+ var _proxy = target._proxy,
+ _context = target._context,
+ _subProxy = target._subProxy,
+ descriptors = target._descriptors;
+ if (typeof _context.index !== 'undefined' && isIndexable(prop)) {
+ return value[_context.index % value.length];
+ } else if (isObject(value[0])) {
+ // Array of objects, return array or resolvers
+ var arr = value;
+ var scopes = _proxy._scopes.filter(function (s) {
+ return s !== arr;
+ });
+ value = [];
+ var _iterator5 = _createForOfIteratorHelper$1(arr),
+ _step5;
+ try {
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
+ var item = _step5.value;
+ var resolver = createSubResolver(scopes, _proxy, prop, item);
+ value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors));
+ }
+ } catch (err) {
+ _iterator5.e(err);
+ } finally {
+ _iterator5.f();
+ }
+ }
+ return value;
+ }
+ function resolveFallback(fallback, prop, value) {
+ return isFunction(fallback) ? fallback(prop, value) : fallback;
+ }
+ var getScope = function getScope(key, parent) {
+ return key === true ? parent : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;
+ };
+ function addScopes(set, parentScopes, key, parentFallback, value) {
+ var _iterator6 = _createForOfIteratorHelper$1(parentScopes),
+ _step6;
+ try {
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
+ var parent = _step6.value;
+ var scope = getScope(key, parent);
+ if (scope) {
+ set.add(scope);
+ var fallback = resolveFallback(scope._fallback, key, value);
+ if (typeof fallback !== 'undefined' && fallback !== key && fallback !== parentFallback) {
+ // When we reach the descriptor that defines a new _fallback, return that.
+ // The fallback will resume to that new scope.
+ return fallback;
+ }
+ } else if (scope === false && typeof parentFallback !== 'undefined' && key !== parentFallback) {
+ // Fallback to `false` results to `false`, when falling back to different key.
+ // For example `interaction` from `hover` or `plugins.tooltip` and `animation` from `animations`
+ return null;
+ }
+ }
+ } catch (err) {
+ _iterator6.e(err);
+ } finally {
+ _iterator6.f();
+ }
+ return false;
+ }
+ function createSubResolver(parentScopes, resolver, prop, value) {
+ var rootScopes = resolver._rootScopes;
+ var fallback = resolveFallback(resolver._fallback, prop, value);
+ var allScopes = [].concat(_toConsumableArray(parentScopes), _toConsumableArray(rootScopes));
+ var set = new Set();
+ set.add(value);
+ var key = addScopesFromKey(set, allScopes, prop, fallback || prop, value);
+ if (key === null) {
+ return false;
+ }
+ if (typeof fallback !== 'undefined' && fallback !== prop) {
+ key = addScopesFromKey(set, allScopes, fallback, key, value);
+ if (key === null) {
+ return false;
+ }
+ }
+ return _createResolver(Array.from(set), [''], rootScopes, fallback, function () {
+ return subGetTarget(resolver, prop, value);
+ });
+ }
+ function addScopesFromKey(set, allScopes, key, fallback, item) {
+ while (key) {
+ key = addScopes(set, allScopes, key, fallback, item);
+ }
+ return key;
+ }
+ function subGetTarget(resolver, prop, value) {
+ var parent = resolver._getTarget();
+ if (!(prop in parent)) {
+ parent[prop] = {};
+ }
+ var target = parent[prop];
+ if (isArray(target) && isObject(value)) {
+ // For array of objects, the object is used to store updated values
+ return value;
+ }
+ return target || {};
+ }
+ function _resolveWithPrefixes(prop, prefixes, scopes, proxy) {
+ var value;
+ var _iterator7 = _createForOfIteratorHelper$1(prefixes),
+ _step7;
+ try {
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
+ var prefix = _step7.value;
+ value = _resolve(readKey(prefix, prop), scopes);
+ if (typeof value !== 'undefined') {
+ return needsSubResolver(prop, value) ? createSubResolver(scopes, proxy, prop, value) : value;
+ }
+ }
+ } catch (err) {
+ _iterator7.e(err);
+ } finally {
+ _iterator7.f();
+ }
+ }
+ function _resolve(key, scopes) {
+ var _iterator8 = _createForOfIteratorHelper$1(scopes),
+ _step8;
+ try {
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
+ var scope = _step8.value;
+ if (!scope) {
+ continue;
+ }
+ var value = scope[key];
+ if (typeof value !== 'undefined') {
+ return value;
+ }
+ }
+ } catch (err) {
+ _iterator8.e(err);
+ } finally {
+ _iterator8.f();
+ }
+ }
+ function getKeysFromAllScopes(target) {
+ var keys = target._keys;
+ if (!keys) {
+ keys = target._keys = resolveKeysFromAllScopes(target._scopes);
+ }
+ return keys;
+ }
+ function resolveKeysFromAllScopes(scopes) {
+ var set = new Set();
+ var _iterator9 = _createForOfIteratorHelper$1(scopes),
+ _step9;
+ try {
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
+ var scope = _step9.value;
+ var _iterator10 = _createForOfIteratorHelper$1(Object.keys(scope).filter(function (k) {
+ return !k.startsWith('_');
+ })),
+ _step10;
+ try {
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
+ var key = _step10.value;
+ set.add(key);
+ }
+ } catch (err) {
+ _iterator10.e(err);
+ } finally {
+ _iterator10.f();
+ }
+ }
+ } catch (err) {
+ _iterator9.e(err);
+ } finally {
+ _iterator9.f();
+ }
+ return Array.from(set);
+ }
+ function _parseObjectDataRadialScale(meta, data, start, count) {
+ var iScale = meta.iScale;
+ var _this$_parsing$key = this._parsing.key,
+ key = _this$_parsing$key === void 0 ? 'r' : _this$_parsing$key;
+ var parsed = new Array(count);
+ var i, ilen, index, item;
+ for (i = 0, ilen = count; i < ilen; ++i) {
+ index = i + start;
+ item = data[index];
+ parsed[i] = {
+ r: iScale.parse(resolveObjectKey(item, key), index)
+ };
+ }
+ return parsed;
+ }
+ var EPSILON = Number.EPSILON || 1e-14;
+ var getPoint = function getPoint(points, i) {
+ return i < points.length && !points[i].skip && points[i];
+ };
+ var getValueAxis = function getValueAxis(indexAxis) {
+ return indexAxis === 'x' ? 'y' : 'x';
+ };
+ function splineCurve(firstPoint, middlePoint, afterPoint, t) {
+ // Props to Rob Spencer at scaled innovation for his post on splining between points
+ // http://scaledinnovation.com/analytics/splines/aboutSplines.html
+ // This function must also respect "skipped" points
+ var previous = firstPoint.skip ? middlePoint : firstPoint;
+ var current = middlePoint;
+ var next = afterPoint.skip ? middlePoint : afterPoint;
+ var d01 = distanceBetweenPoints(current, previous);
+ var d12 = distanceBetweenPoints(next, current);
+ var s01 = d01 / (d01 + d12);
+ var s12 = d12 / (d01 + d12);
+ // If all points are the same, s01 & s02 will be inf
+ s01 = isNaN(s01) ? 0 : s01;
+ s12 = isNaN(s12) ? 0 : s12;
+ var fa = t * s01; // scaling factor for triangle Ta
+ var fb = t * s12;
+ return {
+ previous: {
+ x: current.x - fa * (next.x - previous.x),
+ y: current.y - fa * (next.y - previous.y)
+ },
+ next: {
+ x: current.x + fb * (next.x - previous.x),
+ y: current.y + fb * (next.y - previous.y)
+ }
+ };
+ }
+ /**
+ * Adjust tangents to ensure monotonic properties
+ */
+ function monotoneAdjust(points, deltaK, mK) {
+ var pointsLen = points.length;
+ var alphaK, betaK, tauK, squaredMagnitude, pointCurrent;
+ var pointAfter = getPoint(points, 0);
+ for (var i = 0; i < pointsLen - 1; ++i) {
+ pointCurrent = pointAfter;
+ pointAfter = getPoint(points, i + 1);
+ if (!pointCurrent || !pointAfter) {
+ continue;
+ }
+ if (almostEquals(deltaK[i], 0, EPSILON)) {
+ mK[i] = mK[i + 1] = 0;
+ continue;
+ }
+ alphaK = mK[i] / deltaK[i];
+ betaK = mK[i + 1] / deltaK[i];
+ squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
+ if (squaredMagnitude <= 9) {
+ continue;
+ }
+ tauK = 3 / Math.sqrt(squaredMagnitude);
+ mK[i] = alphaK * tauK * deltaK[i];
+ mK[i + 1] = betaK * tauK * deltaK[i];
+ }
+ }
+ function monotoneCompute(points, mK) {
+ var indexAxis = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'x';
+ var valueAxis = getValueAxis(indexAxis);
+ var pointsLen = points.length;
+ var delta, pointBefore, pointCurrent;
+ var pointAfter = getPoint(points, 0);
+ for (var i = 0; i < pointsLen; ++i) {
+ pointBefore = pointCurrent;
+ pointCurrent = pointAfter;
+ pointAfter = getPoint(points, i + 1);
+ if (!pointCurrent) {
+ continue;
+ }
+ var iPixel = pointCurrent[indexAxis];
+ var vPixel = pointCurrent[valueAxis];
+ if (pointBefore) {
+ delta = (iPixel - pointBefore[indexAxis]) / 3;
+ pointCurrent["cp1".concat(indexAxis)] = iPixel - delta;
+ pointCurrent["cp1".concat(valueAxis)] = vPixel - delta * mK[i];
+ }
+ if (pointAfter) {
+ delta = (pointAfter[indexAxis] - iPixel) / 3;
+ pointCurrent["cp2".concat(indexAxis)] = iPixel + delta;
+ pointCurrent["cp2".concat(valueAxis)] = vPixel + delta * mK[i];
+ }
+ }
+ }
+ /**
+ * This function calculates Bézier control points in a similar way than |splineCurve|,
+ * but preserves monotonicity of the provided data and ensures no local extremums are added
+ * between the dataset discrete points due to the interpolation.
+ * See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
+ */
+ function splineCurveMonotone(points) {
+ var indexAxis = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'x';
+ var valueAxis = getValueAxis(indexAxis);
+ var pointsLen = points.length;
+ var deltaK = Array(pointsLen).fill(0);
+ var mK = Array(pointsLen);
+ // Calculate slopes (deltaK) and initialize tangents (mK)
+ var i, pointBefore, pointCurrent;
+ var pointAfter = getPoint(points, 0);
+ for (i = 0; i < pointsLen; ++i) {
+ pointBefore = pointCurrent;
+ pointCurrent = pointAfter;
+ pointAfter = getPoint(points, i + 1);
+ if (!pointCurrent) {
+ continue;
+ }
+ if (pointAfter) {
+ var slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis];
+ // In the case of two points that appear at the same x pixel, slopeDeltaX is 0
+ deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0;
+ }
+ mK[i] = !pointBefore ? deltaK[i] : !pointAfter ? deltaK[i - 1] : sign(deltaK[i - 1]) !== sign(deltaK[i]) ? 0 : (deltaK[i - 1] + deltaK[i]) / 2;
+ }
+ monotoneAdjust(points, deltaK, mK);
+ monotoneCompute(points, mK, indexAxis);
+ }
+ function capControlPoint(pt, min, max) {
+ return Math.max(Math.min(pt, max), min);
+ }
+ function capBezierPoints(points, area) {
+ var i, ilen, point, inArea, inAreaPrev;
+ var inAreaNext = _isPointInArea(points[0], area);
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ inAreaPrev = inArea;
+ inArea = inAreaNext;
+ inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area);
+ if (!inArea) {
+ continue;
+ }
+ point = points[i];
+ if (inAreaPrev) {
+ point.cp1x = capControlPoint(point.cp1x, area.left, area.right);
+ point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom);
+ }
+ if (inAreaNext) {
+ point.cp2x = capControlPoint(point.cp2x, area.left, area.right);
+ point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom);
+ }
+ }
+ }
+ /**
+ * @private
+ */
+ function _updateBezierControlPoints(points, options, area, loop, indexAxis) {
+ var i, ilen, point, controlPoints;
+ // Only consider points that are drawn in case the spanGaps option is used
+ if (options.spanGaps) {
+ points = points.filter(function (pt) {
+ return !pt.skip;
+ });
+ }
+ if (options.cubicInterpolationMode === 'monotone') {
+ splineCurveMonotone(points, indexAxis);
+ } else {
+ var prev = loop ? points[points.length - 1] : points[0];
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ point = points[i];
+ controlPoints = splineCurve(prev, point, points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen], options.tension);
+ point.cp1x = controlPoints.previous.x;
+ point.cp1y = controlPoints.previous.y;
+ point.cp2x = controlPoints.next.x;
+ point.cp2y = controlPoints.next.y;
+ prev = point;
+ }
+ }
+ if (options.capBezierPoints) {
+ capBezierPoints(points, area);
+ }
+ }
+
+ /**
+ * @private
+ */
+ function _isDomSupported() {
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
+ }
+ /**
+ * @private
+ */
+ function _getParentNode(domNode) {
+ var parent = domNode.parentNode;
+ if (parent && parent.toString() === '[object ShadowRoot]') {
+ parent = parent.host;
+ }
+ return parent;
+ }
+ /**
+ * convert max-width/max-height values that may be percentages into a number
+ * @private
+ */
+ function parseMaxStyle(styleValue, node, parentProperty) {
+ var valueInPixels;
+ if (typeof styleValue === 'string') {
+ valueInPixels = parseInt(styleValue, 10);
+ if (styleValue.indexOf('%') !== -1) {
+ // percentage * size in dimension
+ valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
+ }
+ } else {
+ valueInPixels = styleValue;
+ }
+ return valueInPixels;
+ }
+ var getComputedStyle = function getComputedStyle(element) {
+ return element.ownerDocument.defaultView.getComputedStyle(element, null);
+ };
+ function getStyle(el, property) {
+ return getComputedStyle(el).getPropertyValue(property);
+ }
+ var positions = ['top', 'right', 'bottom', 'left'];
+ function getPositionedStyle(styles, style, suffix) {
+ var result = {};
+ suffix = suffix ? '-' + suffix : '';
+ for (var i = 0; i < 4; i++) {
+ var pos = positions[i];
+ result[pos] = parseFloat(styles[style + '-' + pos + suffix]) || 0;
+ }
+ result.width = result.left + result.right;
+ result.height = result.top + result.bottom;
+ return result;
+ }
+ var useOffsetPos = function useOffsetPos(x, y, target) {
+ return (x > 0 || y > 0) && (!target || !target.shadowRoot);
+ };
+ /**
+ * @param e
+ * @param canvas
+ * @returns Canvas position
+ */
+ function getCanvasPosition(e, canvas) {
+ var touches = e.touches;
+ var source = touches && touches.length ? touches[0] : e;
+ var offsetX = source.offsetX,
+ offsetY = source.offsetY;
+ var box = false;
+ var x, y;
+ if (useOffsetPos(offsetX, offsetY, e.target)) {
+ x = offsetX;
+ y = offsetY;
+ } else {
+ var rect = canvas.getBoundingClientRect();
+ x = source.clientX - rect.left;
+ y = source.clientY - rect.top;
+ box = true;
+ }
+ return {
+ x: x,
+ y: y,
+ box: box
+ };
+ }
+ /**
+ * Gets an event's x, y coordinates, relative to the chart area
+ * @param event
+ * @param chart
+ * @returns x and y coordinates of the event
+ */
+ function getRelativePosition(event, chart) {
+ if ('native' in event) {
+ return event;
+ }
+ var canvas = chart.canvas,
+ currentDevicePixelRatio = chart.currentDevicePixelRatio;
+ var style = getComputedStyle(canvas);
+ var borderBox = style.boxSizing === 'border-box';
+ var paddings = getPositionedStyle(style, 'padding');
+ var borders = getPositionedStyle(style, 'border', 'width');
+ var _getCanvasPosition = getCanvasPosition(event, canvas),
+ x = _getCanvasPosition.x,
+ y = _getCanvasPosition.y,
+ box = _getCanvasPosition.box;
+ var xOffset = paddings.left + (box && borders.left);
+ var yOffset = paddings.top + (box && borders.top);
+ var width = chart.width,
+ height = chart.height;
+ if (borderBox) {
+ width -= paddings.width + borders.width;
+ height -= paddings.height + borders.height;
+ }
+ return {
+ x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio),
+ y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio)
+ };
+ }
+ function getContainerSize(canvas, width, height) {
+ var maxWidth, maxHeight;
+ if (width === undefined || height === undefined) {
+ var container = canvas && _getParentNode(canvas);
+ if (!container) {
+ width = canvas.clientWidth;
+ height = canvas.clientHeight;
+ } else {
+ var rect = container.getBoundingClientRect(); // this is the border box of the container
+ var containerStyle = getComputedStyle(container);
+ var containerBorder = getPositionedStyle(containerStyle, 'border', 'width');
+ var containerPadding = getPositionedStyle(containerStyle, 'padding');
+ width = rect.width - containerPadding.width - containerBorder.width;
+ height = rect.height - containerPadding.height - containerBorder.height;
+ maxWidth = parseMaxStyle(containerStyle.maxWidth, container, 'clientWidth');
+ maxHeight = parseMaxStyle(containerStyle.maxHeight, container, 'clientHeight');
+ }
+ }
+ return {
+ width: width,
+ height: height,
+ maxWidth: maxWidth || INFINITY,
+ maxHeight: maxHeight || INFINITY
+ };
+ }
+ var round1 = function round1(v) {
+ return Math.round(v * 10) / 10;
+ };
+ // eslint-disable-next-line complexity
+ function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) {
+ var style = getComputedStyle(canvas);
+ var margins = getPositionedStyle(style, 'margin');
+ var maxWidth = parseMaxStyle(style.maxWidth, canvas, 'clientWidth') || INFINITY;
+ var maxHeight = parseMaxStyle(style.maxHeight, canvas, 'clientHeight') || INFINITY;
+ var containerSize = getContainerSize(canvas, bbWidth, bbHeight);
+ var width = containerSize.width,
+ height = containerSize.height;
+ if (style.boxSizing === 'content-box') {
+ var borders = getPositionedStyle(style, 'border', 'width');
+ var paddings = getPositionedStyle(style, 'padding');
+ width -= paddings.width + borders.width;
+ height -= paddings.height + borders.height;
+ }
+ width = Math.max(0, width - margins.width);
+ height = Math.max(0, aspectRatio ? width / aspectRatio : height - margins.height);
+ width = round1(Math.min(width, maxWidth, containerSize.maxWidth));
+ height = round1(Math.min(height, maxHeight, containerSize.maxHeight));
+ if (width && !height) {
+ // https://github.com/chartjs/Chart.js/issues/4659
+ // If the canvas has width, but no height, default to aspectRatio of 2 (canvas default)
+ height = round1(width / 2);
+ }
+ var maintainHeight = bbWidth !== undefined || bbHeight !== undefined;
+ if (maintainHeight && aspectRatio && containerSize.height && height > containerSize.height) {
+ height = containerSize.height;
+ width = round1(Math.floor(height * aspectRatio));
+ }
+ return {
+ width: width,
+ height: height
+ };
+ }
+ /**
+ * @param chart
+ * @param forceRatio
+ * @param forceStyle
+ * @returns True if the canvas context size or transformation has changed.
+ */
+ function retinaScale(chart, forceRatio, forceStyle) {
+ var pixelRatio = forceRatio || 1;
+ var deviceHeight = Math.floor(chart.height * pixelRatio);
+ var deviceWidth = Math.floor(chart.width * pixelRatio);
+ chart.height = Math.floor(chart.height);
+ chart.width = Math.floor(chart.width);
+ var canvas = chart.canvas;
+ // If no style has been set on the canvas, the render size is used as display size,
+ // making the chart visually bigger, so let's enforce it to the "correct" values.
+ // See https://github.com/chartjs/Chart.js/issues/3575
+ if (canvas.style && (forceStyle || !canvas.style.height && !canvas.style.width)) {
+ canvas.style.height = "".concat(chart.height, "px");
+ canvas.style.width = "".concat(chart.width, "px");
+ }
+ if (chart.currentDevicePixelRatio !== pixelRatio || canvas.height !== deviceHeight || canvas.width !== deviceWidth) {
+ chart.currentDevicePixelRatio = pixelRatio;
+ canvas.height = deviceHeight;
+ canvas.width = deviceWidth;
+ chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Detects support for options object argument in addEventListener.
+ * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
+ * @private
+ */
+ var supportsEventListenerOptions = function () {
+ var passiveSupported = false;
+ try {
+ var options = {
+ get passive() {
+ passiveSupported = true;
+ return false;
+ }
+ };
+ if (_isDomSupported()) {
+ window.addEventListener('test', null, options);
+ window.removeEventListener('test', null, options);
+ }
+ } catch (e) {
+ // continue regardless of error
+ }
+ return passiveSupported;
+ }();
+ /**
+ * The "used" size is the final value of a dimension property after all calculations have
+ * been performed. This method uses the computed style of `element` but returns undefined
+ * if the computed style is not expressed in pixels. That can happen in some cases where
+ * `element` has a size relative to its parent and this last one is not yet displayed,
+ * for example because of `display: none` on a parent node.
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
+ * @returns Size in pixels or undefined if unknown.
+ */
+ function readUsedSize(element, property) {
+ var value = getStyle(element, property);
+ var matches = value && value.match(/^(\d+)(\.\d+)?px$/);
+ return matches ? +matches[1] : undefined;
+ }
+
+ /**
+ * @private
+ */
+ function _pointInLine(p1, p2, t, mode) {
+ return {
+ x: p1.x + t * (p2.x - p1.x),
+ y: p1.y + t * (p2.y - p1.y)
+ };
+ }
+ /**
+ * @private
+ */
+ function _steppedInterpolation(p1, p2, t, mode) {
+ return {
+ x: p1.x + t * (p2.x - p1.x),
+ y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y : mode === 'after' ? t < 1 ? p1.y : p2.y : t > 0 ? p2.y : p1.y
+ };
+ }
+ /**
+ * @private
+ */
+ function _bezierInterpolation(p1, p2, t, mode) {
+ var cp1 = {
+ x: p1.cp2x,
+ y: p1.cp2y
+ };
+ var cp2 = {
+ x: p2.cp1x,
+ y: p2.cp1y
+ };
+ var a = _pointInLine(p1, cp1, t);
+ var b = _pointInLine(cp1, cp2, t);
+ var c = _pointInLine(cp2, p2, t);
+ var d = _pointInLine(a, b, t);
+ var e = _pointInLine(b, c, t);
+ return _pointInLine(d, e, t);
+ }
+ var getRightToLeftAdapter = function getRightToLeftAdapter(rectX, width) {
+ return {
+ x: function x(_x) {
+ return rectX + rectX + width - _x;
+ },
+ setWidth: function setWidth(w) {
+ width = w;
+ },
+ textAlign: function textAlign(align) {
+ if (align === 'center') {
+ return align;
+ }
+ return align === 'right' ? 'left' : 'right';
+ },
+ xPlus: function xPlus(x, value) {
+ return x - value;
+ },
+ leftForLtr: function leftForLtr(x, itemWidth) {
+ return x - itemWidth;
+ }
+ };
+ };
+ var getLeftToRightAdapter = function getLeftToRightAdapter() {
+ return {
+ x: function x(_x2) {
+ return _x2;
+ },
+ setWidth: function setWidth(w) {},
+ textAlign: function textAlign(align) {
+ return align;
+ },
+ xPlus: function xPlus(x, value) {
+ return x + value;
+ },
+ leftForLtr: function leftForLtr(x, _itemWidth) {
+ return x;
+ }
+ };
+ };
+ function getRtlAdapter(rtl, rectX, width) {
+ return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter();
+ }
+ function overrideTextDirection(ctx, direction) {
+ var style, original;
+ if (direction === 'ltr' || direction === 'rtl') {
+ style = ctx.canvas.style;
+ original = [style.getPropertyValue('direction'), style.getPropertyPriority('direction')];
+ style.setProperty('direction', direction, 'important');
+ ctx.prevTextDirection = original;
+ }
+ }
+ function restoreTextDirection(ctx, original) {
+ if (original !== undefined) {
+ delete ctx.prevTextDirection;
+ ctx.canvas.style.setProperty('direction', original[0], original[1]);
+ }
+ }
+ function propertyFn(property) {
+ if (property === 'angle') {
+ return {
+ between: _angleBetween,
+ compare: _angleDiff,
+ normalize: _normalizeAngle
+ };
+ }
+ return {
+ between: _isBetween,
+ compare: function compare(a, b) {
+ return a - b;
+ },
+ normalize: function normalize(x) {
+ return x;
+ }
+ };
+ }
+ function normalizeSegment(_ref) {
+ var start = _ref.start,
+ end = _ref.end,
+ count = _ref.count,
+ loop = _ref.loop,
+ style = _ref.style;
+ return {
+ start: start % count,
+ end: end % count,
+ loop: loop && (end - start + 1) % count === 0,
+ style: style
+ };
+ }
+ function getSegment(segment, points, bounds) {
+ var property = bounds.property,
+ startBound = bounds.start,
+ endBound = bounds.end;
+ var _propertyFn = propertyFn(property),
+ between = _propertyFn.between,
+ normalize = _propertyFn.normalize;
+ var count = points.length;
+ var start = segment.start,
+ end = segment.end,
+ loop = segment.loop;
+ var i, ilen;
+ if (loop) {
+ start += count;
+ end += count;
+ for (i = 0, ilen = count; i < ilen; ++i) {
+ if (!between(normalize(points[start % count][property]), startBound, endBound)) {
+ break;
+ }
+ start--;
+ end--;
+ }
+ start %= count;
+ end %= count;
+ }
+ if (end < start) {
+ end += count;
+ }
+ return {
+ start: start,
+ end: end,
+ loop: loop,
+ style: segment.style
+ };
+ }
+ function _boundSegment(segment, points, bounds) {
+ if (!bounds) {
+ return [segment];
+ }
+ var property = bounds.property,
+ startBound = bounds.start,
+ endBound = bounds.end;
+ var count = points.length;
+ var _propertyFn2 = propertyFn(property),
+ compare = _propertyFn2.compare,
+ between = _propertyFn2.between,
+ normalize = _propertyFn2.normalize;
+ var _getSegment = getSegment(segment, points, bounds),
+ start = _getSegment.start,
+ end = _getSegment.end,
+ loop = _getSegment.loop,
+ style = _getSegment.style;
+ var result = [];
+ var inside = false;
+ var subStart = null;
+ var value, point, prevValue;
+ var startIsBefore = function startIsBefore() {
+ return between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0;
+ };
+ var endIsBefore = function endIsBefore() {
+ return compare(endBound, value) === 0 || between(endBound, prevValue, value);
+ };
+ var shouldStart = function shouldStart() {
+ return inside || startIsBefore();
+ };
+ var shouldStop = function shouldStop() {
+ return !inside || endIsBefore();
+ };
+ for (var i = start, prev = start; i <= end; ++i) {
+ point = points[i % count];
+ if (point.skip) {
+ continue;
+ }
+ value = normalize(point[property]);
+ if (value === prevValue) {
+ continue;
+ }
+ inside = between(value, startBound, endBound);
+ if (subStart === null && shouldStart()) {
+ subStart = compare(value, startBound) === 0 ? i : prev;
+ }
+ if (subStart !== null && shouldStop()) {
+ result.push(normalizeSegment({
+ start: subStart,
+ end: i,
+ loop: loop,
+ count: count,
+ style: style
+ }));
+ subStart = null;
+ }
+ prev = i;
+ prevValue = value;
+ }
+ if (subStart !== null) {
+ result.push(normalizeSegment({
+ start: subStart,
+ end: end,
+ loop: loop,
+ count: count,
+ style: style
+ }));
+ }
+ return result;
+ }
+ function _boundSegments(line, bounds) {
+ var result = [];
+ var segments = line.segments;
+ for (var i = 0; i < segments.length; i++) {
+ var sub = _boundSegment(segments[i], line.points, bounds);
+ if (sub.length) {
+ result.push.apply(result, _toConsumableArray(sub));
+ }
+ }
+ return result;
+ }
+ function findStartAndEnd(points, count, loop, spanGaps) {
+ var start = 0;
+ var end = count - 1;
+ if (loop && !spanGaps) {
+ while (start < count && !points[start].skip) {
+ start++;
+ }
+ }
+ while (start < count && points[start].skip) {
+ start++;
+ }
+ start %= count;
+ if (loop) {
+ end += start;
+ }
+ while (end > start && points[end % count].skip) {
+ end--;
+ }
+ end %= count;
+ return {
+ start: start,
+ end: end
+ };
+ }
+ function solidSegments(points, start, max, loop) {
+ var count = points.length;
+ var result = [];
+ var last = start;
+ var prev = points[start];
+ var end;
+ for (end = start + 1; end <= max; ++end) {
+ var cur = points[end % count];
+ if (cur.skip || cur.stop) {
+ if (!prev.skip) {
+ loop = false;
+ result.push({
+ start: start % count,
+ end: (end - 1) % count,
+ loop: loop
+ });
+ start = last = cur.stop ? end : null;
+ }
+ } else {
+ last = end;
+ if (prev.skip) {
+ start = end;
+ }
+ }
+ prev = cur;
+ }
+ if (last !== null) {
+ result.push({
+ start: start % count,
+ end: last % count,
+ loop: loop
+ });
+ }
+ return result;
+ }
+ function _computeSegments(line, segmentOptions) {
+ var points = line.points;
+ var spanGaps = line.options.spanGaps;
+ var count = points.length;
+ if (!count) {
+ return [];
+ }
+ var loop = !!line._loop;
+ var _findStartAndEnd = findStartAndEnd(points, count, loop, spanGaps),
+ start = _findStartAndEnd.start,
+ end = _findStartAndEnd.end;
+ if (spanGaps === true) {
+ return splitByStyles(line, [{
+ start: start,
+ end: end,
+ loop: loop
+ }], points, segmentOptions);
+ }
+ var max = end < start ? end + count : end;
+ var completeLoop = !!line._fullLoop && start === 0 && end === count - 1;
+ return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions);
+ }
+ function splitByStyles(line, segments, points, segmentOptions) {
+ if (!segmentOptions || !segmentOptions.setContext || !points) {
+ return segments;
+ }
+ return doSplitByStyles(line, segments, points, segmentOptions);
+ }
+ function doSplitByStyles(line, segments, points, segmentOptions) {
+ var chartContext = line._chart.getContext();
+ var baseStyle = readStyle(line.options);
+ var datasetIndex = line._datasetIndex,
+ spanGaps = line.options.spanGaps;
+ var count = points.length;
+ var result = [];
+ var prevStyle = baseStyle;
+ var start = segments[0].start;
+ var i = start;
+ function addStyle(s, e, l, st) {
+ var dir = spanGaps ? -1 : 1;
+ if (s === e) {
+ return;
+ }
+ s += count;
+ while (points[s % count].skip) {
+ s -= dir;
+ }
+ while (points[e % count].skip) {
+ e += dir;
+ }
+ if (s % count !== e % count) {
+ result.push({
+ start: s % count,
+ end: e % count,
+ loop: l,
+ style: st
+ });
+ prevStyle = st;
+ start = e % count;
+ }
+ }
+ var _iterator11 = _createForOfIteratorHelper$1(segments),
+ _step11;
+ try {
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
+ var segment = _step11.value;
+ start = spanGaps ? start : segment.start;
+ var prev = points[start % count];
+ var style = void 0;
+ for (i = start + 1; i <= segment.end; i++) {
+ var pt = points[i % count];
+ style = readStyle(segmentOptions.setContext(createContext(chartContext, {
+ type: 'segment',
+ p0: prev,
+ p1: pt,
+ p0DataIndex: (i - 1) % count,
+ p1DataIndex: i % count,
+ datasetIndex: datasetIndex
+ })));
+ if (styleChanged(style, prevStyle)) {
+ addStyle(start, i - 1, segment.loop, prevStyle);
+ }
+ prev = pt;
+ prevStyle = style;
+ }
+ if (start < i - 1) {
+ addStyle(start, i - 1, segment.loop, prevStyle);
+ }
+ }
+ } catch (err) {
+ _iterator11.e(err);
+ } finally {
+ _iterator11.f();
+ }
+ return result;
+ }
+ function readStyle(options) {
+ return {
+ backgroundColor: options.backgroundColor,
+ borderCapStyle: options.borderCapStyle,
+ borderDash: options.borderDash,
+ borderDashOffset: options.borderDashOffset,
+ borderJoinStyle: options.borderJoinStyle,
+ borderWidth: options.borderWidth,
+ borderColor: options.borderColor
+ };
+ }
+ function styleChanged(style, prevStyle) {
+ if (!prevStyle) {
+ return false;
+ }
+ var cache = [];
+ var replacer = function replacer(key, value) {
+ if (!isPatternOrGradient(value)) {
+ return value;
+ }
+ if (!cache.includes(value)) {
+ cache.push(value);
+ }
+ return cache.indexOf(value);
+ };
+ return JSON.stringify(style, replacer) !== JSON.stringify(prevStyle, replacer);
+ }
+
+ var Animator = /*#__PURE__*/function () {
+ function Animator() {
+ _classCallCheck$1(this, Animator);
+ this._request = null;
+ this._charts = new Map();
+ this._running = false;
+ this._lastDate = undefined;
+ }
+ return _createClass$1(Animator, [{
+ key: "_notify",
+ value: function _notify(chart, anims, date, type) {
+ var callbacks = anims.listeners[type];
+ var numSteps = anims.duration;
+ callbacks.forEach(function (fn) {
+ return fn({
+ chart: chart,
+ initial: anims.initial,
+ numSteps: numSteps,
+ currentStep: Math.min(date - anims.start, numSteps)
+ });
+ });
+ }
+ }, {
+ key: "_refresh",
+ value: function _refresh() {
+ var _this = this;
+ if (this._request) {
+ return;
+ }
+ this._running = true;
+ this._request = requestAnimFrame.call(window, function () {
+ _this._update();
+ _this._request = null;
+ if (_this._running) {
+ _this._refresh();
+ }
+ });
+ }
+ }, {
+ key: "_update",
+ value: function _update() {
+ var _this2 = this;
+ var date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Date.now();
+ var remaining = 0;
+ this._charts.forEach(function (anims, chart) {
+ if (!anims.running || !anims.items.length) {
+ return;
+ }
+ var items = anims.items;
+ var i = items.length - 1;
+ var draw = false;
+ var item;
+ for (; i >= 0; --i) {
+ item = items[i];
+ if (item._active) {
+ if (item._total > anims.duration) {
+ anims.duration = item._total;
+ }
+ item.tick(date);
+ draw = true;
+ } else {
+ items[i] = items[items.length - 1];
+ items.pop();
+ }
+ }
+ if (draw) {
+ chart.draw();
+ _this2._notify(chart, anims, date, 'progress');
+ }
+ if (!items.length) {
+ anims.running = false;
+ _this2._notify(chart, anims, date, 'complete');
+ anims.initial = false;
+ }
+ remaining += items.length;
+ });
+ this._lastDate = date;
+ if (remaining === 0) {
+ this._running = false;
+ }
+ }
+ }, {
+ key: "_getAnims",
+ value: function _getAnims(chart) {
+ var charts = this._charts;
+ var anims = charts.get(chart);
+ if (!anims) {
+ anims = {
+ running: false,
+ initial: true,
+ items: [],
+ listeners: {
+ complete: [],
+ progress: []
+ }
+ };
+ charts.set(chart, anims);
+ }
+ return anims;
+ }
+ }, {
+ key: "listen",
+ value: function listen(chart, event, cb) {
+ this._getAnims(chart).listeners[event].push(cb);
+ }
+ }, {
+ key: "add",
+ value: function add(chart, items) {
+ var _this$_getAnims$items;
+ if (!items || !items.length) {
+ return;
+ }
+ (_this$_getAnims$items = this._getAnims(chart).items).push.apply(_this$_getAnims$items, _toConsumableArray(items));
+ }
+ }, {
+ key: "has",
+ value: function has(chart) {
+ return this._getAnims(chart).items.length > 0;
+ }
+ }, {
+ key: "start",
+ value: function start(chart) {
+ var anims = this._charts.get(chart);
+ if (!anims) {
+ return;
+ }
+ anims.running = true;
+ anims.start = Date.now();
+ anims.duration = anims.items.reduce(function (acc, cur) {
+ return Math.max(acc, cur._duration);
+ }, 0);
+ this._refresh();
+ }
+ }, {
+ key: "running",
+ value: function running(chart) {
+ if (!this._running) {
+ return false;
+ }
+ var anims = this._charts.get(chart);
+ if (!anims || !anims.running || !anims.items.length) {
+ return false;
+ }
+ return true;
+ }
+ }, {
+ key: "stop",
+ value: function stop(chart) {
+ var anims = this._charts.get(chart);
+ if (!anims || !anims.items.length) {
+ return;
+ }
+ var items = anims.items;
+ var i = items.length - 1;
+ for (; i >= 0; --i) {
+ items[i].cancel();
+ }
+ anims.items = [];
+ this._notify(chart, anims, Date.now(), 'complete');
+ }
+ }, {
+ key: "remove",
+ value: function remove(chart) {
+ return this._charts["delete"](chart);
+ }
+ }]);
+ }();
+ var animator = /* #__PURE__ */new Animator();
+ var transparent = 'transparent';
+ var interpolators = {
+ "boolean": function boolean(from, to, factor) {
+ return factor > 0.5 ? to : from;
+ },
+ color: function color$1(from, to, factor) {
+ var c0 = color(from || transparent);
+ var c1 = c0.valid && color(to || transparent);
+ return c1 && c1.valid ? c1.mix(c0, factor).hexString() : to;
+ },
+ number: function number(from, to, factor) {
+ return from + (to - from) * factor;
+ }
+ };
+ var Animation = /*#__PURE__*/function () {
+ function Animation(cfg, target, prop, to) {
+ _classCallCheck$1(this, Animation);
+ var currentValue = target[prop];
+ to = resolve([cfg.to, to, currentValue, cfg.from]);
+ var from = resolve([cfg.from, currentValue, to]);
+ this._active = true;
+ this._fn = cfg.fn || interpolators[cfg.type || _typeof$1(from)];
+ this._easing = effects[cfg.easing] || effects.linear;
+ this._start = Math.floor(Date.now() + (cfg.delay || 0));
+ this._duration = this._total = Math.floor(cfg.duration);
+ this._loop = !!cfg.loop;
+ this._target = target;
+ this._prop = prop;
+ this._from = from;
+ this._to = to;
+ this._promises = undefined;
+ }
+ return _createClass$1(Animation, [{
+ key: "active",
+ value: function active() {
+ return this._active;
+ }
+ }, {
+ key: "update",
+ value: function update(cfg, to, date) {
+ if (this._active) {
+ this._notify(false);
+ var currentValue = this._target[this._prop];
+ var elapsed = date - this._start;
+ var remain = this._duration - elapsed;
+ this._start = date;
+ this._duration = Math.floor(Math.max(remain, cfg.duration));
+ this._total += elapsed;
+ this._loop = !!cfg.loop;
+ this._to = resolve([cfg.to, to, currentValue, cfg.from]);
+ this._from = resolve([cfg.from, currentValue, to]);
+ }
+ }
+ }, {
+ key: "cancel",
+ value: function cancel() {
+ if (this._active) {
+ this.tick(Date.now());
+ this._active = false;
+ this._notify(false);
+ }
+ }
+ }, {
+ key: "tick",
+ value: function tick(date) {
+ var elapsed = date - this._start;
+ var duration = this._duration;
+ var prop = this._prop;
+ var from = this._from;
+ var loop = this._loop;
+ var to = this._to;
+ var factor;
+ this._active = from !== to && (loop || elapsed < duration);
+ if (!this._active) {
+ this._target[prop] = to;
+ this._notify(true);
+ return;
+ }
+ if (elapsed < 0) {
+ this._target[prop] = from;
+ return;
+ }
+ factor = elapsed / duration % 2;
+ factor = loop && factor > 1 ? 2 - factor : factor;
+ factor = this._easing(Math.min(1, Math.max(0, factor)));
+ this._target[prop] = this._fn(from, to, factor);
+ }
+ }, {
+ key: "wait",
+ value: function wait() {
+ var promises = this._promises || (this._promises = []);
+ return new Promise(function (res, rej) {
+ promises.push({
+ res: res,
+ rej: rej
+ });
+ });
+ }
+ }, {
+ key: "_notify",
+ value: function _notify(resolved) {
+ var method = resolved ? 'res' : 'rej';
+ var promises = this._promises || [];
+ for (var i = 0; i < promises.length; i++) {
+ promises[i][method]();
+ }
+ }
+ }]);
+ }();
+ var Animations = /*#__PURE__*/function () {
+ function Animations(chart, config) {
+ _classCallCheck$1(this, Animations);
+ this._chart = chart;
+ this._properties = new Map();
+ this.configure(config);
+ }
+ return _createClass$1(Animations, [{
+ key: "configure",
+ value: function configure(config) {
+ if (!isObject(config)) {
+ return;
+ }
+ var animationOptions = Object.keys(defaults.animation);
+ var animatedProps = this._properties;
+ Object.getOwnPropertyNames(config).forEach(function (key) {
+ var cfg = config[key];
+ if (!isObject(cfg)) {
+ return;
+ }
+ var resolved = {};
+ for (var _i = 0, _animationOptions = animationOptions; _i < _animationOptions.length; _i++) {
+ var option = _animationOptions[_i];
+ resolved[option] = cfg[option];
+ }
+ (isArray(cfg.properties) && cfg.properties || [key]).forEach(function (prop) {
+ if (prop === key || !animatedProps.has(prop)) {
+ animatedProps.set(prop, resolved);
+ }
+ });
+ });
+ }
+ }, {
+ key: "_animateOptions",
+ value: function _animateOptions(target, values) {
+ var newOptions = values.options;
+ var options = resolveTargetOptions(target, newOptions);
+ if (!options) {
+ return [];
+ }
+ var animations = this._createAnimations(options, newOptions);
+ if (newOptions.$shared) {
+ awaitAll(target.options.$animations, newOptions).then(function () {
+ target.options = newOptions;
+ }, function () {});
+ }
+ return animations;
+ }
+ }, {
+ key: "_createAnimations",
+ value: function _createAnimations(target, values) {
+ var animatedProps = this._properties;
+ var animations = [];
+ var running = target.$animations || (target.$animations = {});
+ var props = Object.keys(values);
+ var date = Date.now();
+ var i;
+ for (i = props.length - 1; i >= 0; --i) {
+ var prop = props[i];
+ if (prop.charAt(0) === '$') {
+ continue;
+ }
+ if (prop === 'options') {
+ animations.push.apply(animations, _toConsumableArray(this._animateOptions(target, values)));
+ continue;
+ }
+ var value = values[prop];
+ var animation = running[prop];
+ var cfg = animatedProps.get(prop);
+ if (animation) {
+ if (cfg && animation.active()) {
+ animation.update(cfg, value, date);
+ continue;
+ } else {
+ animation.cancel();
+ }
+ }
+ if (!cfg || !cfg.duration) {
+ target[prop] = value;
+ continue;
+ }
+ running[prop] = animation = new Animation(cfg, target, prop, value);
+ animations.push(animation);
+ }
+ return animations;
+ }
+ }, {
+ key: "update",
+ value: function update(target, values) {
+ if (this._properties.size === 0) {
+ Object.assign(target, values);
+ return;
+ }
+ var animations = this._createAnimations(target, values);
+ if (animations.length) {
+ animator.add(this._chart, animations);
+ return true;
+ }
+ }
+ }]);
+ }();
+ function awaitAll(animations, properties) {
+ var running = [];
+ var keys = Object.keys(properties);
+ for (var i = 0; i < keys.length; i++) {
+ var anim = animations[keys[i]];
+ if (anim && anim.active()) {
+ running.push(anim.wait());
+ }
+ }
+ return Promise.all(running);
+ }
+ function resolveTargetOptions(target, newOptions) {
+ if (!newOptions) {
+ return;
+ }
+ var options = target.options;
+ if (!options) {
+ target.options = newOptions;
+ return;
+ }
+ if (options.$shared) {
+ target.options = options = Object.assign({}, options, {
+ $shared: false,
+ $animations: {}
+ });
+ }
+ return options;
+ }
+ function scaleClip(scale, allowedOverflow) {
+ var opts = scale && scale.options || {};
+ var reverse = opts.reverse;
+ var min = opts.min === undefined ? allowedOverflow : 0;
+ var max = opts.max === undefined ? allowedOverflow : 0;
+ return {
+ start: reverse ? max : min,
+ end: reverse ? min : max
+ };
+ }
+ function defaultClip(xScale, yScale, allowedOverflow) {
+ if (allowedOverflow === false) {
+ return false;
+ }
+ var x = scaleClip(xScale, allowedOverflow);
+ var y = scaleClip(yScale, allowedOverflow);
+ return {
+ top: y.end,
+ right: x.end,
+ bottom: y.start,
+ left: x.start
+ };
+ }
+ function toClip(value) {
+ var t, r, b, l;
+ if (isObject(value)) {
+ t = value.top;
+ r = value.right;
+ b = value.bottom;
+ l = value.left;
+ } else {
+ t = r = b = l = value;
+ }
+ return {
+ top: t,
+ right: r,
+ bottom: b,
+ left: l,
+ disabled: value === false
+ };
+ }
+ function getSortedDatasetIndices(chart, filterVisible) {
+ var keys = [];
+ var metasets = chart._getSortedDatasetMetas(filterVisible);
+ var i, ilen;
+ for (i = 0, ilen = metasets.length; i < ilen; ++i) {
+ keys.push(metasets[i].index);
+ }
+ return keys;
+ }
+ function _applyStack(stack, value, dsIndex) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+ var keys = stack.keys;
+ var singleMode = options.mode === 'single';
+ var i, ilen, datasetIndex, otherValue;
+ if (value === null) {
+ return;
+ }
+ var found = false;
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ datasetIndex = +keys[i];
+ if (datasetIndex === dsIndex) {
+ found = true;
+ if (options.all) {
+ continue;
+ }
+ break;
+ }
+ otherValue = stack.values[datasetIndex];
+ if (isNumberFinite(otherValue) && (singleMode || value === 0 || sign(value) === sign(otherValue))) {
+ value += otherValue;
+ }
+ }
+ if (!found && !options.all) {
+ return 0;
+ }
+ return value;
+ }
+ function convertObjectDataToArray(data, meta) {
+ var iScale = meta.iScale,
+ vScale = meta.vScale;
+ var iAxisKey = iScale.axis === 'x' ? 'x' : 'y';
+ var vAxisKey = vScale.axis === 'x' ? 'x' : 'y';
+ var keys = Object.keys(data);
+ var adata = new Array(keys.length);
+ var i, ilen, key;
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+ adata[i] = _defineProperty$1(_defineProperty$1({}, iAxisKey, key), vAxisKey, data[key]);
+ }
+ return adata;
+ }
+ function isStacked(scale, meta) {
+ var stacked = scale && scale.options.stacked;
+ return stacked || stacked === undefined && meta.stack !== undefined;
+ }
+ function getStackKey(indexScale, valueScale, meta) {
+ return "".concat(indexScale.id, ".").concat(valueScale.id, ".").concat(meta.stack || meta.type);
+ }
+ function getUserBounds(scale) {
+ var _scale$getUserBounds = scale.getUserBounds(),
+ min = _scale$getUserBounds.min,
+ max = _scale$getUserBounds.max,
+ minDefined = _scale$getUserBounds.minDefined,
+ maxDefined = _scale$getUserBounds.maxDefined;
+ return {
+ min: minDefined ? min : Number.NEGATIVE_INFINITY,
+ max: maxDefined ? max : Number.POSITIVE_INFINITY
+ };
+ }
+ function getOrCreateStack(stacks, stackKey, indexValue) {
+ var subStack = stacks[stackKey] || (stacks[stackKey] = {});
+ return subStack[indexValue] || (subStack[indexValue] = {});
+ }
+ function getLastIndexInStack(stack, vScale, positive, type) {
+ var _iterator = _createForOfIteratorHelper$1(vScale.getMatchingVisibleMetas(type).reverse()),
+ _step;
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var meta = _step.value;
+ var value = stack[meta.index];
+ if (positive && value > 0 || !positive && value < 0) {
+ return meta.index;
+ }
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+ return null;
+ }
+ function updateStacks(controller, parsed) {
+ var chart = controller.chart,
+ meta = controller._cachedMeta;
+ var stacks = chart._stacks || (chart._stacks = {});
+ var iScale = meta.iScale,
+ vScale = meta.vScale,
+ datasetIndex = meta.index;
+ var iAxis = iScale.axis;
+ var vAxis = vScale.axis;
+ var key = getStackKey(iScale, vScale, meta);
+ var ilen = parsed.length;
+ var stack;
+ for (var i = 0; i < ilen; ++i) {
+ var item = parsed[i];
+ var _index = item[iAxis],
+ value = item[vAxis];
+ var itemStacks = item._stacks || (item._stacks = {});
+ stack = itemStacks[vAxis] = getOrCreateStack(stacks, key, _index);
+ stack[datasetIndex] = value;
+ stack._top = getLastIndexInStack(stack, vScale, true, meta.type);
+ stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type);
+ var visualValues = stack._visualValues || (stack._visualValues = {});
+ visualValues[datasetIndex] = value;
+ }
+ }
+ function getFirstScaleId(chart, axis) {
+ var scales = chart.scales;
+ return Object.keys(scales).filter(function (key) {
+ return scales[key].axis === axis;
+ }).shift();
+ }
+ function createDatasetContext(parent, index) {
+ return createContext(parent, {
+ active: false,
+ dataset: undefined,
+ datasetIndex: index,
+ index: index,
+ mode: 'default',
+ type: 'dataset'
+ });
+ }
+ function createDataContext(parent, index, element) {
+ return createContext(parent, {
+ active: false,
+ dataIndex: index,
+ parsed: undefined,
+ raw: undefined,
+ element: element,
+ index: index,
+ mode: 'default',
+ type: 'data'
+ });
+ }
+ function clearStacks(meta, items) {
+ var datasetIndex = meta.controller.index;
+ var axis = meta.vScale && meta.vScale.axis;
+ if (!axis) {
+ return;
+ }
+ items = items || meta._parsed;
+ var _iterator2 = _createForOfIteratorHelper$1(items),
+ _step2;
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ var parsed = _step2.value;
+ var stacks = parsed._stacks;
+ if (!stacks || stacks[axis] === undefined || stacks[axis][datasetIndex] === undefined) {
+ return;
+ }
+ delete stacks[axis][datasetIndex];
+ if (stacks[axis]._visualValues !== undefined && stacks[axis]._visualValues[datasetIndex] !== undefined) {
+ delete stacks[axis]._visualValues[datasetIndex];
+ }
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
+ }
+ var isDirectUpdateMode = function isDirectUpdateMode(mode) {
+ return mode === 'reset' || mode === 'none';
+ };
+ var cloneIfNotShared = function cloneIfNotShared(cached, shared) {
+ return shared ? cached : Object.assign({}, cached);
+ };
+ var createStack = function createStack(canStack, meta, chart) {
+ return canStack && !meta.hidden && meta._stacked && {
+ keys: getSortedDatasetIndices(chart, true),
+ values: null
+ };
+ };
+ var DatasetController = /*#__PURE__*/function () {
+ function DatasetController(chart, datasetIndex) {
+ _classCallCheck$1(this, DatasetController);
+ this.chart = chart;
+ this._ctx = chart.ctx;
+ this.index = datasetIndex;
+ this._cachedDataOpts = {};
+ this._cachedMeta = this.getMeta();
+ this._type = this._cachedMeta.type;
+ this.options = undefined;
+ this._parsing = false;
+ this._data = undefined;
+ this._objectData = undefined;
+ this._sharedOptions = undefined;
+ this._drawStart = undefined;
+ this._drawCount = undefined;
+ this.enableOptionSharing = false;
+ this.supportsDecimation = false;
+ this.$context = undefined;
+ this._syncList = [];
+ this.datasetElementType = (this instanceof DatasetController ? this.constructor : void 0).datasetElementType;
+ this.dataElementType = (this instanceof DatasetController ? this.constructor : void 0).dataElementType;
+ this.initialize();
+ }
+ return _createClass$1(DatasetController, [{
+ key: "initialize",
+ value: function initialize() {
+ var meta = this._cachedMeta;
+ this.configure();
+ this.linkScales();
+ meta._stacked = isStacked(meta.vScale, meta);
+ this.addElements();
+ if (this.options.fill && !this.chart.isPluginEnabled('filler')) {
+ console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options");
+ }
+ }
+ }, {
+ key: "updateIndex",
+ value: function updateIndex(datasetIndex) {
+ if (this.index !== datasetIndex) {
+ clearStacks(this._cachedMeta);
+ }
+ this.index = datasetIndex;
+ }
+ }, {
+ key: "linkScales",
+ value: function linkScales() {
+ var chart = this.chart;
+ var meta = this._cachedMeta;
+ var dataset = this.getDataset();
+ var chooseId = function chooseId(axis, x, y, r) {
+ return axis === 'x' ? x : axis === 'r' ? r : y;
+ };
+ var xid = meta.xAxisID = valueOrDefault(dataset.xAxisID, getFirstScaleId(chart, 'x'));
+ var yid = meta.yAxisID = valueOrDefault(dataset.yAxisID, getFirstScaleId(chart, 'y'));
+ var rid = meta.rAxisID = valueOrDefault(dataset.rAxisID, getFirstScaleId(chart, 'r'));
+ var indexAxis = meta.indexAxis;
+ var iid = meta.iAxisID = chooseId(indexAxis, xid, yid, rid);
+ var vid = meta.vAxisID = chooseId(indexAxis, yid, xid, rid);
+ meta.xScale = this.getScaleForId(xid);
+ meta.yScale = this.getScaleForId(yid);
+ meta.rScale = this.getScaleForId(rid);
+ meta.iScale = this.getScaleForId(iid);
+ meta.vScale = this.getScaleForId(vid);
+ }
+ }, {
+ key: "getDataset",
+ value: function getDataset() {
+ return this.chart.data.datasets[this.index];
+ }
+ }, {
+ key: "getMeta",
+ value: function getMeta() {
+ return this.chart.getDatasetMeta(this.index);
+ }
+ }, {
+ key: "getScaleForId",
+ value: function getScaleForId(scaleID) {
+ return this.chart.scales[scaleID];
+ }
+ }, {
+ key: "_getOtherScale",
+ value: function _getOtherScale(scale) {
+ var meta = this._cachedMeta;
+ return scale === meta.iScale ? meta.vScale : meta.iScale;
+ }
+ }, {
+ key: "reset",
+ value: function reset() {
+ this._update('reset');
+ }
+ }, {
+ key: "_destroy",
+ value: function _destroy() {
+ var meta = this._cachedMeta;
+ if (this._data) {
+ unlistenArrayEvents(this._data, this);
+ }
+ if (meta._stacked) {
+ clearStacks(meta);
+ }
+ }
+ }, {
+ key: "_dataCheck",
+ value: function _dataCheck() {
+ var dataset = this.getDataset();
+ var data = dataset.data || (dataset.data = []);
+ var _data = this._data;
+ if (isObject(data)) {
+ var meta = this._cachedMeta;
+ this._data = convertObjectDataToArray(data, meta);
+ } else if (_data !== data) {
+ if (_data) {
+ unlistenArrayEvents(_data, this);
+ var _meta = this._cachedMeta;
+ clearStacks(_meta);
+ _meta._parsed = [];
+ }
+ if (data && Object.isExtensible(data)) {
+ listenArrayEvents(data, this);
+ }
+ this._syncList = [];
+ this._data = data;
+ }
+ }
+ }, {
+ key: "addElements",
+ value: function addElements() {
+ var meta = this._cachedMeta;
+ this._dataCheck();
+ if (this.datasetElementType) {
+ meta.dataset = new this.datasetElementType();
+ }
+ }
+ }, {
+ key: "buildOrUpdateElements",
+ value: function buildOrUpdateElements(resetNewElements) {
+ var meta = this._cachedMeta;
+ var dataset = this.getDataset();
+ var stackChanged = false;
+ this._dataCheck();
+ var oldStacked = meta._stacked;
+ meta._stacked = isStacked(meta.vScale, meta);
+ if (meta.stack !== dataset.stack) {
+ stackChanged = true;
+ clearStacks(meta);
+ meta.stack = dataset.stack;
+ }
+ this._resyncElements(resetNewElements);
+ if (stackChanged || oldStacked !== meta._stacked) {
+ updateStacks(this, meta._parsed);
+ meta._stacked = isStacked(meta.vScale, meta);
+ }
+ }
+ }, {
+ key: "configure",
+ value: function configure() {
+ var config = this.chart.config;
+ var scopeKeys = config.datasetScopeKeys(this._type);
+ var scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true);
+ this.options = config.createResolver(scopes, this.getContext());
+ this._parsing = this.options.parsing;
+ this._cachedDataOpts = {};
+ }
+ }, {
+ key: "parse",
+ value: function parse(start, count) {
+ var meta = this._cachedMeta,
+ data = this._data;
+ var iScale = meta.iScale,
+ _stacked = meta._stacked;
+ var iAxis = iScale.axis;
+ var sorted = start === 0 && count === data.length ? true : meta._sorted;
+ var prev = start > 0 && meta._parsed[start - 1];
+ var i, cur, parsed;
+ if (this._parsing === false) {
+ meta._parsed = data;
+ meta._sorted = true;
+ parsed = data;
+ } else {
+ if (isArray(data[start])) {
+ parsed = this.parseArrayData(meta, data, start, count);
+ } else if (isObject(data[start])) {
+ parsed = this.parseObjectData(meta, data, start, count);
+ } else {
+ parsed = this.parsePrimitiveData(meta, data, start, count);
+ }
+ var isNotInOrderComparedToPrev = function isNotInOrderComparedToPrev() {
+ return cur[iAxis] === null || prev && cur[iAxis] < prev[iAxis];
+ };
+ for (i = 0; i < count; ++i) {
+ meta._parsed[i + start] = cur = parsed[i];
+ if (sorted) {
+ if (isNotInOrderComparedToPrev()) {
+ sorted = false;
+ }
+ prev = cur;
+ }
+ }
+ meta._sorted = sorted;
+ }
+ if (_stacked) {
+ updateStacks(this, parsed);
+ }
+ }
+ }, {
+ key: "parsePrimitiveData",
+ value: function parsePrimitiveData(meta, data, start, count) {
+ var iScale = meta.iScale,
+ vScale = meta.vScale;
+ var iAxis = iScale.axis;
+ var vAxis = vScale.axis;
+ var labels = iScale.getLabels();
+ var singleScale = iScale === vScale;
+ var parsed = new Array(count);
+ var i, ilen, index;
+ for (i = 0, ilen = count; i < ilen; ++i) {
+ index = i + start;
+ parsed[i] = _defineProperty$1(_defineProperty$1({}, iAxis, singleScale || iScale.parse(labels[index], index)), vAxis, vScale.parse(data[index], index));
+ }
+ return parsed;
+ }
+ }, {
+ key: "parseArrayData",
+ value: function parseArrayData(meta, data, start, count) {
+ var xScale = meta.xScale,
+ yScale = meta.yScale;
+ var parsed = new Array(count);
+ var i, ilen, index, item;
+ for (i = 0, ilen = count; i < ilen; ++i) {
+ index = i + start;
+ item = data[index];
+ parsed[i] = {
+ x: xScale.parse(item[0], index),
+ y: yScale.parse(item[1], index)
+ };
+ }
+ return parsed;
+ }
+ }, {
+ key: "parseObjectData",
+ value: function parseObjectData(meta, data, start, count) {
+ var xScale = meta.xScale,
+ yScale = meta.yScale;
+ var _this$_parsing = this._parsing,
+ _this$_parsing$xAxisK = _this$_parsing.xAxisKey,
+ xAxisKey = _this$_parsing$xAxisK === void 0 ? 'x' : _this$_parsing$xAxisK,
+ _this$_parsing$yAxisK = _this$_parsing.yAxisKey,
+ yAxisKey = _this$_parsing$yAxisK === void 0 ? 'y' : _this$_parsing$yAxisK;
+ var parsed = new Array(count);
+ var i, ilen, index, item;
+ for (i = 0, ilen = count; i < ilen; ++i) {
+ index = i + start;
+ item = data[index];
+ parsed[i] = {
+ x: xScale.parse(resolveObjectKey(item, xAxisKey), index),
+ y: yScale.parse(resolveObjectKey(item, yAxisKey), index)
+ };
+ }
+ return parsed;
+ }
+ }, {
+ key: "getParsed",
+ value: function getParsed(index) {
+ return this._cachedMeta._parsed[index];
+ }
+ }, {
+ key: "getDataElement",
+ value: function getDataElement(index) {
+ return this._cachedMeta.data[index];
+ }
+ }, {
+ key: "applyStack",
+ value: function applyStack(scale, parsed, mode) {
+ var chart = this.chart;
+ var meta = this._cachedMeta;
+ var value = parsed[scale.axis];
+ var stack = {
+ keys: getSortedDatasetIndices(chart, true),
+ values: parsed._stacks[scale.axis]._visualValues
+ };
+ return _applyStack(stack, value, meta.index, {
+ mode: mode
+ });
+ }
+ }, {
+ key: "updateRangeFromParsed",
+ value: function updateRangeFromParsed(range, scale, parsed, stack) {
+ var parsedValue = parsed[scale.axis];
+ var value = parsedValue === null ? NaN : parsedValue;
+ var values = stack && parsed._stacks[scale.axis];
+ if (stack && values) {
+ stack.values = values;
+ value = _applyStack(stack, parsedValue, this._cachedMeta.index);
+ }
+ range.min = Math.min(range.min, value);
+ range.max = Math.max(range.max, value);
+ }
+ }, {
+ key: "getMinMax",
+ value: function getMinMax(scale, canStack) {
+ var meta = this._cachedMeta;
+ var _parsed = meta._parsed;
+ var sorted = meta._sorted && scale === meta.iScale;
+ var ilen = _parsed.length;
+ var otherScale = this._getOtherScale(scale);
+ var stack = createStack(canStack, meta, this.chart);
+ var range = {
+ min: Number.POSITIVE_INFINITY,
+ max: Number.NEGATIVE_INFINITY
+ };
+ var _getUserBounds = getUserBounds(otherScale),
+ otherMin = _getUserBounds.min,
+ otherMax = _getUserBounds.max;
+ var i, parsed;
+ function _skip() {
+ parsed = _parsed[i];
+ var otherValue = parsed[otherScale.axis];
+ return !isNumberFinite(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue;
+ }
+ for (i = 0; i < ilen; ++i) {
+ if (_skip()) {
+ continue;
+ }
+ this.updateRangeFromParsed(range, scale, parsed, stack);
+ if (sorted) {
+ break;
+ }
+ }
+ if (sorted) {
+ for (i = ilen - 1; i >= 0; --i) {
+ if (_skip()) {
+ continue;
+ }
+ this.updateRangeFromParsed(range, scale, parsed, stack);
+ break;
+ }
+ }
+ return range;
+ }
+ }, {
+ key: "getAllParsedValues",
+ value: function getAllParsedValues(scale) {
+ var parsed = this._cachedMeta._parsed;
+ var values = [];
+ var i, ilen, value;
+ for (i = 0, ilen = parsed.length; i < ilen; ++i) {
+ value = parsed[i][scale.axis];
+ if (isNumberFinite(value)) {
+ values.push(value);
+ }
+ }
+ return values;
+ }
+ }, {
+ key: "getMaxOverflow",
+ value: function getMaxOverflow() {
+ return false;
+ }
+ }, {
+ key: "getLabelAndValue",
+ value: function getLabelAndValue(index) {
+ var meta = this._cachedMeta;
+ var iScale = meta.iScale;
+ var vScale = meta.vScale;
+ var parsed = this.getParsed(index);
+ return {
+ label: iScale ? '' + iScale.getLabelForValue(parsed[iScale.axis]) : '',
+ value: vScale ? '' + vScale.getLabelForValue(parsed[vScale.axis]) : ''
+ };
+ }
+ }, {
+ key: "_update",
+ value: function _update(mode) {
+ var meta = this._cachedMeta;
+ this.update(mode || 'default');
+ meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow())));
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {}
+ }, {
+ key: "draw",
+ value: function draw() {
+ var ctx = this._ctx;
+ var chart = this.chart;
+ var meta = this._cachedMeta;
+ var elements = meta.data || [];
+ var area = chart.chartArea;
+ var active = [];
+ var start = this._drawStart || 0;
+ var count = this._drawCount || elements.length - start;
+ var drawActiveElementsOnTop = this.options.drawActiveElementsOnTop;
+ var i;
+ if (meta.dataset) {
+ meta.dataset.draw(ctx, area, start, count);
+ }
+ for (i = start; i < start + count; ++i) {
+ var element = elements[i];
+ if (element.hidden) {
+ continue;
+ }
+ if (element.active && drawActiveElementsOnTop) {
+ active.push(element);
+ } else {
+ element.draw(ctx, area);
+ }
+ }
+ for (i = 0; i < active.length; ++i) {
+ active[i].draw(ctx, area);
+ }
+ }
+ }, {
+ key: "getStyle",
+ value: function getStyle(index, active) {
+ var mode = active ? 'active' : 'default';
+ return index === undefined && this._cachedMeta.dataset ? this.resolveDatasetElementOptions(mode) : this.resolveDataElementOptions(index || 0, mode);
+ }
+ }, {
+ key: "getContext",
+ value: function getContext(index, active, mode) {
+ var dataset = this.getDataset();
+ var context;
+ if (index >= 0 && index < this._cachedMeta.data.length) {
+ var element = this._cachedMeta.data[index];
+ context = element.$context || (element.$context = createDataContext(this.getContext(), index, element));
+ context.parsed = this.getParsed(index);
+ context.raw = dataset.data[index];
+ context.index = context.dataIndex = index;
+ } else {
+ context = this.$context || (this.$context = createDatasetContext(this.chart.getContext(), this.index));
+ context.dataset = dataset;
+ context.index = context.datasetIndex = this.index;
+ }
+ context.active = !!active;
+ context.mode = mode;
+ return context;
+ }
+ }, {
+ key: "resolveDatasetElementOptions",
+ value: function resolveDatasetElementOptions(mode) {
+ return this._resolveElementOptions(this.datasetElementType.id, mode);
+ }
+ }, {
+ key: "resolveDataElementOptions",
+ value: function resolveDataElementOptions(index, mode) {
+ return this._resolveElementOptions(this.dataElementType.id, mode, index);
+ }
+ }, {
+ key: "_resolveElementOptions",
+ value: function _resolveElementOptions(elementType) {
+ var _this3 = this;
+ var mode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default';
+ var index = arguments.length > 2 ? arguments[2] : undefined;
+ var active = mode === 'active';
+ var cache = this._cachedDataOpts;
+ var cacheKey = elementType + '-' + mode;
+ var cached = cache[cacheKey];
+ var sharing = this.enableOptionSharing && defined(index);
+ if (cached) {
+ return cloneIfNotShared(cached, sharing);
+ }
+ var config = this.chart.config;
+ var scopeKeys = config.datasetElementScopeKeys(this._type, elementType);
+ var prefixes = active ? ["".concat(elementType, "Hover"), 'hover', elementType, ''] : [elementType, ''];
+ var scopes = config.getOptionScopes(this.getDataset(), scopeKeys);
+ var names = Object.keys(defaults.elements[elementType]);
+ var context = function context() {
+ return _this3.getContext(index, active, mode);
+ };
+ var values = config.resolveNamedOptions(scopes, names, context, prefixes);
+ if (values.$shared) {
+ values.$shared = sharing;
+ cache[cacheKey] = Object.freeze(cloneIfNotShared(values, sharing));
+ }
+ return values;
+ }
+ }, {
+ key: "_resolveAnimations",
+ value: function _resolveAnimations(index, transition, active) {
+ var chart = this.chart;
+ var cache = this._cachedDataOpts;
+ var cacheKey = "animation-".concat(transition);
+ var cached = cache[cacheKey];
+ if (cached) {
+ return cached;
+ }
+ var options;
+ if (chart.options.animation !== false) {
+ var config = this.chart.config;
+ var scopeKeys = config.datasetAnimationScopeKeys(this._type, transition);
+ var scopes = config.getOptionScopes(this.getDataset(), scopeKeys);
+ options = config.createResolver(scopes, this.getContext(index, active, transition));
+ }
+ var animations = new Animations(chart, options && options.animations);
+ if (options && options._cacheable) {
+ cache[cacheKey] = Object.freeze(animations);
+ }
+ return animations;
+ }
+ }, {
+ key: "getSharedOptions",
+ value: function getSharedOptions(options) {
+ if (!options.$shared) {
+ return;
+ }
+ return this._sharedOptions || (this._sharedOptions = Object.assign({}, options));
+ }
+ }, {
+ key: "includeOptions",
+ value: function includeOptions(mode, sharedOptions) {
+ return !sharedOptions || isDirectUpdateMode(mode) || this.chart._animationsDisabled;
+ }
+ }, {
+ key: "_getSharedOptions",
+ value: function _getSharedOptions(start, mode) {
+ var firstOpts = this.resolveDataElementOptions(start, mode);
+ var previouslySharedOptions = this._sharedOptions;
+ var sharedOptions = this.getSharedOptions(firstOpts);
+ var includeOptions = this.includeOptions(mode, sharedOptions) || sharedOptions !== previouslySharedOptions;
+ this.updateSharedOptions(sharedOptions, mode, firstOpts);
+ return {
+ sharedOptions: sharedOptions,
+ includeOptions: includeOptions
+ };
+ }
+ }, {
+ key: "updateElement",
+ value: function updateElement(element, index, properties, mode) {
+ if (isDirectUpdateMode(mode)) {
+ Object.assign(element, properties);
+ } else {
+ this._resolveAnimations(index, mode).update(element, properties);
+ }
+ }
+ }, {
+ key: "updateSharedOptions",
+ value: function updateSharedOptions(sharedOptions, mode, newOptions) {
+ if (sharedOptions && !isDirectUpdateMode(mode)) {
+ this._resolveAnimations(undefined, mode).update(sharedOptions, newOptions);
+ }
+ }
+ }, {
+ key: "_setStyle",
+ value: function _setStyle(element, index, mode, active) {
+ element.active = active;
+ var options = this.getStyle(index, active);
+ this._resolveAnimations(index, mode, active).update(element, {
+ options: !active && this.getSharedOptions(options) || options
+ });
+ }
+ }, {
+ key: "removeHoverStyle",
+ value: function removeHoverStyle(element, datasetIndex, index) {
+ this._setStyle(element, index, 'active', false);
+ }
+ }, {
+ key: "setHoverStyle",
+ value: function setHoverStyle(element, datasetIndex, index) {
+ this._setStyle(element, index, 'active', true);
+ }
+ }, {
+ key: "_removeDatasetHoverStyle",
+ value: function _removeDatasetHoverStyle() {
+ var element = this._cachedMeta.dataset;
+ if (element) {
+ this._setStyle(element, undefined, 'active', false);
+ }
+ }
+ }, {
+ key: "_setDatasetHoverStyle",
+ value: function _setDatasetHoverStyle() {
+ var element = this._cachedMeta.dataset;
+ if (element) {
+ this._setStyle(element, undefined, 'active', true);
+ }
+ }
+ }, {
+ key: "_resyncElements",
+ value: function _resyncElements(resetNewElements) {
+ var data = this._data;
+ var elements = this._cachedMeta.data;
+ var _iterator3 = _createForOfIteratorHelper$1(this._syncList),
+ _step3;
+ try {
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
+ var _step3$value = _slicedToArray(_step3.value, 3),
+ method = _step3$value[0],
+ arg1 = _step3$value[1],
+ arg2 = _step3$value[2];
+ this[method](arg1, arg2);
+ }
+ } catch (err) {
+ _iterator3.e(err);
+ } finally {
+ _iterator3.f();
+ }
+ this._syncList = [];
+ var numMeta = elements.length;
+ var numData = data.length;
+ var count = Math.min(numData, numMeta);
+ if (count) {
+ this.parse(0, count);
+ }
+ if (numData > numMeta) {
+ this._insertElements(numMeta, numData - numMeta, resetNewElements);
+ } else if (numData < numMeta) {
+ this._removeElements(numData, numMeta - numData);
+ }
+ }
+ }, {
+ key: "_insertElements",
+ value: function _insertElements(start, count) {
+ var resetNewElements = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
+ var meta = this._cachedMeta;
+ var data = meta.data;
+ var end = start + count;
+ var i;
+ var move = function move(arr) {
+ arr.length += count;
+ for (i = arr.length - 1; i >= end; i--) {
+ arr[i] = arr[i - count];
+ }
+ };
+ move(data);
+ for (i = start; i < end; ++i) {
+ data[i] = new this.dataElementType();
+ }
+ if (this._parsing) {
+ move(meta._parsed);
+ }
+ this.parse(start, count);
+ if (resetNewElements) {
+ this.updateElements(data, start, count, 'reset');
+ }
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(element, start, count, mode) {}
+ }, {
+ key: "_removeElements",
+ value: function _removeElements(start, count) {
+ var meta = this._cachedMeta;
+ if (this._parsing) {
+ var removed = meta._parsed.splice(start, count);
+ if (meta._stacked) {
+ clearStacks(meta, removed);
+ }
+ }
+ meta.data.splice(start, count);
+ }
+ }, {
+ key: "_sync",
+ value: function _sync(args) {
+ if (this._parsing) {
+ this._syncList.push(args);
+ } else {
+ var _args2 = _slicedToArray(args, 3),
+ method = _args2[0],
+ arg1 = _args2[1],
+ arg2 = _args2[2];
+ this[method](arg1, arg2);
+ }
+ this.chart._dataChanges.push([this.index].concat(_toConsumableArray(args)));
+ }
+ }, {
+ key: "_onDataPush",
+ value: function _onDataPush() {
+ var count = arguments.length;
+ this._sync(['_insertElements', this.getDataset().data.length - count, count]);
+ }
+ }, {
+ key: "_onDataPop",
+ value: function _onDataPop() {
+ this._sync(['_removeElements', this._cachedMeta.data.length - 1, 1]);
+ }
+ }, {
+ key: "_onDataShift",
+ value: function _onDataShift() {
+ this._sync(['_removeElements', 0, 1]);
+ }
+ }, {
+ key: "_onDataSplice",
+ value: function _onDataSplice(start, count) {
+ if (count) {
+ this._sync(['_removeElements', start, count]);
+ }
+ var newCount = arguments.length - 2;
+ if (newCount) {
+ this._sync(['_insertElements', start, newCount]);
+ }
+ }
+ }, {
+ key: "_onDataUnshift",
+ value: function _onDataUnshift() {
+ this._sync(['_insertElements', 0, arguments.length]);
+ }
+ }]);
+ }();
+ _defineProperty$1(DatasetController, "defaults", {});
+ _defineProperty$1(DatasetController, "datasetElementType", null);
+ _defineProperty$1(DatasetController, "dataElementType", null);
+ function getAllScaleValues(scale, type) {
+ if (!scale._cache.$bar) {
+ var visibleMetas = scale.getMatchingVisibleMetas(type);
+ var values = [];
+ for (var i = 0, ilen = visibleMetas.length; i < ilen; i++) {
+ values = values.concat(visibleMetas[i].controller.getAllParsedValues(scale));
+ }
+ scale._cache.$bar = _arrayUnique(values.sort(function (a, b) {
+ return a - b;
+ }));
+ }
+ return scale._cache.$bar;
+ }
+ function computeMinSampleSize(meta) {
+ var scale = meta.iScale;
+ var values = getAllScaleValues(scale, meta.type);
+ var min = scale._length;
+ var i, ilen, curr, prev;
+ var updateMinAndPrev = function updateMinAndPrev() {
+ if (curr === 32767 || curr === -32768) {
+ return;
+ }
+ if (defined(prev)) {
+ min = Math.min(min, Math.abs(curr - prev) || min);
+ }
+ prev = curr;
+ };
+ for (i = 0, ilen = values.length; i < ilen; ++i) {
+ curr = scale.getPixelForValue(values[i]);
+ updateMinAndPrev();
+ }
+ prev = undefined;
+ for (i = 0, ilen = scale.ticks.length; i < ilen; ++i) {
+ curr = scale.getPixelForTick(i);
+ updateMinAndPrev();
+ }
+ return min;
+ }
+ function computeFitCategoryTraits(index, ruler, options, stackCount) {
+ var thickness = options.barThickness;
+ var size, ratio;
+ if (isNullOrUndef(thickness)) {
+ size = ruler.min * options.categoryPercentage;
+ ratio = options.barPercentage;
+ } else {
+ size = thickness * stackCount;
+ ratio = 1;
+ }
+ return {
+ chunk: size / stackCount,
+ ratio: ratio,
+ start: ruler.pixels[index] - size / 2
+ };
+ }
+ function computeFlexCategoryTraits(index, ruler, options, stackCount) {
+ var pixels = ruler.pixels;
+ var curr = pixels[index];
+ var prev = index > 0 ? pixels[index - 1] : null;
+ var next = index < pixels.length - 1 ? pixels[index + 1] : null;
+ var percent = options.categoryPercentage;
+ if (prev === null) {
+ prev = curr - (next === null ? ruler.end - ruler.start : next - curr);
+ }
+ if (next === null) {
+ next = curr + curr - prev;
+ }
+ var start = curr - (curr - Math.min(prev, next)) / 2 * percent;
+ var size = Math.abs(next - prev) / 2 * percent;
+ return {
+ chunk: size / stackCount,
+ ratio: options.barPercentage,
+ start: start
+ };
+ }
+ function parseFloatBar(entry, item, vScale, i) {
+ var startValue = vScale.parse(entry[0], i);
+ var endValue = vScale.parse(entry[1], i);
+ var min = Math.min(startValue, endValue);
+ var max = Math.max(startValue, endValue);
+ var barStart = min;
+ var barEnd = max;
+ if (Math.abs(min) > Math.abs(max)) {
+ barStart = max;
+ barEnd = min;
+ }
+ item[vScale.axis] = barEnd;
+ item._custom = {
+ barStart: barStart,
+ barEnd: barEnd,
+ start: startValue,
+ end: endValue,
+ min: min,
+ max: max
+ };
+ }
+ function parseValue(entry, item, vScale, i) {
+ if (isArray(entry)) {
+ parseFloatBar(entry, item, vScale, i);
+ } else {
+ item[vScale.axis] = vScale.parse(entry, i);
+ }
+ return item;
+ }
+ function parseArrayOrPrimitive(meta, data, start, count) {
+ var iScale = meta.iScale;
+ var vScale = meta.vScale;
+ var labels = iScale.getLabels();
+ var singleScale = iScale === vScale;
+ var parsed = [];
+ var i, ilen, item, entry;
+ for (i = start, ilen = start + count; i < ilen; ++i) {
+ entry = data[i];
+ item = {};
+ item[iScale.axis] = singleScale || iScale.parse(labels[i], i);
+ parsed.push(parseValue(entry, item, vScale, i));
+ }
+ return parsed;
+ }
+ function isFloatBar(custom) {
+ return custom && custom.barStart !== undefined && custom.barEnd !== undefined;
+ }
+ function barSign(size, vScale, actualBase) {
+ if (size !== 0) {
+ return sign(size);
+ }
+ return (vScale.isHorizontal() ? 1 : -1) * (vScale.min >= actualBase ? 1 : -1);
+ }
+ function borderProps(properties) {
+ var reverse, start, end, top, bottom;
+ if (properties.horizontal) {
+ reverse = properties.base > properties.x;
+ start = 'left';
+ end = 'right';
+ } else {
+ reverse = properties.base < properties.y;
+ start = 'bottom';
+ end = 'top';
+ }
+ if (reverse) {
+ top = 'end';
+ bottom = 'start';
+ } else {
+ top = 'start';
+ bottom = 'end';
+ }
+ return {
+ start: start,
+ end: end,
+ reverse: reverse,
+ top: top,
+ bottom: bottom
+ };
+ }
+ function setBorderSkipped(properties, options, stack, index) {
+ var edge = options.borderSkipped;
+ var res = {};
+ if (!edge) {
+ properties.borderSkipped = res;
+ return;
+ }
+ if (edge === true) {
+ properties.borderSkipped = {
+ top: true,
+ right: true,
+ bottom: true,
+ left: true
+ };
+ return;
+ }
+ var _borderProps = borderProps(properties),
+ start = _borderProps.start,
+ end = _borderProps.end,
+ reverse = _borderProps.reverse,
+ top = _borderProps.top,
+ bottom = _borderProps.bottom;
+ if (edge === 'middle' && stack) {
+ properties.enableBorderRadius = true;
+ if ((stack._top || 0) === index) {
+ edge = top;
+ } else if ((stack._bottom || 0) === index) {
+ edge = bottom;
+ } else {
+ res[parseEdge(bottom, start, end, reverse)] = true;
+ edge = top;
+ }
+ }
+ res[parseEdge(edge, start, end, reverse)] = true;
+ properties.borderSkipped = res;
+ }
+ function parseEdge(edge, a, b, reverse) {
+ if (reverse) {
+ edge = swap(edge, a, b);
+ edge = startEnd(edge, b, a);
+ } else {
+ edge = startEnd(edge, a, b);
+ }
+ return edge;
+ }
+ function swap(orig, v1, v2) {
+ return orig === v1 ? v2 : orig === v2 ? v1 : orig;
+ }
+ function startEnd(v, start, end) {
+ return v === 'start' ? start : v === 'end' ? end : v;
+ }
+ function setInflateAmount(properties, _ref, ratio) {
+ var inflateAmount = _ref.inflateAmount;
+ properties.inflateAmount = inflateAmount === 'auto' ? ratio === 1 ? 0.33 : 0 : inflateAmount;
+ }
+ var BarController = /*#__PURE__*/function (_DatasetController2) {
+ function BarController() {
+ _classCallCheck$1(this, BarController);
+ return _callSuper(this, BarController, arguments);
+ }
+ _inherits$1(BarController, _DatasetController2);
+ return _createClass$1(BarController, [{
+ key: "parsePrimitiveData",
+ value: function parsePrimitiveData(meta, data, start, count) {
+ return parseArrayOrPrimitive(meta, data, start, count);
+ }
+ }, {
+ key: "parseArrayData",
+ value: function parseArrayData(meta, data, start, count) {
+ return parseArrayOrPrimitive(meta, data, start, count);
+ }
+ }, {
+ key: "parseObjectData",
+ value: function parseObjectData(meta, data, start, count) {
+ var iScale = meta.iScale,
+ vScale = meta.vScale;
+ var _this$_parsing2 = this._parsing,
+ _this$_parsing2$xAxis = _this$_parsing2.xAxisKey,
+ xAxisKey = _this$_parsing2$xAxis === void 0 ? 'x' : _this$_parsing2$xAxis,
+ _this$_parsing2$yAxis = _this$_parsing2.yAxisKey,
+ yAxisKey = _this$_parsing2$yAxis === void 0 ? 'y' : _this$_parsing2$yAxis;
+ var iAxisKey = iScale.axis === 'x' ? xAxisKey : yAxisKey;
+ var vAxisKey = vScale.axis === 'x' ? xAxisKey : yAxisKey;
+ var parsed = [];
+ var i, ilen, item, obj;
+ for (i = start, ilen = start + count; i < ilen; ++i) {
+ obj = data[i];
+ item = {};
+ item[iScale.axis] = iScale.parse(resolveObjectKey(obj, iAxisKey), i);
+ parsed.push(parseValue(resolveObjectKey(obj, vAxisKey), item, vScale, i));
+ }
+ return parsed;
+ }
+ }, {
+ key: "updateRangeFromParsed",
+ value: function updateRangeFromParsed(range, scale, parsed, stack) {
+ _superPropGet(BarController, "updateRangeFromParsed", this, 3)([range, scale, parsed, stack]);
+ var custom = parsed._custom;
+ if (custom && scale === this._cachedMeta.vScale) {
+ range.min = Math.min(range.min, custom.min);
+ range.max = Math.max(range.max, custom.max);
+ }
+ }
+ }, {
+ key: "getMaxOverflow",
+ value: function getMaxOverflow() {
+ return 0;
+ }
+ }, {
+ key: "getLabelAndValue",
+ value: function getLabelAndValue(index) {
+ var meta = this._cachedMeta;
+ var iScale = meta.iScale,
+ vScale = meta.vScale;
+ var parsed = this.getParsed(index);
+ var custom = parsed._custom;
+ var value = isFloatBar(custom) ? '[' + custom.start + ', ' + custom.end + ']' : '' + vScale.getLabelForValue(parsed[vScale.axis]);
+ return {
+ label: '' + iScale.getLabelForValue(parsed[iScale.axis]),
+ value: value
+ };
+ }
+ }, {
+ key: "initialize",
+ value: function initialize() {
+ this.enableOptionSharing = true;
+ _superPropGet(BarController, "initialize", this, 3)([]);
+ var meta = this._cachedMeta;
+ meta.stack = this.getDataset().stack;
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var meta = this._cachedMeta;
+ this.updateElements(meta.data, 0, meta.data.length, mode);
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(bars, start, count, mode) {
+ var reset = mode === 'reset';
+ var index = this.index,
+ vScale = this._cachedMeta.vScale;
+ var base = vScale.getBasePixel();
+ var horizontal = vScale.isHorizontal();
+ var ruler = this._getRuler();
+ var _this$_getSharedOptio = this._getSharedOptions(start, mode),
+ sharedOptions = _this$_getSharedOptio.sharedOptions,
+ includeOptions = _this$_getSharedOptio.includeOptions;
+ for (var i = start; i < start + count; i++) {
+ var parsed = this.getParsed(i);
+ var vpixels = reset || isNullOrUndef(parsed[vScale.axis]) ? {
+ base: base,
+ head: base
+ } : this._calculateBarValuePixels(i);
+ var ipixels = this._calculateBarIndexPixels(i, ruler);
+ var stack = (parsed._stacks || {})[vScale.axis];
+ var properties = {
+ horizontal: horizontal,
+ base: vpixels.base,
+ enableBorderRadius: !stack || isFloatBar(parsed._custom) || index === stack._top || index === stack._bottom,
+ x: horizontal ? vpixels.head : ipixels.center,
+ y: horizontal ? ipixels.center : vpixels.head,
+ height: horizontal ? ipixels.size : Math.abs(vpixels.size),
+ width: horizontal ? Math.abs(vpixels.size) : ipixels.size
+ };
+ if (includeOptions) {
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, bars[i].active ? 'active' : mode);
+ }
+ var options = properties.options || bars[i].options;
+ setBorderSkipped(properties, options, stack, index);
+ setInflateAmount(properties, options, ruler.ratio);
+ this.updateElement(bars[i], i, properties, mode);
+ }
+ }
+ }, {
+ key: "_getStacks",
+ value: function _getStacks(last, dataIndex) {
+ var iScale = this._cachedMeta.iScale;
+ var metasets = iScale.getMatchingVisibleMetas(this._type).filter(function (meta) {
+ return meta.controller.options.grouped;
+ });
+ var stacked = iScale.options.stacked;
+ var stacks = [];
+ var currentParsed = this._cachedMeta.controller.getParsed(dataIndex);
+ var iScaleValue = currentParsed && currentParsed[iScale.axis];
+ var skipNull = function skipNull(meta) {
+ var parsed = meta._parsed.find(function (item) {
+ return item[iScale.axis] === iScaleValue;
+ });
+ var val = parsed && parsed[meta.vScale.axis];
+ if (isNullOrUndef(val) || isNaN(val)) {
+ return true;
+ }
+ };
+ var _iterator4 = _createForOfIteratorHelper$1(metasets),
+ _step4;
+ try {
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
+ var meta = _step4.value;
+ if (dataIndex !== undefined && skipNull(meta)) {
+ continue;
+ }
+ if (stacked === false || stacks.indexOf(meta.stack) === -1 || stacked === undefined && meta.stack === undefined) {
+ stacks.push(meta.stack);
+ }
+ if (meta.index === last) {
+ break;
+ }
+ }
+ } catch (err) {
+ _iterator4.e(err);
+ } finally {
+ _iterator4.f();
+ }
+ if (!stacks.length) {
+ stacks.push(undefined);
+ }
+ return stacks;
+ }
+ }, {
+ key: "_getStackCount",
+ value: function _getStackCount(index) {
+ return this._getStacks(undefined, index).length;
+ }
+ }, {
+ key: "_getStackIndex",
+ value: function _getStackIndex(datasetIndex, name, dataIndex) {
+ var stacks = this._getStacks(datasetIndex, dataIndex);
+ var index = name !== undefined ? stacks.indexOf(name) : -1;
+ return index === -1 ? stacks.length - 1 : index;
+ }
+ }, {
+ key: "_getRuler",
+ value: function _getRuler() {
+ var opts = this.options;
+ var meta = this._cachedMeta;
+ var iScale = meta.iScale;
+ var pixels = [];
+ var i, ilen;
+ for (i = 0, ilen = meta.data.length; i < ilen; ++i) {
+ pixels.push(iScale.getPixelForValue(this.getParsed(i)[iScale.axis], i));
+ }
+ var barThickness = opts.barThickness;
+ var min = barThickness || computeMinSampleSize(meta);
+ return {
+ min: min,
+ pixels: pixels,
+ start: iScale._startPixel,
+ end: iScale._endPixel,
+ stackCount: this._getStackCount(),
+ scale: iScale,
+ grouped: opts.grouped,
+ ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage
+ };
+ }
+ }, {
+ key: "_calculateBarValuePixels",
+ value: function _calculateBarValuePixels(index) {
+ var _this$_cachedMeta = this._cachedMeta,
+ vScale = _this$_cachedMeta.vScale,
+ _stacked = _this$_cachedMeta._stacked,
+ datasetIndex = _this$_cachedMeta.index,
+ _this$options = this.options,
+ baseValue = _this$options.base,
+ minBarLength = _this$options.minBarLength;
+ var actualBase = baseValue || 0;
+ var parsed = this.getParsed(index);
+ var custom = parsed._custom;
+ var floating = isFloatBar(custom);
+ var value = parsed[vScale.axis];
+ var start = 0;
+ var length = _stacked ? this.applyStack(vScale, parsed, _stacked) : value;
+ var head, size;
+ if (length !== value) {
+ start = length - value;
+ length = value;
+ }
+ if (floating) {
+ value = custom.barStart;
+ length = custom.barEnd - custom.barStart;
+ if (value !== 0 && sign(value) !== sign(custom.barEnd)) {
+ start = 0;
+ }
+ start += value;
+ }
+ var startValue = !isNullOrUndef(baseValue) && !floating ? baseValue : start;
+ var base = vScale.getPixelForValue(startValue);
+ if (this.chart.getDataVisibility(index)) {
+ head = vScale.getPixelForValue(start + length);
+ } else {
+ head = base;
+ }
+ size = head - base;
+ if (Math.abs(size) < minBarLength) {
+ size = barSign(size, vScale, actualBase) * minBarLength;
+ if (value === actualBase) {
+ base -= size / 2;
+ }
+ var startPixel = vScale.getPixelForDecimal(0);
+ var endPixel = vScale.getPixelForDecimal(1);
+ var min = Math.min(startPixel, endPixel);
+ var max = Math.max(startPixel, endPixel);
+ base = Math.max(Math.min(base, max), min);
+ head = base + size;
+ if (_stacked && !floating) {
+ parsed._stacks[vScale.axis]._visualValues[datasetIndex] = vScale.getValueForPixel(head) - vScale.getValueForPixel(base);
+ }
+ }
+ if (base === vScale.getPixelForValue(actualBase)) {
+ var halfGrid = sign(size) * vScale.getLineWidthForValue(actualBase) / 2;
+ base += halfGrid;
+ size -= halfGrid;
+ }
+ return {
+ size: size,
+ base: base,
+ head: head,
+ center: head + size / 2
+ };
+ }
+ }, {
+ key: "_calculateBarIndexPixels",
+ value: function _calculateBarIndexPixels(index, ruler) {
+ var scale = ruler.scale;
+ var options = this.options;
+ var skipNull = options.skipNull;
+ var maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity);
+ var center, size;
+ if (ruler.grouped) {
+ var stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount;
+ var range = options.barThickness === 'flex' ? computeFlexCategoryTraits(index, ruler, options, stackCount) : computeFitCategoryTraits(index, ruler, options, stackCount);
+ var stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined);
+ center = range.start + range.chunk * stackIndex + range.chunk / 2;
+ size = Math.min(maxBarThickness, range.chunk * range.ratio);
+ } else {
+ center = scale.getPixelForValue(this.getParsed(index)[scale.axis], index);
+ size = Math.min(maxBarThickness, ruler.min * ruler.ratio);
+ }
+ return {
+ base: center - size / 2,
+ head: center + size / 2,
+ center: center,
+ size: size
+ };
+ }
+ }, {
+ key: "draw",
+ value: function draw() {
+ var meta = this._cachedMeta;
+ var vScale = meta.vScale;
+ var rects = meta.data;
+ var ilen = rects.length;
+ var i = 0;
+ for (; i < ilen; ++i) {
+ if (this.getParsed(i)[vScale.axis] !== null && !rects[i].hidden) {
+ rects[i].draw(this._ctx);
+ }
+ }
+ }
+ }]);
+ }(DatasetController);
+ _defineProperty$1(BarController, "id", 'bar');
+ _defineProperty$1(BarController, "defaults", {
+ datasetElementType: false,
+ dataElementType: 'bar',
+ categoryPercentage: 0.8,
+ barPercentage: 0.9,
+ grouped: true,
+ animations: {
+ numbers: {
+ type: 'number',
+ properties: ['x', 'y', 'base', 'width', 'height']
+ }
+ }
+ });
+ _defineProperty$1(BarController, "overrides", {
+ scales: {
+ _index_: {
+ type: 'category',
+ offset: true,
+ grid: {
+ offset: true
+ }
+ },
+ _value_: {
+ type: 'linear',
+ beginAtZero: true
+ }
+ }
+ });
+ var BubbleController = /*#__PURE__*/function (_DatasetController3) {
+ function BubbleController() {
+ _classCallCheck$1(this, BubbleController);
+ return _callSuper(this, BubbleController, arguments);
+ }
+ _inherits$1(BubbleController, _DatasetController3);
+ return _createClass$1(BubbleController, [{
+ key: "initialize",
+ value: function initialize() {
+ this.enableOptionSharing = true;
+ _superPropGet(BubbleController, "initialize", this, 3)([]);
+ }
+ }, {
+ key: "parsePrimitiveData",
+ value: function parsePrimitiveData(meta, data, start, count) {
+ var parsed = _superPropGet(BubbleController, "parsePrimitiveData", this, 3)([meta, data, start, count]);
+ for (var i = 0; i < parsed.length; i++) {
+ parsed[i]._custom = this.resolveDataElementOptions(i + start).radius;
+ }
+ return parsed;
+ }
+ }, {
+ key: "parseArrayData",
+ value: function parseArrayData(meta, data, start, count) {
+ var parsed = _superPropGet(BubbleController, "parseArrayData", this, 3)([meta, data, start, count]);
+ for (var i = 0; i < parsed.length; i++) {
+ var item = data[start + i];
+ parsed[i]._custom = valueOrDefault(item[2], this.resolveDataElementOptions(i + start).radius);
+ }
+ return parsed;
+ }
+ }, {
+ key: "parseObjectData",
+ value: function parseObjectData(meta, data, start, count) {
+ var parsed = _superPropGet(BubbleController, "parseObjectData", this, 3)([meta, data, start, count]);
+ for (var i = 0; i < parsed.length; i++) {
+ var item = data[start + i];
+ parsed[i]._custom = valueOrDefault(item && item.r && +item.r, this.resolveDataElementOptions(i + start).radius);
+ }
+ return parsed;
+ }
+ }, {
+ key: "getMaxOverflow",
+ value: function getMaxOverflow() {
+ var data = this._cachedMeta.data;
+ var max = 0;
+ for (var i = data.length - 1; i >= 0; --i) {
+ max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2);
+ }
+ return max > 0 && max;
+ }
+ }, {
+ key: "getLabelAndValue",
+ value: function getLabelAndValue(index) {
+ var meta = this._cachedMeta;
+ var labels = this.chart.data.labels || [];
+ var xScale = meta.xScale,
+ yScale = meta.yScale;
+ var parsed = this.getParsed(index);
+ var x = xScale.getLabelForValue(parsed.x);
+ var y = yScale.getLabelForValue(parsed.y);
+ var r = parsed._custom;
+ return {
+ label: labels[index] || '',
+ value: '(' + x + ', ' + y + (r ? ', ' + r : '') + ')'
+ };
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var points = this._cachedMeta.data;
+ this.updateElements(points, 0, points.length, mode);
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(points, start, count, mode) {
+ var reset = mode === 'reset';
+ var _this$_cachedMeta2 = this._cachedMeta,
+ iScale = _this$_cachedMeta2.iScale,
+ vScale = _this$_cachedMeta2.vScale;
+ var _this$_getSharedOptio2 = this._getSharedOptions(start, mode),
+ sharedOptions = _this$_getSharedOptio2.sharedOptions,
+ includeOptions = _this$_getSharedOptio2.includeOptions;
+ var iAxis = iScale.axis;
+ var vAxis = vScale.axis;
+ for (var i = start; i < start + count; i++) {
+ var point = points[i];
+ var parsed = !reset && this.getParsed(i);
+ var properties = {};
+ var iPixel = properties[iAxis] = reset ? iScale.getPixelForDecimal(0.5) : iScale.getPixelForValue(parsed[iAxis]);
+ var vPixel = properties[vAxis] = reset ? vScale.getBasePixel() : vScale.getPixelForValue(parsed[vAxis]);
+ properties.skip = isNaN(iPixel) || isNaN(vPixel);
+ if (includeOptions) {
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);
+ if (reset) {
+ properties.options.radius = 0;
+ }
+ }
+ this.updateElement(point, i, properties, mode);
+ }
+ }
+ }, {
+ key: "resolveDataElementOptions",
+ value: function resolveDataElementOptions(index, mode) {
+ var parsed = this.getParsed(index);
+ var values = _superPropGet(BubbleController, "resolveDataElementOptions", this, 3)([index, mode]);
+ if (values.$shared) {
+ values = Object.assign({}, values, {
+ $shared: false
+ });
+ }
+ var radius = values.radius;
+ if (mode !== 'active') {
+ values.radius = 0;
+ }
+ values.radius += valueOrDefault(parsed && parsed._custom, radius);
+ return values;
+ }
+ }]);
+ }(DatasetController);
+ _defineProperty$1(BubbleController, "id", 'bubble');
+ _defineProperty$1(BubbleController, "defaults", {
+ datasetElementType: false,
+ dataElementType: 'point',
+ animations: {
+ numbers: {
+ type: 'number',
+ properties: ['x', 'y', 'borderWidth', 'radius']
+ }
+ }
+ });
+ _defineProperty$1(BubbleController, "overrides", {
+ scales: {
+ x: {
+ type: 'linear'
+ },
+ y: {
+ type: 'linear'
+ }
+ }
+ });
+ function getRatioAndOffset(rotation, circumference, cutout) {
+ var ratioX = 1;
+ var ratioY = 1;
+ var offsetX = 0;
+ var offsetY = 0;
+ if (circumference < TAU) {
+ var startAngle = rotation;
+ var endAngle = startAngle + circumference;
+ var startX = Math.cos(startAngle);
+ var startY = Math.sin(startAngle);
+ var endX = Math.cos(endAngle);
+ var endY = Math.sin(endAngle);
+ var calcMax = function calcMax(angle, a, b) {
+ return _angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout);
+ };
+ var calcMin = function calcMin(angle, a, b) {
+ return _angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout);
+ };
+ var maxX = calcMax(0, startX, endX);
+ var maxY = calcMax(HALF_PI, startY, endY);
+ var minX = calcMin(PI, startX, endX);
+ var minY = calcMin(PI + HALF_PI, startY, endY);
+ ratioX = (maxX - minX) / 2;
+ ratioY = (maxY - minY) / 2;
+ offsetX = -(maxX + minX) / 2;
+ offsetY = -(maxY + minY) / 2;
+ }
+ return {
+ ratioX: ratioX,
+ ratioY: ratioY,
+ offsetX: offsetX,
+ offsetY: offsetY
+ };
+ }
+ var DoughnutController = /*#__PURE__*/function (_DatasetController4) {
+ function DoughnutController(chart, datasetIndex) {
+ var _this4;
+ _classCallCheck$1(this, DoughnutController);
+ _this4 = _callSuper(this, DoughnutController, [chart, datasetIndex]);
+ _this4.enableOptionSharing = true;
+ _this4.innerRadius = undefined;
+ _this4.outerRadius = undefined;
+ _this4.offsetX = undefined;
+ _this4.offsetY = undefined;
+ return _this4;
+ }
+ _inherits$1(DoughnutController, _DatasetController4);
+ return _createClass$1(DoughnutController, [{
+ key: "linkScales",
+ value: function linkScales() {}
+ }, {
+ key: "parse",
+ value: function parse(start, count) {
+ var data = this.getDataset().data;
+ var meta = this._cachedMeta;
+ if (this._parsing === false) {
+ meta._parsed = data;
+ } else {
+ var getter = function getter(i) {
+ return +data[i];
+ };
+ if (isObject(data[start])) {
+ var _this$_parsing$key = this._parsing.key,
+ key = _this$_parsing$key === void 0 ? 'value' : _this$_parsing$key;
+ getter = function getter(i) {
+ return +resolveObjectKey(data[i], key);
+ };
+ }
+ var i, ilen;
+ for (i = start, ilen = start + count; i < ilen; ++i) {
+ meta._parsed[i] = getter(i);
+ }
+ }
+ }
+ }, {
+ key: "_getRotation",
+ value: function _getRotation() {
+ return toRadians(this.options.rotation - 90);
+ }
+ }, {
+ key: "_getCircumference",
+ value: function _getCircumference() {
+ return toRadians(this.options.circumference);
+ }
+ }, {
+ key: "_getRotationExtents",
+ value: function _getRotationExtents() {
+ var min = TAU;
+ var max = -TAU;
+ for (var i = 0; i < this.chart.data.datasets.length; ++i) {
+ if (this.chart.isDatasetVisible(i) && this.chart.getDatasetMeta(i).type === this._type) {
+ var controller = this.chart.getDatasetMeta(i).controller;
+ var rotation = controller._getRotation();
+ var circumference = controller._getCircumference();
+ min = Math.min(min, rotation);
+ max = Math.max(max, rotation + circumference);
+ }
+ }
+ return {
+ rotation: min,
+ circumference: max - min
+ };
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var chart = this.chart;
+ var chartArea = chart.chartArea;
+ var meta = this._cachedMeta;
+ var arcs = meta.data;
+ var spacing = this.getMaxBorderWidth() + this.getMaxOffset(arcs) + this.options.spacing;
+ var maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0);
+ var cutout = Math.min(toPercentage(this.options.cutout, maxSize), 1);
+ var chartWeight = this._getRingWeight(this.index);
+ var _this$_getRotationExt = this._getRotationExtents(),
+ circumference = _this$_getRotationExt.circumference,
+ rotation = _this$_getRotationExt.rotation;
+ var _getRatioAndOffset = getRatioAndOffset(rotation, circumference, cutout),
+ ratioX = _getRatioAndOffset.ratioX,
+ ratioY = _getRatioAndOffset.ratioY,
+ offsetX = _getRatioAndOffset.offsetX,
+ offsetY = _getRatioAndOffset.offsetY;
+ var maxWidth = (chartArea.width - spacing) / ratioX;
+ var maxHeight = (chartArea.height - spacing) / ratioY;
+ var maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);
+ var outerRadius = toDimension(this.options.radius, maxRadius);
+ var innerRadius = Math.max(outerRadius * cutout, 0);
+ var radiusLength = (outerRadius - innerRadius) / this._getVisibleDatasetWeightTotal();
+ this.offsetX = offsetX * outerRadius;
+ this.offsetY = offsetY * outerRadius;
+ meta.total = this.calculateTotal();
+ this.outerRadius = outerRadius - radiusLength * this._getRingWeightOffset(this.index);
+ this.innerRadius = Math.max(this.outerRadius - radiusLength * chartWeight, 0);
+ this.updateElements(arcs, 0, arcs.length, mode);
+ }
+ }, {
+ key: "_circumference",
+ value: function _circumference(i, reset) {
+ var opts = this.options;
+ var meta = this._cachedMeta;
+ var circumference = this._getCircumference();
+ if (reset && opts.animation.animateRotate || !this.chart.getDataVisibility(i) || meta._parsed[i] === null || meta.data[i].hidden) {
+ return 0;
+ }
+ return this.calculateCircumference(meta._parsed[i] * circumference / TAU);
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(arcs, start, count, mode) {
+ var reset = mode === 'reset';
+ var chart = this.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var centerX = (chartArea.left + chartArea.right) / 2;
+ var centerY = (chartArea.top + chartArea.bottom) / 2;
+ var animateScale = reset && animationOpts.animateScale;
+ var innerRadius = animateScale ? 0 : this.innerRadius;
+ var outerRadius = animateScale ? 0 : this.outerRadius;
+ var _this$_getSharedOptio3 = this._getSharedOptions(start, mode),
+ sharedOptions = _this$_getSharedOptio3.sharedOptions,
+ includeOptions = _this$_getSharedOptio3.includeOptions;
+ var startAngle = this._getRotation();
+ var i;
+ for (i = 0; i < start; ++i) {
+ startAngle += this._circumference(i, reset);
+ }
+ for (i = start; i < start + count; ++i) {
+ var circumference = this._circumference(i, reset);
+ var arc = arcs[i];
+ var properties = {
+ x: centerX + this.offsetX,
+ y: centerY + this.offsetY,
+ startAngle: startAngle,
+ endAngle: startAngle + circumference,
+ circumference: circumference,
+ outerRadius: outerRadius,
+ innerRadius: innerRadius
+ };
+ if (includeOptions) {
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, arc.active ? 'active' : mode);
+ }
+ startAngle += circumference;
+ this.updateElement(arc, i, properties, mode);
+ }
+ }
+ }, {
+ key: "calculateTotal",
+ value: function calculateTotal() {
+ var meta = this._cachedMeta;
+ var metaData = meta.data;
+ var total = 0;
+ var i;
+ for (i = 0; i < metaData.length; i++) {
+ var value = meta._parsed[i];
+ if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i) && !metaData[i].hidden) {
+ total += Math.abs(value);
+ }
+ }
+ return total;
+ }
+ }, {
+ key: "calculateCircumference",
+ value: function calculateCircumference(value) {
+ var total = this._cachedMeta.total;
+ if (total > 0 && !isNaN(value)) {
+ return TAU * (Math.abs(value) / total);
+ }
+ return 0;
+ }
+ }, {
+ key: "getLabelAndValue",
+ value: function getLabelAndValue(index) {
+ var meta = this._cachedMeta;
+ var chart = this.chart;
+ var labels = chart.data.labels || [];
+ var value = formatNumber(meta._parsed[index], chart.options.locale);
+ return {
+ label: labels[index] || '',
+ value: value
+ };
+ }
+ }, {
+ key: "getMaxBorderWidth",
+ value: function getMaxBorderWidth(arcs) {
+ var max = 0;
+ var chart = this.chart;
+ var i, ilen, meta, controller, options;
+ if (!arcs) {
+ for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {
+ if (chart.isDatasetVisible(i)) {
+ meta = chart.getDatasetMeta(i);
+ arcs = meta.data;
+ controller = meta.controller;
+ break;
+ }
+ }
+ }
+ if (!arcs) {
+ return 0;
+ }
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ options = controller.resolveDataElementOptions(i);
+ if (options.borderAlign !== 'inner') {
+ max = Math.max(max, options.borderWidth || 0, options.hoverBorderWidth || 0);
+ }
+ }
+ return max;
+ }
+ }, {
+ key: "getMaxOffset",
+ value: function getMaxOffset(arcs) {
+ var max = 0;
+ for (var i = 0, ilen = arcs.length; i < ilen; ++i) {
+ var options = this.resolveDataElementOptions(i);
+ max = Math.max(max, options.offset || 0, options.hoverOffset || 0);
+ }
+ return max;
+ }
+ }, {
+ key: "_getRingWeightOffset",
+ value: function _getRingWeightOffset(datasetIndex) {
+ var ringWeightOffset = 0;
+ for (var i = 0; i < datasetIndex; ++i) {
+ if (this.chart.isDatasetVisible(i)) {
+ ringWeightOffset += this._getRingWeight(i);
+ }
+ }
+ return ringWeightOffset;
+ }
+ }, {
+ key: "_getRingWeight",
+ value: function _getRingWeight(datasetIndex) {
+ return Math.max(valueOrDefault(this.chart.data.datasets[datasetIndex].weight, 1), 0);
+ }
+ }, {
+ key: "_getVisibleDatasetWeightTotal",
+ value: function _getVisibleDatasetWeightTotal() {
+ return this._getRingWeightOffset(this.chart.data.datasets.length) || 1;
+ }
+ }]);
+ }(DatasetController);
+ _defineProperty$1(DoughnutController, "id", 'doughnut');
+ _defineProperty$1(DoughnutController, "defaults", {
+ datasetElementType: false,
+ dataElementType: 'arc',
+ animation: {
+ animateRotate: true,
+ animateScale: false
+ },
+ animations: {
+ numbers: {
+ type: 'number',
+ properties: ['circumference', 'endAngle', 'innerRadius', 'outerRadius', 'startAngle', 'x', 'y', 'offset', 'borderWidth', 'spacing']
+ }
+ },
+ cutout: '50%',
+ rotation: 0,
+ circumference: 360,
+ radius: '100%',
+ spacing: 0,
+ indexAxis: 'r'
+ });
+ _defineProperty$1(DoughnutController, "descriptors", {
+ _scriptable: function _scriptable(name) {
+ return name !== 'spacing';
+ },
+ _indexable: function _indexable(name) {
+ return name !== 'spacing' && !name.startsWith('borderDash') && !name.startsWith('hoverBorderDash');
+ }
+ });
+ _defineProperty$1(DoughnutController, "overrides", {
+ aspectRatio: 1,
+ plugins: {
+ legend: {
+ labels: {
+ generateLabels: function generateLabels(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ var _chart$legend$options2 = chart.legend.options.labels,
+ pointStyle = _chart$legend$options2.pointStyle,
+ color = _chart$legend$options2.color;
+ return data.labels.map(function (label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var style = meta.controller.getStyle(i);
+ return {
+ text: label,
+ fillStyle: style.backgroundColor,
+ strokeStyle: style.borderColor,
+ fontColor: color,
+ lineWidth: style.borderWidth,
+ pointStyle: pointStyle,
+ hidden: !chart.getDataVisibility(i),
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+ onClick: function onClick(e, legendItem, legend) {
+ legend.chart.toggleDataVisibility(legendItem.index);
+ legend.chart.update();
+ }
+ }
+ }
+ });
+ var LineController = /*#__PURE__*/function (_DatasetController5) {
+ function LineController() {
+ _classCallCheck$1(this, LineController);
+ return _callSuper(this, LineController, arguments);
+ }
+ _inherits$1(LineController, _DatasetController5);
+ return _createClass$1(LineController, [{
+ key: "initialize",
+ value: function initialize() {
+ this.enableOptionSharing = true;
+ this.supportsDecimation = true;
+ _superPropGet(LineController, "initialize", this, 3)([]);
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var meta = this._cachedMeta;
+ var line = meta.dataset,
+ _meta$data = meta.data,
+ points = _meta$data === void 0 ? [] : _meta$data,
+ _dataset = meta._dataset;
+ var animationsDisabled = this.chart._animationsDisabled;
+ var _getStartAndCountOfVi = _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled),
+ start = _getStartAndCountOfVi.start,
+ count = _getStartAndCountOfVi.count;
+ this._drawStart = start;
+ this._drawCount = count;
+ if (_scaleRangesChanged(meta)) {
+ start = 0;
+ count = points.length;
+ }
+ line._chart = this.chart;
+ line._datasetIndex = this.index;
+ line._decimated = !!_dataset._decimated;
+ line.points = points;
+ var options = this.resolveDatasetElementOptions(mode);
+ if (!this.options.showLine) {
+ options.borderWidth = 0;
+ }
+ options.segment = this.options.segment;
+ this.updateElement(line, undefined, {
+ animated: !animationsDisabled,
+ options: options
+ }, mode);
+ this.updateElements(points, start, count, mode);
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(points, start, count, mode) {
+ var reset = mode === 'reset';
+ var _this$_cachedMeta3 = this._cachedMeta,
+ iScale = _this$_cachedMeta3.iScale,
+ vScale = _this$_cachedMeta3.vScale,
+ _stacked = _this$_cachedMeta3._stacked,
+ _dataset = _this$_cachedMeta3._dataset;
+ var _this$_getSharedOptio4 = this._getSharedOptions(start, mode),
+ sharedOptions = _this$_getSharedOptio4.sharedOptions,
+ includeOptions = _this$_getSharedOptio4.includeOptions;
+ var iAxis = iScale.axis;
+ var vAxis = vScale.axis;
+ var _this$options2 = this.options,
+ spanGaps = _this$options2.spanGaps,
+ segment = _this$options2.segment;
+ var maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
+ var directUpdate = this.chart._animationsDisabled || reset || mode === 'none';
+ var end = start + count;
+ var pointsCount = points.length;
+ var prevParsed = start > 0 && this.getParsed(start - 1);
+ for (var i = 0; i < pointsCount; ++i) {
+ var point = points[i];
+ var properties = directUpdate ? point : {};
+ if (i < start || i >= end) {
+ properties.skip = true;
+ continue;
+ }
+ var parsed = this.getParsed(i);
+ var nullData = isNullOrUndef(parsed[vAxis]);
+ var iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i);
+ var vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i);
+ properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;
+ properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength;
+ if (segment) {
+ properties.parsed = parsed;
+ properties.raw = _dataset.data[i];
+ }
+ if (includeOptions) {
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);
+ }
+ if (!directUpdate) {
+ this.updateElement(point, i, properties, mode);
+ }
+ prevParsed = parsed;
+ }
+ }
+ }, {
+ key: "getMaxOverflow",
+ value: function getMaxOverflow() {
+ var meta = this._cachedMeta;
+ var dataset = meta.dataset;
+ var border = dataset.options && dataset.options.borderWidth || 0;
+ var data = meta.data || [];
+ if (!data.length) {
+ return border;
+ }
+ var firstPoint = data[0].size(this.resolveDataElementOptions(0));
+ var lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1));
+ return Math.max(border, firstPoint, lastPoint) / 2;
+ }
+ }, {
+ key: "draw",
+ value: function draw() {
+ var meta = this._cachedMeta;
+ meta.dataset.updateControlPoints(this.chart.chartArea, meta.iScale.axis);
+ _superPropGet(LineController, "draw", this, 3)([]);
+ }
+ }]);
+ }(DatasetController);
+ _defineProperty$1(LineController, "id", 'line');
+ _defineProperty$1(LineController, "defaults", {
+ datasetElementType: 'line',
+ dataElementType: 'point',
+ showLine: true,
+ spanGaps: false
+ });
+ _defineProperty$1(LineController, "overrides", {
+ scales: {
+ _index_: {
+ type: 'category'
+ },
+ _value_: {
+ type: 'linear'
+ }
+ }
+ });
+ var PolarAreaController = /*#__PURE__*/function (_DatasetController6) {
+ function PolarAreaController(chart, datasetIndex) {
+ var _this5;
+ _classCallCheck$1(this, PolarAreaController);
+ _this5 = _callSuper(this, PolarAreaController, [chart, datasetIndex]);
+ _this5.innerRadius = undefined;
+ _this5.outerRadius = undefined;
+ return _this5;
+ }
+ _inherits$1(PolarAreaController, _DatasetController6);
+ return _createClass$1(PolarAreaController, [{
+ key: "getLabelAndValue",
+ value: function getLabelAndValue(index) {
+ var meta = this._cachedMeta;
+ var chart = this.chart;
+ var labels = chart.data.labels || [];
+ var value = formatNumber(meta._parsed[index].r, chart.options.locale);
+ return {
+ label: labels[index] || '',
+ value: value
+ };
+ }
+ }, {
+ key: "parseObjectData",
+ value: function parseObjectData(meta, data, start, count) {
+ return _parseObjectDataRadialScale.bind(this)(meta, data, start, count);
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var arcs = this._cachedMeta.data;
+ this._updateRadius();
+ this.updateElements(arcs, 0, arcs.length, mode);
+ }
+ }, {
+ key: "getMinMax",
+ value: function getMinMax() {
+ var _this6 = this;
+ var meta = this._cachedMeta;
+ var range = {
+ min: Number.POSITIVE_INFINITY,
+ max: Number.NEGATIVE_INFINITY
+ };
+ meta.data.forEach(function (element, index) {
+ var parsed = _this6.getParsed(index).r;
+ if (!isNaN(parsed) && _this6.chart.getDataVisibility(index)) {
+ if (parsed < range.min) {
+ range.min = parsed;
+ }
+ if (parsed > range.max) {
+ range.max = parsed;
+ }
+ }
+ });
+ return range;
+ }
+ }, {
+ key: "_updateRadius",
+ value: function _updateRadius() {
+ var chart = this.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
+ var outerRadius = Math.max(minSize / 2, 0);
+ var innerRadius = Math.max(opts.cutoutPercentage ? outerRadius / 100 * opts.cutoutPercentage : 1, 0);
+ var radiusLength = (outerRadius - innerRadius) / chart.getVisibleDatasetCount();
+ this.outerRadius = outerRadius - radiusLength * this.index;
+ this.innerRadius = this.outerRadius - radiusLength;
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(arcs, start, count, mode) {
+ var reset = mode === 'reset';
+ var chart = this.chart;
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var scale = this._cachedMeta.rScale;
+ var centerX = scale.xCenter;
+ var centerY = scale.yCenter;
+ var datasetStartAngle = scale.getIndexAngle(0) - 0.5 * PI;
+ var angle = datasetStartAngle;
+ var i;
+ var defaultAngle = 360 / this.countVisibleElements();
+ for (i = 0; i < start; ++i) {
+ angle += this._computeAngle(i, mode, defaultAngle);
+ }
+ for (i = start; i < start + count; i++) {
+ var arc = arcs[i];
+ var startAngle = angle;
+ var endAngle = angle + this._computeAngle(i, mode, defaultAngle);
+ var outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(this.getParsed(i).r) : 0;
+ angle = endAngle;
+ if (reset) {
+ if (animationOpts.animateScale) {
+ outerRadius = 0;
+ }
+ if (animationOpts.animateRotate) {
+ startAngle = endAngle = datasetStartAngle;
+ }
+ }
+ var properties = {
+ x: centerX,
+ y: centerY,
+ innerRadius: 0,
+ outerRadius: outerRadius,
+ startAngle: startAngle,
+ endAngle: endAngle,
+ options: this.resolveDataElementOptions(i, arc.active ? 'active' : mode)
+ };
+ this.updateElement(arc, i, properties, mode);
+ }
+ }
+ }, {
+ key: "countVisibleElements",
+ value: function countVisibleElements() {
+ var _this7 = this;
+ var meta = this._cachedMeta;
+ var count = 0;
+ meta.data.forEach(function (element, index) {
+ if (!isNaN(_this7.getParsed(index).r) && _this7.chart.getDataVisibility(index)) {
+ count++;
+ }
+ });
+ return count;
+ }
+ }, {
+ key: "_computeAngle",
+ value: function _computeAngle(index, mode, defaultAngle) {
+ return this.chart.getDataVisibility(index) ? toRadians(this.resolveDataElementOptions(index, mode).angle || defaultAngle) : 0;
+ }
+ }]);
+ }(DatasetController);
+ _defineProperty$1(PolarAreaController, "id", 'polarArea');
+ _defineProperty$1(PolarAreaController, "defaults", {
+ dataElementType: 'arc',
+ animation: {
+ animateRotate: true,
+ animateScale: true
+ },
+ animations: {
+ numbers: {
+ type: 'number',
+ properties: ['x', 'y', 'startAngle', 'endAngle', 'innerRadius', 'outerRadius']
+ }
+ },
+ indexAxis: 'r',
+ startAngle: 0
+ });
+ _defineProperty$1(PolarAreaController, "overrides", {
+ aspectRatio: 1,
+ plugins: {
+ legend: {
+ labels: {
+ generateLabels: function generateLabels(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ var _chart$legend$options3 = chart.legend.options.labels,
+ pointStyle = _chart$legend$options3.pointStyle,
+ color = _chart$legend$options3.color;
+ return data.labels.map(function (label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var style = meta.controller.getStyle(i);
+ return {
+ text: label,
+ fillStyle: style.backgroundColor,
+ strokeStyle: style.borderColor,
+ fontColor: color,
+ lineWidth: style.borderWidth,
+ pointStyle: pointStyle,
+ hidden: !chart.getDataVisibility(i),
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+ onClick: function onClick(e, legendItem, legend) {
+ legend.chart.toggleDataVisibility(legendItem.index);
+ legend.chart.update();
+ }
+ }
+ },
+ scales: {
+ r: {
+ type: 'radialLinear',
+ angleLines: {
+ display: false
+ },
+ beginAtZero: true,
+ grid: {
+ circular: true
+ },
+ pointLabels: {
+ display: false
+ },
+ startAngle: 0
+ }
+ }
+ });
+ var PieController = /*#__PURE__*/function (_DoughnutController2) {
+ function PieController() {
+ _classCallCheck$1(this, PieController);
+ return _callSuper(this, PieController, arguments);
+ }
+ _inherits$1(PieController, _DoughnutController2);
+ return _createClass$1(PieController);
+ }(DoughnutController);
+ _defineProperty$1(PieController, "id", 'pie');
+ _defineProperty$1(PieController, "defaults", {
+ cutout: 0,
+ rotation: 0,
+ circumference: 360,
+ radius: '100%'
+ });
+ var RadarController = /*#__PURE__*/function (_DatasetController7) {
+ function RadarController() {
+ _classCallCheck$1(this, RadarController);
+ return _callSuper(this, RadarController, arguments);
+ }
+ _inherits$1(RadarController, _DatasetController7);
+ return _createClass$1(RadarController, [{
+ key: "getLabelAndValue",
+ value: function getLabelAndValue(index) {
+ var vScale = this._cachedMeta.vScale;
+ var parsed = this.getParsed(index);
+ return {
+ label: vScale.getLabels()[index],
+ value: '' + vScale.getLabelForValue(parsed[vScale.axis])
+ };
+ }
+ }, {
+ key: "parseObjectData",
+ value: function parseObjectData(meta, data, start, count) {
+ return _parseObjectDataRadialScale.bind(this)(meta, data, start, count);
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var meta = this._cachedMeta;
+ var line = meta.dataset;
+ var points = meta.data || [];
+ var labels = meta.iScale.getLabels();
+ line.points = points;
+ if (mode !== 'resize') {
+ var options = this.resolveDatasetElementOptions(mode);
+ if (!this.options.showLine) {
+ options.borderWidth = 0;
+ }
+ var properties = {
+ _loop: true,
+ _fullLoop: labels.length === points.length,
+ options: options
+ };
+ this.updateElement(line, undefined, properties, mode);
+ }
+ this.updateElements(points, 0, points.length, mode);
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(points, start, count, mode) {
+ var scale = this._cachedMeta.rScale;
+ var reset = mode === 'reset';
+ for (var i = start; i < start + count; i++) {
+ var point = points[i];
+ var options = this.resolveDataElementOptions(i, point.active ? 'active' : mode);
+ var pointPosition = scale.getPointPositionForValue(i, this.getParsed(i).r);
+ var x = reset ? scale.xCenter : pointPosition.x;
+ var y = reset ? scale.yCenter : pointPosition.y;
+ var properties = {
+ x: x,
+ y: y,
+ angle: pointPosition.angle,
+ skip: isNaN(x) || isNaN(y),
+ options: options
+ };
+ this.updateElement(point, i, properties, mode);
+ }
+ }
+ }]);
+ }(DatasetController);
+ _defineProperty$1(RadarController, "id", 'radar');
+ _defineProperty$1(RadarController, "defaults", {
+ datasetElementType: 'line',
+ dataElementType: 'point',
+ indexAxis: 'r',
+ showLine: true,
+ elements: {
+ line: {
+ fill: 'start'
+ }
+ }
+ });
+ _defineProperty$1(RadarController, "overrides", {
+ aspectRatio: 1,
+ scales: {
+ r: {
+ type: 'radialLinear'
+ }
+ }
+ });
+ var ScatterController = /*#__PURE__*/function (_DatasetController8) {
+ function ScatterController() {
+ _classCallCheck$1(this, ScatterController);
+ return _callSuper(this, ScatterController, arguments);
+ }
+ _inherits$1(ScatterController, _DatasetController8);
+ return _createClass$1(ScatterController, [{
+ key: "getLabelAndValue",
+ value: function getLabelAndValue(index) {
+ var meta = this._cachedMeta;
+ var labels = this.chart.data.labels || [];
+ var xScale = meta.xScale,
+ yScale = meta.yScale;
+ var parsed = this.getParsed(index);
+ var x = xScale.getLabelForValue(parsed.x);
+ var y = yScale.getLabelForValue(parsed.y);
+ return {
+ label: labels[index] || '',
+ value: '(' + x + ', ' + y + ')'
+ };
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var meta = this._cachedMeta;
+ var _meta$data2 = meta.data,
+ points = _meta$data2 === void 0 ? [] : _meta$data2;
+ var animationsDisabled = this.chart._animationsDisabled;
+ var _getStartAndCountOfVi2 = _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled),
+ start = _getStartAndCountOfVi2.start,
+ count = _getStartAndCountOfVi2.count;
+ this._drawStart = start;
+ this._drawCount = count;
+ if (_scaleRangesChanged(meta)) {
+ start = 0;
+ count = points.length;
+ }
+ if (this.options.showLine) {
+ if (!this.datasetElementType) {
+ this.addElements();
+ }
+ var line = meta.dataset,
+ _dataset = meta._dataset;
+ line._chart = this.chart;
+ line._datasetIndex = this.index;
+ line._decimated = !!_dataset._decimated;
+ line.points = points;
+ var options = this.resolveDatasetElementOptions(mode);
+ options.segment = this.options.segment;
+ this.updateElement(line, undefined, {
+ animated: !animationsDisabled,
+ options: options
+ }, mode);
+ } else if (this.datasetElementType) {
+ delete meta.dataset;
+ this.datasetElementType = false;
+ }
+ this.updateElements(points, start, count, mode);
+ }
+ }, {
+ key: "addElements",
+ value: function addElements() {
+ var showLine = this.options.showLine;
+ if (!this.datasetElementType && showLine) {
+ this.datasetElementType = this.chart.registry.getElement('line');
+ }
+ _superPropGet(ScatterController, "addElements", this, 3)([]);
+ }
+ }, {
+ key: "updateElements",
+ value: function updateElements(points, start, count, mode) {
+ var reset = mode === 'reset';
+ var _this$_cachedMeta4 = this._cachedMeta,
+ iScale = _this$_cachedMeta4.iScale,
+ vScale = _this$_cachedMeta4.vScale,
+ _stacked = _this$_cachedMeta4._stacked,
+ _dataset = _this$_cachedMeta4._dataset;
+ var firstOpts = this.resolveDataElementOptions(start, mode);
+ var sharedOptions = this.getSharedOptions(firstOpts);
+ var includeOptions = this.includeOptions(mode, sharedOptions);
+ var iAxis = iScale.axis;
+ var vAxis = vScale.axis;
+ var _this$options3 = this.options,
+ spanGaps = _this$options3.spanGaps,
+ segment = _this$options3.segment;
+ var maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
+ var directUpdate = this.chart._animationsDisabled || reset || mode === 'none';
+ var prevParsed = start > 0 && this.getParsed(start - 1);
+ for (var i = start; i < start + count; ++i) {
+ var point = points[i];
+ var parsed = this.getParsed(i);
+ var properties = directUpdate ? point : {};
+ var nullData = isNullOrUndef(parsed[vAxis]);
+ var iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i);
+ var vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i);
+ properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;
+ properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength;
+ if (segment) {
+ properties.parsed = parsed;
+ properties.raw = _dataset.data[i];
+ }
+ if (includeOptions) {
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);
+ }
+ if (!directUpdate) {
+ this.updateElement(point, i, properties, mode);
+ }
+ prevParsed = parsed;
+ }
+ this.updateSharedOptions(sharedOptions, mode, firstOpts);
+ }
+ }, {
+ key: "getMaxOverflow",
+ value: function getMaxOverflow() {
+ var meta = this._cachedMeta;
+ var data = meta.data || [];
+ if (!this.options.showLine) {
+ var max = 0;
+ for (var i = data.length - 1; i >= 0; --i) {
+ max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2);
+ }
+ return max > 0 && max;
+ }
+ var dataset = meta.dataset;
+ var border = dataset.options && dataset.options.borderWidth || 0;
+ if (!data.length) {
+ return border;
+ }
+ var firstPoint = data[0].size(this.resolveDataElementOptions(0));
+ var lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1));
+ return Math.max(border, firstPoint, lastPoint) / 2;
+ }
+ }]);
+ }(DatasetController);
+ _defineProperty$1(ScatterController, "id", 'scatter');
+ _defineProperty$1(ScatterController, "defaults", {
+ datasetElementType: false,
+ dataElementType: 'point',
+ showLine: false,
+ fill: false
+ });
+ _defineProperty$1(ScatterController, "overrides", {
+ interaction: {
+ mode: 'point'
+ },
+ scales: {
+ x: {
+ type: 'linear'
+ },
+ y: {
+ type: 'linear'
+ }
+ }
+ });
+ var controllers = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ BarController: BarController,
+ BubbleController: BubbleController,
+ DoughnutController: DoughnutController,
+ LineController: LineController,
+ PieController: PieController,
+ PolarAreaController: PolarAreaController,
+ RadarController: RadarController,
+ ScatterController: ScatterController
+ });
+
+ /**
+ * @namespace Chart._adapters
+ * @since 2.8.0
+ * @private
+ */
+ function _abstract() {
+ throw new Error('This method is not implemented: Check that a complete date adapter is provided.');
+ }
+ /**
+ * Date adapter (current used by the time scale)
+ * @namespace Chart._adapters._date
+ * @memberof Chart._adapters
+ * @private
+ */
+ var DateAdapterBase = /*#__PURE__*/function () {
+ function DateAdapterBase(options) {
+ _classCallCheck$1(this, DateAdapterBase);
+ _defineProperty$1(this, "options", void 0);
+ this.options = options || {};
+ }
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ return _createClass$1(DateAdapterBase, [{
+ key: "init",
+ value: function init() {}
+ }, {
+ key: "formats",
+ value: function formats() {
+ return _abstract();
+ }
+ }, {
+ key: "parse",
+ value: function parse() {
+ return _abstract();
+ }
+ }, {
+ key: "format",
+ value: function format() {
+ return _abstract();
+ }
+ }, {
+ key: "add",
+ value: function add() {
+ return _abstract();
+ }
+ }, {
+ key: "diff",
+ value: function diff() {
+ return _abstract();
+ }
+ }, {
+ key: "startOf",
+ value: function startOf() {
+ return _abstract();
+ }
+ }, {
+ key: "endOf",
+ value: function endOf() {
+ return _abstract();
+ }
+ }], [{
+ key: "override",
+ value:
+ /**
+ * Override default date adapter methods.
+ * Accepts type parameter to define options type.
+ * @example
+ * Chart._adapters._date.override<{myAdapterOption: string}>({
+ * init() {
+ * console.log(this.options.myAdapterOption);
+ * }
+ * })
+ */
+ function override(members) {
+ Object.assign(DateAdapterBase.prototype, members);
+ }
+ }]);
+ }();
+ var adapters = {
+ _date: DateAdapterBase
+ };
+ function binarySearch(metaset, axis, value, intersect) {
+ var controller = metaset.controller,
+ data = metaset.data,
+ _sorted = metaset._sorted;
+ var iScale = controller._cachedMeta.iScale;
+ var spanGaps = metaset.dataset ? metaset.dataset.options ? metaset.dataset.options.spanGaps : null : null;
+ if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) {
+ var lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey;
+ if (!intersect) {
+ var result = lookupMethod(data, axis, value);
+ if (spanGaps) {
+ var vScale = controller._cachedMeta.vScale;
+ var _parsed = metaset._parsed;
+ var distanceToDefinedLo = _parsed.slice(0, result.lo + 1).reverse().findIndex(function (point) {
+ return !isNullOrUndef(point[vScale.axis]);
+ });
+ result.lo -= Math.max(0, distanceToDefinedLo);
+ var distanceToDefinedHi = _parsed.slice(result.hi).findIndex(function (point) {
+ return !isNullOrUndef(point[vScale.axis]);
+ });
+ result.hi += Math.max(0, distanceToDefinedHi);
+ }
+ return result;
+ } else if (controller._sharedOptions) {
+ var el = data[0];
+ var range = typeof el.getRange === 'function' && el.getRange(axis);
+ if (range) {
+ var start = lookupMethod(data, axis, value - range);
+ var end = lookupMethod(data, axis, value + range);
+ return {
+ lo: start.lo,
+ hi: end.hi
+ };
+ }
+ }
+ }
+ return {
+ lo: 0,
+ hi: data.length - 1
+ };
+ }
+ function evaluateInteractionItems(chart, axis, position, handler, intersect) {
+ var metasets = chart.getSortedVisibleDatasetMetas();
+ var value = position[axis];
+ for (var i = 0, ilen = metasets.length; i < ilen; ++i) {
+ var _metasets$i = metasets[i],
+ _index2 = _metasets$i.index,
+ data = _metasets$i.data;
+ var _binarySearch = binarySearch(metasets[i], axis, value, intersect),
+ lo = _binarySearch.lo,
+ hi = _binarySearch.hi;
+ for (var j = lo; j <= hi; ++j) {
+ var element = data[j];
+ if (!element.skip) {
+ handler(element, _index2, j);
+ }
+ }
+ }
+ }
+ function getDistanceMetricForAxis(axis) {
+ var useX = axis.indexOf('x') !== -1;
+ var useY = axis.indexOf('y') !== -1;
+ return function (pt1, pt2) {
+ var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;
+ var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;
+ return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
+ };
+ }
+ function getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) {
+ var items = [];
+ if (!includeInvisible && !chart.isPointInArea(position)) {
+ return items;
+ }
+ var evaluationFunc = function evaluationFunc(element, datasetIndex, index) {
+ if (!includeInvisible && !_isPointInArea(element, chart.chartArea, 0)) {
+ return;
+ }
+ if (element.inRange(position.x, position.y, useFinalPosition)) {
+ items.push({
+ element: element,
+ datasetIndex: datasetIndex,
+ index: index
+ });
+ }
+ };
+ evaluateInteractionItems(chart, axis, position, evaluationFunc, true);
+ return items;
+ }
+ function getNearestRadialItems(chart, position, axis, useFinalPosition) {
+ var items = [];
+ function evaluationFunc(element, datasetIndex, index) {
+ var _element$getProps = element.getProps(['startAngle', 'endAngle'], useFinalPosition),
+ startAngle = _element$getProps.startAngle,
+ endAngle = _element$getProps.endAngle;
+ var _getAngleFromPoint = getAngleFromPoint(element, {
+ x: position.x,
+ y: position.y
+ }),
+ angle = _getAngleFromPoint.angle;
+ if (_angleBetween(angle, startAngle, endAngle)) {
+ items.push({
+ element: element,
+ datasetIndex: datasetIndex,
+ index: index
+ });
+ }
+ }
+ evaluateInteractionItems(chart, axis, position, evaluationFunc);
+ return items;
+ }
+ function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) {
+ var items = [];
+ var distanceMetric = getDistanceMetricForAxis(axis);
+ var minDistance = Number.POSITIVE_INFINITY;
+ function evaluationFunc(element, datasetIndex, index) {
+ var inRange = element.inRange(position.x, position.y, useFinalPosition);
+ if (intersect && !inRange) {
+ return;
+ }
+ var center = element.getCenterPoint(useFinalPosition);
+ var pointInArea = !!includeInvisible || chart.isPointInArea(center);
+ if (!pointInArea && !inRange) {
+ return;
+ }
+ var distance = distanceMetric(position, center);
+ if (distance < minDistance) {
+ items = [{
+ element: element,
+ datasetIndex: datasetIndex,
+ index: index
+ }];
+ minDistance = distance;
+ } else if (distance === minDistance) {
+ items.push({
+ element: element,
+ datasetIndex: datasetIndex,
+ index: index
+ });
+ }
+ }
+ evaluateInteractionItems(chart, axis, position, evaluationFunc);
+ return items;
+ }
+ function getNearestItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) {
+ if (!includeInvisible && !chart.isPointInArea(position)) {
+ return [];
+ }
+ return axis === 'r' && !intersect ? getNearestRadialItems(chart, position, axis, useFinalPosition) : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible);
+ }
+ function getAxisItems(chart, position, axis, intersect, useFinalPosition) {
+ var items = [];
+ var rangeMethod = axis === 'x' ? 'inXRange' : 'inYRange';
+ var intersectsItem = false;
+ evaluateInteractionItems(chart, axis, position, function (element, datasetIndex, index) {
+ if (element[rangeMethod] && element[rangeMethod](position[axis], useFinalPosition)) {
+ items.push({
+ element: element,
+ datasetIndex: datasetIndex,
+ index: index
+ });
+ intersectsItem = intersectsItem || element.inRange(position.x, position.y, useFinalPosition);
+ }
+ });
+ if (intersect && !intersectsItem) {
+ return [];
+ }
+ return items;
+ }
+ var Interaction = {
+ evaluateInteractionItems: evaluateInteractionItems,
+ modes: {
+ index: function index(chart, e, options, useFinalPosition) {
+ var position = getRelativePosition(e, chart);
+ var axis = options.axis || 'x';
+ var includeInvisible = options.includeInvisible || false;
+ var items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible);
+ var elements = [];
+ if (!items.length) {
+ return [];
+ }
+ chart.getSortedVisibleDatasetMetas().forEach(function (meta) {
+ var index = items[0].index;
+ var element = meta.data[index];
+ if (element && !element.skip) {
+ elements.push({
+ element: element,
+ datasetIndex: meta.index,
+ index: index
+ });
+ }
+ });
+ return elements;
+ },
+ dataset: function dataset(chart, e, options, useFinalPosition) {
+ var position = getRelativePosition(e, chart);
+ var axis = options.axis || 'xy';
+ var includeInvisible = options.includeInvisible || false;
+ var items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible);
+ if (items.length > 0) {
+ var datasetIndex = items[0].datasetIndex;
+ var data = chart.getDatasetMeta(datasetIndex).data;
+ items = [];
+ for (var i = 0; i < data.length; ++i) {
+ items.push({
+ element: data[i],
+ datasetIndex: datasetIndex,
+ index: i
+ });
+ }
+ }
+ return items;
+ },
+ point: function point(chart, e, options, useFinalPosition) {
+ var position = getRelativePosition(e, chart);
+ var axis = options.axis || 'xy';
+ var includeInvisible = options.includeInvisible || false;
+ return getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible);
+ },
+ nearest: function nearest(chart, e, options, useFinalPosition) {
+ var position = getRelativePosition(e, chart);
+ var axis = options.axis || 'xy';
+ var includeInvisible = options.includeInvisible || false;
+ return getNearestItems(chart, position, axis, options.intersect, useFinalPosition, includeInvisible);
+ },
+ x: function x(chart, e, options, useFinalPosition) {
+ var position = getRelativePosition(e, chart);
+ return getAxisItems(chart, position, 'x', options.intersect, useFinalPosition);
+ },
+ y: function y(chart, e, options, useFinalPosition) {
+ var position = getRelativePosition(e, chart);
+ return getAxisItems(chart, position, 'y', options.intersect, useFinalPosition);
+ }
+ }
+ };
+ var STATIC_POSITIONS = ['left', 'top', 'right', 'bottom'];
+ function filterByPosition(array, position) {
+ return array.filter(function (v) {
+ return v.pos === position;
+ });
+ }
+ function filterDynamicPositionByAxis(array, axis) {
+ return array.filter(function (v) {
+ return STATIC_POSITIONS.indexOf(v.pos) === -1 && v.box.axis === axis;
+ });
+ }
+ function sortByWeight(array, reverse) {
+ return array.sort(function (a, b) {
+ var v0 = reverse ? b : a;
+ var v1 = reverse ? a : b;
+ return v0.weight === v1.weight ? v0.index - v1.index : v0.weight - v1.weight;
+ });
+ }
+ function wrapBoxes(boxes) {
+ var layoutBoxes = [];
+ var i, ilen, box, pos, stack, stackWeight;
+ for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) {
+ box = boxes[i];
+ var _box = box;
+ pos = _box.position;
+ var _box$options = _box.options;
+ stack = _box$options.stack;
+ var _box$options$stackWei = _box$options.stackWeight;
+ stackWeight = _box$options$stackWei === void 0 ? 1 : _box$options$stackWei;
+ layoutBoxes.push({
+ index: i,
+ box: box,
+ pos: pos,
+ horizontal: box.isHorizontal(),
+ weight: box.weight,
+ stack: stack && pos + stack,
+ stackWeight: stackWeight
+ });
+ }
+ return layoutBoxes;
+ }
+ function buildStacks(layouts) {
+ var stacks = {};
+ var _iterator5 = _createForOfIteratorHelper$1(layouts),
+ _step5;
+ try {
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
+ var wrap = _step5.value;
+ var stack = wrap.stack,
+ pos = wrap.pos,
+ stackWeight = wrap.stackWeight;
+ if (!stack || !STATIC_POSITIONS.includes(pos)) {
+ continue;
+ }
+ var _stack = stacks[stack] || (stacks[stack] = {
+ count: 0,
+ placed: 0,
+ weight: 0,
+ size: 0
+ });
+ _stack.count++;
+ _stack.weight += stackWeight;
+ }
+ } catch (err) {
+ _iterator5.e(err);
+ } finally {
+ _iterator5.f();
+ }
+ return stacks;
+ }
+ function setLayoutDims(layouts, params) {
+ var stacks = buildStacks(layouts);
+ var vBoxMaxWidth = params.vBoxMaxWidth,
+ hBoxMaxHeight = params.hBoxMaxHeight;
+ var i, ilen, layout;
+ for (i = 0, ilen = layouts.length; i < ilen; ++i) {
+ layout = layouts[i];
+ var fullSize = layout.box.fullSize;
+ var stack = stacks[layout.stack];
+ var factor = stack && layout.stackWeight / stack.weight;
+ if (layout.horizontal) {
+ layout.width = factor ? factor * vBoxMaxWidth : fullSize && params.availableWidth;
+ layout.height = hBoxMaxHeight;
+ } else {
+ layout.width = vBoxMaxWidth;
+ layout.height = factor ? factor * hBoxMaxHeight : fullSize && params.availableHeight;
+ }
+ }
+ return stacks;
+ }
+ function buildLayoutBoxes(boxes) {
+ var layoutBoxes = wrapBoxes(boxes);
+ var fullSize = sortByWeight(layoutBoxes.filter(function (wrap) {
+ return wrap.box.fullSize;
+ }), true);
+ var left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);
+ var right = sortByWeight(filterByPosition(layoutBoxes, 'right'));
+ var top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);
+ var bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));
+ var centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, 'x');
+ var centerVertical = filterDynamicPositionByAxis(layoutBoxes, 'y');
+ return {
+ fullSize: fullSize,
+ leftAndTop: left.concat(top),
+ rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal),
+ chartArea: filterByPosition(layoutBoxes, 'chartArea'),
+ vertical: left.concat(right).concat(centerVertical),
+ horizontal: top.concat(bottom).concat(centerHorizontal)
+ };
+ }
+ function getCombinedMax(maxPadding, chartArea, a, b) {
+ return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);
+ }
+ function updateMaxPadding(maxPadding, boxPadding) {
+ maxPadding.top = Math.max(maxPadding.top, boxPadding.top);
+ maxPadding.left = Math.max(maxPadding.left, boxPadding.left);
+ maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);
+ maxPadding.right = Math.max(maxPadding.right, boxPadding.right);
+ }
+ function updateDims(chartArea, params, layout, stacks) {
+ var pos = layout.pos,
+ box = layout.box;
+ var maxPadding = chartArea.maxPadding;
+ if (!isObject(pos)) {
+ if (layout.size) {
+ chartArea[pos] -= layout.size;
+ }
+ var stack = stacks[layout.stack] || {
+ size: 0,
+ count: 1
+ };
+ stack.size = Math.max(stack.size, layout.horizontal ? box.height : box.width);
+ layout.size = stack.size / stack.count;
+ chartArea[pos] += layout.size;
+ }
+ if (box.getPadding) {
+ updateMaxPadding(maxPadding, box.getPadding());
+ }
+ var newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'));
+ var newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'));
+ var widthChanged = newWidth !== chartArea.w;
+ var heightChanged = newHeight !== chartArea.h;
+ chartArea.w = newWidth;
+ chartArea.h = newHeight;
+ return layout.horizontal ? {
+ same: widthChanged,
+ other: heightChanged
+ } : {
+ same: heightChanged,
+ other: widthChanged
+ };
+ }
+ function handleMaxPadding(chartArea) {
+ var maxPadding = chartArea.maxPadding;
+ function updatePos(pos) {
+ var change = Math.max(maxPadding[pos] - chartArea[pos], 0);
+ chartArea[pos] += change;
+ return change;
+ }
+ chartArea.y += updatePos('top');
+ chartArea.x += updatePos('left');
+ updatePos('right');
+ updatePos('bottom');
+ }
+ function getMargins(horizontal, chartArea) {
+ var maxPadding = chartArea.maxPadding;
+ function marginForPositions(positions) {
+ var margin = {
+ left: 0,
+ top: 0,
+ right: 0,
+ bottom: 0
+ };
+ positions.forEach(function (pos) {
+ margin[pos] = Math.max(chartArea[pos], maxPadding[pos]);
+ });
+ return margin;
+ }
+ return horizontal ? marginForPositions(['left', 'right']) : marginForPositions(['top', 'bottom']);
+ }
+ function fitBoxes(boxes, chartArea, params, stacks) {
+ var refitBoxes = [];
+ var i, ilen, layout, box, refit, changed;
+ for (i = 0, ilen = boxes.length, refit = 0; i < ilen; ++i) {
+ layout = boxes[i];
+ box = layout.box;
+ box.update(layout.width || chartArea.w, layout.height || chartArea.h, getMargins(layout.horizontal, chartArea));
+ var _updateDims = updateDims(chartArea, params, layout, stacks),
+ same = _updateDims.same,
+ other = _updateDims.other;
+ refit |= same && refitBoxes.length;
+ changed = changed || other;
+ if (!box.fullSize) {
+ refitBoxes.push(layout);
+ }
+ }
+ return refit && fitBoxes(refitBoxes, chartArea, params, stacks) || changed;
+ }
+ function setBoxDims(box, left, top, width, height) {
+ box.top = top;
+ box.left = left;
+ box.right = left + width;
+ box.bottom = top + height;
+ box.width = width;
+ box.height = height;
+ }
+ function placeBoxes(boxes, chartArea, params, stacks) {
+ var userPadding = params.padding;
+ var x = chartArea.x,
+ y = chartArea.y;
+ var _iterator6 = _createForOfIteratorHelper$1(boxes),
+ _step6;
+ try {
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
+ var layout = _step6.value;
+ var box = layout.box;
+ var stack = stacks[layout.stack] || {
+ count: 1,
+ placed: 0,
+ weight: 1
+ };
+ var weight = layout.stackWeight / stack.weight || 1;
+ if (layout.horizontal) {
+ var width = chartArea.w * weight;
+ var height = stack.size || box.height;
+ if (defined(stack.start)) {
+ y = stack.start;
+ }
+ if (box.fullSize) {
+ setBoxDims(box, userPadding.left, y, params.outerWidth - userPadding.right - userPadding.left, height);
+ } else {
+ setBoxDims(box, chartArea.left + stack.placed, y, width, height);
+ }
+ stack.start = y;
+ stack.placed += width;
+ y = box.bottom;
+ } else {
+ var _height = chartArea.h * weight;
+ var _width = stack.size || box.width;
+ if (defined(stack.start)) {
+ x = stack.start;
+ }
+ if (box.fullSize) {
+ setBoxDims(box, x, userPadding.top, _width, params.outerHeight - userPadding.bottom - userPadding.top);
+ } else {
+ setBoxDims(box, x, chartArea.top + stack.placed, _width, _height);
+ }
+ stack.start = x;
+ stack.placed += _height;
+ x = box.right;
+ }
+ }
+ } catch (err) {
+ _iterator6.e(err);
+ } finally {
+ _iterator6.f();
+ }
+ chartArea.x = x;
+ chartArea.y = y;
+ }
+ var layouts = {
+ addBox: function addBox(chart, item) {
+ if (!chart.boxes) {
+ chart.boxes = [];
+ }
+ item.fullSize = item.fullSize || false;
+ item.position = item.position || 'top';
+ item.weight = item.weight || 0;
+ item._layers = item._layers || function () {
+ return [{
+ z: 0,
+ draw: function draw(chartArea) {
+ item.draw(chartArea);
+ }
+ }];
+ };
+ chart.boxes.push(item);
+ },
+ removeBox: function removeBox(chart, layoutItem) {
+ var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
+ if (index !== -1) {
+ chart.boxes.splice(index, 1);
+ }
+ },
+ configure: function configure(chart, item, options) {
+ item.fullSize = options.fullSize;
+ item.position = options.position;
+ item.weight = options.weight;
+ },
+ update: function update(chart, width, height, minPadding) {
+ if (!chart) {
+ return;
+ }
+ var padding = toPadding(chart.options.layout.padding);
+ var availableWidth = Math.max(width - padding.width, 0);
+ var availableHeight = Math.max(height - padding.height, 0);
+ var boxes = buildLayoutBoxes(chart.boxes);
+ var verticalBoxes = boxes.vertical;
+ var horizontalBoxes = boxes.horizontal;
+ each(chart.boxes, function (box) {
+ if (typeof box.beforeLayout === 'function') {
+ box.beforeLayout();
+ }
+ });
+ var visibleVerticalBoxCount = verticalBoxes.reduce(function (total, wrap) {
+ return wrap.box.options && wrap.box.options.display === false ? total : total + 1;
+ }, 0) || 1;
+ var params = Object.freeze({
+ outerWidth: width,
+ outerHeight: height,
+ padding: padding,
+ availableWidth: availableWidth,
+ availableHeight: availableHeight,
+ vBoxMaxWidth: availableWidth / 2 / visibleVerticalBoxCount,
+ hBoxMaxHeight: availableHeight / 2
+ });
+ var maxPadding = Object.assign({}, padding);
+ updateMaxPadding(maxPadding, toPadding(minPadding));
+ var chartArea = Object.assign({
+ maxPadding: maxPadding,
+ w: availableWidth,
+ h: availableHeight,
+ x: padding.left,
+ y: padding.top
+ }, padding);
+ var stacks = setLayoutDims(verticalBoxes.concat(horizontalBoxes), params);
+ fitBoxes(boxes.fullSize, chartArea, params, stacks);
+ fitBoxes(verticalBoxes, chartArea, params, stacks);
+ if (fitBoxes(horizontalBoxes, chartArea, params, stacks)) {
+ fitBoxes(verticalBoxes, chartArea, params, stacks);
+ }
+ handleMaxPadding(chartArea);
+ placeBoxes(boxes.leftAndTop, chartArea, params, stacks);
+ chartArea.x += chartArea.w;
+ chartArea.y += chartArea.h;
+ placeBoxes(boxes.rightAndBottom, chartArea, params, stacks);
+ chart.chartArea = {
+ left: chartArea.left,
+ top: chartArea.top,
+ right: chartArea.left + chartArea.w,
+ bottom: chartArea.top + chartArea.h,
+ height: chartArea.h,
+ width: chartArea.w
+ };
+ each(boxes.chartArea, function (layout) {
+ var box = layout.box;
+ Object.assign(box, chart.chartArea);
+ box.update(chartArea.w, chartArea.h, {
+ left: 0,
+ top: 0,
+ right: 0,
+ bottom: 0
+ });
+ });
+ }
+ };
+ var BasePlatform = /*#__PURE__*/function () {
+ function BasePlatform() {
+ _classCallCheck$1(this, BasePlatform);
+ }
+ return _createClass$1(BasePlatform, [{
+ key: "acquireContext",
+ value: function acquireContext(canvas, aspectRatio) {}
+ }, {
+ key: "releaseContext",
+ value: function releaseContext(context) {
+ return false;
+ }
+ }, {
+ key: "addEventListener",
+ value: function addEventListener(chart, type, listener) {}
+ }, {
+ key: "removeEventListener",
+ value: function removeEventListener(chart, type, listener) {}
+ }, {
+ key: "getDevicePixelRatio",
+ value: function getDevicePixelRatio() {
+ return 1;
+ }
+ }, {
+ key: "getMaximumSize",
+ value: function getMaximumSize(element, width, height, aspectRatio) {
+ width = Math.max(0, width || element.width);
+ height = height || element.height;
+ return {
+ width: width,
+ height: Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height)
+ };
+ }
+ }, {
+ key: "isAttached",
+ value: function isAttached(canvas) {
+ return true;
+ }
+ }, {
+ key: "updateConfig",
+ value: function updateConfig(config) {}
+ }]);
+ }();
+ var BasicPlatform = /*#__PURE__*/function (_BasePlatform) {
+ function BasicPlatform() {
+ _classCallCheck$1(this, BasicPlatform);
+ return _callSuper(this, BasicPlatform, arguments);
+ }
+ _inherits$1(BasicPlatform, _BasePlatform);
+ return _createClass$1(BasicPlatform, [{
+ key: "acquireContext",
+ value: function acquireContext(item) {
+ return item && item.getContext && item.getContext('2d') || null;
+ }
+ }, {
+ key: "updateConfig",
+ value: function updateConfig(config) {
+ config.options.animation = false;
+ }
+ }]);
+ }(BasePlatform);
+ var EXPANDO_KEY = '$chartjs';
+ var EVENT_TYPES = {
+ touchstart: 'mousedown',
+ touchmove: 'mousemove',
+ touchend: 'mouseup',
+ pointerenter: 'mouseenter',
+ pointerdown: 'mousedown',
+ pointermove: 'mousemove',
+ pointerup: 'mouseup',
+ pointerleave: 'mouseout',
+ pointerout: 'mouseout'
+ };
+ var isNullOrEmpty = function isNullOrEmpty(value) {
+ return value === null || value === '';
+ };
+ function initCanvas(canvas, aspectRatio) {
+ var style = canvas.style;
+ var renderHeight = canvas.getAttribute('height');
+ var renderWidth = canvas.getAttribute('width');
+ canvas[EXPANDO_KEY] = {
+ initial: {
+ height: renderHeight,
+ width: renderWidth,
+ style: {
+ display: style.display,
+ height: style.height,
+ width: style.width
+ }
+ }
+ };
+ style.display = style.display || 'block';
+ style.boxSizing = style.boxSizing || 'border-box';
+ if (isNullOrEmpty(renderWidth)) {
+ var displayWidth = readUsedSize(canvas, 'width');
+ if (displayWidth !== undefined) {
+ canvas.width = displayWidth;
+ }
+ }
+ if (isNullOrEmpty(renderHeight)) {
+ if (canvas.style.height === '') {
+ canvas.height = canvas.width / (aspectRatio || 2);
+ } else {
+ var displayHeight = readUsedSize(canvas, 'height');
+ if (displayHeight !== undefined) {
+ canvas.height = displayHeight;
+ }
+ }
+ }
+ return canvas;
+ }
+ var eventListenerOptions = supportsEventListenerOptions ? {
+ passive: true
+ } : false;
+ function addListener(node, type, listener) {
+ if (node) {
+ node.addEventListener(type, listener, eventListenerOptions);
+ }
+ }
+ function removeListener(chart, type, listener) {
+ if (chart && chart.canvas) {
+ chart.canvas.removeEventListener(type, listener, eventListenerOptions);
+ }
+ }
+ function fromNativeEvent(event, chart) {
+ var type = EVENT_TYPES[event.type] || event.type;
+ var _getRelativePosition = getRelativePosition(event, chart),
+ x = _getRelativePosition.x,
+ y = _getRelativePosition.y;
+ return {
+ type: type,
+ chart: chart,
+ "native": event,
+ x: x !== undefined ? x : null,
+ y: y !== undefined ? y : null
+ };
+ }
+ function nodeListContains(nodeList, canvas) {
+ var _iterator7 = _createForOfIteratorHelper$1(nodeList),
+ _step7;
+ try {
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
+ var node = _step7.value;
+ if (node === canvas || node.contains(canvas)) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _iterator7.e(err);
+ } finally {
+ _iterator7.f();
+ }
+ }
+ function createAttachObserver(chart, type, listener) {
+ var canvas = chart.canvas;
+ var observer = new MutationObserver(function (entries) {
+ var trigger = false;
+ var _iterator8 = _createForOfIteratorHelper$1(entries),
+ _step8;
+ try {
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
+ var entry = _step8.value;
+ trigger = trigger || nodeListContains(entry.addedNodes, canvas);
+ trigger = trigger && !nodeListContains(entry.removedNodes, canvas);
+ }
+ } catch (err) {
+ _iterator8.e(err);
+ } finally {
+ _iterator8.f();
+ }
+ if (trigger) {
+ listener();
+ }
+ });
+ observer.observe(document, {
+ childList: true,
+ subtree: true
+ });
+ return observer;
+ }
+ function createDetachObserver(chart, type, listener) {
+ var canvas = chart.canvas;
+ var observer = new MutationObserver(function (entries) {
+ var trigger = false;
+ var _iterator9 = _createForOfIteratorHelper$1(entries),
+ _step9;
+ try {
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
+ var entry = _step9.value;
+ trigger = trigger || nodeListContains(entry.removedNodes, canvas);
+ trigger = trigger && !nodeListContains(entry.addedNodes, canvas);
+ }
+ } catch (err) {
+ _iterator9.e(err);
+ } finally {
+ _iterator9.f();
+ }
+ if (trigger) {
+ listener();
+ }
+ });
+ observer.observe(document, {
+ childList: true,
+ subtree: true
+ });
+ return observer;
+ }
+ var drpListeningCharts = new Map();
+ var oldDevicePixelRatio = 0;
+ function onWindowResize() {
+ var dpr = window.devicePixelRatio;
+ if (dpr === oldDevicePixelRatio) {
+ return;
+ }
+ oldDevicePixelRatio = dpr;
+ drpListeningCharts.forEach(function (resize, chart) {
+ if (chart.currentDevicePixelRatio !== dpr) {
+ resize();
+ }
+ });
+ }
+ function listenDevicePixelRatioChanges(chart, resize) {
+ if (!drpListeningCharts.size) {
+ window.addEventListener('resize', onWindowResize);
+ }
+ drpListeningCharts.set(chart, resize);
+ }
+ function unlistenDevicePixelRatioChanges(chart) {
+ drpListeningCharts["delete"](chart);
+ if (!drpListeningCharts.size) {
+ window.removeEventListener('resize', onWindowResize);
+ }
+ }
+ function createResizeObserver(chart, type, listener) {
+ var canvas = chart.canvas;
+ var container = canvas && _getParentNode(canvas);
+ if (!container) {
+ return;
+ }
+ var resize = throttled(function (width, height) {
+ var w = container.clientWidth;
+ listener(width, height);
+ if (w < container.clientWidth) {
+ listener();
+ }
+ }, window);
+ var observer = new ResizeObserver(function (entries) {
+ var entry = entries[0];
+ var width = entry.contentRect.width;
+ var height = entry.contentRect.height;
+ if (width === 0 && height === 0) {
+ return;
+ }
+ resize(width, height);
+ });
+ observer.observe(container);
+ listenDevicePixelRatioChanges(chart, resize);
+ return observer;
+ }
+ function releaseObserver(chart, type, observer) {
+ if (observer) {
+ observer.disconnect();
+ }
+ if (type === 'resize') {
+ unlistenDevicePixelRatioChanges(chart);
+ }
+ }
+ function createProxyAndListen(chart, type, listener) {
+ var canvas = chart.canvas;
+ var proxy = throttled(function (event) {
+ if (chart.ctx !== null) {
+ listener(fromNativeEvent(event, chart));
+ }
+ }, chart);
+ addListener(canvas, type, proxy);
+ return proxy;
+ }
+ var DomPlatform = /*#__PURE__*/function (_BasePlatform2) {
+ function DomPlatform() {
+ _classCallCheck$1(this, DomPlatform);
+ return _callSuper(this, DomPlatform, arguments);
+ }
+ _inherits$1(DomPlatform, _BasePlatform2);
+ return _createClass$1(DomPlatform, [{
+ key: "acquireContext",
+ value: function acquireContext(canvas, aspectRatio) {
+ var context = canvas && canvas.getContext && canvas.getContext('2d');
+ if (context && context.canvas === canvas) {
+ initCanvas(canvas, aspectRatio);
+ return context;
+ }
+ return null;
+ }
+ }, {
+ key: "releaseContext",
+ value: function releaseContext(context) {
+ var canvas = context.canvas;
+ if (!canvas[EXPANDO_KEY]) {
+ return false;
+ }
+ var initial = canvas[EXPANDO_KEY].initial;
+ ['height', 'width'].forEach(function (prop) {
+ var value = initial[prop];
+ if (isNullOrUndef(value)) {
+ canvas.removeAttribute(prop);
+ } else {
+ canvas.setAttribute(prop, value);
+ }
+ });
+ var style = initial.style || {};
+ Object.keys(style).forEach(function (key) {
+ canvas.style[key] = style[key];
+ });
+ canvas.width = canvas.width;
+ delete canvas[EXPANDO_KEY];
+ return true;
+ }
+ }, {
+ key: "addEventListener",
+ value: function addEventListener(chart, type, listener) {
+ this.removeEventListener(chart, type);
+ var proxies = chart.$proxies || (chart.$proxies = {});
+ var handlers = {
+ attach: createAttachObserver,
+ detach: createDetachObserver,
+ resize: createResizeObserver
+ };
+ var handler = handlers[type] || createProxyAndListen;
+ proxies[type] = handler(chart, type, listener);
+ }
+ }, {
+ key: "removeEventListener",
+ value: function removeEventListener(chart, type) {
+ var proxies = chart.$proxies || (chart.$proxies = {});
+ var proxy = proxies[type];
+ if (!proxy) {
+ return;
+ }
+ var handlers = {
+ attach: releaseObserver,
+ detach: releaseObserver,
+ resize: releaseObserver
+ };
+ var handler = handlers[type] || removeListener;
+ handler(chart, type, proxy);
+ proxies[type] = undefined;
+ }
+ }, {
+ key: "getDevicePixelRatio",
+ value: function getDevicePixelRatio() {
+ return window.devicePixelRatio;
+ }
+ }, {
+ key: "getMaximumSize",
+ value: function getMaximumSize$1(canvas, width, height, aspectRatio) {
+ return getMaximumSize(canvas, width, height, aspectRatio);
+ }
+ }, {
+ key: "isAttached",
+ value: function isAttached(canvas) {
+ var container = canvas && _getParentNode(canvas);
+ return !!(container && container.isConnected);
+ }
+ }]);
+ }(BasePlatform);
+ function _detectPlatform(canvas) {
+ if (!_isDomSupported() || typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas) {
+ return BasicPlatform;
+ }
+ return DomPlatform;
+ }
+ var Element = /*#__PURE__*/function () {
+ function Element() {
+ _classCallCheck$1(this, Element);
+ _defineProperty$1(this, "x", void 0);
+ _defineProperty$1(this, "y", void 0);
+ _defineProperty$1(this, "active", false);
+ _defineProperty$1(this, "options", void 0);
+ _defineProperty$1(this, "$animations", void 0);
+ }
+ return _createClass$1(Element, [{
+ key: "tooltipPosition",
+ value: function tooltipPosition(useFinalPosition) {
+ var _this$getProps = this.getProps(['x', 'y'], useFinalPosition),
+ x = _this$getProps.x,
+ y = _this$getProps.y;
+ return {
+ x: x,
+ y: y
+ };
+ }
+ }, {
+ key: "hasValue",
+ value: function hasValue() {
+ return isNumber(this.x) && isNumber(this.y);
+ }
+ }, {
+ key: "getProps",
+ value: function getProps(props, _final) {
+ var _this8 = this;
+ var anims = this.$animations;
+ if (!_final || !anims) {
+ // let's not create an object, if not needed
+ return this;
+ }
+ var ret = {};
+ props.forEach(function (prop) {
+ ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : _this8[prop];
+ });
+ return ret;
+ }
+ }]);
+ }();
+ _defineProperty$1(Element, "defaults", {});
+ _defineProperty$1(Element, "defaultRoutes", undefined);
+ function autoSkip(scale, ticks) {
+ var tickOpts = scale.options.ticks;
+ var determinedMaxTicks = determineMaxTicks(scale);
+ var ticksLimit = Math.min(tickOpts.maxTicksLimit || determinedMaxTicks, determinedMaxTicks);
+ var majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : [];
+ var numMajorIndices = majorIndices.length;
+ var first = majorIndices[0];
+ var last = majorIndices[numMajorIndices - 1];
+ var newTicks = [];
+ if (numMajorIndices > ticksLimit) {
+ skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit);
+ return newTicks;
+ }
+ var spacing = calculateSpacing(majorIndices, ticks, ticksLimit);
+ if (numMajorIndices > 0) {
+ var i, ilen;
+ var avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null;
+ skip(ticks, newTicks, spacing, isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first);
+ for (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) {
+ skip(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]);
+ }
+ skip(ticks, newTicks, spacing, last, isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing);
+ return newTicks;
+ }
+ skip(ticks, newTicks, spacing);
+ return newTicks;
+ }
+ function determineMaxTicks(scale) {
+ var offset = scale.options.offset;
+ var tickLength = scale._tickSize();
+ var maxScale = scale._length / tickLength + (offset ? 0 : 1);
+ var maxChart = scale._maxLength / tickLength;
+ return Math.floor(Math.min(maxScale, maxChart));
+ }
+ function calculateSpacing(majorIndices, ticks, ticksLimit) {
+ var evenMajorSpacing = getEvenSpacing(majorIndices);
+ var spacing = ticks.length / ticksLimit;
+ if (!evenMajorSpacing) {
+ return Math.max(spacing, 1);
+ }
+ var factors = _factorize(evenMajorSpacing);
+ for (var i = 0, ilen = factors.length - 1; i < ilen; i++) {
+ var factor = factors[i];
+ if (factor > spacing) {
+ return factor;
+ }
+ }
+ return Math.max(spacing, 1);
+ }
+ function getMajorIndices(ticks) {
+ var result = [];
+ var i, ilen;
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
+ if (ticks[i].major) {
+ result.push(i);
+ }
+ }
+ return result;
+ }
+ function skipMajors(ticks, newTicks, majorIndices, spacing) {
+ var count = 0;
+ var next = majorIndices[0];
+ var i;
+ spacing = Math.ceil(spacing);
+ for (i = 0; i < ticks.length; i++) {
+ if (i === next) {
+ newTicks.push(ticks[i]);
+ count++;
+ next = majorIndices[count * spacing];
+ }
+ }
+ }
+ function skip(ticks, newTicks, spacing, majorStart, majorEnd) {
+ var start = valueOrDefault(majorStart, 0);
+ var end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length);
+ var count = 0;
+ var length, i, next;
+ spacing = Math.ceil(spacing);
+ if (majorEnd) {
+ length = majorEnd - majorStart;
+ spacing = length / Math.floor(length / spacing);
+ }
+ next = start;
+ while (next < 0) {
+ count++;
+ next = Math.round(start + count * spacing);
+ }
+ for (i = Math.max(start, 0); i < end; i++) {
+ if (i === next) {
+ newTicks.push(ticks[i]);
+ count++;
+ next = Math.round(start + count * spacing);
+ }
+ }
+ }
+ function getEvenSpacing(arr) {
+ var len = arr.length;
+ var i, diff;
+ if (len < 2) {
+ return false;
+ }
+ for (diff = arr[0], i = 1; i < len; ++i) {
+ if (arr[i] - arr[i - 1] !== diff) {
+ return false;
+ }
+ }
+ return diff;
+ }
+ var reverseAlign = function reverseAlign(align) {
+ return align === 'left' ? 'right' : align === 'right' ? 'left' : align;
+ };
+ var offsetFromEdge = function offsetFromEdge(scale, edge, offset) {
+ return edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset;
+ };
+ var getTicksLimit = function getTicksLimit(ticksLength, maxTicksLimit) {
+ return Math.min(maxTicksLimit || ticksLength, ticksLength);
+ };
+ function sample(arr, numItems) {
+ var result = [];
+ var increment = arr.length / numItems;
+ var len = arr.length;
+ var i = 0;
+ for (; i < len; i += increment) {
+ result.push(arr[Math.floor(i)]);
+ }
+ return result;
+ }
+ function getPixelForGridLine(scale, index, offsetGridLines) {
+ var length = scale.ticks.length;
+ var validIndex = Math.min(index, length - 1);
+ var start = scale._startPixel;
+ var end = scale._endPixel;
+ var epsilon = 1e-6;
+ var lineValue = scale.getPixelForTick(validIndex);
+ var offset;
+ if (offsetGridLines) {
+ if (length === 1) {
+ offset = Math.max(lineValue - start, end - lineValue);
+ } else if (index === 0) {
+ offset = (scale.getPixelForTick(1) - lineValue) / 2;
+ } else {
+ offset = (lineValue - scale.getPixelForTick(validIndex - 1)) / 2;
+ }
+ lineValue += validIndex < index ? offset : -offset;
+ if (lineValue < start - epsilon || lineValue > end + epsilon) {
+ return;
+ }
+ }
+ return lineValue;
+ }
+ function garbageCollect(caches, length) {
+ each(caches, function (cache) {
+ var gc = cache.gc;
+ var gcLen = gc.length / 2;
+ var i;
+ if (gcLen > length) {
+ for (i = 0; i < gcLen; ++i) {
+ delete cache.data[gc[i]];
+ }
+ gc.splice(0, gcLen);
+ }
+ });
+ }
+ function getTickMarkLength(options) {
+ return options.drawTicks ? options.tickLength : 0;
+ }
+ function getTitleHeight(options, fallback) {
+ if (!options.display) {
+ return 0;
+ }
+ var font = toFont(options.font, fallback);
+ var padding = toPadding(options.padding);
+ var lines = isArray(options.text) ? options.text.length : 1;
+ return lines * font.lineHeight + padding.height;
+ }
+ function createScaleContext(parent, scale) {
+ return createContext(parent, {
+ scale: scale,
+ type: 'scale'
+ });
+ }
+ function createTickContext(parent, index, tick) {
+ return createContext(parent, {
+ tick: tick,
+ index: index,
+ type: 'tick'
+ });
+ }
+ function titleAlign(align, position, reverse) {
+ var ret = _toLeftRightCenter(align);
+ if (reverse && position !== 'right' || !reverse && position === 'right') {
+ ret = reverseAlign(ret);
+ }
+ return ret;
+ }
+ function titleArgs(scale, offset, position, align) {
+ var top = scale.top,
+ left = scale.left,
+ bottom = scale.bottom,
+ right = scale.right,
+ chart = scale.chart;
+ var chartArea = chart.chartArea,
+ scales = chart.scales;
+ var rotation = 0;
+ var maxWidth, titleX, titleY;
+ var height = bottom - top;
+ var width = right - left;
+ if (scale.isHorizontal()) {
+ titleX = _alignStartEnd(align, left, right);
+ if (isObject(position)) {
+ var positionAxisID = Object.keys(position)[0];
+ var value = position[positionAxisID];
+ titleY = scales[positionAxisID].getPixelForValue(value) + height - offset;
+ } else if (position === 'center') {
+ titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset;
+ } else {
+ titleY = offsetFromEdge(scale, position, offset);
+ }
+ maxWidth = right - left;
+ } else {
+ if (isObject(position)) {
+ var _positionAxisID = Object.keys(position)[0];
+ var _value = position[_positionAxisID];
+ titleX = scales[_positionAxisID].getPixelForValue(_value) - width + offset;
+ } else if (position === 'center') {
+ titleX = (chartArea.left + chartArea.right) / 2 - width + offset;
+ } else {
+ titleX = offsetFromEdge(scale, position, offset);
+ }
+ titleY = _alignStartEnd(align, bottom, top);
+ rotation = position === 'left' ? -HALF_PI : HALF_PI;
+ }
+ return {
+ titleX: titleX,
+ titleY: titleY,
+ maxWidth: maxWidth,
+ rotation: rotation
+ };
+ }
+ var Scale = /*#__PURE__*/function (_Element2) {
+ function Scale(cfg) {
+ var _this9;
+ _classCallCheck$1(this, Scale);
+ _this9 = _callSuper(this, Scale);
+ _this9.id = cfg.id;
+ _this9.type = cfg.type;
+ _this9.options = undefined;
+ _this9.ctx = cfg.ctx;
+ _this9.chart = cfg.chart;
+ _this9.top = undefined;
+ _this9.bottom = undefined;
+ _this9.left = undefined;
+ _this9.right = undefined;
+ _this9.width = undefined;
+ _this9.height = undefined;
+ _this9._margins = {
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0
+ };
+ _this9.maxWidth = undefined;
+ _this9.maxHeight = undefined;
+ _this9.paddingTop = undefined;
+ _this9.paddingBottom = undefined;
+ _this9.paddingLeft = undefined;
+ _this9.paddingRight = undefined;
+ _this9.axis = undefined;
+ _this9.labelRotation = undefined;
+ _this9.min = undefined;
+ _this9.max = undefined;
+ _this9._range = undefined;
+ _this9.ticks = [];
+ _this9._gridLineItems = null;
+ _this9._labelItems = null;
+ _this9._labelSizes = null;
+ _this9._length = 0;
+ _this9._maxLength = 0;
+ _this9._longestTextCache = {};
+ _this9._startPixel = undefined;
+ _this9._endPixel = undefined;
+ _this9._reversePixels = false;
+ _this9._userMax = undefined;
+ _this9._userMin = undefined;
+ _this9._suggestedMax = undefined;
+ _this9._suggestedMin = undefined;
+ _this9._ticksLength = 0;
+ _this9._borderValue = 0;
+ _this9._cache = {};
+ _this9._dataLimitsCached = false;
+ _this9.$context = undefined;
+ return _this9;
+ }
+ _inherits$1(Scale, _Element2);
+ return _createClass$1(Scale, [{
+ key: "init",
+ value: function init(options) {
+ this.options = options.setContext(this.getContext());
+ this.axis = options.axis;
+ this._userMin = this.parse(options.min);
+ this._userMax = this.parse(options.max);
+ this._suggestedMin = this.parse(options.suggestedMin);
+ this._suggestedMax = this.parse(options.suggestedMax);
+ }
+ }, {
+ key: "parse",
+ value: function parse(raw, index) {
+ return raw;
+ }
+ }, {
+ key: "getUserBounds",
+ value: function getUserBounds() {
+ var _userMin = this._userMin,
+ _userMax = this._userMax,
+ _suggestedMin = this._suggestedMin,
+ _suggestedMax = this._suggestedMax;
+ _userMin = finiteOrDefault(_userMin, Number.POSITIVE_INFINITY);
+ _userMax = finiteOrDefault(_userMax, Number.NEGATIVE_INFINITY);
+ _suggestedMin = finiteOrDefault(_suggestedMin, Number.POSITIVE_INFINITY);
+ _suggestedMax = finiteOrDefault(_suggestedMax, Number.NEGATIVE_INFINITY);
+ return {
+ min: finiteOrDefault(_userMin, _suggestedMin),
+ max: finiteOrDefault(_userMax, _suggestedMax),
+ minDefined: isNumberFinite(_userMin),
+ maxDefined: isNumberFinite(_userMax)
+ };
+ }
+ }, {
+ key: "getMinMax",
+ value: function getMinMax(canStack) {
+ var _this$getUserBounds = this.getUserBounds(),
+ min = _this$getUserBounds.min,
+ max = _this$getUserBounds.max,
+ minDefined = _this$getUserBounds.minDefined,
+ maxDefined = _this$getUserBounds.maxDefined;
+ var range;
+ if (minDefined && maxDefined) {
+ return {
+ min: min,
+ max: max
+ };
+ }
+ var metas = this.getMatchingVisibleMetas();
+ for (var i = 0, ilen = metas.length; i < ilen; ++i) {
+ range = metas[i].controller.getMinMax(this, canStack);
+ if (!minDefined) {
+ min = Math.min(min, range.min);
+ }
+ if (!maxDefined) {
+ max = Math.max(max, range.max);
+ }
+ }
+ min = maxDefined && min > max ? max : min;
+ max = minDefined && min > max ? min : max;
+ return {
+ min: finiteOrDefault(min, finiteOrDefault(max, min)),
+ max: finiteOrDefault(max, finiteOrDefault(min, max))
+ };
+ }
+ }, {
+ key: "getPadding",
+ value: function getPadding() {
+ return {
+ left: this.paddingLeft || 0,
+ top: this.paddingTop || 0,
+ right: this.paddingRight || 0,
+ bottom: this.paddingBottom || 0
+ };
+ }
+ }, {
+ key: "getTicks",
+ value: function getTicks() {
+ return this.ticks;
+ }
+ }, {
+ key: "getLabels",
+ value: function getLabels() {
+ var data = this.chart.data;
+ return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || [];
+ }
+ }, {
+ key: "getLabelItems",
+ value: function getLabelItems() {
+ var chartArea = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.chart.chartArea;
+ var items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea));
+ return items;
+ }
+ }, {
+ key: "beforeLayout",
+ value: function beforeLayout() {
+ this._cache = {};
+ this._dataLimitsCached = false;
+ }
+ }, {
+ key: "beforeUpdate",
+ value: function beforeUpdate() {
+ callback(this.options.beforeUpdate, [this]);
+ }
+ }, {
+ key: "update",
+ value: function update(maxWidth, maxHeight, margins) {
+ var _this$options4 = this.options,
+ beginAtZero = _this$options4.beginAtZero,
+ grace = _this$options4.grace,
+ tickOpts = _this$options4.ticks;
+ var sampleSize = tickOpts.sampleSize;
+ this.beforeUpdate();
+ this.maxWidth = maxWidth;
+ this.maxHeight = maxHeight;
+ this._margins = margins = Object.assign({
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0
+ }, margins);
+ this.ticks = null;
+ this._labelSizes = null;
+ this._gridLineItems = null;
+ this._labelItems = null;
+ this.beforeSetDimensions();
+ this.setDimensions();
+ this.afterSetDimensions();
+ this._maxLength = this.isHorizontal() ? this.width + margins.left + margins.right : this.height + margins.top + margins.bottom;
+ if (!this._dataLimitsCached) {
+ this.beforeDataLimits();
+ this.determineDataLimits();
+ this.afterDataLimits();
+ this._range = _addGrace(this, grace, beginAtZero);
+ this._dataLimitsCached = true;
+ }
+ this.beforeBuildTicks();
+ this.ticks = this.buildTicks() || [];
+ this.afterBuildTicks();
+ var samplingEnabled = sampleSize < this.ticks.length;
+ this._convertTicksToLabels(samplingEnabled ? sample(this.ticks, sampleSize) : this.ticks);
+ this.configure();
+ this.beforeCalculateLabelRotation();
+ this.calculateLabelRotation();
+ this.afterCalculateLabelRotation();
+ if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto')) {
+ this.ticks = autoSkip(this, this.ticks);
+ this._labelSizes = null;
+ this.afterAutoSkip();
+ }
+ if (samplingEnabled) {
+ this._convertTicksToLabels(this.ticks);
+ }
+ this.beforeFit();
+ this.fit();
+ this.afterFit();
+ this.afterUpdate();
+ }
+ }, {
+ key: "configure",
+ value: function configure() {
+ var reversePixels = this.options.reverse;
+ var startPixel, endPixel;
+ if (this.isHorizontal()) {
+ startPixel = this.left;
+ endPixel = this.right;
+ } else {
+ startPixel = this.top;
+ endPixel = this.bottom;
+ reversePixels = !reversePixels;
+ }
+ this._startPixel = startPixel;
+ this._endPixel = endPixel;
+ this._reversePixels = reversePixels;
+ this._length = endPixel - startPixel;
+ this._alignToPixels = this.options.alignToPixels;
+ }
+ }, {
+ key: "afterUpdate",
+ value: function afterUpdate() {
+ callback(this.options.afterUpdate, [this]);
+ }
+ }, {
+ key: "beforeSetDimensions",
+ value: function beforeSetDimensions() {
+ callback(this.options.beforeSetDimensions, [this]);
+ }
+ }, {
+ key: "setDimensions",
+ value: function setDimensions() {
+ if (this.isHorizontal()) {
+ this.width = this.maxWidth;
+ this.left = 0;
+ this.right = this.width;
+ } else {
+ this.height = this.maxHeight;
+ this.top = 0;
+ this.bottom = this.height;
+ }
+ this.paddingLeft = 0;
+ this.paddingTop = 0;
+ this.paddingRight = 0;
+ this.paddingBottom = 0;
+ }
+ }, {
+ key: "afterSetDimensions",
+ value: function afterSetDimensions() {
+ callback(this.options.afterSetDimensions, [this]);
+ }
+ }, {
+ key: "_callHooks",
+ value: function _callHooks(name) {
+ this.chart.notifyPlugins(name, this.getContext());
+ callback(this.options[name], [this]);
+ }
+ }, {
+ key: "beforeDataLimits",
+ value: function beforeDataLimits() {
+ this._callHooks('beforeDataLimits');
+ }
+ }, {
+ key: "determineDataLimits",
+ value: function determineDataLimits() {}
+ }, {
+ key: "afterDataLimits",
+ value: function afterDataLimits() {
+ this._callHooks('afterDataLimits');
+ }
+ }, {
+ key: "beforeBuildTicks",
+ value: function beforeBuildTicks() {
+ this._callHooks('beforeBuildTicks');
+ }
+ }, {
+ key: "buildTicks",
+ value: function buildTicks() {
+ return [];
+ }
+ }, {
+ key: "afterBuildTicks",
+ value: function afterBuildTicks() {
+ this._callHooks('afterBuildTicks');
+ }
+ }, {
+ key: "beforeTickToLabelConversion",
+ value: function beforeTickToLabelConversion() {
+ callback(this.options.beforeTickToLabelConversion, [this]);
+ }
+ }, {
+ key: "generateTickLabels",
+ value: function generateTickLabels(ticks) {
+ var tickOpts = this.options.ticks;
+ var i, ilen, tick;
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
+ tick = ticks[i];
+ tick.label = callback(tickOpts.callback, [tick.value, i, ticks], this);
+ }
+ }
+ }, {
+ key: "afterTickToLabelConversion",
+ value: function afterTickToLabelConversion() {
+ callback(this.options.afterTickToLabelConversion, [this]);
+ }
+ }, {
+ key: "beforeCalculateLabelRotation",
+ value: function beforeCalculateLabelRotation() {
+ callback(this.options.beforeCalculateLabelRotation, [this]);
+ }
+ }, {
+ key: "calculateLabelRotation",
+ value: function calculateLabelRotation() {
+ var options = this.options;
+ var tickOpts = options.ticks;
+ var numTicks = getTicksLimit(this.ticks.length, options.ticks.maxTicksLimit);
+ var minRotation = tickOpts.minRotation || 0;
+ var maxRotation = tickOpts.maxRotation;
+ var labelRotation = minRotation;
+ var tickWidth, maxHeight, maxLabelDiagonal;
+ if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) {
+ this.labelRotation = minRotation;
+ return;
+ }
+ var labelSizes = this._getLabelSizes();
+ var maxLabelWidth = labelSizes.widest.width;
+ var maxLabelHeight = labelSizes.highest.height;
+ var maxWidth = _limitValue(this.chart.width - maxLabelWidth, 0, this.maxWidth);
+ tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1);
+ if (maxLabelWidth + 6 > tickWidth) {
+ tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1));
+ maxHeight = this.maxHeight - getTickMarkLength(options.grid) - tickOpts.padding - getTitleHeight(options.title, this.chart.options.font);
+ maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight);
+ labelRotation = toDegrees(Math.min(Math.asin(_limitValue((labelSizes.highest.height + 6) / tickWidth, -1, 1)), Math.asin(_limitValue(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin(_limitValue(maxLabelHeight / maxLabelDiagonal, -1, 1))));
+ labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation));
+ }
+ this.labelRotation = labelRotation;
+ }
+ }, {
+ key: "afterCalculateLabelRotation",
+ value: function afterCalculateLabelRotation() {
+ callback(this.options.afterCalculateLabelRotation, [this]);
+ }
+ }, {
+ key: "afterAutoSkip",
+ value: function afterAutoSkip() {}
+ }, {
+ key: "beforeFit",
+ value: function beforeFit() {
+ callback(this.options.beforeFit, [this]);
+ }
+ }, {
+ key: "fit",
+ value: function fit() {
+ var minSize = {
+ width: 0,
+ height: 0
+ };
+ var chart = this.chart,
+ _this$options5 = this.options,
+ tickOpts = _this$options5.ticks,
+ titleOpts = _this$options5.title,
+ gridOpts = _this$options5.grid;
+ var display = this._isVisible();
+ var isHorizontal = this.isHorizontal();
+ if (display) {
+ var titleHeight = getTitleHeight(titleOpts, chart.options.font);
+ if (isHorizontal) {
+ minSize.width = this.maxWidth;
+ minSize.height = getTickMarkLength(gridOpts) + titleHeight;
+ } else {
+ minSize.height = this.maxHeight;
+ minSize.width = getTickMarkLength(gridOpts) + titleHeight;
+ }
+ if (tickOpts.display && this.ticks.length) {
+ var _this$_getLabelSizes = this._getLabelSizes(),
+ first = _this$_getLabelSizes.first,
+ last = _this$_getLabelSizes.last,
+ widest = _this$_getLabelSizes.widest,
+ highest = _this$_getLabelSizes.highest;
+ var tickPadding = tickOpts.padding * 2;
+ var angleRadians = toRadians(this.labelRotation);
+ var cos = Math.cos(angleRadians);
+ var sin = Math.sin(angleRadians);
+ if (isHorizontal) {
+ var labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height;
+ minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding);
+ } else {
+ var labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height;
+ minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding);
+ }
+ this._calculatePadding(first, last, sin, cos);
+ }
+ }
+ this._handleMargins();
+ if (isHorizontal) {
+ this.width = this._length = chart.width - this._margins.left - this._margins.right;
+ this.height = minSize.height;
+ } else {
+ this.width = minSize.width;
+ this.height = this._length = chart.height - this._margins.top - this._margins.bottom;
+ }
+ }
+ }, {
+ key: "_calculatePadding",
+ value: function _calculatePadding(first, last, sin, cos) {
+ var _this$options6 = this.options,
+ _this$options6$ticks = _this$options6.ticks,
+ align = _this$options6$ticks.align,
+ padding = _this$options6$ticks.padding,
+ position = _this$options6.position;
+ var isRotated = this.labelRotation !== 0;
+ var labelsBelowTicks = position !== 'top' && this.axis === 'x';
+ if (this.isHorizontal()) {
+ var offsetLeft = this.getPixelForTick(0) - this.left;
+ var offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1);
+ var paddingLeft = 0;
+ var paddingRight = 0;
+ if (isRotated) {
+ if (labelsBelowTicks) {
+ paddingLeft = cos * first.width;
+ paddingRight = sin * last.height;
+ } else {
+ paddingLeft = sin * first.height;
+ paddingRight = cos * last.width;
+ }
+ } else if (align === 'start') {
+ paddingRight = last.width;
+ } else if (align === 'end') {
+ paddingLeft = first.width;
+ } else if (align !== 'inner') {
+ paddingLeft = first.width / 2;
+ paddingRight = last.width / 2;
+ }
+ this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0);
+ this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0);
+ } else {
+ var paddingTop = last.height / 2;
+ var paddingBottom = first.height / 2;
+ if (align === 'start') {
+ paddingTop = 0;
+ paddingBottom = first.height;
+ } else if (align === 'end') {
+ paddingTop = last.height;
+ paddingBottom = 0;
+ }
+ this.paddingTop = paddingTop + padding;
+ this.paddingBottom = paddingBottom + padding;
+ }
+ }
+ }, {
+ key: "_handleMargins",
+ value: function _handleMargins() {
+ if (this._margins) {
+ this._margins.left = Math.max(this.paddingLeft, this._margins.left);
+ this._margins.top = Math.max(this.paddingTop, this._margins.top);
+ this._margins.right = Math.max(this.paddingRight, this._margins.right);
+ this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom);
+ }
+ }
+ }, {
+ key: "afterFit",
+ value: function afterFit() {
+ callback(this.options.afterFit, [this]);
+ }
+ }, {
+ key: "isHorizontal",
+ value: function isHorizontal() {
+ var _this$options7 = this.options,
+ axis = _this$options7.axis,
+ position = _this$options7.position;
+ return position === 'top' || position === 'bottom' || axis === 'x';
+ }
+ }, {
+ key: "isFullSize",
+ value: function isFullSize() {
+ return this.options.fullSize;
+ }
+ }, {
+ key: "_convertTicksToLabels",
+ value: function _convertTicksToLabels(ticks) {
+ this.beforeTickToLabelConversion();
+ this.generateTickLabels(ticks);
+ var i, ilen;
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
+ if (isNullOrUndef(ticks[i].label)) {
+ ticks.splice(i, 1);
+ ilen--;
+ i--;
+ }
+ }
+ this.afterTickToLabelConversion();
+ }
+ }, {
+ key: "_getLabelSizes",
+ value: function _getLabelSizes() {
+ var labelSizes = this._labelSizes;
+ if (!labelSizes) {
+ var sampleSize = this.options.ticks.sampleSize;
+ var ticks = this.ticks;
+ if (sampleSize < ticks.length) {
+ ticks = sample(ticks, sampleSize);
+ }
+ this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length, this.options.ticks.maxTicksLimit);
+ }
+ return labelSizes;
+ }
+ }, {
+ key: "_computeLabelSizes",
+ value: function _computeLabelSizes(ticks, length, maxTicksLimit) {
+ var ctx = this.ctx,
+ caches = this._longestTextCache;
+ var widths = [];
+ var heights = [];
+ var increment = Math.floor(length / getTicksLimit(length, maxTicksLimit));
+ var widestLabelSize = 0;
+ var highestLabelSize = 0;
+ var i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel;
+ for (i = 0; i < length; i += increment) {
+ label = ticks[i].label;
+ tickFont = this._resolveTickFontOptions(i);
+ ctx.font = fontString = tickFont.string;
+ cache = caches[fontString] = caches[fontString] || {
+ data: {},
+ gc: []
+ };
+ lineHeight = tickFont.lineHeight;
+ width = height = 0;
+ if (!isNullOrUndef(label) && !isArray(label)) {
+ width = _measureText(ctx, cache.data, cache.gc, width, label);
+ height = lineHeight;
+ } else if (isArray(label)) {
+ for (j = 0, jlen = label.length; j < jlen; ++j) {
+ nestedLabel = label[j];
+ if (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) {
+ width = _measureText(ctx, cache.data, cache.gc, width, nestedLabel);
+ height += lineHeight;
+ }
+ }
+ }
+ widths.push(width);
+ heights.push(height);
+ widestLabelSize = Math.max(width, widestLabelSize);
+ highestLabelSize = Math.max(height, highestLabelSize);
+ }
+ garbageCollect(caches, length);
+ var widest = widths.indexOf(widestLabelSize);
+ var highest = heights.indexOf(highestLabelSize);
+ var valueAt = function valueAt(idx) {
+ return {
+ width: widths[idx] || 0,
+ height: heights[idx] || 0
+ };
+ };
+ return {
+ first: valueAt(0),
+ last: valueAt(length - 1),
+ widest: valueAt(widest),
+ highest: valueAt(highest),
+ widths: widths,
+ heights: heights
+ };
+ }
+ }, {
+ key: "getLabelForValue",
+ value: function getLabelForValue(value) {
+ return value;
+ }
+ }, {
+ key: "getPixelForValue",
+ value: function getPixelForValue(value, index) {
+ return NaN;
+ }
+ }, {
+ key: "getValueForPixel",
+ value: function getValueForPixel(pixel) {}
+ }, {
+ key: "getPixelForTick",
+ value: function getPixelForTick(index) {
+ var ticks = this.ticks;
+ if (index < 0 || index > ticks.length - 1) {
+ return null;
+ }
+ return this.getPixelForValue(ticks[index].value);
+ }
+ }, {
+ key: "getPixelForDecimal",
+ value: function getPixelForDecimal(decimal) {
+ if (this._reversePixels) {
+ decimal = 1 - decimal;
+ }
+ var pixel = this._startPixel + decimal * this._length;
+ return _int16Range(this._alignToPixels ? _alignPixel(this.chart, pixel, 0) : pixel);
+ }
+ }, {
+ key: "getDecimalForPixel",
+ value: function getDecimalForPixel(pixel) {
+ var decimal = (pixel - this._startPixel) / this._length;
+ return this._reversePixels ? 1 - decimal : decimal;
+ }
+ }, {
+ key: "getBasePixel",
+ value: function getBasePixel() {
+ return this.getPixelForValue(this.getBaseValue());
+ }
+ }, {
+ key: "getBaseValue",
+ value: function getBaseValue() {
+ var min = this.min,
+ max = this.max;
+ return min < 0 && max < 0 ? max : min > 0 && max > 0 ? min : 0;
+ }
+ }, {
+ key: "getContext",
+ value: function getContext(index) {
+ var ticks = this.ticks || [];
+ if (index >= 0 && index < ticks.length) {
+ var tick = ticks[index];
+ return tick.$context || (tick.$context = createTickContext(this.getContext(), index, tick));
+ }
+ return this.$context || (this.$context = createScaleContext(this.chart.getContext(), this));
+ }
+ }, {
+ key: "_tickSize",
+ value: function _tickSize() {
+ var optionTicks = this.options.ticks;
+ var rot = toRadians(this.labelRotation);
+ var cos = Math.abs(Math.cos(rot));
+ var sin = Math.abs(Math.sin(rot));
+ var labelSizes = this._getLabelSizes();
+ var padding = optionTicks.autoSkipPadding || 0;
+ var w = labelSizes ? labelSizes.widest.width + padding : 0;
+ var h = labelSizes ? labelSizes.highest.height + padding : 0;
+ return this.isHorizontal() ? h * cos > w * sin ? w / cos : h / sin : h * sin < w * cos ? h / cos : w / sin;
+ }
+ }, {
+ key: "_isVisible",
+ value: function _isVisible() {
+ var display = this.options.display;
+ if (display !== 'auto') {
+ return !!display;
+ }
+ return this.getMatchingVisibleMetas().length > 0;
+ }
+ }, {
+ key: "_computeGridLineItems",
+ value: function _computeGridLineItems(chartArea) {
+ var axis = this.axis;
+ var chart = this.chart;
+ var options = this.options;
+ var grid = options.grid,
+ position = options.position,
+ border = options.border;
+ var offset = grid.offset;
+ var isHorizontal = this.isHorizontal();
+ var ticks = this.ticks;
+ var ticksLength = ticks.length + (offset ? 1 : 0);
+ var tl = getTickMarkLength(grid);
+ var items = [];
+ var borderOpts = border.setContext(this.getContext());
+ var axisWidth = borderOpts.display ? borderOpts.width : 0;
+ var axisHalfWidth = axisWidth / 2;
+ var alignBorderValue = function alignBorderValue(pixel) {
+ return _alignPixel(chart, pixel, axisWidth);
+ };
+ var borderValue, i, lineValue, alignedLineValue;
+ var tx1, ty1, tx2, ty2, x1, y1, x2, y2;
+ if (position === 'top') {
+ borderValue = alignBorderValue(this.bottom);
+ ty1 = this.bottom - tl;
+ ty2 = borderValue - axisHalfWidth;
+ y1 = alignBorderValue(chartArea.top) + axisHalfWidth;
+ y2 = chartArea.bottom;
+ } else if (position === 'bottom') {
+ borderValue = alignBorderValue(this.top);
+ y1 = chartArea.top;
+ y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth;
+ ty1 = borderValue + axisHalfWidth;
+ ty2 = this.top + tl;
+ } else if (position === 'left') {
+ borderValue = alignBorderValue(this.right);
+ tx1 = this.right - tl;
+ tx2 = borderValue - axisHalfWidth;
+ x1 = alignBorderValue(chartArea.left) + axisHalfWidth;
+ x2 = chartArea.right;
+ } else if (position === 'right') {
+ borderValue = alignBorderValue(this.left);
+ x1 = chartArea.left;
+ x2 = alignBorderValue(chartArea.right) - axisHalfWidth;
+ tx1 = borderValue + axisHalfWidth;
+ tx2 = this.left + tl;
+ } else if (axis === 'x') {
+ if (position === 'center') {
+ borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5);
+ } else if (isObject(position)) {
+ var positionAxisID = Object.keys(position)[0];
+ var value = position[positionAxisID];
+ borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));
+ }
+ y1 = chartArea.top;
+ y2 = chartArea.bottom;
+ ty1 = borderValue + axisHalfWidth;
+ ty2 = ty1 + tl;
+ } else if (axis === 'y') {
+ if (position === 'center') {
+ borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2);
+ } else if (isObject(position)) {
+ var _positionAxisID2 = Object.keys(position)[0];
+ var _value2 = position[_positionAxisID2];
+ borderValue = alignBorderValue(this.chart.scales[_positionAxisID2].getPixelForValue(_value2));
+ }
+ tx1 = borderValue - axisHalfWidth;
+ tx2 = tx1 - tl;
+ x1 = chartArea.left;
+ x2 = chartArea.right;
+ }
+ var limit = valueOrDefault(options.ticks.maxTicksLimit, ticksLength);
+ var step = Math.max(1, Math.ceil(ticksLength / limit));
+ for (i = 0; i < ticksLength; i += step) {
+ var context = this.getContext(i);
+ var optsAtIndex = grid.setContext(context);
+ var optsAtIndexBorder = border.setContext(context);
+ var lineWidth = optsAtIndex.lineWidth;
+ var lineColor = optsAtIndex.color;
+ var borderDash = optsAtIndexBorder.dash || [];
+ var borderDashOffset = optsAtIndexBorder.dashOffset;
+ var tickWidth = optsAtIndex.tickWidth;
+ var tickColor = optsAtIndex.tickColor;
+ var tickBorderDash = optsAtIndex.tickBorderDash || [];
+ var tickBorderDashOffset = optsAtIndex.tickBorderDashOffset;
+ lineValue = getPixelForGridLine(this, i, offset);
+ if (lineValue === undefined) {
+ continue;
+ }
+ alignedLineValue = _alignPixel(chart, lineValue, lineWidth);
+ if (isHorizontal) {
+ tx1 = tx2 = x1 = x2 = alignedLineValue;
+ } else {
+ ty1 = ty2 = y1 = y2 = alignedLineValue;
+ }
+ items.push({
+ tx1: tx1,
+ ty1: ty1,
+ tx2: tx2,
+ ty2: ty2,
+ x1: x1,
+ y1: y1,
+ x2: x2,
+ y2: y2,
+ width: lineWidth,
+ color: lineColor,
+ borderDash: borderDash,
+ borderDashOffset: borderDashOffset,
+ tickWidth: tickWidth,
+ tickColor: tickColor,
+ tickBorderDash: tickBorderDash,
+ tickBorderDashOffset: tickBorderDashOffset
+ });
+ }
+ this._ticksLength = ticksLength;
+ this._borderValue = borderValue;
+ return items;
+ }
+ }, {
+ key: "_computeLabelItems",
+ value: function _computeLabelItems(chartArea) {
+ var axis = this.axis;
+ var options = this.options;
+ var position = options.position,
+ optionTicks = options.ticks;
+ var isHorizontal = this.isHorizontal();
+ var ticks = this.ticks;
+ var align = optionTicks.align,
+ crossAlign = optionTicks.crossAlign,
+ padding = optionTicks.padding,
+ mirror = optionTicks.mirror;
+ var tl = getTickMarkLength(options.grid);
+ var tickAndPadding = tl + padding;
+ var hTickAndPadding = mirror ? -padding : tickAndPadding;
+ var rotation = -toRadians(this.labelRotation);
+ var items = [];
+ var i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;
+ var textBaseline = 'middle';
+ if (position === 'top') {
+ y = this.bottom - hTickAndPadding;
+ textAlign = this._getXAxisLabelAlignment();
+ } else if (position === 'bottom') {
+ y = this.top + hTickAndPadding;
+ textAlign = this._getXAxisLabelAlignment();
+ } else if (position === 'left') {
+ var ret = this._getYAxisLabelAlignment(tl);
+ textAlign = ret.textAlign;
+ x = ret.x;
+ } else if (position === 'right') {
+ var _ret = this._getYAxisLabelAlignment(tl);
+ textAlign = _ret.textAlign;
+ x = _ret.x;
+ } else if (axis === 'x') {
+ if (position === 'center') {
+ y = (chartArea.top + chartArea.bottom) / 2 + tickAndPadding;
+ } else if (isObject(position)) {
+ var positionAxisID = Object.keys(position)[0];
+ var value = position[positionAxisID];
+ y = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding;
+ }
+ textAlign = this._getXAxisLabelAlignment();
+ } else if (axis === 'y') {
+ if (position === 'center') {
+ x = (chartArea.left + chartArea.right) / 2 - tickAndPadding;
+ } else if (isObject(position)) {
+ var _positionAxisID3 = Object.keys(position)[0];
+ var _value3 = position[_positionAxisID3];
+ x = this.chart.scales[_positionAxisID3].getPixelForValue(_value3);
+ }
+ textAlign = this._getYAxisLabelAlignment(tl).textAlign;
+ }
+ if (axis === 'y') {
+ if (align === 'start') {
+ textBaseline = 'top';
+ } else if (align === 'end') {
+ textBaseline = 'bottom';
+ }
+ }
+ var labelSizes = this._getLabelSizes();
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ tick = ticks[i];
+ label = tick.label;
+ var optsAtIndex = optionTicks.setContext(this.getContext(i));
+ pixel = this.getPixelForTick(i) + optionTicks.labelOffset;
+ font = this._resolveTickFontOptions(i);
+ lineHeight = font.lineHeight;
+ lineCount = isArray(label) ? label.length : 1;
+ var halfCount = lineCount / 2;
+ var color = optsAtIndex.color;
+ var strokeColor = optsAtIndex.textStrokeColor;
+ var strokeWidth = optsAtIndex.textStrokeWidth;
+ var tickTextAlign = textAlign;
+ if (isHorizontal) {
+ x = pixel;
+ if (textAlign === 'inner') {
+ if (i === ilen - 1) {
+ tickTextAlign = !this.options.reverse ? 'right' : 'left';
+ } else if (i === 0) {
+ tickTextAlign = !this.options.reverse ? 'left' : 'right';
+ } else {
+ tickTextAlign = 'center';
+ }
+ }
+ if (position === 'top') {
+ if (crossAlign === 'near' || rotation !== 0) {
+ textOffset = -lineCount * lineHeight + lineHeight / 2;
+ } else if (crossAlign === 'center') {
+ textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight;
+ } else {
+ textOffset = -labelSizes.highest.height + lineHeight / 2;
+ }
+ } else {
+ if (crossAlign === 'near' || rotation !== 0) {
+ textOffset = lineHeight / 2;
+ } else if (crossAlign === 'center') {
+ textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight;
+ } else {
+ textOffset = labelSizes.highest.height - lineCount * lineHeight;
+ }
+ }
+ if (mirror) {
+ textOffset *= -1;
+ }
+ if (rotation !== 0 && !optsAtIndex.showLabelBackdrop) {
+ x += lineHeight / 2 * Math.sin(rotation);
+ }
+ } else {
+ y = pixel;
+ textOffset = (1 - lineCount) * lineHeight / 2;
+ }
+ var backdrop = void 0;
+ if (optsAtIndex.showLabelBackdrop) {
+ var labelPadding = toPadding(optsAtIndex.backdropPadding);
+ var height = labelSizes.heights[i];
+ var width = labelSizes.widths[i];
+ var top = textOffset - labelPadding.top;
+ var left = 0 - labelPadding.left;
+ switch (textBaseline) {
+ case 'middle':
+ top -= height / 2;
+ break;
+ case 'bottom':
+ top -= height;
+ break;
+ }
+ switch (textAlign) {
+ case 'center':
+ left -= width / 2;
+ break;
+ case 'right':
+ left -= width;
+ break;
+ case 'inner':
+ if (i === ilen - 1) {
+ left -= width;
+ } else if (i > 0) {
+ left -= width / 2;
+ }
+ break;
+ }
+ backdrop = {
+ left: left,
+ top: top,
+ width: width + labelPadding.width,
+ height: height + labelPadding.height,
+ color: optsAtIndex.backdropColor
+ };
+ }
+ items.push({
+ label: label,
+ font: font,
+ textOffset: textOffset,
+ options: {
+ rotation: rotation,
+ color: color,
+ strokeColor: strokeColor,
+ strokeWidth: strokeWidth,
+ textAlign: tickTextAlign,
+ textBaseline: textBaseline,
+ translation: [x, y],
+ backdrop: backdrop
+ }
+ });
+ }
+ return items;
+ }
+ }, {
+ key: "_getXAxisLabelAlignment",
+ value: function _getXAxisLabelAlignment() {
+ var _this$options8 = this.options,
+ position = _this$options8.position,
+ ticks = _this$options8.ticks;
+ var rotation = -toRadians(this.labelRotation);
+ if (rotation) {
+ return position === 'top' ? 'left' : 'right';
+ }
+ var align = 'center';
+ if (ticks.align === 'start') {
+ align = 'left';
+ } else if (ticks.align === 'end') {
+ align = 'right';
+ } else if (ticks.align === 'inner') {
+ align = 'inner';
+ }
+ return align;
+ }
+ }, {
+ key: "_getYAxisLabelAlignment",
+ value: function _getYAxisLabelAlignment(tl) {
+ var _this$options9 = this.options,
+ position = _this$options9.position,
+ _this$options9$ticks = _this$options9.ticks,
+ crossAlign = _this$options9$ticks.crossAlign,
+ mirror = _this$options9$ticks.mirror,
+ padding = _this$options9$ticks.padding;
+ var labelSizes = this._getLabelSizes();
+ var tickAndPadding = tl + padding;
+ var widest = labelSizes.widest.width;
+ var textAlign;
+ var x;
+ if (position === 'left') {
+ if (mirror) {
+ x = this.right + padding;
+ if (crossAlign === 'near') {
+ textAlign = 'left';
+ } else if (crossAlign === 'center') {
+ textAlign = 'center';
+ x += widest / 2;
+ } else {
+ textAlign = 'right';
+ x += widest;
+ }
+ } else {
+ x = this.right - tickAndPadding;
+ if (crossAlign === 'near') {
+ textAlign = 'right';
+ } else if (crossAlign === 'center') {
+ textAlign = 'center';
+ x -= widest / 2;
+ } else {
+ textAlign = 'left';
+ x = this.left;
+ }
+ }
+ } else if (position === 'right') {
+ if (mirror) {
+ x = this.left + padding;
+ if (crossAlign === 'near') {
+ textAlign = 'right';
+ } else if (crossAlign === 'center') {
+ textAlign = 'center';
+ x -= widest / 2;
+ } else {
+ textAlign = 'left';
+ x -= widest;
+ }
+ } else {
+ x = this.left + tickAndPadding;
+ if (crossAlign === 'near') {
+ textAlign = 'left';
+ } else if (crossAlign === 'center') {
+ textAlign = 'center';
+ x += widest / 2;
+ } else {
+ textAlign = 'right';
+ x = this.right;
+ }
+ }
+ } else {
+ textAlign = 'right';
+ }
+ return {
+ textAlign: textAlign,
+ x: x
+ };
+ }
+ }, {
+ key: "_computeLabelArea",
+ value: function _computeLabelArea() {
+ if (this.options.ticks.mirror) {
+ return;
+ }
+ var chart = this.chart;
+ var position = this.options.position;
+ if (position === 'left' || position === 'right') {
+ return {
+ top: 0,
+ left: this.left,
+ bottom: chart.height,
+ right: this.right
+ };
+ }
+ if (position === 'top' || position === 'bottom') {
+ return {
+ top: this.top,
+ left: 0,
+ bottom: this.bottom,
+ right: chart.width
+ };
+ }
+ }
+ }, {
+ key: "drawBackground",
+ value: function drawBackground() {
+ var ctx = this.ctx,
+ backgroundColor = this.options.backgroundColor,
+ left = this.left,
+ top = this.top,
+ width = this.width,
+ height = this.height;
+ if (backgroundColor) {
+ ctx.save();
+ ctx.fillStyle = backgroundColor;
+ ctx.fillRect(left, top, width, height);
+ ctx.restore();
+ }
+ }
+ }, {
+ key: "getLineWidthForValue",
+ value: function getLineWidthForValue(value) {
+ var grid = this.options.grid;
+ if (!this._isVisible() || !grid.display) {
+ return 0;
+ }
+ var ticks = this.ticks;
+ var index = ticks.findIndex(function (t) {
+ return t.value === value;
+ });
+ if (index >= 0) {
+ var opts = grid.setContext(this.getContext(index));
+ return opts.lineWidth;
+ }
+ return 0;
+ }
+ }, {
+ key: "drawGrid",
+ value: function drawGrid(chartArea) {
+ var grid = this.options.grid;
+ var ctx = this.ctx;
+ var items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea));
+ var i, ilen;
+ var drawLine = function drawLine(p1, p2, style) {
+ if (!style.width || !style.color) {
+ return;
+ }
+ ctx.save();
+ ctx.lineWidth = style.width;
+ ctx.strokeStyle = style.color;
+ ctx.setLineDash(style.borderDash || []);
+ ctx.lineDashOffset = style.borderDashOffset;
+ ctx.beginPath();
+ ctx.moveTo(p1.x, p1.y);
+ ctx.lineTo(p2.x, p2.y);
+ ctx.stroke();
+ ctx.restore();
+ };
+ if (grid.display) {
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
+ var item = items[i];
+ if (grid.drawOnChartArea) {
+ drawLine({
+ x: item.x1,
+ y: item.y1
+ }, {
+ x: item.x2,
+ y: item.y2
+ }, item);
+ }
+ if (grid.drawTicks) {
+ drawLine({
+ x: item.tx1,
+ y: item.ty1
+ }, {
+ x: item.tx2,
+ y: item.ty2
+ }, {
+ color: item.tickColor,
+ width: item.tickWidth,
+ borderDash: item.tickBorderDash,
+ borderDashOffset: item.tickBorderDashOffset
+ });
+ }
+ }
+ }
+ }
+ }, {
+ key: "drawBorder",
+ value: function drawBorder() {
+ var chart = this.chart,
+ ctx = this.ctx,
+ _this$options10 = this.options,
+ border = _this$options10.border,
+ grid = _this$options10.grid;
+ var borderOpts = border.setContext(this.getContext());
+ var axisWidth = border.display ? borderOpts.width : 0;
+ if (!axisWidth) {
+ return;
+ }
+ var lastLineWidth = grid.setContext(this.getContext(0)).lineWidth;
+ var borderValue = this._borderValue;
+ var x1, x2, y1, y2;
+ if (this.isHorizontal()) {
+ x1 = _alignPixel(chart, this.left, axisWidth) - axisWidth / 2;
+ x2 = _alignPixel(chart, this.right, lastLineWidth) + lastLineWidth / 2;
+ y1 = y2 = borderValue;
+ } else {
+ y1 = _alignPixel(chart, this.top, axisWidth) - axisWidth / 2;
+ y2 = _alignPixel(chart, this.bottom, lastLineWidth) + lastLineWidth / 2;
+ x1 = x2 = borderValue;
+ }
+ ctx.save();
+ ctx.lineWidth = borderOpts.width;
+ ctx.strokeStyle = borderOpts.color;
+ ctx.beginPath();
+ ctx.moveTo(x1, y1);
+ ctx.lineTo(x2, y2);
+ ctx.stroke();
+ ctx.restore();
+ }
+ }, {
+ key: "drawLabels",
+ value: function drawLabels(chartArea) {
+ var optionTicks = this.options.ticks;
+ if (!optionTicks.display) {
+ return;
+ }
+ var ctx = this.ctx;
+ var area = this._computeLabelArea();
+ if (area) {
+ clipArea(ctx, area);
+ }
+ var items = this.getLabelItems(chartArea);
+ var _iterator10 = _createForOfIteratorHelper$1(items),
+ _step10;
+ try {
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
+ var item = _step10.value;
+ var renderTextOptions = item.options;
+ var tickFont = item.font;
+ var label = item.label;
+ var y = item.textOffset;
+ renderText(ctx, label, 0, y, tickFont, renderTextOptions);
+ }
+ } catch (err) {
+ _iterator10.e(err);
+ } finally {
+ _iterator10.f();
+ }
+ if (area) {
+ unclipArea(ctx);
+ }
+ }
+ }, {
+ key: "drawTitle",
+ value: function drawTitle() {
+ var ctx = this.ctx,
+ _this$options11 = this.options,
+ position = _this$options11.position,
+ title = _this$options11.title,
+ reverse = _this$options11.reverse;
+ if (!title.display) {
+ return;
+ }
+ var font = toFont(title.font);
+ var padding = toPadding(title.padding);
+ var align = title.align;
+ var offset = font.lineHeight / 2;
+ if (position === 'bottom' || position === 'center' || isObject(position)) {
+ offset += padding.bottom;
+ if (isArray(title.text)) {
+ offset += font.lineHeight * (title.text.length - 1);
+ }
+ } else {
+ offset += padding.top;
+ }
+ var _titleArgs = titleArgs(this, offset, position, align),
+ titleX = _titleArgs.titleX,
+ titleY = _titleArgs.titleY,
+ maxWidth = _titleArgs.maxWidth,
+ rotation = _titleArgs.rotation;
+ renderText(ctx, title.text, 0, 0, font, {
+ color: title.color,
+ maxWidth: maxWidth,
+ rotation: rotation,
+ textAlign: titleAlign(align, position, reverse),
+ textBaseline: 'middle',
+ translation: [titleX, titleY]
+ });
+ }
+ }, {
+ key: "draw",
+ value: function draw(chartArea) {
+ if (!this._isVisible()) {
+ return;
+ }
+ this.drawBackground();
+ this.drawGrid(chartArea);
+ this.drawBorder();
+ this.drawTitle();
+ this.drawLabels(chartArea);
+ }
+ }, {
+ key: "_layers",
+ value: function _layers() {
+ var _this10 = this;
+ var opts = this.options;
+ var tz = opts.ticks && opts.ticks.z || 0;
+ var gz = valueOrDefault(opts.grid && opts.grid.z, -1);
+ var bz = valueOrDefault(opts.border && opts.border.z, 0);
+ if (!this._isVisible() || this.draw !== Scale.prototype.draw) {
+ return [{
+ z: tz,
+ draw: function draw(chartArea) {
+ _this10.draw(chartArea);
+ }
+ }];
+ }
+ return [{
+ z: gz,
+ draw: function draw(chartArea) {
+ _this10.drawBackground();
+ _this10.drawGrid(chartArea);
+ _this10.drawTitle();
+ }
+ }, {
+ z: bz,
+ draw: function draw() {
+ _this10.drawBorder();
+ }
+ }, {
+ z: tz,
+ draw: function draw(chartArea) {
+ _this10.drawLabels(chartArea);
+ }
+ }];
+ }
+ }, {
+ key: "getMatchingVisibleMetas",
+ value: function getMatchingVisibleMetas(type) {
+ var metas = this.chart.getSortedVisibleDatasetMetas();
+ var axisID = this.axis + 'AxisID';
+ var result = [];
+ var i, ilen;
+ for (i = 0, ilen = metas.length; i < ilen; ++i) {
+ var meta = metas[i];
+ if (meta[axisID] === this.id && (!type || meta.type === type)) {
+ result.push(meta);
+ }
+ }
+ return result;
+ }
+ }, {
+ key: "_resolveTickFontOptions",
+ value: function _resolveTickFontOptions(index) {
+ var opts = this.options.ticks.setContext(this.getContext(index));
+ return toFont(opts.font);
+ }
+ }, {
+ key: "_maxDigits",
+ value: function _maxDigits() {
+ var fontSize = this._resolveTickFontOptions(0).lineHeight;
+ return (this.isHorizontal() ? this.width : this.height) / fontSize;
+ }
+ }]);
+ }(Element);
+ var TypedRegistry = /*#__PURE__*/function () {
+ function TypedRegistry(type, scope, override) {
+ _classCallCheck$1(this, TypedRegistry);
+ this.type = type;
+ this.scope = scope;
+ this.override = override;
+ this.items = Object.create(null);
+ }
+ return _createClass$1(TypedRegistry, [{
+ key: "isForType",
+ value: function isForType(type) {
+ return Object.prototype.isPrototypeOf.call(this.type.prototype, type.prototype);
+ }
+ }, {
+ key: "register",
+ value: function register(item) {
+ var proto = Object.getPrototypeOf(item);
+ var parentScope;
+ if (isIChartComponent(proto)) {
+ parentScope = this.register(proto);
+ }
+ var items = this.items;
+ var id = item.id;
+ var scope = this.scope + '.' + id;
+ if (!id) {
+ throw new Error('class does not have id: ' + item);
+ }
+ if (id in items) {
+ return scope;
+ }
+ items[id] = item;
+ registerDefaults(item, scope, parentScope);
+ if (this.override) {
+ defaults.override(item.id, item.overrides);
+ }
+ return scope;
+ }
+ }, {
+ key: "get",
+ value: function get(id) {
+ return this.items[id];
+ }
+ }, {
+ key: "unregister",
+ value: function unregister(item) {
+ var items = this.items;
+ var id = item.id;
+ var scope = this.scope;
+ if (id in items) {
+ delete items[id];
+ }
+ if (scope && id in defaults[scope]) {
+ delete defaults[scope][id];
+ if (this.override) {
+ delete overrides[id];
+ }
+ }
+ }
+ }]);
+ }();
+ function registerDefaults(item, scope, parentScope) {
+ var itemDefaults = merge(Object.create(null), [parentScope ? defaults.get(parentScope) : {}, defaults.get(scope), item.defaults]);
+ defaults.set(scope, itemDefaults);
+ if (item.defaultRoutes) {
+ routeDefaults(scope, item.defaultRoutes);
+ }
+ if (item.descriptors) {
+ defaults.describe(scope, item.descriptors);
+ }
+ }
+ function routeDefaults(scope, routes) {
+ Object.keys(routes).forEach(function (property) {
+ var propertyParts = property.split('.');
+ var sourceName = propertyParts.pop();
+ var sourceScope = [scope].concat(propertyParts).join('.');
+ var parts = routes[property].split('.');
+ var targetName = parts.pop();
+ var targetScope = parts.join('.');
+ defaults.route(sourceScope, sourceName, targetScope, targetName);
+ });
+ }
+ function isIChartComponent(proto) {
+ return 'id' in proto && 'defaults' in proto;
+ }
+ var Registry = /*#__PURE__*/function () {
+ function Registry() {
+ _classCallCheck$1(this, Registry);
+ this.controllers = new TypedRegistry(DatasetController, 'datasets', true);
+ this.elements = new TypedRegistry(Element, 'elements');
+ this.plugins = new TypedRegistry(Object, 'plugins');
+ this.scales = new TypedRegistry(Scale, 'scales');
+ this._typedRegistries = [this.controllers, this.scales, this.elements];
+ }
+ return _createClass$1(Registry, [{
+ key: "add",
+ value: function add() {
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ this._each('register', args);
+ }
+ }, {
+ key: "remove",
+ value: function remove() {
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args[_key2] = arguments[_key2];
+ }
+ this._each('unregister', args);
+ }
+ }, {
+ key: "addControllers",
+ value: function addControllers() {
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
+ args[_key3] = arguments[_key3];
+ }
+ this._each('register', args, this.controllers);
+ }
+ }, {
+ key: "addElements",
+ value: function addElements() {
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
+ args[_key4] = arguments[_key4];
+ }
+ this._each('register', args, this.elements);
+ }
+ }, {
+ key: "addPlugins",
+ value: function addPlugins() {
+ for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
+ args[_key5] = arguments[_key5];
+ }
+ this._each('register', args, this.plugins);
+ }
+ }, {
+ key: "addScales",
+ value: function addScales() {
+ for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
+ args[_key6] = arguments[_key6];
+ }
+ this._each('register', args, this.scales);
+ }
+ }, {
+ key: "getController",
+ value: function getController(id) {
+ return this._get(id, this.controllers, 'controller');
+ }
+ }, {
+ key: "getElement",
+ value: function getElement(id) {
+ return this._get(id, this.elements, 'element');
+ }
+ }, {
+ key: "getPlugin",
+ value: function getPlugin(id) {
+ return this._get(id, this.plugins, 'plugin');
+ }
+ }, {
+ key: "getScale",
+ value: function getScale(id) {
+ return this._get(id, this.scales, 'scale');
+ }
+ }, {
+ key: "removeControllers",
+ value: function removeControllers() {
+ for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
+ args[_key7] = arguments[_key7];
+ }
+ this._each('unregister', args, this.controllers);
+ }
+ }, {
+ key: "removeElements",
+ value: function removeElements() {
+ for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
+ args[_key8] = arguments[_key8];
+ }
+ this._each('unregister', args, this.elements);
+ }
+ }, {
+ key: "removePlugins",
+ value: function removePlugins() {
+ for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
+ args[_key9] = arguments[_key9];
+ }
+ this._each('unregister', args, this.plugins);
+ }
+ }, {
+ key: "removeScales",
+ value: function removeScales() {
+ for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
+ args[_key10] = arguments[_key10];
+ }
+ this._each('unregister', args, this.scales);
+ }
+ }, {
+ key: "_each",
+ value: function _each(method, args, typedRegistry) {
+ var _this11 = this;
+ _toConsumableArray(args).forEach(function (arg) {
+ var reg = typedRegistry || _this11._getRegistryForType(arg);
+ if (typedRegistry || reg.isForType(arg) || reg === _this11.plugins && arg.id) {
+ _this11._exec(method, reg, arg);
+ } else {
+ each(arg, function (item) {
+ var itemReg = typedRegistry || _this11._getRegistryForType(item);
+ _this11._exec(method, itemReg, item);
+ });
+ }
+ });
+ }
+ }, {
+ key: "_exec",
+ value: function _exec(method, registry, component) {
+ var camelMethod = _capitalize(method);
+ callback(component['before' + camelMethod], [], component);
+ registry[method](component);
+ callback(component['after' + camelMethod], [], component);
+ }
+ }, {
+ key: "_getRegistryForType",
+ value: function _getRegistryForType(type) {
+ for (var i = 0; i < this._typedRegistries.length; i++) {
+ var reg = this._typedRegistries[i];
+ if (reg.isForType(type)) {
+ return reg;
+ }
+ }
+ return this.plugins;
+ }
+ }, {
+ key: "_get",
+ value: function _get(id, typedRegistry, type) {
+ var item = typedRegistry.get(id);
+ if (item === undefined) {
+ throw new Error('"' + id + '" is not a registered ' + type + '.');
+ }
+ return item;
+ }
+ }]);
+ }();
+ var registry = /* #__PURE__ */new Registry();
+ var PluginService = /*#__PURE__*/function () {
+ function PluginService() {
+ _classCallCheck$1(this, PluginService);
+ this._init = [];
+ }
+ return _createClass$1(PluginService, [{
+ key: "notify",
+ value: function notify(chart, hook, args, filter) {
+ if (hook === 'beforeInit') {
+ this._init = this._createDescriptors(chart, true);
+ this._notify(this._init, chart, 'install');
+ }
+ var descriptors = filter ? this._descriptors(chart).filter(filter) : this._descriptors(chart);
+ var result = this._notify(descriptors, chart, hook, args);
+ if (hook === 'afterDestroy') {
+ this._notify(descriptors, chart, 'stop');
+ this._notify(this._init, chart, 'uninstall');
+ }
+ return result;
+ }
+ }, {
+ key: "_notify",
+ value: function _notify(descriptors, chart, hook, args) {
+ args = args || {};
+ var _iterator11 = _createForOfIteratorHelper$1(descriptors),
+ _step11;
+ try {
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
+ var descriptor = _step11.value;
+ var plugin = descriptor.plugin;
+ var method = plugin[hook];
+ var params = [chart, args, descriptor.options];
+ if (callback(method, params, plugin) === false && args.cancelable) {
+ return false;
+ }
+ }
+ } catch (err) {
+ _iterator11.e(err);
+ } finally {
+ _iterator11.f();
+ }
+ return true;
+ }
+ }, {
+ key: "invalidate",
+ value: function invalidate() {
+ if (!isNullOrUndef(this._cache)) {
+ this._oldCache = this._cache;
+ this._cache = undefined;
+ }
+ }
+ }, {
+ key: "_descriptors",
+ value: function _descriptors(chart) {
+ if (this._cache) {
+ return this._cache;
+ }
+ var descriptors = this._cache = this._createDescriptors(chart);
+ this._notifyStateChanges(chart);
+ return descriptors;
+ }
+ }, {
+ key: "_createDescriptors",
+ value: function _createDescriptors(chart, all) {
+ var config = chart && chart.config;
+ var options = valueOrDefault(config.options && config.options.plugins, {});
+ var plugins = allPlugins(config);
+ return options === false && !all ? [] : createDescriptors(chart, plugins, options, all);
+ }
+ }, {
+ key: "_notifyStateChanges",
+ value: function _notifyStateChanges(chart) {
+ var previousDescriptors = this._oldCache || [];
+ var descriptors = this._cache;
+ var diff = function diff(a, b) {
+ return a.filter(function (x) {
+ return !b.some(function (y) {
+ return x.plugin.id === y.plugin.id;
+ });
+ });
+ };
+ this._notify(diff(previousDescriptors, descriptors), chart, 'stop');
+ this._notify(diff(descriptors, previousDescriptors), chart, 'start');
+ }
+ }]);
+ }();
+ function allPlugins(config) {
+ var localIds = {};
+ var plugins = [];
+ var keys = Object.keys(registry.plugins.items);
+ for (var i = 0; i < keys.length; i++) {
+ plugins.push(registry.getPlugin(keys[i]));
+ }
+ var local = config.plugins || [];
+ for (var _i2 = 0; _i2 < local.length; _i2++) {
+ var plugin = local[_i2];
+ if (plugins.indexOf(plugin) === -1) {
+ plugins.push(plugin);
+ localIds[plugin.id] = true;
+ }
+ }
+ return {
+ plugins: plugins,
+ localIds: localIds
+ };
+ }
+ function getOpts(options, all) {
+ if (!all && options === false) {
+ return null;
+ }
+ if (options === true) {
+ return {};
+ }
+ return options;
+ }
+ function createDescriptors(chart, _ref2, options, all) {
+ var plugins = _ref2.plugins,
+ localIds = _ref2.localIds;
+ var result = [];
+ var context = chart.getContext();
+ var _iterator12 = _createForOfIteratorHelper$1(plugins),
+ _step12;
+ try {
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
+ var plugin = _step12.value;
+ var id = plugin.id;
+ var opts = getOpts(options[id], all);
+ if (opts === null) {
+ continue;
+ }
+ result.push({
+ plugin: plugin,
+ options: pluginOpts(chart.config, {
+ plugin: plugin,
+ local: localIds[id]
+ }, opts, context)
+ });
+ }
+ } catch (err) {
+ _iterator12.e(err);
+ } finally {
+ _iterator12.f();
+ }
+ return result;
+ }
+ function pluginOpts(config, _ref3, opts, context) {
+ var plugin = _ref3.plugin,
+ local = _ref3.local;
+ var keys = config.pluginScopeKeys(plugin);
+ var scopes = config.getOptionScopes(opts, keys);
+ if (local && plugin.defaults) {
+ scopes.push(plugin.defaults);
+ }
+ return config.createResolver(scopes, context, [''], {
+ scriptable: false,
+ indexable: false,
+ allKeys: true
+ });
+ }
+ function getIndexAxis(type, options) {
+ var datasetDefaults = defaults.datasets[type] || {};
+ var datasetOptions = (options.datasets || {})[type] || {};
+ return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || 'x';
+ }
+ function getAxisFromDefaultScaleID(id, indexAxis) {
+ var axis = id;
+ if (id === '_index_') {
+ axis = indexAxis;
+ } else if (id === '_value_') {
+ axis = indexAxis === 'x' ? 'y' : 'x';
+ }
+ return axis;
+ }
+ function getDefaultScaleIDFromAxis(axis, indexAxis) {
+ return axis === indexAxis ? '_index_' : '_value_';
+ }
+ function idMatchesAxis(id) {
+ if (id === 'x' || id === 'y' || id === 'r') {
+ return id;
+ }
+ }
+ function axisFromPosition(position) {
+ if (position === 'top' || position === 'bottom') {
+ return 'x';
+ }
+ if (position === 'left' || position === 'right') {
+ return 'y';
+ }
+ }
+ function determineAxis(id) {
+ if (idMatchesAxis(id)) {
+ return id;
+ }
+ for (var _len11 = arguments.length, scaleOptions = new Array(_len11 > 1 ? _len11 - 1 : 0), _key11 = 1; _key11 < _len11; _key11++) {
+ scaleOptions[_key11 - 1] = arguments[_key11];
+ }
+ for (var _i3 = 0, _scaleOptions = scaleOptions; _i3 < _scaleOptions.length; _i3++) {
+ var opts = _scaleOptions[_i3];
+ var axis = opts.axis || axisFromPosition(opts.position) || id.length > 1 && idMatchesAxis(id[0].toLowerCase());
+ if (axis) {
+ return axis;
+ }
+ }
+ throw new Error("Cannot determine type of '".concat(id, "' axis. Please provide 'axis' or 'position' option."));
+ }
+ function getAxisFromDataset(id, axis, dataset) {
+ if (dataset[axis + 'AxisID'] === id) {
+ return {
+ axis: axis
+ };
+ }
+ }
+ function retrieveAxisFromDatasets(id, config) {
+ if (config.data && config.data.datasets) {
+ var boundDs = config.data.datasets.filter(function (d) {
+ return d.xAxisID === id || d.yAxisID === id;
+ });
+ if (boundDs.length) {
+ return getAxisFromDataset(id, 'x', boundDs[0]) || getAxisFromDataset(id, 'y', boundDs[0]);
+ }
+ }
+ return {};
+ }
+ function mergeScaleConfig(config, options) {
+ var chartDefaults = overrides[config.type] || {
+ scales: {}
+ };
+ var configScales = options.scales || {};
+ var chartIndexAxis = getIndexAxis(config.type, options);
+ var scales = Object.create(null);
+ Object.keys(configScales).forEach(function (id) {
+ var scaleConf = configScales[id];
+ if (!isObject(scaleConf)) {
+ return console.error("Invalid scale configuration for scale: ".concat(id));
+ }
+ if (scaleConf._proxy) {
+ return console.warn("Ignoring resolver passed as options for scale: ".concat(id));
+ }
+ var axis = determineAxis(id, scaleConf, retrieveAxisFromDatasets(id, config), defaults.scales[scaleConf.type]);
+ var defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis);
+ var defaultScaleOptions = chartDefaults.scales || {};
+ scales[id] = mergeIf(Object.create(null), [{
+ axis: axis
+ }, scaleConf, defaultScaleOptions[axis], defaultScaleOptions[defaultId]]);
+ });
+ config.data.datasets.forEach(function (dataset) {
+ var type = dataset.type || config.type;
+ var indexAxis = dataset.indexAxis || getIndexAxis(type, options);
+ var datasetDefaults = overrides[type] || {};
+ var defaultScaleOptions = datasetDefaults.scales || {};
+ Object.keys(defaultScaleOptions).forEach(function (defaultID) {
+ var axis = getAxisFromDefaultScaleID(defaultID, indexAxis);
+ var id = dataset[axis + 'AxisID'] || axis;
+ scales[id] = scales[id] || Object.create(null);
+ mergeIf(scales[id], [{
+ axis: axis
+ }, configScales[id], defaultScaleOptions[defaultID]]);
+ });
+ });
+ Object.keys(scales).forEach(function (key) {
+ var scale = scales[key];
+ mergeIf(scale, [defaults.scales[scale.type], defaults.scale]);
+ });
+ return scales;
+ }
+ function initOptions(config) {
+ var options = config.options || (config.options = {});
+ options.plugins = valueOrDefault(options.plugins, {});
+ options.scales = mergeScaleConfig(config, options);
+ }
+ function initData(data) {
+ data = data || {};
+ data.datasets = data.datasets || [];
+ data.labels = data.labels || [];
+ return data;
+ }
+ function initConfig(config) {
+ config = config || {};
+ config.data = initData(config.data);
+ initOptions(config);
+ return config;
+ }
+ var keyCache = new Map();
+ var keysCached = new Set();
+ function cachedKeys(cacheKey, generate) {
+ var keys = keyCache.get(cacheKey);
+ if (!keys) {
+ keys = generate();
+ keyCache.set(cacheKey, keys);
+ keysCached.add(keys);
+ }
+ return keys;
+ }
+ var addIfFound = function addIfFound(set, obj, key) {
+ var opts = resolveObjectKey(obj, key);
+ if (opts !== undefined) {
+ set.add(opts);
+ }
+ };
+ var Config = /*#__PURE__*/function () {
+ function Config(config) {
+ _classCallCheck$1(this, Config);
+ this._config = initConfig(config);
+ this._scopeCache = new Map();
+ this._resolverCache = new Map();
+ }
+ return _createClass$1(Config, [{
+ key: "platform",
+ get: function get() {
+ return this._config.platform;
+ }
+ }, {
+ key: "type",
+ get: function get() {
+ return this._config.type;
+ },
+ set: function set(type) {
+ this._config.type = type;
+ }
+ }, {
+ key: "data",
+ get: function get() {
+ return this._config.data;
+ },
+ set: function set(data) {
+ this._config.data = initData(data);
+ }
+ }, {
+ key: "options",
+ get: function get() {
+ return this._config.options;
+ },
+ set: function set(options) {
+ this._config.options = options;
+ }
+ }, {
+ key: "plugins",
+ get: function get() {
+ return this._config.plugins;
+ }
+ }, {
+ key: "update",
+ value: function update() {
+ var config = this._config;
+ this.clearCache();
+ initOptions(config);
+ }
+ }, {
+ key: "clearCache",
+ value: function clearCache() {
+ this._scopeCache.clear();
+ this._resolverCache.clear();
+ }
+ }, {
+ key: "datasetScopeKeys",
+ value: function datasetScopeKeys(datasetType) {
+ return cachedKeys(datasetType, function () {
+ return [["datasets.".concat(datasetType), '']];
+ });
+ }
+ }, {
+ key: "datasetAnimationScopeKeys",
+ value: function datasetAnimationScopeKeys(datasetType, transition) {
+ return cachedKeys("".concat(datasetType, ".transition.").concat(transition), function () {
+ return [["datasets.".concat(datasetType, ".transitions.").concat(transition), "transitions.".concat(transition)], ["datasets.".concat(datasetType), '']];
+ });
+ }
+ }, {
+ key: "datasetElementScopeKeys",
+ value: function datasetElementScopeKeys(datasetType, elementType) {
+ return cachedKeys("".concat(datasetType, "-").concat(elementType), function () {
+ return [["datasets.".concat(datasetType, ".elements.").concat(elementType), "datasets.".concat(datasetType), "elements.".concat(elementType), '']];
+ });
+ }
+ }, {
+ key: "pluginScopeKeys",
+ value: function pluginScopeKeys(plugin) {
+ var id = plugin.id;
+ var type = this.type;
+ return cachedKeys("".concat(type, "-plugin-").concat(id), function () {
+ return [["plugins.".concat(id)].concat(_toConsumableArray(plugin.additionalOptionScopes || []))];
+ });
+ }
+ }, {
+ key: "_cachedScopes",
+ value: function _cachedScopes(mainScope, resetCache) {
+ var _scopeCache = this._scopeCache;
+ var cache = _scopeCache.get(mainScope);
+ if (!cache || resetCache) {
+ cache = new Map();
+ _scopeCache.set(mainScope, cache);
+ }
+ return cache;
+ }
+ }, {
+ key: "getOptionScopes",
+ value: function getOptionScopes(mainScope, keyLists, resetCache) {
+ var options = this.options,
+ type = this.type;
+ var cache = this._cachedScopes(mainScope, resetCache);
+ var cached = cache.get(keyLists);
+ if (cached) {
+ return cached;
+ }
+ var scopes = new Set();
+ keyLists.forEach(function (keys) {
+ if (mainScope) {
+ scopes.add(mainScope);
+ keys.forEach(function (key) {
+ return addIfFound(scopes, mainScope, key);
+ });
+ }
+ keys.forEach(function (key) {
+ return addIfFound(scopes, options, key);
+ });
+ keys.forEach(function (key) {
+ return addIfFound(scopes, overrides[type] || {}, key);
+ });
+ keys.forEach(function (key) {
+ return addIfFound(scopes, defaults, key);
+ });
+ keys.forEach(function (key) {
+ return addIfFound(scopes, descriptors, key);
+ });
+ });
+ var array = Array.from(scopes);
+ if (array.length === 0) {
+ array.push(Object.create(null));
+ }
+ if (keysCached.has(keyLists)) {
+ cache.set(keyLists, array);
+ }
+ return array;
+ }
+ }, {
+ key: "chartOptionScopes",
+ value: function chartOptionScopes() {
+ var options = this.options,
+ type = this.type;
+ return [options, overrides[type] || {}, defaults.datasets[type] || {}, {
+ type: type
+ }, defaults, descriptors];
+ }
+ }, {
+ key: "resolveNamedOptions",
+ value: function resolveNamedOptions(scopes, names, context) {
+ var prefixes = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [''];
+ var result = {
+ $shared: true
+ };
+ var _getResolver = getResolver(this._resolverCache, scopes, prefixes),
+ resolver = _getResolver.resolver,
+ subPrefixes = _getResolver.subPrefixes;
+ var options = resolver;
+ if (needContext(resolver, names)) {
+ result.$shared = false;
+ context = isFunction(context) ? context() : context;
+ var subResolver = this.createResolver(scopes, context, subPrefixes);
+ options = _attachContext(resolver, context, subResolver);
+ }
+ var _iterator13 = _createForOfIteratorHelper$1(names),
+ _step13;
+ try {
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
+ var prop = _step13.value;
+ result[prop] = options[prop];
+ }
+ } catch (err) {
+ _iterator13.e(err);
+ } finally {
+ _iterator13.f();
+ }
+ return result;
+ }
+ }, {
+ key: "createResolver",
+ value: function createResolver(scopes, context) {
+ var prefixes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [''];
+ var descriptorDefaults = arguments.length > 3 ? arguments[3] : undefined;
+ var _getResolver2 = getResolver(this._resolverCache, scopes, prefixes),
+ resolver = _getResolver2.resolver;
+ return isObject(context) ? _attachContext(resolver, context, undefined, descriptorDefaults) : resolver;
+ }
+ }]);
+ }();
+ function getResolver(resolverCache, scopes, prefixes) {
+ var cache = resolverCache.get(scopes);
+ if (!cache) {
+ cache = new Map();
+ resolverCache.set(scopes, cache);
+ }
+ var cacheKey = prefixes.join();
+ var cached = cache.get(cacheKey);
+ if (!cached) {
+ var resolver = _createResolver(scopes, prefixes);
+ cached = {
+ resolver: resolver,
+ subPrefixes: prefixes.filter(function (p) {
+ return !p.toLowerCase().includes('hover');
+ })
+ };
+ cache.set(cacheKey, cached);
+ }
+ return cached;
+ }
+ var hasFunction = function hasFunction(value) {
+ return isObject(value) && Object.getOwnPropertyNames(value).some(function (key) {
+ return isFunction(value[key]);
+ });
+ };
+ function needContext(proxy, names) {
+ var _descriptors2 = _descriptors(proxy),
+ isScriptable = _descriptors2.isScriptable,
+ isIndexable = _descriptors2.isIndexable;
+ var _iterator14 = _createForOfIteratorHelper$1(names),
+ _step14;
+ try {
+ for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
+ var prop = _step14.value;
+ var scriptable = isScriptable(prop);
+ var indexable = isIndexable(prop);
+ var value = (indexable || scriptable) && proxy[prop];
+ if (scriptable && (isFunction(value) || hasFunction(value)) || indexable && isArray(value)) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _iterator14.e(err);
+ } finally {
+ _iterator14.f();
+ }
+ return false;
+ }
+ var version = "4.4.8";
+ var KNOWN_POSITIONS = ['top', 'bottom', 'left', 'right', 'chartArea'];
+ function positionIsHorizontal(position, axis) {
+ return position === 'top' || position === 'bottom' || KNOWN_POSITIONS.indexOf(position) === -1 && axis === 'x';
+ }
+ function compare2Level(l1, l2) {
+ return function (a, b) {
+ return a[l1] === b[l1] ? a[l2] - b[l2] : a[l1] - b[l1];
+ };
+ }
+ function onAnimationsComplete(context) {
+ var chart = context.chart;
+ var animationOptions = chart.options.animation;
+ chart.notifyPlugins('afterRender');
+ callback(animationOptions && animationOptions.onComplete, [context], chart);
+ }
+ function onAnimationProgress(context) {
+ var chart = context.chart;
+ var animationOptions = chart.options.animation;
+ callback(animationOptions && animationOptions.onProgress, [context], chart);
+ }
+ function getCanvas(item) {
+ if (_isDomSupported() && typeof item === 'string') {
+ item = document.getElementById(item);
+ } else if (item && item.length) {
+ item = item[0];
+ }
+ if (item && item.canvas) {
+ item = item.canvas;
+ }
+ return item;
+ }
+ var instances = {};
+ var getChart = function getChart(key) {
+ var canvas = getCanvas(key);
+ return Object.values(instances).filter(function (c) {
+ return c.canvas === canvas;
+ }).pop();
+ };
+ function moveNumericKeys(obj, start, move) {
+ var keys = Object.keys(obj);
+ for (var _i4 = 0, _keys = keys; _i4 < _keys.length; _i4++) {
+ var key = _keys[_i4];
+ var intKey = +key;
+ if (intKey >= start) {
+ var value = obj[key];
+ delete obj[key];
+ if (move > 0 || intKey > start) {
+ obj[intKey + move] = value;
+ }
+ }
+ }
+ }
+ function determineLastEvent(e, lastEvent, inChartArea, isClick) {
+ if (!inChartArea || e.type === 'mouseout') {
+ return null;
+ }
+ if (isClick) {
+ return lastEvent;
+ }
+ return e;
+ }
+ function getSizeForArea(scale, chartArea, field) {
+ return scale.options.clip ? scale[field] : chartArea[field];
+ }
+ function getDatasetArea(meta, chartArea) {
+ var xScale = meta.xScale,
+ yScale = meta.yScale;
+ if (xScale && yScale) {
+ return {
+ left: getSizeForArea(xScale, chartArea, 'left'),
+ right: getSizeForArea(xScale, chartArea, 'right'),
+ top: getSizeForArea(yScale, chartArea, 'top'),
+ bottom: getSizeForArea(yScale, chartArea, 'bottom')
+ };
+ }
+ return chartArea;
+ }
+ var Chart = /*#__PURE__*/function () {
+ function Chart(item, userConfig) {
+ var _this12 = this;
+ _classCallCheck$1(this, Chart);
+ var config = this.config = new Config(userConfig);
+ var initialCanvas = getCanvas(item);
+ var existingChart = getChart(initialCanvas);
+ if (existingChart) {
+ throw new Error('Canvas is already in use. Chart with ID \'' + existingChart.id + '\'' + ' must be destroyed before the canvas with ID \'' + existingChart.canvas.id + '\' can be reused.');
+ }
+ var options = config.createResolver(config.chartOptionScopes(), this.getContext());
+ this.platform = new (config.platform || _detectPlatform(initialCanvas))();
+ this.platform.updateConfig(config);
+ var context = this.platform.acquireContext(initialCanvas, options.aspectRatio);
+ var canvas = context && context.canvas;
+ var height = canvas && canvas.height;
+ var width = canvas && canvas.width;
+ this.id = uid();
+ this.ctx = context;
+ this.canvas = canvas;
+ this.width = width;
+ this.height = height;
+ this._options = options;
+ this._aspectRatio = this.aspectRatio;
+ this._layers = [];
+ this._metasets = [];
+ this._stacks = undefined;
+ this.boxes = [];
+ this.currentDevicePixelRatio = undefined;
+ this.chartArea = undefined;
+ this._active = [];
+ this._lastEvent = undefined;
+ this._listeners = {};
+ this._responsiveListeners = undefined;
+ this._sortedMetasets = [];
+ this.scales = {};
+ this._plugins = new PluginService();
+ this.$proxies = {};
+ this._hiddenIndices = {};
+ this.attached = false;
+ this._animationsDisabled = undefined;
+ this.$context = undefined;
+ this._doResize = debounce(function (mode) {
+ return _this12.update(mode);
+ }, options.resizeDelay || 0);
+ this._dataChanges = [];
+ instances[this.id] = this;
+ if (!context || !canvas) {
+ console.error("Failed to create chart: can't acquire context from the given item");
+ return;
+ }
+ animator.listen(this, 'complete', onAnimationsComplete);
+ animator.listen(this, 'progress', onAnimationProgress);
+ this._initialize();
+ if (this.attached) {
+ this.update();
+ }
+ }
+ return _createClass$1(Chart, [{
+ key: "aspectRatio",
+ get: function get() {
+ var _this$options12 = this.options,
+ aspectRatio = _this$options12.aspectRatio,
+ maintainAspectRatio = _this$options12.maintainAspectRatio,
+ width = this.width,
+ height = this.height,
+ _aspectRatio = this._aspectRatio;
+ if (!isNullOrUndef(aspectRatio)) {
+ return aspectRatio;
+ }
+ if (maintainAspectRatio && _aspectRatio) {
+ return _aspectRatio;
+ }
+ return height ? width / height : null;
+ }
+ }, {
+ key: "data",
+ get: function get() {
+ return this.config.data;
+ },
+ set: function set(data) {
+ this.config.data = data;
+ }
+ }, {
+ key: "options",
+ get: function get() {
+ return this._options;
+ },
+ set: function set(options) {
+ this.config.options = options;
+ }
+ }, {
+ key: "registry",
+ get: function get() {
+ return registry;
+ }
+ }, {
+ key: "_initialize",
+ value: function _initialize() {
+ this.notifyPlugins('beforeInit');
+ if (this.options.responsive) {
+ this.resize();
+ } else {
+ retinaScale(this, this.options.devicePixelRatio);
+ }
+ this.bindEvents();
+ this.notifyPlugins('afterInit');
+ return this;
+ }
+ }, {
+ key: "clear",
+ value: function clear() {
+ clearCanvas(this.canvas, this.ctx);
+ return this;
+ }
+ }, {
+ key: "stop",
+ value: function stop() {
+ animator.stop(this);
+ return this;
+ }
+ }, {
+ key: "resize",
+ value: function resize(width, height) {
+ if (!animator.running(this)) {
+ this._resize(width, height);
+ } else {
+ this._resizeBeforeDraw = {
+ width: width,
+ height: height
+ };
+ }
+ }
+ }, {
+ key: "_resize",
+ value: function _resize(width, height) {
+ var options = this.options;
+ var canvas = this.canvas;
+ var aspectRatio = options.maintainAspectRatio && this.aspectRatio;
+ var newSize = this.platform.getMaximumSize(canvas, width, height, aspectRatio);
+ var newRatio = options.devicePixelRatio || this.platform.getDevicePixelRatio();
+ var mode = this.width ? 'resize' : 'attach';
+ this.width = newSize.width;
+ this.height = newSize.height;
+ this._aspectRatio = this.aspectRatio;
+ if (!retinaScale(this, newRatio, true)) {
+ return;
+ }
+ this.notifyPlugins('resize', {
+ size: newSize
+ });
+ callback(options.onResize, [this, newSize], this);
+ if (this.attached) {
+ if (this._doResize(mode)) {
+ this.render();
+ }
+ }
+ }
+ }, {
+ key: "ensureScalesHaveIDs",
+ value: function ensureScalesHaveIDs() {
+ var options = this.options;
+ var scalesOptions = options.scales || {};
+ each(scalesOptions, function (axisOptions, axisID) {
+ axisOptions.id = axisID;
+ });
+ }
+ }, {
+ key: "buildOrUpdateScales",
+ value: function buildOrUpdateScales() {
+ var _this13 = this;
+ var options = this.options;
+ var scaleOpts = options.scales;
+ var scales = this.scales;
+ var updated = Object.keys(scales).reduce(function (obj, id) {
+ obj[id] = false;
+ return obj;
+ }, {});
+ var items = [];
+ if (scaleOpts) {
+ items = items.concat(Object.keys(scaleOpts).map(function (id) {
+ var scaleOptions = scaleOpts[id];
+ var axis = determineAxis(id, scaleOptions);
+ var isRadial = axis === 'r';
+ var isHorizontal = axis === 'x';
+ return {
+ options: scaleOptions,
+ dposition: isRadial ? 'chartArea' : isHorizontal ? 'bottom' : 'left',
+ dtype: isRadial ? 'radialLinear' : isHorizontal ? 'category' : 'linear'
+ };
+ }));
+ }
+ each(items, function (item) {
+ var scaleOptions = item.options;
+ var id = scaleOptions.id;
+ var axis = determineAxis(id, scaleOptions);
+ var scaleType = valueOrDefault(scaleOptions.type, item.dtype);
+ if (scaleOptions.position === undefined || positionIsHorizontal(scaleOptions.position, axis) !== positionIsHorizontal(item.dposition)) {
+ scaleOptions.position = item.dposition;
+ }
+ updated[id] = true;
+ var scale = null;
+ if (id in scales && scales[id].type === scaleType) {
+ scale = scales[id];
+ } else {
+ var scaleClass = registry.getScale(scaleType);
+ scale = new scaleClass({
+ id: id,
+ type: scaleType,
+ ctx: _this13.ctx,
+ chart: _this13
+ });
+ scales[scale.id] = scale;
+ }
+ scale.init(scaleOptions, options);
+ });
+ each(updated, function (hasUpdated, id) {
+ if (!hasUpdated) {
+ delete scales[id];
+ }
+ });
+ each(scales, function (scale) {
+ layouts.configure(_this13, scale, scale.options);
+ layouts.addBox(_this13, scale);
+ });
+ }
+ }, {
+ key: "_updateMetasets",
+ value: function _updateMetasets() {
+ var metasets = this._metasets;
+ var numData = this.data.datasets.length;
+ var numMeta = metasets.length;
+ metasets.sort(function (a, b) {
+ return a.index - b.index;
+ });
+ if (numMeta > numData) {
+ for (var i = numData; i < numMeta; ++i) {
+ this._destroyDatasetMeta(i);
+ }
+ metasets.splice(numData, numMeta - numData);
+ }
+ this._sortedMetasets = metasets.slice(0).sort(compare2Level('order', 'index'));
+ }
+ }, {
+ key: "_removeUnreferencedMetasets",
+ value: function _removeUnreferencedMetasets() {
+ var _this14 = this;
+ var metasets = this._metasets,
+ datasets = this.data.datasets;
+ if (metasets.length > datasets.length) {
+ delete this._stacks;
+ }
+ metasets.forEach(function (meta, index) {
+ if (datasets.filter(function (x) {
+ return x === meta._dataset;
+ }).length === 0) {
+ _this14._destroyDatasetMeta(index);
+ }
+ });
+ }
+ }, {
+ key: "buildOrUpdateControllers",
+ value: function buildOrUpdateControllers() {
+ var newControllers = [];
+ var datasets = this.data.datasets;
+ var i, ilen;
+ this._removeUnreferencedMetasets();
+ for (i = 0, ilen = datasets.length; i < ilen; i++) {
+ var dataset = datasets[i];
+ var meta = this.getDatasetMeta(i);
+ var type = dataset.type || this.config.type;
+ if (meta.type && meta.type !== type) {
+ this._destroyDatasetMeta(i);
+ meta = this.getDatasetMeta(i);
+ }
+ meta.type = type;
+ meta.indexAxis = dataset.indexAxis || getIndexAxis(type, this.options);
+ meta.order = dataset.order || 0;
+ meta.index = i;
+ meta.label = '' + dataset.label;
+ meta.visible = this.isDatasetVisible(i);
+ if (meta.controller) {
+ meta.controller.updateIndex(i);
+ meta.controller.linkScales();
+ } else {
+ var ControllerClass = registry.getController(type);
+ var _defaults$datasets$ty = defaults.datasets[type],
+ datasetElementType = _defaults$datasets$ty.datasetElementType,
+ dataElementType = _defaults$datasets$ty.dataElementType;
+ Object.assign(ControllerClass, {
+ dataElementType: registry.getElement(dataElementType),
+ datasetElementType: datasetElementType && registry.getElement(datasetElementType)
+ });
+ meta.controller = new ControllerClass(this, i);
+ newControllers.push(meta.controller);
+ }
+ }
+ this._updateMetasets();
+ return newControllers;
+ }
+ }, {
+ key: "_resetElements",
+ value: function _resetElements() {
+ var _this15 = this;
+ each(this.data.datasets, function (dataset, datasetIndex) {
+ _this15.getDatasetMeta(datasetIndex).controller.reset();
+ }, this);
+ }
+ }, {
+ key: "reset",
+ value: function reset() {
+ this._resetElements();
+ this.notifyPlugins('reset');
+ }
+ }, {
+ key: "update",
+ value: function update(mode) {
+ var config = this.config;
+ config.update();
+ var options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext());
+ var animsDisabled = this._animationsDisabled = !options.animation;
+ this._updateScales();
+ this._checkEventBindings();
+ this._updateHiddenIndices();
+ this._plugins.invalidate();
+ if (this.notifyPlugins('beforeUpdate', {
+ mode: mode,
+ cancelable: true
+ }) === false) {
+ return;
+ }
+ var newControllers = this.buildOrUpdateControllers();
+ this.notifyPlugins('beforeElementsUpdate');
+ var minPadding = 0;
+ for (var i = 0, ilen = this.data.datasets.length; i < ilen; i++) {
+ var _this$getDatasetMeta = this.getDatasetMeta(i),
+ controller = _this$getDatasetMeta.controller;
+ var reset = !animsDisabled && newControllers.indexOf(controller) === -1;
+ controller.buildOrUpdateElements(reset);
+ minPadding = Math.max(+controller.getMaxOverflow(), minPadding);
+ }
+ minPadding = this._minPadding = options.layout.autoPadding ? minPadding : 0;
+ this._updateLayout(minPadding);
+ if (!animsDisabled) {
+ each(newControllers, function (controller) {
+ controller.reset();
+ });
+ }
+ this._updateDatasets(mode);
+ this.notifyPlugins('afterUpdate', {
+ mode: mode
+ });
+ this._layers.sort(compare2Level('z', '_idx'));
+ var _active = this._active,
+ _lastEvent = this._lastEvent;
+ if (_lastEvent) {
+ this._eventHandler(_lastEvent, true);
+ } else if (_active.length) {
+ this._updateHoverStyles(_active, _active, true);
+ }
+ this.render();
+ }
+ }, {
+ key: "_updateScales",
+ value: function _updateScales() {
+ var _this16 = this;
+ each(this.scales, function (scale) {
+ layouts.removeBox(_this16, scale);
+ });
+ this.ensureScalesHaveIDs();
+ this.buildOrUpdateScales();
+ }
+ }, {
+ key: "_checkEventBindings",
+ value: function _checkEventBindings() {
+ var options = this.options;
+ var existingEvents = new Set(Object.keys(this._listeners));
+ var newEvents = new Set(options.events);
+ if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {
+ this.unbindEvents();
+ this.bindEvents();
+ }
+ }
+ }, {
+ key: "_updateHiddenIndices",
+ value: function _updateHiddenIndices() {
+ var _hiddenIndices = this._hiddenIndices;
+ var changes = this._getUniformDataChanges() || [];
+ var _iterator15 = _createForOfIteratorHelper$1(changes),
+ _step15;
+ try {
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
+ var _step15$value = _step15.value,
+ method = _step15$value.method,
+ start = _step15$value.start,
+ count = _step15$value.count;
+ var move = method === '_removeElements' ? -count : count;
+ moveNumericKeys(_hiddenIndices, start, move);
+ }
+ } catch (err) {
+ _iterator15.e(err);
+ } finally {
+ _iterator15.f();
+ }
+ }
+ }, {
+ key: "_getUniformDataChanges",
+ value: function _getUniformDataChanges() {
+ var _dataChanges = this._dataChanges;
+ if (!_dataChanges || !_dataChanges.length) {
+ return;
+ }
+ this._dataChanges = [];
+ var datasetCount = this.data.datasets.length;
+ var makeSet = function makeSet(idx) {
+ return new Set(_dataChanges.filter(function (c) {
+ return c[0] === idx;
+ }).map(function (c, i) {
+ return i + ',' + c.splice(1).join(',');
+ }));
+ };
+ var changeSet = makeSet(0);
+ for (var i = 1; i < datasetCount; i++) {
+ if (!setsEqual(changeSet, makeSet(i))) {
+ return;
+ }
+ }
+ return Array.from(changeSet).map(function (c) {
+ return c.split(',');
+ }).map(function (a) {
+ return {
+ method: a[1],
+ start: +a[2],
+ count: +a[3]
+ };
+ });
+ }
+ }, {
+ key: "_updateLayout",
+ value: function _updateLayout(minPadding) {
+ var _this17 = this;
+ if (this.notifyPlugins('beforeLayout', {
+ cancelable: true
+ }) === false) {
+ return;
+ }
+ layouts.update(this, this.width, this.height, minPadding);
+ var area = this.chartArea;
+ var noArea = area.width <= 0 || area.height <= 0;
+ this._layers = [];
+ each(this.boxes, function (box) {
+ var _this17$_layers;
+ if (noArea && box.position === 'chartArea') {
+ return;
+ }
+ if (box.configure) {
+ box.configure();
+ }
+ (_this17$_layers = _this17._layers).push.apply(_this17$_layers, _toConsumableArray(box._layers()));
+ }, this);
+ this._layers.forEach(function (item, index) {
+ item._idx = index;
+ });
+ this.notifyPlugins('afterLayout');
+ }
+ }, {
+ key: "_updateDatasets",
+ value: function _updateDatasets(mode) {
+ if (this.notifyPlugins('beforeDatasetsUpdate', {
+ mode: mode,
+ cancelable: true
+ }) === false) {
+ return;
+ }
+ for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
+ this.getDatasetMeta(i).controller.configure();
+ }
+ for (var _i5 = 0, _ilen = this.data.datasets.length; _i5 < _ilen; ++_i5) {
+ this._updateDataset(_i5, isFunction(mode) ? mode({
+ datasetIndex: _i5
+ }) : mode);
+ }
+ this.notifyPlugins('afterDatasetsUpdate', {
+ mode: mode
+ });
+ }
+ }, {
+ key: "_updateDataset",
+ value: function _updateDataset(index, mode) {
+ var meta = this.getDatasetMeta(index);
+ var args = {
+ meta: meta,
+ index: index,
+ mode: mode,
+ cancelable: true
+ };
+ if (this.notifyPlugins('beforeDatasetUpdate', args) === false) {
+ return;
+ }
+ meta.controller._update(mode);
+ args.cancelable = false;
+ this.notifyPlugins('afterDatasetUpdate', args);
+ }
+ }, {
+ key: "render",
+ value: function render() {
+ if (this.notifyPlugins('beforeRender', {
+ cancelable: true
+ }) === false) {
+ return;
+ }
+ if (animator.has(this)) {
+ if (this.attached && !animator.running(this)) {
+ animator.start(this);
+ }
+ } else {
+ this.draw();
+ onAnimationsComplete({
+ chart: this
+ });
+ }
+ }
+ }, {
+ key: "draw",
+ value: function draw() {
+ var i;
+ if (this._resizeBeforeDraw) {
+ var _this$_resizeBeforeDr = this._resizeBeforeDraw,
+ width = _this$_resizeBeforeDr.width,
+ height = _this$_resizeBeforeDr.height;
+ this._resizeBeforeDraw = null;
+ this._resize(width, height);
+ }
+ this.clear();
+ if (this.width <= 0 || this.height <= 0) {
+ return;
+ }
+ if (this.notifyPlugins('beforeDraw', {
+ cancelable: true
+ }) === false) {
+ return;
+ }
+ var layers = this._layers;
+ for (i = 0; i < layers.length && layers[i].z <= 0; ++i) {
+ layers[i].draw(this.chartArea);
+ }
+ this._drawDatasets();
+ for (; i < layers.length; ++i) {
+ layers[i].draw(this.chartArea);
+ }
+ this.notifyPlugins('afterDraw');
+ }
+ }, {
+ key: "_getSortedDatasetMetas",
+ value: function _getSortedDatasetMetas(filterVisible) {
+ var metasets = this._sortedMetasets;
+ var result = [];
+ var i, ilen;
+ for (i = 0, ilen = metasets.length; i < ilen; ++i) {
+ var meta = metasets[i];
+ if (!filterVisible || meta.visible) {
+ result.push(meta);
+ }
+ }
+ return result;
+ }
+ }, {
+ key: "getSortedVisibleDatasetMetas",
+ value: function getSortedVisibleDatasetMetas() {
+ return this._getSortedDatasetMetas(true);
+ }
+ }, {
+ key: "_drawDatasets",
+ value: function _drawDatasets() {
+ if (this.notifyPlugins('beforeDatasetsDraw', {
+ cancelable: true
+ }) === false) {
+ return;
+ }
+ var metasets = this.getSortedVisibleDatasetMetas();
+ for (var i = metasets.length - 1; i >= 0; --i) {
+ this._drawDataset(metasets[i]);
+ }
+ this.notifyPlugins('afterDatasetsDraw');
+ }
+ }, {
+ key: "_drawDataset",
+ value: function _drawDataset(meta) {
+ var ctx = this.ctx;
+ var clip = meta._clip;
+ var useClip = !clip.disabled;
+ var area = getDatasetArea(meta, this.chartArea);
+ var args = {
+ meta: meta,
+ index: meta.index,
+ cancelable: true
+ };
+ if (this.notifyPlugins('beforeDatasetDraw', args) === false) {
+ return;
+ }
+ if (useClip) {
+ clipArea(ctx, {
+ left: clip.left === false ? 0 : area.left - clip.left,
+ right: clip.right === false ? this.width : area.right + clip.right,
+ top: clip.top === false ? 0 : area.top - clip.top,
+ bottom: clip.bottom === false ? this.height : area.bottom + clip.bottom
+ });
+ }
+ meta.controller.draw();
+ if (useClip) {
+ unclipArea(ctx);
+ }
+ args.cancelable = false;
+ this.notifyPlugins('afterDatasetDraw', args);
+ }
+ }, {
+ key: "isPointInArea",
+ value: function isPointInArea(point) {
+ return _isPointInArea(point, this.chartArea, this._minPadding);
+ }
+ }, {
+ key: "getElementsAtEventForMode",
+ value: function getElementsAtEventForMode(e, mode, options, useFinalPosition) {
+ var method = Interaction.modes[mode];
+ if (typeof method === 'function') {
+ return method(this, e, options, useFinalPosition);
+ }
+ return [];
+ }
+ }, {
+ key: "getDatasetMeta",
+ value: function getDatasetMeta(datasetIndex) {
+ var dataset = this.data.datasets[datasetIndex];
+ var metasets = this._metasets;
+ var meta = metasets.filter(function (x) {
+ return x && x._dataset === dataset;
+ }).pop();
+ if (!meta) {
+ meta = {
+ type: null,
+ data: [],
+ dataset: null,
+ controller: null,
+ hidden: null,
+ xAxisID: null,
+ yAxisID: null,
+ order: dataset && dataset.order || 0,
+ index: datasetIndex,
+ _dataset: dataset,
+ _parsed: [],
+ _sorted: false
+ };
+ metasets.push(meta);
+ }
+ return meta;
+ }
+ }, {
+ key: "getContext",
+ value: function getContext() {
+ return this.$context || (this.$context = createContext(null, {
+ chart: this,
+ type: 'chart'
+ }));
+ }
+ }, {
+ key: "getVisibleDatasetCount",
+ value: function getVisibleDatasetCount() {
+ return this.getSortedVisibleDatasetMetas().length;
+ }
+ }, {
+ key: "isDatasetVisible",
+ value: function isDatasetVisible(datasetIndex) {
+ var dataset = this.data.datasets[datasetIndex];
+ if (!dataset) {
+ return false;
+ }
+ var meta = this.getDatasetMeta(datasetIndex);
+ return typeof meta.hidden === 'boolean' ? !meta.hidden : !dataset.hidden;
+ }
+ }, {
+ key: "setDatasetVisibility",
+ value: function setDatasetVisibility(datasetIndex, visible) {
+ var meta = this.getDatasetMeta(datasetIndex);
+ meta.hidden = !visible;
+ }
+ }, {
+ key: "toggleDataVisibility",
+ value: function toggleDataVisibility(index) {
+ this._hiddenIndices[index] = !this._hiddenIndices[index];
+ }
+ }, {
+ key: "getDataVisibility",
+ value: function getDataVisibility(index) {
+ return !this._hiddenIndices[index];
+ }
+ }, {
+ key: "_updateVisibility",
+ value: function _updateVisibility(datasetIndex, dataIndex, visible) {
+ var mode = visible ? 'show' : 'hide';
+ var meta = this.getDatasetMeta(datasetIndex);
+ var anims = meta.controller._resolveAnimations(undefined, mode);
+ if (defined(dataIndex)) {
+ meta.data[dataIndex].hidden = !visible;
+ this.update();
+ } else {
+ this.setDatasetVisibility(datasetIndex, visible);
+ anims.update(meta, {
+ visible: visible
+ });
+ this.update(function (ctx) {
+ return ctx.datasetIndex === datasetIndex ? mode : undefined;
+ });
+ }
+ }
+ }, {
+ key: "hide",
+ value: function hide(datasetIndex, dataIndex) {
+ this._updateVisibility(datasetIndex, dataIndex, false);
+ }
+ }, {
+ key: "show",
+ value: function show(datasetIndex, dataIndex) {
+ this._updateVisibility(datasetIndex, dataIndex, true);
+ }
+ }, {
+ key: "_destroyDatasetMeta",
+ value: function _destroyDatasetMeta(datasetIndex) {
+ var meta = this._metasets[datasetIndex];
+ if (meta && meta.controller) {
+ meta.controller._destroy();
+ }
+ delete this._metasets[datasetIndex];
+ }
+ }, {
+ key: "_stop",
+ value: function _stop() {
+ var i, ilen;
+ this.stop();
+ animator.remove(this);
+ for (i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
+ this._destroyDatasetMeta(i);
+ }
+ }
+ }, {
+ key: "destroy",
+ value: function destroy() {
+ this.notifyPlugins('beforeDestroy');
+ var canvas = this.canvas,
+ ctx = this.ctx;
+ this._stop();
+ this.config.clearCache();
+ if (canvas) {
+ this.unbindEvents();
+ clearCanvas(canvas, ctx);
+ this.platform.releaseContext(ctx);
+ this.canvas = null;
+ this.ctx = null;
+ }
+ delete instances[this.id];
+ this.notifyPlugins('afterDestroy');
+ }
+ }, {
+ key: "toBase64Image",
+ value: function toBase64Image() {
+ var _this$canvas;
+ return (_this$canvas = this.canvas).toDataURL.apply(_this$canvas, arguments);
+ }
+ }, {
+ key: "bindEvents",
+ value: function bindEvents() {
+ this.bindUserEvents();
+ if (this.options.responsive) {
+ this.bindResponsiveEvents();
+ } else {
+ this.attached = true;
+ }
+ }
+ }, {
+ key: "bindUserEvents",
+ value: function bindUserEvents() {
+ var _this18 = this;
+ var listeners = this._listeners;
+ var platform = this.platform;
+ var _add = function _add(type, listener) {
+ platform.addEventListener(_this18, type, listener);
+ listeners[type] = listener;
+ };
+ var listener = function listener(e, x, y) {
+ e.offsetX = x;
+ e.offsetY = y;
+ _this18._eventHandler(e);
+ };
+ each(this.options.events, function (type) {
+ return _add(type, listener);
+ });
+ }
+ }, {
+ key: "bindResponsiveEvents",
+ value: function bindResponsiveEvents() {
+ var _this19 = this;
+ if (!this._responsiveListeners) {
+ this._responsiveListeners = {};
+ }
+ var listeners = this._responsiveListeners;
+ var platform = this.platform;
+ var _add = function _add(type, listener) {
+ platform.addEventListener(_this19, type, listener);
+ listeners[type] = listener;
+ };
+ var _remove = function _remove(type, listener) {
+ if (listeners[type]) {
+ platform.removeEventListener(_this19, type, listener);
+ delete listeners[type];
+ }
+ };
+ var listener = function listener(width, height) {
+ if (_this19.canvas) {
+ _this19.resize(width, height);
+ }
+ };
+ var detached;
+ var _attached = function attached() {
+ _remove('attach', _attached);
+ _this19.attached = true;
+ _this19.resize();
+ _add('resize', listener);
+ _add('detach', detached);
+ };
+ detached = function detached() {
+ _this19.attached = false;
+ _remove('resize', listener);
+ _this19._stop();
+ _this19._resize(0, 0);
+ _add('attach', _attached);
+ };
+ if (platform.isAttached(this.canvas)) {
+ _attached();
+ } else {
+ detached();
+ }
+ }
+ }, {
+ key: "unbindEvents",
+ value: function unbindEvents() {
+ var _this20 = this;
+ each(this._listeners, function (listener, type) {
+ _this20.platform.removeEventListener(_this20, type, listener);
+ });
+ this._listeners = {};
+ each(this._responsiveListeners, function (listener, type) {
+ _this20.platform.removeEventListener(_this20, type, listener);
+ });
+ this._responsiveListeners = undefined;
+ }
+ }, {
+ key: "updateHoverStyle",
+ value: function updateHoverStyle(items, mode, enabled) {
+ var prefix = enabled ? 'set' : 'remove';
+ var meta, item, i, ilen;
+ if (mode === 'dataset') {
+ meta = this.getDatasetMeta(items[0].datasetIndex);
+ meta.controller['_' + prefix + 'DatasetHoverStyle']();
+ }
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
+ item = items[i];
+ var controller = item && this.getDatasetMeta(item.datasetIndex).controller;
+ if (controller) {
+ controller[prefix + 'HoverStyle'](item.element, item.datasetIndex, item.index);
+ }
+ }
+ }
+ }, {
+ key: "getActiveElements",
+ value: function getActiveElements() {
+ return this._active || [];
+ }
+ }, {
+ key: "setActiveElements",
+ value: function setActiveElements(activeElements) {
+ var _this21 = this;
+ var lastActive = this._active || [];
+ var active = activeElements.map(function (_ref4) {
+ var datasetIndex = _ref4.datasetIndex,
+ index = _ref4.index;
+ var meta = _this21.getDatasetMeta(datasetIndex);
+ if (!meta) {
+ throw new Error('No dataset found at index ' + datasetIndex);
+ }
+ return {
+ datasetIndex: datasetIndex,
+ element: meta.data[index],
+ index: index
+ };
+ });
+ var changed = !_elementsEqual(active, lastActive);
+ if (changed) {
+ this._active = active;
+ this._lastEvent = null;
+ this._updateHoverStyles(active, lastActive);
+ }
+ }
+ }, {
+ key: "notifyPlugins",
+ value: function notifyPlugins(hook, args, filter) {
+ return this._plugins.notify(this, hook, args, filter);
+ }
+ }, {
+ key: "isPluginEnabled",
+ value: function isPluginEnabled(pluginId) {
+ return this._plugins._cache.filter(function (p) {
+ return p.plugin.id === pluginId;
+ }).length === 1;
+ }
+ }, {
+ key: "_updateHoverStyles",
+ value: function _updateHoverStyles(active, lastActive, replay) {
+ var hoverOptions = this.options.hover;
+ var diff = function diff(a, b) {
+ return a.filter(function (x) {
+ return !b.some(function (y) {
+ return x.datasetIndex === y.datasetIndex && x.index === y.index;
+ });
+ });
+ };
+ var deactivated = diff(lastActive, active);
+ var activated = replay ? active : diff(active, lastActive);
+ if (deactivated.length) {
+ this.updateHoverStyle(deactivated, hoverOptions.mode, false);
+ }
+ if (activated.length && hoverOptions.mode) {
+ this.updateHoverStyle(activated, hoverOptions.mode, true);
+ }
+ }
+ }, {
+ key: "_eventHandler",
+ value: function _eventHandler(e, replay) {
+ var _this22 = this;
+ var args = {
+ event: e,
+ replay: replay,
+ cancelable: true,
+ inChartArea: this.isPointInArea(e)
+ };
+ var eventFilter = function eventFilter(plugin) {
+ return (plugin.options.events || _this22.options.events).includes(e["native"].type);
+ };
+ if (this.notifyPlugins('beforeEvent', args, eventFilter) === false) {
+ return;
+ }
+ var changed = this._handleEvent(e, replay, args.inChartArea);
+ args.cancelable = false;
+ this.notifyPlugins('afterEvent', args, eventFilter);
+ if (changed || args.changed) {
+ this.render();
+ }
+ return this;
+ }
+ }, {
+ key: "_handleEvent",
+ value: function _handleEvent(e, replay, inChartArea) {
+ var _this$_active = this._active,
+ lastActive = _this$_active === void 0 ? [] : _this$_active,
+ options = this.options;
+ var useFinalPosition = replay;
+ var active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition);
+ var isClick = _isClickEvent(e);
+ var lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isClick);
+ if (inChartArea) {
+ this._lastEvent = null;
+ callback(options.onHover, [e, active, this], this);
+ if (isClick) {
+ callback(options.onClick, [e, active, this], this);
+ }
+ }
+ var changed = !_elementsEqual(active, lastActive);
+ if (changed || replay) {
+ this._active = active;
+ this._updateHoverStyles(active, lastActive, replay);
+ }
+ this._lastEvent = lastEvent;
+ return changed;
+ }
+ }, {
+ key: "_getActiveElements",
+ value: function _getActiveElements(e, lastActive, inChartArea, useFinalPosition) {
+ if (e.type === 'mouseout') {
+ return [];
+ }
+ if (!inChartArea) {
+ return lastActive;
+ }
+ var hoverOptions = this.options.hover;
+ return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);
+ }
+ }], [{
+ key: "register",
+ value: function register() {
+ registry.add.apply(registry, arguments);
+ invalidatePlugins();
+ }
+ }, {
+ key: "unregister",
+ value: function unregister() {
+ registry.remove.apply(registry, arguments);
+ invalidatePlugins();
+ }
+ }]);
+ }();
+ _defineProperty$1(Chart, "defaults", defaults);
+ _defineProperty$1(Chart, "instances", instances);
+ _defineProperty$1(Chart, "overrides", overrides);
+ _defineProperty$1(Chart, "registry", registry);
+ _defineProperty$1(Chart, "version", version);
+ _defineProperty$1(Chart, "getChart", getChart);
+ function invalidatePlugins() {
+ return each(Chart.instances, function (chart) {
+ return chart._plugins.invalidate();
+ });
+ }
+ function clipArc(ctx, element, endAngle) {
+ var startAngle = element.startAngle,
+ pixelMargin = element.pixelMargin,
+ x = element.x,
+ y = element.y,
+ outerRadius = element.outerRadius,
+ innerRadius = element.innerRadius;
+ var angleMargin = pixelMargin / outerRadius;
+ // Draw an inner border by clipping the arc and drawing a double-width border
+ // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders
+ ctx.beginPath();
+ ctx.arc(x, y, outerRadius, startAngle - angleMargin, endAngle + angleMargin);
+ if (innerRadius > pixelMargin) {
+ angleMargin = pixelMargin / innerRadius;
+ ctx.arc(x, y, innerRadius, endAngle + angleMargin, startAngle - angleMargin, true);
+ } else {
+ ctx.arc(x, y, pixelMargin, endAngle + HALF_PI, startAngle - HALF_PI);
+ }
+ ctx.closePath();
+ ctx.clip();
+ }
+ function toRadiusCorners(value) {
+ return _readValueToProps(value, ['outerStart', 'outerEnd', 'innerStart', 'innerEnd']);
+ }
+ /**
+ * Parse border radius from the provided options
+ */
+ function parseBorderRadius$1(arc, innerRadius, outerRadius, angleDelta) {
+ var o = toRadiusCorners(arc.options.borderRadius);
+ var halfThickness = (outerRadius - innerRadius) / 2;
+ var innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2);
+ // Outer limits are complicated. We want to compute the available angular distance at
+ // a radius of outerRadius - borderRadius because for small angular distances, this term limits.
+ // We compute at r = outerRadius - borderRadius because this circle defines the center of the border corners.
+ //
+ // If the borderRadius is large, that value can become negative.
+ // This causes the outer borders to lose their radius entirely, which is rather unexpected. To solve that, if borderRadius > outerRadius
+ // we know that the thickness term will dominate and compute the limits at that point
+ var computeOuterLimit = function computeOuterLimit(val) {
+ var outerArcLimit = (outerRadius - Math.min(halfThickness, val)) * angleDelta / 2;
+ return _limitValue(val, 0, Math.min(halfThickness, outerArcLimit));
+ };
+ return {
+ outerStart: computeOuterLimit(o.outerStart),
+ outerEnd: computeOuterLimit(o.outerEnd),
+ innerStart: _limitValue(o.innerStart, 0, innerLimit),
+ innerEnd: _limitValue(o.innerEnd, 0, innerLimit)
+ };
+ }
+ /**
+ * Convert (r, 𝜃) to (x, y)
+ */
+ function rThetaToXY(r, theta, x, y) {
+ return {
+ x: x + r * Math.cos(theta),
+ y: y + r * Math.sin(theta)
+ };
+ }
+ /**
+ * Path the arc, respecting border radius by separating into left and right halves.
+ *
+ * Start End
+ *
+ * 1--->a--->2 Outer
+ * / \
+ * 8 3
+ * | |
+ * | |
+ * 7 4
+ * \ /
+ * 6<---b<---5 Inner
+ */
+ function pathArc(ctx, element, offset, spacing, end, circular) {
+ var x = element.x,
+ y = element.y,
+ start = element.startAngle,
+ pixelMargin = element.pixelMargin,
+ innerR = element.innerRadius;
+ var outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0);
+ var innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0;
+ var spacingOffset = 0;
+ var alpha = end - start;
+ if (spacing) {
+ // When spacing is present, it is the same for all items
+ // So we adjust the start and end angle of the arc such that
+ // the distance is the same as it would be without the spacing
+ var noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0;
+ var noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0;
+ var avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2;
+ var adjustedAngle = avNogSpacingRadius !== 0 ? alpha * avNogSpacingRadius / (avNogSpacingRadius + spacing) : alpha;
+ spacingOffset = (alpha - adjustedAngle) / 2;
+ }
+ var beta = Math.max(0.001, alpha * outerRadius - offset / PI) / outerRadius;
+ var angleOffset = (alpha - beta) / 2;
+ var startAngle = start + angleOffset + spacingOffset;
+ var endAngle = end - angleOffset - spacingOffset;
+ var _parseBorderRadius$ = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle),
+ outerStart = _parseBorderRadius$.outerStart,
+ outerEnd = _parseBorderRadius$.outerEnd,
+ innerStart = _parseBorderRadius$.innerStart,
+ innerEnd = _parseBorderRadius$.innerEnd;
+ var outerStartAdjustedRadius = outerRadius - outerStart;
+ var outerEndAdjustedRadius = outerRadius - outerEnd;
+ var outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius;
+ var outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius;
+ var innerStartAdjustedRadius = innerRadius + innerStart;
+ var innerEndAdjustedRadius = innerRadius + innerEnd;
+ var innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius;
+ var innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius;
+ ctx.beginPath();
+ if (circular) {
+ // The first arc segments from point 1 to point a to point 2
+ var outerMidAdjustedAngle = (outerStartAdjustedAngle + outerEndAdjustedAngle) / 2;
+ ctx.arc(x, y, outerRadius, outerStartAdjustedAngle, outerMidAdjustedAngle);
+ ctx.arc(x, y, outerRadius, outerMidAdjustedAngle, outerEndAdjustedAngle);
+ // The corner segment from point 2 to point 3
+ if (outerEnd > 0) {
+ var pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x, y);
+ ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + HALF_PI);
+ }
+ // The line from point 3 to point 4
+ var p4 = rThetaToXY(innerEndAdjustedRadius, endAngle, x, y);
+ ctx.lineTo(p4.x, p4.y);
+ // The corner segment from point 4 to point 5
+ if (innerEnd > 0) {
+ var _pCenter = rThetaToXY(innerEndAdjustedRadius, innerEndAdjustedAngle, x, y);
+ ctx.arc(_pCenter.x, _pCenter.y, innerEnd, endAngle + HALF_PI, innerEndAdjustedAngle + Math.PI);
+ }
+ // The inner arc from point 5 to point b to point 6
+ var innerMidAdjustedAngle = (endAngle - innerEnd / innerRadius + (startAngle + innerStart / innerRadius)) / 2;
+ ctx.arc(x, y, innerRadius, endAngle - innerEnd / innerRadius, innerMidAdjustedAngle, true);
+ ctx.arc(x, y, innerRadius, innerMidAdjustedAngle, startAngle + innerStart / innerRadius, true);
+ // The corner segment from point 6 to point 7
+ if (innerStart > 0) {
+ var _pCenter2 = rThetaToXY(innerStartAdjustedRadius, innerStartAdjustedAngle, x, y);
+ ctx.arc(_pCenter2.x, _pCenter2.y, innerStart, innerStartAdjustedAngle + Math.PI, startAngle - HALF_PI);
+ }
+ // The line from point 7 to point 8
+ var p8 = rThetaToXY(outerStartAdjustedRadius, startAngle, x, y);
+ ctx.lineTo(p8.x, p8.y);
+ // The corner segment from point 8 to point 1
+ if (outerStart > 0) {
+ var _pCenter3 = rThetaToXY(outerStartAdjustedRadius, outerStartAdjustedAngle, x, y);
+ ctx.arc(_pCenter3.x, _pCenter3.y, outerStart, startAngle - HALF_PI, outerStartAdjustedAngle);
+ }
+ } else {
+ ctx.moveTo(x, y);
+ var outerStartX = Math.cos(outerStartAdjustedAngle) * outerRadius + x;
+ var outerStartY = Math.sin(outerStartAdjustedAngle) * outerRadius + y;
+ ctx.lineTo(outerStartX, outerStartY);
+ var outerEndX = Math.cos(outerEndAdjustedAngle) * outerRadius + x;
+ var outerEndY = Math.sin(outerEndAdjustedAngle) * outerRadius + y;
+ ctx.lineTo(outerEndX, outerEndY);
+ }
+ ctx.closePath();
+ }
+ function drawArc(ctx, element, offset, spacing, circular) {
+ var fullCircles = element.fullCircles,
+ startAngle = element.startAngle,
+ circumference = element.circumference;
+ var endAngle = element.endAngle;
+ if (fullCircles) {
+ pathArc(ctx, element, offset, spacing, endAngle, circular);
+ for (var i = 0; i < fullCircles; ++i) {
+ ctx.fill();
+ }
+ if (!isNaN(circumference)) {
+ endAngle = startAngle + (circumference % TAU || TAU);
+ }
+ }
+ pathArc(ctx, element, offset, spacing, endAngle, circular);
+ ctx.fill();
+ return endAngle;
+ }
+ function drawBorder(ctx, element, offset, spacing, circular) {
+ var fullCircles = element.fullCircles,
+ startAngle = element.startAngle,
+ circumference = element.circumference,
+ options = element.options;
+ var borderWidth = options.borderWidth,
+ borderJoinStyle = options.borderJoinStyle,
+ borderDash = options.borderDash,
+ borderDashOffset = options.borderDashOffset;
+ var inner = options.borderAlign === 'inner';
+ if (!borderWidth) {
+ return;
+ }
+ ctx.setLineDash(borderDash || []);
+ ctx.lineDashOffset = borderDashOffset;
+ if (inner) {
+ ctx.lineWidth = borderWidth * 2;
+ ctx.lineJoin = borderJoinStyle || 'round';
+ } else {
+ ctx.lineWidth = borderWidth;
+ ctx.lineJoin = borderJoinStyle || 'bevel';
+ }
+ var endAngle = element.endAngle;
+ if (fullCircles) {
+ pathArc(ctx, element, offset, spacing, endAngle, circular);
+ for (var i = 0; i < fullCircles; ++i) {
+ ctx.stroke();
+ }
+ if (!isNaN(circumference)) {
+ endAngle = startAngle + (circumference % TAU || TAU);
+ }
+ }
+ if (inner) {
+ clipArc(ctx, element, endAngle);
+ }
+ if (!fullCircles) {
+ pathArc(ctx, element, offset, spacing, endAngle, circular);
+ ctx.stroke();
+ }
+ }
+ var ArcElement = /*#__PURE__*/function (_Element3) {
+ function ArcElement(cfg) {
+ var _this23;
+ _classCallCheck$1(this, ArcElement);
+ _this23 = _callSuper(this, ArcElement);
+ _defineProperty$1(_this23, "circumference", void 0);
+ _defineProperty$1(_this23, "endAngle", void 0);
+ _defineProperty$1(_this23, "fullCircles", void 0);
+ _defineProperty$1(_this23, "innerRadius", void 0);
+ _defineProperty$1(_this23, "outerRadius", void 0);
+ _defineProperty$1(_this23, "pixelMargin", void 0);
+ _defineProperty$1(_this23, "startAngle", void 0);
+ _this23.options = undefined;
+ _this23.circumference = undefined;
+ _this23.startAngle = undefined;
+ _this23.endAngle = undefined;
+ _this23.innerRadius = undefined;
+ _this23.outerRadius = undefined;
+ _this23.pixelMargin = 0;
+ _this23.fullCircles = 0;
+ if (cfg) {
+ Object.assign(_this23, cfg);
+ }
+ return _this23;
+ }
+ _inherits$1(ArcElement, _Element3);
+ return _createClass$1(ArcElement, [{
+ key: "inRange",
+ value: function inRange(chartX, chartY, useFinalPosition) {
+ var point = this.getProps(['x', 'y'], useFinalPosition);
+ var _getAngleFromPoint2 = getAngleFromPoint(point, {
+ x: chartX,
+ y: chartY
+ }),
+ angle = _getAngleFromPoint2.angle,
+ distance = _getAngleFromPoint2.distance;
+ var _this$getProps2 = this.getProps(['startAngle', 'endAngle', 'innerRadius', 'outerRadius', 'circumference'], useFinalPosition),
+ startAngle = _this$getProps2.startAngle,
+ endAngle = _this$getProps2.endAngle,
+ innerRadius = _this$getProps2.innerRadius,
+ outerRadius = _this$getProps2.outerRadius,
+ circumference = _this$getProps2.circumference;
+ var rAdjust = (this.options.spacing + this.options.borderWidth) / 2;
+ var _circumference = valueOrDefault(circumference, endAngle - startAngle);
+ var nonZeroBetween = _angleBetween(angle, startAngle, endAngle) && startAngle !== endAngle;
+ var betweenAngles = _circumference >= TAU || nonZeroBetween;
+ var withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust);
+ return betweenAngles && withinRadius;
+ }
+ }, {
+ key: "getCenterPoint",
+ value: function getCenterPoint(useFinalPosition) {
+ var _this$getProps3 = this.getProps(['x', 'y', 'startAngle', 'endAngle', 'innerRadius', 'outerRadius'], useFinalPosition),
+ x = _this$getProps3.x,
+ y = _this$getProps3.y,
+ startAngle = _this$getProps3.startAngle,
+ endAngle = _this$getProps3.endAngle,
+ innerRadius = _this$getProps3.innerRadius,
+ outerRadius = _this$getProps3.outerRadius;
+ var _this$options13 = this.options,
+ offset = _this$options13.offset,
+ spacing = _this$options13.spacing;
+ var halfAngle = (startAngle + endAngle) / 2;
+ var halfRadius = (innerRadius + outerRadius + spacing + offset) / 2;
+ return {
+ x: x + Math.cos(halfAngle) * halfRadius,
+ y: y + Math.sin(halfAngle) * halfRadius
+ };
+ }
+ }, {
+ key: "tooltipPosition",
+ value: function tooltipPosition(useFinalPosition) {
+ return this.getCenterPoint(useFinalPosition);
+ }
+ }, {
+ key: "draw",
+ value: function draw(ctx) {
+ var options = this.options,
+ circumference = this.circumference;
+ var offset = (options.offset || 0) / 4;
+ var spacing = (options.spacing || 0) / 2;
+ var circular = options.circular;
+ this.pixelMargin = options.borderAlign === 'inner' ? 0.33 : 0;
+ this.fullCircles = circumference > TAU ? Math.floor(circumference / TAU) : 0;
+ if (circumference === 0 || this.innerRadius < 0 || this.outerRadius < 0) {
+ return;
+ }
+ ctx.save();
+ var halfAngle = (this.startAngle + this.endAngle) / 2;
+ ctx.translate(Math.cos(halfAngle) * offset, Math.sin(halfAngle) * offset);
+ var fix = 1 - Math.sin(Math.min(PI, circumference || 0));
+ var radiusOffset = offset * fix;
+ ctx.fillStyle = options.backgroundColor;
+ ctx.strokeStyle = options.borderColor;
+ drawArc(ctx, this, radiusOffset, spacing, circular);
+ drawBorder(ctx, this, radiusOffset, spacing, circular);
+ ctx.restore();
+ }
+ }]);
+ }(Element);
+ _defineProperty$1(ArcElement, "id", 'arc');
+ _defineProperty$1(ArcElement, "defaults", {
+ borderAlign: 'center',
+ borderColor: '#fff',
+ borderDash: [],
+ borderDashOffset: 0,
+ borderJoinStyle: undefined,
+ borderRadius: 0,
+ borderWidth: 2,
+ offset: 0,
+ spacing: 0,
+ angle: undefined,
+ circular: true
+ });
+ _defineProperty$1(ArcElement, "defaultRoutes", {
+ backgroundColor: 'backgroundColor'
+ });
+ _defineProperty$1(ArcElement, "descriptors", {
+ _scriptable: true,
+ _indexable: function _indexable(name) {
+ return name !== 'borderDash';
+ }
+ });
+ function setStyle(ctx, options) {
+ var style = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : options;
+ ctx.lineCap = valueOrDefault(style.borderCapStyle, options.borderCapStyle);
+ ctx.setLineDash(valueOrDefault(style.borderDash, options.borderDash));
+ ctx.lineDashOffset = valueOrDefault(style.borderDashOffset, options.borderDashOffset);
+ ctx.lineJoin = valueOrDefault(style.borderJoinStyle, options.borderJoinStyle);
+ ctx.lineWidth = valueOrDefault(style.borderWidth, options.borderWidth);
+ ctx.strokeStyle = valueOrDefault(style.borderColor, options.borderColor);
+ }
+ function lineTo(ctx, previous, target) {
+ ctx.lineTo(target.x, target.y);
+ }
+ function getLineMethod(options) {
+ if (options.stepped) {
+ return _steppedLineTo;
+ }
+ if (options.tension || options.cubicInterpolationMode === 'monotone') {
+ return _bezierCurveTo;
+ }
+ return lineTo;
+ }
+ function pathVars(points, segment) {
+ var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+ var count = points.length;
+ var _params$start = params.start,
+ paramsStart = _params$start === void 0 ? 0 : _params$start,
+ _params$end = params.end,
+ paramsEnd = _params$end === void 0 ? count - 1 : _params$end;
+ var segmentStart = segment.start,
+ segmentEnd = segment.end;
+ var start = Math.max(paramsStart, segmentStart);
+ var end = Math.min(paramsEnd, segmentEnd);
+ var outside = paramsStart < segmentStart && paramsEnd < segmentStart || paramsStart > segmentEnd && paramsEnd > segmentEnd;
+ return {
+ count: count,
+ start: start,
+ loop: segment.loop,
+ ilen: end < start && !outside ? count + end - start : end - start
+ };
+ }
+ function pathSegment(ctx, line, segment, params) {
+ var points = line.points,
+ options = line.options;
+ var _pathVars = pathVars(points, segment, params),
+ count = _pathVars.count,
+ start = _pathVars.start,
+ loop = _pathVars.loop,
+ ilen = _pathVars.ilen;
+ var lineMethod = getLineMethod(options);
+ var _ref5 = params || {},
+ _ref5$move = _ref5.move,
+ move = _ref5$move === void 0 ? true : _ref5$move,
+ reverse = _ref5.reverse;
+ var i, point, prev;
+ for (i = 0; i <= ilen; ++i) {
+ point = points[(start + (reverse ? ilen - i : i)) % count];
+ if (point.skip) {
+ continue;
+ } else if (move) {
+ ctx.moveTo(point.x, point.y);
+ move = false;
+ } else {
+ lineMethod(ctx, prev, point, reverse, options.stepped);
+ }
+ prev = point;
+ }
+ if (loop) {
+ point = points[(start + (reverse ? ilen : 0)) % count];
+ lineMethod(ctx, prev, point, reverse, options.stepped);
+ }
+ return !!loop;
+ }
+ function fastPathSegment(ctx, line, segment, params) {
+ var points = line.points;
+ var _pathVars2 = pathVars(points, segment, params),
+ count = _pathVars2.count,
+ start = _pathVars2.start,
+ ilen = _pathVars2.ilen;
+ var _ref6 = params || {},
+ _ref6$move = _ref6.move,
+ move = _ref6$move === void 0 ? true : _ref6$move,
+ reverse = _ref6.reverse;
+ var avgX = 0;
+ var countX = 0;
+ var i, point, prevX, minY, maxY, lastY;
+ var pointIndex = function pointIndex(index) {
+ return (start + (reverse ? ilen - index : index)) % count;
+ };
+ var drawX = function drawX() {
+ if (minY !== maxY) {
+ ctx.lineTo(avgX, maxY);
+ ctx.lineTo(avgX, minY);
+ ctx.lineTo(avgX, lastY);
+ }
+ };
+ if (move) {
+ point = points[pointIndex(0)];
+ ctx.moveTo(point.x, point.y);
+ }
+ for (i = 0; i <= ilen; ++i) {
+ point = points[pointIndex(i)];
+ if (point.skip) {
+ continue;
+ }
+ var x = point.x;
+ var y = point.y;
+ var truncX = x | 0;
+ if (truncX === prevX) {
+ if (y < minY) {
+ minY = y;
+ } else if (y > maxY) {
+ maxY = y;
+ }
+ avgX = (countX * avgX + x) / ++countX;
+ } else {
+ drawX();
+ ctx.lineTo(x, y);
+ prevX = truncX;
+ countX = 0;
+ minY = maxY = y;
+ }
+ lastY = y;
+ }
+ drawX();
+ }
+ function _getSegmentMethod(line) {
+ var opts = line.options;
+ var borderDash = opts.borderDash && opts.borderDash.length;
+ var useFastPath = !line._decimated && !line._loop && !opts.tension && opts.cubicInterpolationMode !== 'monotone' && !opts.stepped && !borderDash;
+ return useFastPath ? fastPathSegment : pathSegment;
+ }
+ function _getInterpolationMethod(options) {
+ if (options.stepped) {
+ return _steppedInterpolation;
+ }
+ if (options.tension || options.cubicInterpolationMode === 'monotone') {
+ return _bezierInterpolation;
+ }
+ return _pointInLine;
+ }
+ function strokePathWithCache(ctx, line, start, count) {
+ var path = line._path;
+ if (!path) {
+ path = line._path = new Path2D();
+ if (line.path(path, start, count)) {
+ path.closePath();
+ }
+ }
+ setStyle(ctx, line.options);
+ ctx.stroke(path);
+ }
+ function strokePathDirect(ctx, line, start, count) {
+ var segments = line.segments,
+ options = line.options;
+ var segmentMethod = _getSegmentMethod(line);
+ var _iterator16 = _createForOfIteratorHelper$1(segments),
+ _step16;
+ try {
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
+ var segment = _step16.value;
+ setStyle(ctx, options, segment.style);
+ ctx.beginPath();
+ if (segmentMethod(ctx, line, segment, {
+ start: start,
+ end: start + count - 1
+ })) {
+ ctx.closePath();
+ }
+ ctx.stroke();
+ }
+ } catch (err) {
+ _iterator16.e(err);
+ } finally {
+ _iterator16.f();
+ }
+ }
+ var usePath2D = typeof Path2D === 'function';
+ function _draw(ctx, line, start, count) {
+ if (usePath2D && !line.options.segment) {
+ strokePathWithCache(ctx, line, start, count);
+ } else {
+ strokePathDirect(ctx, line, start, count);
+ }
+ }
+ var LineElement = /*#__PURE__*/function (_Element4) {
+ function LineElement(cfg) {
+ var _this24;
+ _classCallCheck$1(this, LineElement);
+ _this24 = _callSuper(this, LineElement);
+ _this24.animated = true;
+ _this24.options = undefined;
+ _this24._chart = undefined;
+ _this24._loop = undefined;
+ _this24._fullLoop = undefined;
+ _this24._path = undefined;
+ _this24._points = undefined;
+ _this24._segments = undefined;
+ _this24._decimated = false;
+ _this24._pointsUpdated = false;
+ _this24._datasetIndex = undefined;
+ if (cfg) {
+ Object.assign(_this24, cfg);
+ }
+ return _this24;
+ }
+ _inherits$1(LineElement, _Element4);
+ return _createClass$1(LineElement, [{
+ key: "updateControlPoints",
+ value: function updateControlPoints(chartArea, indexAxis) {
+ var options = this.options;
+ if ((options.tension || options.cubicInterpolationMode === 'monotone') && !options.stepped && !this._pointsUpdated) {
+ var loop = options.spanGaps ? this._loop : this._fullLoop;
+ _updateBezierControlPoints(this._points, options, chartArea, loop, indexAxis);
+ this._pointsUpdated = true;
+ }
+ }
+ }, {
+ key: "points",
+ get: function get() {
+ return this._points;
+ },
+ set: function set(points) {
+ this._points = points;
+ delete this._segments;
+ delete this._path;
+ this._pointsUpdated = false;
+ }
+ }, {
+ key: "segments",
+ get: function get() {
+ return this._segments || (this._segments = _computeSegments(this, this.options.segment));
+ }
+ }, {
+ key: "first",
+ value: function first() {
+ var segments = this.segments;
+ var points = this.points;
+ return segments.length && points[segments[0].start];
+ }
+ }, {
+ key: "last",
+ value: function last() {
+ var segments = this.segments;
+ var points = this.points;
+ var count = segments.length;
+ return count && points[segments[count - 1].end];
+ }
+ }, {
+ key: "interpolate",
+ value: function interpolate(point, property) {
+ var options = this.options;
+ var value = point[property];
+ var points = this.points;
+ var segments = _boundSegments(this, {
+ property: property,
+ start: value,
+ end: value
+ });
+ if (!segments.length) {
+ return;
+ }
+ var result = [];
+ var _interpolate = _getInterpolationMethod(options);
+ var i, ilen;
+ for (i = 0, ilen = segments.length; i < ilen; ++i) {
+ var _segments$i = segments[i],
+ start = _segments$i.start,
+ end = _segments$i.end;
+ var p1 = points[start];
+ var p2 = points[end];
+ if (p1 === p2) {
+ result.push(p1);
+ continue;
+ }
+ var t = Math.abs((value - p1[property]) / (p2[property] - p1[property]));
+ var interpolated = _interpolate(p1, p2, t, options.stepped);
+ interpolated[property] = point[property];
+ result.push(interpolated);
+ }
+ return result.length === 1 ? result[0] : result;
+ }
+ }, {
+ key: "pathSegment",
+ value: function pathSegment(ctx, segment, params) {
+ var segmentMethod = _getSegmentMethod(this);
+ return segmentMethod(ctx, this, segment, params);
+ }
+ }, {
+ key: "path",
+ value: function path(ctx, start, count) {
+ var segments = this.segments;
+ var segmentMethod = _getSegmentMethod(this);
+ var loop = this._loop;
+ start = start || 0;
+ count = count || this.points.length - start;
+ var _iterator17 = _createForOfIteratorHelper$1(segments),
+ _step17;
+ try {
+ for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
+ var segment = _step17.value;
+ loop &= segmentMethod(ctx, this, segment, {
+ start: start,
+ end: start + count - 1
+ });
+ }
+ } catch (err) {
+ _iterator17.e(err);
+ } finally {
+ _iterator17.f();
+ }
+ return !!loop;
+ }
+ }, {
+ key: "draw",
+ value: function draw(ctx, chartArea, start, count) {
+ var options = this.options || {};
+ var points = this.points || [];
+ if (points.length && options.borderWidth) {
+ ctx.save();
+ _draw(ctx, this, start, count);
+ ctx.restore();
+ }
+ if (this.animated) {
+ this._pointsUpdated = false;
+ this._path = undefined;
+ }
+ }
+ }]);
+ }(Element);
+ _defineProperty$1(LineElement, "id", 'line');
+ _defineProperty$1(LineElement, "defaults", {
+ borderCapStyle: 'butt',
+ borderDash: [],
+ borderDashOffset: 0,
+ borderJoinStyle: 'miter',
+ borderWidth: 3,
+ capBezierPoints: true,
+ cubicInterpolationMode: 'default',
+ fill: false,
+ spanGaps: false,
+ stepped: false,
+ tension: 0
+ });
+ _defineProperty$1(LineElement, "defaultRoutes", {
+ backgroundColor: 'backgroundColor',
+ borderColor: 'borderColor'
+ });
+ _defineProperty$1(LineElement, "descriptors", {
+ _scriptable: true,
+ _indexable: function _indexable(name) {
+ return name !== 'borderDash' && name !== 'fill';
+ }
+ });
+ function inRange$1(el, pos, axis, useFinalPosition) {
+ var options = el.options;
+ var _el$getProps = el.getProps([axis], useFinalPosition),
+ value = _el$getProps[axis];
+ return Math.abs(pos - value) < options.radius + options.hitRadius;
+ }
+ var PointElement = /*#__PURE__*/function (_Element5) {
+ function PointElement(cfg) {
+ var _this25;
+ _classCallCheck$1(this, PointElement);
+ _this25 = _callSuper(this, PointElement);
+ _defineProperty$1(_this25, "parsed", void 0);
+ _defineProperty$1(_this25, "skip", void 0);
+ _defineProperty$1(_this25, "stop", void 0);
+ _this25.options = undefined;
+ _this25.parsed = undefined;
+ _this25.skip = undefined;
+ _this25.stop = undefined;
+ if (cfg) {
+ Object.assign(_this25, cfg);
+ }
+ return _this25;
+ }
+ _inherits$1(PointElement, _Element5);
+ return _createClass$1(PointElement, [{
+ key: "inRange",
+ value: function inRange(mouseX, mouseY, useFinalPosition) {
+ var options = this.options;
+ var _this$getProps4 = this.getProps(['x', 'y'], useFinalPosition),
+ x = _this$getProps4.x,
+ y = _this$getProps4.y;
+ return Math.pow(mouseX - x, 2) + Math.pow(mouseY - y, 2) < Math.pow(options.hitRadius + options.radius, 2);
+ }
+ }, {
+ key: "inXRange",
+ value: function inXRange(mouseX, useFinalPosition) {
+ return inRange$1(this, mouseX, 'x', useFinalPosition);
+ }
+ }, {
+ key: "inYRange",
+ value: function inYRange(mouseY, useFinalPosition) {
+ return inRange$1(this, mouseY, 'y', useFinalPosition);
+ }
+ }, {
+ key: "getCenterPoint",
+ value: function getCenterPoint(useFinalPosition) {
+ var _this$getProps5 = this.getProps(['x', 'y'], useFinalPosition),
+ x = _this$getProps5.x,
+ y = _this$getProps5.y;
+ return {
+ x: x,
+ y: y
+ };
+ }
+ }, {
+ key: "size",
+ value: function size(options) {
+ options = options || this.options || {};
+ var radius = options.radius || 0;
+ radius = Math.max(radius, radius && options.hoverRadius || 0);
+ var borderWidth = radius && options.borderWidth || 0;
+ return (radius + borderWidth) * 2;
+ }
+ }, {
+ key: "draw",
+ value: function draw(ctx, area) {
+ var options = this.options;
+ if (this.skip || options.radius < 0.1 || !_isPointInArea(this, area, this.size(options) / 2)) {
+ return;
+ }
+ ctx.strokeStyle = options.borderColor;
+ ctx.lineWidth = options.borderWidth;
+ ctx.fillStyle = options.backgroundColor;
+ drawPoint(ctx, options, this.x, this.y);
+ }
+ }, {
+ key: "getRange",
+ value: function getRange() {
+ var options = this.options || {};
+ // @ts-expect-error Fallbacks should never be hit in practice
+ return options.radius + options.hitRadius;
+ }
+ }]);
+ }(Element);
+ _defineProperty$1(PointElement, "id", 'point');
+ /**
+ * @type {any}
+ */
+ _defineProperty$1(PointElement, "defaults", {
+ borderWidth: 1,
+ hitRadius: 1,
+ hoverBorderWidth: 1,
+ hoverRadius: 4,
+ pointStyle: 'circle',
+ radius: 3,
+ rotation: 0
+ });
+ /**
+ * @type {any}
+ */
+ _defineProperty$1(PointElement, "defaultRoutes", {
+ backgroundColor: 'backgroundColor',
+ borderColor: 'borderColor'
+ });
+ function getBarBounds(bar, useFinalPosition) {
+ var _bar$getProps = bar.getProps(['x', 'y', 'base', 'width', 'height'], useFinalPosition),
+ x = _bar$getProps.x,
+ y = _bar$getProps.y,
+ base = _bar$getProps.base,
+ width = _bar$getProps.width,
+ height = _bar$getProps.height;
+ var left, right, top, bottom, half;
+ if (bar.horizontal) {
+ half = height / 2;
+ left = Math.min(x, base);
+ right = Math.max(x, base);
+ top = y - half;
+ bottom = y + half;
+ } else {
+ half = width / 2;
+ left = x - half;
+ right = x + half;
+ top = Math.min(y, base);
+ bottom = Math.max(y, base);
+ }
+ return {
+ left: left,
+ top: top,
+ right: right,
+ bottom: bottom
+ };
+ }
+ function skipOrLimit(skip, value, min, max) {
+ return skip ? 0 : _limitValue(value, min, max);
+ }
+ function parseBorderWidth(bar, maxW, maxH) {
+ var value = bar.options.borderWidth;
+ var skip = bar.borderSkipped;
+ var o = toTRBL(value);
+ return {
+ t: skipOrLimit(skip.top, o.top, 0, maxH),
+ r: skipOrLimit(skip.right, o.right, 0, maxW),
+ b: skipOrLimit(skip.bottom, o.bottom, 0, maxH),
+ l: skipOrLimit(skip.left, o.left, 0, maxW)
+ };
+ }
+ function parseBorderRadius(bar, maxW, maxH) {
+ var _bar$getProps2 = bar.getProps(['enableBorderRadius']),
+ enableBorderRadius = _bar$getProps2.enableBorderRadius;
+ var value = bar.options.borderRadius;
+ var o = toTRBLCorners(value);
+ var maxR = Math.min(maxW, maxH);
+ var skip = bar.borderSkipped;
+ var enableBorder = enableBorderRadius || isObject(value);
+ return {
+ topLeft: skipOrLimit(!enableBorder || skip.top || skip.left, o.topLeft, 0, maxR),
+ topRight: skipOrLimit(!enableBorder || skip.top || skip.right, o.topRight, 0, maxR),
+ bottomLeft: skipOrLimit(!enableBorder || skip.bottom || skip.left, o.bottomLeft, 0, maxR),
+ bottomRight: skipOrLimit(!enableBorder || skip.bottom || skip.right, o.bottomRight, 0, maxR)
+ };
+ }
+ function boundingRects(bar) {
+ var bounds = getBarBounds(bar);
+ var width = bounds.right - bounds.left;
+ var height = bounds.bottom - bounds.top;
+ var border = parseBorderWidth(bar, width / 2, height / 2);
+ var radius = parseBorderRadius(bar, width / 2, height / 2);
+ return {
+ outer: {
+ x: bounds.left,
+ y: bounds.top,
+ w: width,
+ h: height,
+ radius: radius
+ },
+ inner: {
+ x: bounds.left + border.l,
+ y: bounds.top + border.t,
+ w: width - border.l - border.r,
+ h: height - border.t - border.b,
+ radius: {
+ topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),
+ topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),
+ bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)),
+ bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r))
+ }
+ }
+ };
+ }
+ function _inRange(bar, x, y, useFinalPosition) {
+ var skipX = x === null;
+ var skipY = y === null;
+ var skipBoth = skipX && skipY;
+ var bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition);
+ return bounds && (skipX || _isBetween(x, bounds.left, bounds.right)) && (skipY || _isBetween(y, bounds.top, bounds.bottom));
+ }
+ function hasRadius(radius) {
+ return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight;
+ }
+ function addNormalRectPath(ctx, rect) {
+ ctx.rect(rect.x, rect.y, rect.w, rect.h);
+ }
+ function inflateRect(rect, amount) {
+ var refRect = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+ var x = rect.x !== refRect.x ? -amount : 0;
+ var y = rect.y !== refRect.y ? -amount : 0;
+ var w = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x;
+ var h = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y;
+ return {
+ x: rect.x + x,
+ y: rect.y + y,
+ w: rect.w + w,
+ h: rect.h + h,
+ radius: rect.radius
+ };
+ }
+ var BarElement = /*#__PURE__*/function (_Element6) {
+ function BarElement(cfg) {
+ var _this26;
+ _classCallCheck$1(this, BarElement);
+ _this26 = _callSuper(this, BarElement);
+ _this26.options = undefined;
+ _this26.horizontal = undefined;
+ _this26.base = undefined;
+ _this26.width = undefined;
+ _this26.height = undefined;
+ _this26.inflateAmount = undefined;
+ if (cfg) {
+ Object.assign(_this26, cfg);
+ }
+ return _this26;
+ }
+ _inherits$1(BarElement, _Element6);
+ return _createClass$1(BarElement, [{
+ key: "draw",
+ value: function draw(ctx) {
+ var inflateAmount = this.inflateAmount,
+ _this$options14 = this.options,
+ borderColor = _this$options14.borderColor,
+ backgroundColor = _this$options14.backgroundColor;
+ var _boundingRects = boundingRects(this),
+ inner = _boundingRects.inner,
+ outer = _boundingRects.outer;
+ var addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;
+ ctx.save();
+ if (outer.w !== inner.w || outer.h !== inner.h) {
+ ctx.beginPath();
+ addRectPath(ctx, inflateRect(outer, inflateAmount, inner));
+ ctx.clip();
+ addRectPath(ctx, inflateRect(inner, -inflateAmount, outer));
+ ctx.fillStyle = borderColor;
+ ctx.fill('evenodd');
+ }
+ ctx.beginPath();
+ addRectPath(ctx, inflateRect(inner, inflateAmount));
+ ctx.fillStyle = backgroundColor;
+ ctx.fill();
+ ctx.restore();
+ }
+ }, {
+ key: "inRange",
+ value: function inRange(mouseX, mouseY, useFinalPosition) {
+ return _inRange(this, mouseX, mouseY, useFinalPosition);
+ }
+ }, {
+ key: "inXRange",
+ value: function inXRange(mouseX, useFinalPosition) {
+ return _inRange(this, mouseX, null, useFinalPosition);
+ }
+ }, {
+ key: "inYRange",
+ value: function inYRange(mouseY, useFinalPosition) {
+ return _inRange(this, null, mouseY, useFinalPosition);
+ }
+ }, {
+ key: "getCenterPoint",
+ value: function getCenterPoint(useFinalPosition) {
+ var _this$getProps6 = this.getProps(['x', 'y', 'base', 'horizontal'], useFinalPosition),
+ x = _this$getProps6.x,
+ y = _this$getProps6.y,
+ base = _this$getProps6.base,
+ horizontal = _this$getProps6.horizontal;
+ return {
+ x: horizontal ? (x + base) / 2 : x,
+ y: horizontal ? y : (y + base) / 2
+ };
+ }
+ }, {
+ key: "getRange",
+ value: function getRange(axis) {
+ return axis === 'x' ? this.width / 2 : this.height / 2;
+ }
+ }]);
+ }(Element);
+ _defineProperty$1(BarElement, "id", 'bar');
+ _defineProperty$1(BarElement, "defaults", {
+ borderSkipped: 'start',
+ borderWidth: 0,
+ borderRadius: 0,
+ inflateAmount: 'auto',
+ pointStyle: undefined
+ });
+ _defineProperty$1(BarElement, "defaultRoutes", {
+ backgroundColor: 'backgroundColor',
+ borderColor: 'borderColor'
+ });
+ var elements = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ ArcElement: ArcElement,
+ BarElement: BarElement,
+ LineElement: LineElement,
+ PointElement: PointElement
+ });
+ var BORDER_COLORS = ['rgb(54, 162, 235)', 'rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(255, 205, 86)', 'rgb(75, 192, 192)', 'rgb(153, 102, 255)', 'rgb(201, 203, 207)' // grey
+ ];
+ // Border colors with 50% transparency
+ var BACKGROUND_COLORS = /* #__PURE__ */BORDER_COLORS.map(function (color) {
+ return color.replace('rgb(', 'rgba(').replace(')', ', 0.5)');
+ });
+ function getBorderColor(i) {
+ return BORDER_COLORS[i % BORDER_COLORS.length];
+ }
+ function getBackgroundColor(i) {
+ return BACKGROUND_COLORS[i % BACKGROUND_COLORS.length];
+ }
+ function colorizeDefaultDataset(dataset, i) {
+ dataset.borderColor = getBorderColor(i);
+ dataset.backgroundColor = getBackgroundColor(i);
+ return ++i;
+ }
+ function colorizeDoughnutDataset(dataset, i) {
+ dataset.backgroundColor = dataset.data.map(function () {
+ return getBorderColor(i++);
+ });
+ return i;
+ }
+ function colorizePolarAreaDataset(dataset, i) {
+ dataset.backgroundColor = dataset.data.map(function () {
+ return getBackgroundColor(i++);
+ });
+ return i;
+ }
+ function getColorizer(chart) {
+ var i = 0;
+ return function (dataset, datasetIndex) {
+ var controller = chart.getDatasetMeta(datasetIndex).controller;
+ if (controller instanceof DoughnutController) {
+ i = colorizeDoughnutDataset(dataset, i);
+ } else if (controller instanceof PolarAreaController) {
+ i = colorizePolarAreaDataset(dataset, i);
+ } else if (controller) {
+ i = colorizeDefaultDataset(dataset, i);
+ }
+ };
+ }
+ function containsColorsDefinitions(descriptors) {
+ var k;
+ for (k in descriptors) {
+ if (descriptors[k].borderColor || descriptors[k].backgroundColor) {
+ return true;
+ }
+ }
+ return false;
+ }
+ function containsColorsDefinition(descriptor) {
+ return descriptor && (descriptor.borderColor || descriptor.backgroundColor);
+ }
+ function containsDefaultColorsDefenitions() {
+ return defaults.borderColor !== 'rgba(0,0,0,0.1)' || defaults.backgroundColor !== 'rgba(0,0,0,0.1)';
+ }
+ var plugin_colors = {
+ id: 'colors',
+ defaults: {
+ enabled: true,
+ forceOverride: false
+ },
+ beforeLayout: function beforeLayout(chart, _args, options) {
+ if (!options.enabled) {
+ return;
+ }
+ var _chart$config = chart.config,
+ datasets = _chart$config.data.datasets,
+ chartOptions = _chart$config.options;
+ var elements = chartOptions.elements;
+ var containsColorDefenition = containsColorsDefinitions(datasets) || containsColorsDefinition(chartOptions) || elements && containsColorsDefinitions(elements) || containsDefaultColorsDefenitions();
+ if (!options.forceOverride && containsColorDefenition) {
+ return;
+ }
+ var colorizer = getColorizer(chart);
+ datasets.forEach(colorizer);
+ }
+ };
+ function lttbDecimation(data, start, count, availableWidth, options) {
+ var samples = options.samples || availableWidth;
+ if (samples >= count) {
+ return data.slice(start, start + count);
+ }
+ var decimated = [];
+ var bucketWidth = (count - 2) / (samples - 2);
+ var sampledIndex = 0;
+ var endIndex = start + count - 1;
+ var a = start;
+ var i, maxAreaPoint, maxArea, area, nextA;
+ decimated[sampledIndex++] = data[a];
+ for (i = 0; i < samples - 2; i++) {
+ var avgX = 0;
+ var avgY = 0;
+ var j = void 0;
+ var avgRangeStart = Math.floor((i + 1) * bucketWidth) + 1 + start;
+ var avgRangeEnd = Math.min(Math.floor((i + 2) * bucketWidth) + 1, count) + start;
+ var avgRangeLength = avgRangeEnd - avgRangeStart;
+ for (j = avgRangeStart; j < avgRangeEnd; j++) {
+ avgX += data[j].x;
+ avgY += data[j].y;
+ }
+ avgX /= avgRangeLength;
+ avgY /= avgRangeLength;
+ var rangeOffs = Math.floor(i * bucketWidth) + 1 + start;
+ var rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start;
+ var _data$a = data[a],
+ pointAx = _data$a.x,
+ pointAy = _data$a.y;
+ maxArea = area = -1;
+ for (j = rangeOffs; j < rangeTo; j++) {
+ area = 0.5 * Math.abs((pointAx - avgX) * (data[j].y - pointAy) - (pointAx - data[j].x) * (avgY - pointAy));
+ if (area > maxArea) {
+ maxArea = area;
+ maxAreaPoint = data[j];
+ nextA = j;
+ }
+ }
+ decimated[sampledIndex++] = maxAreaPoint;
+ a = nextA;
+ }
+ decimated[sampledIndex++] = data[endIndex];
+ return decimated;
+ }
+ function minMaxDecimation(data, start, count, availableWidth) {
+ var avgX = 0;
+ var countX = 0;
+ var i, point, x, y, prevX, minIndex, maxIndex, startIndex, minY, maxY;
+ var decimated = [];
+ var endIndex = start + count - 1;
+ var xMin = data[start].x;
+ var xMax = data[endIndex].x;
+ var dx = xMax - xMin;
+ for (i = start; i < start + count; ++i) {
+ point = data[i];
+ x = (point.x - xMin) / dx * availableWidth;
+ y = point.y;
+ var truncX = x | 0;
+ if (truncX === prevX) {
+ if (y < minY) {
+ minY = y;
+ minIndex = i;
+ } else if (y > maxY) {
+ maxY = y;
+ maxIndex = i;
+ }
+ avgX = (countX * avgX + point.x) / ++countX;
+ } else {
+ var lastIndex = i - 1;
+ if (!isNullOrUndef(minIndex) && !isNullOrUndef(maxIndex)) {
+ var intermediateIndex1 = Math.min(minIndex, maxIndex);
+ var intermediateIndex2 = Math.max(minIndex, maxIndex);
+ if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) {
+ decimated.push(_objectSpread2(_objectSpread2({}, data[intermediateIndex1]), {}, {
+ x: avgX
+ }));
+ }
+ if (intermediateIndex2 !== startIndex && intermediateIndex2 !== lastIndex) {
+ decimated.push(_objectSpread2(_objectSpread2({}, data[intermediateIndex2]), {}, {
+ x: avgX
+ }));
+ }
+ }
+ if (i > 0 && lastIndex !== startIndex) {
+ decimated.push(data[lastIndex]);
+ }
+ decimated.push(point);
+ prevX = truncX;
+ countX = 0;
+ minY = maxY = y;
+ minIndex = maxIndex = startIndex = i;
+ }
+ }
+ return decimated;
+ }
+ function cleanDecimatedDataset(dataset) {
+ if (dataset._decimated) {
+ var data = dataset._data;
+ delete dataset._decimated;
+ delete dataset._data;
+ Object.defineProperty(dataset, 'data', {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: data
+ });
+ }
+ }
+ function cleanDecimatedData(chart) {
+ chart.data.datasets.forEach(function (dataset) {
+ cleanDecimatedDataset(dataset);
+ });
+ }
+ function getStartAndCountOfVisiblePointsSimplified(meta, points) {
+ var pointCount = points.length;
+ var start = 0;
+ var count;
+ var iScale = meta.iScale;
+ var _iScale$getUserBounds = iScale.getUserBounds(),
+ min = _iScale$getUserBounds.min,
+ max = _iScale$getUserBounds.max,
+ minDefined = _iScale$getUserBounds.minDefined,
+ maxDefined = _iScale$getUserBounds.maxDefined;
+ if (minDefined) {
+ start = _limitValue(_lookupByKey(points, iScale.axis, min).lo, 0, pointCount - 1);
+ }
+ if (maxDefined) {
+ count = _limitValue(_lookupByKey(points, iScale.axis, max).hi + 1, start, pointCount) - start;
+ } else {
+ count = pointCount - start;
+ }
+ return {
+ start: start,
+ count: count
+ };
+ }
+ var plugin_decimation = {
+ id: 'decimation',
+ defaults: {
+ algorithm: 'min-max',
+ enabled: false
+ },
+ beforeElementsUpdate: function beforeElementsUpdate(chart, args, options) {
+ if (!options.enabled) {
+ cleanDecimatedData(chart);
+ return;
+ }
+ var availableWidth = chart.width;
+ chart.data.datasets.forEach(function (dataset, datasetIndex) {
+ var _data = dataset._data,
+ indexAxis = dataset.indexAxis;
+ var meta = chart.getDatasetMeta(datasetIndex);
+ var data = _data || dataset.data;
+ if (resolve([indexAxis, chart.options.indexAxis]) === 'y') {
+ return;
+ }
+ if (!meta.controller.supportsDecimation) {
+ return;
+ }
+ var xAxis = chart.scales[meta.xAxisID];
+ if (xAxis.type !== 'linear' && xAxis.type !== 'time') {
+ return;
+ }
+ if (chart.options.parsing) {
+ return;
+ }
+ var _getStartAndCountOfVi3 = getStartAndCountOfVisiblePointsSimplified(meta, data),
+ start = _getStartAndCountOfVi3.start,
+ count = _getStartAndCountOfVi3.count;
+ var threshold = options.threshold || 4 * availableWidth;
+ if (count <= threshold) {
+ cleanDecimatedDataset(dataset);
+ return;
+ }
+ if (isNullOrUndef(_data)) {
+ dataset._data = data;
+ delete dataset.data;
+ Object.defineProperty(dataset, 'data', {
+ configurable: true,
+ enumerable: true,
+ get: function get() {
+ return this._decimated;
+ },
+ set: function set(d) {
+ this._data = d;
+ }
+ });
+ }
+ var decimated;
+ switch (options.algorithm) {
+ case 'lttb':
+ decimated = lttbDecimation(data, start, count, availableWidth, options);
+ break;
+ case 'min-max':
+ decimated = minMaxDecimation(data, start, count, availableWidth);
+ break;
+ default:
+ throw new Error("Unsupported decimation algorithm '".concat(options.algorithm, "'"));
+ }
+ dataset._decimated = decimated;
+ });
+ },
+ destroy: function destroy(chart) {
+ cleanDecimatedData(chart);
+ }
+ };
+ function _segments(line, target, property) {
+ var segments = line.segments;
+ var points = line.points;
+ var tpoints = target.points;
+ var parts = [];
+ var _iterator18 = _createForOfIteratorHelper$1(segments),
+ _step18;
+ try {
+ for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
+ var segment = _step18.value;
+ var start = segment.start,
+ end = segment.end;
+ end = _findSegmentEnd(start, end, points);
+ var bounds = _getBounds(property, points[start], points[end], segment.loop);
+ if (!target.segments) {
+ parts.push({
+ source: segment,
+ target: bounds,
+ start: points[start],
+ end: points[end]
+ });
+ continue;
+ }
+ var targetSegments = _boundSegments(target, bounds);
+ var _iterator19 = _createForOfIteratorHelper$1(targetSegments),
+ _step19;
+ try {
+ for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
+ var tgt = _step19.value;
+ var subBounds = _getBounds(property, tpoints[tgt.start], tpoints[tgt.end], tgt.loop);
+ var fillSources = _boundSegment(segment, points, subBounds);
+ var _iterator20 = _createForOfIteratorHelper$1(fillSources),
+ _step20;
+ try {
+ for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
+ var fillSource = _step20.value;
+ parts.push({
+ source: fillSource,
+ target: tgt,
+ start: _defineProperty$1({}, property, _getEdge(bounds, subBounds, 'start', Math.max)),
+ end: _defineProperty$1({}, property, _getEdge(bounds, subBounds, 'end', Math.min))
+ });
+ }
+ } catch (err) {
+ _iterator20.e(err);
+ } finally {
+ _iterator20.f();
+ }
+ }
+ } catch (err) {
+ _iterator19.e(err);
+ } finally {
+ _iterator19.f();
+ }
+ }
+ } catch (err) {
+ _iterator18.e(err);
+ } finally {
+ _iterator18.f();
+ }
+ return parts;
+ }
+ function _getBounds(property, first, last, loop) {
+ if (loop) {
+ return;
+ }
+ var start = first[property];
+ var end = last[property];
+ if (property === 'angle') {
+ start = _normalizeAngle(start);
+ end = _normalizeAngle(end);
+ }
+ return {
+ property: property,
+ start: start,
+ end: end
+ };
+ }
+ function _pointsFromSegments(boundary, line) {
+ var _ref7 = boundary || {},
+ _ref7$x = _ref7.x,
+ x = _ref7$x === void 0 ? null : _ref7$x,
+ _ref7$y = _ref7.y,
+ y = _ref7$y === void 0 ? null : _ref7$y;
+ var linePoints = line.points;
+ var points = [];
+ line.segments.forEach(function (_ref8) {
+ var start = _ref8.start,
+ end = _ref8.end;
+ end = _findSegmentEnd(start, end, linePoints);
+ var first = linePoints[start];
+ var last = linePoints[end];
+ if (y !== null) {
+ points.push({
+ x: first.x,
+ y: y
+ });
+ points.push({
+ x: last.x,
+ y: y
+ });
+ } else if (x !== null) {
+ points.push({
+ x: x,
+ y: first.y
+ });
+ points.push({
+ x: x,
+ y: last.y
+ });
+ }
+ });
+ return points;
+ }
+ function _findSegmentEnd(start, end, points) {
+ for (; end > start; end--) {
+ var point = points[end];
+ if (!isNaN(point.x) && !isNaN(point.y)) {
+ break;
+ }
+ }
+ return end;
+ }
+ function _getEdge(a, b, prop, fn) {
+ if (a && b) {
+ return fn(a[prop], b[prop]);
+ }
+ return a ? a[prop] : b ? b[prop] : 0;
+ }
+ function _createBoundaryLine(boundary, line) {
+ var points = [];
+ var _loop = false;
+ if (isArray(boundary)) {
+ _loop = true;
+ points = boundary;
+ } else {
+ points = _pointsFromSegments(boundary, line);
+ }
+ return points.length ? new LineElement({
+ points: points,
+ options: {
+ tension: 0
+ },
+ _loop: _loop,
+ _fullLoop: _loop
+ }) : null;
+ }
+ function _shouldApplyFill(source) {
+ return source && source.fill !== false;
+ }
+ function _resolveTarget(sources, index, propagate) {
+ var source = sources[index];
+ var fill = source.fill;
+ var visited = [index];
+ var target;
+ if (!propagate) {
+ return fill;
+ }
+ while (fill !== false && visited.indexOf(fill) === -1) {
+ if (!isNumberFinite(fill)) {
+ return fill;
+ }
+ target = sources[fill];
+ if (!target) {
+ return false;
+ }
+ if (target.visible) {
+ return fill;
+ }
+ visited.push(fill);
+ fill = target.fill;
+ }
+ return false;
+ }
+ function _decodeFill(line, index, count) {
+ var fill = parseFillOption(line);
+ if (isObject(fill)) {
+ return isNaN(fill.value) ? false : fill;
+ }
+ var target = parseFloat(fill);
+ if (isNumberFinite(target) && Math.floor(target) === target) {
+ return decodeTargetIndex(fill[0], index, target, count);
+ }
+ return ['origin', 'start', 'end', 'stack', 'shape'].indexOf(fill) >= 0 && fill;
+ }
+ function decodeTargetIndex(firstCh, index, target, count) {
+ if (firstCh === '-' || firstCh === '+') {
+ target = index + target;
+ }
+ if (target === index || target < 0 || target >= count) {
+ return false;
+ }
+ return target;
+ }
+ function _getTargetPixel(fill, scale) {
+ var pixel = null;
+ if (fill === 'start') {
+ pixel = scale.bottom;
+ } else if (fill === 'end') {
+ pixel = scale.top;
+ } else if (isObject(fill)) {
+ pixel = scale.getPixelForValue(fill.value);
+ } else if (scale.getBasePixel) {
+ pixel = scale.getBasePixel();
+ }
+ return pixel;
+ }
+ function _getTargetValue(fill, scale, startValue) {
+ var value;
+ if (fill === 'start') {
+ value = startValue;
+ } else if (fill === 'end') {
+ value = scale.options.reverse ? scale.min : scale.max;
+ } else if (isObject(fill)) {
+ value = fill.value;
+ } else {
+ value = scale.getBaseValue();
+ }
+ return value;
+ }
+ function parseFillOption(line) {
+ var options = line.options;
+ var fillOption = options.fill;
+ var fill = valueOrDefault(fillOption && fillOption.target, fillOption);
+ if (fill === undefined) {
+ fill = !!options.backgroundColor;
+ }
+ if (fill === false || fill === null) {
+ return false;
+ }
+ if (fill === true) {
+ return 'origin';
+ }
+ return fill;
+ }
+ function _buildStackLine(source) {
+ var scale = source.scale,
+ index = source.index,
+ line = source.line;
+ var points = [];
+ var segments = line.segments;
+ var sourcePoints = line.points;
+ var linesBelow = getLinesBelow(scale, index);
+ linesBelow.push(_createBoundaryLine({
+ x: null,
+ y: scale.bottom
+ }, line));
+ for (var i = 0; i < segments.length; i++) {
+ var segment = segments[i];
+ for (var j = segment.start; j <= segment.end; j++) {
+ addPointsBelow(points, sourcePoints[j], linesBelow);
+ }
+ }
+ return new LineElement({
+ points: points,
+ options: {}
+ });
+ }
+ function getLinesBelow(scale, index) {
+ var below = [];
+ var metas = scale.getMatchingVisibleMetas('line');
+ for (var i = 0; i < metas.length; i++) {
+ var meta = metas[i];
+ if (meta.index === index) {
+ break;
+ }
+ if (!meta.hidden) {
+ below.unshift(meta.dataset);
+ }
+ }
+ return below;
+ }
+ function addPointsBelow(points, sourcePoint, linesBelow) {
+ var postponed = [];
+ for (var j = 0; j < linesBelow.length; j++) {
+ var line = linesBelow[j];
+ var _findPoint = findPoint(line, sourcePoint, 'x'),
+ first = _findPoint.first,
+ last = _findPoint.last,
+ point = _findPoint.point;
+ if (!point || first && last) {
+ continue;
+ }
+ if (first) {
+ postponed.unshift(point);
+ } else {
+ points.push(point);
+ if (!last) {
+ break;
+ }
+ }
+ }
+ points.push.apply(points, postponed);
+ }
+ function findPoint(line, sourcePoint, property) {
+ var point = line.interpolate(sourcePoint, property);
+ if (!point) {
+ return {};
+ }
+ var pointValue = point[property];
+ var segments = line.segments;
+ var linePoints = line.points;
+ var first = false;
+ var last = false;
+ for (var i = 0; i < segments.length; i++) {
+ var segment = segments[i];
+ var firstValue = linePoints[segment.start][property];
+ var lastValue = linePoints[segment.end][property];
+ if (_isBetween(pointValue, firstValue, lastValue)) {
+ first = pointValue === firstValue;
+ last = pointValue === lastValue;
+ break;
+ }
+ }
+ return {
+ first: first,
+ last: last,
+ point: point
+ };
+ }
+ var simpleArc = /*#__PURE__*/function () {
+ function simpleArc(opts) {
+ _classCallCheck$1(this, simpleArc);
+ this.x = opts.x;
+ this.y = opts.y;
+ this.radius = opts.radius;
+ }
+ return _createClass$1(simpleArc, [{
+ key: "pathSegment",
+ value: function pathSegment(ctx, bounds, opts) {
+ var x = this.x,
+ y = this.y,
+ radius = this.radius;
+ bounds = bounds || {
+ start: 0,
+ end: TAU
+ };
+ ctx.arc(x, y, radius, bounds.end, bounds.start, true);
+ return !opts.bounds;
+ }
+ }, {
+ key: "interpolate",
+ value: function interpolate(point) {
+ var x = this.x,
+ y = this.y,
+ radius = this.radius;
+ var angle = point.angle;
+ return {
+ x: x + Math.cos(angle) * radius,
+ y: y + Math.sin(angle) * radius,
+ angle: angle
+ };
+ }
+ }]);
+ }();
+ function _getTarget(source) {
+ var chart = source.chart,
+ fill = source.fill,
+ line = source.line;
+ if (isNumberFinite(fill)) {
+ return getLineByIndex(chart, fill);
+ }
+ if (fill === 'stack') {
+ return _buildStackLine(source);
+ }
+ if (fill === 'shape') {
+ return true;
+ }
+ var boundary = computeBoundary(source);
+ if (boundary instanceof simpleArc) {
+ return boundary;
+ }
+ return _createBoundaryLine(boundary, line);
+ }
+ function getLineByIndex(chart, index) {
+ var meta = chart.getDatasetMeta(index);
+ var visible = meta && chart.isDatasetVisible(index);
+ return visible ? meta.dataset : null;
+ }
+ function computeBoundary(source) {
+ var scale = source.scale || {};
+ if (scale.getPointPositionForValue) {
+ return computeCircularBoundary(source);
+ }
+ return computeLinearBoundary(source);
+ }
+ function computeLinearBoundary(source) {
+ var _source$scale = source.scale,
+ scale = _source$scale === void 0 ? {} : _source$scale,
+ fill = source.fill;
+ var pixel = _getTargetPixel(fill, scale);
+ if (isNumberFinite(pixel)) {
+ var horizontal = scale.isHorizontal();
+ return {
+ x: horizontal ? pixel : null,
+ y: horizontal ? null : pixel
+ };
+ }
+ return null;
+ }
+ function computeCircularBoundary(source) {
+ var scale = source.scale,
+ fill = source.fill;
+ var options = scale.options;
+ var length = scale.getLabels().length;
+ var start = options.reverse ? scale.max : scale.min;
+ var value = _getTargetValue(fill, scale, start);
+ var target = [];
+ if (options.grid.circular) {
+ var center = scale.getPointPositionForValue(0, start);
+ return new simpleArc({
+ x: center.x,
+ y: center.y,
+ radius: scale.getDistanceFromCenterForValue(value)
+ });
+ }
+ for (var i = 0; i < length; ++i) {
+ target.push(scale.getPointPositionForValue(i, value));
+ }
+ return target;
+ }
+ function _drawfill(ctx, source, area) {
+ var target = _getTarget(source);
+ var line = source.line,
+ scale = source.scale,
+ axis = source.axis;
+ var lineOpts = line.options;
+ var fillOption = lineOpts.fill;
+ var color = lineOpts.backgroundColor;
+ var _ref9 = fillOption || {},
+ _ref9$above = _ref9.above,
+ above = _ref9$above === void 0 ? color : _ref9$above,
+ _ref9$below = _ref9.below,
+ below = _ref9$below === void 0 ? color : _ref9$below;
+ if (target && line.points.length) {
+ clipArea(ctx, area);
+ doFill(ctx, {
+ line: line,
+ target: target,
+ above: above,
+ below: below,
+ area: area,
+ scale: scale,
+ axis: axis
+ });
+ unclipArea(ctx);
+ }
+ }
+ function doFill(ctx, cfg) {
+ var line = cfg.line,
+ target = cfg.target,
+ above = cfg.above,
+ below = cfg.below,
+ area = cfg.area,
+ scale = cfg.scale;
+ var property = line._loop ? 'angle' : cfg.axis;
+ ctx.save();
+ if (property === 'x' && below !== above) {
+ clipVertical(ctx, target, area.top);
+ fill(ctx, {
+ line: line,
+ target: target,
+ color: above,
+ scale: scale,
+ property: property
+ });
+ ctx.restore();
+ ctx.save();
+ clipVertical(ctx, target, area.bottom);
+ }
+ fill(ctx, {
+ line: line,
+ target: target,
+ color: below,
+ scale: scale,
+ property: property
+ });
+ ctx.restore();
+ }
+ function clipVertical(ctx, target, clipY) {
+ var segments = target.segments,
+ points = target.points;
+ var first = true;
+ var lineLoop = false;
+ ctx.beginPath();
+ var _iterator21 = _createForOfIteratorHelper$1(segments),
+ _step21;
+ try {
+ for (_iterator21.s(); !(_step21 = _iterator21.n()).done;) {
+ var segment = _step21.value;
+ var start = segment.start,
+ end = segment.end;
+ var firstPoint = points[start];
+ var lastPoint = points[_findSegmentEnd(start, end, points)];
+ if (first) {
+ ctx.moveTo(firstPoint.x, firstPoint.y);
+ first = false;
+ } else {
+ ctx.lineTo(firstPoint.x, clipY);
+ ctx.lineTo(firstPoint.x, firstPoint.y);
+ }
+ lineLoop = !!target.pathSegment(ctx, segment, {
+ move: lineLoop
+ });
+ if (lineLoop) {
+ ctx.closePath();
+ } else {
+ ctx.lineTo(lastPoint.x, clipY);
+ }
+ }
+ } catch (err) {
+ _iterator21.e(err);
+ } finally {
+ _iterator21.f();
+ }
+ ctx.lineTo(target.first().x, clipY);
+ ctx.closePath();
+ ctx.clip();
+ }
+ function fill(ctx, cfg) {
+ var line = cfg.line,
+ target = cfg.target,
+ property = cfg.property,
+ color = cfg.color,
+ scale = cfg.scale;
+ var segments = _segments(line, target, property);
+ var _iterator22 = _createForOfIteratorHelper$1(segments),
+ _step22;
+ try {
+ for (_iterator22.s(); !(_step22 = _iterator22.n()).done;) {
+ var _step22$value = _step22.value,
+ src = _step22$value.source,
+ tgt = _step22$value.target,
+ start = _step22$value.start,
+ end = _step22$value.end;
+ var _src$style = src.style,
+ _src$style2 = _src$style === void 0 ? {} : _src$style,
+ _src$style2$backgroun = _src$style2.backgroundColor,
+ backgroundColor = _src$style2$backgroun === void 0 ? color : _src$style2$backgroun;
+ var notShape = target !== true;
+ ctx.save();
+ ctx.fillStyle = backgroundColor;
+ clipBounds(ctx, scale, notShape && _getBounds(property, start, end));
+ ctx.beginPath();
+ var lineLoop = !!line.pathSegment(ctx, src);
+ var loop = void 0;
+ if (notShape) {
+ if (lineLoop) {
+ ctx.closePath();
+ } else {
+ interpolatedLineTo(ctx, target, end, property);
+ }
+ var targetLoop = !!target.pathSegment(ctx, tgt, {
+ move: lineLoop,
+ reverse: true
+ });
+ loop = lineLoop && targetLoop;
+ if (!loop) {
+ interpolatedLineTo(ctx, target, start, property);
+ }
+ }
+ ctx.closePath();
+ ctx.fill(loop ? 'evenodd' : 'nonzero');
+ ctx.restore();
+ }
+ } catch (err) {
+ _iterator22.e(err);
+ } finally {
+ _iterator22.f();
+ }
+ }
+ function clipBounds(ctx, scale, bounds) {
+ var _scale$chart$chartAre = scale.chart.chartArea,
+ top = _scale$chart$chartAre.top,
+ bottom = _scale$chart$chartAre.bottom;
+ var _ref10 = bounds || {},
+ property = _ref10.property,
+ start = _ref10.start,
+ end = _ref10.end;
+ if (property === 'x') {
+ ctx.beginPath();
+ ctx.rect(start, top, end - start, bottom - top);
+ ctx.clip();
+ }
+ }
+ function interpolatedLineTo(ctx, target, point, property) {
+ var interpolatedPoint = target.interpolate(point, property);
+ if (interpolatedPoint) {
+ ctx.lineTo(interpolatedPoint.x, interpolatedPoint.y);
+ }
+ }
+ var index = {
+ id: 'filler',
+ afterDatasetsUpdate: function afterDatasetsUpdate(chart, _args, options) {
+ var count = (chart.data.datasets || []).length;
+ var sources = [];
+ var meta, i, line, source;
+ for (i = 0; i < count; ++i) {
+ meta = chart.getDatasetMeta(i);
+ line = meta.dataset;
+ source = null;
+ if (line && line.options && line instanceof LineElement) {
+ source = {
+ visible: chart.isDatasetVisible(i),
+ index: i,
+ fill: _decodeFill(line, i, count),
+ chart: chart,
+ axis: meta.controller.options.indexAxis,
+ scale: meta.vScale,
+ line: line
+ };
+ }
+ meta.$filler = source;
+ sources.push(source);
+ }
+ for (i = 0; i < count; ++i) {
+ source = sources[i];
+ if (!source || source.fill === false) {
+ continue;
+ }
+ source.fill = _resolveTarget(sources, i, options.propagate);
+ }
+ },
+ beforeDraw: function beforeDraw(chart, _args, options) {
+ var draw = options.drawTime === 'beforeDraw';
+ var metasets = chart.getSortedVisibleDatasetMetas();
+ var area = chart.chartArea;
+ for (var i = metasets.length - 1; i >= 0; --i) {
+ var source = metasets[i].$filler;
+ if (!source) {
+ continue;
+ }
+ source.line.updateControlPoints(area, source.axis);
+ if (draw && source.fill) {
+ _drawfill(chart.ctx, source, area);
+ }
+ }
+ },
+ beforeDatasetsDraw: function beforeDatasetsDraw(chart, _args, options) {
+ if (options.drawTime !== 'beforeDatasetsDraw') {
+ return;
+ }
+ var metasets = chart.getSortedVisibleDatasetMetas();
+ for (var i = metasets.length - 1; i >= 0; --i) {
+ var source = metasets[i].$filler;
+ if (_shouldApplyFill(source)) {
+ _drawfill(chart.ctx, source, chart.chartArea);
+ }
+ }
+ },
+ beforeDatasetDraw: function beforeDatasetDraw(chart, args, options) {
+ var source = args.meta.$filler;
+ if (!_shouldApplyFill(source) || options.drawTime !== 'beforeDatasetDraw') {
+ return;
+ }
+ _drawfill(chart.ctx, source, chart.chartArea);
+ },
+ defaults: {
+ propagate: true,
+ drawTime: 'beforeDatasetDraw'
+ }
+ };
+ var getBoxSize = function getBoxSize(labelOpts, fontSize) {
+ var _labelOpts$boxHeight = labelOpts.boxHeight,
+ boxHeight = _labelOpts$boxHeight === void 0 ? fontSize : _labelOpts$boxHeight,
+ _labelOpts$boxWidth = labelOpts.boxWidth,
+ boxWidth = _labelOpts$boxWidth === void 0 ? fontSize : _labelOpts$boxWidth;
+ if (labelOpts.usePointStyle) {
+ boxHeight = Math.min(boxHeight, fontSize);
+ boxWidth = labelOpts.pointStyleWidth || Math.min(boxWidth, fontSize);
+ }
+ return {
+ boxWidth: boxWidth,
+ boxHeight: boxHeight,
+ itemHeight: Math.max(fontSize, boxHeight)
+ };
+ };
+ var itemsEqual = function itemsEqual(a, b) {
+ return a !== null && b !== null && a.datasetIndex === b.datasetIndex && a.index === b.index;
+ };
+ var Legend = /*#__PURE__*/function (_Element7) {
+ function Legend(config) {
+ var _this27;
+ _classCallCheck$1(this, Legend);
+ _this27 = _callSuper(this, Legend);
+ _this27._added = false;
+ _this27.legendHitBoxes = [];
+ _this27._hoveredItem = null;
+ _this27.doughnutMode = false;
+ _this27.chart = config.chart;
+ _this27.options = config.options;
+ _this27.ctx = config.ctx;
+ _this27.legendItems = undefined;
+ _this27.columnSizes = undefined;
+ _this27.lineWidths = undefined;
+ _this27.maxHeight = undefined;
+ _this27.maxWidth = undefined;
+ _this27.top = undefined;
+ _this27.bottom = undefined;
+ _this27.left = undefined;
+ _this27.right = undefined;
+ _this27.height = undefined;
+ _this27.width = undefined;
+ _this27._margins = undefined;
+ _this27.position = undefined;
+ _this27.weight = undefined;
+ _this27.fullSize = undefined;
+ return _this27;
+ }
+ _inherits$1(Legend, _Element7);
+ return _createClass$1(Legend, [{
+ key: "update",
+ value: function update(maxWidth, maxHeight, margins) {
+ this.maxWidth = maxWidth;
+ this.maxHeight = maxHeight;
+ this._margins = margins;
+ this.setDimensions();
+ this.buildLabels();
+ this.fit();
+ }
+ }, {
+ key: "setDimensions",
+ value: function setDimensions() {
+ if (this.isHorizontal()) {
+ this.width = this.maxWidth;
+ this.left = this._margins.left;
+ this.right = this.width;
+ } else {
+ this.height = this.maxHeight;
+ this.top = this._margins.top;
+ this.bottom = this.height;
+ }
+ }
+ }, {
+ key: "buildLabels",
+ value: function buildLabels() {
+ var _this28 = this;
+ var labelOpts = this.options.labels || {};
+ var legendItems = callback(labelOpts.generateLabels, [this.chart], this) || [];
+ if (labelOpts.filter) {
+ legendItems = legendItems.filter(function (item) {
+ return labelOpts.filter(item, _this28.chart.data);
+ });
+ }
+ if (labelOpts.sort) {
+ legendItems = legendItems.sort(function (a, b) {
+ return labelOpts.sort(a, b, _this28.chart.data);
+ });
+ }
+ if (this.options.reverse) {
+ legendItems.reverse();
+ }
+ this.legendItems = legendItems;
+ }
+ }, {
+ key: "fit",
+ value: function fit() {
+ var options = this.options,
+ ctx = this.ctx;
+ if (!options.display) {
+ this.width = this.height = 0;
+ return;
+ }
+ var labelOpts = options.labels;
+ var labelFont = toFont(labelOpts.font);
+ var fontSize = labelFont.size;
+ var titleHeight = this._computeTitleHeight();
+ var _getBoxSize = getBoxSize(labelOpts, fontSize),
+ boxWidth = _getBoxSize.boxWidth,
+ itemHeight = _getBoxSize.itemHeight;
+ var width, height;
+ ctx.font = labelFont.string;
+ if (this.isHorizontal()) {
+ width = this.maxWidth;
+ height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10;
+ } else {
+ height = this.maxHeight;
+ width = this._fitCols(titleHeight, labelFont, boxWidth, itemHeight) + 10;
+ }
+ this.width = Math.min(width, options.maxWidth || this.maxWidth);
+ this.height = Math.min(height, options.maxHeight || this.maxHeight);
+ }
+ }, {
+ key: "_fitRows",
+ value: function _fitRows(titleHeight, fontSize, boxWidth, itemHeight) {
+ var ctx = this.ctx,
+ maxWidth = this.maxWidth,
+ padding = this.options.labels.padding;
+ var hitboxes = this.legendHitBoxes = [];
+ var lineWidths = this.lineWidths = [0];
+ var lineHeight = itemHeight + padding;
+ var totalHeight = titleHeight;
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'middle';
+ var row = -1;
+ var top = -lineHeight;
+ this.legendItems.forEach(function (legendItem, i) {
+ var itemWidth = boxWidth + fontSize / 2 + ctx.measureText(legendItem.text).width;
+ if (i === 0 || lineWidths[lineWidths.length - 1] + itemWidth + 2 * padding > maxWidth) {
+ totalHeight += lineHeight;
+ lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0;
+ top += lineHeight;
+ row++;
+ }
+ hitboxes[i] = {
+ left: 0,
+ top: top,
+ row: row,
+ width: itemWidth,
+ height: itemHeight
+ };
+ lineWidths[lineWidths.length - 1] += itemWidth + padding;
+ });
+ return totalHeight;
+ }
+ }, {
+ key: "_fitCols",
+ value: function _fitCols(titleHeight, labelFont, boxWidth, _itemHeight) {
+ var ctx = this.ctx,
+ maxHeight = this.maxHeight,
+ padding = this.options.labels.padding;
+ var hitboxes = this.legendHitBoxes = [];
+ var columnSizes = this.columnSizes = [];
+ var heightLimit = maxHeight - titleHeight;
+ var totalWidth = padding;
+ var currentColWidth = 0;
+ var currentColHeight = 0;
+ var left = 0;
+ var col = 0;
+ this.legendItems.forEach(function (legendItem, i) {
+ var _calculateItemSize = calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight),
+ itemWidth = _calculateItemSize.itemWidth,
+ itemHeight = _calculateItemSize.itemHeight;
+ if (i > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) {
+ totalWidth += currentColWidth + padding;
+ columnSizes.push({
+ width: currentColWidth,
+ height: currentColHeight
+ });
+ left += currentColWidth + padding;
+ col++;
+ currentColWidth = currentColHeight = 0;
+ }
+ hitboxes[i] = {
+ left: left,
+ top: currentColHeight,
+ col: col,
+ width: itemWidth,
+ height: itemHeight
+ };
+ currentColWidth = Math.max(currentColWidth, itemWidth);
+ currentColHeight += itemHeight + padding;
+ });
+ totalWidth += currentColWidth;
+ columnSizes.push({
+ width: currentColWidth,
+ height: currentColHeight
+ });
+ return totalWidth;
+ }
+ }, {
+ key: "adjustHitBoxes",
+ value: function adjustHitBoxes() {
+ if (!this.options.display) {
+ return;
+ }
+ var titleHeight = this._computeTitleHeight();
+ var hitboxes = this.legendHitBoxes,
+ _this$options15 = this.options,
+ align = _this$options15.align,
+ padding = _this$options15.labels.padding,
+ rtl = _this$options15.rtl;
+ var rtlHelper = getRtlAdapter(rtl, this.left, this.width);
+ if (this.isHorizontal()) {
+ var row = 0;
+ var left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);
+ var _iterator23 = _createForOfIteratorHelper$1(hitboxes),
+ _step23;
+ try {
+ for (_iterator23.s(); !(_step23 = _iterator23.n()).done;) {
+ var hitbox = _step23.value;
+ if (row !== hitbox.row) {
+ row = hitbox.row;
+ left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);
+ }
+ hitbox.top += this.top + titleHeight + padding;
+ hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width);
+ left += hitbox.width + padding;
+ }
+ } catch (err) {
+ _iterator23.e(err);
+ } finally {
+ _iterator23.f();
+ }
+ } else {
+ var col = 0;
+ var top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);
+ var _iterator24 = _createForOfIteratorHelper$1(hitboxes),
+ _step24;
+ try {
+ for (_iterator24.s(); !(_step24 = _iterator24.n()).done;) {
+ var _hitbox = _step24.value;
+ if (_hitbox.col !== col) {
+ col = _hitbox.col;
+ top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);
+ }
+ _hitbox.top = top;
+ _hitbox.left += this.left + padding;
+ _hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(_hitbox.left), _hitbox.width);
+ top += _hitbox.height + padding;
+ }
+ } catch (err) {
+ _iterator24.e(err);
+ } finally {
+ _iterator24.f();
+ }
+ }
+ }
+ }, {
+ key: "isHorizontal",
+ value: function isHorizontal() {
+ return this.options.position === 'top' || this.options.position === 'bottom';
+ }
+ }, {
+ key: "draw",
+ value: function draw() {
+ if (this.options.display) {
+ var ctx = this.ctx;
+ clipArea(ctx, this);
+ this._draw();
+ unclipArea(ctx);
+ }
+ }
+ }, {
+ key: "_draw",
+ value: function _draw() {
+ var _this29 = this;
+ var opts = this.options,
+ columnSizes = this.columnSizes,
+ lineWidths = this.lineWidths,
+ ctx = this.ctx;
+ var align = opts.align,
+ labelOpts = opts.labels;
+ var defaultColor = defaults.color;
+ var rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);
+ var labelFont = toFont(labelOpts.font);
+ var padding = labelOpts.padding;
+ var fontSize = labelFont.size;
+ var halfFontSize = fontSize / 2;
+ var cursor;
+ this.drawTitle();
+ ctx.textAlign = rtlHelper.textAlign('left');
+ ctx.textBaseline = 'middle';
+ ctx.lineWidth = 0.5;
+ ctx.font = labelFont.string;
+ var _getBoxSize2 = getBoxSize(labelOpts, fontSize),
+ boxWidth = _getBoxSize2.boxWidth,
+ boxHeight = _getBoxSize2.boxHeight,
+ itemHeight = _getBoxSize2.itemHeight;
+ var drawLegendBox = function drawLegendBox(x, y, legendItem) {
+ if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) {
+ return;
+ }
+ ctx.save();
+ var lineWidth = valueOrDefault(legendItem.lineWidth, 1);
+ ctx.fillStyle = valueOrDefault(legendItem.fillStyle, defaultColor);
+ ctx.lineCap = valueOrDefault(legendItem.lineCap, 'butt');
+ ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, 0);
+ ctx.lineJoin = valueOrDefault(legendItem.lineJoin, 'miter');
+ ctx.lineWidth = lineWidth;
+ ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, defaultColor);
+ ctx.setLineDash(valueOrDefault(legendItem.lineDash, []));
+ if (labelOpts.usePointStyle) {
+ var drawOptions = {
+ radius: boxHeight * Math.SQRT2 / 2,
+ pointStyle: legendItem.pointStyle,
+ rotation: legendItem.rotation,
+ borderWidth: lineWidth
+ };
+ var centerX = rtlHelper.xPlus(x, boxWidth / 2);
+ var centerY = y + halfFontSize;
+ drawPointLegend(ctx, drawOptions, centerX, centerY, labelOpts.pointStyleWidth && boxWidth);
+ } else {
+ var yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0);
+ var xBoxLeft = rtlHelper.leftForLtr(x, boxWidth);
+ var borderRadius = toTRBLCorners(legendItem.borderRadius);
+ ctx.beginPath();
+ if (Object.values(borderRadius).some(function (v) {
+ return v !== 0;
+ })) {
+ addRoundedRectPath(ctx, {
+ x: xBoxLeft,
+ y: yBoxTop,
+ w: boxWidth,
+ h: boxHeight,
+ radius: borderRadius
+ });
+ } else {
+ ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight);
+ }
+ ctx.fill();
+ if (lineWidth !== 0) {
+ ctx.stroke();
+ }
+ }
+ ctx.restore();
+ };
+ var fillText = function fillText(x, y, legendItem) {
+ renderText(ctx, legendItem.text, x, y + itemHeight / 2, labelFont, {
+ strikethrough: legendItem.hidden,
+ textAlign: rtlHelper.textAlign(legendItem.textAlign)
+ });
+ };
+ var isHorizontal = this.isHorizontal();
+ var titleHeight = this._computeTitleHeight();
+ if (isHorizontal) {
+ cursor = {
+ x: _alignStartEnd(align, this.left + padding, this.right - lineWidths[0]),
+ y: this.top + padding + titleHeight,
+ line: 0
+ };
+ } else {
+ cursor = {
+ x: this.left + padding,
+ y: _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[0].height),
+ line: 0
+ };
+ }
+ overrideTextDirection(this.ctx, opts.textDirection);
+ var lineHeight = itemHeight + padding;
+ this.legendItems.forEach(function (legendItem, i) {
+ ctx.strokeStyle = legendItem.fontColor;
+ ctx.fillStyle = legendItem.fontColor;
+ var textWidth = ctx.measureText(legendItem.text).width;
+ var textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign));
+ var width = boxWidth + halfFontSize + textWidth;
+ var x = cursor.x;
+ var y = cursor.y;
+ rtlHelper.setWidth(_this29.width);
+ if (isHorizontal) {
+ if (i > 0 && x + width + padding > _this29.right) {
+ y = cursor.y += lineHeight;
+ cursor.line++;
+ x = cursor.x = _alignStartEnd(align, _this29.left + padding, _this29.right - lineWidths[cursor.line]);
+ }
+ } else if (i > 0 && y + lineHeight > _this29.bottom) {
+ x = cursor.x = x + columnSizes[cursor.line].width + padding;
+ cursor.line++;
+ y = cursor.y = _alignStartEnd(align, _this29.top + titleHeight + padding, _this29.bottom - columnSizes[cursor.line].height);
+ }
+ var realX = rtlHelper.x(x);
+ drawLegendBox(realX, y, legendItem);
+ x = _textX(textAlign, x + boxWidth + halfFontSize, isHorizontal ? x + width : _this29.right, opts.rtl);
+ fillText(rtlHelper.x(x), y, legendItem);
+ if (isHorizontal) {
+ cursor.x += width + padding;
+ } else if (typeof legendItem.text !== 'string') {
+ var fontLineHeight = labelFont.lineHeight;
+ cursor.y += calculateLegendItemHeight(legendItem, fontLineHeight) + padding;
+ } else {
+ cursor.y += lineHeight;
+ }
+ });
+ restoreTextDirection(this.ctx, opts.textDirection);
+ }
+ }, {
+ key: "drawTitle",
+ value: function drawTitle() {
+ var opts = this.options;
+ var titleOpts = opts.title;
+ var titleFont = toFont(titleOpts.font);
+ var titlePadding = toPadding(titleOpts.padding);
+ if (!titleOpts.display) {
+ return;
+ }
+ var rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);
+ var ctx = this.ctx;
+ var position = titleOpts.position;
+ var halfFontSize = titleFont.size / 2;
+ var topPaddingPlusHalfFontSize = titlePadding.top + halfFontSize;
+ var y;
+ var left = this.left;
+ var maxWidth = this.width;
+ if (this.isHorizontal()) {
+ maxWidth = Math.max.apply(Math, _toConsumableArray(this.lineWidths));
+ y = this.top + topPaddingPlusHalfFontSize;
+ left = _alignStartEnd(opts.align, left, this.right - maxWidth);
+ } else {
+ var maxHeight = this.columnSizes.reduce(function (acc, size) {
+ return Math.max(acc, size.height);
+ }, 0);
+ y = topPaddingPlusHalfFontSize + _alignStartEnd(opts.align, this.top, this.bottom - maxHeight - opts.labels.padding - this._computeTitleHeight());
+ }
+ var x = _alignStartEnd(position, left, left + maxWidth);
+ ctx.textAlign = rtlHelper.textAlign(_toLeftRightCenter(position));
+ ctx.textBaseline = 'middle';
+ ctx.strokeStyle = titleOpts.color;
+ ctx.fillStyle = titleOpts.color;
+ ctx.font = titleFont.string;
+ renderText(ctx, titleOpts.text, x, y, titleFont);
+ }
+ }, {
+ key: "_computeTitleHeight",
+ value: function _computeTitleHeight() {
+ var titleOpts = this.options.title;
+ var titleFont = toFont(titleOpts.font);
+ var titlePadding = toPadding(titleOpts.padding);
+ return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0;
+ }
+ }, {
+ key: "_getLegendItemAt",
+ value: function _getLegendItemAt(x, y) {
+ var i, hitBox, lh;
+ if (_isBetween(x, this.left, this.right) && _isBetween(y, this.top, this.bottom)) {
+ lh = this.legendHitBoxes;
+ for (i = 0; i < lh.length; ++i) {
+ hitBox = lh[i];
+ if (_isBetween(x, hitBox.left, hitBox.left + hitBox.width) && _isBetween(y, hitBox.top, hitBox.top + hitBox.height)) {
+ return this.legendItems[i];
+ }
+ }
+ }
+ return null;
+ }
+ }, {
+ key: "handleEvent",
+ value: function handleEvent(e) {
+ var opts = this.options;
+ if (!isListened(e.type, opts)) {
+ return;
+ }
+ var hoveredItem = this._getLegendItemAt(e.x, e.y);
+ if (e.type === 'mousemove' || e.type === 'mouseout') {
+ var previous = this._hoveredItem;
+ var sameItem = itemsEqual(previous, hoveredItem);
+ if (previous && !sameItem) {
+ callback(opts.onLeave, [e, previous, this], this);
+ }
+ this._hoveredItem = hoveredItem;
+ if (hoveredItem && !sameItem) {
+ callback(opts.onHover, [e, hoveredItem, this], this);
+ }
+ } else if (hoveredItem) {
+ callback(opts.onClick, [e, hoveredItem, this], this);
+ }
+ }
+ }]);
+ }(Element);
+ function calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight) {
+ var itemWidth = calculateItemWidth(legendItem, boxWidth, labelFont, ctx);
+ var itemHeight = calculateItemHeight(_itemHeight, legendItem, labelFont.lineHeight);
+ return {
+ itemWidth: itemWidth,
+ itemHeight: itemHeight
+ };
+ }
+ function calculateItemWidth(legendItem, boxWidth, labelFont, ctx) {
+ var legendItemText = legendItem.text;
+ if (legendItemText && typeof legendItemText !== 'string') {
+ legendItemText = legendItemText.reduce(function (a, b) {
+ return a.length > b.length ? a : b;
+ });
+ }
+ return boxWidth + labelFont.size / 2 + ctx.measureText(legendItemText).width;
+ }
+ function calculateItemHeight(_itemHeight, legendItem, fontLineHeight) {
+ var itemHeight = _itemHeight;
+ if (typeof legendItem.text !== 'string') {
+ itemHeight = calculateLegendItemHeight(legendItem, fontLineHeight);
+ }
+ return itemHeight;
+ }
+ function calculateLegendItemHeight(legendItem, fontLineHeight) {
+ var labelHeight = legendItem.text ? legendItem.text.length : 0;
+ return fontLineHeight * labelHeight;
+ }
+ function isListened(type, opts) {
+ if ((type === 'mousemove' || type === 'mouseout') && (opts.onHover || opts.onLeave)) {
+ return true;
+ }
+ if (opts.onClick && (type === 'click' || type === 'mouseup')) {
+ return true;
+ }
+ return false;
+ }
+ var plugin_legend = {
+ id: 'legend',
+ _element: Legend,
+ start: function start(chart, _args, options) {
+ var legend = chart.legend = new Legend({
+ ctx: chart.ctx,
+ options: options,
+ chart: chart
+ });
+ layouts.configure(chart, legend, options);
+ layouts.addBox(chart, legend);
+ },
+ stop: function stop(chart) {
+ layouts.removeBox(chart, chart.legend);
+ delete chart.legend;
+ },
+ beforeUpdate: function beforeUpdate(chart, _args, options) {
+ var legend = chart.legend;
+ layouts.configure(chart, legend, options);
+ legend.options = options;
+ },
+ afterUpdate: function afterUpdate(chart) {
+ var legend = chart.legend;
+ legend.buildLabels();
+ legend.adjustHitBoxes();
+ },
+ afterEvent: function afterEvent(chart, args) {
+ if (!args.replay) {
+ chart.legend.handleEvent(args.event);
+ }
+ },
+ defaults: {
+ display: true,
+ position: 'top',
+ align: 'center',
+ fullSize: true,
+ reverse: false,
+ weight: 1000,
+ onClick: function onClick(e, legendItem, legend) {
+ var index = legendItem.datasetIndex;
+ var ci = legend.chart;
+ if (ci.isDatasetVisible(index)) {
+ ci.hide(index);
+ legendItem.hidden = true;
+ } else {
+ ci.show(index);
+ legendItem.hidden = false;
+ }
+ },
+ onHover: null,
+ onLeave: null,
+ labels: {
+ color: function color(ctx) {
+ return ctx.chart.options.color;
+ },
+ boxWidth: 40,
+ padding: 10,
+ generateLabels: function generateLabels(chart) {
+ var datasets = chart.data.datasets;
+ var _chart$legend$options = chart.legend.options.labels,
+ usePointStyle = _chart$legend$options.usePointStyle,
+ pointStyle = _chart$legend$options.pointStyle,
+ textAlign = _chart$legend$options.textAlign,
+ color = _chart$legend$options.color,
+ useBorderRadius = _chart$legend$options.useBorderRadius,
+ borderRadius = _chart$legend$options.borderRadius;
+ return chart._getSortedDatasetMetas().map(function (meta) {
+ var style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
+ var borderWidth = toPadding(style.borderWidth);
+ return {
+ text: datasets[meta.index].label,
+ fillStyle: style.backgroundColor,
+ fontColor: color,
+ hidden: !meta.visible,
+ lineCap: style.borderCapStyle,
+ lineDash: style.borderDash,
+ lineDashOffset: style.borderDashOffset,
+ lineJoin: style.borderJoinStyle,
+ lineWidth: (borderWidth.width + borderWidth.height) / 4,
+ strokeStyle: style.borderColor,
+ pointStyle: pointStyle || style.pointStyle,
+ rotation: style.rotation,
+ textAlign: textAlign || style.textAlign,
+ borderRadius: useBorderRadius && (borderRadius || style.borderRadius),
+ datasetIndex: meta.index
+ };
+ }, this);
+ }
+ },
+ title: {
+ color: function color(ctx) {
+ return ctx.chart.options.color;
+ },
+ display: false,
+ position: 'center',
+ text: ''
+ }
+ },
+ descriptors: {
+ _scriptable: function _scriptable(name) {
+ return !name.startsWith('on');
+ },
+ labels: {
+ _scriptable: function _scriptable(name) {
+ return !['generateLabels', 'filter', 'sort'].includes(name);
+ }
+ }
+ }
+ };
+ var Title = /*#__PURE__*/function (_Element8) {
+ function Title(config) {
+ var _this30;
+ _classCallCheck$1(this, Title);
+ _this30 = _callSuper(this, Title);
+ _this30.chart = config.chart;
+ _this30.options = config.options;
+ _this30.ctx = config.ctx;
+ _this30._padding = undefined;
+ _this30.top = undefined;
+ _this30.bottom = undefined;
+ _this30.left = undefined;
+ _this30.right = undefined;
+ _this30.width = undefined;
+ _this30.height = undefined;
+ _this30.position = undefined;
+ _this30.weight = undefined;
+ _this30.fullSize = undefined;
+ return _this30;
+ }
+ _inherits$1(Title, _Element8);
+ return _createClass$1(Title, [{
+ key: "update",
+ value: function update(maxWidth, maxHeight) {
+ var opts = this.options;
+ this.left = 0;
+ this.top = 0;
+ if (!opts.display) {
+ this.width = this.height = this.right = this.bottom = 0;
+ return;
+ }
+ this.width = this.right = maxWidth;
+ this.height = this.bottom = maxHeight;
+ var lineCount = isArray(opts.text) ? opts.text.length : 1;
+ this._padding = toPadding(opts.padding);
+ var textSize = lineCount * toFont(opts.font).lineHeight + this._padding.height;
+ if (this.isHorizontal()) {
+ this.height = textSize;
+ } else {
+ this.width = textSize;
+ }
+ }
+ }, {
+ key: "isHorizontal",
+ value: function isHorizontal() {
+ var pos = this.options.position;
+ return pos === 'top' || pos === 'bottom';
+ }
+ }, {
+ key: "_drawArgs",
+ value: function _drawArgs(offset) {
+ var top = this.top,
+ left = this.left,
+ bottom = this.bottom,
+ right = this.right,
+ options = this.options;
+ var align = options.align;
+ var rotation = 0;
+ var maxWidth, titleX, titleY;
+ if (this.isHorizontal()) {
+ titleX = _alignStartEnd(align, left, right);
+ titleY = top + offset;
+ maxWidth = right - left;
+ } else {
+ if (options.position === 'left') {
+ titleX = left + offset;
+ titleY = _alignStartEnd(align, bottom, top);
+ rotation = PI * -0.5;
+ } else {
+ titleX = right - offset;
+ titleY = _alignStartEnd(align, top, bottom);
+ rotation = PI * 0.5;
+ }
+ maxWidth = bottom - top;
+ }
+ return {
+ titleX: titleX,
+ titleY: titleY,
+ maxWidth: maxWidth,
+ rotation: rotation
+ };
+ }
+ }, {
+ key: "draw",
+ value: function draw() {
+ var ctx = this.ctx;
+ var opts = this.options;
+ if (!opts.display) {
+ return;
+ }
+ var fontOpts = toFont(opts.font);
+ var lineHeight = fontOpts.lineHeight;
+ var offset = lineHeight / 2 + this._padding.top;
+ var _this$_drawArgs = this._drawArgs(offset),
+ titleX = _this$_drawArgs.titleX,
+ titleY = _this$_drawArgs.titleY,
+ maxWidth = _this$_drawArgs.maxWidth,
+ rotation = _this$_drawArgs.rotation;
+ renderText(ctx, opts.text, 0, 0, fontOpts, {
+ color: opts.color,
+ maxWidth: maxWidth,
+ rotation: rotation,
+ textAlign: _toLeftRightCenter(opts.align),
+ textBaseline: 'middle',
+ translation: [titleX, titleY]
+ });
+ }
+ }]);
+ }(Element);
+ function createTitle(chart, titleOpts) {
+ var title = new Title({
+ ctx: chart.ctx,
+ options: titleOpts,
+ chart: chart
+ });
+ layouts.configure(chart, title, titleOpts);
+ layouts.addBox(chart, title);
+ chart.titleBlock = title;
+ }
+ var plugin_title = {
+ id: 'title',
+ _element: Title,
+ start: function start(chart, _args, options) {
+ createTitle(chart, options);
+ },
+ stop: function stop(chart) {
+ var titleBlock = chart.titleBlock;
+ layouts.removeBox(chart, titleBlock);
+ delete chart.titleBlock;
+ },
+ beforeUpdate: function beforeUpdate(chart, _args, options) {
+ var title = chart.titleBlock;
+ layouts.configure(chart, title, options);
+ title.options = options;
+ },
+ defaults: {
+ align: 'center',
+ display: false,
+ font: {
+ weight: 'bold'
+ },
+ fullSize: true,
+ padding: 10,
+ position: 'top',
+ text: '',
+ weight: 2000
+ },
+ defaultRoutes: {
+ color: 'color'
+ },
+ descriptors: {
+ _scriptable: true,
+ _indexable: false
+ }
+ };
+ var map = new WeakMap();
+ var plugin_subtitle = {
+ id: 'subtitle',
+ start: function start(chart, _args, options) {
+ var title = new Title({
+ ctx: chart.ctx,
+ options: options,
+ chart: chart
+ });
+ layouts.configure(chart, title, options);
+ layouts.addBox(chart, title);
+ map.set(chart, title);
+ },
+ stop: function stop(chart) {
+ layouts.removeBox(chart, map.get(chart));
+ map["delete"](chart);
+ },
+ beforeUpdate: function beforeUpdate(chart, _args, options) {
+ var title = map.get(chart);
+ layouts.configure(chart, title, options);
+ title.options = options;
+ },
+ defaults: {
+ align: 'center',
+ display: false,
+ font: {
+ weight: 'normal'
+ },
+ fullSize: true,
+ padding: 0,
+ position: 'top',
+ text: '',
+ weight: 1500
+ },
+ defaultRoutes: {
+ color: 'color'
+ },
+ descriptors: {
+ _scriptable: true,
+ _indexable: false
+ }
+ };
+ var positioners = {
+ average: function average(items) {
+ if (!items.length) {
+ return false;
+ }
+ var i, len;
+ var xSet = new Set();
+ var y = 0;
+ var count = 0;
+ for (i = 0, len = items.length; i < len; ++i) {
+ var el = items[i].element;
+ if (el && el.hasValue()) {
+ var pos = el.tooltipPosition();
+ xSet.add(pos.x);
+ y += pos.y;
+ ++count;
+ }
+ }
+ if (count === 0 || xSet.size === 0) {
+ return false;
+ }
+ var xAverage = _toConsumableArray(xSet).reduce(function (a, b) {
+ return a + b;
+ }) / xSet.size;
+ return {
+ x: xAverage,
+ y: y / count
+ };
+ },
+ nearest: function nearest(items, eventPosition) {
+ if (!items.length) {
+ return false;
+ }
+ var x = eventPosition.x;
+ var y = eventPosition.y;
+ var minDistance = Number.POSITIVE_INFINITY;
+ var i, len, nearestElement;
+ for (i = 0, len = items.length; i < len; ++i) {
+ var el = items[i].element;
+ if (el && el.hasValue()) {
+ var center = el.getCenterPoint();
+ var d = distanceBetweenPoints(eventPosition, center);
+ if (d < minDistance) {
+ minDistance = d;
+ nearestElement = el;
+ }
+ }
+ }
+ if (nearestElement) {
+ var tp = nearestElement.tooltipPosition();
+ x = tp.x;
+ y = tp.y;
+ }
+ return {
+ x: x,
+ y: y
+ };
+ }
+ };
+ function pushOrConcat(base, toPush) {
+ if (toPush) {
+ if (isArray(toPush)) {
+ Array.prototype.push.apply(base, toPush);
+ } else {
+ base.push(toPush);
+ }
+ }
+ return base;
+ }
+ function splitNewlines(str) {
+ if ((typeof str === 'string' || str instanceof String) && str.indexOf('\n') > -1) {
+ return str.split('\n');
+ }
+ return str;
+ }
+ function createTooltipItem(chart, item) {
+ var element = item.element,
+ datasetIndex = item.datasetIndex,
+ index = item.index;
+ var controller = chart.getDatasetMeta(datasetIndex).controller;
+ var _controller$getLabelA = controller.getLabelAndValue(index),
+ label = _controller$getLabelA.label,
+ value = _controller$getLabelA.value;
+ return {
+ chart: chart,
+ label: label,
+ parsed: controller.getParsed(index),
+ raw: chart.data.datasets[datasetIndex].data[index],
+ formattedValue: value,
+ dataset: controller.getDataset(),
+ dataIndex: index,
+ datasetIndex: datasetIndex,
+ element: element
+ };
+ }
+ function getTooltipSize(tooltip, options) {
+ var ctx = tooltip.chart.ctx;
+ var body = tooltip.body,
+ footer = tooltip.footer,
+ title = tooltip.title;
+ var boxWidth = options.boxWidth,
+ boxHeight = options.boxHeight;
+ var bodyFont = toFont(options.bodyFont);
+ var titleFont = toFont(options.titleFont);
+ var footerFont = toFont(options.footerFont);
+ var titleLineCount = title.length;
+ var footerLineCount = footer.length;
+ var bodyLineItemCount = body.length;
+ var padding = toPadding(options.padding);
+ var height = padding.height;
+ var width = 0;
+ var combinedBodyLength = body.reduce(function (count, bodyItem) {
+ return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
+ }, 0);
+ combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length;
+ if (titleLineCount) {
+ height += titleLineCount * titleFont.lineHeight + (titleLineCount - 1) * options.titleSpacing + options.titleMarginBottom;
+ }
+ if (combinedBodyLength) {
+ var bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.lineHeight) : bodyFont.lineHeight;
+ height += bodyLineItemCount * bodyLineHeight + (combinedBodyLength - bodyLineItemCount) * bodyFont.lineHeight + (combinedBodyLength - 1) * options.bodySpacing;
+ }
+ if (footerLineCount) {
+ height += options.footerMarginTop + footerLineCount * footerFont.lineHeight + (footerLineCount - 1) * options.footerSpacing;
+ }
+ var widthPadding = 0;
+ var maxLineWidth = function maxLineWidth(line) {
+ width = Math.max(width, ctx.measureText(line).width + widthPadding);
+ };
+ ctx.save();
+ ctx.font = titleFont.string;
+ each(tooltip.title, maxLineWidth);
+ ctx.font = bodyFont.string;
+ each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth);
+ widthPadding = options.displayColors ? boxWidth + 2 + options.boxPadding : 0;
+ each(body, function (bodyItem) {
+ each(bodyItem.before, maxLineWidth);
+ each(bodyItem.lines, maxLineWidth);
+ each(bodyItem.after, maxLineWidth);
+ });
+ widthPadding = 0;
+ ctx.font = footerFont.string;
+ each(tooltip.footer, maxLineWidth);
+ ctx.restore();
+ width += padding.width;
+ return {
+ width: width,
+ height: height
+ };
+ }
+ function determineYAlign(chart, size) {
+ var y = size.y,
+ height = size.height;
+ if (y < height / 2) {
+ return 'top';
+ } else if (y > chart.height - height / 2) {
+ return 'bottom';
+ }
+ return 'center';
+ }
+ function doesNotFitWithAlign(xAlign, chart, options, size) {
+ var x = size.x,
+ width = size.width;
+ var caret = options.caretSize + options.caretPadding;
+ if (xAlign === 'left' && x + width + caret > chart.width) {
+ return true;
+ }
+ if (xAlign === 'right' && x - width - caret < 0) {
+ return true;
+ }
+ }
+ function determineXAlign(chart, options, size, yAlign) {
+ var x = size.x,
+ width = size.width;
+ var chartWidth = chart.width,
+ _chart$chartArea = chart.chartArea,
+ left = _chart$chartArea.left,
+ right = _chart$chartArea.right;
+ var xAlign = 'center';
+ if (yAlign === 'center') {
+ xAlign = x <= (left + right) / 2 ? 'left' : 'right';
+ } else if (x <= width / 2) {
+ xAlign = 'left';
+ } else if (x >= chartWidth - width / 2) {
+ xAlign = 'right';
+ }
+ if (doesNotFitWithAlign(xAlign, chart, options, size)) {
+ xAlign = 'center';
+ }
+ return xAlign;
+ }
+ function determineAlignment(chart, options, size) {
+ var yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size);
+ return {
+ xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign),
+ yAlign: yAlign
+ };
+ }
+ function alignX(size, xAlign) {
+ var x = size.x,
+ width = size.width;
+ if (xAlign === 'right') {
+ x -= width;
+ } else if (xAlign === 'center') {
+ x -= width / 2;
+ }
+ return x;
+ }
+ function alignY(size, yAlign, paddingAndSize) {
+ var y = size.y,
+ height = size.height;
+ if (yAlign === 'top') {
+ y += paddingAndSize;
+ } else if (yAlign === 'bottom') {
+ y -= height + paddingAndSize;
+ } else {
+ y -= height / 2;
+ }
+ return y;
+ }
+ function getBackgroundPoint(options, size, alignment, chart) {
+ var caretSize = options.caretSize,
+ caretPadding = options.caretPadding,
+ cornerRadius = options.cornerRadius;
+ var xAlign = alignment.xAlign,
+ yAlign = alignment.yAlign;
+ var paddingAndSize = caretSize + caretPadding;
+ var _toTRBLCorners = toTRBLCorners(cornerRadius),
+ topLeft = _toTRBLCorners.topLeft,
+ topRight = _toTRBLCorners.topRight,
+ bottomLeft = _toTRBLCorners.bottomLeft,
+ bottomRight = _toTRBLCorners.bottomRight;
+ var x = alignX(size, xAlign);
+ var y = alignY(size, yAlign, paddingAndSize);
+ if (yAlign === 'center') {
+ if (xAlign === 'left') {
+ x += paddingAndSize;
+ } else if (xAlign === 'right') {
+ x -= paddingAndSize;
+ }
+ } else if (xAlign === 'left') {
+ x -= Math.max(topLeft, bottomLeft) + caretSize;
+ } else if (xAlign === 'right') {
+ x += Math.max(topRight, bottomRight) + caretSize;
+ }
+ return {
+ x: _limitValue(x, 0, chart.width - size.width),
+ y: _limitValue(y, 0, chart.height - size.height)
+ };
+ }
+ function getAlignedX(tooltip, align, options) {
+ var padding = toPadding(options.padding);
+ return align === 'center' ? tooltip.x + tooltip.width / 2 : align === 'right' ? tooltip.x + tooltip.width - padding.right : tooltip.x + padding.left;
+ }
+ function getBeforeAfterBodyLines(callback) {
+ return pushOrConcat([], splitNewlines(callback));
+ }
+ function createTooltipContext(parent, tooltip, tooltipItems) {
+ return createContext(parent, {
+ tooltip: tooltip,
+ tooltipItems: tooltipItems,
+ type: 'tooltip'
+ });
+ }
+ function overrideCallbacks(callbacks, context) {
+ var override = context && context.dataset && context.dataset.tooltip && context.dataset.tooltip.callbacks;
+ return override ? callbacks.override(override) : callbacks;
+ }
+ var defaultCallbacks = {
+ beforeTitle: noop,
+ title: function title(tooltipItems) {
+ if (tooltipItems.length > 0) {
+ var item = tooltipItems[0];
+ var labels = item.chart.data.labels;
+ var labelCount = labels ? labels.length : 0;
+ if (this && this.options && this.options.mode === 'dataset') {
+ return item.dataset.label || '';
+ } else if (item.label) {
+ return item.label;
+ } else if (labelCount > 0 && item.dataIndex < labelCount) {
+ return labels[item.dataIndex];
+ }
+ }
+ return '';
+ },
+ afterTitle: noop,
+ beforeBody: noop,
+ beforeLabel: noop,
+ label: function label(tooltipItem) {
+ if (this && this.options && this.options.mode === 'dataset') {
+ return tooltipItem.label + ': ' + tooltipItem.formattedValue || tooltipItem.formattedValue;
+ }
+ var label = tooltipItem.dataset.label || '';
+ if (label) {
+ label += ': ';
+ }
+ var value = tooltipItem.formattedValue;
+ if (!isNullOrUndef(value)) {
+ label += value;
+ }
+ return label;
+ },
+ labelColor: function labelColor(tooltipItem) {
+ var meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);
+ var options = meta.controller.getStyle(tooltipItem.dataIndex);
+ return {
+ borderColor: options.borderColor,
+ backgroundColor: options.backgroundColor,
+ borderWidth: options.borderWidth,
+ borderDash: options.borderDash,
+ borderDashOffset: options.borderDashOffset,
+ borderRadius: 0
+ };
+ },
+ labelTextColor: function labelTextColor() {
+ return this.options.bodyColor;
+ },
+ labelPointStyle: function labelPointStyle(tooltipItem) {
+ var meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);
+ var options = meta.controller.getStyle(tooltipItem.dataIndex);
+ return {
+ pointStyle: options.pointStyle,
+ rotation: options.rotation
+ };
+ },
+ afterLabel: noop,
+ afterBody: noop,
+ beforeFooter: noop,
+ footer: noop,
+ afterFooter: noop
+ };
+ function invokeCallbackWithFallback(callbacks, name, ctx, arg) {
+ var result = callbacks[name].call(ctx, arg);
+ if (typeof result === 'undefined') {
+ return defaultCallbacks[name].call(ctx, arg);
+ }
+ return result;
+ }
+ var Tooltip = /*#__PURE__*/function (_Element9) {
+ function Tooltip(config) {
+ var _this31;
+ _classCallCheck$1(this, Tooltip);
+ _this31 = _callSuper(this, Tooltip);
+ _this31.opacity = 0;
+ _this31._active = [];
+ _this31._eventPosition = undefined;
+ _this31._size = undefined;
+ _this31._cachedAnimations = undefined;
+ _this31._tooltipItems = [];
+ _this31.$animations = undefined;
+ _this31.$context = undefined;
+ _this31.chart = config.chart;
+ _this31.options = config.options;
+ _this31.dataPoints = undefined;
+ _this31.title = undefined;
+ _this31.beforeBody = undefined;
+ _this31.body = undefined;
+ _this31.afterBody = undefined;
+ _this31.footer = undefined;
+ _this31.xAlign = undefined;
+ _this31.yAlign = undefined;
+ _this31.x = undefined;
+ _this31.y = undefined;
+ _this31.height = undefined;
+ _this31.width = undefined;
+ _this31.caretX = undefined;
+ _this31.caretY = undefined;
+ _this31.labelColors = undefined;
+ _this31.labelPointStyles = undefined;
+ _this31.labelTextColors = undefined;
+ return _this31;
+ }
+ _inherits$1(Tooltip, _Element9);
+ return _createClass$1(Tooltip, [{
+ key: "initialize",
+ value: function initialize(options) {
+ this.options = options;
+ this._cachedAnimations = undefined;
+ this.$context = undefined;
+ }
+ }, {
+ key: "_resolveAnimations",
+ value: function _resolveAnimations() {
+ var cached = this._cachedAnimations;
+ if (cached) {
+ return cached;
+ }
+ var chart = this.chart;
+ var options = this.options.setContext(this.getContext());
+ var opts = options.enabled && chart.options.animation && options.animations;
+ var animations = new Animations(this.chart, opts);
+ if (opts._cacheable) {
+ this._cachedAnimations = Object.freeze(animations);
+ }
+ return animations;
+ }
+ }, {
+ key: "getContext",
+ value: function getContext() {
+ return this.$context || (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems));
+ }
+ }, {
+ key: "getTitle",
+ value: function getTitle(context, options) {
+ var callbacks = options.callbacks;
+ var beforeTitle = invokeCallbackWithFallback(callbacks, 'beforeTitle', this, context);
+ var title = invokeCallbackWithFallback(callbacks, 'title', this, context);
+ var afterTitle = invokeCallbackWithFallback(callbacks, 'afterTitle', this, context);
+ var lines = [];
+ lines = pushOrConcat(lines, splitNewlines(beforeTitle));
+ lines = pushOrConcat(lines, splitNewlines(title));
+ lines = pushOrConcat(lines, splitNewlines(afterTitle));
+ return lines;
+ }
+ }, {
+ key: "getBeforeBody",
+ value: function getBeforeBody(tooltipItems, options) {
+ return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, 'beforeBody', this, tooltipItems));
+ }
+ }, {
+ key: "getBody",
+ value: function getBody(tooltipItems, options) {
+ var _this32 = this;
+ var callbacks = options.callbacks;
+ var bodyItems = [];
+ each(tooltipItems, function (context) {
+ var bodyItem = {
+ before: [],
+ lines: [],
+ after: []
+ };
+ var scoped = overrideCallbacks(callbacks, context);
+ pushOrConcat(bodyItem.before, splitNewlines(invokeCallbackWithFallback(scoped, 'beforeLabel', _this32, context)));
+ pushOrConcat(bodyItem.lines, invokeCallbackWithFallback(scoped, 'label', _this32, context));
+ pushOrConcat(bodyItem.after, splitNewlines(invokeCallbackWithFallback(scoped, 'afterLabel', _this32, context)));
+ bodyItems.push(bodyItem);
+ });
+ return bodyItems;
+ }
+ }, {
+ key: "getAfterBody",
+ value: function getAfterBody(tooltipItems, options) {
+ return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, 'afterBody', this, tooltipItems));
+ }
+ }, {
+ key: "getFooter",
+ value: function getFooter(tooltipItems, options) {
+ var callbacks = options.callbacks;
+ var beforeFooter = invokeCallbackWithFallback(callbacks, 'beforeFooter', this, tooltipItems);
+ var footer = invokeCallbackWithFallback(callbacks, 'footer', this, tooltipItems);
+ var afterFooter = invokeCallbackWithFallback(callbacks, 'afterFooter', this, tooltipItems);
+ var lines = [];
+ lines = pushOrConcat(lines, splitNewlines(beforeFooter));
+ lines = pushOrConcat(lines, splitNewlines(footer));
+ lines = pushOrConcat(lines, splitNewlines(afterFooter));
+ return lines;
+ }
+ }, {
+ key: "_createItems",
+ value: function _createItems(options) {
+ var _this33 = this;
+ var active = this._active;
+ var data = this.chart.data;
+ var labelColors = [];
+ var labelPointStyles = [];
+ var labelTextColors = [];
+ var tooltipItems = [];
+ var i, len;
+ for (i = 0, len = active.length; i < len; ++i) {
+ tooltipItems.push(createTooltipItem(this.chart, active[i]));
+ }
+ if (options.filter) {
+ tooltipItems = tooltipItems.filter(function (element, index, array) {
+ return options.filter(element, index, array, data);
+ });
+ }
+ if (options.itemSort) {
+ tooltipItems = tooltipItems.sort(function (a, b) {
+ return options.itemSort(a, b, data);
+ });
+ }
+ each(tooltipItems, function (context) {
+ var scoped = overrideCallbacks(options.callbacks, context);
+ labelColors.push(invokeCallbackWithFallback(scoped, 'labelColor', _this33, context));
+ labelPointStyles.push(invokeCallbackWithFallback(scoped, 'labelPointStyle', _this33, context));
+ labelTextColors.push(invokeCallbackWithFallback(scoped, 'labelTextColor', _this33, context));
+ });
+ this.labelColors = labelColors;
+ this.labelPointStyles = labelPointStyles;
+ this.labelTextColors = labelTextColors;
+ this.dataPoints = tooltipItems;
+ return tooltipItems;
+ }
+ }, {
+ key: "update",
+ value: function update(changed, replay) {
+ var options = this.options.setContext(this.getContext());
+ var active = this._active;
+ var properties;
+ var tooltipItems = [];
+ if (!active.length) {
+ if (this.opacity !== 0) {
+ properties = {
+ opacity: 0
+ };
+ }
+ } else {
+ var position = positioners[options.position].call(this, active, this._eventPosition);
+ tooltipItems = this._createItems(options);
+ this.title = this.getTitle(tooltipItems, options);
+ this.beforeBody = this.getBeforeBody(tooltipItems, options);
+ this.body = this.getBody(tooltipItems, options);
+ this.afterBody = this.getAfterBody(tooltipItems, options);
+ this.footer = this.getFooter(tooltipItems, options);
+ var size = this._size = getTooltipSize(this, options);
+ var positionAndSize = Object.assign({}, position, size);
+ var alignment = determineAlignment(this.chart, options, positionAndSize);
+ var backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart);
+ this.xAlign = alignment.xAlign;
+ this.yAlign = alignment.yAlign;
+ properties = {
+ opacity: 1,
+ x: backgroundPoint.x,
+ y: backgroundPoint.y,
+ width: size.width,
+ height: size.height,
+ caretX: position.x,
+ caretY: position.y
+ };
+ }
+ this._tooltipItems = tooltipItems;
+ this.$context = undefined;
+ if (properties) {
+ this._resolveAnimations().update(this, properties);
+ }
+ if (changed && options.external) {
+ options.external.call(this, {
+ chart: this.chart,
+ tooltip: this,
+ replay: replay
+ });
+ }
+ }
+ }, {
+ key: "drawCaret",
+ value: function drawCaret(tooltipPoint, ctx, size, options) {
+ var caretPosition = this.getCaretPosition(tooltipPoint, size, options);
+ ctx.lineTo(caretPosition.x1, caretPosition.y1);
+ ctx.lineTo(caretPosition.x2, caretPosition.y2);
+ ctx.lineTo(caretPosition.x3, caretPosition.y3);
+ }
+ }, {
+ key: "getCaretPosition",
+ value: function getCaretPosition(tooltipPoint, size, options) {
+ var xAlign = this.xAlign,
+ yAlign = this.yAlign;
+ var caretSize = options.caretSize,
+ cornerRadius = options.cornerRadius;
+ var _toTRBLCorners2 = toTRBLCorners(cornerRadius),
+ topLeft = _toTRBLCorners2.topLeft,
+ topRight = _toTRBLCorners2.topRight,
+ bottomLeft = _toTRBLCorners2.bottomLeft,
+ bottomRight = _toTRBLCorners2.bottomRight;
+ var ptX = tooltipPoint.x,
+ ptY = tooltipPoint.y;
+ var width = size.width,
+ height = size.height;
+ var x1, x2, x3, y1, y2, y3;
+ if (yAlign === 'center') {
+ y2 = ptY + height / 2;
+ if (xAlign === 'left') {
+ x1 = ptX;
+ x2 = x1 - caretSize;
+ y1 = y2 + caretSize;
+ y3 = y2 - caretSize;
+ } else {
+ x1 = ptX + width;
+ x2 = x1 + caretSize;
+ y1 = y2 - caretSize;
+ y3 = y2 + caretSize;
+ }
+ x3 = x1;
+ } else {
+ if (xAlign === 'left') {
+ x2 = ptX + Math.max(topLeft, bottomLeft) + caretSize;
+ } else if (xAlign === 'right') {
+ x2 = ptX + width - Math.max(topRight, bottomRight) - caretSize;
+ } else {
+ x2 = this.caretX;
+ }
+ if (yAlign === 'top') {
+ y1 = ptY;
+ y2 = y1 - caretSize;
+ x1 = x2 - caretSize;
+ x3 = x2 + caretSize;
+ } else {
+ y1 = ptY + height;
+ y2 = y1 + caretSize;
+ x1 = x2 + caretSize;
+ x3 = x2 - caretSize;
+ }
+ y3 = y1;
+ }
+ return {
+ x1: x1,
+ x2: x2,
+ x3: x3,
+ y1: y1,
+ y2: y2,
+ y3: y3
+ };
+ }
+ }, {
+ key: "drawTitle",
+ value: function drawTitle(pt, ctx, options) {
+ var title = this.title;
+ var length = title.length;
+ var titleFont, titleSpacing, i;
+ if (length) {
+ var rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
+ pt.x = getAlignedX(this, options.titleAlign, options);
+ ctx.textAlign = rtlHelper.textAlign(options.titleAlign);
+ ctx.textBaseline = 'middle';
+ titleFont = toFont(options.titleFont);
+ titleSpacing = options.titleSpacing;
+ ctx.fillStyle = options.titleColor;
+ ctx.font = titleFont.string;
+ for (i = 0; i < length; ++i) {
+ ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFont.lineHeight / 2);
+ pt.y += titleFont.lineHeight + titleSpacing;
+ if (i + 1 === length) {
+ pt.y += options.titleMarginBottom - titleSpacing;
+ }
+ }
+ }
+ }
+ }, {
+ key: "_drawColorBox",
+ value: function _drawColorBox(ctx, pt, i, rtlHelper, options) {
+ var labelColor = this.labelColors[i];
+ var labelPointStyle = this.labelPointStyles[i];
+ var boxHeight = options.boxHeight,
+ boxWidth = options.boxWidth;
+ var bodyFont = toFont(options.bodyFont);
+ var colorX = getAlignedX(this, 'left', options);
+ var rtlColorX = rtlHelper.x(colorX);
+ var yOffSet = boxHeight < bodyFont.lineHeight ? (bodyFont.lineHeight - boxHeight) / 2 : 0;
+ var colorY = pt.y + yOffSet;
+ if (options.usePointStyle) {
+ var drawOptions = {
+ radius: Math.min(boxWidth, boxHeight) / 2,
+ pointStyle: labelPointStyle.pointStyle,
+ rotation: labelPointStyle.rotation,
+ borderWidth: 1
+ };
+ var centerX = rtlHelper.leftForLtr(rtlColorX, boxWidth) + boxWidth / 2;
+ var centerY = colorY + boxHeight / 2;
+ ctx.strokeStyle = options.multiKeyBackground;
+ ctx.fillStyle = options.multiKeyBackground;
+ drawPoint(ctx, drawOptions, centerX, centerY);
+ ctx.strokeStyle = labelColor.borderColor;
+ ctx.fillStyle = labelColor.backgroundColor;
+ drawPoint(ctx, drawOptions, centerX, centerY);
+ } else {
+ ctx.lineWidth = isObject(labelColor.borderWidth) ? Math.max.apply(Math, _toConsumableArray(Object.values(labelColor.borderWidth))) : labelColor.borderWidth || 1;
+ ctx.strokeStyle = labelColor.borderColor;
+ ctx.setLineDash(labelColor.borderDash || []);
+ ctx.lineDashOffset = labelColor.borderDashOffset || 0;
+ var outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth);
+ var innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - 2);
+ var borderRadius = toTRBLCorners(labelColor.borderRadius);
+ if (Object.values(borderRadius).some(function (v) {
+ return v !== 0;
+ })) {
+ ctx.beginPath();
+ ctx.fillStyle = options.multiKeyBackground;
+ addRoundedRectPath(ctx, {
+ x: outerX,
+ y: colorY,
+ w: boxWidth,
+ h: boxHeight,
+ radius: borderRadius
+ });
+ ctx.fill();
+ ctx.stroke();
+ ctx.fillStyle = labelColor.backgroundColor;
+ ctx.beginPath();
+ addRoundedRectPath(ctx, {
+ x: innerX,
+ y: colorY + 1,
+ w: boxWidth - 2,
+ h: boxHeight - 2,
+ radius: borderRadius
+ });
+ ctx.fill();
+ } else {
+ ctx.fillStyle = options.multiKeyBackground;
+ ctx.fillRect(outerX, colorY, boxWidth, boxHeight);
+ ctx.strokeRect(outerX, colorY, boxWidth, boxHeight);
+ ctx.fillStyle = labelColor.backgroundColor;
+ ctx.fillRect(innerX, colorY + 1, boxWidth - 2, boxHeight - 2);
+ }
+ }
+ ctx.fillStyle = this.labelTextColors[i];
+ }
+ }, {
+ key: "drawBody",
+ value: function drawBody(pt, ctx, options) {
+ var body = this.body;
+ var bodySpacing = options.bodySpacing,
+ bodyAlign = options.bodyAlign,
+ displayColors = options.displayColors,
+ boxHeight = options.boxHeight,
+ boxWidth = options.boxWidth,
+ boxPadding = options.boxPadding;
+ var bodyFont = toFont(options.bodyFont);
+ var bodyLineHeight = bodyFont.lineHeight;
+ var xLinePadding = 0;
+ var rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
+ var fillLineOfText = function fillLineOfText(line) {
+ ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyLineHeight / 2);
+ pt.y += bodyLineHeight + bodySpacing;
+ };
+ var bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign);
+ var bodyItem, textColor, lines, i, j, ilen, jlen;
+ ctx.textAlign = bodyAlign;
+ ctx.textBaseline = 'middle';
+ ctx.font = bodyFont.string;
+ pt.x = getAlignedX(this, bodyAlignForCalculation, options);
+ ctx.fillStyle = options.bodyColor;
+ each(this.beforeBody, fillLineOfText);
+ xLinePadding = displayColors && bodyAlignForCalculation !== 'right' ? bodyAlign === 'center' ? boxWidth / 2 + boxPadding : boxWidth + 2 + boxPadding : 0;
+ for (i = 0, ilen = body.length; i < ilen; ++i) {
+ bodyItem = body[i];
+ textColor = this.labelTextColors[i];
+ ctx.fillStyle = textColor;
+ each(bodyItem.before, fillLineOfText);
+ lines = bodyItem.lines;
+ if (displayColors && lines.length) {
+ this._drawColorBox(ctx, pt, i, rtlHelper, options);
+ bodyLineHeight = Math.max(bodyFont.lineHeight, boxHeight);
+ }
+ for (j = 0, jlen = lines.length; j < jlen; ++j) {
+ fillLineOfText(lines[j]);
+ bodyLineHeight = bodyFont.lineHeight;
+ }
+ each(bodyItem.after, fillLineOfText);
+ }
+ xLinePadding = 0;
+ bodyLineHeight = bodyFont.lineHeight;
+ each(this.afterBody, fillLineOfText);
+ pt.y -= bodySpacing;
+ }
+ }, {
+ key: "drawFooter",
+ value: function drawFooter(pt, ctx, options) {
+ var footer = this.footer;
+ var length = footer.length;
+ var footerFont, i;
+ if (length) {
+ var rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
+ pt.x = getAlignedX(this, options.footerAlign, options);
+ pt.y += options.footerMarginTop;
+ ctx.textAlign = rtlHelper.textAlign(options.footerAlign);
+ ctx.textBaseline = 'middle';
+ footerFont = toFont(options.footerFont);
+ ctx.fillStyle = options.footerColor;
+ ctx.font = footerFont.string;
+ for (i = 0; i < length; ++i) {
+ ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFont.lineHeight / 2);
+ pt.y += footerFont.lineHeight + options.footerSpacing;
+ }
+ }
+ }
+ }, {
+ key: "drawBackground",
+ value: function drawBackground(pt, ctx, tooltipSize, options) {
+ var xAlign = this.xAlign,
+ yAlign = this.yAlign;
+ var x = pt.x,
+ y = pt.y;
+ var width = tooltipSize.width,
+ height = tooltipSize.height;
+ var _toTRBLCorners3 = toTRBLCorners(options.cornerRadius),
+ topLeft = _toTRBLCorners3.topLeft,
+ topRight = _toTRBLCorners3.topRight,
+ bottomLeft = _toTRBLCorners3.bottomLeft,
+ bottomRight = _toTRBLCorners3.bottomRight;
+ ctx.fillStyle = options.backgroundColor;
+ ctx.strokeStyle = options.borderColor;
+ ctx.lineWidth = options.borderWidth;
+ ctx.beginPath();
+ ctx.moveTo(x + topLeft, y);
+ if (yAlign === 'top') {
+ this.drawCaret(pt, ctx, tooltipSize, options);
+ }
+ ctx.lineTo(x + width - topRight, y);
+ ctx.quadraticCurveTo(x + width, y, x + width, y + topRight);
+ if (yAlign === 'center' && xAlign === 'right') {
+ this.drawCaret(pt, ctx, tooltipSize, options);
+ }
+ ctx.lineTo(x + width, y + height - bottomRight);
+ ctx.quadraticCurveTo(x + width, y + height, x + width - bottomRight, y + height);
+ if (yAlign === 'bottom') {
+ this.drawCaret(pt, ctx, tooltipSize, options);
+ }
+ ctx.lineTo(x + bottomLeft, y + height);
+ ctx.quadraticCurveTo(x, y + height, x, y + height - bottomLeft);
+ if (yAlign === 'center' && xAlign === 'left') {
+ this.drawCaret(pt, ctx, tooltipSize, options);
+ }
+ ctx.lineTo(x, y + topLeft);
+ ctx.quadraticCurveTo(x, y, x + topLeft, y);
+ ctx.closePath();
+ ctx.fill();
+ if (options.borderWidth > 0) {
+ ctx.stroke();
+ }
+ }
+ }, {
+ key: "_updateAnimationTarget",
+ value: function _updateAnimationTarget(options) {
+ var chart = this.chart;
+ var anims = this.$animations;
+ var animX = anims && anims.x;
+ var animY = anims && anims.y;
+ if (animX || animY) {
+ var position = positioners[options.position].call(this, this._active, this._eventPosition);
+ if (!position) {
+ return;
+ }
+ var size = this._size = getTooltipSize(this, options);
+ var positionAndSize = Object.assign({}, position, this._size);
+ var alignment = determineAlignment(chart, options, positionAndSize);
+ var point = getBackgroundPoint(options, positionAndSize, alignment, chart);
+ if (animX._to !== point.x || animY._to !== point.y) {
+ this.xAlign = alignment.xAlign;
+ this.yAlign = alignment.yAlign;
+ this.width = size.width;
+ this.height = size.height;
+ this.caretX = position.x;
+ this.caretY = position.y;
+ this._resolveAnimations().update(this, point);
+ }
+ }
+ }
+ }, {
+ key: "_willRender",
+ value: function _willRender() {
+ return !!this.opacity;
+ }
+ }, {
+ key: "draw",
+ value: function draw(ctx) {
+ var options = this.options.setContext(this.getContext());
+ var opacity = this.opacity;
+ if (!opacity) {
+ return;
+ }
+ this._updateAnimationTarget(options);
+ var tooltipSize = {
+ width: this.width,
+ height: this.height
+ };
+ var pt = {
+ x: this.x,
+ y: this.y
+ };
+ opacity = Math.abs(opacity) < 1e-3 ? 0 : opacity;
+ var padding = toPadding(options.padding);
+ var hasTooltipContent = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length;
+ if (options.enabled && hasTooltipContent) {
+ ctx.save();
+ ctx.globalAlpha = opacity;
+ this.drawBackground(pt, ctx, tooltipSize, options);
+ overrideTextDirection(ctx, options.textDirection);
+ pt.y += padding.top;
+ this.drawTitle(pt, ctx, options);
+ this.drawBody(pt, ctx, options);
+ this.drawFooter(pt, ctx, options);
+ restoreTextDirection(ctx, options.textDirection);
+ ctx.restore();
+ }
+ }
+ }, {
+ key: "getActiveElements",
+ value: function getActiveElements() {
+ return this._active || [];
+ }
+ }, {
+ key: "setActiveElements",
+ value: function setActiveElements(activeElements, eventPosition) {
+ var _this34 = this;
+ var lastActive = this._active;
+ var active = activeElements.map(function (_ref11) {
+ var datasetIndex = _ref11.datasetIndex,
+ index = _ref11.index;
+ var meta = _this34.chart.getDatasetMeta(datasetIndex);
+ if (!meta) {
+ throw new Error('Cannot find a dataset at index ' + datasetIndex);
+ }
+ return {
+ datasetIndex: datasetIndex,
+ element: meta.data[index],
+ index: index
+ };
+ });
+ var changed = !_elementsEqual(lastActive, active);
+ var positionChanged = this._positionChanged(active, eventPosition);
+ if (changed || positionChanged) {
+ this._active = active;
+ this._eventPosition = eventPosition;
+ this._ignoreReplayEvents = true;
+ this.update(true);
+ }
+ }
+ }, {
+ key: "handleEvent",
+ value: function handleEvent(e, replay) {
+ var inChartArea = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
+ if (replay && this._ignoreReplayEvents) {
+ return false;
+ }
+ this._ignoreReplayEvents = false;
+ var options = this.options;
+ var lastActive = this._active || [];
+ var active = this._getActiveElements(e, lastActive, replay, inChartArea);
+ var positionChanged = this._positionChanged(active, e);
+ var changed = replay || !_elementsEqual(active, lastActive) || positionChanged;
+ if (changed) {
+ this._active = active;
+ if (options.enabled || options.external) {
+ this._eventPosition = {
+ x: e.x,
+ y: e.y
+ };
+ this.update(true, replay);
+ }
+ }
+ return changed;
+ }
+ }, {
+ key: "_getActiveElements",
+ value: function _getActiveElements(e, lastActive, replay, inChartArea) {
+ var _this35 = this;
+ var options = this.options;
+ if (e.type === 'mouseout') {
+ return [];
+ }
+ if (!inChartArea) {
+ return lastActive.filter(function (i) {
+ return _this35.chart.data.datasets[i.datasetIndex] && _this35.chart.getDatasetMeta(i.datasetIndex).controller.getParsed(i.index) !== undefined;
+ });
+ }
+ var active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay);
+ if (options.reverse) {
+ active.reverse();
+ }
+ return active;
+ }
+ }, {
+ key: "_positionChanged",
+ value: function _positionChanged(active, e) {
+ var caretX = this.caretX,
+ caretY = this.caretY,
+ options = this.options;
+ var position = positioners[options.position].call(this, active, e);
+ return position !== false && (caretX !== position.x || caretY !== position.y);
+ }
+ }]);
+ }(Element);
+ _defineProperty$1(Tooltip, "positioners", positioners);
+ var plugin_tooltip = {
+ id: 'tooltip',
+ _element: Tooltip,
+ positioners: positioners,
+ afterInit: function afterInit(chart, _args, options) {
+ if (options) {
+ chart.tooltip = new Tooltip({
+ chart: chart,
+ options: options
+ });
+ }
+ },
+ beforeUpdate: function beforeUpdate(chart, _args, options) {
+ if (chart.tooltip) {
+ chart.tooltip.initialize(options);
+ }
+ },
+ reset: function reset(chart, _args, options) {
+ if (chart.tooltip) {
+ chart.tooltip.initialize(options);
+ }
+ },
+ afterDraw: function afterDraw(chart) {
+ var tooltip = chart.tooltip;
+ if (tooltip && tooltip._willRender()) {
+ var args = {
+ tooltip: tooltip
+ };
+ if (chart.notifyPlugins('beforeTooltipDraw', _objectSpread2(_objectSpread2({}, args), {}, {
+ cancelable: true
+ })) === false) {
+ return;
+ }
+ tooltip.draw(chart.ctx);
+ chart.notifyPlugins('afterTooltipDraw', args);
+ }
+ },
+ afterEvent: function afterEvent(chart, args) {
+ if (chart.tooltip) {
+ var useFinalPosition = args.replay;
+ if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) {
+ args.changed = true;
+ }
+ }
+ },
+ defaults: {
+ enabled: true,
+ external: null,
+ position: 'average',
+ backgroundColor: 'rgba(0,0,0,0.8)',
+ titleColor: '#fff',
+ titleFont: {
+ weight: 'bold'
+ },
+ titleSpacing: 2,
+ titleMarginBottom: 6,
+ titleAlign: 'left',
+ bodyColor: '#fff',
+ bodySpacing: 2,
+ bodyFont: {},
+ bodyAlign: 'left',
+ footerColor: '#fff',
+ footerSpacing: 2,
+ footerMarginTop: 6,
+ footerFont: {
+ weight: 'bold'
+ },
+ footerAlign: 'left',
+ padding: 6,
+ caretPadding: 2,
+ caretSize: 5,
+ cornerRadius: 6,
+ boxHeight: function boxHeight(ctx, opts) {
+ return opts.bodyFont.size;
+ },
+ boxWidth: function boxWidth(ctx, opts) {
+ return opts.bodyFont.size;
+ },
+ multiKeyBackground: '#fff',
+ displayColors: true,
+ boxPadding: 0,
+ borderColor: 'rgba(0,0,0,0)',
+ borderWidth: 0,
+ animation: {
+ duration: 400,
+ easing: 'easeOutQuart'
+ },
+ animations: {
+ numbers: {
+ type: 'number',
+ properties: ['x', 'y', 'width', 'height', 'caretX', 'caretY']
+ },
+ opacity: {
+ easing: 'linear',
+ duration: 200
+ }
+ },
+ callbacks: defaultCallbacks
+ },
+ defaultRoutes: {
+ bodyFont: 'font',
+ footerFont: 'font',
+ titleFont: 'font'
+ },
+ descriptors: {
+ _scriptable: function _scriptable(name) {
+ return name !== 'filter' && name !== 'itemSort' && name !== 'external';
+ },
+ _indexable: false,
+ callbacks: {
+ _scriptable: false,
+ _indexable: false
+ },
+ animation: {
+ _fallback: false
+ },
+ animations: {
+ _fallback: 'animation'
+ }
+ },
+ additionalOptionScopes: ['interaction']
+ };
+ var plugins = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ Colors: plugin_colors,
+ Decimation: plugin_decimation,
+ Filler: index,
+ Legend: plugin_legend,
+ SubTitle: plugin_subtitle,
+ Title: plugin_title,
+ Tooltip: plugin_tooltip
+ });
+ var addIfString = function addIfString(labels, raw, index, addedLabels) {
+ if (typeof raw === 'string') {
+ index = labels.push(raw) - 1;
+ addedLabels.unshift({
+ index: index,
+ label: raw
+ });
+ } else if (isNaN(raw)) {
+ index = null;
+ }
+ return index;
+ };
+ function findOrAddLabel(labels, raw, index, addedLabels) {
+ var first = labels.indexOf(raw);
+ if (first === -1) {
+ return addIfString(labels, raw, index, addedLabels);
+ }
+ var last = labels.lastIndexOf(raw);
+ return first !== last ? index : first;
+ }
+ var validIndex = function validIndex(index, max) {
+ return index === null ? null : _limitValue(Math.round(index), 0, max);
+ };
+ function _getLabelForValue(value) {
+ var labels = this.getLabels();
+ if (value >= 0 && value < labels.length) {
+ return labels[value];
+ }
+ return value;
+ }
+ var CategoryScale = /*#__PURE__*/function (_Scale) {
+ function CategoryScale(cfg) {
+ var _this36;
+ _classCallCheck$1(this, CategoryScale);
+ _this36 = _callSuper(this, CategoryScale, [cfg]);
+ _this36._startValue = undefined;
+ _this36._valueRange = 0;
+ _this36._addedLabels = [];
+ return _this36;
+ }
+ _inherits$1(CategoryScale, _Scale);
+ return _createClass$1(CategoryScale, [{
+ key: "init",
+ value: function init(scaleOptions) {
+ var added = this._addedLabels;
+ if (added.length) {
+ var labels = this.getLabels();
+ var _iterator25 = _createForOfIteratorHelper$1(added),
+ _step25;
+ try {
+ for (_iterator25.s(); !(_step25 = _iterator25.n()).done;) {
+ var _step25$value = _step25.value,
+ _index3 = _step25$value.index,
+ label = _step25$value.label;
+ if (labels[_index3] === label) {
+ labels.splice(_index3, 1);
+ }
+ }
+ } catch (err) {
+ _iterator25.e(err);
+ } finally {
+ _iterator25.f();
+ }
+ this._addedLabels = [];
+ }
+ _superPropGet(CategoryScale, "init", this, 3)([scaleOptions]);
+ }
+ }, {
+ key: "parse",
+ value: function parse(raw, index) {
+ if (isNullOrUndef(raw)) {
+ return null;
+ }
+ var labels = this.getLabels();
+ index = isFinite(index) && labels[index] === raw ? index : findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels);
+ return validIndex(index, labels.length - 1);
+ }
+ }, {
+ key: "determineDataLimits",
+ value: function determineDataLimits() {
+ var _this$getUserBounds2 = this.getUserBounds(),
+ minDefined = _this$getUserBounds2.minDefined,
+ maxDefined = _this$getUserBounds2.maxDefined;
+ var _this$getMinMax = this.getMinMax(true),
+ min = _this$getMinMax.min,
+ max = _this$getMinMax.max;
+ if (this.options.bounds === 'ticks') {
+ if (!minDefined) {
+ min = 0;
+ }
+ if (!maxDefined) {
+ max = this.getLabels().length - 1;
+ }
+ }
+ this.min = min;
+ this.max = max;
+ }
+ }, {
+ key: "buildTicks",
+ value: function buildTicks() {
+ var min = this.min;
+ var max = this.max;
+ var offset = this.options.offset;
+ var ticks = [];
+ var labels = this.getLabels();
+ labels = min === 0 && max === labels.length - 1 ? labels : labels.slice(min, max + 1);
+ this._valueRange = Math.max(labels.length - (offset ? 0 : 1), 1);
+ this._startValue = this.min - (offset ? 0.5 : 0);
+ for (var value = min; value <= max; value++) {
+ ticks.push({
+ value: value
+ });
+ }
+ return ticks;
+ }
+ }, {
+ key: "getLabelForValue",
+ value: function getLabelForValue(value) {
+ return _getLabelForValue.call(this, value);
+ }
+ }, {
+ key: "configure",
+ value: function configure() {
+ _superPropGet(CategoryScale, "configure", this, 3)([]);
+ if (!this.isHorizontal()) {
+ this._reversePixels = !this._reversePixels;
+ }
+ }
+ }, {
+ key: "getPixelForValue",
+ value: function getPixelForValue(value) {
+ if (typeof value !== 'number') {
+ value = this.parse(value);
+ }
+ return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);
+ }
+ }, {
+ key: "getPixelForTick",
+ value: function getPixelForTick(index) {
+ var ticks = this.ticks;
+ if (index < 0 || index > ticks.length - 1) {
+ return null;
+ }
+ return this.getPixelForValue(ticks[index].value);
+ }
+ }, {
+ key: "getValueForPixel",
+ value: function getValueForPixel(pixel) {
+ return Math.round(this._startValue + this.getDecimalForPixel(pixel) * this._valueRange);
+ }
+ }, {
+ key: "getBasePixel",
+ value: function getBasePixel() {
+ return this.bottom;
+ }
+ }]);
+ }(Scale);
+ _defineProperty$1(CategoryScale, "id", 'category');
+ _defineProperty$1(CategoryScale, "defaults", {
+ ticks: {
+ callback: _getLabelForValue
+ }
+ });
+ function generateTicks$1(generationOptions, dataRange) {
+ var ticks = [];
+ var MIN_SPACING = 1e-14;
+ var bounds = generationOptions.bounds,
+ step = generationOptions.step,
+ min = generationOptions.min,
+ max = generationOptions.max,
+ precision = generationOptions.precision,
+ count = generationOptions.count,
+ maxTicks = generationOptions.maxTicks,
+ maxDigits = generationOptions.maxDigits,
+ includeBounds = generationOptions.includeBounds;
+ var unit = step || 1;
+ var maxSpaces = maxTicks - 1;
+ var rmin = dataRange.min,
+ rmax = dataRange.max;
+ var minDefined = !isNullOrUndef(min);
+ var maxDefined = !isNullOrUndef(max);
+ var countDefined = !isNullOrUndef(count);
+ var minSpacing = (rmax - rmin) / (maxDigits + 1);
+ var spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit;
+ var factor, niceMin, niceMax, numSpaces;
+ if (spacing < MIN_SPACING && !minDefined && !maxDefined) {
+ return [{
+ value: rmin
+ }, {
+ value: rmax
+ }];
+ }
+ numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing);
+ if (numSpaces > maxSpaces) {
+ spacing = niceNum(numSpaces * spacing / maxSpaces / unit) * unit;
+ }
+ if (!isNullOrUndef(precision)) {
+ factor = Math.pow(10, precision);
+ spacing = Math.ceil(spacing * factor) / factor;
+ }
+ if (bounds === 'ticks') {
+ niceMin = Math.floor(rmin / spacing) * spacing;
+ niceMax = Math.ceil(rmax / spacing) * spacing;
+ } else {
+ niceMin = rmin;
+ niceMax = rmax;
+ }
+ if (minDefined && maxDefined && step && almostWhole((max - min) / step, spacing / 1000)) {
+ numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks));
+ spacing = (max - min) / numSpaces;
+ niceMin = min;
+ niceMax = max;
+ } else if (countDefined) {
+ niceMin = minDefined ? min : niceMin;
+ niceMax = maxDefined ? max : niceMax;
+ numSpaces = count - 1;
+ spacing = (niceMax - niceMin) / numSpaces;
+ } else {
+ numSpaces = (niceMax - niceMin) / spacing;
+ if (almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
+ numSpaces = Math.round(numSpaces);
+ } else {
+ numSpaces = Math.ceil(numSpaces);
+ }
+ }
+ var decimalPlaces = Math.max(_decimalPlaces(spacing), _decimalPlaces(niceMin));
+ factor = Math.pow(10, isNullOrUndef(precision) ? decimalPlaces : precision);
+ niceMin = Math.round(niceMin * factor) / factor;
+ niceMax = Math.round(niceMax * factor) / factor;
+ var j = 0;
+ if (minDefined) {
+ if (includeBounds && niceMin !== min) {
+ ticks.push({
+ value: min
+ });
+ if (niceMin < min) {
+ j++;
+ }
+ if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) {
+ j++;
+ }
+ } else if (niceMin < min) {
+ j++;
+ }
+ }
+ for (; j < numSpaces; ++j) {
+ var tickValue = Math.round((niceMin + j * spacing) * factor) / factor;
+ if (maxDefined && tickValue > max) {
+ break;
+ }
+ ticks.push({
+ value: tickValue
+ });
+ }
+ if (maxDefined && includeBounds && niceMax !== max) {
+ if (ticks.length && almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) {
+ ticks[ticks.length - 1].value = max;
+ } else {
+ ticks.push({
+ value: max
+ });
+ }
+ } else if (!maxDefined || niceMax === max) {
+ ticks.push({
+ value: niceMax
+ });
+ }
+ return ticks;
+ }
+ function relativeLabelSize(value, minSpacing, _ref12) {
+ var horizontal = _ref12.horizontal,
+ minRotation = _ref12.minRotation;
+ var rad = toRadians(minRotation);
+ var ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 0.001;
+ var length = 0.75 * minSpacing * ('' + value).length;
+ return Math.min(minSpacing / ratio, length);
+ }
+ var LinearScaleBase = /*#__PURE__*/function (_Scale2) {
+ function LinearScaleBase(cfg) {
+ var _this37;
+ _classCallCheck$1(this, LinearScaleBase);
+ _this37 = _callSuper(this, LinearScaleBase, [cfg]);
+ _this37.start = undefined;
+ _this37.end = undefined;
+ _this37._startValue = undefined;
+ _this37._endValue = undefined;
+ _this37._valueRange = 0;
+ return _this37;
+ }
+ _inherits$1(LinearScaleBase, _Scale2);
+ return _createClass$1(LinearScaleBase, [{
+ key: "parse",
+ value: function parse(raw, index) {
+ if (isNullOrUndef(raw)) {
+ return null;
+ }
+ if ((typeof raw === 'number' || raw instanceof Number) && !isFinite(+raw)) {
+ return null;
+ }
+ return +raw;
+ }
+ }, {
+ key: "handleTickRangeOptions",
+ value: function handleTickRangeOptions() {
+ var beginAtZero = this.options.beginAtZero;
+ var _this$getUserBounds3 = this.getUserBounds(),
+ minDefined = _this$getUserBounds3.minDefined,
+ maxDefined = _this$getUserBounds3.maxDefined;
+ var min = this.min,
+ max = this.max;
+ var setMin = function setMin(v) {
+ return min = minDefined ? min : v;
+ };
+ var setMax = function setMax(v) {
+ return max = maxDefined ? max : v;
+ };
+ if (beginAtZero) {
+ var minSign = sign(min);
+ var maxSign = sign(max);
+ if (minSign < 0 && maxSign < 0) {
+ setMax(0);
+ } else if (minSign > 0 && maxSign > 0) {
+ setMin(0);
+ }
+ }
+ if (min === max) {
+ var offset = max === 0 ? 1 : Math.abs(max * 0.05);
+ setMax(max + offset);
+ if (!beginAtZero) {
+ setMin(min - offset);
+ }
+ }
+ this.min = min;
+ this.max = max;
+ }
+ }, {
+ key: "getTickLimit",
+ value: function getTickLimit() {
+ var tickOpts = this.options.ticks;
+ var maxTicksLimit = tickOpts.maxTicksLimit,
+ stepSize = tickOpts.stepSize;
+ var maxTicks;
+ if (stepSize) {
+ maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1;
+ if (maxTicks > 1000) {
+ console.warn("scales.".concat(this.id, ".ticks.stepSize: ").concat(stepSize, " would result generating up to ").concat(maxTicks, " ticks. Limiting to 1000."));
+ maxTicks = 1000;
+ }
+ } else {
+ maxTicks = this.computeTickLimit();
+ maxTicksLimit = maxTicksLimit || 11;
+ }
+ if (maxTicksLimit) {
+ maxTicks = Math.min(maxTicksLimit, maxTicks);
+ }
+ return maxTicks;
+ }
+ }, {
+ key: "computeTickLimit",
+ value: function computeTickLimit() {
+ return Number.POSITIVE_INFINITY;
+ }
+ }, {
+ key: "buildTicks",
+ value: function buildTicks() {
+ var opts = this.options;
+ var tickOpts = opts.ticks;
+ var maxTicks = this.getTickLimit();
+ maxTicks = Math.max(2, maxTicks);
+ var numericGeneratorOptions = {
+ maxTicks: maxTicks,
+ bounds: opts.bounds,
+ min: opts.min,
+ max: opts.max,
+ precision: tickOpts.precision,
+ step: tickOpts.stepSize,
+ count: tickOpts.count,
+ maxDigits: this._maxDigits(),
+ horizontal: this.isHorizontal(),
+ minRotation: tickOpts.minRotation || 0,
+ includeBounds: tickOpts.includeBounds !== false
+ };
+ var dataRange = this._range || this;
+ var ticks = generateTicks$1(numericGeneratorOptions, dataRange);
+ if (opts.bounds === 'ticks') {
+ _setMinAndMaxByKey(ticks, this, 'value');
+ }
+ if (opts.reverse) {
+ ticks.reverse();
+ this.start = this.max;
+ this.end = this.min;
+ } else {
+ this.start = this.min;
+ this.end = this.max;
+ }
+ return ticks;
+ }
+ }, {
+ key: "configure",
+ value: function configure() {
+ var ticks = this.ticks;
+ var start = this.min;
+ var end = this.max;
+ _superPropGet(LinearScaleBase, "configure", this, 3)([]);
+ if (this.options.offset && ticks.length) {
+ var offset = (end - start) / Math.max(ticks.length - 1, 1) / 2;
+ start -= offset;
+ end += offset;
+ }
+ this._startValue = start;
+ this._endValue = end;
+ this._valueRange = end - start;
+ }
+ }, {
+ key: "getLabelForValue",
+ value: function getLabelForValue(value) {
+ return formatNumber(value, this.chart.options.locale, this.options.ticks.format);
+ }
+ }]);
+ }(Scale);
+ var LinearScale = /*#__PURE__*/function (_LinearScaleBase) {
+ function LinearScale() {
+ _classCallCheck$1(this, LinearScale);
+ return _callSuper(this, LinearScale, arguments);
+ }
+ _inherits$1(LinearScale, _LinearScaleBase);
+ return _createClass$1(LinearScale, [{
+ key: "determineDataLimits",
+ value: function determineDataLimits() {
+ var _this$getMinMax2 = this.getMinMax(true),
+ min = _this$getMinMax2.min,
+ max = _this$getMinMax2.max;
+ this.min = isNumberFinite(min) ? min : 0;
+ this.max = isNumberFinite(max) ? max : 1;
+ this.handleTickRangeOptions();
+ }
+ }, {
+ key: "computeTickLimit",
+ value: function computeTickLimit() {
+ var horizontal = this.isHorizontal();
+ var length = horizontal ? this.width : this.height;
+ var minRotation = toRadians(this.options.ticks.minRotation);
+ var ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 0.001;
+ var tickFont = this._resolveTickFontOptions(0);
+ return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio));
+ }
+ }, {
+ key: "getPixelForValue",
+ value: function getPixelForValue(value) {
+ return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);
+ }
+ }, {
+ key: "getValueForPixel",
+ value: function getValueForPixel(pixel) {
+ return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange;
+ }
+ }]);
+ }(LinearScaleBase);
+ _defineProperty$1(LinearScale, "id", 'linear');
+ _defineProperty$1(LinearScale, "defaults", {
+ ticks: {
+ callback: Ticks.formatters.numeric
+ }
+ });
+ var log10Floor = function log10Floor(v) {
+ return Math.floor(log10(v));
+ };
+ var changeExponent = function changeExponent(v, m) {
+ return Math.pow(10, log10Floor(v) + m);
+ };
+ function isMajor(tickVal) {
+ var remain = tickVal / Math.pow(10, log10Floor(tickVal));
+ return remain === 1;
+ }
+ function steps(min, max, rangeExp) {
+ var rangeStep = Math.pow(10, rangeExp);
+ var start = Math.floor(min / rangeStep);
+ var end = Math.ceil(max / rangeStep);
+ return end - start;
+ }
+ function startExp(min, max) {
+ var range = max - min;
+ var rangeExp = log10Floor(range);
+ while (steps(min, max, rangeExp) > 10) {
+ rangeExp++;
+ }
+ while (steps(min, max, rangeExp) < 10) {
+ rangeExp--;
+ }
+ return Math.min(rangeExp, log10Floor(min));
+ }
+ function generateTicks(generationOptions, _ref13) {
+ var min = _ref13.min,
+ max = _ref13.max;
+ min = finiteOrDefault(generationOptions.min, min);
+ var ticks = [];
+ var minExp = log10Floor(min);
+ var exp = startExp(min, max);
+ var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
+ var stepSize = Math.pow(10, exp);
+ var base = minExp > exp ? Math.pow(10, minExp) : 0;
+ var start = Math.round((min - base) * precision) / precision;
+ var offset = Math.floor((min - base) / stepSize / 10) * stepSize * 10;
+ var significand = Math.floor((start - offset) / Math.pow(10, exp));
+ var value = finiteOrDefault(generationOptions.min, Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision);
+ while (value < max) {
+ ticks.push({
+ value: value,
+ major: isMajor(value),
+ significand: significand
+ });
+ if (significand >= 10) {
+ significand = significand < 15 ? 15 : 20;
+ } else {
+ significand++;
+ }
+ if (significand >= 20) {
+ exp++;
+ significand = 2;
+ precision = exp >= 0 ? 1 : precision;
+ }
+ value = Math.round((base + offset + significand * Math.pow(10, exp)) * precision) / precision;
+ }
+ var lastTick = finiteOrDefault(generationOptions.max, value);
+ ticks.push({
+ value: lastTick,
+ major: isMajor(lastTick),
+ significand: significand
+ });
+ return ticks;
+ }
+ var LogarithmicScale = /*#__PURE__*/function (_Scale3) {
+ function LogarithmicScale(cfg) {
+ var _this38;
+ _classCallCheck$1(this, LogarithmicScale);
+ _this38 = _callSuper(this, LogarithmicScale, [cfg]);
+ _this38.start = undefined;
+ _this38.end = undefined;
+ _this38._startValue = undefined;
+ _this38._valueRange = 0;
+ return _this38;
+ }
+ _inherits$1(LogarithmicScale, _Scale3);
+ return _createClass$1(LogarithmicScale, [{
+ key: "parse",
+ value: function parse(raw, index) {
+ var value = LinearScaleBase.prototype.parse.apply(this, [raw, index]);
+ if (value === 0) {
+ this._zero = true;
+ return undefined;
+ }
+ return isNumberFinite(value) && value > 0 ? value : null;
+ }
+ }, {
+ key: "determineDataLimits",
+ value: function determineDataLimits() {
+ var _this$getMinMax3 = this.getMinMax(true),
+ min = _this$getMinMax3.min,
+ max = _this$getMinMax3.max;
+ this.min = isNumberFinite(min) ? Math.max(0, min) : null;
+ this.max = isNumberFinite(max) ? Math.max(0, max) : null;
+ if (this.options.beginAtZero) {
+ this._zero = true;
+ }
+ if (this._zero && this.min !== this._suggestedMin && !isNumberFinite(this._userMin)) {
+ this.min = min === changeExponent(this.min, 0) ? changeExponent(this.min, -1) : changeExponent(this.min, 0);
+ }
+ this.handleTickRangeOptions();
+ }
+ }, {
+ key: "handleTickRangeOptions",
+ value: function handleTickRangeOptions() {
+ var _this$getUserBounds4 = this.getUserBounds(),
+ minDefined = _this$getUserBounds4.minDefined,
+ maxDefined = _this$getUserBounds4.maxDefined;
+ var min = this.min;
+ var max = this.max;
+ var setMin = function setMin(v) {
+ return min = minDefined ? min : v;
+ };
+ var setMax = function setMax(v) {
+ return max = maxDefined ? max : v;
+ };
+ if (min === max) {
+ if (min <= 0) {
+ setMin(1);
+ setMax(10);
+ } else {
+ setMin(changeExponent(min, -1));
+ setMax(changeExponent(max, +1));
+ }
+ }
+ if (min <= 0) {
+ setMin(changeExponent(max, -1));
+ }
+ if (max <= 0) {
+ setMax(changeExponent(min, +1));
+ }
+ this.min = min;
+ this.max = max;
+ }
+ }, {
+ key: "buildTicks",
+ value: function buildTicks() {
+ var opts = this.options;
+ var generationOptions = {
+ min: this._userMin,
+ max: this._userMax
+ };
+ var ticks = generateTicks(generationOptions, this);
+ if (opts.bounds === 'ticks') {
+ _setMinAndMaxByKey(ticks, this, 'value');
+ }
+ if (opts.reverse) {
+ ticks.reverse();
+ this.start = this.max;
+ this.end = this.min;
+ } else {
+ this.start = this.min;
+ this.end = this.max;
+ }
+ return ticks;
+ }
+ }, {
+ key: "getLabelForValue",
+ value: function getLabelForValue(value) {
+ return value === undefined ? '0' : formatNumber(value, this.chart.options.locale, this.options.ticks.format);
+ }
+ }, {
+ key: "configure",
+ value: function configure() {
+ var start = this.min;
+ _superPropGet(LogarithmicScale, "configure", this, 3)([]);
+ this._startValue = log10(start);
+ this._valueRange = log10(this.max) - log10(start);
+ }
+ }, {
+ key: "getPixelForValue",
+ value: function getPixelForValue(value) {
+ if (value === undefined || value === 0) {
+ value = this.min;
+ }
+ if (value === null || isNaN(value)) {
+ return NaN;
+ }
+ return this.getPixelForDecimal(value === this.min ? 0 : (log10(value) - this._startValue) / this._valueRange);
+ }
+ }, {
+ key: "getValueForPixel",
+ value: function getValueForPixel(pixel) {
+ var decimal = this.getDecimalForPixel(pixel);
+ return Math.pow(10, this._startValue + decimal * this._valueRange);
+ }
+ }]);
+ }(Scale);
+ _defineProperty$1(LogarithmicScale, "id", 'logarithmic');
+ _defineProperty$1(LogarithmicScale, "defaults", {
+ ticks: {
+ callback: Ticks.formatters.logarithmic,
+ major: {
+ enabled: true
+ }
+ }
+ });
+ function getTickBackdropHeight(opts) {
+ var tickOpts = opts.ticks;
+ if (tickOpts.display && opts.display) {
+ var padding = toPadding(tickOpts.backdropPadding);
+ return valueOrDefault(tickOpts.font && tickOpts.font.size, defaults.font.size) + padding.height;
+ }
+ return 0;
+ }
+ function measureLabelSize(ctx, font, label) {
+ label = isArray(label) ? label : [label];
+ return {
+ w: _longestText(ctx, font.string, label),
+ h: label.length * font.lineHeight
+ };
+ }
+ function determineLimits(angle, pos, size, min, max) {
+ if (angle === min || angle === max) {
+ return {
+ start: pos - size / 2,
+ end: pos + size / 2
+ };
+ } else if (angle < min || angle > max) {
+ return {
+ start: pos - size,
+ end: pos
+ };
+ }
+ return {
+ start: pos,
+ end: pos + size
+ };
+ }
+ function fitWithPointLabels(scale) {
+ var orig = {
+ l: scale.left + scale._padding.left,
+ r: scale.right - scale._padding.right,
+ t: scale.top + scale._padding.top,
+ b: scale.bottom - scale._padding.bottom
+ };
+ var limits = Object.assign({}, orig);
+ var labelSizes = [];
+ var padding = [];
+ var valueCount = scale._pointLabels.length;
+ var pointLabelOpts = scale.options.pointLabels;
+ var additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0;
+ for (var i = 0; i < valueCount; i++) {
+ var opts = pointLabelOpts.setContext(scale.getPointLabelContext(i));
+ padding[i] = opts.padding;
+ var pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle);
+ var plFont = toFont(opts.font);
+ var textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]);
+ labelSizes[i] = textSize;
+ var angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle);
+ var angle = Math.round(toDegrees(angleRadians));
+ var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
+ var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
+ updateLimits(limits, orig, angleRadians, hLimits, vLimits);
+ }
+ scale.setCenterPoint(orig.l - limits.l, limits.r - orig.r, orig.t - limits.t, limits.b - orig.b);
+ scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);
+ }
+ function updateLimits(limits, orig, angle, hLimits, vLimits) {
+ var sin = Math.abs(Math.sin(angle));
+ var cos = Math.abs(Math.cos(angle));
+ var x = 0;
+ var y = 0;
+ if (hLimits.start < orig.l) {
+ x = (orig.l - hLimits.start) / sin;
+ limits.l = Math.min(limits.l, orig.l - x);
+ } else if (hLimits.end > orig.r) {
+ x = (hLimits.end - orig.r) / sin;
+ limits.r = Math.max(limits.r, orig.r + x);
+ }
+ if (vLimits.start < orig.t) {
+ y = (orig.t - vLimits.start) / cos;
+ limits.t = Math.min(limits.t, orig.t - y);
+ } else if (vLimits.end > orig.b) {
+ y = (vLimits.end - orig.b) / cos;
+ limits.b = Math.max(limits.b, orig.b + y);
+ }
+ }
+ function createPointLabelItem(scale, index, itemOpts) {
+ var outerDistance = scale.drawingArea;
+ var extra = itemOpts.extra,
+ additionalAngle = itemOpts.additionalAngle,
+ padding = itemOpts.padding,
+ size = itemOpts.size;
+ var pointLabelPosition = scale.getPointPosition(index, outerDistance + extra + padding, additionalAngle);
+ var angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI)));
+ var y = yForAngle(pointLabelPosition.y, size.h, angle);
+ var textAlign = getTextAlignForAngle(angle);
+ var left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign);
+ return {
+ visible: true,
+ x: pointLabelPosition.x,
+ y: y,
+ textAlign: textAlign,
+ left: left,
+ top: y,
+ right: left + size.w,
+ bottom: y + size.h
+ };
+ }
+ function isNotOverlapped(item, area) {
+ if (!area) {
+ return true;
+ }
+ var left = item.left,
+ top = item.top,
+ right = item.right,
+ bottom = item.bottom;
+ var apexesInArea = _isPointInArea({
+ x: left,
+ y: top
+ }, area) || _isPointInArea({
+ x: left,
+ y: bottom
+ }, area) || _isPointInArea({
+ x: right,
+ y: top
+ }, area) || _isPointInArea({
+ x: right,
+ y: bottom
+ }, area);
+ return !apexesInArea;
+ }
+ function buildPointLabelItems(scale, labelSizes, padding) {
+ var items = [];
+ var valueCount = scale._pointLabels.length;
+ var opts = scale.options;
+ var _opts$pointLabels = opts.pointLabels,
+ centerPointLabels = _opts$pointLabels.centerPointLabels,
+ display = _opts$pointLabels.display;
+ var itemOpts = {
+ extra: getTickBackdropHeight(opts) / 2,
+ additionalAngle: centerPointLabels ? PI / valueCount : 0
+ };
+ var area;
+ for (var i = 0; i < valueCount; i++) {
+ itemOpts.padding = padding[i];
+ itemOpts.size = labelSizes[i];
+ var item = createPointLabelItem(scale, i, itemOpts);
+ items.push(item);
+ if (display === 'auto') {
+ item.visible = isNotOverlapped(item, area);
+ if (item.visible) {
+ area = item;
+ }
+ }
+ }
+ return items;
+ }
+ function getTextAlignForAngle(angle) {
+ if (angle === 0 || angle === 180) {
+ return 'center';
+ } else if (angle < 180) {
+ return 'left';
+ }
+ return 'right';
+ }
+ function leftForTextAlign(x, w, align) {
+ if (align === 'right') {
+ x -= w;
+ } else if (align === 'center') {
+ x -= w / 2;
+ }
+ return x;
+ }
+ function yForAngle(y, h, angle) {
+ if (angle === 90 || angle === 270) {
+ y -= h / 2;
+ } else if (angle > 270 || angle < 90) {
+ y -= h;
+ }
+ return y;
+ }
+ function drawPointLabelBox(ctx, opts, item) {
+ var left = item.left,
+ top = item.top,
+ right = item.right,
+ bottom = item.bottom;
+ var backdropColor = opts.backdropColor;
+ if (!isNullOrUndef(backdropColor)) {
+ var borderRadius = toTRBLCorners(opts.borderRadius);
+ var padding = toPadding(opts.backdropPadding);
+ ctx.fillStyle = backdropColor;
+ var backdropLeft = left - padding.left;
+ var backdropTop = top - padding.top;
+ var backdropWidth = right - left + padding.width;
+ var backdropHeight = bottom - top + padding.height;
+ if (Object.values(borderRadius).some(function (v) {
+ return v !== 0;
+ })) {
+ ctx.beginPath();
+ addRoundedRectPath(ctx, {
+ x: backdropLeft,
+ y: backdropTop,
+ w: backdropWidth,
+ h: backdropHeight,
+ radius: borderRadius
+ });
+ ctx.fill();
+ } else {
+ ctx.fillRect(backdropLeft, backdropTop, backdropWidth, backdropHeight);
+ }
+ }
+ }
+ function drawPointLabels(scale, labelCount) {
+ var ctx = scale.ctx,
+ pointLabels = scale.options.pointLabels;
+ for (var i = labelCount - 1; i >= 0; i--) {
+ var item = scale._pointLabelItems[i];
+ if (!item.visible) {
+ continue;
+ }
+ var optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i));
+ drawPointLabelBox(ctx, optsAtIndex, item);
+ var plFont = toFont(optsAtIndex.font);
+ var x = item.x,
+ y = item.y,
+ textAlign = item.textAlign;
+ renderText(ctx, scale._pointLabels[i], x, y + plFont.lineHeight / 2, plFont, {
+ color: optsAtIndex.color,
+ textAlign: textAlign,
+ textBaseline: 'middle'
+ });
+ }
+ }
+ function pathRadiusLine(scale, radius, circular, labelCount) {
+ var ctx = scale.ctx;
+ if (circular) {
+ ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU);
+ } else {
+ var pointPosition = scale.getPointPosition(0, radius);
+ ctx.moveTo(pointPosition.x, pointPosition.y);
+ for (var i = 1; i < labelCount; i++) {
+ pointPosition = scale.getPointPosition(i, radius);
+ ctx.lineTo(pointPosition.x, pointPosition.y);
+ }
+ }
+ }
+ function drawRadiusLine(scale, gridLineOpts, radius, labelCount, borderOpts) {
+ var ctx = scale.ctx;
+ var circular = gridLineOpts.circular;
+ var color = gridLineOpts.color,
+ lineWidth = gridLineOpts.lineWidth;
+ if (!circular && !labelCount || !color || !lineWidth || radius < 0) {
+ return;
+ }
+ ctx.save();
+ ctx.strokeStyle = color;
+ ctx.lineWidth = lineWidth;
+ ctx.setLineDash(borderOpts.dash || []);
+ ctx.lineDashOffset = borderOpts.dashOffset;
+ ctx.beginPath();
+ pathRadiusLine(scale, radius, circular, labelCount);
+ ctx.closePath();
+ ctx.stroke();
+ ctx.restore();
+ }
+ function createPointLabelContext(parent, index, label) {
+ return createContext(parent, {
+ label: label,
+ index: index,
+ type: 'pointLabel'
+ });
+ }
+ var RadialLinearScale = /*#__PURE__*/function (_LinearScaleBase2) {
+ function RadialLinearScale(cfg) {
+ var _this39;
+ _classCallCheck$1(this, RadialLinearScale);
+ _this39 = _callSuper(this, RadialLinearScale, [cfg]);
+ _this39.xCenter = undefined;
+ _this39.yCenter = undefined;
+ _this39.drawingArea = undefined;
+ _this39._pointLabels = [];
+ _this39._pointLabelItems = [];
+ return _this39;
+ }
+ _inherits$1(RadialLinearScale, _LinearScaleBase2);
+ return _createClass$1(RadialLinearScale, [{
+ key: "setDimensions",
+ value: function setDimensions() {
+ var padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2);
+ var w = this.width = this.maxWidth - padding.width;
+ var h = this.height = this.maxHeight - padding.height;
+ this.xCenter = Math.floor(this.left + w / 2 + padding.left);
+ this.yCenter = Math.floor(this.top + h / 2 + padding.top);
+ this.drawingArea = Math.floor(Math.min(w, h) / 2);
+ }
+ }, {
+ key: "determineDataLimits",
+ value: function determineDataLimits() {
+ var _this$getMinMax4 = this.getMinMax(false),
+ min = _this$getMinMax4.min,
+ max = _this$getMinMax4.max;
+ this.min = isNumberFinite(min) && !isNaN(min) ? min : 0;
+ this.max = isNumberFinite(max) && !isNaN(max) ? max : 0;
+ this.handleTickRangeOptions();
+ }
+ }, {
+ key: "computeTickLimit",
+ value: function computeTickLimit() {
+ return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options));
+ }
+ }, {
+ key: "generateTickLabels",
+ value: function generateTickLabels(ticks) {
+ var _this40 = this;
+ LinearScaleBase.prototype.generateTickLabels.call(this, ticks);
+ this._pointLabels = this.getLabels().map(function (value, index) {
+ var label = callback(_this40.options.pointLabels.callback, [value, index], _this40);
+ return label || label === 0 ? label : '';
+ }).filter(function (v, i) {
+ return _this40.chart.getDataVisibility(i);
+ });
+ }
+ }, {
+ key: "fit",
+ value: function fit() {
+ var opts = this.options;
+ if (opts.display && opts.pointLabels.display) {
+ fitWithPointLabels(this);
+ } else {
+ this.setCenterPoint(0, 0, 0, 0);
+ }
+ }
+ }, {
+ key: "setCenterPoint",
+ value: function setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) {
+ this.xCenter += Math.floor((leftMovement - rightMovement) / 2);
+ this.yCenter += Math.floor((topMovement - bottomMovement) / 2);
+ this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement));
+ }
+ }, {
+ key: "getIndexAngle",
+ value: function getIndexAngle(index) {
+ var angleMultiplier = TAU / (this._pointLabels.length || 1);
+ var startAngle = this.options.startAngle || 0;
+ return _normalizeAngle(index * angleMultiplier + toRadians(startAngle));
+ }
+ }, {
+ key: "getDistanceFromCenterForValue",
+ value: function getDistanceFromCenterForValue(value) {
+ if (isNullOrUndef(value)) {
+ return NaN;
+ }
+ var scalingFactor = this.drawingArea / (this.max - this.min);
+ if (this.options.reverse) {
+ return (this.max - value) * scalingFactor;
+ }
+ return (value - this.min) * scalingFactor;
+ }
+ }, {
+ key: "getValueForDistanceFromCenter",
+ value: function getValueForDistanceFromCenter(distance) {
+ if (isNullOrUndef(distance)) {
+ return NaN;
+ }
+ var scaledDistance = distance / (this.drawingArea / (this.max - this.min));
+ return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance;
+ }
+ }, {
+ key: "getPointLabelContext",
+ value: function getPointLabelContext(index) {
+ var pointLabels = this._pointLabels || [];
+ if (index >= 0 && index < pointLabels.length) {
+ var pointLabel = pointLabels[index];
+ return createPointLabelContext(this.getContext(), index, pointLabel);
+ }
+ }
+ }, {
+ key: "getPointPosition",
+ value: function getPointPosition(index, distanceFromCenter) {
+ var additionalAngle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
+ var angle = this.getIndexAngle(index) - HALF_PI + additionalAngle;
+ return {
+ x: Math.cos(angle) * distanceFromCenter + this.xCenter,
+ y: Math.sin(angle) * distanceFromCenter + this.yCenter,
+ angle: angle
+ };
+ }
+ }, {
+ key: "getPointPositionForValue",
+ value: function getPointPositionForValue(index, value) {
+ return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
+ }
+ }, {
+ key: "getBasePosition",
+ value: function getBasePosition(index) {
+ return this.getPointPositionForValue(index || 0, this.getBaseValue());
+ }
+ }, {
+ key: "getPointLabelPosition",
+ value: function getPointLabelPosition(index) {
+ var _this$_pointLabelItem = this._pointLabelItems[index],
+ left = _this$_pointLabelItem.left,
+ top = _this$_pointLabelItem.top,
+ right = _this$_pointLabelItem.right,
+ bottom = _this$_pointLabelItem.bottom;
+ return {
+ left: left,
+ top: top,
+ right: right,
+ bottom: bottom
+ };
+ }
+ }, {
+ key: "drawBackground",
+ value: function drawBackground() {
+ var _this$options16 = this.options,
+ backgroundColor = _this$options16.backgroundColor,
+ circular = _this$options16.grid.circular;
+ if (backgroundColor) {
+ var ctx = this.ctx;
+ ctx.save();
+ ctx.beginPath();
+ pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length);
+ ctx.closePath();
+ ctx.fillStyle = backgroundColor;
+ ctx.fill();
+ ctx.restore();
+ }
+ }
+ }, {
+ key: "drawGrid",
+ value: function drawGrid() {
+ var _this41 = this;
+ var ctx = this.ctx;
+ var opts = this.options;
+ var angleLines = opts.angleLines,
+ grid = opts.grid,
+ border = opts.border;
+ var labelCount = this._pointLabels.length;
+ var i, offset, position;
+ if (opts.pointLabels.display) {
+ drawPointLabels(this, labelCount);
+ }
+ if (grid.display) {
+ this.ticks.forEach(function (tick, index) {
+ if (index !== 0 || index === 0 && _this41.min < 0) {
+ offset = _this41.getDistanceFromCenterForValue(tick.value);
+ var context = _this41.getContext(index);
+ var optsAtIndex = grid.setContext(context);
+ var optsAtIndexBorder = border.setContext(context);
+ drawRadiusLine(_this41, optsAtIndex, offset, labelCount, optsAtIndexBorder);
+ }
+ });
+ }
+ if (angleLines.display) {
+ ctx.save();
+ for (i = labelCount - 1; i >= 0; i--) {
+ var optsAtIndex = angleLines.setContext(this.getPointLabelContext(i));
+ var color = optsAtIndex.color,
+ lineWidth = optsAtIndex.lineWidth;
+ if (!lineWidth || !color) {
+ continue;
+ }
+ ctx.lineWidth = lineWidth;
+ ctx.strokeStyle = color;
+ ctx.setLineDash(optsAtIndex.borderDash);
+ ctx.lineDashOffset = optsAtIndex.borderDashOffset;
+ offset = this.getDistanceFromCenterForValue(opts.reverse ? this.min : this.max);
+ position = this.getPointPosition(i, offset);
+ ctx.beginPath();
+ ctx.moveTo(this.xCenter, this.yCenter);
+ ctx.lineTo(position.x, position.y);
+ ctx.stroke();
+ }
+ ctx.restore();
+ }
+ }
+ }, {
+ key: "drawBorder",
+ value: function drawBorder() {}
+ }, {
+ key: "drawLabels",
+ value: function drawLabels() {
+ var _this42 = this;
+ var ctx = this.ctx;
+ var opts = this.options;
+ var tickOpts = opts.ticks;
+ if (!tickOpts.display) {
+ return;
+ }
+ var startAngle = this.getIndexAngle(0);
+ var offset, width;
+ ctx.save();
+ ctx.translate(this.xCenter, this.yCenter);
+ ctx.rotate(startAngle);
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+ this.ticks.forEach(function (tick, index) {
+ if (index === 0 && _this42.min >= 0 && !opts.reverse) {
+ return;
+ }
+ var optsAtIndex = tickOpts.setContext(_this42.getContext(index));
+ var tickFont = toFont(optsAtIndex.font);
+ offset = _this42.getDistanceFromCenterForValue(_this42.ticks[index].value);
+ if (optsAtIndex.showLabelBackdrop) {
+ ctx.font = tickFont.string;
+ width = ctx.measureText(tick.label).width;
+ ctx.fillStyle = optsAtIndex.backdropColor;
+ var padding = toPadding(optsAtIndex.backdropPadding);
+ ctx.fillRect(-width / 2 - padding.left, -offset - tickFont.size / 2 - padding.top, width + padding.width, tickFont.size + padding.height);
+ }
+ renderText(ctx, tick.label, 0, -offset, tickFont, {
+ color: optsAtIndex.color,
+ strokeColor: optsAtIndex.textStrokeColor,
+ strokeWidth: optsAtIndex.textStrokeWidth
+ });
+ });
+ ctx.restore();
+ }
+ }, {
+ key: "drawTitle",
+ value: function drawTitle() {}
+ }]);
+ }(LinearScaleBase);
+ _defineProperty$1(RadialLinearScale, "id", 'radialLinear');
+ _defineProperty$1(RadialLinearScale, "defaults", {
+ display: true,
+ animate: true,
+ position: 'chartArea',
+ angleLines: {
+ display: true,
+ lineWidth: 1,
+ borderDash: [],
+ borderDashOffset: 0.0
+ },
+ grid: {
+ circular: false
+ },
+ startAngle: 0,
+ ticks: {
+ showLabelBackdrop: true,
+ callback: Ticks.formatters.numeric
+ },
+ pointLabels: {
+ backdropColor: undefined,
+ backdropPadding: 2,
+ display: true,
+ font: {
+ size: 10
+ },
+ callback: function callback(label) {
+ return label;
+ },
+ padding: 5,
+ centerPointLabels: false
+ }
+ });
+ _defineProperty$1(RadialLinearScale, "defaultRoutes", {
+ 'angleLines.color': 'borderColor',
+ 'pointLabels.color': 'color',
+ 'ticks.color': 'color'
+ });
+ _defineProperty$1(RadialLinearScale, "descriptors", {
+ angleLines: {
+ _fallback: 'grid'
+ }
+ });
+ var INTERVALS = {
+ millisecond: {
+ common: true,
+ size: 1,
+ steps: 1000
+ },
+ second: {
+ common: true,
+ size: 1000,
+ steps: 60
+ },
+ minute: {
+ common: true,
+ size: 60000,
+ steps: 60
+ },
+ hour: {
+ common: true,
+ size: 3600000,
+ steps: 24
+ },
+ day: {
+ common: true,
+ size: 86400000,
+ steps: 30
+ },
+ week: {
+ common: false,
+ size: 604800000,
+ steps: 4
+ },
+ month: {
+ common: true,
+ size: 2.628e9,
+ steps: 12
+ },
+ quarter: {
+ common: false,
+ size: 7.884e9,
+ steps: 4
+ },
+ year: {
+ common: true,
+ size: 3.154e10
+ }
+ };
+ var UNITS = /* #__PURE__ */Object.keys(INTERVALS);
+ function sorter(a, b) {
+ return a - b;
+ }
+ function _parse(scale, input) {
+ if (isNullOrUndef(input)) {
+ return null;
+ }
+ var adapter = scale._adapter;
+ var _scale$_parseOpts = scale._parseOpts,
+ parser = _scale$_parseOpts.parser,
+ round = _scale$_parseOpts.round,
+ isoWeekday = _scale$_parseOpts.isoWeekday;
+ var value = input;
+ if (typeof parser === 'function') {
+ value = parser(value);
+ }
+ if (!isNumberFinite(value)) {
+ value = typeof parser === 'string' ? adapter.parse(value, parser) : adapter.parse(value);
+ }
+ if (value === null) {
+ return null;
+ }
+ if (round) {
+ value = round === 'week' && (isNumber(isoWeekday) || isoWeekday === true) ? adapter.startOf(value, 'isoWeek', isoWeekday) : adapter.startOf(value, round);
+ }
+ return +value;
+ }
+ function determineUnitForAutoTicks(minUnit, min, max, capacity) {
+ var ilen = UNITS.length;
+ for (var i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {
+ var interval = INTERVALS[UNITS[i]];
+ var factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER;
+ if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {
+ return UNITS[i];
+ }
+ }
+ return UNITS[ilen - 1];
+ }
+ function determineUnitForFormatting(scale, numTicks, minUnit, min, max) {
+ for (var i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--) {
+ var unit = UNITS[i];
+ if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) {
+ return unit;
+ }
+ }
+ return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];
+ }
+ function determineMajorUnit(unit) {
+ for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {
+ if (INTERVALS[UNITS[i]].common) {
+ return UNITS[i];
+ }
+ }
+ }
+ function addTick(ticks, time, timestamps) {
+ if (!timestamps) {
+ ticks[time] = true;
+ } else if (timestamps.length) {
+ var _lookup2 = _lookup(timestamps, time),
+ lo = _lookup2.lo,
+ hi = _lookup2.hi;
+ var timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi];
+ ticks[timestamp] = true;
+ }
+ }
+ function setMajorTicks(scale, ticks, map, majorUnit) {
+ var adapter = scale._adapter;
+ var first = +adapter.startOf(ticks[0].value, majorUnit);
+ var last = ticks[ticks.length - 1].value;
+ var major, index;
+ for (major = first; major <= last; major = +adapter.add(major, 1, majorUnit)) {
+ index = map[major];
+ if (index >= 0) {
+ ticks[index].major = true;
+ }
+ }
+ return ticks;
+ }
+ function ticksFromTimestamps(scale, values, majorUnit) {
+ var ticks = [];
+ var map = {};
+ var ilen = values.length;
+ var i, value;
+ for (i = 0; i < ilen; ++i) {
+ value = values[i];
+ map[value] = i;
+ ticks.push({
+ value: value,
+ major: false
+ });
+ }
+ return ilen === 0 || !majorUnit ? ticks : setMajorTicks(scale, ticks, map, majorUnit);
+ }
+ var TimeScale = /*#__PURE__*/function (_Scale4) {
+ function TimeScale(props) {
+ var _this43;
+ _classCallCheck$1(this, TimeScale);
+ _this43 = _callSuper(this, TimeScale, [props]);
+ _this43._cache = {
+ data: [],
+ labels: [],
+ all: []
+ };
+ _this43._unit = 'day';
+ _this43._majorUnit = undefined;
+ _this43._offsets = {};
+ _this43._normalized = false;
+ _this43._parseOpts = undefined;
+ return _this43;
+ }
+ _inherits$1(TimeScale, _Scale4);
+ return _createClass$1(TimeScale, [{
+ key: "init",
+ value: function init(scaleOpts) {
+ var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ var time = scaleOpts.time || (scaleOpts.time = {});
+ var adapter = this._adapter = new adapters._date(scaleOpts.adapters.date);
+ adapter.init(opts);
+ mergeIf(time.displayFormats, adapter.formats());
+ this._parseOpts = {
+ parser: time.parser,
+ round: time.round,
+ isoWeekday: time.isoWeekday
+ };
+ _superPropGet(TimeScale, "init", this, 3)([scaleOpts]);
+ this._normalized = opts.normalized;
+ }
+ }, {
+ key: "parse",
+ value: function parse(raw, index) {
+ if (raw === undefined) {
+ return null;
+ }
+ return _parse(this, raw);
+ }
+ }, {
+ key: "beforeLayout",
+ value: function beforeLayout() {
+ _superPropGet(TimeScale, "beforeLayout", this, 3)([]);
+ this._cache = {
+ data: [],
+ labels: [],
+ all: []
+ };
+ }
+ }, {
+ key: "determineDataLimits",
+ value: function determineDataLimits() {
+ var options = this.options;
+ var adapter = this._adapter;
+ var unit = options.time.unit || 'day';
+ var _this$getUserBounds5 = this.getUserBounds(),
+ min = _this$getUserBounds5.min,
+ max = _this$getUserBounds5.max,
+ minDefined = _this$getUserBounds5.minDefined,
+ maxDefined = _this$getUserBounds5.maxDefined;
+ function _applyBounds(bounds) {
+ if (!minDefined && !isNaN(bounds.min)) {
+ min = Math.min(min, bounds.min);
+ }
+ if (!maxDefined && !isNaN(bounds.max)) {
+ max = Math.max(max, bounds.max);
+ }
+ }
+ if (!minDefined || !maxDefined) {
+ _applyBounds(this._getLabelBounds());
+ if (options.bounds !== 'ticks' || options.ticks.source !== 'labels') {
+ _applyBounds(this.getMinMax(false));
+ }
+ }
+ min = isNumberFinite(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit);
+ max = isNumberFinite(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1;
+ this.min = Math.min(min, max - 1);
+ this.max = Math.max(min + 1, max);
+ }
+ }, {
+ key: "_getLabelBounds",
+ value: function _getLabelBounds() {
+ var arr = this.getLabelTimestamps();
+ var min = Number.POSITIVE_INFINITY;
+ var max = Number.NEGATIVE_INFINITY;
+ if (arr.length) {
+ min = arr[0];
+ max = arr[arr.length - 1];
+ }
+ return {
+ min: min,
+ max: max
+ };
+ }
+ }, {
+ key: "buildTicks",
+ value: function buildTicks() {
+ var options = this.options;
+ var timeOpts = options.time;
+ var tickOpts = options.ticks;
+ var timestamps = tickOpts.source === 'labels' ? this.getLabelTimestamps() : this._generate();
+ if (options.bounds === 'ticks' && timestamps.length) {
+ this.min = this._userMin || timestamps[0];
+ this.max = this._userMax || timestamps[timestamps.length - 1];
+ }
+ var min = this.min;
+ var max = this.max;
+ var ticks = _filterBetween(timestamps, min, max);
+ this._unit = timeOpts.unit || (tickOpts.autoSkip ? determineUnitForAutoTicks(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min)) : determineUnitForFormatting(this, ticks.length, timeOpts.minUnit, this.min, this.max));
+ this._majorUnit = !tickOpts.major.enabled || this._unit === 'year' ? undefined : determineMajorUnit(this._unit);
+ this.initOffsets(timestamps);
+ if (options.reverse) {
+ ticks.reverse();
+ }
+ return ticksFromTimestamps(this, ticks, this._majorUnit);
+ }
+ }, {
+ key: "afterAutoSkip",
+ value: function afterAutoSkip() {
+ if (this.options.offsetAfterAutoskip) {
+ this.initOffsets(this.ticks.map(function (tick) {
+ return +tick.value;
+ }));
+ }
+ }
+ }, {
+ key: "initOffsets",
+ value: function initOffsets() {
+ var timestamps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
+ var start = 0;
+ var end = 0;
+ var first, last;
+ if (this.options.offset && timestamps.length) {
+ first = this.getDecimalForValue(timestamps[0]);
+ if (timestamps.length === 1) {
+ start = 1 - first;
+ } else {
+ start = (this.getDecimalForValue(timestamps[1]) - first) / 2;
+ }
+ last = this.getDecimalForValue(timestamps[timestamps.length - 1]);
+ if (timestamps.length === 1) {
+ end = last;
+ } else {
+ end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2;
+ }
+ }
+ var limit = timestamps.length < 3 ? 0.5 : 0.25;
+ start = _limitValue(start, 0, limit);
+ end = _limitValue(end, 0, limit);
+ this._offsets = {
+ start: start,
+ end: end,
+ factor: 1 / (start + 1 + end)
+ };
+ }
+ }, {
+ key: "_generate",
+ value: function _generate() {
+ var adapter = this._adapter;
+ var min = this.min;
+ var max = this.max;
+ var options = this.options;
+ var timeOpts = options.time;
+ var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min));
+ var stepSize = valueOrDefault(options.ticks.stepSize, 1);
+ var weekday = minor === 'week' ? timeOpts.isoWeekday : false;
+ var hasWeekday = isNumber(weekday) || weekday === true;
+ var ticks = {};
+ var first = min;
+ var time, count;
+ if (hasWeekday) {
+ first = +adapter.startOf(first, 'isoWeek', weekday);
+ }
+ first = +adapter.startOf(first, hasWeekday ? 'day' : minor);
+ if (adapter.diff(max, min, minor) > 100000 * stepSize) {
+ throw new Error(min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor);
+ }
+ var timestamps = options.ticks.source === 'data' && this.getDataTimestamps();
+ for (time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++) {
+ addTick(ticks, time, timestamps);
+ }
+ if (time === max || options.bounds === 'ticks' || count === 1) {
+ addTick(ticks, time, timestamps);
+ }
+ return Object.keys(ticks).sort(sorter).map(function (x) {
+ return +x;
+ });
+ }
+ }, {
+ key: "getLabelForValue",
+ value: function getLabelForValue(value) {
+ var adapter = this._adapter;
+ var timeOpts = this.options.time;
+ if (timeOpts.tooltipFormat) {
+ return adapter.format(value, timeOpts.tooltipFormat);
+ }
+ return adapter.format(value, timeOpts.displayFormats.datetime);
+ }
+ }, {
+ key: "format",
+ value: function format(value, _format) {
+ var options = this.options;
+ var formats = options.time.displayFormats;
+ var unit = this._unit;
+ var fmt = _format || formats[unit];
+ return this._adapter.format(value, fmt);
+ }
+ }, {
+ key: "_tickFormatFunction",
+ value: function _tickFormatFunction(time, index, ticks, format) {
+ var options = this.options;
+ var formatter = options.ticks.callback;
+ if (formatter) {
+ return callback(formatter, [time, index, ticks], this);
+ }
+ var formats = options.time.displayFormats;
+ var unit = this._unit;
+ var majorUnit = this._majorUnit;
+ var minorFormat = unit && formats[unit];
+ var majorFormat = majorUnit && formats[majorUnit];
+ var tick = ticks[index];
+ var major = majorUnit && majorFormat && tick && tick.major;
+ return this._adapter.format(time, format || (major ? majorFormat : minorFormat));
+ }
+ }, {
+ key: "generateTickLabels",
+ value: function generateTickLabels(ticks) {
+ var i, ilen, tick;
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ tick = ticks[i];
+ tick.label = this._tickFormatFunction(tick.value, i, ticks);
+ }
+ }
+ }, {
+ key: "getDecimalForValue",
+ value: function getDecimalForValue(value) {
+ return value === null ? NaN : (value - this.min) / (this.max - this.min);
+ }
+ }, {
+ key: "getPixelForValue",
+ value: function getPixelForValue(value) {
+ var offsets = this._offsets;
+ var pos = this.getDecimalForValue(value);
+ return this.getPixelForDecimal((offsets.start + pos) * offsets.factor);
+ }
+ }, {
+ key: "getValueForPixel",
+ value: function getValueForPixel(pixel) {
+ var offsets = this._offsets;
+ var pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;
+ return this.min + pos * (this.max - this.min);
+ }
+ }, {
+ key: "_getLabelSize",
+ value: function _getLabelSize(label) {
+ var ticksOpts = this.options.ticks;
+ var tickLabelWidth = this.ctx.measureText(label).width;
+ var angle = toRadians(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation);
+ var cosRotation = Math.cos(angle);
+ var sinRotation = Math.sin(angle);
+ var tickFontSize = this._resolveTickFontOptions(0).size;
+ return {
+ w: tickLabelWidth * cosRotation + tickFontSize * sinRotation,
+ h: tickLabelWidth * sinRotation + tickFontSize * cosRotation
+ };
+ }
+ }, {
+ key: "_getLabelCapacity",
+ value: function _getLabelCapacity(exampleTime) {
+ var timeOpts = this.options.time;
+ var displayFormats = timeOpts.displayFormats;
+ var format = displayFormats[timeOpts.unit] || displayFormats.millisecond;
+ var exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps(this, [exampleTime], this._majorUnit), format);
+ var size = this._getLabelSize(exampleLabel);
+ var capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1;
+ return capacity > 0 ? capacity : 1;
+ }
+ }, {
+ key: "getDataTimestamps",
+ value: function getDataTimestamps() {
+ var timestamps = this._cache.data || [];
+ var i, ilen;
+ if (timestamps.length) {
+ return timestamps;
+ }
+ var metas = this.getMatchingVisibleMetas();
+ if (this._normalized && metas.length) {
+ return this._cache.data = metas[0].controller.getAllParsedValues(this);
+ }
+ for (i = 0, ilen = metas.length; i < ilen; ++i) {
+ timestamps = timestamps.concat(metas[i].controller.getAllParsedValues(this));
+ }
+ return this._cache.data = this.normalize(timestamps);
+ }
+ }, {
+ key: "getLabelTimestamps",
+ value: function getLabelTimestamps() {
+ var timestamps = this._cache.labels || [];
+ var i, ilen;
+ if (timestamps.length) {
+ return timestamps;
+ }
+ var labels = this.getLabels();
+ for (i = 0, ilen = labels.length; i < ilen; ++i) {
+ timestamps.push(_parse(this, labels[i]));
+ }
+ return this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps);
+ }
+ }, {
+ key: "normalize",
+ value: function normalize(values) {
+ return _arrayUnique(values.sort(sorter));
+ }
+ }]);
+ }(Scale);
+ _defineProperty$1(TimeScale, "id", 'time');
+ _defineProperty$1(TimeScale, "defaults", {
+ bounds: 'data',
+ adapters: {},
+ time: {
+ parser: false,
+ unit: false,
+ round: false,
+ isoWeekday: false,
+ minUnit: 'millisecond',
+ displayFormats: {}
+ },
+ ticks: {
+ source: 'auto',
+ callback: false,
+ major: {
+ enabled: false
+ }
+ }
+ });
+ function interpolate(table, val, reverse) {
+ var lo = 0;
+ var hi = table.length - 1;
+ var prevSource, nextSource, prevTarget, nextTarget;
+ if (reverse) {
+ if (val >= table[lo].pos && val <= table[hi].pos) {
+ var _lookupByKey2 = _lookupByKey(table, 'pos', val);
+ lo = _lookupByKey2.lo;
+ hi = _lookupByKey2.hi;
+ }
+ var _table$lo = table[lo];
+ prevSource = _table$lo.pos;
+ prevTarget = _table$lo.time;
+ var _table$hi = table[hi];
+ nextSource = _table$hi.pos;
+ nextTarget = _table$hi.time;
+ } else {
+ if (val >= table[lo].time && val <= table[hi].time) {
+ var _lookupByKey3 = _lookupByKey(table, 'time', val);
+ lo = _lookupByKey3.lo;
+ hi = _lookupByKey3.hi;
+ }
+ var _table$lo2 = table[lo];
+ prevSource = _table$lo2.time;
+ prevTarget = _table$lo2.pos;
+ var _table$hi2 = table[hi];
+ nextSource = _table$hi2.time;
+ nextTarget = _table$hi2.pos;
+ }
+ var span = nextSource - prevSource;
+ return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget;
+ }
+ var TimeSeriesScale = /*#__PURE__*/function (_TimeScale2) {
+ function TimeSeriesScale(props) {
+ var _this44;
+ _classCallCheck$1(this, TimeSeriesScale);
+ _this44 = _callSuper(this, TimeSeriesScale, [props]);
+ _this44._table = [];
+ _this44._minPos = undefined;
+ _this44._tableRange = undefined;
+ return _this44;
+ }
+ _inherits$1(TimeSeriesScale, _TimeScale2);
+ return _createClass$1(TimeSeriesScale, [{
+ key: "initOffsets",
+ value: function initOffsets() {
+ var timestamps = this._getTimestampsForTable();
+ var table = this._table = this.buildLookupTable(timestamps);
+ this._minPos = interpolate(table, this.min);
+ this._tableRange = interpolate(table, this.max) - this._minPos;
+ _superPropGet(TimeSeriesScale, "initOffsets", this, 3)([timestamps]);
+ }
+ }, {
+ key: "buildLookupTable",
+ value: function buildLookupTable(timestamps) {
+ var min = this.min,
+ max = this.max;
+ var items = [];
+ var table = [];
+ var i, ilen, prev, curr, next;
+ for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
+ curr = timestamps[i];
+ if (curr >= min && curr <= max) {
+ items.push(curr);
+ }
+ }
+ if (items.length < 2) {
+ return [{
+ time: min,
+ pos: 0
+ }, {
+ time: max,
+ pos: 1
+ }];
+ }
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
+ next = items[i + 1];
+ prev = items[i - 1];
+ curr = items[i];
+ if (Math.round((next + prev) / 2) !== curr) {
+ table.push({
+ time: curr,
+ pos: i / (ilen - 1)
+ });
+ }
+ }
+ return table;
+ }
+ }, {
+ key: "_generate",
+ value: function _generate() {
+ var min = this.min;
+ var max = this.max;
+ var timestamps = _superPropGet(TimeSeriesScale, "getDataTimestamps", this, 3)([]);
+ if (!timestamps.includes(min) || !timestamps.length) {
+ timestamps.splice(0, 0, min);
+ }
+ if (!timestamps.includes(max) || timestamps.length === 1) {
+ timestamps.push(max);
+ }
+ return timestamps.sort(function (a, b) {
+ return a - b;
+ });
+ }
+ }, {
+ key: "_getTimestampsForTable",
+ value: function _getTimestampsForTable() {
+ var timestamps = this._cache.all || [];
+ if (timestamps.length) {
+ return timestamps;
+ }
+ var data = this.getDataTimestamps();
+ var label = this.getLabelTimestamps();
+ if (data.length && label.length) {
+ timestamps = this.normalize(data.concat(label));
+ } else {
+ timestamps = data.length ? data : label;
+ }
+ timestamps = this._cache.all = timestamps;
+ return timestamps;
+ }
+ }, {
+ key: "getDecimalForValue",
+ value: function getDecimalForValue(value) {
+ return (interpolate(this._table, value) - this._minPos) / this._tableRange;
+ }
+ }, {
+ key: "getValueForPixel",
+ value: function getValueForPixel(pixel) {
+ var offsets = this._offsets;
+ var decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;
+ return interpolate(this._table, decimal * this._tableRange + this._minPos, true);
+ }
+ }]);
+ }(TimeScale);
+ _defineProperty$1(TimeSeriesScale, "id", 'timeseries');
+ _defineProperty$1(TimeSeriesScale, "defaults", TimeScale.defaults);
+ var scales = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ CategoryScale: CategoryScale,
+ LinearScale: LinearScale,
+ LogarithmicScale: LogarithmicScale,
+ RadialLinearScale: RadialLinearScale,
+ TimeScale: TimeScale,
+ TimeSeriesScale: TimeSeriesScale
+ });
+ var registerables = [controllers, elements, plugins, scales];
+
+ Chart.register.apply(Chart, _toConsumableArray(registerables));
+
+ var helpers = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ HALF_PI: HALF_PI,
+ INFINITY: INFINITY,
+ PI: PI,
+ PITAU: PITAU,
+ QUARTER_PI: QUARTER_PI,
+ RAD_PER_DEG: RAD_PER_DEG,
+ TAU: TAU,
+ TWO_THIRDS_PI: TWO_THIRDS_PI,
+ _addGrace: _addGrace,
+ _alignPixel: _alignPixel,
+ _alignStartEnd: _alignStartEnd,
+ _angleBetween: _angleBetween,
+ _angleDiff: _angleDiff,
+ _arrayUnique: _arrayUnique,
+ _attachContext: _attachContext,
+ _bezierCurveTo: _bezierCurveTo,
+ _bezierInterpolation: _bezierInterpolation,
+ _boundSegment: _boundSegment,
+ _boundSegments: _boundSegments,
+ _capitalize: _capitalize,
+ _computeSegments: _computeSegments,
+ _createResolver: _createResolver,
+ _decimalPlaces: _decimalPlaces,
+ _deprecated: _deprecated,
+ _descriptors: _descriptors,
+ _elementsEqual: _elementsEqual,
+ _factorize: _factorize,
+ _filterBetween: _filterBetween,
+ _getParentNode: _getParentNode,
+ _getStartAndCountOfVisiblePoints: _getStartAndCountOfVisiblePoints,
+ _int16Range: _int16Range,
+ _isBetween: _isBetween,
+ _isClickEvent: _isClickEvent,
+ _isDomSupported: _isDomSupported,
+ _isPointInArea: _isPointInArea,
+ _limitValue: _limitValue,
+ _longestText: _longestText,
+ _lookup: _lookup,
+ _lookupByKey: _lookupByKey,
+ _measureText: _measureText,
+ _merger: _merger,
+ _mergerIf: _mergerIf,
+ _normalizeAngle: _normalizeAngle,
+ _parseObjectDataRadialScale: _parseObjectDataRadialScale,
+ _pointInLine: _pointInLine,
+ _readValueToProps: _readValueToProps,
+ _rlookupByKey: _rlookupByKey,
+ _scaleRangesChanged: _scaleRangesChanged,
+ _setMinAndMaxByKey: _setMinAndMaxByKey,
+ _splitKey: _splitKey,
+ _steppedInterpolation: _steppedInterpolation,
+ _steppedLineTo: _steppedLineTo,
+ _textX: _textX,
+ _toLeftRightCenter: _toLeftRightCenter,
+ _updateBezierControlPoints: _updateBezierControlPoints,
+ addRoundedRectPath: addRoundedRectPath,
+ almostEquals: almostEquals,
+ almostWhole: almostWhole,
+ callback: callback,
+ clearCanvas: clearCanvas,
+ clipArea: clipArea,
+ clone: clone,
+ color: color,
+ createContext: createContext,
+ debounce: debounce,
+ defined: defined,
+ distanceBetweenPoints: distanceBetweenPoints,
+ drawPoint: drawPoint,
+ drawPointLegend: drawPointLegend,
+ each: each,
+ easingEffects: effects,
+ finiteOrDefault: finiteOrDefault,
+ fontString: fontString,
+ formatNumber: formatNumber,
+ getAngleFromPoint: getAngleFromPoint,
+ getHoverColor: getHoverColor,
+ getMaximumSize: getMaximumSize,
+ getRelativePosition: getRelativePosition,
+ getRtlAdapter: getRtlAdapter,
+ getStyle: getStyle,
+ isArray: isArray,
+ isFinite: isNumberFinite,
+ isFunction: isFunction,
+ isNullOrUndef: isNullOrUndef,
+ isNumber: isNumber,
+ isObject: isObject,
+ isPatternOrGradient: isPatternOrGradient,
+ listenArrayEvents: listenArrayEvents,
+ log10: log10,
+ merge: merge,
+ mergeIf: mergeIf,
+ niceNum: niceNum,
+ noop: noop,
+ overrideTextDirection: overrideTextDirection,
+ readUsedSize: readUsedSize,
+ renderText: renderText,
+ requestAnimFrame: requestAnimFrame,
+ resolve: resolve,
+ resolveObjectKey: resolveObjectKey,
+ restoreTextDirection: restoreTextDirection,
+ retinaScale: retinaScale,
+ setsEqual: setsEqual,
+ sign: sign,
+ splineCurve: splineCurve,
+ splineCurveMonotone: splineCurveMonotone,
+ supportsEventListenerOptions: supportsEventListenerOptions,
+ throttled: throttled,
+ toDegrees: toDegrees,
+ toDimension: toDimension,
+ toFont: toFont,
+ toFontString: toFontString,
+ toLineHeight: toLineHeight,
+ toPadding: toPadding,
+ toPercentage: toPercentage,
+ toRadians: toRadians,
+ toTRBL: toTRBL,
+ toTRBLCorners: toTRBLCorners,
+ uid: uid,
+ unclipArea: unclipArea,
+ unlistenArrayEvents: unlistenArrayEvents,
+ valueOrDefault: valueOrDefault
+ });
+
+ function _typeof(o) {
+ "@babel/helpers - typeof";
+
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
+ return typeof o;
+ } : function (o) {
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
+ }, _typeof(o);
+ }
+
+ function toInteger(dirtyNumber) {
+ if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {
+ return NaN;
+ }
+ var number = Number(dirtyNumber);
+ if (isNaN(number)) {
+ return number;
+ }
+ return number < 0 ? Math.ceil(number) : Math.floor(number);
+ }
+
+ function requiredArgs(required, args) {
+ if (args.length < required) {
+ throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');
+ }
+ }
+
+ /**
+ * @name toDate
+ * @category Common Helpers
+ * @summary Convert the given argument to an instance of Date.
+ *
+ * @description
+ * Convert the given argument to an instance of Date.
+ *
+ * If the argument is an instance of Date, the function returns its clone.
+ *
+ * If the argument is a number, it is treated as a timestamp.
+ *
+ * If the argument is none of the above, the function returns Invalid Date.
+ *
+ * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
+ *
+ * @param {Date|Number} argument - the value to convert
+ * @returns {Date} the parsed date in the local time zone
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // Clone the date:
+ * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))
+ * //=> Tue Feb 11 2014 11:30:30
+ *
+ * @example
+ * // Convert the timestamp to date:
+ * const result = toDate(1392098430000)
+ * //=> Tue Feb 11 2014 11:30:30
+ */
+ function toDate(argument) {
+ requiredArgs(1, arguments);
+ var argStr = Object.prototype.toString.call(argument);
+
+ // Clone the date
+ if (argument instanceof Date || _typeof(argument) === 'object' && argStr === '[object Date]') {
+ // Prevent the date to lose the milliseconds when passed to new Date() in IE10
+ return new Date(argument.getTime());
+ } else if (typeof argument === 'number' || argStr === '[object Number]') {
+ return new Date(argument);
+ } else {
+ if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {
+ // eslint-disable-next-line no-console
+ console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments");
+ // eslint-disable-next-line no-console
+ console.warn(new Error().stack);
+ }
+ return new Date(NaN);
+ }
+ }
+
+ /**
+ * @name addDays
+ * @category Day Helpers
+ * @summary Add the specified number of days to the given date.
+ *
+ * @description
+ * Add the specified number of days to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} - the new date with the days added
+ * @throws {TypeError} - 2 arguments required
+ *
+ * @example
+ * // Add 10 days to 1 September 2014:
+ * const result = addDays(new Date(2014, 8, 1), 10)
+ * //=> Thu Sep 11 2014 00:00:00
+ */
+ function addDays(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var date = toDate(dirtyDate);
+ var amount = toInteger(dirtyAmount);
+ if (isNaN(amount)) {
+ return new Date(NaN);
+ }
+ if (!amount) {
+ // If 0 days, no-op to avoid changing times in the hour before end of DST
+ return date;
+ }
+ date.setDate(date.getDate() + amount);
+ return date;
+ }
+
+ /**
+ * @name addMonths
+ * @category Month Helpers
+ * @summary Add the specified number of months to the given date.
+ *
+ * @description
+ * Add the specified number of months to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of months to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the months added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 5 months to 1 September 2014:
+ * const result = addMonths(new Date(2014, 8, 1), 5)
+ * //=> Sun Feb 01 2015 00:00:00
+ */
+ function addMonths(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var date = toDate(dirtyDate);
+ var amount = toInteger(dirtyAmount);
+ if (isNaN(amount)) {
+ return new Date(NaN);
+ }
+ if (!amount) {
+ // If 0 months, no-op to avoid changing times in the hour before end of DST
+ return date;
+ }
+ var dayOfMonth = date.getDate();
+
+ // The JS Date object supports date math by accepting out-of-bounds values for
+ // month, day, etc. For example, new Date(2020, 0, 0) returns 31 Dec 2019 and
+ // new Date(2020, 13, 1) returns 1 Feb 2021. This is *almost* the behavior we
+ // want except that dates will wrap around the end of a month, meaning that
+ // new Date(2020, 13, 31) will return 3 Mar 2021 not 28 Feb 2021 as desired. So
+ // we'll default to the end of the desired month by adding 1 to the desired
+ // month and using a date of 0 to back up one day to the end of the desired
+ // month.
+ var endOfDesiredMonth = new Date(date.getTime());
+ endOfDesiredMonth.setMonth(date.getMonth() + amount + 1, 0);
+ var daysInMonth = endOfDesiredMonth.getDate();
+ if (dayOfMonth >= daysInMonth) {
+ // If we're already at the end of the month, then this is the correct date
+ // and we're done.
+ return endOfDesiredMonth;
+ } else {
+ // Otherwise, we now know that setting the original day-of-month value won't
+ // cause an overflow, so set the desired day-of-month. Note that we can't
+ // just set the date of `endOfDesiredMonth` because that object may have had
+ // its time changed in the unusual case where where a DST transition was on
+ // the last day of the month and its local time was in the hour skipped or
+ // repeated next to a DST transition. So we use `date` instead which is
+ // guaranteed to still have the original time.
+ date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
+ return date;
+ }
+ }
+
+ /**
+ * @name addMilliseconds
+ * @category Millisecond Helpers
+ * @summary Add the specified number of milliseconds to the given date.
+ *
+ * @description
+ * Add the specified number of milliseconds to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of milliseconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the milliseconds added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 750 milliseconds to 10 July 2014 12:45:30.000:
+ * const result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)
+ * //=> Thu Jul 10 2014 12:45:30.750
+ */
+ function addMilliseconds(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var timestamp = toDate(dirtyDate).getTime();
+ var amount = toInteger(dirtyAmount);
+ return new Date(timestamp + amount);
+ }
+
+ var MILLISECONDS_IN_HOUR = 3600000;
+
+ /**
+ * @name addHours
+ * @category Hour Helpers
+ * @summary Add the specified number of hours to the given date.
+ *
+ * @description
+ * Add the specified number of hours to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of hours to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the hours added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 2 hours to 10 July 2014 23:00:00:
+ * const result = addHours(new Date(2014, 6, 10, 23, 0), 2)
+ * //=> Fri Jul 11 2014 01:00:00
+ */
+ function addHours(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var amount = toInteger(dirtyAmount);
+ return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_HOUR);
+ }
+
+ var defaultOptions = {};
+ function getDefaultOptions() {
+ return defaultOptions;
+ }
+
+ /**
+ * @name startOfWeek
+ * @category Week Helpers
+ * @summary Return the start of a week for the given date.
+ *
+ * @description
+ * Return the start of a week for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @param {Object} [options] - an object with options.
+ * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
+ * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
+ * @returns {Date} the start of a week
+ * @throws {TypeError} 1 argument required
+ * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
+ *
+ * @example
+ * // The start of a week for 2 September 2014 11:55:00:
+ * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Sun Aug 31 2014 00:00:00
+ *
+ * @example
+ * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:
+ * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
+ * //=> Mon Sep 01 2014 00:00:00
+ */
+ function startOfWeek(dirtyDate, options) {
+ var _ref, _ref2, _ref3, _options$weekStartsOn, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;
+ requiredArgs(1, arguments);
+ var defaultOptions = getDefaultOptions();
+ var weekStartsOn = toInteger((_ref = (_ref2 = (_ref3 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.weekStartsOn) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.weekStartsOn) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.weekStartsOn) !== null && _ref !== void 0 ? _ref : 0);
+
+ // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
+ if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
+ throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
+ }
+ var date = toDate(dirtyDate);
+ var day = date.getDay();
+ var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
+ date.setDate(date.getDate() - diff);
+ date.setHours(0, 0, 0, 0);
+ return date;
+ }
+
+ /**
+ * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.
+ * They usually appear for dates that denote time before the timezones were introduced
+ * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891
+ * and GMT+01:00:00 after that date)
+ *
+ * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,
+ * which would lead to incorrect calculations.
+ *
+ * This function returns the timezone offset in milliseconds that takes seconds in account.
+ */
+ function getTimezoneOffsetInMilliseconds(date) {
+ var utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
+ utcDate.setUTCFullYear(date.getFullYear());
+ return date.getTime() - utcDate.getTime();
+ }
+
+ /**
+ * @name startOfDay
+ * @category Day Helpers
+ * @summary Return the start of a day for the given date.
+ *
+ * @description
+ * Return the start of a day for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the start of a day
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The start of a day for 2 September 2014 11:55:00:
+ * const result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Tue Sep 02 2014 00:00:00
+ */
+ function startOfDay(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setHours(0, 0, 0, 0);
+ return date;
+ }
+
+ var MILLISECONDS_IN_DAY$1 = 86400000;
+
+ /**
+ * @name differenceInCalendarDays
+ * @category Day Helpers
+ * @summary Get the number of calendar days between the given dates.
+ *
+ * @description
+ * Get the number of calendar days between the given dates. This means that the times are removed
+ * from the dates and then the difference in days is calculated.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @returns {Number} the number of calendar days
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many calendar days are between
+ * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
+ * const result = differenceInCalendarDays(
+ * new Date(2012, 6, 2, 0, 0),
+ * new Date(2011, 6, 2, 23, 0)
+ * )
+ * //=> 366
+ * // How many calendar days are between
+ * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?
+ * const result = differenceInCalendarDays(
+ * new Date(2011, 6, 3, 0, 1),
+ * new Date(2011, 6, 2, 23, 59)
+ * )
+ * //=> 1
+ */
+ function differenceInCalendarDays(dirtyDateLeft, dirtyDateRight) {
+ requiredArgs(2, arguments);
+ var startOfDayLeft = startOfDay(dirtyDateLeft);
+ var startOfDayRight = startOfDay(dirtyDateRight);
+ var timestampLeft = startOfDayLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfDayLeft);
+ var timestampRight = startOfDayRight.getTime() - getTimezoneOffsetInMilliseconds(startOfDayRight);
+
+ // Round the number of days to the nearest integer
+ // because the number of milliseconds in a day is not constant
+ // (e.g. it's different in the day of the daylight saving time clock shift)
+ return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_DAY$1);
+ }
+
+ var MILLISECONDS_IN_MINUTE = 60000;
+
+ /**
+ * @name addMinutes
+ * @category Minute Helpers
+ * @summary Add the specified number of minutes to the given date.
+ *
+ * @description
+ * Add the specified number of minutes to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of minutes to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the minutes added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 30 minutes to 10 July 2014 12:00:00:
+ * const result = addMinutes(new Date(2014, 6, 10, 12, 0), 30)
+ * //=> Thu Jul 10 2014 12:30:00
+ */
+ function addMinutes(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var amount = toInteger(dirtyAmount);
+ return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE);
+ }
+
+ /**
+ * @name addQuarters
+ * @category Quarter Helpers
+ * @summary Add the specified number of year quarters to the given date.
+ *
+ * @description
+ * Add the specified number of year quarters to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of quarters to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the quarters added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 1 quarter to 1 September 2014:
+ * const result = addQuarters(new Date(2014, 8, 1), 1)
+ * //=> Mon Dec 01 2014 00:00:00
+ */
+ function addQuarters(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var amount = toInteger(dirtyAmount);
+ var months = amount * 3;
+ return addMonths(dirtyDate, months);
+ }
+
+ /**
+ * @name addSeconds
+ * @category Second Helpers
+ * @summary Add the specified number of seconds to the given date.
+ *
+ * @description
+ * Add the specified number of seconds to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of seconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the seconds added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 30 seconds to 10 July 2014 12:45:00:
+ * const result = addSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)
+ * //=> Thu Jul 10 2014 12:45:30
+ */
+ function addSeconds(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var amount = toInteger(dirtyAmount);
+ return addMilliseconds(dirtyDate, amount * 1000);
+ }
+
+ /**
+ * @name addWeeks
+ * @category Week Helpers
+ * @summary Add the specified number of weeks to the given date.
+ *
+ * @description
+ * Add the specified number of week to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of weeks to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the weeks added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 4 weeks to 1 September 2014:
+ * const result = addWeeks(new Date(2014, 8, 1), 4)
+ * //=> Mon Sep 29 2014 00:00:00
+ */
+ function addWeeks(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var amount = toInteger(dirtyAmount);
+ var days = amount * 7;
+ return addDays(dirtyDate, days);
+ }
+
+ /**
+ * @name addYears
+ * @category Year Helpers
+ * @summary Add the specified number of years to the given date.
+ *
+ * @description
+ * Add the specified number of years to the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of years to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the years added
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Add 5 years to 1 September 2014:
+ * const result = addYears(new Date(2014, 8, 1), 5)
+ * //=> Sun Sep 01 2019 00:00:00
+ */
+ function addYears(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var amount = toInteger(dirtyAmount);
+ return addMonths(dirtyDate, amount * 12);
+ }
+
+ /**
+ * @name compareAsc
+ * @category Common Helpers
+ * @summary Compare the two dates and return -1, 0 or 1.
+ *
+ * @description
+ * Compare the two dates and return 1 if the first date is after the second,
+ * -1 if the first date is before the second or 0 if dates are equal.
+ *
+ * @param {Date|Number} dateLeft - the first date to compare
+ * @param {Date|Number} dateRight - the second date to compare
+ * @returns {Number} the result of the comparison
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Compare 11 February 1987 and 10 July 1989:
+ * const result = compareAsc(new Date(1987, 1, 11), new Date(1989, 6, 10))
+ * //=> -1
+ *
+ * @example
+ * // Sort the array of dates:
+ * const result = [
+ * new Date(1995, 6, 2),
+ * new Date(1987, 1, 11),
+ * new Date(1989, 6, 10)
+ * ].sort(compareAsc)
+ * //=> [
+ * // Wed Feb 11 1987 00:00:00,
+ * // Mon Jul 10 1989 00:00:00,
+ * // Sun Jul 02 1995 00:00:00
+ * // ]
+ */
+ function compareAsc(dirtyDateLeft, dirtyDateRight) {
+ requiredArgs(2, arguments);
+ var dateLeft = toDate(dirtyDateLeft);
+ var dateRight = toDate(dirtyDateRight);
+ var diff = dateLeft.getTime() - dateRight.getTime();
+ if (diff < 0) {
+ return -1;
+ } else if (diff > 0) {
+ return 1;
+ // Return 0 if diff is 0; return NaN if diff is NaN
+ } else {
+ return diff;
+ }
+ }
+
+ /**
+ * Days in 1 week.
+ *
+ * @name daysInWeek
+ * @constant
+ * @type {number}
+ * @default
+ */
+
+ /**
+ * Milliseconds in 1 minute
+ *
+ * @name millisecondsInMinute
+ * @constant
+ * @type {number}
+ * @default
+ */
+ var millisecondsInMinute = 60000;
+
+ /**
+ * Milliseconds in 1 hour
+ *
+ * @name millisecondsInHour
+ * @constant
+ * @type {number}
+ * @default
+ */
+ var millisecondsInHour = 3600000;
+
+ /**
+ * Milliseconds in 1 second
+ *
+ * @name millisecondsInSecond
+ * @constant
+ * @type {number}
+ * @default
+ */
+ var millisecondsInSecond = 1000;
+
+ /**
+ * @name isDate
+ * @category Common Helpers
+ * @summary Is the given value a date?
+ *
+ * @description
+ * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.
+ *
+ * @param {*} value - the value to check
+ * @returns {boolean} true if the given value is a date
+ * @throws {TypeError} 1 arguments required
+ *
+ * @example
+ * // For a valid date:
+ * const result = isDate(new Date())
+ * //=> true
+ *
+ * @example
+ * // For an invalid date:
+ * const result = isDate(new Date(NaN))
+ * //=> true
+ *
+ * @example
+ * // For some value:
+ * const result = isDate('2014-02-31')
+ * //=> false
+ *
+ * @example
+ * // For an object:
+ * const result = isDate({})
+ * //=> false
+ */
+ function isDate(value) {
+ requiredArgs(1, arguments);
+ return value instanceof Date || _typeof(value) === 'object' && Object.prototype.toString.call(value) === '[object Date]';
+ }
+
+ /**
+ * @name isValid
+ * @category Common Helpers
+ * @summary Is the given date valid?
+ *
+ * @description
+ * Returns false if argument is Invalid Date and true otherwise.
+ * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}
+ * Invalid Date is a Date, whose time value is NaN.
+ *
+ * Time value of Date: http://es5.github.io/#x15.9.1.1
+ *
+ * @param {*} date - the date to check
+ * @returns {Boolean} the date is valid
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // For the valid date:
+ * const result = isValid(new Date(2014, 1, 31))
+ * //=> true
+ *
+ * @example
+ * // For the value, convertable into a date:
+ * const result = isValid(1393804800000)
+ * //=> true
+ *
+ * @example
+ * // For the invalid date:
+ * const result = isValid(new Date(''))
+ * //=> false
+ */
+ function isValid(dirtyDate) {
+ requiredArgs(1, arguments);
+ if (!isDate(dirtyDate) && typeof dirtyDate !== 'number') {
+ return false;
+ }
+ var date = toDate(dirtyDate);
+ return !isNaN(Number(date));
+ }
+
+ /**
+ * @name differenceInCalendarMonths
+ * @category Month Helpers
+ * @summary Get the number of calendar months between the given dates.
+ *
+ * @description
+ * Get the number of calendar months between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @returns {Number} the number of calendar months
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many calendar months are between 31 January 2014 and 1 September 2014?
+ * const result = differenceInCalendarMonths(
+ * new Date(2014, 8, 1),
+ * new Date(2014, 0, 31)
+ * )
+ * //=> 8
+ */
+ function differenceInCalendarMonths(dirtyDateLeft, dirtyDateRight) {
+ requiredArgs(2, arguments);
+ var dateLeft = toDate(dirtyDateLeft);
+ var dateRight = toDate(dirtyDateRight);
+ var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear();
+ var monthDiff = dateLeft.getMonth() - dateRight.getMonth();
+ return yearDiff * 12 + monthDiff;
+ }
+
+ /**
+ * @name differenceInCalendarYears
+ * @category Year Helpers
+ * @summary Get the number of calendar years between the given dates.
+ *
+ * @description
+ * Get the number of calendar years between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @returns {Number} the number of calendar years
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many calendar years are between 31 December 2013 and 11 February 2015?
+ * const result = differenceInCalendarYears(
+ * new Date(2015, 1, 11),
+ * new Date(2013, 11, 31)
+ * )
+ * //=> 2
+ */
+ function differenceInCalendarYears(dirtyDateLeft, dirtyDateRight) {
+ requiredArgs(2, arguments);
+ var dateLeft = toDate(dirtyDateLeft);
+ var dateRight = toDate(dirtyDateRight);
+ return dateLeft.getFullYear() - dateRight.getFullYear();
+ }
+
+ // for accurate equality comparisons of UTC timestamps that end up
+ // having the same representation in local time, e.g. one hour before
+ // DST ends vs. the instant that DST ends.
+ function compareLocalAsc(dateLeft, dateRight) {
+ var diff = dateLeft.getFullYear() - dateRight.getFullYear() || dateLeft.getMonth() - dateRight.getMonth() || dateLeft.getDate() - dateRight.getDate() || dateLeft.getHours() - dateRight.getHours() || dateLeft.getMinutes() - dateRight.getMinutes() || dateLeft.getSeconds() - dateRight.getSeconds() || dateLeft.getMilliseconds() - dateRight.getMilliseconds();
+ if (diff < 0) {
+ return -1;
+ } else if (diff > 0) {
+ return 1;
+ // Return 0 if diff is 0; return NaN if diff is NaN
+ } else {
+ return diff;
+ }
+ }
+
+ /**
+ * @name differenceInDays
+ * @category Day Helpers
+ * @summary Get the number of full days between the given dates.
+ *
+ * @description
+ * Get the number of full day periods between two dates. Fractional days are
+ * truncated towards zero.
+ *
+ * One "full day" is the distance between a local time in one day to the same
+ * local time on the next or previous day. A full day can sometimes be less than
+ * or more than 24 hours if a daylight savings change happens between two dates.
+ *
+ * To ignore DST and only measure exact 24-hour periods, use this instead:
+ * `Math.floor(differenceInHours(dateLeft, dateRight)/24)|0`.
+ *
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @returns {Number} the number of full days according to the local timezone
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many full days are between
+ * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
+ * const result = differenceInDays(
+ * new Date(2012, 6, 2, 0, 0),
+ * new Date(2011, 6, 2, 23, 0)
+ * )
+ * //=> 365
+ * // How many full days are between
+ * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?
+ * const result = differenceInDays(
+ * new Date(2011, 6, 3, 0, 1),
+ * new Date(2011, 6, 2, 23, 59)
+ * )
+ * //=> 0
+ * // How many full days are between
+ * // 1 March 2020 0:00 and 1 June 2020 0:00 ?
+ * // Note: because local time is used, the
+ * // result will always be 92 days, even in
+ * // time zones where DST starts and the
+ * // period has only 92*24-1 hours.
+ * const result = differenceInDays(
+ * new Date(2020, 5, 1),
+ * new Date(2020, 2, 1)
+ * )
+ //=> 92
+ */
+ function differenceInDays(dirtyDateLeft, dirtyDateRight) {
+ requiredArgs(2, arguments);
+ var dateLeft = toDate(dirtyDateLeft);
+ var dateRight = toDate(dirtyDateRight);
+ var sign = compareLocalAsc(dateLeft, dateRight);
+ var difference = Math.abs(differenceInCalendarDays(dateLeft, dateRight));
+ dateLeft.setDate(dateLeft.getDate() - sign * difference);
+
+ // Math.abs(diff in full days - diff in calendar days) === 1 if last calendar day is not full
+ // If so, result must be decreased by 1 in absolute value
+ var isLastDayNotFull = Number(compareLocalAsc(dateLeft, dateRight) === -sign);
+ var result = sign * (difference - isLastDayNotFull);
+ // Prevent negative zero
+ return result === 0 ? 0 : result;
+ }
+
+ /**
+ * @name differenceInMilliseconds
+ * @category Millisecond Helpers
+ * @summary Get the number of milliseconds between the given dates.
+ *
+ * @description
+ * Get the number of milliseconds between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @returns {Number} the number of milliseconds
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many milliseconds are between
+ * // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?
+ * const result = differenceInMilliseconds(
+ * new Date(2014, 6, 2, 12, 30, 21, 700),
+ * new Date(2014, 6, 2, 12, 30, 20, 600)
+ * )
+ * //=> 1100
+ */
+ function differenceInMilliseconds(dateLeft, dateRight) {
+ requiredArgs(2, arguments);
+ return toDate(dateLeft).getTime() - toDate(dateRight).getTime();
+ }
+
+ var roundingMap = {
+ ceil: Math.ceil,
+ round: Math.round,
+ floor: Math.floor,
+ trunc: function trunc(value) {
+ return value < 0 ? Math.ceil(value) : Math.floor(value);
+ } // Math.trunc is not supported by IE
+ };
+ var defaultRoundingMethod = 'trunc';
+ function getRoundingMethod(method) {
+ return method ? roundingMap[method] : roundingMap[defaultRoundingMethod];
+ }
+
+ /**
+ * @name differenceInHours
+ * @category Hour Helpers
+ * @summary Get the number of hours between the given dates.
+ *
+ * @description
+ * Get the number of hours between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @param {Object} [options] - an object with options.
+ * @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
+ * @returns {Number} the number of hours
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many hours are between 2 July 2014 06:50:00 and 2 July 2014 19:00:00?
+ * const result = differenceInHours(
+ * new Date(2014, 6, 2, 19, 0),
+ * new Date(2014, 6, 2, 6, 50)
+ * )
+ * //=> 12
+ */
+ function differenceInHours(dateLeft, dateRight, options) {
+ requiredArgs(2, arguments);
+ var diff = differenceInMilliseconds(dateLeft, dateRight) / millisecondsInHour;
+ return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
+ }
+
+ /**
+ * @name differenceInMinutes
+ * @category Minute Helpers
+ * @summary Get the number of minutes between the given dates.
+ *
+ * @description
+ * Get the signed number of full (rounded towards 0) minutes between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @param {Object} [options] - an object with options.
+ * @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
+ * @returns {Number} the number of minutes
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many minutes are between 2 July 2014 12:07:59 and 2 July 2014 12:20:00?
+ * const result = differenceInMinutes(
+ * new Date(2014, 6, 2, 12, 20, 0),
+ * new Date(2014, 6, 2, 12, 7, 59)
+ * )
+ * //=> 12
+ *
+ * @example
+ * // How many minutes are between 10:01:59 and 10:00:00
+ * const result = differenceInMinutes(
+ * new Date(2000, 0, 1, 10, 0, 0),
+ * new Date(2000, 0, 1, 10, 1, 59)
+ * )
+ * //=> -1
+ */
+ function differenceInMinutes(dateLeft, dateRight, options) {
+ requiredArgs(2, arguments);
+ var diff = differenceInMilliseconds(dateLeft, dateRight) / millisecondsInMinute;
+ return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
+ }
+
+ /**
+ * @name endOfDay
+ * @category Day Helpers
+ * @summary Return the end of a day for the given date.
+ *
+ * @description
+ * Return the end of a day for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the end of a day
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The end of a day for 2 September 2014 11:55:00:
+ * const result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Tue Sep 02 2014 23:59:59.999
+ */
+ function endOfDay(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setHours(23, 59, 59, 999);
+ return date;
+ }
+
+ /**
+ * @name endOfMonth
+ * @category Month Helpers
+ * @summary Return the end of a month for the given date.
+ *
+ * @description
+ * Return the end of a month for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the end of a month
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The end of a month for 2 September 2014 11:55:00:
+ * const result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Tue Sep 30 2014 23:59:59.999
+ */
+ function endOfMonth(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var month = date.getMonth();
+ date.setFullYear(date.getFullYear(), month + 1, 0);
+ date.setHours(23, 59, 59, 999);
+ return date;
+ }
+
+ /**
+ * @name isLastDayOfMonth
+ * @category Month Helpers
+ * @summary Is the given date the last day of a month?
+ *
+ * @description
+ * Is the given date the last day of a month?
+ *
+ * @param {Date|Number} date - the date to check
+ * @returns {Boolean} the date is the last day of a month
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // Is 28 February 2014 the last day of a month?
+ * const result = isLastDayOfMonth(new Date(2014, 1, 28))
+ * //=> true
+ */
+ function isLastDayOfMonth(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ return endOfDay(date).getTime() === endOfMonth(date).getTime();
+ }
+
+ /**
+ * @name differenceInMonths
+ * @category Month Helpers
+ * @summary Get the number of full months between the given dates.
+ *
+ * @description
+ * Get the number of full months between the given dates using trunc as a default rounding method.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @returns {Number} the number of full months
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many full months are between 31 January 2014 and 1 September 2014?
+ * const result = differenceInMonths(new Date(2014, 8, 1), new Date(2014, 0, 31))
+ * //=> 7
+ */
+ function differenceInMonths(dirtyDateLeft, dirtyDateRight) {
+ requiredArgs(2, arguments);
+ var dateLeft = toDate(dirtyDateLeft);
+ var dateRight = toDate(dirtyDateRight);
+ var sign = compareAsc(dateLeft, dateRight);
+ var difference = Math.abs(differenceInCalendarMonths(dateLeft, dateRight));
+ var result;
+
+ // Check for the difference of less than month
+ if (difference < 1) {
+ result = 0;
+ } else {
+ if (dateLeft.getMonth() === 1 && dateLeft.getDate() > 27) {
+ // This will check if the date is end of Feb and assign a higher end of month date
+ // to compare it with Jan
+ dateLeft.setDate(30);
+ }
+ dateLeft.setMonth(dateLeft.getMonth() - sign * difference);
+
+ // Math.abs(diff in full months - diff in calendar months) === 1 if last calendar month is not full
+ // If so, result must be decreased by 1 in absolute value
+ var isLastMonthNotFull = compareAsc(dateLeft, dateRight) === -sign;
+
+ // Check for cases of one full calendar month
+ if (isLastDayOfMonth(toDate(dirtyDateLeft)) && difference === 1 && compareAsc(dirtyDateLeft, dateRight) === 1) {
+ isLastMonthNotFull = false;
+ }
+ result = sign * (difference - Number(isLastMonthNotFull));
+ }
+
+ // Prevent negative zero
+ return result === 0 ? 0 : result;
+ }
+
+ /**
+ * @name differenceInQuarters
+ * @category Quarter Helpers
+ * @summary Get the number of quarters between the given dates.
+ *
+ * @description
+ * Get the number of quarters between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @param {Object} [options] - an object with options.
+ * @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
+ * @returns {Number} the number of full quarters
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many full quarters are between 31 December 2013 and 2 July 2014?
+ * const result = differenceInQuarters(new Date(2014, 6, 2), new Date(2013, 11, 31))
+ * //=> 2
+ */
+ function differenceInQuarters(dateLeft, dateRight, options) {
+ requiredArgs(2, arguments);
+ var diff = differenceInMonths(dateLeft, dateRight) / 3;
+ return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
+ }
+
+ /**
+ * @name differenceInSeconds
+ * @category Second Helpers
+ * @summary Get the number of seconds between the given dates.
+ *
+ * @description
+ * Get the number of seconds between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @param {Object} [options] - an object with options.
+ * @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
+ * @returns {Number} the number of seconds
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many seconds are between
+ * // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?
+ * const result = differenceInSeconds(
+ * new Date(2014, 6, 2, 12, 30, 20, 0),
+ * new Date(2014, 6, 2, 12, 30, 7, 999)
+ * )
+ * //=> 12
+ */
+ function differenceInSeconds(dateLeft, dateRight, options) {
+ requiredArgs(2, arguments);
+ var diff = differenceInMilliseconds(dateLeft, dateRight) / 1000;
+ return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
+ }
+
+ /**
+ * @name differenceInWeeks
+ * @category Week Helpers
+ * @summary Get the number of full weeks between the given dates.
+ *
+ * @description
+ * Get the number of full weeks between two dates. Fractional weeks are
+ * truncated towards zero by default.
+ *
+ * One "full week" is the distance between a local time in one day to the same
+ * local time 7 days earlier or later. A full week can sometimes be less than
+ * or more than 7*24 hours if a daylight savings change happens between two dates.
+ *
+ * To ignore DST and only measure exact 7*24-hour periods, use this instead:
+ * `Math.floor(differenceInHours(dateLeft, dateRight)/(7*24))|0`.
+ *
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @param {Object} [options] - an object with options.
+ * @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
+ * @returns {Number} the number of full weeks
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many full weeks are between 5 July 2014 and 20 July 2014?
+ * const result = differenceInWeeks(new Date(2014, 6, 20), new Date(2014, 6, 5))
+ * //=> 2
+ *
+ * // How many full weeks are between
+ * // 1 March 2020 0:00 and 6 June 2020 0:00 ?
+ * // Note: because local time is used, the
+ * // result will always be 8 weeks (54 days),
+ * // even if DST starts and the period has
+ * // only 54*24-1 hours.
+ * const result = differenceInWeeks(
+ * new Date(2020, 5, 1),
+ * new Date(2020, 2, 6)
+ * )
+ * //=> 8
+ */
+ function differenceInWeeks(dateLeft, dateRight, options) {
+ requiredArgs(2, arguments);
+ var diff = differenceInDays(dateLeft, dateRight) / 7;
+ return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
+ }
+
+ /**
+ * @name differenceInYears
+ * @category Year Helpers
+ * @summary Get the number of full years between the given dates.
+ *
+ * @description
+ * Get the number of full years between the given dates.
+ *
+ * @param {Date|Number} dateLeft - the later date
+ * @param {Date|Number} dateRight - the earlier date
+ * @returns {Number} the number of full years
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // How many full years are between 31 December 2013 and 11 February 2015?
+ * const result = differenceInYears(new Date(2015, 1, 11), new Date(2013, 11, 31))
+ * //=> 1
+ */
+ function differenceInYears(dirtyDateLeft, dirtyDateRight) {
+ requiredArgs(2, arguments);
+ var dateLeft = toDate(dirtyDateLeft);
+ var dateRight = toDate(dirtyDateRight);
+ var sign = compareAsc(dateLeft, dateRight);
+ var difference = Math.abs(differenceInCalendarYears(dateLeft, dateRight));
+
+ // Set both dates to a valid leap year for accurate comparison when dealing
+ // with leap days
+ dateLeft.setFullYear(1584);
+ dateRight.setFullYear(1584);
+
+ // Math.abs(diff in full years - diff in calendar years) === 1 if last calendar year is not full
+ // If so, result must be decreased by 1 in absolute value
+ var isLastYearNotFull = compareAsc(dateLeft, dateRight) === -sign;
+ var result = sign * (difference - Number(isLastYearNotFull));
+ // Prevent negative zero
+ return result === 0 ? 0 : result;
+ }
+
+ /**
+ * @name startOfMinute
+ * @category Minute Helpers
+ * @summary Return the start of a minute for the given date.
+ *
+ * @description
+ * Return the start of a minute for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the start of a minute
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The start of a minute for 1 December 2014 22:15:45.400:
+ * const result = startOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))
+ * //=> Mon Dec 01 2014 22:15:00
+ */
+ function startOfMinute(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setSeconds(0, 0);
+ return date;
+ }
+
+ /**
+ * @name startOfQuarter
+ * @category Quarter Helpers
+ * @summary Return the start of a year quarter for the given date.
+ *
+ * @description
+ * Return the start of a year quarter for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the start of a quarter
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The start of a quarter for 2 September 2014 11:55:00:
+ * const result = startOfQuarter(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Tue Jul 01 2014 00:00:00
+ */
+ function startOfQuarter(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var currentMonth = date.getMonth();
+ var month = currentMonth - currentMonth % 3;
+ date.setMonth(month, 1);
+ date.setHours(0, 0, 0, 0);
+ return date;
+ }
+
+ /**
+ * @name startOfMonth
+ * @category Month Helpers
+ * @summary Return the start of a month for the given date.
+ *
+ * @description
+ * Return the start of a month for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the start of a month
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The start of a month for 2 September 2014 11:55:00:
+ * const result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Mon Sep 01 2014 00:00:00
+ */
+ function startOfMonth(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setDate(1);
+ date.setHours(0, 0, 0, 0);
+ return date;
+ }
+
+ /**
+ * @name endOfYear
+ * @category Year Helpers
+ * @summary Return the end of a year for the given date.
+ *
+ * @description
+ * Return the end of a year for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the end of a year
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The end of a year for 2 September 2014 11:55:00:
+ * const result = endOfYear(new Date(2014, 8, 2, 11, 55, 00))
+ * //=> Wed Dec 31 2014 23:59:59.999
+ */
+ function endOfYear(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var year = date.getFullYear();
+ date.setFullYear(year + 1, 0, 0);
+ date.setHours(23, 59, 59, 999);
+ return date;
+ }
+
+ /**
+ * @name startOfYear
+ * @category Year Helpers
+ * @summary Return the start of a year for the given date.
+ *
+ * @description
+ * Return the start of a year for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the start of a year
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The start of a year for 2 September 2014 11:55:00:
+ * const result = startOfYear(new Date(2014, 8, 2, 11, 55, 00))
+ * //=> Wed Jan 01 2014 00:00:00
+ */
+ function startOfYear(dirtyDate) {
+ requiredArgs(1, arguments);
+ var cleanDate = toDate(dirtyDate);
+ var date = new Date(0);
+ date.setFullYear(cleanDate.getFullYear(), 0, 1);
+ date.setHours(0, 0, 0, 0);
+ return date;
+ }
+
+ /**
+ * @name endOfHour
+ * @category Hour Helpers
+ * @summary Return the end of an hour for the given date.
+ *
+ * @description
+ * Return the end of an hour for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the end of an hour
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The end of an hour for 2 September 2014 11:55:00:
+ * const result = endOfHour(new Date(2014, 8, 2, 11, 55))
+ * //=> Tue Sep 02 2014 11:59:59.999
+ */
+ function endOfHour(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setMinutes(59, 59, 999);
+ return date;
+ }
+
+ /**
+ * @name endOfWeek
+ * @category Week Helpers
+ * @summary Return the end of a week for the given date.
+ *
+ * @description
+ * Return the end of a week for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @param {Object} [options] - an object with options.
+ * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
+ * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
+ * @returns {Date} the end of a week
+ * @throws {TypeError} 1 argument required
+ * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
+ *
+ * @example
+ * // The end of a week for 2 September 2014 11:55:00:
+ * const result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Sat Sep 06 2014 23:59:59.999
+ *
+ * @example
+ * // If the week starts on Monday, the end of the week for 2 September 2014 11:55:00:
+ * const result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
+ * //=> Sun Sep 07 2014 23:59:59.999
+ */
+ function endOfWeek(dirtyDate, options) {
+ var _ref, _ref2, _ref3, _options$weekStartsOn, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;
+ requiredArgs(1, arguments);
+ var defaultOptions = getDefaultOptions();
+ var weekStartsOn = toInteger((_ref = (_ref2 = (_ref3 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.weekStartsOn) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.weekStartsOn) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.weekStartsOn) !== null && _ref !== void 0 ? _ref : 0);
+
+ // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
+ if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
+ throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
+ }
+ var date = toDate(dirtyDate);
+ var day = date.getDay();
+ var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);
+ date.setDate(date.getDate() + diff);
+ date.setHours(23, 59, 59, 999);
+ return date;
+ }
+
+ /**
+ * @name endOfMinute
+ * @category Minute Helpers
+ * @summary Return the end of a minute for the given date.
+ *
+ * @description
+ * Return the end of a minute for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the end of a minute
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The end of a minute for 1 December 2014 22:15:45.400:
+ * const result = endOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))
+ * //=> Mon Dec 01 2014 22:15:59.999
+ */
+ function endOfMinute(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setSeconds(59, 999);
+ return date;
+ }
+
+ /**
+ * @name endOfQuarter
+ * @category Quarter Helpers
+ * @summary Return the end of a year quarter for the given date.
+ *
+ * @description
+ * Return the end of a year quarter for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the end of a quarter
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The end of a quarter for 2 September 2014 11:55:00:
+ * const result = endOfQuarter(new Date(2014, 8, 2, 11, 55, 0))
+ * //=> Tue Sep 30 2014 23:59:59.999
+ */
+ function endOfQuarter(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var currentMonth = date.getMonth();
+ var month = currentMonth - currentMonth % 3 + 3;
+ date.setMonth(month, 0);
+ date.setHours(23, 59, 59, 999);
+ return date;
+ }
+
+ /**
+ * @name endOfSecond
+ * @category Second Helpers
+ * @summary Return the end of a second for the given date.
+ *
+ * @description
+ * Return the end of a second for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the end of a second
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The end of a second for 1 December 2014 22:15:45.400:
+ * const result = endOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))
+ * //=> Mon Dec 01 2014 22:15:45.999
+ */
+ function endOfSecond(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setMilliseconds(999);
+ return date;
+ }
+
+ /**
+ * @name subMilliseconds
+ * @category Millisecond Helpers
+ * @summary Subtract the specified number of milliseconds from the given date.
+ *
+ * @description
+ * Subtract the specified number of milliseconds from the given date.
+ *
+ * @param {Date|Number} date - the date to be changed
+ * @param {Number} amount - the amount of milliseconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
+ * @returns {Date} the new date with the milliseconds subtracted
+ * @throws {TypeError} 2 arguments required
+ *
+ * @example
+ * // Subtract 750 milliseconds from 10 July 2014 12:45:30.000:
+ * const result = subMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)
+ * //=> Thu Jul 10 2014 12:45:29.250
+ */
+ function subMilliseconds(dirtyDate, dirtyAmount) {
+ requiredArgs(2, arguments);
+ var amount = toInteger(dirtyAmount);
+ return addMilliseconds(dirtyDate, -amount);
+ }
+
+ var MILLISECONDS_IN_DAY = 86400000;
+ function getUTCDayOfYear(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var timestamp = date.getTime();
+ date.setUTCMonth(0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ var startOfYearTimestamp = date.getTime();
+ var difference = timestamp - startOfYearTimestamp;
+ return Math.floor(difference / MILLISECONDS_IN_DAY) + 1;
+ }
+
+ function startOfUTCISOWeek(dirtyDate) {
+ requiredArgs(1, arguments);
+ var weekStartsOn = 1;
+ var date = toDate(dirtyDate);
+ var day = date.getUTCDay();
+ var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
+ date.setUTCDate(date.getUTCDate() - diff);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+
+ function getUTCISOWeekYear(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var year = date.getUTCFullYear();
+ var fourthOfJanuaryOfNextYear = new Date(0);
+ fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4);
+ fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0);
+ var startOfNextYear = startOfUTCISOWeek(fourthOfJanuaryOfNextYear);
+ var fourthOfJanuaryOfThisYear = new Date(0);
+ fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4);
+ fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0);
+ var startOfThisYear = startOfUTCISOWeek(fourthOfJanuaryOfThisYear);
+ if (date.getTime() >= startOfNextYear.getTime()) {
+ return year + 1;
+ } else if (date.getTime() >= startOfThisYear.getTime()) {
+ return year;
+ } else {
+ return year - 1;
+ }
+ }
+
+ function startOfUTCISOWeekYear(dirtyDate) {
+ requiredArgs(1, arguments);
+ var year = getUTCISOWeekYear(dirtyDate);
+ var fourthOfJanuary = new Date(0);
+ fourthOfJanuary.setUTCFullYear(year, 0, 4);
+ fourthOfJanuary.setUTCHours(0, 0, 0, 0);
+ var date = startOfUTCISOWeek(fourthOfJanuary);
+ return date;
+ }
+
+ var MILLISECONDS_IN_WEEK$1 = 604800000;
+ function getUTCISOWeek(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var diff = startOfUTCISOWeek(date).getTime() - startOfUTCISOWeekYear(date).getTime();
+
+ // Round the number of days to the nearest integer
+ // because the number of milliseconds in a week is not constant
+ // (e.g. it's different in the week of the daylight saving time clock shift)
+ return Math.round(diff / MILLISECONDS_IN_WEEK$1) + 1;
+ }
+
+ function startOfUTCWeek(dirtyDate, options) {
+ var _ref, _ref2, _ref3, _options$weekStartsOn, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;
+ requiredArgs(1, arguments);
+ var defaultOptions = getDefaultOptions();
+ var weekStartsOn = toInteger((_ref = (_ref2 = (_ref3 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.weekStartsOn) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.weekStartsOn) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.weekStartsOn) !== null && _ref !== void 0 ? _ref : 0);
+
+ // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
+ if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
+ throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
+ }
+ var date = toDate(dirtyDate);
+ var day = date.getUTCDay();
+ var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
+ date.setUTCDate(date.getUTCDate() - diff);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+
+ function getUTCWeekYear(dirtyDate, options) {
+ var _ref, _ref2, _ref3, _options$firstWeekCon, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var year = date.getUTCFullYear();
+ var defaultOptions = getDefaultOptions();
+ var firstWeekContainsDate = toInteger((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1);
+
+ // Test if weekStartsOn is between 1 and 7 _and_ is not NaN
+ if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {
+ throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');
+ }
+ var firstWeekOfNextYear = new Date(0);
+ firstWeekOfNextYear.setUTCFullYear(year + 1, 0, firstWeekContainsDate);
+ firstWeekOfNextYear.setUTCHours(0, 0, 0, 0);
+ var startOfNextYear = startOfUTCWeek(firstWeekOfNextYear, options);
+ var firstWeekOfThisYear = new Date(0);
+ firstWeekOfThisYear.setUTCFullYear(year, 0, firstWeekContainsDate);
+ firstWeekOfThisYear.setUTCHours(0, 0, 0, 0);
+ var startOfThisYear = startOfUTCWeek(firstWeekOfThisYear, options);
+ if (date.getTime() >= startOfNextYear.getTime()) {
+ return year + 1;
+ } else if (date.getTime() >= startOfThisYear.getTime()) {
+ return year;
+ } else {
+ return year - 1;
+ }
+ }
+
+ function startOfUTCWeekYear(dirtyDate, options) {
+ var _ref, _ref2, _ref3, _options$firstWeekCon, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;
+ requiredArgs(1, arguments);
+ var defaultOptions = getDefaultOptions();
+ var firstWeekContainsDate = toInteger((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1);
+ var year = getUTCWeekYear(dirtyDate, options);
+ var firstWeek = new Date(0);
+ firstWeek.setUTCFullYear(year, 0, firstWeekContainsDate);
+ firstWeek.setUTCHours(0, 0, 0, 0);
+ var date = startOfUTCWeek(firstWeek, options);
+ return date;
+ }
+
+ var MILLISECONDS_IN_WEEK = 604800000;
+ function getUTCWeek(dirtyDate, options) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ var diff = startOfUTCWeek(date, options).getTime() - startOfUTCWeekYear(date, options).getTime();
+
+ // Round the number of days to the nearest integer
+ // because the number of milliseconds in a week is not constant
+ // (e.g. it's different in the week of the daylight saving time clock shift)
+ return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;
+ }
+
+ function addLeadingZeros(number, targetLength) {
+ var sign = number < 0 ? '-' : '';
+ var output = Math.abs(number).toString();
+ while (output.length < targetLength) {
+ output = '0' + output;
+ }
+ return sign + output;
+ }
+
+ /*
+ * | | Unit | | Unit |
+ * |-----|--------------------------------|-----|--------------------------------|
+ * | a | AM, PM | A* | |
+ * | d | Day of month | D | |
+ * | h | Hour [1-12] | H | Hour [0-23] |
+ * | m | Minute | M | Month |
+ * | s | Second | S | Fraction of second |
+ * | y | Year (abs) | Y | |
+ *
+ * Letters marked by * are not implemented but reserved by Unicode standard.
+ */
+ var formatters$2 = {
+ // Year
+ y: function y(date, token) {
+ // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens
+ // | Year | y | yy | yyy | yyyy | yyyyy |
+ // |----------|-------|----|-------|-------|-------|
+ // | AD 1 | 1 | 01 | 001 | 0001 | 00001 |
+ // | AD 12 | 12 | 12 | 012 | 0012 | 00012 |
+ // | AD 123 | 123 | 23 | 123 | 0123 | 00123 |
+ // | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 |
+ // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |
+
+ var signedYear = date.getUTCFullYear();
+ // Returns 1 for 1 BC (which is year 0 in JavaScript)
+ var year = signedYear > 0 ? signedYear : 1 - signedYear;
+ return addLeadingZeros(token === 'yy' ? year % 100 : year, token.length);
+ },
+ // Month
+ M: function M(date, token) {
+ var month = date.getUTCMonth();
+ return token === 'M' ? String(month + 1) : addLeadingZeros(month + 1, 2);
+ },
+ // Day of the month
+ d: function d(date, token) {
+ return addLeadingZeros(date.getUTCDate(), token.length);
+ },
+ // AM or PM
+ a: function a(date, token) {
+ var dayPeriodEnumValue = date.getUTCHours() / 12 >= 1 ? 'pm' : 'am';
+ switch (token) {
+ case 'a':
+ case 'aa':
+ return dayPeriodEnumValue.toUpperCase();
+ case 'aaa':
+ return dayPeriodEnumValue;
+ case 'aaaaa':
+ return dayPeriodEnumValue[0];
+ case 'aaaa':
+ default:
+ return dayPeriodEnumValue === 'am' ? 'a.m.' : 'p.m.';
+ }
+ },
+ // Hour [1-12]
+ h: function h(date, token) {
+ return addLeadingZeros(date.getUTCHours() % 12 || 12, token.length);
+ },
+ // Hour [0-23]
+ H: function H(date, token) {
+ return addLeadingZeros(date.getUTCHours(), token.length);
+ },
+ // Minute
+ m: function m(date, token) {
+ return addLeadingZeros(date.getUTCMinutes(), token.length);
+ },
+ // Second
+ s: function s(date, token) {
+ return addLeadingZeros(date.getUTCSeconds(), token.length);
+ },
+ // Fraction of second
+ S: function S(date, token) {
+ var numberOfDigits = token.length;
+ var milliseconds = date.getUTCMilliseconds();
+ var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, numberOfDigits - 3));
+ return addLeadingZeros(fractionalSeconds, token.length);
+ }
+ };
+ var formatters$3 = formatters$2;
+
+ var dayPeriodEnum = {
+ am: 'am',
+ pm: 'pm',
+ midnight: 'midnight',
+ noon: 'noon',
+ morning: 'morning',
+ afternoon: 'afternoon',
+ evening: 'evening',
+ night: 'night'
+ };
+ /*
+ * | | Unit | | Unit |
+ * |-----|--------------------------------|-----|--------------------------------|
+ * | a | AM, PM | A* | Milliseconds in day |
+ * | b | AM, PM, noon, midnight | B | Flexible day period |
+ * | c | Stand-alone local day of week | C* | Localized hour w/ day period |
+ * | d | Day of month | D | Day of year |
+ * | e | Local day of week | E | Day of week |
+ * | f | | F* | Day of week in month |
+ * | g* | Modified Julian day | G | Era |
+ * | h | Hour [1-12] | H | Hour [0-23] |
+ * | i! | ISO day of week | I! | ISO week of year |
+ * | j* | Localized hour w/ day period | J* | Localized hour w/o day period |
+ * | k | Hour [1-24] | K | Hour [0-11] |
+ * | l* | (deprecated) | L | Stand-alone month |
+ * | m | Minute | M | Month |
+ * | n | | N | |
+ * | o! | Ordinal number modifier | O | Timezone (GMT) |
+ * | p! | Long localized time | P! | Long localized date |
+ * | q | Stand-alone quarter | Q | Quarter |
+ * | r* | Related Gregorian year | R! | ISO week-numbering year |
+ * | s | Second | S | Fraction of second |
+ * | t! | Seconds timestamp | T! | Milliseconds timestamp |
+ * | u | Extended year | U* | Cyclic year |
+ * | v* | Timezone (generic non-locat.) | V* | Timezone (location) |
+ * | w | Local week of year | W* | Week of month |
+ * | x | Timezone (ISO-8601 w/o Z) | X | Timezone (ISO-8601) |
+ * | y | Year (abs) | Y | Local week-numbering year |
+ * | z | Timezone (specific non-locat.) | Z* | Timezone (aliases) |
+ *
+ * Letters marked by * are not implemented but reserved by Unicode standard.
+ *
+ * Letters marked by ! are non-standard, but implemented by date-fns:
+ * - `o` modifies the previous token to turn it into an ordinal (see `format` docs)
+ * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,
+ * i.e. 7 for Sunday, 1 for Monday, etc.
+ * - `I` is ISO week of year, as opposed to `w` which is local week of year.
+ * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.
+ * `R` is supposed to be used in conjunction with `I` and `i`
+ * for universal ISO week-numbering date, whereas
+ * `Y` is supposed to be used in conjunction with `w` and `e`
+ * for week-numbering date specific to the locale.
+ * - `P` is long localized date format
+ * - `p` is long localized time format
+ */
+
+ var formatters = {
+ // Era
+ G: function G(date, token, localize) {
+ var era = date.getUTCFullYear() > 0 ? 1 : 0;
+ switch (token) {
+ // AD, BC
+ case 'G':
+ case 'GG':
+ case 'GGG':
+ return localize.era(era, {
+ width: 'abbreviated'
+ });
+ // A, B
+ case 'GGGGG':
+ return localize.era(era, {
+ width: 'narrow'
+ });
+ // Anno Domini, Before Christ
+ case 'GGGG':
+ default:
+ return localize.era(era, {
+ width: 'wide'
+ });
+ }
+ },
+ // Year
+ y: function y(date, token, localize) {
+ // Ordinal number
+ if (token === 'yo') {
+ var signedYear = date.getUTCFullYear();
+ // Returns 1 for 1 BC (which is year 0 in JavaScript)
+ var year = signedYear > 0 ? signedYear : 1 - signedYear;
+ return localize.ordinalNumber(year, {
+ unit: 'year'
+ });
+ }
+ return formatters$3.y(date, token);
+ },
+ // Local week-numbering year
+ Y: function Y(date, token, localize, options) {
+ var signedWeekYear = getUTCWeekYear(date, options);
+ // Returns 1 for 1 BC (which is year 0 in JavaScript)
+ var weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear;
+
+ // Two digit year
+ if (token === 'YY') {
+ var twoDigitYear = weekYear % 100;
+ return addLeadingZeros(twoDigitYear, 2);
+ }
+
+ // Ordinal number
+ if (token === 'Yo') {
+ return localize.ordinalNumber(weekYear, {
+ unit: 'year'
+ });
+ }
+
+ // Padding
+ return addLeadingZeros(weekYear, token.length);
+ },
+ // ISO week-numbering year
+ R: function R(date, token) {
+ var isoWeekYear = getUTCISOWeekYear(date);
+
+ // Padding
+ return addLeadingZeros(isoWeekYear, token.length);
+ },
+ // Extended year. This is a single number designating the year of this calendar system.
+ // The main difference between `y` and `u` localizers are B.C. years:
+ // | Year | `y` | `u` |
+ // |------|-----|-----|
+ // | AC 1 | 1 | 1 |
+ // | BC 1 | 1 | 0 |
+ // | BC 2 | 2 | -1 |
+ // Also `yy` always returns the last two digits of a year,
+ // while `uu` pads single digit years to 2 characters and returns other years unchanged.
+ u: function u(date, token) {
+ var year = date.getUTCFullYear();
+ return addLeadingZeros(year, token.length);
+ },
+ // Quarter
+ Q: function Q(date, token, localize) {
+ var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);
+ switch (token) {
+ // 1, 2, 3, 4
+ case 'Q':
+ return String(quarter);
+ // 01, 02, 03, 04
+ case 'QQ':
+ return addLeadingZeros(quarter, 2);
+ // 1st, 2nd, 3rd, 4th
+ case 'Qo':
+ return localize.ordinalNumber(quarter, {
+ unit: 'quarter'
+ });
+ // Q1, Q2, Q3, Q4
+ case 'QQQ':
+ return localize.quarter(quarter, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ // 1, 2, 3, 4 (narrow quarter; could be not numerical)
+ case 'QQQQQ':
+ return localize.quarter(quarter, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // 1st quarter, 2nd quarter, ...
+ case 'QQQQ':
+ default:
+ return localize.quarter(quarter, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // Stand-alone quarter
+ q: function q(date, token, localize) {
+ var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);
+ switch (token) {
+ // 1, 2, 3, 4
+ case 'q':
+ return String(quarter);
+ // 01, 02, 03, 04
+ case 'qq':
+ return addLeadingZeros(quarter, 2);
+ // 1st, 2nd, 3rd, 4th
+ case 'qo':
+ return localize.ordinalNumber(quarter, {
+ unit: 'quarter'
+ });
+ // Q1, Q2, Q3, Q4
+ case 'qqq':
+ return localize.quarter(quarter, {
+ width: 'abbreviated',
+ context: 'standalone'
+ });
+ // 1, 2, 3, 4 (narrow quarter; could be not numerical)
+ case 'qqqqq':
+ return localize.quarter(quarter, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // 1st quarter, 2nd quarter, ...
+ case 'qqqq':
+ default:
+ return localize.quarter(quarter, {
+ width: 'wide',
+ context: 'standalone'
+ });
+ }
+ },
+ // Month
+ M: function M(date, token, localize) {
+ var month = date.getUTCMonth();
+ switch (token) {
+ case 'M':
+ case 'MM':
+ return formatters$3.M(date, token);
+ // 1st, 2nd, ..., 12th
+ case 'Mo':
+ return localize.ordinalNumber(month + 1, {
+ unit: 'month'
+ });
+ // Jan, Feb, ..., Dec
+ case 'MMM':
+ return localize.month(month, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ // J, F, ..., D
+ case 'MMMMM':
+ return localize.month(month, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // January, February, ..., December
+ case 'MMMM':
+ default:
+ return localize.month(month, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // Stand-alone month
+ L: function L(date, token, localize) {
+ var month = date.getUTCMonth();
+ switch (token) {
+ // 1, 2, ..., 12
+ case 'L':
+ return String(month + 1);
+ // 01, 02, ..., 12
+ case 'LL':
+ return addLeadingZeros(month + 1, 2);
+ // 1st, 2nd, ..., 12th
+ case 'Lo':
+ return localize.ordinalNumber(month + 1, {
+ unit: 'month'
+ });
+ // Jan, Feb, ..., Dec
+ case 'LLL':
+ return localize.month(month, {
+ width: 'abbreviated',
+ context: 'standalone'
+ });
+ // J, F, ..., D
+ case 'LLLLL':
+ return localize.month(month, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // January, February, ..., December
+ case 'LLLL':
+ default:
+ return localize.month(month, {
+ width: 'wide',
+ context: 'standalone'
+ });
+ }
+ },
+ // Local week of year
+ w: function w(date, token, localize, options) {
+ var week = getUTCWeek(date, options);
+ if (token === 'wo') {
+ return localize.ordinalNumber(week, {
+ unit: 'week'
+ });
+ }
+ return addLeadingZeros(week, token.length);
+ },
+ // ISO week of year
+ I: function I(date, token, localize) {
+ var isoWeek = getUTCISOWeek(date);
+ if (token === 'Io') {
+ return localize.ordinalNumber(isoWeek, {
+ unit: 'week'
+ });
+ }
+ return addLeadingZeros(isoWeek, token.length);
+ },
+ // Day of the month
+ d: function d(date, token, localize) {
+ if (token === 'do') {
+ return localize.ordinalNumber(date.getUTCDate(), {
+ unit: 'date'
+ });
+ }
+ return formatters$3.d(date, token);
+ },
+ // Day of year
+ D: function D(date, token, localize) {
+ var dayOfYear = getUTCDayOfYear(date);
+ if (token === 'Do') {
+ return localize.ordinalNumber(dayOfYear, {
+ unit: 'dayOfYear'
+ });
+ }
+ return addLeadingZeros(dayOfYear, token.length);
+ },
+ // Day of week
+ E: function E(date, token, localize) {
+ var dayOfWeek = date.getUTCDay();
+ switch (token) {
+ // Tue
+ case 'E':
+ case 'EE':
+ case 'EEE':
+ return localize.day(dayOfWeek, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ // T
+ case 'EEEEE':
+ return localize.day(dayOfWeek, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // Tu
+ case 'EEEEEE':
+ return localize.day(dayOfWeek, {
+ width: 'short',
+ context: 'formatting'
+ });
+ // Tuesday
+ case 'EEEE':
+ default:
+ return localize.day(dayOfWeek, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // Local day of week
+ e: function e(date, token, localize, options) {
+ var dayOfWeek = date.getUTCDay();
+ var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
+ switch (token) {
+ // Numerical value (Nth day of week with current locale or weekStartsOn)
+ case 'e':
+ return String(localDayOfWeek);
+ // Padded numerical value
+ case 'ee':
+ return addLeadingZeros(localDayOfWeek, 2);
+ // 1st, 2nd, ..., 7th
+ case 'eo':
+ return localize.ordinalNumber(localDayOfWeek, {
+ unit: 'day'
+ });
+ case 'eee':
+ return localize.day(dayOfWeek, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ // T
+ case 'eeeee':
+ return localize.day(dayOfWeek, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // Tu
+ case 'eeeeee':
+ return localize.day(dayOfWeek, {
+ width: 'short',
+ context: 'formatting'
+ });
+ // Tuesday
+ case 'eeee':
+ default:
+ return localize.day(dayOfWeek, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // Stand-alone local day of week
+ c: function c(date, token, localize, options) {
+ var dayOfWeek = date.getUTCDay();
+ var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
+ switch (token) {
+ // Numerical value (same as in `e`)
+ case 'c':
+ return String(localDayOfWeek);
+ // Padded numerical value
+ case 'cc':
+ return addLeadingZeros(localDayOfWeek, token.length);
+ // 1st, 2nd, ..., 7th
+ case 'co':
+ return localize.ordinalNumber(localDayOfWeek, {
+ unit: 'day'
+ });
+ case 'ccc':
+ return localize.day(dayOfWeek, {
+ width: 'abbreviated',
+ context: 'standalone'
+ });
+ // T
+ case 'ccccc':
+ return localize.day(dayOfWeek, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // Tu
+ case 'cccccc':
+ return localize.day(dayOfWeek, {
+ width: 'short',
+ context: 'standalone'
+ });
+ // Tuesday
+ case 'cccc':
+ default:
+ return localize.day(dayOfWeek, {
+ width: 'wide',
+ context: 'standalone'
+ });
+ }
+ },
+ // ISO day of week
+ i: function i(date, token, localize) {
+ var dayOfWeek = date.getUTCDay();
+ var isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;
+ switch (token) {
+ // 2
+ case 'i':
+ return String(isoDayOfWeek);
+ // 02
+ case 'ii':
+ return addLeadingZeros(isoDayOfWeek, token.length);
+ // 2nd
+ case 'io':
+ return localize.ordinalNumber(isoDayOfWeek, {
+ unit: 'day'
+ });
+ // Tue
+ case 'iii':
+ return localize.day(dayOfWeek, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ // T
+ case 'iiiii':
+ return localize.day(dayOfWeek, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // Tu
+ case 'iiiiii':
+ return localize.day(dayOfWeek, {
+ width: 'short',
+ context: 'formatting'
+ });
+ // Tuesday
+ case 'iiii':
+ default:
+ return localize.day(dayOfWeek, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // AM or PM
+ a: function a(date, token, localize) {
+ var hours = date.getUTCHours();
+ var dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';
+ switch (token) {
+ case 'a':
+ case 'aa':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ case 'aaa':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }).toLowerCase();
+ case 'aaaaa':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'aaaa':
+ default:
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // AM, PM, midnight, noon
+ b: function b(date, token, localize) {
+ var hours = date.getUTCHours();
+ var dayPeriodEnumValue;
+ if (hours === 12) {
+ dayPeriodEnumValue = dayPeriodEnum.noon;
+ } else if (hours === 0) {
+ dayPeriodEnumValue = dayPeriodEnum.midnight;
+ } else {
+ dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';
+ }
+ switch (token) {
+ case 'b':
+ case 'bb':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ case 'bbb':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }).toLowerCase();
+ case 'bbbbb':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'bbbb':
+ default:
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // in the morning, in the afternoon, in the evening, at night
+ B: function B(date, token, localize) {
+ var hours = date.getUTCHours();
+ var dayPeriodEnumValue;
+ if (hours >= 17) {
+ dayPeriodEnumValue = dayPeriodEnum.evening;
+ } else if (hours >= 12) {
+ dayPeriodEnumValue = dayPeriodEnum.afternoon;
+ } else if (hours >= 4) {
+ dayPeriodEnumValue = dayPeriodEnum.morning;
+ } else {
+ dayPeriodEnumValue = dayPeriodEnum.night;
+ }
+ switch (token) {
+ case 'B':
+ case 'BB':
+ case 'BBB':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'abbreviated',
+ context: 'formatting'
+ });
+ case 'BBBBB':
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'BBBB':
+ default:
+ return localize.dayPeriod(dayPeriodEnumValue, {
+ width: 'wide',
+ context: 'formatting'
+ });
+ }
+ },
+ // Hour [1-12]
+ h: function h(date, token, localize) {
+ if (token === 'ho') {
+ var hours = date.getUTCHours() % 12;
+ if (hours === 0) hours = 12;
+ return localize.ordinalNumber(hours, {
+ unit: 'hour'
+ });
+ }
+ return formatters$3.h(date, token);
+ },
+ // Hour [0-23]
+ H: function H(date, token, localize) {
+ if (token === 'Ho') {
+ return localize.ordinalNumber(date.getUTCHours(), {
+ unit: 'hour'
+ });
+ }
+ return formatters$3.H(date, token);
+ },
+ // Hour [0-11]
+ K: function K(date, token, localize) {
+ var hours = date.getUTCHours() % 12;
+ if (token === 'Ko') {
+ return localize.ordinalNumber(hours, {
+ unit: 'hour'
+ });
+ }
+ return addLeadingZeros(hours, token.length);
+ },
+ // Hour [1-24]
+ k: function k(date, token, localize) {
+ var hours = date.getUTCHours();
+ if (hours === 0) hours = 24;
+ if (token === 'ko') {
+ return localize.ordinalNumber(hours, {
+ unit: 'hour'
+ });
+ }
+ return addLeadingZeros(hours, token.length);
+ },
+ // Minute
+ m: function m(date, token, localize) {
+ if (token === 'mo') {
+ return localize.ordinalNumber(date.getUTCMinutes(), {
+ unit: 'minute'
+ });
+ }
+ return formatters$3.m(date, token);
+ },
+ // Second
+ s: function s(date, token, localize) {
+ if (token === 'so') {
+ return localize.ordinalNumber(date.getUTCSeconds(), {
+ unit: 'second'
+ });
+ }
+ return formatters$3.s(date, token);
+ },
+ // Fraction of second
+ S: function S(date, token) {
+ return formatters$3.S(date, token);
+ },
+ // Timezone (ISO-8601. If offset is 0, output is always `'Z'`)
+ X: function X(date, token, _localize, options) {
+ var originalDate = options._originalDate || date;
+ var timezoneOffset = originalDate.getTimezoneOffset();
+ if (timezoneOffset === 0) {
+ return 'Z';
+ }
+ switch (token) {
+ // Hours and optional minutes
+ case 'X':
+ return formatTimezoneWithOptionalMinutes(timezoneOffset);
+
+ // Hours, minutes and optional seconds without `:` delimiter
+ // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
+ // so this token always has the same output as `XX`
+ case 'XXXX':
+ case 'XX':
+ // Hours and minutes without `:` delimiter
+ return formatTimezone(timezoneOffset);
+
+ // Hours, minutes and optional seconds with `:` delimiter
+ // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
+ // so this token always has the same output as `XXX`
+ case 'XXXXX':
+ case 'XXX': // Hours and minutes with `:` delimiter
+ default:
+ return formatTimezone(timezoneOffset, ':');
+ }
+ },
+ // Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent)
+ x: function x(date, token, _localize, options) {
+ var originalDate = options._originalDate || date;
+ var timezoneOffset = originalDate.getTimezoneOffset();
+ switch (token) {
+ // Hours and optional minutes
+ case 'x':
+ return formatTimezoneWithOptionalMinutes(timezoneOffset);
+
+ // Hours, minutes and optional seconds without `:` delimiter
+ // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
+ // so this token always has the same output as `xx`
+ case 'xxxx':
+ case 'xx':
+ // Hours and minutes without `:` delimiter
+ return formatTimezone(timezoneOffset);
+
+ // Hours, minutes and optional seconds with `:` delimiter
+ // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
+ // so this token always has the same output as `xxx`
+ case 'xxxxx':
+ case 'xxx': // Hours and minutes with `:` delimiter
+ default:
+ return formatTimezone(timezoneOffset, ':');
+ }
+ },
+ // Timezone (GMT)
+ O: function O(date, token, _localize, options) {
+ var originalDate = options._originalDate || date;
+ var timezoneOffset = originalDate.getTimezoneOffset();
+ switch (token) {
+ // Short
+ case 'O':
+ case 'OO':
+ case 'OOO':
+ return 'GMT' + formatTimezoneShort(timezoneOffset, ':');
+ // Long
+ case 'OOOO':
+ default:
+ return 'GMT' + formatTimezone(timezoneOffset, ':');
+ }
+ },
+ // Timezone (specific non-location)
+ z: function z(date, token, _localize, options) {
+ var originalDate = options._originalDate || date;
+ var timezoneOffset = originalDate.getTimezoneOffset();
+ switch (token) {
+ // Short
+ case 'z':
+ case 'zz':
+ case 'zzz':
+ return 'GMT' + formatTimezoneShort(timezoneOffset, ':');
+ // Long
+ case 'zzzz':
+ default:
+ return 'GMT' + formatTimezone(timezoneOffset, ':');
+ }
+ },
+ // Seconds timestamp
+ t: function t(date, token, _localize, options) {
+ var originalDate = options._originalDate || date;
+ var timestamp = Math.floor(originalDate.getTime() / 1000);
+ return addLeadingZeros(timestamp, token.length);
+ },
+ // Milliseconds timestamp
+ T: function T(date, token, _localize, options) {
+ var originalDate = options._originalDate || date;
+ var timestamp = originalDate.getTime();
+ return addLeadingZeros(timestamp, token.length);
+ }
+ };
+ function formatTimezoneShort(offset, dirtyDelimiter) {
+ var sign = offset > 0 ? '-' : '+';
+ var absOffset = Math.abs(offset);
+ var hours = Math.floor(absOffset / 60);
+ var minutes = absOffset % 60;
+ if (minutes === 0) {
+ return sign + String(hours);
+ }
+ var delimiter = dirtyDelimiter || '';
+ return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2);
+ }
+ function formatTimezoneWithOptionalMinutes(offset, dirtyDelimiter) {
+ if (offset % 60 === 0) {
+ var sign = offset > 0 ? '-' : '+';
+ return sign + addLeadingZeros(Math.abs(offset) / 60, 2);
+ }
+ return formatTimezone(offset, dirtyDelimiter);
+ }
+ function formatTimezone(offset, dirtyDelimiter) {
+ var delimiter = dirtyDelimiter || '';
+ var sign = offset > 0 ? '-' : '+';
+ var absOffset = Math.abs(offset);
+ var hours = addLeadingZeros(Math.floor(absOffset / 60), 2);
+ var minutes = addLeadingZeros(absOffset % 60, 2);
+ return sign + hours + delimiter + minutes;
+ }
+ var formatters$1 = formatters;
+
+ var dateLongFormatter = function dateLongFormatter(pattern, formatLong) {
+ switch (pattern) {
+ case 'P':
+ return formatLong.date({
+ width: 'short'
+ });
+ case 'PP':
+ return formatLong.date({
+ width: 'medium'
+ });
+ case 'PPP':
+ return formatLong.date({
+ width: 'long'
+ });
+ case 'PPPP':
+ default:
+ return formatLong.date({
+ width: 'full'
+ });
+ }
+ };
+ var timeLongFormatter = function timeLongFormatter(pattern, formatLong) {
+ switch (pattern) {
+ case 'p':
+ return formatLong.time({
+ width: 'short'
+ });
+ case 'pp':
+ return formatLong.time({
+ width: 'medium'
+ });
+ case 'ppp':
+ return formatLong.time({
+ width: 'long'
+ });
+ case 'pppp':
+ default:
+ return formatLong.time({
+ width: 'full'
+ });
+ }
+ };
+ var dateTimeLongFormatter = function dateTimeLongFormatter(pattern, formatLong) {
+ var matchResult = pattern.match(/(P+)(p+)?/) || [];
+ var datePattern = matchResult[1];
+ var timePattern = matchResult[2];
+ if (!timePattern) {
+ return dateLongFormatter(pattern, formatLong);
+ }
+ var dateTimeFormat;
+ switch (datePattern) {
+ case 'P':
+ dateTimeFormat = formatLong.dateTime({
+ width: 'short'
+ });
+ break;
+ case 'PP':
+ dateTimeFormat = formatLong.dateTime({
+ width: 'medium'
+ });
+ break;
+ case 'PPP':
+ dateTimeFormat = formatLong.dateTime({
+ width: 'long'
+ });
+ break;
+ case 'PPPP':
+ default:
+ dateTimeFormat = formatLong.dateTime({
+ width: 'full'
+ });
+ break;
+ }
+ return dateTimeFormat.replace('{{date}}', dateLongFormatter(datePattern, formatLong)).replace('{{time}}', timeLongFormatter(timePattern, formatLong));
+ };
+ var longFormatters = {
+ p: timeLongFormatter,
+ P: dateTimeLongFormatter
+ };
+ var longFormatters$1 = longFormatters;
+
+ var protectedDayOfYearTokens = ['D', 'DD'];
+ var protectedWeekYearTokens = ['YY', 'YYYY'];
+ function isProtectedDayOfYearToken(token) {
+ return protectedDayOfYearTokens.indexOf(token) !== -1;
+ }
+ function isProtectedWeekYearToken(token) {
+ return protectedWeekYearTokens.indexOf(token) !== -1;
+ }
+ function throwProtectedError(token, format, input) {
+ if (token === 'YYYY') {
+ throw new RangeError("Use `yyyy` instead of `YYYY` (in `".concat(format, "`) for formatting years to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"));
+ } else if (token === 'YY') {
+ throw new RangeError("Use `yy` instead of `YY` (in `".concat(format, "`) for formatting years to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"));
+ } else if (token === 'D') {
+ throw new RangeError("Use `d` instead of `D` (in `".concat(format, "`) for formatting days of the month to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"));
+ } else if (token === 'DD') {
+ throw new RangeError("Use `dd` instead of `DD` (in `".concat(format, "`) for formatting days of the month to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"));
+ }
+ }
+
+ var formatDistanceLocale = {
+ lessThanXSeconds: {
+ one: 'less than a second',
+ other: 'less than {{count}} seconds'
+ },
+ xSeconds: {
+ one: '1 second',
+ other: '{{count}} seconds'
+ },
+ halfAMinute: 'half a minute',
+ lessThanXMinutes: {
+ one: 'less than a minute',
+ other: 'less than {{count}} minutes'
+ },
+ xMinutes: {
+ one: '1 minute',
+ other: '{{count}} minutes'
+ },
+ aboutXHours: {
+ one: 'about 1 hour',
+ other: 'about {{count}} hours'
+ },
+ xHours: {
+ one: '1 hour',
+ other: '{{count}} hours'
+ },
+ xDays: {
+ one: '1 day',
+ other: '{{count}} days'
+ },
+ aboutXWeeks: {
+ one: 'about 1 week',
+ other: 'about {{count}} weeks'
+ },
+ xWeeks: {
+ one: '1 week',
+ other: '{{count}} weeks'
+ },
+ aboutXMonths: {
+ one: 'about 1 month',
+ other: 'about {{count}} months'
+ },
+ xMonths: {
+ one: '1 month',
+ other: '{{count}} months'
+ },
+ aboutXYears: {
+ one: 'about 1 year',
+ other: 'about {{count}} years'
+ },
+ xYears: {
+ one: '1 year',
+ other: '{{count}} years'
+ },
+ overXYears: {
+ one: 'over 1 year',
+ other: 'over {{count}} years'
+ },
+ almostXYears: {
+ one: 'almost 1 year',
+ other: 'almost {{count}} years'
+ }
+ };
+ var formatDistance = function formatDistance(token, count, options) {
+ var result;
+ var tokenValue = formatDistanceLocale[token];
+ if (typeof tokenValue === 'string') {
+ result = tokenValue;
+ } else if (count === 1) {
+ result = tokenValue.one;
+ } else {
+ result = tokenValue.other.replace('{{count}}', count.toString());
+ }
+ if (options !== null && options !== void 0 && options.addSuffix) {
+ if (options.comparison && options.comparison > 0) {
+ return 'in ' + result;
+ } else {
+ return result + ' ago';
+ }
+ }
+ return result;
+ };
+ var formatDistance$1 = formatDistance;
+
+ function buildFormatLongFn(args) {
+ return function () {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ // TODO: Remove String()
+ var width = options.width ? String(options.width) : args.defaultWidth;
+ var format = args.formats[width] || args.formats[args.defaultWidth];
+ return format;
+ };
+ }
+
+ var dateFormats = {
+ full: 'EEEE, MMMM do, y',
+ "long": 'MMMM do, y',
+ medium: 'MMM d, y',
+ "short": 'MM/dd/yyyy'
+ };
+ var timeFormats = {
+ full: 'h:mm:ss a zzzz',
+ "long": 'h:mm:ss a z',
+ medium: 'h:mm:ss a',
+ "short": 'h:mm a'
+ };
+ var dateTimeFormats = {
+ full: "{{date}} 'at' {{time}}",
+ "long": "{{date}} 'at' {{time}}",
+ medium: '{{date}}, {{time}}',
+ "short": '{{date}}, {{time}}'
+ };
+ var formatLong = {
+ date: buildFormatLongFn({
+ formats: dateFormats,
+ defaultWidth: 'full'
+ }),
+ time: buildFormatLongFn({
+ formats: timeFormats,
+ defaultWidth: 'full'
+ }),
+ dateTime: buildFormatLongFn({
+ formats: dateTimeFormats,
+ defaultWidth: 'full'
+ })
+ };
+ var formatLong$1 = formatLong;
+
+ var formatRelativeLocale = {
+ lastWeek: "'last' eeee 'at' p",
+ yesterday: "'yesterday at' p",
+ today: "'today at' p",
+ tomorrow: "'tomorrow at' p",
+ nextWeek: "eeee 'at' p",
+ other: 'P'
+ };
+ var formatRelative = function formatRelative(token, _date, _baseDate, _options) {
+ return formatRelativeLocale[token];
+ };
+ var formatRelative$1 = formatRelative;
+
+ function buildLocalizeFn(args) {
+ return function (dirtyIndex, options) {
+ var context = options !== null && options !== void 0 && options.context ? String(options.context) : 'standalone';
+ var valuesArray;
+ if (context === 'formatting' && args.formattingValues) {
+ var defaultWidth = args.defaultFormattingWidth || args.defaultWidth;
+ var width = options !== null && options !== void 0 && options.width ? String(options.width) : defaultWidth;
+ valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];
+ } else {
+ var _defaultWidth = args.defaultWidth;
+ var _width = options !== null && options !== void 0 && options.width ? String(options.width) : args.defaultWidth;
+ valuesArray = args.values[_width] || args.values[_defaultWidth];
+ }
+ var index = args.argumentCallback ? args.argumentCallback(dirtyIndex) : dirtyIndex;
+ // @ts-ignore: For some reason TypeScript just don't want to match it, no matter how hard we try. I challenge you to try to remove it!
+ return valuesArray[index];
+ };
+ }
+
+ var eraValues = {
+ narrow: ['B', 'A'],
+ abbreviated: ['BC', 'AD'],
+ wide: ['Before Christ', 'Anno Domini']
+ };
+ var quarterValues = {
+ narrow: ['1', '2', '3', '4'],
+ abbreviated: ['Q1', 'Q2', 'Q3', 'Q4'],
+ wide: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter']
+ };
+
+ // Note: in English, the names of days of the week and months are capitalized.
+ // If you are making a new locale based on this one, check if the same is true for the language you're working on.
+ // Generally, formatted dates should look like they are in the middle of a sentence,
+ // e.g. in Spanish language the weekdays and months should be in the lowercase.
+ var monthValues = {
+ narrow: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
+ abbreviated: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ wide: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
+ };
+ var dayValues = {
+ narrow: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
+ "short": ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+ abbreviated: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ wide: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
+ };
+ var dayPeriodValues = {
+ narrow: {
+ am: 'a',
+ pm: 'p',
+ midnight: 'mi',
+ noon: 'n',
+ morning: 'morning',
+ afternoon: 'afternoon',
+ evening: 'evening',
+ night: 'night'
+ },
+ abbreviated: {
+ am: 'AM',
+ pm: 'PM',
+ midnight: 'midnight',
+ noon: 'noon',
+ morning: 'morning',
+ afternoon: 'afternoon',
+ evening: 'evening',
+ night: 'night'
+ },
+ wide: {
+ am: 'a.m.',
+ pm: 'p.m.',
+ midnight: 'midnight',
+ noon: 'noon',
+ morning: 'morning',
+ afternoon: 'afternoon',
+ evening: 'evening',
+ night: 'night'
+ }
+ };
+ var formattingDayPeriodValues = {
+ narrow: {
+ am: 'a',
+ pm: 'p',
+ midnight: 'mi',
+ noon: 'n',
+ morning: 'in the morning',
+ afternoon: 'in the afternoon',
+ evening: 'in the evening',
+ night: 'at night'
+ },
+ abbreviated: {
+ am: 'AM',
+ pm: 'PM',
+ midnight: 'midnight',
+ noon: 'noon',
+ morning: 'in the morning',
+ afternoon: 'in the afternoon',
+ evening: 'in the evening',
+ night: 'at night'
+ },
+ wide: {
+ am: 'a.m.',
+ pm: 'p.m.',
+ midnight: 'midnight',
+ noon: 'noon',
+ morning: 'in the morning',
+ afternoon: 'in the afternoon',
+ evening: 'in the evening',
+ night: 'at night'
+ }
+ };
+ var ordinalNumber = function ordinalNumber(dirtyNumber, _options) {
+ var number = Number(dirtyNumber);
+
+ // If ordinal numbers depend on context, for example,
+ // if they are different for different grammatical genders,
+ // use `options.unit`.
+ //
+ // `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',
+ // 'day', 'hour', 'minute', 'second'.
+
+ var rem100 = number % 100;
+ if (rem100 > 20 || rem100 < 10) {
+ switch (rem100 % 10) {
+ case 1:
+ return number + 'st';
+ case 2:
+ return number + 'nd';
+ case 3:
+ return number + 'rd';
+ }
+ }
+ return number + 'th';
+ };
+ var localize = {
+ ordinalNumber: ordinalNumber,
+ era: buildLocalizeFn({
+ values: eraValues,
+ defaultWidth: 'wide'
+ }),
+ quarter: buildLocalizeFn({
+ values: quarterValues,
+ defaultWidth: 'wide',
+ argumentCallback: function argumentCallback(quarter) {
+ return quarter - 1;
+ }
+ }),
+ month: buildLocalizeFn({
+ values: monthValues,
+ defaultWidth: 'wide'
+ }),
+ day: buildLocalizeFn({
+ values: dayValues,
+ defaultWidth: 'wide'
+ }),
+ dayPeriod: buildLocalizeFn({
+ values: dayPeriodValues,
+ defaultWidth: 'wide',
+ formattingValues: formattingDayPeriodValues,
+ defaultFormattingWidth: 'wide'
+ })
+ };
+ var localize$1 = localize;
+
+ function buildMatchFn(args) {
+ return function (string) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ var width = options.width;
+ var matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];
+ var matchResult = string.match(matchPattern);
+ if (!matchResult) {
+ return null;
+ }
+ var matchedString = matchResult[0];
+ var parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];
+ var key = Array.isArray(parsePatterns) ? findIndex(parsePatterns, function (pattern) {
+ return pattern.test(matchedString);
+ }) : findKey(parsePatterns, function (pattern) {
+ return pattern.test(matchedString);
+ });
+ var value;
+ value = args.valueCallback ? args.valueCallback(key) : key;
+ value = options.valueCallback ? options.valueCallback(value) : value;
+ var rest = string.slice(matchedString.length);
+ return {
+ value: value,
+ rest: rest
+ };
+ };
+ }
+ function findKey(object, predicate) {
+ for (var key in object) {
+ if (object.hasOwnProperty(key) && predicate(object[key])) {
+ return key;
+ }
+ }
+ return undefined;
+ }
+ function findIndex(array, predicate) {
+ for (var key = 0; key < array.length; key++) {
+ if (predicate(array[key])) {
+ return key;
+ }
+ }
+ return undefined;
+ }
+
+ function buildMatchPatternFn(args) {
+ return function (string) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ var matchResult = string.match(args.matchPattern);
+ if (!matchResult) return null;
+ var matchedString = matchResult[0];
+ var parseResult = string.match(args.parsePattern);
+ if (!parseResult) return null;
+ var value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];
+ value = options.valueCallback ? options.valueCallback(value) : value;
+ var rest = string.slice(matchedString.length);
+ return {
+ value: value,
+ rest: rest
+ };
+ };
+ }
+
+ var matchOrdinalNumberPattern = /^(\d+)(th|st|nd|rd)?/i;
+ var parseOrdinalNumberPattern = /\d+/i;
+ var matchEraPatterns = {
+ narrow: /^(b|a)/i,
+ abbreviated: /^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,
+ wide: /^(before christ|before common era|anno domini|common era)/i
+ };
+ var parseEraPatterns = {
+ any: [/^b/i, /^(a|c)/i]
+ };
+ var matchQuarterPatterns = {
+ narrow: /^[1234]/i,
+ abbreviated: /^q[1234]/i,
+ wide: /^[1234](th|st|nd|rd)? quarter/i
+ };
+ var parseQuarterPatterns = {
+ any: [/1/i, /2/i, /3/i, /4/i]
+ };
+ var matchMonthPatterns = {
+ narrow: /^[jfmasond]/i,
+ abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,
+ wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i
+ };
+ var parseMonthPatterns = {
+ narrow: [/^j/i, /^f/i, /^m/i, /^a/i, /^m/i, /^j/i, /^j/i, /^a/i, /^s/i, /^o/i, /^n/i, /^d/i],
+ any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i]
+ };
+ var matchDayPatterns = {
+ narrow: /^[smtwf]/i,
+ "short": /^(su|mo|tu|we|th|fr|sa)/i,
+ abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,
+ wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i
+ };
+ var parseDayPatterns = {
+ narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],
+ any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i]
+ };
+ var matchDayPeriodPatterns = {
+ narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,
+ any: /^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i
+ };
+ var parseDayPeriodPatterns = {
+ any: {
+ am: /^a/i,
+ pm: /^p/i,
+ midnight: /^mi/i,
+ noon: /^no/i,
+ morning: /morning/i,
+ afternoon: /afternoon/i,
+ evening: /evening/i,
+ night: /night/i
+ }
+ };
+ var match = {
+ ordinalNumber: buildMatchPatternFn({
+ matchPattern: matchOrdinalNumberPattern,
+ parsePattern: parseOrdinalNumberPattern,
+ valueCallback: function valueCallback(value) {
+ return parseInt(value, 10);
+ }
+ }),
+ era: buildMatchFn({
+ matchPatterns: matchEraPatterns,
+ defaultMatchWidth: 'wide',
+ parsePatterns: parseEraPatterns,
+ defaultParseWidth: 'any'
+ }),
+ quarter: buildMatchFn({
+ matchPatterns: matchQuarterPatterns,
+ defaultMatchWidth: 'wide',
+ parsePatterns: parseQuarterPatterns,
+ defaultParseWidth: 'any',
+ valueCallback: function valueCallback(index) {
+ return index + 1;
+ }
+ }),
+ month: buildMatchFn({
+ matchPatterns: matchMonthPatterns,
+ defaultMatchWidth: 'wide',
+ parsePatterns: parseMonthPatterns,
+ defaultParseWidth: 'any'
+ }),
+ day: buildMatchFn({
+ matchPatterns: matchDayPatterns,
+ defaultMatchWidth: 'wide',
+ parsePatterns: parseDayPatterns,
+ defaultParseWidth: 'any'
+ }),
+ dayPeriod: buildMatchFn({
+ matchPatterns: matchDayPeriodPatterns,
+ defaultMatchWidth: 'any',
+ parsePatterns: parseDayPeriodPatterns,
+ defaultParseWidth: 'any'
+ })
+ };
+ var match$1 = match;
+
+ /**
+ * @type {Locale}
+ * @category Locales
+ * @summary English locale (United States).
+ * @language English
+ * @iso-639-2 eng
+ * @author Sasha Koss [@kossnocorp]{@link https://github.com/kossnocorp}
+ * @author Lesha Koss [@leshakoss]{@link https://github.com/leshakoss}
+ */
+ var locale = {
+ code: 'en-US',
+ formatDistance: formatDistance$1,
+ formatLong: formatLong$1,
+ formatRelative: formatRelative$1,
+ localize: localize$1,
+ match: match$1,
+ options: {
+ weekStartsOn: 0 /* Sunday */,
+ firstWeekContainsDate: 1
+ }
+ };
+ var defaultLocale = locale;
+
+ // - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token
+ // (one of the certain letters followed by `o`)
+ // - (\w)\1* matches any sequences of the same letter
+ // - '' matches two quote characters in a row
+ // - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),
+ // except a single quote symbol, which ends the sequence.
+ // Two quote characters do not end the sequence.
+ // If there is no matching single quote
+ // then the sequence will continue until the end of the string.
+ // - . matches any single character unmatched by previous parts of the RegExps
+ var formattingTokensRegExp$1 = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g;
+
+ // This RegExp catches symbols escaped by quotes, and also
+ // sequences of symbols P, p, and the combinations like `PPPPPPPppppp`
+ var longFormattingTokensRegExp$1 = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;
+ var escapedStringRegExp$1 = /^'([^]*?)'?$/;
+ var doubleQuoteRegExp$1 = /''/g;
+ var unescapedLatinCharacterRegExp$1 = /[a-zA-Z]/;
+
+ /**
+ * @name format
+ * @category Common Helpers
+ * @summary Format the date.
+ *
+ * @description
+ * Return the formatted date string in the given format. The result may vary by locale.
+ *
+ * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.
+ * > See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ *
+ * The characters wrapped between two single quotes characters (') are escaped.
+ * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.
+ * (see the last example)
+ *
+ * Format of the string is based on Unicode Technical Standard #35:
+ * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
+ * with a few additions (see note 7 below the table).
+ *
+ * Accepted patterns:
+ * | Unit | Pattern | Result examples | Notes |
+ * |---------------------------------|---------|-----------------------------------|-------|
+ * | Era | G..GGG | AD, BC | |
+ * | | GGGG | Anno Domini, Before Christ | 2 |
+ * | | GGGGG | A, B | |
+ * | Calendar year | y | 44, 1, 1900, 2017 | 5 |
+ * | | yo | 44th, 1st, 0th, 17th | 5,7 |
+ * | | yy | 44, 01, 00, 17 | 5 |
+ * | | yyy | 044, 001, 1900, 2017 | 5 |
+ * | | yyyy | 0044, 0001, 1900, 2017 | 5 |
+ * | | yyyyy | ... | 3,5 |
+ * | Local week-numbering year | Y | 44, 1, 1900, 2017 | 5 |
+ * | | Yo | 44th, 1st, 1900th, 2017th | 5,7 |
+ * | | YY | 44, 01, 00, 17 | 5,8 |
+ * | | YYY | 044, 001, 1900, 2017 | 5 |
+ * | | YYYY | 0044, 0001, 1900, 2017 | 5,8 |
+ * | | YYYYY | ... | 3,5 |
+ * | ISO week-numbering year | R | -43, 0, 1, 1900, 2017 | 5,7 |
+ * | | RR | -43, 00, 01, 1900, 2017 | 5,7 |
+ * | | RRR | -043, 000, 001, 1900, 2017 | 5,7 |
+ * | | RRRR | -0043, 0000, 0001, 1900, 2017 | 5,7 |
+ * | | RRRRR | ... | 3,5,7 |
+ * | Extended year | u | -43, 0, 1, 1900, 2017 | 5 |
+ * | | uu | -43, 01, 1900, 2017 | 5 |
+ * | | uuu | -043, 001, 1900, 2017 | 5 |
+ * | | uuuu | -0043, 0001, 1900, 2017 | 5 |
+ * | | uuuuu | ... | 3,5 |
+ * | Quarter (formatting) | Q | 1, 2, 3, 4 | |
+ * | | Qo | 1st, 2nd, 3rd, 4th | 7 |
+ * | | QQ | 01, 02, 03, 04 | |
+ * | | QQQ | Q1, Q2, Q3, Q4 | |
+ * | | QQQQ | 1st quarter, 2nd quarter, ... | 2 |
+ * | | QQQQQ | 1, 2, 3, 4 | 4 |
+ * | Quarter (stand-alone) | q | 1, 2, 3, 4 | |
+ * | | qo | 1st, 2nd, 3rd, 4th | 7 |
+ * | | qq | 01, 02, 03, 04 | |
+ * | | qqq | Q1, Q2, Q3, Q4 | |
+ * | | qqqq | 1st quarter, 2nd quarter, ... | 2 |
+ * | | qqqqq | 1, 2, 3, 4 | 4 |
+ * | Month (formatting) | M | 1, 2, ..., 12 | |
+ * | | Mo | 1st, 2nd, ..., 12th | 7 |
+ * | | MM | 01, 02, ..., 12 | |
+ * | | MMM | Jan, Feb, ..., Dec | |
+ * | | MMMM | January, February, ..., December | 2 |
+ * | | MMMMM | J, F, ..., D | |
+ * | Month (stand-alone) | L | 1, 2, ..., 12 | |
+ * | | Lo | 1st, 2nd, ..., 12th | 7 |
+ * | | LL | 01, 02, ..., 12 | |
+ * | | LLL | Jan, Feb, ..., Dec | |
+ * | | LLLL | January, February, ..., December | 2 |
+ * | | LLLLL | J, F, ..., D | |
+ * | Local week of year | w | 1, 2, ..., 53 | |
+ * | | wo | 1st, 2nd, ..., 53th | 7 |
+ * | | ww | 01, 02, ..., 53 | |
+ * | ISO week of year | I | 1, 2, ..., 53 | 7 |
+ * | | Io | 1st, 2nd, ..., 53th | 7 |
+ * | | II | 01, 02, ..., 53 | 7 |
+ * | Day of month | d | 1, 2, ..., 31 | |
+ * | | do | 1st, 2nd, ..., 31st | 7 |
+ * | | dd | 01, 02, ..., 31 | |
+ * | Day of year | D | 1, 2, ..., 365, 366 | 9 |
+ * | | Do | 1st, 2nd, ..., 365th, 366th | 7 |
+ * | | DD | 01, 02, ..., 365, 366 | 9 |
+ * | | DDD | 001, 002, ..., 365, 366 | |
+ * | | DDDD | ... | 3 |
+ * | Day of week (formatting) | E..EEE | Mon, Tue, Wed, ..., Sun | |
+ * | | EEEE | Monday, Tuesday, ..., Sunday | 2 |
+ * | | EEEEE | M, T, W, T, F, S, S | |
+ * | | EEEEEE | Mo, Tu, We, Th, Fr, Sa, Su | |
+ * | ISO day of week (formatting) | i | 1, 2, 3, ..., 7 | 7 |
+ * | | io | 1st, 2nd, ..., 7th | 7 |
+ * | | ii | 01, 02, ..., 07 | 7 |
+ * | | iii | Mon, Tue, Wed, ..., Sun | 7 |
+ * | | iiii | Monday, Tuesday, ..., Sunday | 2,7 |
+ * | | iiiii | M, T, W, T, F, S, S | 7 |
+ * | | iiiiii | Mo, Tu, We, Th, Fr, Sa, Su | 7 |
+ * | Local day of week (formatting) | e | 2, 3, 4, ..., 1 | |
+ * | | eo | 2nd, 3rd, ..., 1st | 7 |
+ * | | ee | 02, 03, ..., 01 | |
+ * | | eee | Mon, Tue, Wed, ..., Sun | |
+ * | | eeee | Monday, Tuesday, ..., Sunday | 2 |
+ * | | eeeee | M, T, W, T, F, S, S | |
+ * | | eeeeee | Mo, Tu, We, Th, Fr, Sa, Su | |
+ * | Local day of week (stand-alone) | c | 2, 3, 4, ..., 1 | |
+ * | | co | 2nd, 3rd, ..., 1st | 7 |
+ * | | cc | 02, 03, ..., 01 | |
+ * | | ccc | Mon, Tue, Wed, ..., Sun | |
+ * | | cccc | Monday, Tuesday, ..., Sunday | 2 |
+ * | | ccccc | M, T, W, T, F, S, S | |
+ * | | cccccc | Mo, Tu, We, Th, Fr, Sa, Su | |
+ * | AM, PM | a..aa | AM, PM | |
+ * | | aaa | am, pm | |
+ * | | aaaa | a.m., p.m. | 2 |
+ * | | aaaaa | a, p | |
+ * | AM, PM, noon, midnight | b..bb | AM, PM, noon, midnight | |
+ * | | bbb | am, pm, noon, midnight | |
+ * | | bbbb | a.m., p.m., noon, midnight | 2 |
+ * | | bbbbb | a, p, n, mi | |
+ * | Flexible day period | B..BBB | at night, in the morning, ... | |
+ * | | BBBB | at night, in the morning, ... | 2 |
+ * | | BBBBB | at night, in the morning, ... | |
+ * | Hour [1-12] | h | 1, 2, ..., 11, 12 | |
+ * | | ho | 1st, 2nd, ..., 11th, 12th | 7 |
+ * | | hh | 01, 02, ..., 11, 12 | |
+ * | Hour [0-23] | H | 0, 1, 2, ..., 23 | |
+ * | | Ho | 0th, 1st, 2nd, ..., 23rd | 7 |
+ * | | HH | 00, 01, 02, ..., 23 | |
+ * | Hour [0-11] | K | 1, 2, ..., 11, 0 | |
+ * | | Ko | 1st, 2nd, ..., 11th, 0th | 7 |
+ * | | KK | 01, 02, ..., 11, 00 | |
+ * | Hour [1-24] | k | 24, 1, 2, ..., 23 | |
+ * | | ko | 24th, 1st, 2nd, ..., 23rd | 7 |
+ * | | kk | 24, 01, 02, ..., 23 | |
+ * | Minute | m | 0, 1, ..., 59 | |
+ * | | mo | 0th, 1st, ..., 59th | 7 |
+ * | | mm | 00, 01, ..., 59 | |
+ * | Second | s | 0, 1, ..., 59 | |
+ * | | so | 0th, 1st, ..., 59th | 7 |
+ * | | ss | 00, 01, ..., 59 | |
+ * | Fraction of second | S | 0, 1, ..., 9 | |
+ * | | SS | 00, 01, ..., 99 | |
+ * | | SSS | 000, 001, ..., 999 | |
+ * | | SSSS | ... | 3 |
+ * | Timezone (ISO-8601 w/ Z) | X | -08, +0530, Z | |
+ * | | XX | -0800, +0530, Z | |
+ * | | XXX | -08:00, +05:30, Z | |
+ * | | XXXX | -0800, +0530, Z, +123456 | 2 |
+ * | | XXXXX | -08:00, +05:30, Z, +12:34:56 | |
+ * | Timezone (ISO-8601 w/o Z) | x | -08, +0530, +00 | |
+ * | | xx | -0800, +0530, +0000 | |
+ * | | xxx | -08:00, +05:30, +00:00 | 2 |
+ * | | xxxx | -0800, +0530, +0000, +123456 | |
+ * | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | |
+ * | Timezone (GMT) | O...OOO | GMT-8, GMT+5:30, GMT+0 | |
+ * | | OOOO | GMT-08:00, GMT+05:30, GMT+00:00 | 2 |
+ * | Timezone (specific non-locat.) | z...zzz | GMT-8, GMT+5:30, GMT+0 | 6 |
+ * | | zzzz | GMT-08:00, GMT+05:30, GMT+00:00 | 2,6 |
+ * | Seconds timestamp | t | 512969520 | 7 |
+ * | | tt | ... | 3,7 |
+ * | Milliseconds timestamp | T | 512969520900 | 7 |
+ * | | TT | ... | 3,7 |
+ * | Long localized date | P | 04/29/1453 | 7 |
+ * | | PP | Apr 29, 1453 | 7 |
+ * | | PPP | April 29th, 1453 | 7 |
+ * | | PPPP | Friday, April 29th, 1453 | 2,7 |
+ * | Long localized time | p | 12:00 AM | 7 |
+ * | | pp | 12:00:00 AM | 7 |
+ * | | ppp | 12:00:00 AM GMT+2 | 7 |
+ * | | pppp | 12:00:00 AM GMT+02:00 | 2,7 |
+ * | Combination of date and time | Pp | 04/29/1453, 12:00 AM | 7 |
+ * | | PPpp | Apr 29, 1453, 12:00:00 AM | 7 |
+ * | | PPPppp | April 29th, 1453 at ... | 7 |
+ * | | PPPPpppp| Friday, April 29th, 1453 at ... | 2,7 |
+ * Notes:
+ * 1. "Formatting" units (e.g. formatting quarter) in the default en-US locale
+ * are the same as "stand-alone" units, but are different in some languages.
+ * "Formatting" units are declined according to the rules of the language
+ * in the context of a date. "Stand-alone" units are always nominative singular:
+ *
+ * `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`
+ *
+ * `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`
+ *
+ * 2. Any sequence of the identical letters is a pattern, unless it is escaped by
+ * the single quote characters (see below).
+ * If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`)
+ * the output will be the same as default pattern for this unit, usually
+ * the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units
+ * are marked with "2" in the last column of the table.
+ *
+ * `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'`
+ *
+ * `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'`
+ *
+ * `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'`
+ *
+ * `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'`
+ *
+ * `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'`
+ *
+ * 3. Some patterns could be unlimited length (such as `yyyyyyyy`).
+ * The output will be padded with zeros to match the length of the pattern.
+ *
+ * `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'`
+ *
+ * 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.
+ * These tokens represent the shortest form of the quarter.
+ *
+ * 5. The main difference between `y` and `u` patterns are B.C. years:
+ *
+ * | Year | `y` | `u` |
+ * |------|-----|-----|
+ * | AC 1 | 1 | 1 |
+ * | BC 1 | 1 | 0 |
+ * | BC 2 | 2 | -1 |
+ *
+ * Also `yy` always returns the last two digits of a year,
+ * while `uu` pads single digit years to 2 characters and returns other years unchanged:
+ *
+ * | Year | `yy` | `uu` |
+ * |------|------|------|
+ * | 1 | 01 | 01 |
+ * | 14 | 14 | 14 |
+ * | 376 | 76 | 376 |
+ * | 1453 | 53 | 1453 |
+ *
+ * The same difference is true for local and ISO week-numbering years (`Y` and `R`),
+ * except local week-numbering years are dependent on `options.weekStartsOn`
+ * and `options.firstWeekContainsDate` (compare [getISOWeekYear]{@link https://date-fns.org/docs/getISOWeekYear}
+ * and [getWeekYear]{@link https://date-fns.org/docs/getWeekYear}).
+ *
+ * 6. Specific non-location timezones are currently unavailable in `date-fns`,
+ * so right now these tokens fall back to GMT timezones.
+ *
+ * 7. These patterns are not in the Unicode Technical Standard #35:
+ * - `i`: ISO day of week
+ * - `I`: ISO week of year
+ * - `R`: ISO week-numbering year
+ * - `t`: seconds timestamp
+ * - `T`: milliseconds timestamp
+ * - `o`: ordinal number modifier
+ * - `P`: long localized date
+ * - `p`: long localized time
+ *
+ * 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.
+ * You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ *
+ * 9. `D` and `DD` tokens represent days of the year but they are often confused with days of the month.
+ * You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ *
+ * @param {Date|Number} date - the original date
+ * @param {String} format - the string of tokens
+ * @param {Object} [options] - an object with options.
+ * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
+ * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
+ * @param {Number} [options.firstWeekContainsDate=1] - the day of January, which is
+ * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;
+ * see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;
+ * see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @returns {String} the formatted date string
+ * @throws {TypeError} 2 arguments required
+ * @throws {RangeError} `date` must not be Invalid Date
+ * @throws {RangeError} `options.locale` must contain `localize` property
+ * @throws {RangeError} `options.locale` must contain `formatLong` property
+ * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
+ * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7
+ * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} format string contains an unescaped latin alphabet character
+ *
+ * @example
+ * // Represent 11 February 2014 in middle-endian format:
+ * const result = format(new Date(2014, 1, 11), 'MM/dd/yyyy')
+ * //=> '02/11/2014'
+ *
+ * @example
+ * // Represent 2 July 2014 in Esperanto:
+ * import { eoLocale } from 'date-fns/locale/eo'
+ * const result = format(new Date(2014, 6, 2), "do 'de' MMMM yyyy", {
+ * locale: eoLocale
+ * })
+ * //=> '2-a de julio 2014'
+ *
+ * @example
+ * // Escape string by single quote characters:
+ * const result = format(new Date(2014, 6, 2, 15), "h 'o''clock'")
+ * //=> "3 o'clock"
+ */
+
+ function format(dirtyDate, dirtyFormatStr, options) {
+ var _ref, _options$locale, _ref2, _ref3, _ref4, _options$firstWeekCon, _options$locale2, _options$locale2$opti, _defaultOptions$local, _defaultOptions$local2, _ref5, _ref6, _ref7, _options$weekStartsOn, _options$locale3, _options$locale3$opti, _defaultOptions$local3, _defaultOptions$local4;
+ requiredArgs(2, arguments);
+ var formatStr = String(dirtyFormatStr);
+ var defaultOptions = getDefaultOptions();
+ var locale = (_ref = (_options$locale = options === null || options === void 0 ? void 0 : options.locale) !== null && _options$locale !== void 0 ? _options$locale : defaultOptions.locale) !== null && _ref !== void 0 ? _ref : defaultLocale;
+ var firstWeekContainsDate = toInteger((_ref2 = (_ref3 = (_ref4 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale2 = options.locale) === null || _options$locale2 === void 0 ? void 0 : (_options$locale2$opti = _options$locale2.options) === null || _options$locale2$opti === void 0 ? void 0 : _options$locale2$opti.firstWeekContainsDate) !== null && _ref4 !== void 0 ? _ref4 : defaultOptions.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : 1);
+
+ // Test if weekStartsOn is between 1 and 7 _and_ is not NaN
+ if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {
+ throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');
+ }
+ var weekStartsOn = toInteger((_ref5 = (_ref6 = (_ref7 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale3 = options.locale) === null || _options$locale3 === void 0 ? void 0 : (_options$locale3$opti = _options$locale3.options) === null || _options$locale3$opti === void 0 ? void 0 : _options$locale3$opti.weekStartsOn) !== null && _ref7 !== void 0 ? _ref7 : defaultOptions.weekStartsOn) !== null && _ref6 !== void 0 ? _ref6 : (_defaultOptions$local3 = defaultOptions.locale) === null || _defaultOptions$local3 === void 0 ? void 0 : (_defaultOptions$local4 = _defaultOptions$local3.options) === null || _defaultOptions$local4 === void 0 ? void 0 : _defaultOptions$local4.weekStartsOn) !== null && _ref5 !== void 0 ? _ref5 : 0);
+
+ // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
+ if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
+ throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
+ }
+ if (!locale.localize) {
+ throw new RangeError('locale must contain localize property');
+ }
+ if (!locale.formatLong) {
+ throw new RangeError('locale must contain formatLong property');
+ }
+ var originalDate = toDate(dirtyDate);
+ if (!isValid(originalDate)) {
+ throw new RangeError('Invalid time value');
+ }
+
+ // Convert the date in system timezone to the same date in UTC+00:00 timezone.
+ // This ensures that when UTC functions will be implemented, locales will be compatible with them.
+ // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376
+ var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate);
+ var utcDate = subMilliseconds(originalDate, timezoneOffset);
+ var formatterOptions = {
+ firstWeekContainsDate: firstWeekContainsDate,
+ weekStartsOn: weekStartsOn,
+ locale: locale,
+ _originalDate: originalDate
+ };
+ var result = formatStr.match(longFormattingTokensRegExp$1).map(function (substring) {
+ var firstCharacter = substring[0];
+ if (firstCharacter === 'p' || firstCharacter === 'P') {
+ var longFormatter = longFormatters$1[firstCharacter];
+ return longFormatter(substring, locale.formatLong);
+ }
+ return substring;
+ }).join('').match(formattingTokensRegExp$1).map(function (substring) {
+ // Replace two single quote characters with one single quote character
+ if (substring === "''") {
+ return "'";
+ }
+ var firstCharacter = substring[0];
+ if (firstCharacter === "'") {
+ return cleanEscapedString$1(substring);
+ }
+ var formatter = formatters$1[firstCharacter];
+ if (formatter) {
+ if (!(options !== null && options !== void 0 && options.useAdditionalWeekYearTokens) && isProtectedWeekYearToken(substring)) {
+ throwProtectedError(substring, dirtyFormatStr, String(dirtyDate));
+ }
+ if (!(options !== null && options !== void 0 && options.useAdditionalDayOfYearTokens) && isProtectedDayOfYearToken(substring)) {
+ throwProtectedError(substring, dirtyFormatStr, String(dirtyDate));
+ }
+ return formatter(utcDate, substring, locale.localize, formatterOptions);
+ }
+ if (firstCharacter.match(unescapedLatinCharacterRegExp$1)) {
+ throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');
+ }
+ return substring;
+ }).join('');
+ return result;
+ }
+ function cleanEscapedString$1(input) {
+ var matched = input.match(escapedStringRegExp$1);
+ if (!matched) {
+ return input;
+ }
+ return matched[1].replace(doubleQuoteRegExp$1, "'");
+ }
+
+ function assign(target, object) {
+ if (target == null) {
+ throw new TypeError('assign requires that input parameter not be null or undefined');
+ }
+ for (var property in object) {
+ if (Object.prototype.hasOwnProperty.call(object, property)) {
+ target[property] = object[property];
+ }
+ }
+ return target;
+ }
+
+ function _arrayLikeToArray(r, a) {
+ (null == a || a > r.length) && (a = r.length);
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
+ return n;
+ }
+
+ function _unsupportedIterableToArray(r, a) {
+ if (r) {
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
+ var t = {}.toString.call(r).slice(8, -1);
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
+ }
+ }
+
+ function _createForOfIteratorHelper(r, e) {
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
+ if (!t) {
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
+ t && (r = t);
+ var _n = 0,
+ F = function F() {};
+ return {
+ s: F,
+ n: function n() {
+ return _n >= r.length ? {
+ done: !0
+ } : {
+ done: !1,
+ value: r[_n++]
+ };
+ },
+ e: function e(r) {
+ throw r;
+ },
+ f: F
+ };
+ }
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+ var o,
+ a = !0,
+ u = !1;
+ return {
+ s: function s() {
+ t = t.call(r);
+ },
+ n: function n() {
+ var r = t.next();
+ return a = r.done, r;
+ },
+ e: function e(r) {
+ u = !0, o = r;
+ },
+ f: function f() {
+ try {
+ a || null == t["return"] || t["return"]();
+ } finally {
+ if (u) throw o;
+ }
+ }
+ };
+ }
+
+ function _assertThisInitialized(e) {
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ return e;
+ }
+
+ function _setPrototypeOf(t, e) {
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
+ return t.__proto__ = e, t;
+ }, _setPrototypeOf(t, e);
+ }
+
+ function _inherits(t, e) {
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
+ t.prototype = Object.create(e && e.prototype, {
+ constructor: {
+ value: t,
+ writable: !0,
+ configurable: !0
+ }
+ }), Object.defineProperty(t, "prototype", {
+ writable: !1
+ }), e && _setPrototypeOf(t, e);
+ }
+
+ function _getPrototypeOf(t) {
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
+ return t.__proto__ || Object.getPrototypeOf(t);
+ }, _getPrototypeOf(t);
+ }
+
+ function _isNativeReflectConstruct() {
+ try {
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
+ } catch (t) {}
+ return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
+ return !!t;
+ })();
+ }
+
+ function _possibleConstructorReturn(t, e) {
+ if (e && ("object" == _typeof(e) || "function" == typeof e)) return e;
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
+ return _assertThisInitialized(t);
+ }
+
+ function _createSuper(t) {
+ var r = _isNativeReflectConstruct();
+ return function () {
+ var e,
+ o = _getPrototypeOf(t);
+ if (r) {
+ var s = _getPrototypeOf(this).constructor;
+ e = Reflect.construct(o, arguments, s);
+ } else e = o.apply(this, arguments);
+ return _possibleConstructorReturn(this, e);
+ };
+ }
+
+ function _classCallCheck(a, n) {
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
+ }
+
+ function toPrimitive(t, r) {
+ if ("object" != _typeof(t) || !t) return t;
+ var e = t[Symbol.toPrimitive];
+ if (void 0 !== e) {
+ var i = e.call(t, r || "default");
+ if ("object" != _typeof(i)) return i;
+ throw new TypeError("@@toPrimitive must return a primitive value.");
+ }
+ return ("string" === r ? String : Number)(t);
+ }
+
+ function toPropertyKey(t) {
+ var i = toPrimitive(t, "string");
+ return "symbol" == _typeof(i) ? i : i + "";
+ }
+
+ function _defineProperties(e, r) {
+ for (var t = 0; t < r.length; t++) {
+ var o = r[t];
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, toPropertyKey(o.key), o);
+ }
+ }
+ function _createClass(e, r, t) {
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
+ writable: !1
+ }), e;
+ }
+
+ function _defineProperty(e, r, t) {
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
+ value: t,
+ enumerable: !0,
+ configurable: !0,
+ writable: !0
+ }) : e[r] = t, e;
+ }
+
+ var TIMEZONE_UNIT_PRIORITY = 10;
+ var Setter = /*#__PURE__*/function () {
+ function Setter() {
+ _classCallCheck(this, Setter);
+ _defineProperty(this, "priority", void 0);
+ _defineProperty(this, "subPriority", 0);
+ }
+ _createClass(Setter, [{
+ key: "validate",
+ value: function validate(_utcDate, _options) {
+ return true;
+ }
+ }]);
+ return Setter;
+ }();
+ var ValueSetter = /*#__PURE__*/function (_Setter) {
+ _inherits(ValueSetter, _Setter);
+ var _super = _createSuper(ValueSetter);
+ function ValueSetter(value, validateValue, setValue, priority, subPriority) {
+ var _this;
+ _classCallCheck(this, ValueSetter);
+ _this = _super.call(this);
+ _this.value = value;
+ _this.validateValue = validateValue;
+ _this.setValue = setValue;
+ _this.priority = priority;
+ if (subPriority) {
+ _this.subPriority = subPriority;
+ }
+ return _this;
+ }
+ _createClass(ValueSetter, [{
+ key: "validate",
+ value: function validate(utcDate, options) {
+ return this.validateValue(utcDate, this.value, options);
+ }
+ }, {
+ key: "set",
+ value: function set(utcDate, flags, options) {
+ return this.setValue(utcDate, flags, this.value, options);
+ }
+ }]);
+ return ValueSetter;
+ }(Setter);
+ var DateToSystemTimezoneSetter = /*#__PURE__*/function (_Setter2) {
+ _inherits(DateToSystemTimezoneSetter, _Setter2);
+ var _super2 = _createSuper(DateToSystemTimezoneSetter);
+ function DateToSystemTimezoneSetter() {
+ var _this2;
+ _classCallCheck(this, DateToSystemTimezoneSetter);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this2 = _super2.call.apply(_super2, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this2), "priority", TIMEZONE_UNIT_PRIORITY);
+ _defineProperty(_assertThisInitialized(_this2), "subPriority", -1);
+ return _this2;
+ }
+ _createClass(DateToSystemTimezoneSetter, [{
+ key: "set",
+ value: function set(date, flags) {
+ if (flags.timestampIsSet) {
+ return date;
+ }
+ var convertedDate = new Date(0);
+ convertedDate.setFullYear(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
+ convertedDate.setHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
+ return convertedDate;
+ }
+ }]);
+ return DateToSystemTimezoneSetter;
+ }(Setter);
+
+ var Parser = /*#__PURE__*/function () {
+ function Parser() {
+ _classCallCheck(this, Parser);
+ _defineProperty(this, "incompatibleTokens", void 0);
+ _defineProperty(this, "priority", void 0);
+ _defineProperty(this, "subPriority", void 0);
+ }
+ _createClass(Parser, [{
+ key: "run",
+ value: function run(dateString, token, match, options) {
+ var result = this.parse(dateString, token, match, options);
+ if (!result) {
+ return null;
+ }
+ return {
+ setter: new ValueSetter(result.value, this.validate, this.set, this.priority, this.subPriority),
+ rest: result.rest
+ };
+ }
+ }, {
+ key: "validate",
+ value: function validate(_utcDate, _value, _options) {
+ return true;
+ }
+ }]);
+ return Parser;
+ }();
+
+ var EraParser = /*#__PURE__*/function (_Parser) {
+ _inherits(EraParser, _Parser);
+ var _super = _createSuper(EraParser);
+ function EraParser() {
+ var _this;
+ _classCallCheck(this, EraParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 140);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['R', 'u', 't', 'T']);
+ return _this;
+ }
+ _createClass(EraParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ // AD, BC
+ case 'G':
+ case 'GG':
+ case 'GGG':
+ return match.era(dateString, {
+ width: 'abbreviated'
+ }) || match.era(dateString, {
+ width: 'narrow'
+ });
+ // A, B
+ case 'GGGGG':
+ return match.era(dateString, {
+ width: 'narrow'
+ });
+ // Anno Domini, Before Christ
+ case 'GGGG':
+ default:
+ return match.era(dateString, {
+ width: 'wide'
+ }) || match.era(dateString, {
+ width: 'abbreviated'
+ }) || match.era(dateString, {
+ width: 'narrow'
+ });
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, flags, value) {
+ flags.era = value;
+ date.setUTCFullYear(value, 0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return EraParser;
+ }(Parser);
+
+ var numericPatterns = {
+ month: /^(1[0-2]|0?\d)/,
+ // 0 to 12
+ date: /^(3[0-1]|[0-2]?\d)/,
+ // 0 to 31
+ dayOfYear: /^(36[0-6]|3[0-5]\d|[0-2]?\d?\d)/,
+ // 0 to 366
+ week: /^(5[0-3]|[0-4]?\d)/,
+ // 0 to 53
+ hour23h: /^(2[0-3]|[0-1]?\d)/,
+ // 0 to 23
+ hour24h: /^(2[0-4]|[0-1]?\d)/,
+ // 0 to 24
+ hour11h: /^(1[0-1]|0?\d)/,
+ // 0 to 11
+ hour12h: /^(1[0-2]|0?\d)/,
+ // 0 to 12
+ minute: /^[0-5]?\d/,
+ // 0 to 59
+ second: /^[0-5]?\d/,
+ // 0 to 59
+
+ singleDigit: /^\d/,
+ // 0 to 9
+ twoDigits: /^\d{1,2}/,
+ // 0 to 99
+ threeDigits: /^\d{1,3}/,
+ // 0 to 999
+ fourDigits: /^\d{1,4}/,
+ // 0 to 9999
+
+ anyDigitsSigned: /^-?\d+/,
+ singleDigitSigned: /^-?\d/,
+ // 0 to 9, -0 to -9
+ twoDigitsSigned: /^-?\d{1,2}/,
+ // 0 to 99, -0 to -99
+ threeDigitsSigned: /^-?\d{1,3}/,
+ // 0 to 999, -0 to -999
+ fourDigitsSigned: /^-?\d{1,4}/ // 0 to 9999, -0 to -9999
+ };
+ var timezonePatterns = {
+ basicOptionalMinutes: /^([+-])(\d{2})(\d{2})?|Z/,
+ basic: /^([+-])(\d{2})(\d{2})|Z/,
+ basicOptionalSeconds: /^([+-])(\d{2})(\d{2})((\d{2}))?|Z/,
+ extended: /^([+-])(\d{2}):(\d{2})|Z/,
+ extendedOptionalSeconds: /^([+-])(\d{2}):(\d{2})(:(\d{2}))?|Z/
+ };
+
+ function mapValue(parseFnResult, mapFn) {
+ if (!parseFnResult) {
+ return parseFnResult;
+ }
+ return {
+ value: mapFn(parseFnResult.value),
+ rest: parseFnResult.rest
+ };
+ }
+ function parseNumericPattern(pattern, dateString) {
+ var matchResult = dateString.match(pattern);
+ if (!matchResult) {
+ return null;
+ }
+ return {
+ value: parseInt(matchResult[0], 10),
+ rest: dateString.slice(matchResult[0].length)
+ };
+ }
+ function parseTimezonePattern(pattern, dateString) {
+ var matchResult = dateString.match(pattern);
+ if (!matchResult) {
+ return null;
+ }
+
+ // Input is 'Z'
+ if (matchResult[0] === 'Z') {
+ return {
+ value: 0,
+ rest: dateString.slice(1)
+ };
+ }
+ var sign = matchResult[1] === '+' ? 1 : -1;
+ var hours = matchResult[2] ? parseInt(matchResult[2], 10) : 0;
+ var minutes = matchResult[3] ? parseInt(matchResult[3], 10) : 0;
+ var seconds = matchResult[5] ? parseInt(matchResult[5], 10) : 0;
+ return {
+ value: sign * (hours * millisecondsInHour + minutes * millisecondsInMinute + seconds * millisecondsInSecond),
+ rest: dateString.slice(matchResult[0].length)
+ };
+ }
+ function parseAnyDigitsSigned(dateString) {
+ return parseNumericPattern(numericPatterns.anyDigitsSigned, dateString);
+ }
+ function parseNDigits(n, dateString) {
+ switch (n) {
+ case 1:
+ return parseNumericPattern(numericPatterns.singleDigit, dateString);
+ case 2:
+ return parseNumericPattern(numericPatterns.twoDigits, dateString);
+ case 3:
+ return parseNumericPattern(numericPatterns.threeDigits, dateString);
+ case 4:
+ return parseNumericPattern(numericPatterns.fourDigits, dateString);
+ default:
+ return parseNumericPattern(new RegExp('^\\d{1,' + n + '}'), dateString);
+ }
+ }
+ function parseNDigitsSigned(n, dateString) {
+ switch (n) {
+ case 1:
+ return parseNumericPattern(numericPatterns.singleDigitSigned, dateString);
+ case 2:
+ return parseNumericPattern(numericPatterns.twoDigitsSigned, dateString);
+ case 3:
+ return parseNumericPattern(numericPatterns.threeDigitsSigned, dateString);
+ case 4:
+ return parseNumericPattern(numericPatterns.fourDigitsSigned, dateString);
+ default:
+ return parseNumericPattern(new RegExp('^-?\\d{1,' + n + '}'), dateString);
+ }
+ }
+ function dayPeriodEnumToHours(dayPeriod) {
+ switch (dayPeriod) {
+ case 'morning':
+ return 4;
+ case 'evening':
+ return 17;
+ case 'pm':
+ case 'noon':
+ case 'afternoon':
+ return 12;
+ case 'am':
+ case 'midnight':
+ case 'night':
+ default:
+ return 0;
+ }
+ }
+ function normalizeTwoDigitYear(twoDigitYear, currentYear) {
+ var isCommonEra = currentYear > 0;
+ // Absolute number of the current year:
+ // 1 -> 1 AC
+ // 0 -> 1 BC
+ // -1 -> 2 BC
+ var absCurrentYear = isCommonEra ? currentYear : 1 - currentYear;
+ var result;
+ if (absCurrentYear <= 50) {
+ result = twoDigitYear || 100;
+ } else {
+ var rangeEnd = absCurrentYear + 50;
+ var rangeEndCentury = Math.floor(rangeEnd / 100) * 100;
+ var isPreviousCentury = twoDigitYear >= rangeEnd % 100;
+ result = twoDigitYear + rangeEndCentury - (isPreviousCentury ? 100 : 0);
+ }
+ return isCommonEra ? result : 1 - result;
+ }
+ function isLeapYearIndex$1(year) {
+ return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;
+ }
+
+ // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns
+ // | Year | y | yy | yyy | yyyy | yyyyy |
+ // |----------|-------|----|-------|-------|-------|
+ // | AD 1 | 1 | 01 | 001 | 0001 | 00001 |
+ // | AD 12 | 12 | 12 | 012 | 0012 | 00012 |
+ // | AD 123 | 123 | 23 | 123 | 0123 | 00123 |
+ // | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 |
+ // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |
+ var YearParser = /*#__PURE__*/function (_Parser) {
+ _inherits(YearParser, _Parser);
+ var _super = _createSuper(YearParser);
+ function YearParser() {
+ var _this;
+ _classCallCheck(this, YearParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 130);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['Y', 'R', 'u', 'w', 'I', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(YearParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ var valueCallback = function valueCallback(year) {
+ return {
+ year: year,
+ isTwoDigitYear: token === 'yy'
+ };
+ };
+ switch (token) {
+ case 'y':
+ return mapValue(parseNDigits(4, dateString), valueCallback);
+ case 'yo':
+ return mapValue(match.ordinalNumber(dateString, {
+ unit: 'year'
+ }), valueCallback);
+ default:
+ return mapValue(parseNDigits(token.length, dateString), valueCallback);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value.isTwoDigitYear || value.year > 0;
+ }
+ }, {
+ key: "set",
+ value: function set(date, flags, value) {
+ var currentYear = date.getUTCFullYear();
+ if (value.isTwoDigitYear) {
+ var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);
+ date.setUTCFullYear(normalizedTwoDigitYear, 0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;
+ date.setUTCFullYear(year, 0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return YearParser;
+ }(Parser);
+
+ // Local week-numbering year
+ var LocalWeekYearParser = /*#__PURE__*/function (_Parser) {
+ _inherits(LocalWeekYearParser, _Parser);
+ var _super = _createSuper(LocalWeekYearParser);
+ function LocalWeekYearParser() {
+ var _this;
+ _classCallCheck(this, LocalWeekYearParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 130);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['y', 'R', 'u', 'Q', 'q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']);
+ return _this;
+ }
+ _createClass(LocalWeekYearParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ var valueCallback = function valueCallback(year) {
+ return {
+ year: year,
+ isTwoDigitYear: token === 'YY'
+ };
+ };
+ switch (token) {
+ case 'Y':
+ return mapValue(parseNDigits(4, dateString), valueCallback);
+ case 'Yo':
+ return mapValue(match.ordinalNumber(dateString, {
+ unit: 'year'
+ }), valueCallback);
+ default:
+ return mapValue(parseNDigits(token.length, dateString), valueCallback);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value.isTwoDigitYear || value.year > 0;
+ }
+ }, {
+ key: "set",
+ value: function set(date, flags, value, options) {
+ var currentYear = getUTCWeekYear(date, options);
+ if (value.isTwoDigitYear) {
+ var normalizedTwoDigitYear = normalizeTwoDigitYear(value.year, currentYear);
+ date.setUTCFullYear(normalizedTwoDigitYear, 0, options.firstWeekContainsDate);
+ date.setUTCHours(0, 0, 0, 0);
+ return startOfUTCWeek(date, options);
+ }
+ var year = !('era' in flags) || flags.era === 1 ? value.year : 1 - value.year;
+ date.setUTCFullYear(year, 0, options.firstWeekContainsDate);
+ date.setUTCHours(0, 0, 0, 0);
+ return startOfUTCWeek(date, options);
+ }
+ }]);
+ return LocalWeekYearParser;
+ }(Parser);
+
+ var ISOWeekYearParser = /*#__PURE__*/function (_Parser) {
+ _inherits(ISOWeekYearParser, _Parser);
+ var _super = _createSuper(ISOWeekYearParser);
+ function ISOWeekYearParser() {
+ var _this;
+ _classCallCheck(this, ISOWeekYearParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 130);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['G', 'y', 'Y', 'u', 'Q', 'q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(ISOWeekYearParser, [{
+ key: "parse",
+ value: function parse(dateString, token) {
+ if (token === 'R') {
+ return parseNDigitsSigned(4, dateString);
+ }
+ return parseNDigitsSigned(token.length, dateString);
+ }
+ }, {
+ key: "set",
+ value: function set(_date, _flags, value) {
+ var firstWeekOfYear = new Date(0);
+ firstWeekOfYear.setUTCFullYear(value, 0, 4);
+ firstWeekOfYear.setUTCHours(0, 0, 0, 0);
+ return startOfUTCISOWeek(firstWeekOfYear);
+ }
+ }]);
+ return ISOWeekYearParser;
+ }(Parser);
+
+ var ExtendedYearParser = /*#__PURE__*/function (_Parser) {
+ _inherits(ExtendedYearParser, _Parser);
+ var _super = _createSuper(ExtendedYearParser);
+ function ExtendedYearParser() {
+ var _this;
+ _classCallCheck(this, ExtendedYearParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 130);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['G', 'y', 'Y', 'R', 'w', 'I', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(ExtendedYearParser, [{
+ key: "parse",
+ value: function parse(dateString, token) {
+ if (token === 'u') {
+ return parseNDigitsSigned(4, dateString);
+ }
+ return parseNDigitsSigned(token.length, dateString);
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCFullYear(value, 0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return ExtendedYearParser;
+ }(Parser);
+
+ var QuarterParser = /*#__PURE__*/function (_Parser) {
+ _inherits(QuarterParser, _Parser);
+ var _super = _createSuper(QuarterParser);
+ function QuarterParser() {
+ var _this;
+ _classCallCheck(this, QuarterParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 120);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['Y', 'R', 'q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(QuarterParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ // 1, 2, 3, 4
+ case 'Q':
+ case 'QQ':
+ // 01, 02, 03, 04
+ return parseNDigits(token.length, dateString);
+ // 1st, 2nd, 3rd, 4th
+ case 'Qo':
+ return match.ordinalNumber(dateString, {
+ unit: 'quarter'
+ });
+ // Q1, Q2, Q3, Q4
+ case 'QQQ':
+ return match.quarter(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.quarter(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // 1, 2, 3, 4 (narrow quarter; could be not numerical)
+ case 'QQQQQ':
+ return match.quarter(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // 1st quarter, 2nd quarter, ...
+ case 'QQQQ':
+ default:
+ return match.quarter(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.quarter(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.quarter(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 1 && value <= 4;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCMonth((value - 1) * 3, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return QuarterParser;
+ }(Parser);
+
+ var StandAloneQuarterParser = /*#__PURE__*/function (_Parser) {
+ _inherits(StandAloneQuarterParser, _Parser);
+ var _super = _createSuper(StandAloneQuarterParser);
+ function StandAloneQuarterParser() {
+ var _this;
+ _classCallCheck(this, StandAloneQuarterParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 120);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['Y', 'R', 'Q', 'M', 'L', 'w', 'I', 'd', 'D', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(StandAloneQuarterParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ // 1, 2, 3, 4
+ case 'q':
+ case 'qq':
+ // 01, 02, 03, 04
+ return parseNDigits(token.length, dateString);
+ // 1st, 2nd, 3rd, 4th
+ case 'qo':
+ return match.ordinalNumber(dateString, {
+ unit: 'quarter'
+ });
+ // Q1, Q2, Q3, Q4
+ case 'qqq':
+ return match.quarter(dateString, {
+ width: 'abbreviated',
+ context: 'standalone'
+ }) || match.quarter(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // 1, 2, 3, 4 (narrow quarter; could be not numerical)
+ case 'qqqqq':
+ return match.quarter(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // 1st quarter, 2nd quarter, ...
+ case 'qqqq':
+ default:
+ return match.quarter(dateString, {
+ width: 'wide',
+ context: 'standalone'
+ }) || match.quarter(dateString, {
+ width: 'abbreviated',
+ context: 'standalone'
+ }) || match.quarter(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 1 && value <= 4;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCMonth((value - 1) * 3, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return StandAloneQuarterParser;
+ }(Parser);
+
+ var MonthParser = /*#__PURE__*/function (_Parser) {
+ _inherits(MonthParser, _Parser);
+ var _super = _createSuper(MonthParser);
+ function MonthParser() {
+ var _this;
+ _classCallCheck(this, MonthParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['Y', 'R', 'q', 'Q', 'L', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']);
+ _defineProperty(_assertThisInitialized(_this), "priority", 110);
+ return _this;
+ }
+ _createClass(MonthParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ var valueCallback = function valueCallback(value) {
+ return value - 1;
+ };
+ switch (token) {
+ // 1, 2, ..., 12
+ case 'M':
+ return mapValue(parseNumericPattern(numericPatterns.month, dateString), valueCallback);
+ // 01, 02, ..., 12
+ case 'MM':
+ return mapValue(parseNDigits(2, dateString), valueCallback);
+ // 1st, 2nd, ..., 12th
+ case 'Mo':
+ return mapValue(match.ordinalNumber(dateString, {
+ unit: 'month'
+ }), valueCallback);
+ // Jan, Feb, ..., Dec
+ case 'MMM':
+ return match.month(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.month(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // J, F, ..., D
+ case 'MMMMM':
+ return match.month(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // January, February, ..., December
+ case 'MMMM':
+ default:
+ return match.month(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.month(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.month(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 11;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCMonth(value, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return MonthParser;
+ }(Parser);
+
+ var StandAloneMonthParser = /*#__PURE__*/function (_Parser) {
+ _inherits(StandAloneMonthParser, _Parser);
+ var _super = _createSuper(StandAloneMonthParser);
+ function StandAloneMonthParser() {
+ var _this;
+ _classCallCheck(this, StandAloneMonthParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 110);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['Y', 'R', 'q', 'Q', 'M', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(StandAloneMonthParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ var valueCallback = function valueCallback(value) {
+ return value - 1;
+ };
+ switch (token) {
+ // 1, 2, ..., 12
+ case 'L':
+ return mapValue(parseNumericPattern(numericPatterns.month, dateString), valueCallback);
+ // 01, 02, ..., 12
+ case 'LL':
+ return mapValue(parseNDigits(2, dateString), valueCallback);
+ // 1st, 2nd, ..., 12th
+ case 'Lo':
+ return mapValue(match.ordinalNumber(dateString, {
+ unit: 'month'
+ }), valueCallback);
+ // Jan, Feb, ..., Dec
+ case 'LLL':
+ return match.month(dateString, {
+ width: 'abbreviated',
+ context: 'standalone'
+ }) || match.month(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // J, F, ..., D
+ case 'LLLLL':
+ return match.month(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // January, February, ..., December
+ case 'LLLL':
+ default:
+ return match.month(dateString, {
+ width: 'wide',
+ context: 'standalone'
+ }) || match.month(dateString, {
+ width: 'abbreviated',
+ context: 'standalone'
+ }) || match.month(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 11;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCMonth(value, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return StandAloneMonthParser;
+ }(Parser);
+
+ function setUTCWeek(dirtyDate, dirtyWeek, options) {
+ requiredArgs(2, arguments);
+ var date = toDate(dirtyDate);
+ var week = toInteger(dirtyWeek);
+ var diff = getUTCWeek(date, options) - week;
+ date.setUTCDate(date.getUTCDate() - diff * 7);
+ return date;
+ }
+
+ var LocalWeekParser = /*#__PURE__*/function (_Parser) {
+ _inherits(LocalWeekParser, _Parser);
+ var _super = _createSuper(LocalWeekParser);
+ function LocalWeekParser() {
+ var _this;
+ _classCallCheck(this, LocalWeekParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 100);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'i', 't', 'T']);
+ return _this;
+ }
+ _createClass(LocalWeekParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'w':
+ return parseNumericPattern(numericPatterns.week, dateString);
+ case 'wo':
+ return match.ordinalNumber(dateString, {
+ unit: 'week'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 1 && value <= 53;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value, options) {
+ return startOfUTCWeek(setUTCWeek(date, value, options), options);
+ }
+ }]);
+ return LocalWeekParser;
+ }(Parser);
+
+ function setUTCISOWeek(dirtyDate, dirtyISOWeek) {
+ requiredArgs(2, arguments);
+ var date = toDate(dirtyDate);
+ var isoWeek = toInteger(dirtyISOWeek);
+ var diff = getUTCISOWeek(date) - isoWeek;
+ date.setUTCDate(date.getUTCDate() - diff * 7);
+ return date;
+ }
+
+ var ISOWeekParser = /*#__PURE__*/function (_Parser) {
+ _inherits(ISOWeekParser, _Parser);
+ var _super = _createSuper(ISOWeekParser);
+ function ISOWeekParser() {
+ var _this;
+ _classCallCheck(this, ISOWeekParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 100);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(ISOWeekParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'I':
+ return parseNumericPattern(numericPatterns.week, dateString);
+ case 'Io':
+ return match.ordinalNumber(dateString, {
+ unit: 'week'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 1 && value <= 53;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ return startOfUTCISOWeek(setUTCISOWeek(date, value));
+ }
+ }]);
+ return ISOWeekParser;
+ }(Parser);
+
+ var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ var DAYS_IN_MONTH_LEAP_YEAR = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+ // Day of the month
+ var DateParser = /*#__PURE__*/function (_Parser) {
+ _inherits(DateParser, _Parser);
+ var _super = _createSuper(DateParser);
+ function DateParser() {
+ var _this;
+ _classCallCheck(this, DateParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 90);
+ _defineProperty(_assertThisInitialized(_this), "subPriority", 1);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['Y', 'R', 'q', 'Q', 'w', 'I', 'D', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(DateParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'd':
+ return parseNumericPattern(numericPatterns.date, dateString);
+ case 'do':
+ return match.ordinalNumber(dateString, {
+ unit: 'date'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(date, value) {
+ var year = date.getUTCFullYear();
+ var isLeapYear = isLeapYearIndex$1(year);
+ var month = date.getUTCMonth();
+ if (isLeapYear) {
+ return value >= 1 && value <= DAYS_IN_MONTH_LEAP_YEAR[month];
+ } else {
+ return value >= 1 && value <= DAYS_IN_MONTH[month];
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCDate(value);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return DateParser;
+ }(Parser);
+
+ var DayOfYearParser = /*#__PURE__*/function (_Parser) {
+ _inherits(DayOfYearParser, _Parser);
+ var _super = _createSuper(DayOfYearParser);
+ function DayOfYearParser() {
+ var _this;
+ _classCallCheck(this, DayOfYearParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 90);
+ _defineProperty(_assertThisInitialized(_this), "subpriority", 1);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['Y', 'R', 'q', 'Q', 'M', 'L', 'w', 'I', 'd', 'E', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(DayOfYearParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'D':
+ case 'DD':
+ return parseNumericPattern(numericPatterns.dayOfYear, dateString);
+ case 'Do':
+ return match.ordinalNumber(dateString, {
+ unit: 'date'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(date, value) {
+ var year = date.getUTCFullYear();
+ var isLeapYear = isLeapYearIndex$1(year);
+ if (isLeapYear) {
+ return value >= 1 && value <= 366;
+ } else {
+ return value >= 1 && value <= 365;
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCMonth(0, value);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return DayOfYearParser;
+ }(Parser);
+
+ function setUTCDay(dirtyDate, dirtyDay, options) {
+ var _ref, _ref2, _ref3, _options$weekStartsOn, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;
+ requiredArgs(2, arguments);
+ var defaultOptions = getDefaultOptions();
+ var weekStartsOn = toInteger((_ref = (_ref2 = (_ref3 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.weekStartsOn) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.weekStartsOn) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.weekStartsOn) !== null && _ref !== void 0 ? _ref : 0);
+
+ // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
+ if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
+ throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
+ }
+ var date = toDate(dirtyDate);
+ var day = toInteger(dirtyDay);
+ var currentDay = date.getUTCDay();
+ var remainder = day % 7;
+ var dayIndex = (remainder + 7) % 7;
+ var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;
+ date.setUTCDate(date.getUTCDate() + diff);
+ return date;
+ }
+
+ var DayParser = /*#__PURE__*/function (_Parser) {
+ _inherits(DayParser, _Parser);
+ var _super = _createSuper(DayParser);
+ function DayParser() {
+ var _this;
+ _classCallCheck(this, DayParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 90);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['D', 'i', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(DayParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ // Tue
+ case 'E':
+ case 'EE':
+ case 'EEE':
+ return match.day(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // T
+ case 'EEEEE':
+ return match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // Tu
+ case 'EEEEEE':
+ return match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // Tuesday
+ case 'EEEE':
+ default:
+ return match.day(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 6;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value, options) {
+ date = setUTCDay(date, value, options);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return DayParser;
+ }(Parser);
+
+ var LocalDayParser = /*#__PURE__*/function (_Parser) {
+ _inherits(LocalDayParser, _Parser);
+ var _super = _createSuper(LocalDayParser);
+ function LocalDayParser() {
+ var _this;
+ _classCallCheck(this, LocalDayParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 90);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(LocalDayParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match, options) {
+ var valueCallback = function valueCallback(value) {
+ var wholeWeekDays = Math.floor((value - 1) / 7) * 7;
+ return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;
+ };
+ switch (token) {
+ // 3
+ case 'e':
+ case 'ee':
+ // 03
+ return mapValue(parseNDigits(token.length, dateString), valueCallback);
+ // 3rd
+ case 'eo':
+ return mapValue(match.ordinalNumber(dateString, {
+ unit: 'day'
+ }), valueCallback);
+ // Tue
+ case 'eee':
+ return match.day(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // T
+ case 'eeeee':
+ return match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // Tu
+ case 'eeeeee':
+ return match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ // Tuesday
+ case 'eeee':
+ default:
+ return match.day(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 6;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value, options) {
+ date = setUTCDay(date, value, options);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return LocalDayParser;
+ }(Parser);
+
+ var StandAloneLocalDayParser = /*#__PURE__*/function (_Parser) {
+ _inherits(StandAloneLocalDayParser, _Parser);
+ var _super = _createSuper(StandAloneLocalDayParser);
+ function StandAloneLocalDayParser() {
+ var _this;
+ _classCallCheck(this, StandAloneLocalDayParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 90);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['y', 'R', 'u', 'q', 'Q', 'M', 'L', 'I', 'd', 'D', 'E', 'i', 'e', 't', 'T']);
+ return _this;
+ }
+ _createClass(StandAloneLocalDayParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match, options) {
+ var valueCallback = function valueCallback(value) {
+ var wholeWeekDays = Math.floor((value - 1) / 7) * 7;
+ return (value + options.weekStartsOn + 6) % 7 + wholeWeekDays;
+ };
+ switch (token) {
+ // 3
+ case 'c':
+ case 'cc':
+ // 03
+ return mapValue(parseNDigits(token.length, dateString), valueCallback);
+ // 3rd
+ case 'co':
+ return mapValue(match.ordinalNumber(dateString, {
+ unit: 'day'
+ }), valueCallback);
+ // Tue
+ case 'ccc':
+ return match.day(dateString, {
+ width: 'abbreviated',
+ context: 'standalone'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'standalone'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // T
+ case 'ccccc':
+ return match.day(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // Tu
+ case 'cccccc':
+ return match.day(dateString, {
+ width: 'short',
+ context: 'standalone'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ // Tuesday
+ case 'cccc':
+ default:
+ return match.day(dateString, {
+ width: 'wide',
+ context: 'standalone'
+ }) || match.day(dateString, {
+ width: 'abbreviated',
+ context: 'standalone'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'standalone'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'standalone'
+ });
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 6;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value, options) {
+ date = setUTCDay(date, value, options);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return StandAloneLocalDayParser;
+ }(Parser);
+
+ function setUTCISODay(dirtyDate, dirtyDay) {
+ requiredArgs(2, arguments);
+ var day = toInteger(dirtyDay);
+ if (day % 7 === 0) {
+ day = day - 7;
+ }
+ var weekStartsOn = 1;
+ var date = toDate(dirtyDate);
+ var currentDay = date.getUTCDay();
+ var remainder = day % 7;
+ var dayIndex = (remainder + 7) % 7;
+ var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay;
+ date.setUTCDate(date.getUTCDate() + diff);
+ return date;
+ }
+
+ var ISODayParser = /*#__PURE__*/function (_Parser) {
+ _inherits(ISODayParser, _Parser);
+ var _super = _createSuper(ISODayParser);
+ function ISODayParser() {
+ var _this;
+ _classCallCheck(this, ISODayParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 90);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['y', 'Y', 'u', 'q', 'Q', 'M', 'L', 'w', 'd', 'D', 'E', 'e', 'c', 't', 'T']);
+ return _this;
+ }
+ _createClass(ISODayParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ var valueCallback = function valueCallback(value) {
+ if (value === 0) {
+ return 7;
+ }
+ return value;
+ };
+ switch (token) {
+ // 2
+ case 'i':
+ case 'ii':
+ // 02
+ return parseNDigits(token.length, dateString);
+ // 2nd
+ case 'io':
+ return match.ordinalNumber(dateString, {
+ unit: 'day'
+ });
+ // Tue
+ case 'iii':
+ return mapValue(match.day(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ }), valueCallback);
+ // T
+ case 'iiiii':
+ return mapValue(match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ }), valueCallback);
+ // Tu
+ case 'iiiiii':
+ return mapValue(match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ }), valueCallback);
+ // Tuesday
+ case 'iiii':
+ default:
+ return mapValue(match.day(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'short',
+ context: 'formatting'
+ }) || match.day(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ }), valueCallback);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 1 && value <= 7;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date = setUTCISODay(date, value);
+ date.setUTCHours(0, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return ISODayParser;
+ }(Parser);
+
+ var AMPMParser = /*#__PURE__*/function (_Parser) {
+ _inherits(AMPMParser, _Parser);
+ var _super = _createSuper(AMPMParser);
+ function AMPMParser() {
+ var _this;
+ _classCallCheck(this, AMPMParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 80);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['b', 'B', 'H', 'k', 't', 'T']);
+ return _this;
+ }
+ _createClass(AMPMParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'a':
+ case 'aa':
+ case 'aaa':
+ return match.dayPeriod(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'aaaaa':
+ return match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'aaaa':
+ default:
+ return match.dayPeriod(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);
+ return date;
+ }
+ }]);
+ return AMPMParser;
+ }(Parser);
+
+ var AMPMMidnightParser = /*#__PURE__*/function (_Parser) {
+ _inherits(AMPMMidnightParser, _Parser);
+ var _super = _createSuper(AMPMMidnightParser);
+ function AMPMMidnightParser() {
+ var _this;
+ _classCallCheck(this, AMPMMidnightParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 80);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['a', 'B', 'H', 'k', 't', 'T']);
+ return _this;
+ }
+ _createClass(AMPMMidnightParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'b':
+ case 'bb':
+ case 'bbb':
+ return match.dayPeriod(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'bbbbb':
+ return match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'bbbb':
+ default:
+ return match.dayPeriod(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);
+ return date;
+ }
+ }]);
+ return AMPMMidnightParser;
+ }(Parser);
+
+ var DayPeriodParser = /*#__PURE__*/function (_Parser) {
+ _inherits(DayPeriodParser, _Parser);
+ var _super = _createSuper(DayPeriodParser);
+ function DayPeriodParser() {
+ var _this;
+ _classCallCheck(this, DayPeriodParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 80);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['a', 'b', 't', 'T']);
+ return _this;
+ }
+ _createClass(DayPeriodParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'B':
+ case 'BB':
+ case 'BBB':
+ return match.dayPeriod(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'BBBBB':
+ return match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ case 'BBBB':
+ default:
+ return match.dayPeriod(dateString, {
+ width: 'wide',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'abbreviated',
+ context: 'formatting'
+ }) || match.dayPeriod(dateString, {
+ width: 'narrow',
+ context: 'formatting'
+ });
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCHours(dayPeriodEnumToHours(value), 0, 0, 0);
+ return date;
+ }
+ }]);
+ return DayPeriodParser;
+ }(Parser);
+
+ var Hour1to12Parser = /*#__PURE__*/function (_Parser) {
+ _inherits(Hour1to12Parser, _Parser);
+ var _super = _createSuper(Hour1to12Parser);
+ function Hour1to12Parser() {
+ var _this;
+ _classCallCheck(this, Hour1to12Parser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 70);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['H', 'K', 'k', 't', 'T']);
+ return _this;
+ }
+ _createClass(Hour1to12Parser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'h':
+ return parseNumericPattern(numericPatterns.hour12h, dateString);
+ case 'ho':
+ return match.ordinalNumber(dateString, {
+ unit: 'hour'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 1 && value <= 12;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ var isPM = date.getUTCHours() >= 12;
+ if (isPM && value < 12) {
+ date.setUTCHours(value + 12, 0, 0, 0);
+ } else if (!isPM && value === 12) {
+ date.setUTCHours(0, 0, 0, 0);
+ } else {
+ date.setUTCHours(value, 0, 0, 0);
+ }
+ return date;
+ }
+ }]);
+ return Hour1to12Parser;
+ }(Parser);
+
+ var Hour0to23Parser = /*#__PURE__*/function (_Parser) {
+ _inherits(Hour0to23Parser, _Parser);
+ var _super = _createSuper(Hour0to23Parser);
+ function Hour0to23Parser() {
+ var _this;
+ _classCallCheck(this, Hour0to23Parser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 70);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['a', 'b', 'h', 'K', 'k', 't', 'T']);
+ return _this;
+ }
+ _createClass(Hour0to23Parser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'H':
+ return parseNumericPattern(numericPatterns.hour23h, dateString);
+ case 'Ho':
+ return match.ordinalNumber(dateString, {
+ unit: 'hour'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 23;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCHours(value, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return Hour0to23Parser;
+ }(Parser);
+
+ var Hour0To11Parser = /*#__PURE__*/function (_Parser) {
+ _inherits(Hour0To11Parser, _Parser);
+ var _super = _createSuper(Hour0To11Parser);
+ function Hour0To11Parser() {
+ var _this;
+ _classCallCheck(this, Hour0To11Parser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 70);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['h', 'H', 'k', 't', 'T']);
+ return _this;
+ }
+ _createClass(Hour0To11Parser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'K':
+ return parseNumericPattern(numericPatterns.hour11h, dateString);
+ case 'Ko':
+ return match.ordinalNumber(dateString, {
+ unit: 'hour'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 11;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ var isPM = date.getUTCHours() >= 12;
+ if (isPM && value < 12) {
+ date.setUTCHours(value + 12, 0, 0, 0);
+ } else {
+ date.setUTCHours(value, 0, 0, 0);
+ }
+ return date;
+ }
+ }]);
+ return Hour0To11Parser;
+ }(Parser);
+
+ var Hour1To24Parser = /*#__PURE__*/function (_Parser) {
+ _inherits(Hour1To24Parser, _Parser);
+ var _super = _createSuper(Hour1To24Parser);
+ function Hour1To24Parser() {
+ var _this;
+ _classCallCheck(this, Hour1To24Parser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 70);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['a', 'b', 'h', 'H', 'K', 't', 'T']);
+ return _this;
+ }
+ _createClass(Hour1To24Parser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'k':
+ return parseNumericPattern(numericPatterns.hour24h, dateString);
+ case 'ko':
+ return match.ordinalNumber(dateString, {
+ unit: 'hour'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 1 && value <= 24;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ var hours = value <= 24 ? value % 24 : value;
+ date.setUTCHours(hours, 0, 0, 0);
+ return date;
+ }
+ }]);
+ return Hour1To24Parser;
+ }(Parser);
+
+ var MinuteParser = /*#__PURE__*/function (_Parser) {
+ _inherits(MinuteParser, _Parser);
+ var _super = _createSuper(MinuteParser);
+ function MinuteParser() {
+ var _this;
+ _classCallCheck(this, MinuteParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 60);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['t', 'T']);
+ return _this;
+ }
+ _createClass(MinuteParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 'm':
+ return parseNumericPattern(numericPatterns.minute, dateString);
+ case 'mo':
+ return match.ordinalNumber(dateString, {
+ unit: 'minute'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 59;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCMinutes(value, 0, 0);
+ return date;
+ }
+ }]);
+ return MinuteParser;
+ }(Parser);
+
+ var SecondParser = /*#__PURE__*/function (_Parser) {
+ _inherits(SecondParser, _Parser);
+ var _super = _createSuper(SecondParser);
+ function SecondParser() {
+ var _this;
+ _classCallCheck(this, SecondParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 50);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['t', 'T']);
+ return _this;
+ }
+ _createClass(SecondParser, [{
+ key: "parse",
+ value: function parse(dateString, token, match) {
+ switch (token) {
+ case 's':
+ return parseNumericPattern(numericPatterns.second, dateString);
+ case 'so':
+ return match.ordinalNumber(dateString, {
+ unit: 'second'
+ });
+ default:
+ return parseNDigits(token.length, dateString);
+ }
+ }
+ }, {
+ key: "validate",
+ value: function validate(_date, value) {
+ return value >= 0 && value <= 59;
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCSeconds(value, 0);
+ return date;
+ }
+ }]);
+ return SecondParser;
+ }(Parser);
+
+ var FractionOfSecondParser = /*#__PURE__*/function (_Parser) {
+ _inherits(FractionOfSecondParser, _Parser);
+ var _super = _createSuper(FractionOfSecondParser);
+ function FractionOfSecondParser() {
+ var _this;
+ _classCallCheck(this, FractionOfSecondParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 30);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['t', 'T']);
+ return _this;
+ }
+ _createClass(FractionOfSecondParser, [{
+ key: "parse",
+ value: function parse(dateString, token) {
+ var valueCallback = function valueCallback(value) {
+ return Math.floor(value * Math.pow(10, -token.length + 3));
+ };
+ return mapValue(parseNDigits(token.length, dateString), valueCallback);
+ }
+ }, {
+ key: "set",
+ value: function set(date, _flags, value) {
+ date.setUTCMilliseconds(value);
+ return date;
+ }
+ }]);
+ return FractionOfSecondParser;
+ }(Parser);
+
+ var ISOTimezoneWithZParser = /*#__PURE__*/function (_Parser) {
+ _inherits(ISOTimezoneWithZParser, _Parser);
+ var _super = _createSuper(ISOTimezoneWithZParser);
+ function ISOTimezoneWithZParser() {
+ var _this;
+ _classCallCheck(this, ISOTimezoneWithZParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 10);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['t', 'T', 'x']);
+ return _this;
+ }
+ _createClass(ISOTimezoneWithZParser, [{
+ key: "parse",
+ value: function parse(dateString, token) {
+ switch (token) {
+ case 'X':
+ return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, dateString);
+ case 'XX':
+ return parseTimezonePattern(timezonePatterns.basic, dateString);
+ case 'XXXX':
+ return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, dateString);
+ case 'XXXXX':
+ return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, dateString);
+ case 'XXX':
+ default:
+ return parseTimezonePattern(timezonePatterns.extended, dateString);
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, flags, value) {
+ if (flags.timestampIsSet) {
+ return date;
+ }
+ return new Date(date.getTime() - value);
+ }
+ }]);
+ return ISOTimezoneWithZParser;
+ }(Parser);
+
+ var ISOTimezoneParser = /*#__PURE__*/function (_Parser) {
+ _inherits(ISOTimezoneParser, _Parser);
+ var _super = _createSuper(ISOTimezoneParser);
+ function ISOTimezoneParser() {
+ var _this;
+ _classCallCheck(this, ISOTimezoneParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 10);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", ['t', 'T', 'X']);
+ return _this;
+ }
+ _createClass(ISOTimezoneParser, [{
+ key: "parse",
+ value: function parse(dateString, token) {
+ switch (token) {
+ case 'x':
+ return parseTimezonePattern(timezonePatterns.basicOptionalMinutes, dateString);
+ case 'xx':
+ return parseTimezonePattern(timezonePatterns.basic, dateString);
+ case 'xxxx':
+ return parseTimezonePattern(timezonePatterns.basicOptionalSeconds, dateString);
+ case 'xxxxx':
+ return parseTimezonePattern(timezonePatterns.extendedOptionalSeconds, dateString);
+ case 'xxx':
+ default:
+ return parseTimezonePattern(timezonePatterns.extended, dateString);
+ }
+ }
+ }, {
+ key: "set",
+ value: function set(date, flags, value) {
+ if (flags.timestampIsSet) {
+ return date;
+ }
+ return new Date(date.getTime() - value);
+ }
+ }]);
+ return ISOTimezoneParser;
+ }(Parser);
+
+ var TimestampSecondsParser = /*#__PURE__*/function (_Parser) {
+ _inherits(TimestampSecondsParser, _Parser);
+ var _super = _createSuper(TimestampSecondsParser);
+ function TimestampSecondsParser() {
+ var _this;
+ _classCallCheck(this, TimestampSecondsParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 40);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", '*');
+ return _this;
+ }
+ _createClass(TimestampSecondsParser, [{
+ key: "parse",
+ value: function parse(dateString) {
+ return parseAnyDigitsSigned(dateString);
+ }
+ }, {
+ key: "set",
+ value: function set(_date, _flags, value) {
+ return [new Date(value * 1000), {
+ timestampIsSet: true
+ }];
+ }
+ }]);
+ return TimestampSecondsParser;
+ }(Parser);
+
+ var TimestampMillisecondsParser = /*#__PURE__*/function (_Parser) {
+ _inherits(TimestampMillisecondsParser, _Parser);
+ var _super = _createSuper(TimestampMillisecondsParser);
+ function TimestampMillisecondsParser() {
+ var _this;
+ _classCallCheck(this, TimestampMillisecondsParser);
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ _this = _super.call.apply(_super, [this].concat(args));
+ _defineProperty(_assertThisInitialized(_this), "priority", 20);
+ _defineProperty(_assertThisInitialized(_this), "incompatibleTokens", '*');
+ return _this;
+ }
+ _createClass(TimestampMillisecondsParser, [{
+ key: "parse",
+ value: function parse(dateString) {
+ return parseAnyDigitsSigned(dateString);
+ }
+ }, {
+ key: "set",
+ value: function set(_date, _flags, value) {
+ return [new Date(value), {
+ timestampIsSet: true
+ }];
+ }
+ }]);
+ return TimestampMillisecondsParser;
+ }(Parser);
+
+ /*
+ * | | Unit | | Unit |
+ * |-----|--------------------------------|-----|--------------------------------|
+ * | a | AM, PM | A* | Milliseconds in day |
+ * | b | AM, PM, noon, midnight | B | Flexible day period |
+ * | c | Stand-alone local day of week | C* | Localized hour w/ day period |
+ * | d | Day of month | D | Day of year |
+ * | e | Local day of week | E | Day of week |
+ * | f | | F* | Day of week in month |
+ * | g* | Modified Julian day | G | Era |
+ * | h | Hour [1-12] | H | Hour [0-23] |
+ * | i! | ISO day of week | I! | ISO week of year |
+ * | j* | Localized hour w/ day period | J* | Localized hour w/o day period |
+ * | k | Hour [1-24] | K | Hour [0-11] |
+ * | l* | (deprecated) | L | Stand-alone month |
+ * | m | Minute | M | Month |
+ * | n | | N | |
+ * | o! | Ordinal number modifier | O* | Timezone (GMT) |
+ * | p | | P | |
+ * | q | Stand-alone quarter | Q | Quarter |
+ * | r* | Related Gregorian year | R! | ISO week-numbering year |
+ * | s | Second | S | Fraction of second |
+ * | t! | Seconds timestamp | T! | Milliseconds timestamp |
+ * | u | Extended year | U* | Cyclic year |
+ * | v* | Timezone (generic non-locat.) | V* | Timezone (location) |
+ * | w | Local week of year | W* | Week of month |
+ * | x | Timezone (ISO-8601 w/o Z) | X | Timezone (ISO-8601) |
+ * | y | Year (abs) | Y | Local week-numbering year |
+ * | z* | Timezone (specific non-locat.) | Z* | Timezone (aliases) |
+ *
+ * Letters marked by * are not implemented but reserved by Unicode standard.
+ *
+ * Letters marked by ! are non-standard, but implemented by date-fns:
+ * - `o` modifies the previous token to turn it into an ordinal (see `parse` docs)
+ * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,
+ * i.e. 7 for Sunday, 1 for Monday, etc.
+ * - `I` is ISO week of year, as opposed to `w` which is local week of year.
+ * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.
+ * `R` is supposed to be used in conjunction with `I` and `i`
+ * for universal ISO week-numbering date, whereas
+ * `Y` is supposed to be used in conjunction with `w` and `e`
+ * for week-numbering date specific to the locale.
+ */
+ var parsers = {
+ G: new EraParser(),
+ y: new YearParser(),
+ Y: new LocalWeekYearParser(),
+ R: new ISOWeekYearParser(),
+ u: new ExtendedYearParser(),
+ Q: new QuarterParser(),
+ q: new StandAloneQuarterParser(),
+ M: new MonthParser(),
+ L: new StandAloneMonthParser(),
+ w: new LocalWeekParser(),
+ I: new ISOWeekParser(),
+ d: new DateParser(),
+ D: new DayOfYearParser(),
+ E: new DayParser(),
+ e: new LocalDayParser(),
+ c: new StandAloneLocalDayParser(),
+ i: new ISODayParser(),
+ a: new AMPMParser(),
+ b: new AMPMMidnightParser(),
+ B: new DayPeriodParser(),
+ h: new Hour1to12Parser(),
+ H: new Hour0to23Parser(),
+ K: new Hour0To11Parser(),
+ k: new Hour1To24Parser(),
+ m: new MinuteParser(),
+ s: new SecondParser(),
+ S: new FractionOfSecondParser(),
+ X: new ISOTimezoneWithZParser(),
+ x: new ISOTimezoneParser(),
+ t: new TimestampSecondsParser(),
+ T: new TimestampMillisecondsParser()
+ };
+
+ // - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token
+ // (one of the certain letters followed by `o`)
+ // - (\w)\1* matches any sequences of the same letter
+ // - '' matches two quote characters in a row
+ // - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),
+ // except a single quote symbol, which ends the sequence.
+ // Two quote characters do not end the sequence.
+ // If there is no matching single quote
+ // then the sequence will continue until the end of the string.
+ // - . matches any single character unmatched by previous parts of the RegExps
+ var formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g;
+
+ // This RegExp catches symbols escaped by quotes, and also
+ // sequences of symbols P, p, and the combinations like `PPPPPPPppppp`
+ var longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;
+ var escapedStringRegExp = /^'([^]*?)'?$/;
+ var doubleQuoteRegExp = /''/g;
+ var notWhitespaceRegExp = /\S/;
+ var unescapedLatinCharacterRegExp = /[a-zA-Z]/;
+
+ /**
+ * @name parse
+ * @category Common Helpers
+ * @summary Parse the date.
+ *
+ * @description
+ * Return the date parsed from string using the given format string.
+ *
+ * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.
+ * > See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ *
+ * The characters in the format string wrapped between two single quotes characters (') are escaped.
+ * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.
+ *
+ * Format of the format string is based on Unicode Technical Standard #35:
+ * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
+ * with a few additions (see note 5 below the table).
+ *
+ * Not all tokens are compatible. Combinations that don't make sense or could lead to bugs are prohibited
+ * and will throw `RangeError`. For example usage of 24-hour format token with AM/PM token will throw an exception:
+ *
+ * ```javascript
+ * parse('23 AM', 'HH a', new Date())
+ * //=> RangeError: The format string mustn't contain `HH` and `a` at the same time
+ * ```
+ *
+ * See the compatibility table: https://docs.google.com/spreadsheets/d/e/2PACX-1vQOPU3xUhplll6dyoMmVUXHKl_8CRDs6_ueLmex3SoqwhuolkuN3O05l4rqx5h1dKX8eb46Ul-CCSrq/pubhtml?gid=0&single=true
+ *
+ * Accepted format string patterns:
+ * | Unit |Prior| Pattern | Result examples | Notes |
+ * |---------------------------------|-----|---------|-----------------------------------|-------|
+ * | Era | 140 | G..GGG | AD, BC | |
+ * | | | GGGG | Anno Domini, Before Christ | 2 |
+ * | | | GGGGG | A, B | |
+ * | Calendar year | 130 | y | 44, 1, 1900, 2017, 9999 | 4 |
+ * | | | yo | 44th, 1st, 1900th, 9999999th | 4,5 |
+ * | | | yy | 44, 01, 00, 17 | 4 |
+ * | | | yyy | 044, 001, 123, 999 | 4 |
+ * | | | yyyy | 0044, 0001, 1900, 2017 | 4 |
+ * | | | yyyyy | ... | 2,4 |
+ * | Local week-numbering year | 130 | Y | 44, 1, 1900, 2017, 9000 | 4 |
+ * | | | Yo | 44th, 1st, 1900th, 9999999th | 4,5 |
+ * | | | YY | 44, 01, 00, 17 | 4,6 |
+ * | | | YYY | 044, 001, 123, 999 | 4 |
+ * | | | YYYY | 0044, 0001, 1900, 2017 | 4,6 |
+ * | | | YYYYY | ... | 2,4 |
+ * | ISO week-numbering year | 130 | R | -43, 1, 1900, 2017, 9999, -9999 | 4,5 |
+ * | | | RR | -43, 01, 00, 17 | 4,5 |
+ * | | | RRR | -043, 001, 123, 999, -999 | 4,5 |
+ * | | | RRRR | -0043, 0001, 2017, 9999, -9999 | 4,5 |
+ * | | | RRRRR | ... | 2,4,5 |
+ * | Extended year | 130 | u | -43, 1, 1900, 2017, 9999, -999 | 4 |
+ * | | | uu | -43, 01, 99, -99 | 4 |
+ * | | | uuu | -043, 001, 123, 999, -999 | 4 |
+ * | | | uuuu | -0043, 0001, 2017, 9999, -9999 | 4 |
+ * | | | uuuuu | ... | 2,4 |
+ * | Quarter (formatting) | 120 | Q | 1, 2, 3, 4 | |
+ * | | | Qo | 1st, 2nd, 3rd, 4th | 5 |
+ * | | | QQ | 01, 02, 03, 04 | |
+ * | | | QQQ | Q1, Q2, Q3, Q4 | |
+ * | | | QQQQ | 1st quarter, 2nd quarter, ... | 2 |
+ * | | | QQQQQ | 1, 2, 3, 4 | 4 |
+ * | Quarter (stand-alone) | 120 | q | 1, 2, 3, 4 | |
+ * | | | qo | 1st, 2nd, 3rd, 4th | 5 |
+ * | | | qq | 01, 02, 03, 04 | |
+ * | | | qqq | Q1, Q2, Q3, Q4 | |
+ * | | | qqqq | 1st quarter, 2nd quarter, ... | 2 |
+ * | | | qqqqq | 1, 2, 3, 4 | 3 |
+ * | Month (formatting) | 110 | M | 1, 2, ..., 12 | |
+ * | | | Mo | 1st, 2nd, ..., 12th | 5 |
+ * | | | MM | 01, 02, ..., 12 | |
+ * | | | MMM | Jan, Feb, ..., Dec | |
+ * | | | MMMM | January, February, ..., December | 2 |
+ * | | | MMMMM | J, F, ..., D | |
+ * | Month (stand-alone) | 110 | L | 1, 2, ..., 12 | |
+ * | | | Lo | 1st, 2nd, ..., 12th | 5 |
+ * | | | LL | 01, 02, ..., 12 | |
+ * | | | LLL | Jan, Feb, ..., Dec | |
+ * | | | LLLL | January, February, ..., December | 2 |
+ * | | | LLLLL | J, F, ..., D | |
+ * | Local week of year | 100 | w | 1, 2, ..., 53 | |
+ * | | | wo | 1st, 2nd, ..., 53th | 5 |
+ * | | | ww | 01, 02, ..., 53 | |
+ * | ISO week of year | 100 | I | 1, 2, ..., 53 | 5 |
+ * | | | Io | 1st, 2nd, ..., 53th | 5 |
+ * | | | II | 01, 02, ..., 53 | 5 |
+ * | Day of month | 90 | d | 1, 2, ..., 31 | |
+ * | | | do | 1st, 2nd, ..., 31st | 5 |
+ * | | | dd | 01, 02, ..., 31 | |
+ * | Day of year | 90 | D | 1, 2, ..., 365, 366 | 7 |
+ * | | | Do | 1st, 2nd, ..., 365th, 366th | 5 |
+ * | | | DD | 01, 02, ..., 365, 366 | 7 |
+ * | | | DDD | 001, 002, ..., 365, 366 | |
+ * | | | DDDD | ... | 2 |
+ * | Day of week (formatting) | 90 | E..EEE | Mon, Tue, Wed, ..., Sun | |
+ * | | | EEEE | Monday, Tuesday, ..., Sunday | 2 |
+ * | | | EEEEE | M, T, W, T, F, S, S | |
+ * | | | EEEEEE | Mo, Tu, We, Th, Fr, Sa, Su | |
+ * | ISO day of week (formatting) | 90 | i | 1, 2, 3, ..., 7 | 5 |
+ * | | | io | 1st, 2nd, ..., 7th | 5 |
+ * | | | ii | 01, 02, ..., 07 | 5 |
+ * | | | iii | Mon, Tue, Wed, ..., Sun | 5 |
+ * | | | iiii | Monday, Tuesday, ..., Sunday | 2,5 |
+ * | | | iiiii | M, T, W, T, F, S, S | 5 |
+ * | | | iiiiii | Mo, Tu, We, Th, Fr, Sa, Su | 5 |
+ * | Local day of week (formatting) | 90 | e | 2, 3, 4, ..., 1 | |
+ * | | | eo | 2nd, 3rd, ..., 1st | 5 |
+ * | | | ee | 02, 03, ..., 01 | |
+ * | | | eee | Mon, Tue, Wed, ..., Sun | |
+ * | | | eeee | Monday, Tuesday, ..., Sunday | 2 |
+ * | | | eeeee | M, T, W, T, F, S, S | |
+ * | | | eeeeee | Mo, Tu, We, Th, Fr, Sa, Su | |
+ * | Local day of week (stand-alone) | 90 | c | 2, 3, 4, ..., 1 | |
+ * | | | co | 2nd, 3rd, ..., 1st | 5 |
+ * | | | cc | 02, 03, ..., 01 | |
+ * | | | ccc | Mon, Tue, Wed, ..., Sun | |
+ * | | | cccc | Monday, Tuesday, ..., Sunday | 2 |
+ * | | | ccccc | M, T, W, T, F, S, S | |
+ * | | | cccccc | Mo, Tu, We, Th, Fr, Sa, Su | |
+ * | AM, PM | 80 | a..aaa | AM, PM | |
+ * | | | aaaa | a.m., p.m. | 2 |
+ * | | | aaaaa | a, p | |
+ * | AM, PM, noon, midnight | 80 | b..bbb | AM, PM, noon, midnight | |
+ * | | | bbbb | a.m., p.m., noon, midnight | 2 |
+ * | | | bbbbb | a, p, n, mi | |
+ * | Flexible day period | 80 | B..BBB | at night, in the morning, ... | |
+ * | | | BBBB | at night, in the morning, ... | 2 |
+ * | | | BBBBB | at night, in the morning, ... | |
+ * | Hour [1-12] | 70 | h | 1, 2, ..., 11, 12 | |
+ * | | | ho | 1st, 2nd, ..., 11th, 12th | 5 |
+ * | | | hh | 01, 02, ..., 11, 12 | |
+ * | Hour [0-23] | 70 | H | 0, 1, 2, ..., 23 | |
+ * | | | Ho | 0th, 1st, 2nd, ..., 23rd | 5 |
+ * | | | HH | 00, 01, 02, ..., 23 | |
+ * | Hour [0-11] | 70 | K | 1, 2, ..., 11, 0 | |
+ * | | | Ko | 1st, 2nd, ..., 11th, 0th | 5 |
+ * | | | KK | 01, 02, ..., 11, 00 | |
+ * | Hour [1-24] | 70 | k | 24, 1, 2, ..., 23 | |
+ * | | | ko | 24th, 1st, 2nd, ..., 23rd | 5 |
+ * | | | kk | 24, 01, 02, ..., 23 | |
+ * | Minute | 60 | m | 0, 1, ..., 59 | |
+ * | | | mo | 0th, 1st, ..., 59th | 5 |
+ * | | | mm | 00, 01, ..., 59 | |
+ * | Second | 50 | s | 0, 1, ..., 59 | |
+ * | | | so | 0th, 1st, ..., 59th | 5 |
+ * | | | ss | 00, 01, ..., 59 | |
+ * | Seconds timestamp | 40 | t | 512969520 | |
+ * | | | tt | ... | 2 |
+ * | Fraction of second | 30 | S | 0, 1, ..., 9 | |
+ * | | | SS | 00, 01, ..., 99 | |
+ * | | | SSS | 000, 001, ..., 999 | |
+ * | | | SSSS | ... | 2 |
+ * | Milliseconds timestamp | 20 | T | 512969520900 | |
+ * | | | TT | ... | 2 |
+ * | Timezone (ISO-8601 w/ Z) | 10 | X | -08, +0530, Z | |
+ * | | | XX | -0800, +0530, Z | |
+ * | | | XXX | -08:00, +05:30, Z | |
+ * | | | XXXX | -0800, +0530, Z, +123456 | 2 |
+ * | | | XXXXX | -08:00, +05:30, Z, +12:34:56 | |
+ * | Timezone (ISO-8601 w/o Z) | 10 | x | -08, +0530, +00 | |
+ * | | | xx | -0800, +0530, +0000 | |
+ * | | | xxx | -08:00, +05:30, +00:00 | 2 |
+ * | | | xxxx | -0800, +0530, +0000, +123456 | |
+ * | | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | |
+ * | Long localized date | NA | P | 05/29/1453 | 5,8 |
+ * | | | PP | May 29, 1453 | |
+ * | | | PPP | May 29th, 1453 | |
+ * | | | PPPP | Sunday, May 29th, 1453 | 2,5,8 |
+ * | Long localized time | NA | p | 12:00 AM | 5,8 |
+ * | | | pp | 12:00:00 AM | |
+ * | Combination of date and time | NA | Pp | 05/29/1453, 12:00 AM | |
+ * | | | PPpp | May 29, 1453, 12:00:00 AM | |
+ * | | | PPPpp | May 29th, 1453 at ... | |
+ * | | | PPPPpp | Sunday, May 29th, 1453 at ... | 2,5,8 |
+ * Notes:
+ * 1. "Formatting" units (e.g. formatting quarter) in the default en-US locale
+ * are the same as "stand-alone" units, but are different in some languages.
+ * "Formatting" units are declined according to the rules of the language
+ * in the context of a date. "Stand-alone" units are always nominative singular.
+ * In `format` function, they will produce different result:
+ *
+ * `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`
+ *
+ * `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`
+ *
+ * `parse` will try to match both formatting and stand-alone units interchangably.
+ *
+ * 2. Any sequence of the identical letters is a pattern, unless it is escaped by
+ * the single quote characters (see below).
+ * If the sequence is longer than listed in table:
+ * - for numerical units (`yyyyyyyy`) `parse` will try to match a number
+ * as wide as the sequence
+ * - for text units (`MMMMMMMM`) `parse` will try to match the widest variation of the unit.
+ * These variations are marked with "2" in the last column of the table.
+ *
+ * 3. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.
+ * These tokens represent the shortest form of the quarter.
+ *
+ * 4. The main difference between `y` and `u` patterns are B.C. years:
+ *
+ * | Year | `y` | `u` |
+ * |------|-----|-----|
+ * | AC 1 | 1 | 1 |
+ * | BC 1 | 1 | 0 |
+ * | BC 2 | 2 | -1 |
+ *
+ * Also `yy` will try to guess the century of two digit year by proximity with `referenceDate`:
+ *
+ * `parse('50', 'yy', new Date(2018, 0, 1)) //=> Sat Jan 01 2050 00:00:00`
+ *
+ * `parse('75', 'yy', new Date(2018, 0, 1)) //=> Wed Jan 01 1975 00:00:00`
+ *
+ * while `uu` will just assign the year as is:
+ *
+ * `parse('50', 'uu', new Date(2018, 0, 1)) //=> Sat Jan 01 0050 00:00:00`
+ *
+ * `parse('75', 'uu', new Date(2018, 0, 1)) //=> Tue Jan 01 0075 00:00:00`
+ *
+ * The same difference is true for local and ISO week-numbering years (`Y` and `R`),
+ * except local week-numbering years are dependent on `options.weekStartsOn`
+ * and `options.firstWeekContainsDate` (compare [setISOWeekYear]{@link https://date-fns.org/docs/setISOWeekYear}
+ * and [setWeekYear]{@link https://date-fns.org/docs/setWeekYear}).
+ *
+ * 5. These patterns are not in the Unicode Technical Standard #35:
+ * - `i`: ISO day of week
+ * - `I`: ISO week of year
+ * - `R`: ISO week-numbering year
+ * - `o`: ordinal number modifier
+ * - `P`: long localized date
+ * - `p`: long localized time
+ *
+ * 6. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.
+ * You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ *
+ * 7. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month.
+ * You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ *
+ * 8. `P+` tokens do not have a defined priority since they are merely aliases to other tokens based
+ * on the given locale.
+ *
+ * using `en-US` locale: `P` => `MM/dd/yyyy`
+ * using `en-US` locale: `p` => `hh:mm a`
+ * using `pt-BR` locale: `P` => `dd/MM/yyyy`
+ * using `pt-BR` locale: `p` => `HH:mm`
+ *
+ * Values will be assigned to the date in the descending order of its unit's priority.
+ * Units of an equal priority overwrite each other in the order of appearance.
+ *
+ * If no values of higher priority are parsed (e.g. when parsing string 'January 1st' without a year),
+ * the values will be taken from 3rd argument `referenceDate` which works as a context of parsing.
+ *
+ * `referenceDate` must be passed for correct work of the function.
+ * If you're not sure which `referenceDate` to supply, create a new instance of Date:
+ * `parse('02/11/2014', 'MM/dd/yyyy', new Date())`
+ * In this case parsing will be done in the context of the current date.
+ * If `referenceDate` is `Invalid Date` or a value not convertible to valid `Date`,
+ * then `Invalid Date` will be returned.
+ *
+ * The result may vary by locale.
+ *
+ * If `formatString` matches with `dateString` but does not provides tokens, `referenceDate` will be returned.
+ *
+ * If parsing failed, `Invalid Date` will be returned.
+ * Invalid Date is a Date, whose time value is NaN.
+ * Time value of Date: http://es5.github.io/#x15.9.1.1
+ *
+ * @param {String} dateString - the string to parse
+ * @param {String} formatString - the string of tokens
+ * @param {Date|Number} referenceDate - defines values missing from the parsed dateString
+ * @param {Object} [options] - an object with options.
+ * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
+ * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
+ * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year
+ * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;
+ * see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;
+ * see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @returns {Date} the parsed date
+ * @throws {TypeError} 3 arguments required
+ * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
+ * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7
+ * @throws {RangeError} `options.locale` must contain `match` property
+ * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
+ * @throws {RangeError} format string contains an unescaped latin alphabet character
+ *
+ * @example
+ * // Parse 11 February 2014 from middle-endian format:
+ * var result = parse('02/11/2014', 'MM/dd/yyyy', new Date())
+ * //=> Tue Feb 11 2014 00:00:00
+ *
+ * @example
+ * // Parse 28th of February in Esperanto locale in the context of 2010 year:
+ * import eo from 'date-fns/locale/eo'
+ * var result = parse('28-a de februaro', "do 'de' MMMM", new Date(2010, 0, 1), {
+ * locale: eo
+ * })
+ * //=> Sun Feb 28 2010 00:00:00
+ */
+ function parse(dirtyDateString, dirtyFormatString, dirtyReferenceDate, options) {
+ var _ref, _options$locale, _ref2, _ref3, _ref4, _options$firstWeekCon, _options$locale2, _options$locale2$opti, _defaultOptions$local, _defaultOptions$local2, _ref5, _ref6, _ref7, _options$weekStartsOn, _options$locale3, _options$locale3$opti, _defaultOptions$local3, _defaultOptions$local4;
+ requiredArgs(3, arguments);
+ var dateString = String(dirtyDateString);
+ var formatString = String(dirtyFormatString);
+ var defaultOptions = getDefaultOptions();
+ var locale = (_ref = (_options$locale = options === null || options === void 0 ? void 0 : options.locale) !== null && _options$locale !== void 0 ? _options$locale : defaultOptions.locale) !== null && _ref !== void 0 ? _ref : defaultLocale;
+ if (!locale.match) {
+ throw new RangeError('locale must contain match property');
+ }
+ var firstWeekContainsDate = toInteger((_ref2 = (_ref3 = (_ref4 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale2 = options.locale) === null || _options$locale2 === void 0 ? void 0 : (_options$locale2$opti = _options$locale2.options) === null || _options$locale2$opti === void 0 ? void 0 : _options$locale2$opti.firstWeekContainsDate) !== null && _ref4 !== void 0 ? _ref4 : defaultOptions.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : 1);
+
+ // Test if weekStartsOn is between 1 and 7 _and_ is not NaN
+ if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {
+ throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');
+ }
+ var weekStartsOn = toInteger((_ref5 = (_ref6 = (_ref7 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale3 = options.locale) === null || _options$locale3 === void 0 ? void 0 : (_options$locale3$opti = _options$locale3.options) === null || _options$locale3$opti === void 0 ? void 0 : _options$locale3$opti.weekStartsOn) !== null && _ref7 !== void 0 ? _ref7 : defaultOptions.weekStartsOn) !== null && _ref6 !== void 0 ? _ref6 : (_defaultOptions$local3 = defaultOptions.locale) === null || _defaultOptions$local3 === void 0 ? void 0 : (_defaultOptions$local4 = _defaultOptions$local3.options) === null || _defaultOptions$local4 === void 0 ? void 0 : _defaultOptions$local4.weekStartsOn) !== null && _ref5 !== void 0 ? _ref5 : 0);
+
+ // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
+ if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
+ throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
+ }
+ if (formatString === '') {
+ if (dateString === '') {
+ return toDate(dirtyReferenceDate);
+ } else {
+ return new Date(NaN);
+ }
+ }
+ var subFnOptions = {
+ firstWeekContainsDate: firstWeekContainsDate,
+ weekStartsOn: weekStartsOn,
+ locale: locale
+ };
+
+ // If timezone isn't specified, it will be set to the system timezone
+ var setters = [new DateToSystemTimezoneSetter()];
+ var tokens = formatString.match(longFormattingTokensRegExp).map(function (substring) {
+ var firstCharacter = substring[0];
+ if (firstCharacter in longFormatters$1) {
+ var longFormatter = longFormatters$1[firstCharacter];
+ return longFormatter(substring, locale.formatLong);
+ }
+ return substring;
+ }).join('').match(formattingTokensRegExp);
+ var usedTokens = [];
+ var _iterator = _createForOfIteratorHelper(tokens),
+ _step;
+ try {
+ var _loop = function _loop() {
+ var token = _step.value;
+ if (!(options !== null && options !== void 0 && options.useAdditionalWeekYearTokens) && isProtectedWeekYearToken(token)) {
+ throwProtectedError(token, formatString, dirtyDateString);
+ }
+ if (!(options !== null && options !== void 0 && options.useAdditionalDayOfYearTokens) && isProtectedDayOfYearToken(token)) {
+ throwProtectedError(token, formatString, dirtyDateString);
+ }
+ var firstCharacter = token[0];
+ var parser = parsers[firstCharacter];
+ if (parser) {
+ var incompatibleTokens = parser.incompatibleTokens;
+ if (Array.isArray(incompatibleTokens)) {
+ var incompatibleToken = usedTokens.find(function (usedToken) {
+ return incompatibleTokens.includes(usedToken.token) || usedToken.token === firstCharacter;
+ });
+ if (incompatibleToken) {
+ throw new RangeError("The format string mustn't contain `".concat(incompatibleToken.fullToken, "` and `").concat(token, "` at the same time"));
+ }
+ } else if (parser.incompatibleTokens === '*' && usedTokens.length > 0) {
+ throw new RangeError("The format string mustn't contain `".concat(token, "` and any other token at the same time"));
+ }
+ usedTokens.push({
+ token: firstCharacter,
+ fullToken: token
+ });
+ var parseResult = parser.run(dateString, token, locale.match, subFnOptions);
+ if (!parseResult) {
+ return {
+ v: new Date(NaN)
+ };
+ }
+ setters.push(parseResult.setter);
+ dateString = parseResult.rest;
+ } else {
+ if (firstCharacter.match(unescapedLatinCharacterRegExp)) {
+ throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');
+ }
+
+ // Replace two single quote characters with one single quote character
+ if (token === "''") {
+ token = "'";
+ } else if (firstCharacter === "'") {
+ token = cleanEscapedString(token);
+ }
+
+ // Cut token from string, or, if string doesn't match the token, return Invalid Date
+ if (dateString.indexOf(token) === 0) {
+ dateString = dateString.slice(token.length);
+ } else {
+ return {
+ v: new Date(NaN)
+ };
+ }
+ }
+ };
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var _ret = _loop();
+ if (_typeof(_ret) === "object") return _ret.v;
+ }
+
+ // Check if the remaining input contains something other than whitespace
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+ if (dateString.length > 0 && notWhitespaceRegExp.test(dateString)) {
+ return new Date(NaN);
+ }
+ var uniquePrioritySetters = setters.map(function (setter) {
+ return setter.priority;
+ }).sort(function (a, b) {
+ return b - a;
+ }).filter(function (priority, index, array) {
+ return array.indexOf(priority) === index;
+ }).map(function (priority) {
+ return setters.filter(function (setter) {
+ return setter.priority === priority;
+ }).sort(function (a, b) {
+ return b.subPriority - a.subPriority;
+ });
+ }).map(function (setterArray) {
+ return setterArray[0];
+ });
+ var date = toDate(dirtyReferenceDate);
+ if (isNaN(date.getTime())) {
+ return new Date(NaN);
+ }
+
+ // Convert the date in system timezone to the same date in UTC+00:00 timezone.
+ var utcDate = subMilliseconds(date, getTimezoneOffsetInMilliseconds(date));
+ var flags = {};
+ var _iterator2 = _createForOfIteratorHelper(uniquePrioritySetters),
+ _step2;
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ var setter = _step2.value;
+ if (!setter.validate(utcDate, subFnOptions)) {
+ return new Date(NaN);
+ }
+ var result = setter.set(utcDate, flags, subFnOptions);
+ // Result is tuple (date, flags)
+ if (Array.isArray(result)) {
+ utcDate = result[0];
+ assign(flags, result[1]);
+ // Result is date
+ } else {
+ utcDate = result;
+ }
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
+ return utcDate;
+ }
+ function cleanEscapedString(input) {
+ return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, "'");
+ }
+
+ /**
+ * @name startOfHour
+ * @category Hour Helpers
+ * @summary Return the start of an hour for the given date.
+ *
+ * @description
+ * Return the start of an hour for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the start of an hour
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The start of an hour for 2 September 2014 11:55:00:
+ * const result = startOfHour(new Date(2014, 8, 2, 11, 55))
+ * //=> Tue Sep 02 2014 11:00:00
+ */
+ function startOfHour(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setMinutes(0, 0, 0);
+ return date;
+ }
+
+ /**
+ * @name startOfSecond
+ * @category Second Helpers
+ * @summary Return the start of a second for the given date.
+ *
+ * @description
+ * Return the start of a second for the given date.
+ * The result will be in the local timezone.
+ *
+ * @param {Date|Number} date - the original date
+ * @returns {Date} the start of a second
+ * @throws {TypeError} 1 argument required
+ *
+ * @example
+ * // The start of a second for 1 December 2014 22:15:45.400:
+ * const result = startOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))
+ * //=> Mon Dec 01 2014 22:15:45.000
+ */
+ function startOfSecond(dirtyDate) {
+ requiredArgs(1, arguments);
+ var date = toDate(dirtyDate);
+ date.setMilliseconds(0);
+ return date;
+ }
+
+ /**
+ * @name parseISO
+ * @category Common Helpers
+ * @summary Parse ISO string
+ *
+ * @description
+ * Parse the given string in ISO 8601 format and return an instance of Date.
+ *
+ * Function accepts complete ISO 8601 formats as well as partial implementations.
+ * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601
+ *
+ * If the argument isn't a string, the function cannot parse the string or
+ * the values are invalid, it returns Invalid Date.
+ *
+ * @param {String} argument - the value to convert
+ * @param {Object} [options] - an object with options.
+ * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format
+ * @returns {Date} the parsed date in the local time zone
+ * @throws {TypeError} 1 argument required
+ * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2
+ *
+ * @example
+ * // Convert string '2014-02-11T11:30:30' to date:
+ * const result = parseISO('2014-02-11T11:30:30')
+ * //=> Tue Feb 11 2014 11:30:30
+ *
+ * @example
+ * // Convert string '+02014101' to date,
+ * // if the additional number of digits in the extended year format is 1:
+ * const result = parseISO('+02014101', { additionalDigits: 1 })
+ * //=> Fri Apr 11 2014 00:00:00
+ */
+ function parseISO(argument, options) {
+ var _options$additionalDi;
+ requiredArgs(1, arguments);
+ var additionalDigits = toInteger((_options$additionalDi = options === null || options === void 0 ? void 0 : options.additionalDigits) !== null && _options$additionalDi !== void 0 ? _options$additionalDi : 2);
+ if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) {
+ throw new RangeError('additionalDigits must be 0, 1 or 2');
+ }
+ if (!(typeof argument === 'string' || Object.prototype.toString.call(argument) === '[object String]')) {
+ return new Date(NaN);
+ }
+ var dateStrings = splitDateString(argument);
+ var date;
+ if (dateStrings.date) {
+ var parseYearResult = parseYear(dateStrings.date, additionalDigits);
+ date = parseDate(parseYearResult.restDateString, parseYearResult.year);
+ }
+ if (!date || isNaN(date.getTime())) {
+ return new Date(NaN);
+ }
+ var timestamp = date.getTime();
+ var time = 0;
+ var offset;
+ if (dateStrings.time) {
+ time = parseTime(dateStrings.time);
+ if (isNaN(time)) {
+ return new Date(NaN);
+ }
+ }
+ if (dateStrings.timezone) {
+ offset = parseTimezone(dateStrings.timezone);
+ if (isNaN(offset)) {
+ return new Date(NaN);
+ }
+ } else {
+ var dirtyDate = new Date(timestamp + time);
+ // js parsed string assuming it's in UTC timezone
+ // but we need it to be parsed in our timezone
+ // so we use utc values to build date in our timezone.
+ // Year values from 0 to 99 map to the years 1900 to 1999
+ // so set year explicitly with setFullYear.
+ var result = new Date(0);
+ result.setFullYear(dirtyDate.getUTCFullYear(), dirtyDate.getUTCMonth(), dirtyDate.getUTCDate());
+ result.setHours(dirtyDate.getUTCHours(), dirtyDate.getUTCMinutes(), dirtyDate.getUTCSeconds(), dirtyDate.getUTCMilliseconds());
+ return result;
+ }
+ return new Date(timestamp + time + offset);
+ }
+ var patterns = {
+ dateTimeDelimiter: /[T ]/,
+ timeZoneDelimiter: /[Z ]/i,
+ timezone: /([Z+-].*)$/
+ };
+ var dateRegex = /^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/;
+ var timeRegex = /^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/;
+ var timezoneRegex = /^([+-])(\d{2})(?::?(\d{2}))?$/;
+ function splitDateString(dateString) {
+ var dateStrings = {};
+ var array = dateString.split(patterns.dateTimeDelimiter);
+ var timeString;
+
+ // The regex match should only return at maximum two array elements.
+ // [date], [time], or [date, time].
+ if (array.length > 2) {
+ return dateStrings;
+ }
+ if (/:/.test(array[0])) {
+ timeString = array[0];
+ } else {
+ dateStrings.date = array[0];
+ timeString = array[1];
+ if (patterns.timeZoneDelimiter.test(dateStrings.date)) {
+ dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];
+ timeString = dateString.substr(dateStrings.date.length, dateString.length);
+ }
+ }
+ if (timeString) {
+ var token = patterns.timezone.exec(timeString);
+ if (token) {
+ dateStrings.time = timeString.replace(token[1], '');
+ dateStrings.timezone = token[1];
+ } else {
+ dateStrings.time = timeString;
+ }
+ }
+ return dateStrings;
+ }
+ function parseYear(dateString, additionalDigits) {
+ var regex = new RegExp('^(?:(\\d{4}|[+-]\\d{' + (4 + additionalDigits) + '})|(\\d{2}|[+-]\\d{' + (2 + additionalDigits) + '})$)');
+ var captures = dateString.match(regex);
+ // Invalid ISO-formatted year
+ if (!captures) return {
+ year: NaN,
+ restDateString: ''
+ };
+ var year = captures[1] ? parseInt(captures[1]) : null;
+ var century = captures[2] ? parseInt(captures[2]) : null;
+
+ // either year or century is null, not both
+ return {
+ year: century === null ? year : century * 100,
+ restDateString: dateString.slice((captures[1] || captures[2]).length)
+ };
+ }
+ function parseDate(dateString, year) {
+ // Invalid ISO-formatted year
+ if (year === null) return new Date(NaN);
+ var captures = dateString.match(dateRegex);
+ // Invalid ISO-formatted string
+ if (!captures) return new Date(NaN);
+ var isWeekDate = !!captures[4];
+ var dayOfYear = parseDateUnit(captures[1]);
+ var month = parseDateUnit(captures[2]) - 1;
+ var day = parseDateUnit(captures[3]);
+ var week = parseDateUnit(captures[4]);
+ var dayOfWeek = parseDateUnit(captures[5]) - 1;
+ if (isWeekDate) {
+ if (!validateWeekDate(year, week, dayOfWeek)) {
+ return new Date(NaN);
+ }
+ return dayOfISOWeekYear(year, week, dayOfWeek);
+ } else {
+ var date = new Date(0);
+ if (!validateDate(year, month, day) || !validateDayOfYearDate(year, dayOfYear)) {
+ return new Date(NaN);
+ }
+ date.setUTCFullYear(year, month, Math.max(dayOfYear, day));
+ return date;
+ }
+ }
+ function parseDateUnit(value) {
+ return value ? parseInt(value) : 1;
+ }
+ function parseTime(timeString) {
+ var captures = timeString.match(timeRegex);
+ if (!captures) return NaN; // Invalid ISO-formatted time
+
+ var hours = parseTimeUnit(captures[1]);
+ var minutes = parseTimeUnit(captures[2]);
+ var seconds = parseTimeUnit(captures[3]);
+ if (!validateTime(hours, minutes, seconds)) {
+ return NaN;
+ }
+ return hours * millisecondsInHour + minutes * millisecondsInMinute + seconds * 1000;
+ }
+ function parseTimeUnit(value) {
+ return value && parseFloat(value.replace(',', '.')) || 0;
+ }
+ function parseTimezone(timezoneString) {
+ if (timezoneString === 'Z') return 0;
+ var captures = timezoneString.match(timezoneRegex);
+ if (!captures) return 0;
+ var sign = captures[1] === '+' ? -1 : 1;
+ var hours = parseInt(captures[2]);
+ var minutes = captures[3] && parseInt(captures[3]) || 0;
+ if (!validateTimezone(hours, minutes)) {
+ return NaN;
+ }
+ return sign * (hours * millisecondsInHour + minutes * millisecondsInMinute);
+ }
+ function dayOfISOWeekYear(isoWeekYear, week, day) {
+ var date = new Date(0);
+ date.setUTCFullYear(isoWeekYear, 0, 4);
+ var fourthOfJanuaryDay = date.getUTCDay() || 7;
+ var diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;
+ date.setUTCDate(date.getUTCDate() + diff);
+ return date;
+ }
+
+ // Validation functions
+
+ // February is null to handle the leap year (using ||)
+ var daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ function isLeapYearIndex(year) {
+ return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;
+ }
+ function validateDate(year, month, date) {
+ return month >= 0 && month <= 11 && date >= 1 && date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28));
+ }
+ function validateDayOfYearDate(year, dayOfYear) {
+ return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);
+ }
+ function validateWeekDate(_year, week, day) {
+ return week >= 1 && week <= 53 && day >= 0 && day <= 6;
+ }
+ function validateTime(hours, minutes, seconds) {
+ if (hours === 24) {
+ return minutes === 0 && seconds === 0;
+ }
+ return seconds >= 0 && seconds < 60 && minutes >= 0 && minutes < 60 && hours >= 0 && hours < 25;
+ }
+ function validateTimezone(_hours, minutes) {
+ return minutes >= 0 && minutes <= 59;
+ }
+
+ var FORMATS = {
+ datetime: 'MMM d, yyyy, h:mm:ss aaaa',
+ millisecond: 'h:mm:ss.SSS aaaa',
+ second: 'h:mm:ss aaaa',
+ minute: 'h:mm aaaa',
+ hour: 'ha',
+ day: 'MMM d',
+ week: 'PP',
+ month: 'MMM yyyy',
+ quarter: 'qqq - yyyy',
+ year: 'yyyy'
+ };
+ adapters._date.override({
+ _id: 'date-fns',
+ // DEBUG
+
+ formats: function formats() {
+ return FORMATS;
+ },
+ parse: function parse$1(value, fmt) {
+ if (value === null || typeof value === 'undefined') {
+ return null;
+ }
+ var type = _typeof$1(value);
+ if (type === 'number' || value instanceof Date) {
+ value = toDate(value);
+ } else if (type === 'string') {
+ if (typeof fmt === 'string') {
+ value = parse(value, fmt, new Date(), this.options);
+ } else {
+ value = parseISO(value, this.options);
+ }
+ }
+ return isValid(value) ? value.getTime() : null;
+ },
+ format: function format$1(time, fmt) {
+ return format(time, fmt, this.options);
+ },
+ add: function add(time, amount, unit) {
+ switch (unit) {
+ case 'millisecond':
+ return addMilliseconds(time, amount);
+ case 'second':
+ return addSeconds(time, amount);
+ case 'minute':
+ return addMinutes(time, amount);
+ case 'hour':
+ return addHours(time, amount);
+ case 'day':
+ return addDays(time, amount);
+ case 'week':
+ return addWeeks(time, amount);
+ case 'month':
+ return addMonths(time, amount);
+ case 'quarter':
+ return addQuarters(time, amount);
+ case 'year':
+ return addYears(time, amount);
+ default:
+ return time;
+ }
+ },
+ diff: function diff(max, min, unit) {
+ switch (unit) {
+ case 'millisecond':
+ return differenceInMilliseconds(max, min);
+ case 'second':
+ return differenceInSeconds(max, min);
+ case 'minute':
+ return differenceInMinutes(max, min);
+ case 'hour':
+ return differenceInHours(max, min);
+ case 'day':
+ return differenceInDays(max, min);
+ case 'week':
+ return differenceInWeeks(max, min);
+ case 'month':
+ return differenceInMonths(max, min);
+ case 'quarter':
+ return differenceInQuarters(max, min);
+ case 'year':
+ return differenceInYears(max, min);
+ default:
+ return 0;
+ }
+ },
+ startOf: function startOf(time, unit, weekday) {
+ switch (unit) {
+ case 'second':
+ return startOfSecond(time);
+ case 'minute':
+ return startOfMinute(time);
+ case 'hour':
+ return startOfHour(time);
+ case 'day':
+ return startOfDay(time);
+ case 'week':
+ return startOfWeek(time);
+ case 'isoWeek':
+ return startOfWeek(time, {
+ weekStartsOn: +weekday
+ });
+ case 'month':
+ return startOfMonth(time);
+ case 'quarter':
+ return startOfQuarter(time);
+ case 'year':
+ return startOfYear(time);
+ default:
+ return time;
+ }
+ },
+ endOf: function endOf(time, unit) {
+ switch (unit) {
+ case 'second':
+ return endOfSecond(time);
+ case 'minute':
+ return endOfMinute(time);
+ case 'hour':
+ return endOfHour(time);
+ case 'day':
+ return endOfDay(time);
+ case 'week':
+ return endOfWeek(time);
+ case 'month':
+ return endOfMonth(time);
+ case 'quarter':
+ return endOfQuarter(time);
+ case 'year':
+ return endOfYear(time);
+ default:
+ return time;
+ }
+ }
+ });
+
+ // for plugins
+ // match src/index.umd.ts in Chart.js
+ // except for platforms (not exported)
+ Chart.helpers = _objectSpread2({}, helpers);
+ Chart._adapters = adapters;
+ Chart.Animation = Animation;
+ Chart.Animations = Animations;
+ Chart.animator = animator;
+ Chart.controllers = registry.controllers.items;
+ Chart.DatasetController = DatasetController;
+ Chart.Element = Element;
+ Chart.elements = elements;
+ Chart.Interaction = Interaction;
+ Chart.layouts = layouts;
+ Chart.Scale = Scale;
+ Chart.Ticks = Ticks;
+ Object.assign(Chart, controllers, scales, elements, plugins);
+ Chart.Chart = Chart;
+
+ return Chart;
+
+}));
diff --git a/public/chartkick.js b/public/chartkick.js
new file mode 100644
index 0000000..02fbada
--- /dev/null
+++ b/public/chartkick.js
@@ -0,0 +1,2570 @@
+/*!
+ * Chartkick.js v5.0.1
+ * Create beautiful charts with one line of JavaScript
+ * https://github.com/ankane/chartkick.js
+ * MIT License
+ */
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chartkick = factory());
+})(this, (function () { 'use strict';
+
+ function isArray(variable) {
+ return Object.prototype.toString.call(variable) === "[object Array]";
+ }
+
+ function isFunction(variable) {
+ return variable instanceof Function;
+ }
+
+ function isPlainObject(variable) {
+ // protect against prototype pollution, defense 2
+ return Object.prototype.toString.call(variable) === "[object Object]" && !isFunction(variable) && variable instanceof Object;
+ }
+
+ // https://github.com/madrobby/zepto/blob/master/src/zepto.js
+ function extend(target, source) {
+ for (var key in source) {
+ // protect against prototype pollution, defense 1
+ if (key === "__proto__") { continue; }
+
+ if (isPlainObject(source[key]) || isArray(source[key])) {
+ if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
+ target[key] = {};
+ }
+ if (isArray(source[key]) && !isArray(target[key])) {
+ target[key] = [];
+ }
+ extend(target[key], source[key]);
+ } else if (source[key] !== undefined) {
+ target[key] = source[key];
+ }
+ }
+ }
+
+ function merge(obj1, obj2) {
+ var target = {};
+ extend(target, obj1);
+ extend(target, obj2);
+ return target;
+ }
+
+ var DATE_PATTERN = /^(\d\d\d\d)(?:-)?(\d\d)(?:-)?(\d\d)$/i;
+
+ function negativeValues(series) {
+ for (var i = 0; i < series.length; i++) {
+ var data = series[i].data;
+ for (var j = 0; j < data.length; j++) {
+ if (data[j][1] < 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function toStr(obj) {
+ return "" + obj;
+ }
+
+ function toFloat(obj) {
+ return parseFloat(obj);
+ }
+
+ function toDate(obj) {
+ if (obj instanceof Date) {
+ return obj;
+ } else if (typeof obj === "number") {
+ return new Date(obj * 1000); // ms
+ } else {
+ var s = toStr(obj);
+ var matches = s.match(DATE_PATTERN);
+ if (matches) {
+ var year = parseInt(matches[1], 10);
+ var month = parseInt(matches[2], 10) - 1;
+ var day = parseInt(matches[3], 10);
+ return new Date(year, month, day);
+ } else {
+ // try our best to get the str into iso8601
+ // TODO be smarter about this
+ var str = s.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
+ // Date.parse returns milliseconds if valid and NaN if invalid
+ return new Date(Date.parse(str) || s);
+ }
+ }
+ }
+
+ function toArr(obj) {
+ if (isArray(obj)) {
+ return obj;
+ } else {
+ var arr = [];
+ for (var i in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, i)) {
+ arr.push([i, obj[i]]);
+ }
+ }
+ return arr;
+ }
+ }
+
+ function jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle) {
+ return function (chart, opts, chartOptions) {
+ var series = chart.data;
+ var options = merge({}, defaultOptions);
+ options = merge(options, chartOptions || {});
+
+ if (chart.singleSeriesFormat || "legend" in opts) {
+ hideLegend(options, opts.legend, chart.singleSeriesFormat);
+ }
+
+ if (opts.title) {
+ setTitle(options, opts.title);
+ }
+
+ // min
+ if ("min" in opts) {
+ setMin(options, opts.min);
+ } else if (!negativeValues(series)) {
+ setMin(options, 0);
+ }
+
+ // max
+ if (opts.max) {
+ setMax(options, opts.max);
+ }
+
+ if ("stacked" in opts) {
+ setStacked(options, opts.stacked);
+ }
+
+ if (opts.colors) {
+ options.colors = opts.colors;
+ }
+
+ if (opts.xtitle) {
+ setXtitle(options, opts.xtitle);
+ }
+
+ if (opts.ytitle) {
+ setYtitle(options, opts.ytitle);
+ }
+
+ // merge library last
+ options = merge(options, opts.library || {});
+
+ return options;
+ };
+ }
+
+ function sortByTime(a, b) {
+ return a[0].getTime() - b[0].getTime();
+ }
+
+ function sortByNumberSeries(a, b) {
+ return a[0] - b[0];
+ }
+
+ // needed since sort() without arguments does string comparison
+ function sortByNumber(a, b) {
+ return a - b;
+ }
+
+ function every(values, fn) {
+ for (var i = 0; i < values.length; i++) {
+ if (!fn(values[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function isDay(timeUnit) {
+ return timeUnit === "day" || timeUnit === "week" || timeUnit === "month" || timeUnit === "year";
+ }
+
+ function calculateTimeUnit(values, maxDay) {
+ if ( maxDay === void 0 ) maxDay = false;
+
+ if (values.length === 0) {
+ return null;
+ }
+
+ var minute = every(values, function (d) { return d.getMilliseconds() === 0 && d.getSeconds() === 0; });
+ if (!minute) {
+ return null;
+ }
+
+ var hour = every(values, function (d) { return d.getMinutes() === 0; });
+ if (!hour) {
+ return "minute";
+ }
+
+ var day = every(values, function (d) { return d.getHours() === 0; });
+ if (!day) {
+ return "hour";
+ }
+
+ if (maxDay) {
+ return "day";
+ }
+
+ var month = every(values, function (d) { return d.getDate() === 1; });
+ if (!month) {
+ var dayOfWeek = values[0].getDay();
+ var week = every(values, function (d) { return d.getDay() === dayOfWeek; });
+ return (week ? "week" : "day");
+ }
+
+ var year = every(values, function (d) { return d.getMonth() === 0; });
+ if (!year) {
+ return "month";
+ }
+
+ return "year";
+ }
+
+ function isDate(obj) {
+ return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
+ }
+
+ function isNumber(obj) {
+ return typeof obj === "number";
+ }
+
+ var byteSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB"];
+
+ function formatValue(pre, value, options, axis) {
+ pre = pre || "";
+ if (options.prefix) {
+ if (value < 0) {
+ value = value * -1;
+ pre += "-";
+ }
+ pre += options.prefix;
+ }
+
+ var suffix = options.suffix || "";
+ var precision = options.precision;
+ var round = options.round;
+
+ if (options.byteScale) {
+ var positive = value >= 0;
+ if (!positive) {
+ value *= -1;
+ }
+
+ var baseValue = axis ? options.byteScale : value;
+
+ var suffixIdx;
+ if (baseValue >= 1152921504606846976) {
+ value /= 1152921504606846976;
+ suffixIdx = 6;
+ } else if (baseValue >= 1125899906842624) {
+ value /= 1125899906842624;
+ suffixIdx = 5;
+ } else if (baseValue >= 1099511627776) {
+ value /= 1099511627776;
+ suffixIdx = 4;
+ } else if (baseValue >= 1073741824) {
+ value /= 1073741824;
+ suffixIdx = 3;
+ } else if (baseValue >= 1048576) {
+ value /= 1048576;
+ suffixIdx = 2;
+ } else if (baseValue >= 1024) {
+ value /= 1024;
+ suffixIdx = 1;
+ } else {
+ suffixIdx = 0;
+ }
+
+ // TODO handle manual precision case
+ if (precision === undefined && round === undefined) {
+ if (value >= 1023.5) {
+ if (suffixIdx < byteSuffixes.length - 1) {
+ value = 1.0;
+ suffixIdx += 1;
+ }
+ }
+ precision = value >= 1000 ? 4 : 3;
+ }
+ suffix = " " + byteSuffixes[suffixIdx];
+
+ // flip value back
+ if (!positive) {
+ value *= -1;
+ }
+ }
+
+ if (precision !== undefined && round !== undefined) {
+ throw Error("Use either round or precision, not both");
+ }
+
+ if (!axis) {
+ if (precision !== undefined) {
+ value = value.toPrecision(precision);
+ if (!options.zeros) {
+ value = parseFloat(value);
+ }
+ }
+
+ if (round !== undefined) {
+ if (round < 0) {
+ var num = Math.pow(10, -1 * round);
+ value = parseInt((1.0 * value / num).toFixed(0)) * num;
+ } else {
+ value = value.toFixed(round);
+ if (!options.zeros) {
+ value = parseFloat(value);
+ }
+ }
+ }
+ }
+
+ if (options.thousands || options.decimal) {
+ value = toStr(value);
+ var parts = value.split(".");
+ value = parts[0];
+ if (options.thousands) {
+ value = value.replace(/\B(?=(\d{3})+(?!\d))/g, options.thousands);
+ }
+ if (parts.length > 1) {
+ value += (options.decimal || ".") + parts[1];
+ }
+ }
+
+ return pre + value + suffix;
+ }
+
+ function seriesOption(chart, series, option) {
+ if (option in series) {
+ return series[option];
+ } else if (option in chart.options) {
+ return chart.options[option];
+ }
+ return null;
+ }
+
+ var baseOptions = {
+ maintainAspectRatio: false,
+ animation: false,
+ plugins: {
+ legend: {},
+ tooltip: {
+ displayColors: false,
+ callbacks: {}
+ },
+ title: {
+ font: {
+ size: 20
+ },
+ color: "#333"
+ }
+ },
+ interaction: {}
+ };
+
+ var defaultOptions$2 = {
+ scales: {
+ y: {
+ ticks: {
+ maxTicksLimit: 4
+ },
+ title: {
+ font: {
+ size: 16
+ },
+ color: "#333"
+ },
+ grid: {}
+ },
+ x: {
+ grid: {
+ drawOnChartArea: false
+ },
+ title: {
+ font: {
+ size: 16
+ },
+ color: "#333"
+ },
+ time: {},
+ ticks: {}
+ }
+ }
+ };
+
+ // http://there4.io/2012/05/02/google-chart-color-list/
+ var defaultColors = [
+ "#3366CC", "#DC3912", "#FF9900", "#109618", "#990099", "#3B3EAC", "#0099C6",
+ "#DD4477", "#66AA00", "#B82E2E", "#316395", "#994499", "#22AA99", "#AAAA11",
+ "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#651067"
+ ];
+
+ function hideLegend$2(options, legend, hideLegend) {
+ if (legend !== undefined) {
+ options.plugins.legend.display = !!legend;
+ if (legend && legend !== true) {
+ options.plugins.legend.position = legend;
+ }
+ } else if (hideLegend) {
+ options.plugins.legend.display = false;
+ }
+ }
+
+ function setTitle$2(options, title) {
+ options.plugins.title.display = true;
+ options.plugins.title.text = title;
+ }
+
+ function setMin$2(options, min) {
+ if (min !== null) {
+ options.scales.y.min = toFloat(min);
+ }
+ }
+
+ function setMax$2(options, max) {
+ options.scales.y.max = toFloat(max);
+ }
+
+ function setBarMin$1(options, min) {
+ if (min !== null) {
+ options.scales.x.min = toFloat(min);
+ }
+ }
+
+ function setBarMax$1(options, max) {
+ options.scales.x.max = toFloat(max);
+ }
+
+ function setStacked$2(options, stacked) {
+ options.scales.x.stacked = !!stacked;
+ options.scales.y.stacked = !!stacked;
+ }
+
+ function setXtitle$2(options, title) {
+ options.scales.x.title.display = true;
+ options.scales.x.title.text = title;
+ }
+
+ function setYtitle$2(options, title) {
+ options.scales.y.title.display = true;
+ options.scales.y.title.text = title;
+ }
+
+ // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
+ function addOpacity(hex, opacity) {
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+ return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
+ }
+
+ function notnull(x) {
+ return x !== null && x !== undefined;
+ }
+
+ function setLabelSize(chart, data, options) {
+ var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
+ if (maxLabelSize > 25) {
+ maxLabelSize = 25;
+ } else if (maxLabelSize < 10) {
+ maxLabelSize = 10;
+ }
+ if (!options.scales.x.ticks.callback) {
+ options.scales.x.ticks.callback = function (value) {
+ value = toStr(this.getLabelForValue(value));
+ if (value.length > maxLabelSize) {
+ return value.substring(0, maxLabelSize - 2) + "...";
+ } else {
+ return value;
+ }
+ };
+ }
+ }
+
+ function calculateScale(series) {
+ var scale = 1;
+ var max = maxAbsY(series);
+ while (max >= 1024) {
+ scale *= 1024;
+ max /= 1024;
+ }
+ return scale;
+ }
+
+ function setFormatOptions$1(chart, options, chartType) {
+ // options to apply to x and r values for scatter and bubble
+ var numericOptions = {
+ thousands: chart.options.thousands,
+ decimal: chart.options.decimal
+ };
+
+ // options to apply to y value
+ var formatOptions = merge({
+ prefix: chart.options.prefix,
+ suffix: chart.options.suffix,
+ precision: chart.options.precision,
+ round: chart.options.round,
+ zeros: chart.options.zeros
+ }, numericOptions);
+
+ if (chart.options.bytes) {
+ var series = chart.data;
+ if (chartType === "pie") {
+ series = [{data: series}];
+ }
+
+ // set step size
+ formatOptions.byteScale = calculateScale(series);
+ }
+
+ if (chartType !== "pie") {
+ var axis = options.scales.y;
+ if (chartType === "bar") {
+ axis = options.scales.x;
+ }
+
+ if (formatOptions.byteScale) {
+ if (!axis.ticks.stepSize) {
+ axis.ticks.stepSize = formatOptions.byteScale / 2;
+ }
+ if (!axis.ticks.maxTicksLimit) {
+ axis.ticks.maxTicksLimit = 4;
+ }
+ }
+
+ if (!axis.ticks.callback) {
+ axis.ticks.callback = function (value) {
+ return formatValue("", value, formatOptions, true);
+ };
+ }
+
+ if ((chartType === "scatter" || chartType === "bubble") && !options.scales.x.ticks.callback) {
+ options.scales.x.ticks.callback = function (value) {
+ return formatValue("", value, numericOptions, true);
+ };
+ }
+ }
+
+ if (!options.plugins.tooltip.callbacks.label) {
+ if (chartType === "scatter") {
+ options.plugins.tooltip.callbacks.label = function (context) {
+ var label = context.dataset.label || '';
+ if (label) {
+ label += ': ';
+ }
+
+ var dataPoint = context.parsed;
+ return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ')';
+ };
+ } else if (chartType === "bubble") {
+ options.plugins.tooltip.callbacks.label = function (context) {
+ var label = context.dataset.label || '';
+ if (label) {
+ label += ': ';
+ }
+ var dataPoint = context.raw;
+ return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ', ' + formatValue('', dataPoint.v, numericOptions) + ')';
+ };
+ } else if (chartType === "pie") {
+ // need to use separate label for pie charts
+ options.plugins.tooltip.callbacks.label = function (context) {
+ return formatValue('', context.parsed, formatOptions);
+ };
+ } else {
+ var valueLabel = chartType === "bar" ? "x" : "y";
+ options.plugins.tooltip.callbacks.label = function (context) {
+ // don't show null values for stacked charts
+ if (context.parsed[valueLabel] === null) {
+ return;
+ }
+
+ var label = context.dataset.label || '';
+ if (label) {
+ label += ': ';
+ }
+ return formatValue(label, context.parsed[valueLabel], formatOptions);
+ };
+ }
+ }
+
+ // avoid formatting x-axis labels
+ // by default, Chart.js applies locale
+ if ((chartType === "line" || chartType === "area") && chart.xtype === "number") {
+ if (!options.scales.x.ticks.callback) {
+ options.scales.x.ticks.callback = function (value) {
+ return toStr(value);
+ };
+ }
+
+ if (!options.plugins.tooltip.callbacks.title) {
+ options.plugins.tooltip.callbacks.title = function (context) {
+ return toStr(context[0].parsed.x);
+ };
+ }
+ }
+ }
+
+ function maxAbsY(series) {
+ var max = 0;
+ for (var i = 0; i < series.length; i++) {
+ var data = series[i].data;
+ for (var j = 0; j < data.length; j++) {
+ var v = Math.abs(data[j][1]);
+ if (v > max) {
+ max = v;
+ }
+ }
+ }
+ return max;
+ }
+
+ function maxR(series) {
+ // start at zero since radius must be positive
+ var max = 0;
+ for (var i = 0; i < series.length; i++) {
+ var data = series[i].data;
+ for (var j = 0; j < data.length; j++) {
+ var v = data[j][2];
+ if (v > max) {
+ max = v;
+ }
+ }
+ }
+ return max;
+ }
+
+ var jsOptions$2 = jsOptionsFunc(merge(baseOptions, defaultOptions$2), hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
+
+ function prepareDefaultData(chart) {
+ var series = chart.data;
+ var rows = {};
+ var keys = [];
+ var labels = [];
+ var values = [];
+
+ for (var i = 0; i < series.length; i++) {
+ var data = series[i].data;
+
+ for (var j = 0; j < data.length; j++) {
+ var d = data[j];
+ var key = chart.xtype === "datetime" ? d[0].getTime() : d[0];
+ if (!rows[key]) {
+ rows[key] = new Array(series.length);
+ keys.push(key);
+ }
+ rows[key][i] = d[1];
+ }
+ }
+
+ if (chart.xtype === "datetime" || chart.xtype === "number") {
+ keys.sort(sortByNumber);
+ }
+
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
+ values.push([]);
+ }
+
+ for (var i$2 = 0; i$2 < keys.length; i$2++) {
+ var key$1 = keys[i$2];
+
+ var label = chart.xtype === "datetime" ? new Date(key$1) : key$1;
+ labels.push(label);
+
+ var row = rows[key$1];
+ for (var j$1 = 0; j$1 < series.length; j$1++) {
+ var v = row[j$1];
+ // Chart.js doesn't like undefined
+ values[j$1].push(v === undefined ? null : v);
+ }
+ }
+
+ return {
+ labels: labels,
+ values: values
+ };
+ }
+
+ function prepareBubbleData(chart) {
+ var series = chart.data;
+ var values = [];
+ var max = maxR(series);
+
+ for (var i = 0; i < series.length; i++) {
+ var data = series[i].data;
+ var points = [];
+ for (var j = 0; j < data.length; j++) {
+ var v = data[j];
+ points.push({
+ x: v[0],
+ y: v[1],
+ r: v[2] * 20 / max,
+ // custom attribute, for tooltip
+ v: v[2]
+ });
+ }
+ values.push(points);
+ }
+
+ return {
+ labels: [],
+ values: values
+ };
+ }
+
+ // scatter or numeric line/area
+ function prepareNumberData(chart) {
+ var series = chart.data;
+ var values = [];
+
+ for (var i = 0; i < series.length; i++) {
+ var data = series[i].data;
+
+ data.sort(sortByNumberSeries);
+
+ var points = [];
+ for (var j = 0; j < data.length; j++) {
+ var v = data[j];
+ points.push({
+ x: v[0],
+ y: v[1]
+ });
+ }
+ values.push(points);
+ }
+
+ return {
+ labels: [],
+ values: values
+ };
+ }
+
+ function prepareData(chart, chartType) {
+ if (chartType === "bubble") {
+ return prepareBubbleData(chart);
+ } else if (chart.xtype === "number" && chartType !== "bar" && chartType !== "column") {
+ return prepareNumberData(chart);
+ } else {
+ return prepareDefaultData(chart);
+ }
+ }
+
+ function createDataTable(chart, options, chartType) {
+ var ref = prepareData(chart, chartType);
+ var labels = ref.labels;
+ var values = ref.values;
+
+ var series = chart.data;
+ var datasets = [];
+ var colors = chart.options.colors || defaultColors;
+ for (var i = 0; i < series.length; i++) {
+ var s = series[i];
+
+ // use colors for each bar for single series format
+ var color = (void 0);
+ var backgroundColor = (void 0);
+ if (chart.options.colors && chart.singleSeriesFormat && (chartType === "bar" || chartType === "column") && !s.color && isArray(chart.options.colors) && !isArray(chart.options.colors[0])) {
+ color = colors;
+ backgroundColor = [];
+ for (var j = 0; j < colors.length; j++) {
+ backgroundColor[j] = addOpacity(color[j], 0.5);
+ }
+ } else {
+ color = s.color || colors[i];
+ backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
+ }
+
+ var dataset = {
+ label: s.name || "",
+ data: values[i],
+ fill: chartType === "area",
+ borderColor: color,
+ backgroundColor: backgroundColor,
+ borderWidth: 2
+ };
+
+ var pointChart = chartType === "line" || chartType === "area" || chartType === "scatter" || chartType === "bubble";
+ if (pointChart) {
+ dataset.pointBackgroundColor = color;
+ dataset.pointHoverBackgroundColor = color;
+ dataset.pointHitRadius = 50;
+ }
+
+ if (chartType === "bubble") {
+ dataset.pointBackgroundColor = backgroundColor;
+ dataset.pointHoverBackgroundColor = backgroundColor;
+ dataset.pointHoverBorderWidth = 2;
+ }
+
+ if (s.stack) {
+ dataset.stack = s.stack;
+ }
+
+ var curve = seriesOption(chart, s, "curve");
+ if (curve === false) {
+ dataset.tension = 0;
+ } else if (pointChart) {
+ dataset.tension = 0.4;
+ }
+
+ var points = seriesOption(chart, s, "points");
+ if (points === false) {
+ dataset.pointRadius = 0;
+ dataset.pointHoverRadius = 0;
+ }
+
+ dataset = merge(dataset, chart.options.dataset || {});
+ dataset = merge(dataset, s.library || {});
+ dataset = merge(dataset, s.dataset || {});
+
+ datasets.push(dataset);
+ }
+
+ var xmin = chart.options.xmin;
+ var xmax = chart.options.xmax;
+
+ if (chart.xtype === "datetime") {
+ if (notnull(xmin)) {
+ options.scales.x.min = toDate(xmin).getTime();
+ }
+ if (notnull(xmax)) {
+ options.scales.x.max = toDate(xmax).getTime();
+ }
+ } else if (chart.xtype === "number") {
+ if (notnull(xmin)) {
+ options.scales.x.min = xmin;
+ }
+ if (notnull(xmax)) {
+ options.scales.x.max = xmax;
+ }
+ }
+
+ if (chart.xtype === "datetime") {
+ var timeUnit = calculateTimeUnit(labels);
+
+ // for empty datetime chart
+ if (labels.length === 0) {
+ if (notnull(xmin)) {
+ labels.push(toDate(xmin));
+ }
+ if (notnull(xmax)) {
+ labels.push(toDate(xmax));
+ }
+ }
+
+ if (labels.length > 0) {
+ var minTime = (notnull(xmin) ? toDate(xmin) : labels[0]).getTime();
+ var maxTime = (notnull(xmax) ? toDate(xmax) : labels[0]).getTime();
+
+ for (var i$1 = 1; i$1 < labels.length; i$1++) {
+ var value = labels[i$1].getTime();
+ if (value < minTime) {
+ minTime = value;
+ }
+ if (value > maxTime) {
+ maxTime = value;
+ }
+ }
+
+ var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
+
+ if (!options.scales.x.time.unit) {
+ var step;
+ if (timeUnit === "year" || timeDiff > 365 * 10) {
+ options.scales.x.time.unit = "year";
+ step = 365;
+ } else if (timeUnit === "month" || timeDiff > 30 * 10) {
+ options.scales.x.time.unit = "month";
+ step = 30;
+ } else if (timeUnit === "week" || timeUnit === "day" || timeDiff > 10) {
+ options.scales.x.time.unit = "day";
+ step = 1;
+ } else if (timeUnit === "hour" || timeDiff > 0.5) {
+ options.scales.x.time.displayFormats = {hour: "MMM d, h a"};
+ options.scales.x.time.unit = "hour";
+ step = 1 / 24.0;
+ } else if (timeUnit === "minute") {
+ options.scales.x.time.displayFormats = {minute: "h:mm a"};
+ options.scales.x.time.unit = "minute";
+ step = 1 / 24.0 / 60.0;
+ }
+
+ if (step && timeDiff > 0) {
+ // width not available for hidden elements
+ var width = chart.element.offsetWidth;
+ if (width > 0) {
+ var unitStepSize = Math.ceil(timeDiff / step / (width / 100.0));
+ if (timeUnit === "week" && step === 1) {
+ unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
+ }
+ options.scales.x.ticks.stepSize = unitStepSize;
+ }
+ }
+ }
+
+ if (!options.scales.x.time.tooltipFormat) {
+ if (timeUnit === "year") {
+ options.scales.x.time.tooltipFormat = "yyyy";
+ } else if (timeUnit === "month") {
+ options.scales.x.time.tooltipFormat = "MMM yyyy";
+ } else if (timeUnit === "week" || timeUnit === "day") {
+ options.scales.x.time.tooltipFormat = "PP";
+ } else if (timeUnit === "hour") {
+ options.scales.x.time.tooltipFormat = "MMM d, h a";
+ } else if (timeUnit === "minute") {
+ options.scales.x.time.tooltipFormat = "h:mm a";
+ }
+ }
+ }
+ }
+
+ return {
+ labels: labels,
+ datasets: datasets
+ };
+ }
+
+ var defaultExport$2 = function defaultExport(library) {
+ this.name = "chartjs";
+ this.library = library;
+ };
+
+ defaultExport$2.prototype.renderLineChart = function renderLineChart (chart, chartType) {
+ if (!chartType) {
+ chartType = "line";
+ }
+
+ var chartOptions = {};
+
+ var options = jsOptions$2(chart, merge(chartOptions, chart.options));
+ setFormatOptions$1(chart, options, chartType);
+
+ var data = createDataTable(chart, options, chartType);
+
+ if (chart.xtype === "number") {
+ options.scales.x.type = options.scales.x.type || "linear";
+ options.scales.x.position = options.scales.x.position || "bottom";
+ } else {
+ options.scales.x.type = chart.xtype === "string" ? "category" : "time";
+ }
+
+ this.drawChart(chart, "line", data, options);
+ };
+
+ defaultExport$2.prototype.renderPieChart = function renderPieChart (chart) {
+ var options = merge({}, baseOptions);
+ if (chart.options.donut) {
+ options.cutout = "50%";
+ }
+
+ if ("legend" in chart.options) {
+ hideLegend$2(options, chart.options.legend);
+ }
+
+ if (chart.options.title) {
+ setTitle$2(options, chart.options.title);
+ }
+
+ options = merge(options, chart.options.library || {});
+ setFormatOptions$1(chart, options, "pie");
+
+ var labels = [];
+ var values = [];
+ for (var i = 0; i < chart.data.length; i++) {
+ var point = chart.data[i];
+ labels.push(point[0]);
+ values.push(point[1]);
+ }
+
+ var dataset = {
+ data: values,
+ backgroundColor: chart.options.colors || defaultColors
+ };
+ dataset = merge(dataset, chart.options.dataset || {});
+
+ var data = {
+ labels: labels,
+ datasets: [dataset]
+ };
+
+ this.drawChart(chart, "pie", data, options);
+ };
+
+ defaultExport$2.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
+ var options;
+ if (chartType === "bar") {
+ var barOptions = merge(baseOptions, defaultOptions$2);
+ barOptions.indexAxis = "y";
+
+ // ensure gridlines have proper orientation
+ barOptions.scales.x.grid.drawOnChartArea = true;
+ barOptions.scales.y.grid.drawOnChartArea = false;
+ delete barOptions.scales.y.ticks.maxTicksLimit;
+
+ options = jsOptionsFunc(barOptions, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options);
+ } else {
+ options = jsOptions$2(chart, chart.options);
+ }
+ setFormatOptions$1(chart, options, chartType);
+ var data = createDataTable(chart, options, "column");
+ if (chartType !== "bar") {
+ setLabelSize(chart, data, options);
+ }
+ if (!("mode" in options.interaction)) {
+ options.interaction.mode = "index";
+ }
+ this.drawChart(chart, "bar", data, options);
+ };
+
+ defaultExport$2.prototype.renderAreaChart = function renderAreaChart (chart) {
+ this.renderLineChart(chart, "area");
+ };
+
+ defaultExport$2.prototype.renderBarChart = function renderBarChart (chart) {
+ this.renderColumnChart(chart, "bar");
+ };
+
+ defaultExport$2.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
+ chartType = chartType || "scatter";
+
+ var options = jsOptions$2(chart, chart.options);
+ setFormatOptions$1(chart, options, chartType);
+
+ if (!("showLine" in options)) {
+ options.showLine = false;
+ }
+
+ var data = createDataTable(chart, options, chartType);
+
+ options.scales.x.type = options.scales.x.type || "linear";
+ options.scales.x.position = options.scales.x.position || "bottom";
+
+ // prevent grouping hover and tooltips
+ if (!("mode" in options.interaction)) {
+ options.interaction.mode = "nearest";
+ }
+
+ this.drawChart(chart, chartType, data, options);
+ };
+
+ defaultExport$2.prototype.renderBubbleChart = function renderBubbleChart (chart) {
+ this.renderScatterChart(chart, "bubble");
+ };
+
+ defaultExport$2.prototype.destroy = function destroy (chart) {
+ if (chart.chart) {
+ chart.chart.destroy();
+ }
+ };
+
+ defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
+ this.destroy(chart);
+ if (chart.destroyed) { return; }
+
+ var chartOptions = {
+ type: type,
+ data: data,
+ options: options
+ };
+
+ if (chart.options.code) {
+ window.console.log("new Chart(ctx, " + JSON.stringify(chartOptions) + ");");
+ }
+
+ chart.element.innerHTML = "";
+ var ctx = chart.element.getElementsByTagName("CANVAS")[0];
+ chart.chart = new this.library(ctx, chartOptions);
+ };
+
+ var defaultOptions$1 = {
+ chart: {},
+ xAxis: {
+ title: {
+ text: null
+ },
+ labels: {
+ style: {
+ fontSize: "12px"
+ }
+ }
+ },
+ yAxis: {
+ title: {
+ text: null
+ },
+ labels: {
+ style: {
+ fontSize: "12px"
+ }
+ }
+ },
+ title: {
+ text: null
+ },
+ credits: {
+ enabled: false
+ },
+ legend: {
+ borderWidth: 0
+ },
+ tooltip: {
+ style: {
+ fontSize: "12px"
+ }
+ },
+ plotOptions: {
+ areaspline: {},
+ area: {},
+ series: {
+ marker: {}
+ }
+ },
+ time: {
+ useUTC: false
+ }
+ };
+
+ function hideLegend$1(options, legend, hideLegend) {
+ if (legend !== undefined) {
+ options.legend.enabled = !!legend;
+ if (legend && legend !== true) {
+ if (legend === "top" || legend === "bottom") {
+ options.legend.verticalAlign = legend;
+ } else {
+ options.legend.layout = "vertical";
+ options.legend.verticalAlign = "middle";
+ options.legend.align = legend;
+ }
+ }
+ } else if (hideLegend) {
+ options.legend.enabled = false;
+ }
+ }
+
+ function setTitle$1(options, title) {
+ options.title.text = title;
+ }
+
+ function setMin$1(options, min) {
+ options.yAxis.min = min;
+ }
+
+ function setMax$1(options, max) {
+ options.yAxis.max = max;
+ }
+
+ function setStacked$1(options, stacked) {
+ var stackedValue = stacked ? (stacked === true ? "normal" : stacked) : null;
+ options.plotOptions.series.stacking = stackedValue;
+ options.plotOptions.area.stacking = stackedValue;
+ options.plotOptions.areaspline.stacking = stackedValue;
+ }
+
+ function setXtitle$1(options, title) {
+ options.xAxis.title.text = title;
+ }
+
+ function setYtitle$1(options, title) {
+ options.yAxis.title.text = title;
+ }
+
+ var jsOptions$1 = jsOptionsFunc(defaultOptions$1, hideLegend$1, setTitle$1, setMin$1, setMax$1, setStacked$1, setXtitle$1, setYtitle$1);
+
+ function setFormatOptions(chart, options, chartType) {
+ var formatOptions = {
+ prefix: chart.options.prefix,
+ suffix: chart.options.suffix,
+ thousands: chart.options.thousands,
+ decimal: chart.options.decimal,
+ precision: chart.options.precision,
+ round: chart.options.round,
+ zeros: chart.options.zeros
+ };
+
+ // skip when axis is an array (like with min/max)
+ if (chartType !== "pie" && !isArray(options.yAxis) && !options.yAxis.labels.formatter) {
+ options.yAxis.labels.formatter = function () {
+ return formatValue("", this.value, formatOptions);
+ };
+ }
+
+ if (!options.tooltip.pointFormatter && !options.tooltip.pointFormat) {
+ options.tooltip.pointFormatter = function () {
+ return '\u25CF ' + formatValue(this.series.name + ': ', this.y, formatOptions) + '
';
+ };
+ }
+ }
+
+ var defaultExport$1 = function defaultExport(library) {
+ this.name = "highcharts";
+ this.library = library;
+ };
+
+ defaultExport$1.prototype.renderLineChart = function renderLineChart (chart, chartType) {
+ chartType = chartType || "spline";
+ var chartOptions = {};
+ if (chartType === "areaspline") {
+ chartOptions = {
+ plotOptions: {
+ areaspline: {
+ stacking: "normal"
+ },
+ area: {
+ stacking: "normal"
+ },
+ series: {
+ marker: {
+ enabled: false
+ }
+ }
+ }
+ };
+ }
+
+ if (chart.options.curve === false) {
+ if (chartType === "areaspline") {
+ chartType = "area";
+ } else if (chartType === "spline") {
+ chartType = "line";
+ }
+ }
+
+ var options = jsOptions$1(chart, chart.options, chartOptions);
+ if (chart.xtype === "number") {
+ options.xAxis.type = options.xAxis.type || "linear";
+ } else {
+ options.xAxis.type = chart.xtype === "string" ? "category" : "datetime";
+ }
+ if (!options.chart.type) {
+ options.chart.type = chartType;
+ }
+ setFormatOptions(chart, options, chartType);
+
+ var series = chart.data;
+ for (var i = 0; i < series.length; i++) {
+ series[i].name = series[i].name || "Value";
+ var data = series[i].data;
+ if (chart.xtype === "datetime") {
+ for (var j = 0; j < data.length; j++) {
+ data[j][0] = data[j][0].getTime();
+ }
+ } else if (chart.xtype === "number") {
+ data.sort(sortByNumberSeries);
+ }
+ series[i].marker = {symbol: "circle"};
+ if (chart.options.points === false) {
+ series[i].marker.enabled = false;
+ }
+ }
+
+ this.drawChart(chart, series, options);
+ };
+
+ defaultExport$1.prototype.renderScatterChart = function renderScatterChart (chart) {
+ var options = jsOptions$1(chart, chart.options, {});
+ options.chart.type = "scatter";
+ this.drawChart(chart, chart.data, options);
+ };
+
+ defaultExport$1.prototype.renderPieChart = function renderPieChart (chart) {
+ var chartOptions = merge(defaultOptions$1, {});
+
+ if (chart.options.colors) {
+ chartOptions.colors = chart.options.colors;
+ }
+ if (chart.options.donut) {
+ chartOptions.plotOptions = {pie: {innerSize: "50%"}};
+ }
+
+ if ("legend" in chart.options) {
+ hideLegend$1(chartOptions, chart.options.legend);
+ }
+
+ if (chart.options.title) {
+ setTitle$1(chartOptions, chart.options.title);
+ }
+
+ var options = merge(chartOptions, chart.options.library || {});
+ setFormatOptions(chart, options, "pie");
+ var series = [{
+ type: "pie",
+ name: chart.options.label || "Value",
+ data: chart.data
+ }];
+
+ this.drawChart(chart, series, options);
+ };
+
+ defaultExport$1.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
+ chartType = chartType || "column";
+ var series = chart.data;
+ var options = jsOptions$1(chart, chart.options);
+ var rows = [];
+ var categories = [];
+ options.chart.type = chartType;
+ setFormatOptions(chart, options, chartType);
+
+ for (var i = 0; i < series.length; i++) {
+ var s = series[i];
+
+ for (var j = 0; j < s.data.length; j++) {
+ var d = s.data[j];
+ if (!rows[d[0]]) {
+ rows[d[0]] = new Array(series.length);
+ categories.push(d[0]);
+ }
+ rows[d[0]][i] = d[1];
+ }
+ }
+
+ if (chart.xtype === "number") {
+ categories.sort(sortByNumber);
+ }
+
+ options.xAxis.categories = categories;
+
+ var newSeries = [];
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
+ var d$1 = [];
+ for (var j$1 = 0; j$1 < categories.length; j$1++) {
+ d$1.push(rows[categories[j$1]][i$1] || 0);
+ }
+
+ var d2 = {
+ name: series[i$1].name || "Value",
+ data: d$1
+ };
+ if (series[i$1].stack) {
+ d2.stack = series[i$1].stack;
+ }
+
+ newSeries.push(d2);
+ }
+
+ this.drawChart(chart, newSeries, options);
+ };
+
+ defaultExport$1.prototype.renderBarChart = function renderBarChart (chart) {
+ this.renderColumnChart(chart, "bar");
+ };
+
+ defaultExport$1.prototype.renderAreaChart = function renderAreaChart (chart) {
+ this.renderLineChart(chart, "areaspline");
+ };
+
+ defaultExport$1.prototype.destroy = function destroy (chart) {
+ if (chart.chart) {
+ chart.chart.destroy();
+ }
+ };
+
+ defaultExport$1.prototype.drawChart = function drawChart (chart, data, options) {
+ this.destroy(chart);
+ if (chart.destroyed) { return; }
+
+ options.chart.renderTo = chart.element.id;
+ options.series = data;
+
+ if (chart.options.code) {
+ window.console.log("new Highcharts.Chart(" + JSON.stringify(options) + ");");
+ }
+
+ chart.chart = new this.library.Chart(options);
+ };
+
+ var loaded = {};
+ var callbacks = [];
+
+ // Set chart options
+ var defaultOptions = {
+ chartArea: {},
+ fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
+ pointSize: 6,
+ legend: {
+ textStyle: {
+ fontSize: 12,
+ color: "#444"
+ },
+ alignment: "center",
+ position: "right"
+ },
+ curveType: "function",
+ hAxis: {
+ textStyle: {
+ color: "#666",
+ fontSize: 12
+ },
+ titleTextStyle: {},
+ gridlines: {
+ color: "transparent"
+ },
+ baselineColor: "#ccc",
+ viewWindow: {}
+ },
+ vAxis: {
+ textStyle: {
+ color: "#666",
+ fontSize: 12
+ },
+ titleTextStyle: {},
+ baselineColor: "#ccc",
+ viewWindow: {}
+ },
+ tooltip: {
+ textStyle: {
+ color: "#666",
+ fontSize: 12
+ }
+ }
+ };
+
+ function hideLegend(options, legend, hideLegend) {
+ if (legend !== undefined) {
+ var position;
+ if (!legend) {
+ position = "none";
+ } else if (legend === true) {
+ position = "right";
+ } else {
+ position = legend;
+ }
+ options.legend.position = position;
+ } else if (hideLegend) {
+ options.legend.position = "none";
+ }
+ }
+
+ function setTitle(options, title) {
+ options.title = title;
+ options.titleTextStyle = {color: "#333", fontSize: "20px"};
+ }
+
+ function setMin(options, min) {
+ options.vAxis.viewWindow.min = min;
+ }
+
+ function setMax(options, max) {
+ options.vAxis.viewWindow.max = max;
+ }
+
+ function setBarMin(options, min) {
+ options.hAxis.viewWindow.min = min;
+ }
+
+ function setBarMax(options, max) {
+ options.hAxis.viewWindow.max = max;
+ }
+
+ function setStacked(options, stacked) {
+ options.isStacked = stacked || false;
+ }
+
+ function setXtitle(options, title) {
+ options.hAxis.title = title;
+ options.hAxis.titleTextStyle.italic = false;
+ }
+
+ function setYtitle(options, title) {
+ options.vAxis.title = title;
+ options.vAxis.titleTextStyle.italic = false;
+ }
+
+ var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
+
+ function resize(callback) {
+ if (window.attachEvent) {
+ window.attachEvent("onresize", callback);
+ } else if (window.addEventListener) {
+ window.addEventListener("resize", callback, true);
+ }
+ callback();
+ }
+
+ var defaultExport = function defaultExport(library) {
+ this.name = "google";
+ this.library = library;
+ };
+
+ defaultExport.prototype.renderLineChart = function renderLineChart (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, function () {
+ var chartOptions = {};
+
+ if (chart.options.curve === false) {
+ chartOptions.curveType = "none";
+ }
+
+ if (chart.options.points === false) {
+ chartOptions.pointSize = 0;
+ }
+
+ var options = jsOptions(chart, chart.options, chartOptions);
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
+
+ this$1$1.drawChart(chart, "LineChart", data, options);
+ });
+ };
+
+ defaultExport.prototype.renderPieChart = function renderPieChart (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, function () {
+ var chartOptions = {
+ chartArea: {
+ top: "10%",
+ height: "80%"
+ },
+ legend: {}
+ };
+ if (chart.options.colors) {
+ chartOptions.colors = chart.options.colors;
+ }
+ if (chart.options.donut) {
+ chartOptions.pieHole = 0.5;
+ }
+ if ("legend" in chart.options) {
+ hideLegend(chartOptions, chart.options.legend);
+ }
+ if (chart.options.title) {
+ setTitle(chartOptions, chart.options.title);
+ }
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
+
+ var data = new this$1$1.library.visualization.DataTable();
+ data.addColumn("string", "");
+ data.addColumn("number", "Value");
+ data.addRows(chart.data);
+
+ this$1$1.drawChart(chart, "PieChart", data, options);
+ });
+ };
+
+ defaultExport.prototype.renderColumnChart = function renderColumnChart (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, function () {
+ var options = jsOptions(chart, chart.options);
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
+
+ this$1$1.drawChart(chart, "ColumnChart", data, options);
+ });
+ };
+
+ defaultExport.prototype.renderBarChart = function renderBarChart (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, function () {
+ var chartOptions = {
+ hAxis: {
+ gridlines: {
+ color: "#ccc"
+ }
+ }
+ };
+ var options = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options, chartOptions);
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
+
+ this$1$1.drawChart(chart, "BarChart", data, options);
+ });
+ };
+
+ defaultExport.prototype.renderAreaChart = function renderAreaChart (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, function () {
+ var chartOptions = {
+ isStacked: true,
+ pointSize: 0,
+ areaOpacity: 0.5
+ };
+
+ var options = jsOptions(chart, chart.options, chartOptions);
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
+
+ this$1$1.drawChart(chart, "AreaChart", data, options);
+ });
+ };
+
+ defaultExport.prototype.renderGeoChart = function renderGeoChart (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, "geochart", function () {
+ var chartOptions = {
+ legend: "none",
+ colorAxis: {
+ colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
+ }
+ };
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
+
+ var data = new this$1$1.library.visualization.DataTable();
+ data.addColumn("string", "");
+ data.addColumn("number", chart.options.label || "Value");
+ data.addRows(chart.data);
+
+ this$1$1.drawChart(chart, "GeoChart", data, options);
+ });
+ };
+
+ defaultExport.prototype.renderScatterChart = function renderScatterChart (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, function () {
+ var chartOptions = {};
+ var options = jsOptions(chart, chart.options, chartOptions);
+
+ var series = chart.data;
+ var rows2 = [];
+ for (var i = 0; i < series.length; i++) {
+ series[i].name = series[i].name || "Value";
+ var d = series[i].data;
+ for (var j = 0; j < d.length; j++) {
+ var row = new Array(series.length + 1);
+ row[0] = d[j][0];
+ row[i + 1] = d[j][1];
+ rows2.push(row);
+ }
+ }
+
+ var data = new this$1$1.library.visualization.DataTable();
+ data.addColumn("number", "");
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
+ data.addColumn("number", series[i$1].name);
+ }
+ data.addRows(rows2);
+
+ this$1$1.drawChart(chart, "ScatterChart", data, options);
+ });
+ };
+
+ defaultExport.prototype.renderTimeline = function renderTimeline (chart) {
+ var this$1$1 = this;
+
+ this.waitForLoaded(chart, "timeline", function () {
+ var chartOptions = {
+ legend: "none"
+ };
+
+ if (chart.options.colors) {
+ chartOptions.colors = chart.options.colors;
+ }
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
+
+ var data = new this$1$1.library.visualization.DataTable();
+ data.addColumn({type: "string", id: "Name"});
+ data.addColumn({type: "date", id: "Start"});
+ data.addColumn({type: "date", id: "End"});
+ data.addRows(chart.data);
+
+ chart.element.style.lineHeight = "normal";
+
+ this$1$1.drawChart(chart, "Timeline", data, options);
+ });
+ };
+
+ // TODO remove resize events
+ defaultExport.prototype.destroy = function destroy (chart) {
+ if (chart.chart) {
+ chart.chart.clearChart();
+ }
+ };
+
+ defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
+ this.destroy(chart);
+ if (chart.destroyed) { return; }
+
+ if (chart.options.code) {
+ window.console.log("var data = new google.visualization.DataTable(" + data.toJSON() + ");\nvar chart = new google.visualization." + type + "(element);\nchart.draw(data, " + JSON.stringify(options) + ");");
+ }
+
+ chart.chart = new this.library.visualization[type](chart.element);
+ resize(function () {
+ chart.chart.draw(data, options);
+ });
+ };
+
+ defaultExport.prototype.waitForLoaded = function waitForLoaded (chart, pack, callback) {
+ var this$1$1 = this;
+
+ if (!callback) {
+ callback = pack;
+ pack = "corechart";
+ }
+
+ callbacks.push({pack: pack, callback: callback});
+
+ if (loaded[pack]) {
+ this.runCallbacks();
+ } else {
+ loaded[pack] = true;
+
+ // https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
+ var loadOptions = {
+ packages: [pack],
+ callback: function () { this$1$1.runCallbacks(); }
+ };
+ var config = chart.__config();
+ if (config.language) {
+ loadOptions.language = config.language;
+ }
+ if (pack === "geochart" && config.mapsApiKey) {
+ loadOptions.mapsApiKey = config.mapsApiKey;
+ }
+
+ this.library.charts.load("current", loadOptions);
+ }
+ };
+
+ defaultExport.prototype.runCallbacks = function runCallbacks () {
+ for (var i = 0; i < callbacks.length; i++) {
+ var cb = callbacks[i];
+ var call = this.library.visualization && ((cb.pack === "corechart" && this.library.visualization.LineChart) || (cb.pack === "timeline" && this.library.visualization.Timeline) || (cb.pack === "geochart" && this.library.visualization.GeoChart));
+ if (call) {
+ cb.callback();
+ callbacks.splice(i, 1);
+ i--;
+ }
+ }
+ };
+
+ // cant use object as key
+ defaultExport.prototype.createDataTable = function createDataTable (series, columnType) {
+ var rows = [];
+ var sortedLabels = [];
+ for (var i = 0; i < series.length; i++) {
+ var s = series[i];
+ series[i].name = series[i].name || "Value";
+
+ for (var j = 0; j < s.data.length; j++) {
+ var d = s.data[j];
+ var key = columnType === "datetime" ? d[0].getTime() : d[0];
+ if (!rows[key]) {
+ rows[key] = new Array(series.length);
+ sortedLabels.push(key);
+ }
+ rows[key][i] = d[1];
+ }
+ }
+
+ var rows2 = [];
+ var values = [];
+ for (var j$1 = 0; j$1 < sortedLabels.length; j$1++) {
+ var i$1 = sortedLabels[j$1];
+ var value = (void 0);
+ if (columnType === "datetime") {
+ value = new Date(i$1);
+ values.push(value);
+ } else {
+ value = i$1;
+ }
+ rows2.push([value].concat(rows[i$1]));
+ }
+
+ var day = true;
+ if (columnType === "datetime") {
+ rows2.sort(sortByTime);
+
+ var timeUnit = calculateTimeUnit(values, true);
+ day = isDay(timeUnit);
+ } else if (columnType === "number") {
+ rows2.sort(sortByNumberSeries);
+
+ for (var i$2 = 0; i$2 < rows2.length; i$2++) {
+ rows2[i$2][0] = toStr(rows2[i$2][0]);
+ }
+
+ columnType = "string";
+ }
+
+ // create datatable
+ var data = new this.library.visualization.DataTable();
+ columnType = columnType === "datetime" && day ? "date" : columnType;
+ data.addColumn(columnType, "");
+ for (var i$3 = 0; i$3 < series.length; i$3++) {
+ data.addColumn("number", series[i$3].name);
+ }
+ data.addRows(rows2);
+
+ return data;
+ };
+
+ var adapters = [];
+
+ function getAdapterType(library) {
+ if (library) {
+ if (library.product === "Highcharts") {
+ return defaultExport$1;
+ } else if (library.charts) {
+ return defaultExport;
+ } else if (isFunction(library)) {
+ return defaultExport$2;
+ }
+ }
+ throw new Error("Unknown adapter");
+ }
+
+ function addAdapter(library) {
+ var adapterType = getAdapterType(library);
+
+ for (var i = 0; i < adapters.length; i++) {
+ if (adapters[i].library === library) {
+ return;
+ }
+ }
+
+ adapters.push(new adapterType(library));
+ }
+
+ function loadAdapters() {
+ if ("Chart" in window) {
+ addAdapter(window.Chart);
+ }
+
+ if ("Highcharts" in window) {
+ addAdapter(window.Highcharts);
+ }
+
+ if (window.google && window.google.charts) {
+ addAdapter(window.google);
+ }
+ }
+
+ // TODO remove chartType if cross-browser way
+ // to get the name of the chart class
+ function callAdapter(chartType, chart) {
+ var fnName = "render" + chartType;
+ var adapterName = chart.options.adapter;
+
+ loadAdapters();
+
+ for (var i = 0; i < adapters.length; i++) {
+ var adapter = adapters[i];
+ if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
+ chart.adapter = adapter.name;
+ chart.__adapterObject = adapter;
+ return adapter[fnName](chart);
+ }
+ }
+
+ if (adapters.length > 0) {
+ throw new Error("No charting library found for " + chartType);
+ } else {
+ throw new Error("No charting libraries found - be sure to include one before your charts");
+ }
+ }
+
+ var Chartkick = {
+ charts: {},
+ configure: function (options) {
+ for (var key in options) {
+ if (Object.prototype.hasOwnProperty.call(options, key)) {
+ Chartkick.config[key] = options[key];
+ }
+ }
+ },
+ setDefaultOptions: function (opts) {
+ Chartkick.options = opts;
+ },
+ eachChart: function (callback) {
+ for (var chartId in Chartkick.charts) {
+ if (Object.prototype.hasOwnProperty.call(Chartkick.charts, chartId)) {
+ callback(Chartkick.charts[chartId]);
+ }
+ }
+ },
+ destroyAll: function () {
+ for (var chartId in Chartkick.charts) {
+ if (Object.prototype.hasOwnProperty.call(Chartkick.charts, chartId)) {
+ Chartkick.charts[chartId].destroy();
+ delete Chartkick.charts[chartId];
+ }
+ }
+ },
+ config: {},
+ options: {},
+ adapters: adapters,
+ addAdapter: addAdapter,
+ use: function (adapter) {
+ addAdapter(adapter);
+ return Chartkick;
+ }
+ };
+
+ function formatSeriesBubble(data) {
+ var r = [];
+ for (var i = 0; i < data.length; i++) {
+ r.push([toFloat(data[i][0]), toFloat(data[i][1]), toFloat(data[i][2])]);
+ }
+ return r;
+ }
+
+ // casts data to proper type
+ // sorting is left to adapters
+ function formatSeriesData(data, keyType) {
+ if (keyType === "bubble") {
+ return formatSeriesBubble(data);
+ }
+
+ var keyFunc;
+ if (keyType === "number") {
+ keyFunc = toFloat;
+ } else if (keyType === "datetime") {
+ keyFunc = toDate;
+ } else {
+ keyFunc = toStr;
+ }
+
+ var r = [];
+ for (var i = 0; i < data.length; i++) {
+ r.push([keyFunc(data[i][0]), toFloat(data[i][1])]);
+ }
+ return r;
+ }
+
+ function detectXType(series, noDatetime, options) {
+ if (dataEmpty(series)) {
+ if ((options.xmin || options.xmax) && (!options.xmin || isDate(options.xmin)) && (!options.xmax || isDate(options.xmax))) {
+ return "datetime";
+ } else {
+ return "number";
+ }
+ } else if (detectXTypeWithFunction(series, isNumber)) {
+ return "number";
+ } else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
+ return "datetime";
+ } else {
+ return "string";
+ }
+ }
+
+ function detectXTypeWithFunction(series, func) {
+ for (var i = 0; i < series.length; i++) {
+ var data = toArr(series[i].data);
+ for (var j = 0; j < data.length; j++) {
+ if (!func(data[j][0])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // creates a shallow copy of each element of the array
+ // elements are expected to be objects
+ function copySeries(series) {
+ var newSeries = [];
+ for (var i = 0; i < series.length; i++) {
+ var copy = {};
+ for (var j in series[i]) {
+ if (Object.prototype.hasOwnProperty.call(series[i], j)) {
+ copy[j] = series[i][j];
+ }
+ }
+ newSeries.push(copy);
+ }
+ return newSeries;
+ }
+
+ function processSeries(chart, keyType, noDatetime) {
+ var opts = chart.options;
+ var series = chart.rawData;
+
+ // see if one series or multiple
+ chart.singleSeriesFormat = !isArray(series) || !isPlainObject(series[0]);
+ if (chart.singleSeriesFormat) {
+ series = [{name: opts.label, data: series}];
+ }
+
+ // convert to array
+ // must come before dataEmpty check
+ series = copySeries(series);
+ for (var i = 0; i < series.length; i++) {
+ series[i].data = toArr(series[i].data);
+ }
+
+ chart.xtype = keyType || (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
+
+ // right format
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
+ series[i$1].data = formatSeriesData(series[i$1].data, chart.xtype);
+ }
+
+ return series;
+ }
+
+ function processSimple(chart) {
+ var perfectData = toArr(chart.rawData);
+ for (var i = 0; i < perfectData.length; i++) {
+ perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
+ }
+ return perfectData;
+ }
+
+ function dataEmpty(data, chartType) {
+ if (chartType === "PieChart" || chartType === "GeoChart" || chartType === "Timeline") {
+ return data.length === 0;
+ } else {
+ for (var i = 0; i < data.length; i++) {
+ if (data[i].data.length > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ function addDownloadButton(chart) {
+ var download = chart.options.download;
+ if (download === true) {
+ download = {};
+ } else if (typeof download === "string") {
+ download = {filename: download};
+ }
+
+ var link = document.createElement("a");
+ link.download = download.filename || "chart.png";
+ link.style.position = "absolute";
+ link.style.top = "20px";
+ link.style.right = "20px";
+ link.style.zIndex = 1000;
+ link.style.lineHeight = "20px";
+ link.target = "_blank"; // for safari
+
+ var image = document.createElement("img");
+ // icon from Font Awesome, modified to set fill color
+ var svg = "";
+ image.src = "data:image/svg+xml;utf8," + (encodeURIComponent(svg));
+ image.alt = "Download";
+ image.style.width = "20px";
+ image.style.height = "20px";
+ image.style.border = "none";
+ link.appendChild(image);
+
+ var element = chart.element;
+ element.style.position = "relative";
+
+ chart.__downloadAttached = true;
+
+ // mouseenter
+ chart.__enterEvent = element.addEventListener("mouseover", function (e) {
+ var related = e.relatedTarget;
+ // check download option again to ensure it wasn't changed
+ if ((!related || (related !== this && !this.contains(related))) && chart.options.download) {
+ link.href = chart.toImage(download);
+ element.appendChild(link);
+ }
+ });
+
+ // mouseleave
+ chart.__leaveEvent = element.addEventListener("mouseout", function (e) {
+ var related = e.relatedTarget;
+ if (!related || (related !== this && !this.contains(related))) {
+ if (link.parentNode) {
+ link.parentNode.removeChild(link);
+ }
+ }
+ });
+ }
+
+ var pendingRequests = [];
+ var runningRequests = 0;
+ var maxRequests = 4;
+
+ function pushRequest(url, success, error) {
+ pendingRequests.push([url, success, error]);
+ runNext();
+ }
+
+ function runNext() {
+ if (runningRequests < maxRequests) {
+ var request = pendingRequests.shift();
+ if (request) {
+ runningRequests++;
+ getJSON(request[0], request[1], request[2]);
+ runNext();
+ }
+ }
+ }
+
+ function requestComplete() {
+ runningRequests--;
+ runNext();
+ }
+
+ function getJSON(url, success, error) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, true);
+ xhr.setRequestHeader("Content-Type", "application/json");
+ xhr.onload = function () {
+ requestComplete();
+ if (xhr.status === 200) {
+ success(JSON.parse(xhr.responseText));
+ } else {
+ error(xhr.statusText);
+ }
+ };
+ xhr.send();
+ }
+
+ // helpers
+
+ function setText(element, text) {
+ element.textContent = text;
+ }
+
+ // TODO remove prefix for all messages
+ function chartError(element, message, noPrefix) {
+ if (!noPrefix) {
+ message = "Error Loading Chart: " + message;
+ }
+ setText(element, message);
+ element.style.color = "#ff0000";
+ }
+
+ function errorCatcher(chart) {
+ try {
+ chart.__render();
+ } catch (err) {
+ chartError(chart.element, err.message);
+ throw err;
+ }
+ }
+
+ function fetchDataSource(chart, dataSource, showLoading) {
+ // only show loading message for urls and callbacks
+ if (showLoading && chart.options.loading && (typeof dataSource === "string" || typeof dataSource === "function")) {
+ setText(chart.element, chart.options.loading);
+ }
+
+ if (typeof dataSource === "string") {
+ pushRequest(dataSource, function (data) {
+ chart.rawData = data;
+ errorCatcher(chart);
+ }, function (message) {
+ chartError(chart.element, message);
+ });
+ } else if (typeof dataSource === "function") {
+ try {
+ dataSource(function (data) {
+ chart.rawData = data;
+ errorCatcher(chart);
+ }, function (message) {
+ chartError(chart.element, message, true);
+ });
+ } catch (err) {
+ chartError(chart.element, err, true);
+ }
+ } else {
+ chart.rawData = dataSource;
+ errorCatcher(chart);
+ }
+ }
+
+ function renderChart(chartType, chart) {
+ if (dataEmpty(chart.data, chartType)) {
+ var message = chart.options.empty || (chart.options.messages && chart.options.messages.empty) || "No data";
+ setText(chart.element, message);
+ } else {
+ callAdapter(chartType, chart);
+ // TODO add downloadSupported method to adapter
+ if (chart.options.download && !chart.__downloadAttached && chart.adapter === "chartjs") {
+ addDownloadButton(chart);
+ }
+ }
+ }
+
+ function getElement(element) {
+ if (typeof element === "string") {
+ var elementId = element;
+ element = document.getElementById(element);
+ if (!element) {
+ throw new Error("No element with id " + elementId);
+ }
+ }
+ return element;
+ }
+
+ // define classes
+
+ var Chart = function Chart(element, dataSource, options) {
+ this.element = getElement(element);
+ this.options = merge(Chartkick.options, options || {});
+ this.dataSource = dataSource;
+
+ // TODO handle charts without an id for eachChart and destroyAll
+ if (this.element.id) {
+ Chartkick.charts[this.element.id] = this;
+ }
+
+ fetchDataSource(this, dataSource, true);
+
+ if (this.options.refresh) {
+ this.startRefresh();
+ }
+ };
+
+ Chart.prototype.getElement = function getElement () {
+ return this.element;
+ };
+
+ Chart.prototype.getDataSource = function getDataSource () {
+ return this.dataSource;
+ };
+
+ Chart.prototype.getData = function getData () {
+ return this.data;
+ };
+
+ Chart.prototype.getOptions = function getOptions () {
+ return this.options;
+ };
+
+ Chart.prototype.getChartObject = function getChartObject () {
+ return this.chart;
+ };
+
+ Chart.prototype.getAdapter = function getAdapter () {
+ return this.adapter;
+ };
+
+ Chart.prototype.updateData = function updateData (dataSource, options) {
+ this.dataSource = dataSource;
+ if (options) {
+ this.__updateOptions(options);
+ }
+ fetchDataSource(this, dataSource, true);
+ };
+
+ Chart.prototype.setOptions = function setOptions (options) {
+ this.__updateOptions(options);
+ this.redraw();
+ };
+
+ Chart.prototype.redraw = function redraw () {
+ fetchDataSource(this, this.rawData);
+ };
+
+ Chart.prototype.refreshData = function refreshData () {
+ if (typeof this.dataSource === "string") {
+ // prevent browser from caching
+ var sep = this.dataSource.indexOf("?") === -1 ? "?" : "&";
+ var url = this.dataSource + sep + "_=" + (new Date()).getTime();
+ fetchDataSource(this, url);
+ } else if (typeof this.dataSource === "function") {
+ fetchDataSource(this, this.dataSource);
+ }
+ };
+
+ Chart.prototype.startRefresh = function startRefresh () {
+ var this$1$1 = this;
+
+ var refresh = this.options.refresh;
+
+ if (refresh && typeof this.dataSource !== "string" && typeof this.dataSource !== "function") {
+ throw new Error("Data source must be a URL or callback for refresh");
+ }
+
+ if (!this.intervalId) {
+ if (refresh) {
+ this.intervalId = setInterval(function () {
+ this$1$1.refreshData();
+ }, refresh * 1000);
+ } else {
+ throw new Error("No refresh interval");
+ }
+ }
+ };
+
+ Chart.prototype.stopRefresh = function stopRefresh () {
+ if (this.intervalId) {
+ clearInterval(this.intervalId);
+ this.intervalId = null;
+ }
+ };
+
+ Chart.prototype.toImage = function toImage (download) {
+ // TODO move logic to adapter
+ if (this.adapter === "chartjs") {
+ if (download && download.background && download.background !== "transparent") {
+ // https://stackoverflow.com/questions/30464750/chartjs-line-chart-set-background-color
+ var canvas = this.chart.canvas;
+ var ctx = this.chart.ctx;
+ var tmpCanvas = document.createElement("canvas");
+ var tmpCtx = tmpCanvas.getContext("2d");
+ tmpCanvas.width = ctx.canvas.width;
+ tmpCanvas.height = ctx.canvas.height;
+ tmpCtx.fillStyle = download.background;
+ tmpCtx.fillRect(0, 0, tmpCanvas.width, tmpCanvas.height);
+ tmpCtx.drawImage(canvas, 0, 0);
+ return tmpCanvas.toDataURL("image/png");
+ } else {
+ return this.chart.toBase64Image();
+ }
+ } else {
+ throw new Error("Feature only available for Chart.js");
+ }
+ };
+
+ Chart.prototype.destroy = function destroy () {
+ this.destroyed = true;
+ this.stopRefresh();
+
+ if (this.__adapterObject) {
+ this.__adapterObject.destroy(this);
+ }
+
+ if (this.__enterEvent) {
+ this.element.removeEventListener("mouseover", this.__enterEvent);
+ }
+
+ if (this.__leaveEvent) {
+ this.element.removeEventListener("mouseout", this.__leaveEvent);
+ }
+ };
+
+ Chart.prototype.__updateOptions = function __updateOptions (options) {
+ var updateRefresh = options.refresh && options.refresh !== this.options.refresh;
+ this.options = merge(Chartkick.options, options);
+ if (updateRefresh) {
+ this.stopRefresh();
+ this.startRefresh();
+ }
+ };
+
+ Chart.prototype.__render = function __render () {
+ this.data = this.__processData();
+ renderChart(this.__chartName(), this);
+ };
+
+ Chart.prototype.__config = function __config () {
+ return Chartkick.config;
+ };
+
+ var LineChart = /*@__PURE__*/(function (Chart) {
+ function LineChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) LineChart.__proto__ = Chart;
+ LineChart.prototype = Object.create( Chart && Chart.prototype );
+ LineChart.prototype.constructor = LineChart;
+
+ LineChart.prototype.__processData = function __processData () {
+ return processSeries(this);
+ };
+
+ LineChart.prototype.__chartName = function __chartName () {
+ return "LineChart";
+ };
+
+ return LineChart;
+ }(Chart));
+
+ var PieChart = /*@__PURE__*/(function (Chart) {
+ function PieChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) PieChart.__proto__ = Chart;
+ PieChart.prototype = Object.create( Chart && Chart.prototype );
+ PieChart.prototype.constructor = PieChart;
+
+ PieChart.prototype.__processData = function __processData () {
+ return processSimple(this);
+ };
+
+ PieChart.prototype.__chartName = function __chartName () {
+ return "PieChart";
+ };
+
+ return PieChart;
+ }(Chart));
+
+ var ColumnChart = /*@__PURE__*/(function (Chart) {
+ function ColumnChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) ColumnChart.__proto__ = Chart;
+ ColumnChart.prototype = Object.create( Chart && Chart.prototype );
+ ColumnChart.prototype.constructor = ColumnChart;
+
+ ColumnChart.prototype.__processData = function __processData () {
+ return processSeries(this, null, true);
+ };
+
+ ColumnChart.prototype.__chartName = function __chartName () {
+ return "ColumnChart";
+ };
+
+ return ColumnChart;
+ }(Chart));
+
+ var BarChart = /*@__PURE__*/(function (Chart) {
+ function BarChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) BarChart.__proto__ = Chart;
+ BarChart.prototype = Object.create( Chart && Chart.prototype );
+ BarChart.prototype.constructor = BarChart;
+
+ BarChart.prototype.__processData = function __processData () {
+ return processSeries(this, null, true);
+ };
+
+ BarChart.prototype.__chartName = function __chartName () {
+ return "BarChart";
+ };
+
+ return BarChart;
+ }(Chart));
+
+ var AreaChart = /*@__PURE__*/(function (Chart) {
+ function AreaChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) AreaChart.__proto__ = Chart;
+ AreaChart.prototype = Object.create( Chart && Chart.prototype );
+ AreaChart.prototype.constructor = AreaChart;
+
+ AreaChart.prototype.__processData = function __processData () {
+ return processSeries(this);
+ };
+
+ AreaChart.prototype.__chartName = function __chartName () {
+ return "AreaChart";
+ };
+
+ return AreaChart;
+ }(Chart));
+
+ var GeoChart = /*@__PURE__*/(function (Chart) {
+ function GeoChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) GeoChart.__proto__ = Chart;
+ GeoChart.prototype = Object.create( Chart && Chart.prototype );
+ GeoChart.prototype.constructor = GeoChart;
+
+ GeoChart.prototype.__processData = function __processData () {
+ return processSimple(this);
+ };
+
+ GeoChart.prototype.__chartName = function __chartName () {
+ return "GeoChart";
+ };
+
+ return GeoChart;
+ }(Chart));
+
+ var ScatterChart = /*@__PURE__*/(function (Chart) {
+ function ScatterChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) ScatterChart.__proto__ = Chart;
+ ScatterChart.prototype = Object.create( Chart && Chart.prototype );
+ ScatterChart.prototype.constructor = ScatterChart;
+
+ ScatterChart.prototype.__processData = function __processData () {
+ return processSeries(this, "number");
+ };
+
+ ScatterChart.prototype.__chartName = function __chartName () {
+ return "ScatterChart";
+ };
+
+ return ScatterChart;
+ }(Chart));
+
+ var BubbleChart = /*@__PURE__*/(function (Chart) {
+ function BubbleChart () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) BubbleChart.__proto__ = Chart;
+ BubbleChart.prototype = Object.create( Chart && Chart.prototype );
+ BubbleChart.prototype.constructor = BubbleChart;
+
+ BubbleChart.prototype.__processData = function __processData () {
+ return processSeries(this, "bubble");
+ };
+
+ BubbleChart.prototype.__chartName = function __chartName () {
+ return "BubbleChart";
+ };
+
+ return BubbleChart;
+ }(Chart));
+
+ var Timeline = /*@__PURE__*/(function (Chart) {
+ function Timeline () {
+ Chart.apply(this, arguments);
+ }
+
+ if ( Chart ) Timeline.__proto__ = Chart;
+ Timeline.prototype = Object.create( Chart && Chart.prototype );
+ Timeline.prototype.constructor = Timeline;
+
+ Timeline.prototype.__processData = function __processData () {
+ var data = this.rawData;
+ for (var i = 0; i < data.length; i++) {
+ data[i][1] = toDate(data[i][1]);
+ data[i][2] = toDate(data[i][2]);
+ }
+ return data;
+ };
+
+ Timeline.prototype.__chartName = function __chartName () {
+ return "Timeline";
+ };
+
+ return Timeline;
+ }(Chart));
+
+ Chartkick.LineChart = LineChart;
+ Chartkick.PieChart = PieChart;
+ Chartkick.ColumnChart = ColumnChart;
+ Chartkick.BarChart = BarChart;
+ Chartkick.AreaChart = AreaChart;
+ Chartkick.GeoChart = GeoChart;
+ Chartkick.ScatterChart = ScatterChart;
+ Chartkick.BubbleChart = BubbleChart;
+ Chartkick.Timeline = Timeline;
+
+ // not ideal, but allows for simpler integration
+ if (typeof window !== "undefined" && !window.Chartkick) {
+ window.Chartkick = Chartkick;
+
+ // clean up previous charts before Turbolinks loads new page
+ document.addEventListener("turbolinks:before-render", function () {
+ if (Chartkick.config.autoDestroy !== false) {
+ Chartkick.destroyAll();
+ }
+ });
+
+ // clean up previous charts before Turbo loads new page
+ document.addEventListener("turbo:before-render", function () {
+ if (Chartkick.config.autoDestroy !== false) {
+ Chartkick.destroyAll();
+ }
+ });
+
+ // use setTimeout so charting library can come later in same JS file
+ setTimeout(function () {
+ window.dispatchEvent(new Event("chartkick:load"));
+ }, 0);
+ }
+
+ // backwards compatibility for esm require
+ Chartkick.default = Chartkick;
+
+ return Chartkick;
+
+}));