Travis now builds and deploys these files for all tags, so we don't need to have them on the repository anymore.
node_modules/*
custom/*
+dist/*
docs/index.md
+++ /dev/null
-/*!
- * Chart.js
- * http://chartjs.org/
- * Version: 2.1.6
- *
- * Copyright 2016 Nick Downie
- * Released under the MIT license
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
- */
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-/* MIT license */\r
-var colorNames = require(5);\r
-\r
-module.exports = {\r
- getRgba: getRgba,\r
- getHsla: getHsla,\r
- getRgb: getRgb,\r
- getHsl: getHsl,\r
- getHwb: getHwb,\r
- getAlpha: getAlpha,\r
-\r
- hexString: hexString,\r
- rgbString: rgbString,\r
- rgbaString: rgbaString,\r
- percentString: percentString,\r
- percentaString: percentaString,\r
- hslString: hslString,\r
- hslaString: hslaString,\r
- hwbString: hwbString,\r
- keyword: keyword\r
-}\r
-\r
-function getRgba(string) {\r
- if (!string) {\r
- return;\r
- }\r
- var abbr = /^#([a-fA-F0-9]{3})$/,\r
- hex = /^#([a-fA-F0-9]{6})$/,\r
- rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,\r
- per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,\r
- keyword = /(\w+)/;\r
-\r
- var rgb = [0, 0, 0],\r
- a = 1,\r
- match = string.match(abbr);\r
- if (match) {\r
- match = match[1];\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = parseInt(match[i] + match[i], 16);\r
- }\r
- }\r
- else if (match = string.match(hex)) {\r
- match = match[1];\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);\r
- }\r
- }\r
- else if (match = string.match(rgba)) {\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = parseInt(match[i + 1]);\r
- }\r
- a = parseFloat(match[4]);\r
- }\r
- else if (match = string.match(per)) {\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);\r
- }\r
- a = parseFloat(match[4]);\r
- }\r
- else if (match = string.match(keyword)) {\r
- if (match[1] == "transparent") {\r
- return [0, 0, 0, 0];\r
- }\r
- rgb = colorNames[match[1]];\r
- if (!rgb) {\r
- return;\r
- }\r
- }\r
-\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = scale(rgb[i], 0, 255);\r
- }\r
- if (!a && a != 0) {\r
- a = 1;\r
- }\r
- else {\r
- a = scale(a, 0, 1);\r
- }\r
- rgb[3] = a;\r
- return rgb;\r
-}\r
-\r
-function getHsla(string) {\r
- if (!string) {\r
- return;\r
- }\r
- var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;\r
- var match = string.match(hsl);\r
- if (match) {\r
- var alpha = parseFloat(match[4]);\r
- var h = scale(parseInt(match[1]), 0, 360),\r
- s = scale(parseFloat(match[2]), 0, 100),\r
- l = scale(parseFloat(match[3]), 0, 100),\r
- a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r
- return [h, s, l, a];\r
- }\r
-}\r
-\r
-function getHwb(string) {\r
- if (!string) {\r
- return;\r
- }\r
- var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;\r
- var match = string.match(hwb);\r
- if (match) {\r
- var alpha = parseFloat(match[4]);\r
- var h = scale(parseInt(match[1]), 0, 360),\r
- w = scale(parseFloat(match[2]), 0, 100),\r
- b = scale(parseFloat(match[3]), 0, 100),\r
- a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r
- return [h, w, b, a];\r
- }\r
-}\r
-\r
-function getRgb(string) {\r
- var rgba = getRgba(string);\r
- return rgba && rgba.slice(0, 3);\r
-}\r
-\r
-function getHsl(string) {\r
- var hsla = getHsla(string);\r
- return hsla && hsla.slice(0, 3);\r
-}\r
-\r
-function getAlpha(string) {\r
- var vals = getRgba(string);\r
- if (vals) {\r
- return vals[3];\r
- }\r
- else if (vals = getHsla(string)) {\r
- return vals[3];\r
- }\r
- else if (vals = getHwb(string)) {\r
- return vals[3];\r
- }\r
-}\r
-\r
-// generators\r
-function hexString(rgb) {\r
- return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])\r
- + hexDouble(rgb[2]);\r
-}\r
-\r
-function rgbString(rgba, alpha) {\r
- if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r
- return rgbaString(rgba, alpha);\r
- }\r
- return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";\r
-}\r
-\r
-function rgbaString(rgba, alpha) {\r
- if (alpha === undefined) {\r
- alpha = (rgba[3] !== undefined ? rgba[3] : 1);\r
- }\r
- return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]\r
- + ", " + alpha + ")";\r
-}\r
-\r
-function percentString(rgba, alpha) {\r
- if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r
- return percentaString(rgba, alpha);\r
- }\r
- var r = Math.round(rgba[0]/255 * 100),\r
- g = Math.round(rgba[1]/255 * 100),\r
- b = Math.round(rgba[2]/255 * 100);\r
-\r
- return "rgb(" + r + "%, " + g + "%, " + b + "%)";\r
-}\r
-\r
-function percentaString(rgba, alpha) {\r
- var r = Math.round(rgba[0]/255 * 100),\r
- g = Math.round(rgba[1]/255 * 100),\r
- b = Math.round(rgba[2]/255 * 100);\r
- return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";\r
-}\r
-\r
-function hslString(hsla, alpha) {\r
- if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {\r
- return hslaString(hsla, alpha);\r
- }\r
- return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";\r
-}\r
-\r
-function hslaString(hsla, alpha) {\r
- if (alpha === undefined) {\r
- alpha = (hsla[3] !== undefined ? hsla[3] : 1);\r
- }\r
- return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "\r
- + alpha + ")";\r
-}\r
-\r
-// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax\r
-// (hwb have alpha optional & 1 is default value)\r
-function hwbString(hwb, alpha) {\r
- if (alpha === undefined) {\r
- alpha = (hwb[3] !== undefined ? hwb[3] : 1);\r
- }\r
- return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"\r
- + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";\r
-}\r
-\r
-function keyword(rgb) {\r
- return reverseNames[rgb.slice(0, 3)];\r
-}\r
-\r
-// helpers\r
-function scale(num, min, max) {\r
- return Math.min(Math.max(min, num), max);\r
-}\r
-\r
-function hexDouble(num) {\r
- var str = num.toString(16).toUpperCase();\r
- return (str.length < 2) ? "0" + str : str;\r
-}\r
-\r
-\r
-//create a list of reverse color names\r
-var reverseNames = {};\r
-for (var name in colorNames) {\r
- reverseNames[colorNames[name]] = name;\r
-}\r
-
-},{"5":5}],2:[function(require,module,exports){
-/* MIT license */\r
-var convert = require(4);\r
-var string = require(1);\r
-\r
-var Color = function (obj) {\r
- if (obj instanceof Color) {\r
- return obj;\r
- }\r
- if (!(this instanceof Color)) {\r
- return new Color(obj);\r
- }\r
-\r
- this.values = {\r
- rgb: [0, 0, 0],\r
- hsl: [0, 0, 0],\r
- hsv: [0, 0, 0],\r
- hwb: [0, 0, 0],\r
- cmyk: [0, 0, 0, 0],\r
- alpha: 1\r
- };\r
-\r
- // parse Color() argument\r
- var vals;\r
- if (typeof obj === 'string') {\r
- vals = string.getRgba(obj);\r
- if (vals) {\r
- this.setValues('rgb', vals);\r
- } else if (vals = string.getHsla(obj)) {\r
- this.setValues('hsl', vals);\r
- } else if (vals = string.getHwb(obj)) {\r
- this.setValues('hwb', vals);\r
- } else {\r
- throw new Error('Unable to parse color from string "' + obj + '"');\r
- }\r
- } else if (typeof obj === 'object') {\r
- vals = obj;\r
- if (vals.r !== undefined || vals.red !== undefined) {\r
- this.setValues('rgb', vals);\r
- } else if (vals.l !== undefined || vals.lightness !== undefined) {\r
- this.setValues('hsl', vals);\r
- } else if (vals.v !== undefined || vals.value !== undefined) {\r
- this.setValues('hsv', vals);\r
- } else if (vals.w !== undefined || vals.whiteness !== undefined) {\r
- this.setValues('hwb', vals);\r
- } else if (vals.c !== undefined || vals.cyan !== undefined) {\r
- this.setValues('cmyk', vals);\r
- } else {\r
- throw new Error('Unable to parse color from object ' + JSON.stringify(obj));\r
- }\r
- }\r
-};\r
-\r
-Color.prototype = {\r
- rgb: function () {\r
- return this.setSpace('rgb', arguments);\r
- },\r
- hsl: function () {\r
- return this.setSpace('hsl', arguments);\r
- },\r
- hsv: function () {\r
- return this.setSpace('hsv', arguments);\r
- },\r
- hwb: function () {\r
- return this.setSpace('hwb', arguments);\r
- },\r
- cmyk: function () {\r
- return this.setSpace('cmyk', arguments);\r
- },\r
-\r
- rgbArray: function () {\r
- return this.values.rgb;\r
- },\r
- hslArray: function () {\r
- return this.values.hsl;\r
- },\r
- hsvArray: function () {\r
- return this.values.hsv;\r
- },\r
- hwbArray: function () {\r
- var values = this.values;\r
- if (values.alpha !== 1) {\r
- return values.hwb.concat([values.alpha]);\r
- }\r
- return values.hwb;\r
- },\r
- cmykArray: function () {\r
- return this.values.cmyk;\r
- },\r
- rgbaArray: function () {\r
- var values = this.values;\r
- return values.rgb.concat([values.alpha]);\r
- },\r
- hslaArray: function () {\r
- var values = this.values;\r
- return values.hsl.concat([values.alpha]);\r
- },\r
- alpha: function (val) {\r
- if (val === undefined) {\r
- return this.values.alpha;\r
- }\r
- this.setValues('alpha', val);\r
- return this;\r
- },\r
-\r
- red: function (val) {\r
- return this.setChannel('rgb', 0, val);\r
- },\r
- green: function (val) {\r
- return this.setChannel('rgb', 1, val);\r
- },\r
- blue: function (val) {\r
- return this.setChannel('rgb', 2, val);\r
- },\r
- hue: function (val) {\r
- if (val) {\r
- val %= 360;\r
- val = val < 0 ? 360 + val : val;\r
- }\r
- return this.setChannel('hsl', 0, val);\r
- },\r
- saturation: function (val) {\r
- return this.setChannel('hsl', 1, val);\r
- },\r
- lightness: function (val) {\r
- return this.setChannel('hsl', 2, val);\r
- },\r
- saturationv: function (val) {\r
- return this.setChannel('hsv', 1, val);\r
- },\r
- whiteness: function (val) {\r
- return this.setChannel('hwb', 1, val);\r
- },\r
- blackness: function (val) {\r
- return this.setChannel('hwb', 2, val);\r
- },\r
- value: function (val) {\r
- return this.setChannel('hsv', 2, val);\r
- },\r
- cyan: function (val) {\r
- return this.setChannel('cmyk', 0, val);\r
- },\r
- magenta: function (val) {\r
- return this.setChannel('cmyk', 1, val);\r
- },\r
- yellow: function (val) {\r
- return this.setChannel('cmyk', 2, val);\r
- },\r
- black: function (val) {\r
- return this.setChannel('cmyk', 3, val);\r
- },\r
-\r
- hexString: function () {\r
- return string.hexString(this.values.rgb);\r
- },\r
- rgbString: function () {\r
- return string.rgbString(this.values.rgb, this.values.alpha);\r
- },\r
- rgbaString: function () {\r
- return string.rgbaString(this.values.rgb, this.values.alpha);\r
- },\r
- percentString: function () {\r
- return string.percentString(this.values.rgb, this.values.alpha);\r
- },\r
- hslString: function () {\r
- return string.hslString(this.values.hsl, this.values.alpha);\r
- },\r
- hslaString: function () {\r
- return string.hslaString(this.values.hsl, this.values.alpha);\r
- },\r
- hwbString: function () {\r
- return string.hwbString(this.values.hwb, this.values.alpha);\r
- },\r
- keyword: function () {\r
- return string.keyword(this.values.rgb, this.values.alpha);\r
- },\r
-\r
- rgbNumber: function () {\r
- var rgb = this.values.rgb;\r
- return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\r
- },\r
-\r
- luminosity: function () {\r
- // http://www.w3.org/TR/WCAG20/#relativeluminancedef\r
- var rgb = this.values.rgb;\r
- var lum = [];\r
- for (var i = 0; i < rgb.length; i++) {\r
- var chan = rgb[i] / 255;\r
- lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\r
- }\r
- return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\r
- },\r
-\r
- contrast: function (color2) {\r
- // http://www.w3.org/TR/WCAG20/#contrast-ratiodef\r
- var lum1 = this.luminosity();\r
- var lum2 = color2.luminosity();\r
- if (lum1 > lum2) {\r
- return (lum1 + 0.05) / (lum2 + 0.05);\r
- }\r
- return (lum2 + 0.05) / (lum1 + 0.05);\r
- },\r
-\r
- level: function (color2) {\r
- var contrastRatio = this.contrast(color2);\r
- if (contrastRatio >= 7.1) {\r
- return 'AAA';\r
- }\r
-\r
- return (contrastRatio >= 4.5) ? 'AA' : '';\r
- },\r
-\r
- dark: function () {\r
- // YIQ equation from http://24ways.org/2010/calculating-color-contrast\r
- var rgb = this.values.rgb;\r
- var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\r
- return yiq < 128;\r
- },\r
-\r
- light: function () {\r
- return !this.dark();\r
- },\r
-\r
- negate: function () {\r
- var rgb = [];\r
- for (var i = 0; i < 3; i++) {\r
- rgb[i] = 255 - this.values.rgb[i];\r
- }\r
- this.setValues('rgb', rgb);\r
- return this;\r
- },\r
-\r
- lighten: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[2] += hsl[2] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- darken: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[2] -= hsl[2] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- saturate: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[1] += hsl[1] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- desaturate: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[1] -= hsl[1] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- whiten: function (ratio) {\r
- var hwb = this.values.hwb;\r
- hwb[1] += hwb[1] * ratio;\r
- this.setValues('hwb', hwb);\r
- return this;\r
- },\r
-\r
- blacken: function (ratio) {\r
- var hwb = this.values.hwb;\r
- hwb[2] += hwb[2] * ratio;\r
- this.setValues('hwb', hwb);\r
- return this;\r
- },\r
-\r
- greyscale: function () {\r
- var rgb = this.values.rgb;\r
- // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\r
- var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\r
- this.setValues('rgb', [val, val, val]);\r
- return this;\r
- },\r
-\r
- clearer: function (ratio) {\r
- var alpha = this.values.alpha;\r
- this.setValues('alpha', alpha - (alpha * ratio));\r
- return this;\r
- },\r
-\r
- opaquer: function (ratio) {\r
- var alpha = this.values.alpha;\r
- this.setValues('alpha', alpha + (alpha * ratio));\r
- return this;\r
- },\r
-\r
- rotate: function (degrees) {\r
- var hsl = this.values.hsl;\r
- var hue = (hsl[0] + degrees) % 360;\r
- hsl[0] = hue < 0 ? 360 + hue : hue;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- /**\r
- * Ported from sass implementation in C\r
- * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\r
- */\r
- mix: function (mixinColor, weight) {\r
- var color1 = this;\r
- var color2 = mixinColor;\r
- var p = weight === undefined ? 0.5 : weight;\r
-\r
- var w = 2 * p - 1;\r
- var a = color1.alpha() - color2.alpha();\r
-\r
- var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\r
- var w2 = 1 - w1;\r
-\r
- return this\r
- .rgb(\r
- w1 * color1.red() + w2 * color2.red(),\r
- w1 * color1.green() + w2 * color2.green(),\r
- w1 * color1.blue() + w2 * color2.blue()\r
- )\r
- .alpha(color1.alpha() * p + color2.alpha() * (1 - p));\r
- },\r
-\r
- toJSON: function () {\r
- return this.rgb();\r
- },\r
-\r
- clone: function () {\r
- // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,\r
- // making the final build way to big to embed in Chart.js. So let's do it manually,\r
- // assuming that values to clone are 1 dimension arrays containing only numbers,\r
- // except 'alpha' which is a number.\r
- var result = new Color();\r
- var source = this.values;\r
- var target = result.values;\r
- var value, type;\r
-\r
- for (var prop in source) {\r
- if (source.hasOwnProperty(prop)) {\r
- value = source[prop];\r
- type = ({}).toString.call(value);\r
- if (type === '[object Array]') {\r
- target[prop] = value.slice(0);\r
- } else if (type === '[object Number]') {\r
- target[prop] = value;\r
- } else {\r
- console.error('unexpected color value:', value);\r
- }\r
- }\r
- }\r
-\r
- return result;\r
- }\r
-};\r
-\r
-Color.prototype.spaces = {\r
- rgb: ['red', 'green', 'blue'],\r
- hsl: ['hue', 'saturation', 'lightness'],\r
- hsv: ['hue', 'saturation', 'value'],\r
- hwb: ['hue', 'whiteness', 'blackness'],\r
- cmyk: ['cyan', 'magenta', 'yellow', 'black']\r
-};\r
-\r
-Color.prototype.maxes = {\r
- rgb: [255, 255, 255],\r
- hsl: [360, 100, 100],\r
- hsv: [360, 100, 100],\r
- hwb: [360, 100, 100],\r
- cmyk: [100, 100, 100, 100]\r
-};\r
-\r
-Color.prototype.getValues = function (space) {\r
- var values = this.values;\r
- var vals = {};\r
-\r
- for (var i = 0; i < space.length; i++) {\r
- vals[space.charAt(i)] = values[space][i];\r
- }\r
-\r
- if (values.alpha !== 1) {\r
- vals.a = values.alpha;\r
- }\r
-\r
- // {r: 255, g: 255, b: 255, a: 0.4}\r
- return vals;\r
-};\r
-\r
-Color.prototype.setValues = function (space, vals) {\r
- var values = this.values;\r
- var spaces = this.spaces;\r
- var maxes = this.maxes;\r
- var alpha = 1;\r
- var i;\r
-\r
- if (space === 'alpha') {\r
- alpha = vals;\r
- } else if (vals.length) {\r
- // [10, 10, 10]\r
- values[space] = vals.slice(0, space.length);\r
- alpha = vals[space.length];\r
- } else if (vals[space.charAt(0)] !== undefined) {\r
- // {r: 10, g: 10, b: 10}\r
- for (i = 0; i < space.length; i++) {\r
- values[space][i] = vals[space.charAt(i)];\r
- }\r
-\r
- alpha = vals.a;\r
- } else if (vals[spaces[space][0]] !== undefined) {\r
- // {red: 10, green: 10, blue: 10}\r
- var chans = spaces[space];\r
-\r
- for (i = 0; i < space.length; i++) {\r
- values[space][i] = vals[chans[i]];\r
- }\r
-\r
- alpha = vals.alpha;\r
- }\r
-\r
- values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));\r
-\r
- if (space === 'alpha') {\r
- return false;\r
- }\r
-\r
- var capped;\r
-\r
- // cap values of the space prior converting all values\r
- for (i = 0; i < space.length; i++) {\r
- capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));\r
- values[space][i] = Math.round(capped);\r
- }\r
-\r
- // convert to all the other color spaces\r
- for (var sname in spaces) {\r
- if (sname !== space) {\r
- values[sname] = convert[space][sname](values[space]);\r
- }\r
- }\r
-\r
- return true;\r
-};\r
-\r
-Color.prototype.setSpace = function (space, args) {\r
- var vals = args[0];\r
-\r
- if (vals === undefined) {\r
- // color.rgb()\r
- return this.getValues(space);\r
- }\r
-\r
- // color.rgb(10, 10, 10)\r
- if (typeof vals === 'number') {\r
- vals = Array.prototype.slice.call(args);\r
- }\r
-\r
- this.setValues(space, vals);\r
- return this;\r
-};\r
-\r
-Color.prototype.setChannel = function (space, index, val) {\r
- var svalues = this.values[space];\r
- if (val === undefined) {\r
- // color.red()\r
- return svalues[index];\r
- } else if (val === svalues[index]) {\r
- // color.red(color.red())\r
- return this;\r
- }\r
-\r
- // color.red(100)\r
- svalues[index] = val;\r
- this.setValues(space, svalues);\r
-\r
- return this;\r
-};\r
-\r
-if (typeof window !== 'undefined') {\r
- window.Color = Color;\r
-}\r
-\r
-module.exports = Color;\r
-
-},{"1":1,"4":4}],3:[function(require,module,exports){
-/* MIT license */
-
-module.exports = {
- rgb2hsl: rgb2hsl,
- rgb2hsv: rgb2hsv,
- rgb2hwb: rgb2hwb,
- rgb2cmyk: rgb2cmyk,
- rgb2keyword: rgb2keyword,
- rgb2xyz: rgb2xyz,
- rgb2lab: rgb2lab,
- rgb2lch: rgb2lch,
-
- hsl2rgb: hsl2rgb,
- hsl2hsv: hsl2hsv,
- hsl2hwb: hsl2hwb,
- hsl2cmyk: hsl2cmyk,
- hsl2keyword: hsl2keyword,
-
- hsv2rgb: hsv2rgb,
- hsv2hsl: hsv2hsl,
- hsv2hwb: hsv2hwb,
- hsv2cmyk: hsv2cmyk,
- hsv2keyword: hsv2keyword,
-
- hwb2rgb: hwb2rgb,
- hwb2hsl: hwb2hsl,
- hwb2hsv: hwb2hsv,
- hwb2cmyk: hwb2cmyk,
- hwb2keyword: hwb2keyword,
-
- cmyk2rgb: cmyk2rgb,
- cmyk2hsl: cmyk2hsl,
- cmyk2hsv: cmyk2hsv,
- cmyk2hwb: cmyk2hwb,
- cmyk2keyword: cmyk2keyword,
-
- keyword2rgb: keyword2rgb,
- keyword2hsl: keyword2hsl,
- keyword2hsv: keyword2hsv,
- keyword2hwb: keyword2hwb,
- keyword2cmyk: keyword2cmyk,
- keyword2lab: keyword2lab,
- keyword2xyz: keyword2xyz,
-
- xyz2rgb: xyz2rgb,
- xyz2lab: xyz2lab,
- xyz2lch: xyz2lch,
-
- lab2xyz: lab2xyz,
- lab2rgb: lab2rgb,
- lab2lch: lab2lch,
-
- lch2lab: lch2lab,
- lch2xyz: lch2xyz,
- lch2rgb: lch2rgb
-}
-
-
-function rgb2hsl(rgb) {
- var r = rgb[0]/255,
- g = rgb[1]/255,
- b = rgb[2]/255,
- min = Math.min(r, g, b),
- max = Math.max(r, g, b),
- delta = max - min,
- h, s, l;
-
- if (max == min)
- h = 0;
- else if (r == max)
- h = (g - b) / delta;
- else if (g == max)
- h = 2 + (b - r) / delta;
- else if (b == max)
- h = 4 + (r - g)/ delta;
-
- h = Math.min(h * 60, 360);
-
- if (h < 0)
- h += 360;
-
- l = (min + max) / 2;
-
- if (max == min)
- s = 0;
- else if (l <= 0.5)
- s = delta / (max + min);
- else
- s = delta / (2 - max - min);
-
- return [h, s * 100, l * 100];
-}
-
-function rgb2hsv(rgb) {
- var r = rgb[0],
- g = rgb[1],
- b = rgb[2],
- min = Math.min(r, g, b),
- max = Math.max(r, g, b),
- delta = max - min,
- h, s, v;
-
- if (max == 0)
- s = 0;
- else
- s = (delta/max * 1000)/10;
-
- if (max == min)
- h = 0;
- else if (r == max)
- h = (g - b) / delta;
- else if (g == max)
- h = 2 + (b - r) / delta;
- else if (b == max)
- h = 4 + (r - g) / delta;
-
- h = Math.min(h * 60, 360);
-
- if (h < 0)
- h += 360;
-
- v = ((max / 255) * 1000) / 10;
-
- return [h, s, v];
-}
-
-function rgb2hwb(rgb) {
- var r = rgb[0],
- g = rgb[1],
- b = rgb[2],
- h = rgb2hsl(rgb)[0],
- w = 1/255 * Math.min(r, Math.min(g, b)),
- b = 1 - 1/255 * Math.max(r, Math.max(g, b));
-
- return [h, w * 100, b * 100];
-}
-
-function rgb2cmyk(rgb) {
- var r = rgb[0] / 255,
- g = rgb[1] / 255,
- b = rgb[2] / 255,
- c, m, y, k;
-
- k = Math.min(1 - r, 1 - g, 1 - b);
- c = (1 - r - k) / (1 - k) || 0;
- m = (1 - g - k) / (1 - k) || 0;
- y = (1 - b - k) / (1 - k) || 0;
- return [c * 100, m * 100, y * 100, k * 100];
-}
-
-function rgb2keyword(rgb) {
- return reverseKeywords[JSON.stringify(rgb)];
-}
-
-function rgb2xyz(rgb) {
- var r = rgb[0] / 255,
- g = rgb[1] / 255,
- b = rgb[2] / 255;
-
- // assume sRGB
- r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
- g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
- b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
-
- var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
- var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
- var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
-
- return [x * 100, y *100, z * 100];
-}
-
-function rgb2lab(rgb) {
- var xyz = rgb2xyz(rgb),
- x = xyz[0],
- y = xyz[1],
- z = xyz[2],
- l, a, b;
-
- x /= 95.047;
- y /= 100;
- z /= 108.883;
-
- x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
- y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
- z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
-
- l = (116 * y) - 16;
- a = 500 * (x - y);
- b = 200 * (y - z);
-
- return [l, a, b];
-}
-
-function rgb2lch(args) {
- return lab2lch(rgb2lab(args));
-}
-
-function hsl2rgb(hsl) {
- var h = hsl[0] / 360,
- s = hsl[1] / 100,
- l = hsl[2] / 100,
- t1, t2, t3, rgb, val;
-
- if (s == 0) {
- val = l * 255;
- return [val, val, val];
- }
-
- if (l < 0.5)
- t2 = l * (1 + s);
- else
- t2 = l + s - l * s;
- t1 = 2 * l - t2;
-
- rgb = [0, 0, 0];
- for (var i = 0; i < 3; i++) {
- t3 = h + 1 / 3 * - (i - 1);
- t3 < 0 && t3++;
- t3 > 1 && t3--;
-
- if (6 * t3 < 1)
- val = t1 + (t2 - t1) * 6 * t3;
- else if (2 * t3 < 1)
- val = t2;
- else if (3 * t3 < 2)
- val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
- else
- val = t1;
-
- rgb[i] = val * 255;
- }
-
- return rgb;
-}
-
-function hsl2hsv(hsl) {
- var h = hsl[0],
- s = hsl[1] / 100,
- l = hsl[2] / 100,
- sv, v;
-
- if(l === 0) {
- // no need to do calc on black
- // also avoids divide by 0 error
- return [0, 0, 0];
- }
-
- l *= 2;
- s *= (l <= 1) ? l : 2 - l;
- v = (l + s) / 2;
- sv = (2 * s) / (l + s);
- return [h, sv * 100, v * 100];
-}
-
-function hsl2hwb(args) {
- return rgb2hwb(hsl2rgb(args));
-}
-
-function hsl2cmyk(args) {
- return rgb2cmyk(hsl2rgb(args));
-}
-
-function hsl2keyword(args) {
- return rgb2keyword(hsl2rgb(args));
-}
-
-
-function hsv2rgb(hsv) {
- var h = hsv[0] / 60,
- s = hsv[1] / 100,
- v = hsv[2] / 100,
- hi = Math.floor(h) % 6;
-
- var f = h - Math.floor(h),
- p = 255 * v * (1 - s),
- q = 255 * v * (1 - (s * f)),
- t = 255 * v * (1 - (s * (1 - f))),
- v = 255 * v;
-
- switch(hi) {
- case 0:
- return [v, t, p];
- case 1:
- return [q, v, p];
- case 2:
- return [p, v, t];
- case 3:
- return [p, q, v];
- case 4:
- return [t, p, v];
- case 5:
- return [v, p, q];
- }
-}
-
-function hsv2hsl(hsv) {
- var h = hsv[0],
- s = hsv[1] / 100,
- v = hsv[2] / 100,
- sl, l;
-
- l = (2 - s) * v;
- sl = s * v;
- sl /= (l <= 1) ? l : 2 - l;
- sl = sl || 0;
- l /= 2;
- return [h, sl * 100, l * 100];
-}
-
-function hsv2hwb(args) {
- return rgb2hwb(hsv2rgb(args))
-}
-
-function hsv2cmyk(args) {
- return rgb2cmyk(hsv2rgb(args));
-}
-
-function hsv2keyword(args) {
- return rgb2keyword(hsv2rgb(args));
-}
-
-// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
-function hwb2rgb(hwb) {
- var h = hwb[0] / 360,
- wh = hwb[1] / 100,
- bl = hwb[2] / 100,
- ratio = wh + bl,
- i, v, f, n;
-
- // wh + bl cant be > 1
- if (ratio > 1) {
- wh /= ratio;
- bl /= ratio;
- }
-
- i = Math.floor(6 * h);
- v = 1 - bl;
- f = 6 * h - i;
- if ((i & 0x01) != 0) {
- f = 1 - f;
- }
- n = wh + f * (v - wh); // linear interpolation
-
- switch (i) {
- default:
- case 6:
- case 0: r = v; g = n; b = wh; break;
- case 1: r = n; g = v; b = wh; break;
- case 2: r = wh; g = v; b = n; break;
- case 3: r = wh; g = n; b = v; break;
- case 4: r = n; g = wh; b = v; break;
- case 5: r = v; g = wh; b = n; break;
- }
-
- return [r * 255, g * 255, b * 255];
-}
-
-function hwb2hsl(args) {
- return rgb2hsl(hwb2rgb(args));
-}
-
-function hwb2hsv(args) {
- return rgb2hsv(hwb2rgb(args));
-}
-
-function hwb2cmyk(args) {
- return rgb2cmyk(hwb2rgb(args));
-}
-
-function hwb2keyword(args) {
- return rgb2keyword(hwb2rgb(args));
-}
-
-function cmyk2rgb(cmyk) {
- var c = cmyk[0] / 100,
- m = cmyk[1] / 100,
- y = cmyk[2] / 100,
- k = cmyk[3] / 100,
- r, g, b;
-
- r = 1 - Math.min(1, c * (1 - k) + k);
- g = 1 - Math.min(1, m * (1 - k) + k);
- b = 1 - Math.min(1, y * (1 - k) + k);
- return [r * 255, g * 255, b * 255];
-}
-
-function cmyk2hsl(args) {
- return rgb2hsl(cmyk2rgb(args));
-}
-
-function cmyk2hsv(args) {
- return rgb2hsv(cmyk2rgb(args));
-}
-
-function cmyk2hwb(args) {
- return rgb2hwb(cmyk2rgb(args));
-}
-
-function cmyk2keyword(args) {
- return rgb2keyword(cmyk2rgb(args));
-}
-
-
-function xyz2rgb(xyz) {
- var x = xyz[0] / 100,
- y = xyz[1] / 100,
- z = xyz[2] / 100,
- r, g, b;
-
- r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
- g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
- b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
-
- // assume sRGB
- r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
- : r = (r * 12.92);
-
- g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
- : g = (g * 12.92);
-
- b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
- : b = (b * 12.92);
-
- r = Math.min(Math.max(0, r), 1);
- g = Math.min(Math.max(0, g), 1);
- b = Math.min(Math.max(0, b), 1);
-
- return [r * 255, g * 255, b * 255];
-}
-
-function xyz2lab(xyz) {
- var x = xyz[0],
- y = xyz[1],
- z = xyz[2],
- l, a, b;
-
- x /= 95.047;
- y /= 100;
- z /= 108.883;
-
- x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
- y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
- z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
-
- l = (116 * y) - 16;
- a = 500 * (x - y);
- b = 200 * (y - z);
-
- return [l, a, b];
-}
-
-function xyz2lch(args) {
- return lab2lch(xyz2lab(args));
-}
-
-function lab2xyz(lab) {
- var l = lab[0],
- a = lab[1],
- b = lab[2],
- x, y, z, y2;
-
- if (l <= 8) {
- y = (l * 100) / 903.3;
- y2 = (7.787 * (y / 100)) + (16 / 116);
- } else {
- y = 100 * Math.pow((l + 16) / 116, 3);
- y2 = Math.pow(y / 100, 1/3);
- }
-
- x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
-
- z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
-
- return [x, y, z];
-}
-
-function lab2lch(lab) {
- var l = lab[0],
- a = lab[1],
- b = lab[2],
- hr, h, c;
-
- hr = Math.atan2(b, a);
- h = hr * 360 / 2 / Math.PI;
- if (h < 0) {
- h += 360;
- }
- c = Math.sqrt(a * a + b * b);
- return [l, c, h];
-}
-
-function lab2rgb(args) {
- return xyz2rgb(lab2xyz(args));
-}
-
-function lch2lab(lch) {
- var l = lch[0],
- c = lch[1],
- h = lch[2],
- a, b, hr;
-
- hr = h / 360 * 2 * Math.PI;
- a = c * Math.cos(hr);
- b = c * Math.sin(hr);
- return [l, a, b];
-}
-
-function lch2xyz(args) {
- return lab2xyz(lch2lab(args));
-}
-
-function lch2rgb(args) {
- return lab2rgb(lch2lab(args));
-}
-
-function keyword2rgb(keyword) {
- return cssKeywords[keyword];
-}
-
-function keyword2hsl(args) {
- return rgb2hsl(keyword2rgb(args));
-}
-
-function keyword2hsv(args) {
- return rgb2hsv(keyword2rgb(args));
-}
-
-function keyword2hwb(args) {
- return rgb2hwb(keyword2rgb(args));
-}
-
-function keyword2cmyk(args) {
- return rgb2cmyk(keyword2rgb(args));
-}
-
-function keyword2lab(args) {
- return rgb2lab(keyword2rgb(args));
-}
-
-function keyword2xyz(args) {
- return rgb2xyz(keyword2rgb(args));
-}
-
-var cssKeywords = {
- aliceblue: [240,248,255],
- antiquewhite: [250,235,215],
- aqua: [0,255,255],
- aquamarine: [127,255,212],
- azure: [240,255,255],
- beige: [245,245,220],
- bisque: [255,228,196],
- black: [0,0,0],
- blanchedalmond: [255,235,205],
- blue: [0,0,255],
- blueviolet: [138,43,226],
- brown: [165,42,42],
- burlywood: [222,184,135],
- cadetblue: [95,158,160],
- chartreuse: [127,255,0],
- chocolate: [210,105,30],
- coral: [255,127,80],
- cornflowerblue: [100,149,237],
- cornsilk: [255,248,220],
- crimson: [220,20,60],
- cyan: [0,255,255],
- darkblue: [0,0,139],
- darkcyan: [0,139,139],
- darkgoldenrod: [184,134,11],
- darkgray: [169,169,169],
- darkgreen: [0,100,0],
- darkgrey: [169,169,169],
- darkkhaki: [189,183,107],
- darkmagenta: [139,0,139],
- darkolivegreen: [85,107,47],
- darkorange: [255,140,0],
- darkorchid: [153,50,204],
- darkred: [139,0,0],
- darksalmon: [233,150,122],
- darkseagreen: [143,188,143],
- darkslateblue: [72,61,139],
- darkslategray: [47,79,79],
- darkslategrey: [47,79,79],
- darkturquoise: [0,206,209],
- darkviolet: [148,0,211],
- deeppink: [255,20,147],
- deepskyblue: [0,191,255],
- dimgray: [105,105,105],
- dimgrey: [105,105,105],
- dodgerblue: [30,144,255],
- firebrick: [178,34,34],
- floralwhite: [255,250,240],
- forestgreen: [34,139,34],
- fuchsia: [255,0,255],
- gainsboro: [220,220,220],
- ghostwhite: [248,248,255],
- gold: [255,215,0],
- goldenrod: [218,165,32],
- gray: [128,128,128],
- green: [0,128,0],
- greenyellow: [173,255,47],
- grey: [128,128,128],
- honeydew: [240,255,240],
- hotpink: [255,105,180],
- indianred: [205,92,92],
- indigo: [75,0,130],
- ivory: [255,255,240],
- khaki: [240,230,140],
- lavender: [230,230,250],
- lavenderblush: [255,240,245],
- lawngreen: [124,252,0],
- lemonchiffon: [255,250,205],
- lightblue: [173,216,230],
- lightcoral: [240,128,128],
- lightcyan: [224,255,255],
- lightgoldenrodyellow: [250,250,210],
- lightgray: [211,211,211],
- lightgreen: [144,238,144],
- lightgrey: [211,211,211],
- lightpink: [255,182,193],
- lightsalmon: [255,160,122],
- lightseagreen: [32,178,170],
- lightskyblue: [135,206,250],
- lightslategray: [119,136,153],
- lightslategrey: [119,136,153],
- lightsteelblue: [176,196,222],
- lightyellow: [255,255,224],
- lime: [0,255,0],
- limegreen: [50,205,50],
- linen: [250,240,230],
- magenta: [255,0,255],
- maroon: [128,0,0],
- mediumaquamarine: [102,205,170],
- mediumblue: [0,0,205],
- mediumorchid: [186,85,211],
- mediumpurple: [147,112,219],
- mediumseagreen: [60,179,113],
- mediumslateblue: [123,104,238],
- mediumspringgreen: [0,250,154],
- mediumturquoise: [72,209,204],
- mediumvioletred: [199,21,133],
- midnightblue: [25,25,112],
- mintcream: [245,255,250],
- mistyrose: [255,228,225],
- moccasin: [255,228,181],
- navajowhite: [255,222,173],
- navy: [0,0,128],
- oldlace: [253,245,230],
- olive: [128,128,0],
- olivedrab: [107,142,35],
- orange: [255,165,0],
- orangered: [255,69,0],
- orchid: [218,112,214],
- palegoldenrod: [238,232,170],
- palegreen: [152,251,152],
- paleturquoise: [175,238,238],
- palevioletred: [219,112,147],
- papayawhip: [255,239,213],
- peachpuff: [255,218,185],
- peru: [205,133,63],
- pink: [255,192,203],
- plum: [221,160,221],
- powderblue: [176,224,230],
- purple: [128,0,128],
- rebeccapurple: [102, 51, 153],
- red: [255,0,0],
- rosybrown: [188,143,143],
- royalblue: [65,105,225],
- saddlebrown: [139,69,19],
- salmon: [250,128,114],
- sandybrown: [244,164,96],
- seagreen: [46,139,87],
- seashell: [255,245,238],
- sienna: [160,82,45],
- silver: [192,192,192],
- skyblue: [135,206,235],
- slateblue: [106,90,205],
- slategray: [112,128,144],
- slategrey: [112,128,144],
- snow: [255,250,250],
- springgreen: [0,255,127],
- steelblue: [70,130,180],
- tan: [210,180,140],
- teal: [0,128,128],
- thistle: [216,191,216],
- tomato: [255,99,71],
- turquoise: [64,224,208],
- violet: [238,130,238],
- wheat: [245,222,179],
- white: [255,255,255],
- whitesmoke: [245,245,245],
- yellow: [255,255,0],
- yellowgreen: [154,205,50]
-};
-
-var reverseKeywords = {};
-for (var key in cssKeywords) {
- reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
-}
-
-},{}],4:[function(require,module,exports){
-var conversions = require(3);
-
-var convert = function() {
- return new Converter();
-}
-
-for (var func in conversions) {
- // export Raw versions
- convert[func + "Raw"] = (function(func) {
- // accept array or plain args
- return function(arg) {
- if (typeof arg == "number")
- arg = Array.prototype.slice.call(arguments);
- return conversions[func](arg);
- }
- })(func);
-
- var pair = /(\w+)2(\w+)/.exec(func),
- from = pair[1],
- to = pair[2];
-
- // export rgb2hsl and ["rgb"]["hsl"]
- convert[from] = convert[from] || {};
-
- convert[from][to] = convert[func] = (function(func) {
- return function(arg) {
- if (typeof arg == "number")
- arg = Array.prototype.slice.call(arguments);
-
- var val = conversions[func](arg);
- if (typeof val == "string" || val === undefined)
- return val; // keyword
-
- for (var i = 0; i < val.length; i++)
- val[i] = Math.round(val[i]);
- return val;
- }
- })(func);
-}
-
-
-/* Converter does lazy conversion and caching */
-var Converter = function() {
- this.convs = {};
-};
-
-/* Either get the values for a space or
- set the values for a space, depending on args */
-Converter.prototype.routeSpace = function(space, args) {
- var values = args[0];
- if (values === undefined) {
- // color.rgb()
- return this.getValues(space);
- }
- // color.rgb(10, 10, 10)
- if (typeof values == "number") {
- values = Array.prototype.slice.call(args);
- }
-
- return this.setValues(space, values);
-};
-
-/* Set the values for a space, invalidating cache */
-Converter.prototype.setValues = function(space, values) {
- this.space = space;
- this.convs = {};
- this.convs[space] = values;
- return this;
-};
-
-/* Get the values for a space. If there's already
- a conversion for the space, fetch it, otherwise
- compute it */
-Converter.prototype.getValues = function(space) {
- var vals = this.convs[space];
- if (!vals) {
- var fspace = this.space,
- from = this.convs[fspace];
- vals = convert[fspace][space](from);
-
- this.convs[space] = vals;
- }
- return vals;
-};
-
-["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
- Converter.prototype[space] = function(vals) {
- return this.routeSpace(space, arguments);
- }
-});
-
-module.exports = convert;
-},{"3":3}],5:[function(require,module,exports){
-module.exports = {\r
- "aliceblue": [240, 248, 255],\r
- "antiquewhite": [250, 235, 215],\r
- "aqua": [0, 255, 255],\r
- "aquamarine": [127, 255, 212],\r
- "azure": [240, 255, 255],\r
- "beige": [245, 245, 220],\r
- "bisque": [255, 228, 196],\r
- "black": [0, 0, 0],\r
- "blanchedalmond": [255, 235, 205],\r
- "blue": [0, 0, 255],\r
- "blueviolet": [138, 43, 226],\r
- "brown": [165, 42, 42],\r
- "burlywood": [222, 184, 135],\r
- "cadetblue": [95, 158, 160],\r
- "chartreuse": [127, 255, 0],\r
- "chocolate": [210, 105, 30],\r
- "coral": [255, 127, 80],\r
- "cornflowerblue": [100, 149, 237],\r
- "cornsilk": [255, 248, 220],\r
- "crimson": [220, 20, 60],\r
- "cyan": [0, 255, 255],\r
- "darkblue": [0, 0, 139],\r
- "darkcyan": [0, 139, 139],\r
- "darkgoldenrod": [184, 134, 11],\r
- "darkgray": [169, 169, 169],\r
- "darkgreen": [0, 100, 0],\r
- "darkgrey": [169, 169, 169],\r
- "darkkhaki": [189, 183, 107],\r
- "darkmagenta": [139, 0, 139],\r
- "darkolivegreen": [85, 107, 47],\r
- "darkorange": [255, 140, 0],\r
- "darkorchid": [153, 50, 204],\r
- "darkred": [139, 0, 0],\r
- "darksalmon": [233, 150, 122],\r
- "darkseagreen": [143, 188, 143],\r
- "darkslateblue": [72, 61, 139],\r
- "darkslategray": [47, 79, 79],\r
- "darkslategrey": [47, 79, 79],\r
- "darkturquoise": [0, 206, 209],\r
- "darkviolet": [148, 0, 211],\r
- "deeppink": [255, 20, 147],\r
- "deepskyblue": [0, 191, 255],\r
- "dimgray": [105, 105, 105],\r
- "dimgrey": [105, 105, 105],\r
- "dodgerblue": [30, 144, 255],\r
- "firebrick": [178, 34, 34],\r
- "floralwhite": [255, 250, 240],\r
- "forestgreen": [34, 139, 34],\r
- "fuchsia": [255, 0, 255],\r
- "gainsboro": [220, 220, 220],\r
- "ghostwhite": [248, 248, 255],\r
- "gold": [255, 215, 0],\r
- "goldenrod": [218, 165, 32],\r
- "gray": [128, 128, 128],\r
- "green": [0, 128, 0],\r
- "greenyellow": [173, 255, 47],\r
- "grey": [128, 128, 128],\r
- "honeydew": [240, 255, 240],\r
- "hotpink": [255, 105, 180],\r
- "indianred": [205, 92, 92],\r
- "indigo": [75, 0, 130],\r
- "ivory": [255, 255, 240],\r
- "khaki": [240, 230, 140],\r
- "lavender": [230, 230, 250],\r
- "lavenderblush": [255, 240, 245],\r
- "lawngreen": [124, 252, 0],\r
- "lemonchiffon": [255, 250, 205],\r
- "lightblue": [173, 216, 230],\r
- "lightcoral": [240, 128, 128],\r
- "lightcyan": [224, 255, 255],\r
- "lightgoldenrodyellow": [250, 250, 210],\r
- "lightgray": [211, 211, 211],\r
- "lightgreen": [144, 238, 144],\r
- "lightgrey": [211, 211, 211],\r
- "lightpink": [255, 182, 193],\r
- "lightsalmon": [255, 160, 122],\r
- "lightseagreen": [32, 178, 170],\r
- "lightskyblue": [135, 206, 250],\r
- "lightslategray": [119, 136, 153],\r
- "lightslategrey": [119, 136, 153],\r
- "lightsteelblue": [176, 196, 222],\r
- "lightyellow": [255, 255, 224],\r
- "lime": [0, 255, 0],\r
- "limegreen": [50, 205, 50],\r
- "linen": [250, 240, 230],\r
- "magenta": [255, 0, 255],\r
- "maroon": [128, 0, 0],\r
- "mediumaquamarine": [102, 205, 170],\r
- "mediumblue": [0, 0, 205],\r
- "mediumorchid": [186, 85, 211],\r
- "mediumpurple": [147, 112, 219],\r
- "mediumseagreen": [60, 179, 113],\r
- "mediumslateblue": [123, 104, 238],\r
- "mediumspringgreen": [0, 250, 154],\r
- "mediumturquoise": [72, 209, 204],\r
- "mediumvioletred": [199, 21, 133],\r
- "midnightblue": [25, 25, 112],\r
- "mintcream": [245, 255, 250],\r
- "mistyrose": [255, 228, 225],\r
- "moccasin": [255, 228, 181],\r
- "navajowhite": [255, 222, 173],\r
- "navy": [0, 0, 128],\r
- "oldlace": [253, 245, 230],\r
- "olive": [128, 128, 0],\r
- "olivedrab": [107, 142, 35],\r
- "orange": [255, 165, 0],\r
- "orangered": [255, 69, 0],\r
- "orchid": [218, 112, 214],\r
- "palegoldenrod": [238, 232, 170],\r
- "palegreen": [152, 251, 152],\r
- "paleturquoise": [175, 238, 238],\r
- "palevioletred": [219, 112, 147],\r
- "papayawhip": [255, 239, 213],\r
- "peachpuff": [255, 218, 185],\r
- "peru": [205, 133, 63],\r
- "pink": [255, 192, 203],\r
- "plum": [221, 160, 221],\r
- "powderblue": [176, 224, 230],\r
- "purple": [128, 0, 128],\r
- "rebeccapurple": [102, 51, 153],\r
- "red": [255, 0, 0],\r
- "rosybrown": [188, 143, 143],\r
- "royalblue": [65, 105, 225],\r
- "saddlebrown": [139, 69, 19],\r
- "salmon": [250, 128, 114],\r
- "sandybrown": [244, 164, 96],\r
- "seagreen": [46, 139, 87],\r
- "seashell": [255, 245, 238],\r
- "sienna": [160, 82, 45],\r
- "silver": [192, 192, 192],\r
- "skyblue": [135, 206, 235],\r
- "slateblue": [106, 90, 205],\r
- "slategray": [112, 128, 144],\r
- "slategrey": [112, 128, 144],\r
- "snow": [255, 250, 250],\r
- "springgreen": [0, 255, 127],\r
- "steelblue": [70, 130, 180],\r
- "tan": [210, 180, 140],\r
- "teal": [0, 128, 128],\r
- "thistle": [216, 191, 216],\r
- "tomato": [255, 99, 71],\r
- "turquoise": [64, 224, 208],\r
- "violet": [238, 130, 238],\r
- "wheat": [245, 222, 179],\r
- "white": [255, 255, 255],\r
- "whitesmoke": [245, 245, 245],\r
- "yellow": [255, 255, 0],\r
- "yellowgreen": [154, 205, 50]\r
-};
-},{}],6:[function(require,module,exports){
-//! moment.js
-//! version : 2.13.0
-//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
-//! license : MIT
-//! momentjs.com
-
-;(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- global.moment = factory()
-}(this, function () { 'use strict';
-
- var hookCallback;
-
- function utils_hooks__hooks () {
- return hookCallback.apply(null, arguments);
- }
-
- // This is done to register the method called with moment()
- // without creating circular dependencies.
- function setHookCallback (callback) {
- hookCallback = callback;
- }
-
- function isArray(input) {
- return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
- }
-
- function isDate(input) {
- return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
- }
-
- function map(arr, fn) {
- var res = [], i;
- for (i = 0; i < arr.length; ++i) {
- res.push(fn(arr[i], i));
- }
- return res;
- }
-
- function hasOwnProp(a, b) {
- return Object.prototype.hasOwnProperty.call(a, b);
- }
-
- function extend(a, b) {
- for (var i in b) {
- if (hasOwnProp(b, i)) {
- a[i] = b[i];
- }
- }
-
- if (hasOwnProp(b, 'toString')) {
- a.toString = b.toString;
- }
-
- if (hasOwnProp(b, 'valueOf')) {
- a.valueOf = b.valueOf;
- }
-
- return a;
- }
-
- function create_utc__createUTC (input, format, locale, strict) {
- return createLocalOrUTC(input, format, locale, strict, true).utc();
- }
-
- function defaultParsingFlags() {
- // We need to deep clone this object.
- return {
- empty : false,
- unusedTokens : [],
- unusedInput : [],
- overflow : -2,
- charsLeftOver : 0,
- nullInput : false,
- invalidMonth : null,
- invalidFormat : false,
- userInvalidated : false,
- iso : false,
- parsedDateParts : [],
- meridiem : null
- };
- }
-
- function getParsingFlags(m) {
- if (m._pf == null) {
- m._pf = defaultParsingFlags();
- }
- return m._pf;
- }
-
- var some;
- if (Array.prototype.some) {
- some = Array.prototype.some;
- } else {
- some = function (fun) {
- var t = Object(this);
- var len = t.length >>> 0;
-
- for (var i = 0; i < len; i++) {
- if (i in t && fun.call(this, t[i], i, t)) {
- return true;
- }
- }
-
- return false;
- };
- }
-
- function valid__isValid(m) {
- if (m._isValid == null) {
- var flags = getParsingFlags(m);
- var parsedParts = some.call(flags.parsedDateParts, function (i) {
- return i != null;
- });
- m._isValid = !isNaN(m._d.getTime()) &&
- flags.overflow < 0 &&
- !flags.empty &&
- !flags.invalidMonth &&
- !flags.invalidWeekday &&
- !flags.nullInput &&
- !flags.invalidFormat &&
- !flags.userInvalidated &&
- (!flags.meridiem || (flags.meridiem && parsedParts));
-
- if (m._strict) {
- m._isValid = m._isValid &&
- flags.charsLeftOver === 0 &&
- flags.unusedTokens.length === 0 &&
- flags.bigHour === undefined;
- }
- }
- return m._isValid;
- }
-
- function valid__createInvalid (flags) {
- var m = create_utc__createUTC(NaN);
- if (flags != null) {
- extend(getParsingFlags(m), flags);
- }
- else {
- getParsingFlags(m).userInvalidated = true;
- }
-
- return m;
- }
-
- function isUndefined(input) {
- return input === void 0;
- }
-
- // Plugins that add properties should also add the key here (null value),
- // so we can properly clone ourselves.
- var momentProperties = utils_hooks__hooks.momentProperties = [];
-
- function copyConfig(to, from) {
- var i, prop, val;
-
- if (!isUndefined(from._isAMomentObject)) {
- to._isAMomentObject = from._isAMomentObject;
- }
- if (!isUndefined(from._i)) {
- to._i = from._i;
- }
- if (!isUndefined(from._f)) {
- to._f = from._f;
- }
- if (!isUndefined(from._l)) {
- to._l = from._l;
- }
- if (!isUndefined(from._strict)) {
- to._strict = from._strict;
- }
- if (!isUndefined(from._tzm)) {
- to._tzm = from._tzm;
- }
- if (!isUndefined(from._isUTC)) {
- to._isUTC = from._isUTC;
- }
- if (!isUndefined(from._offset)) {
- to._offset = from._offset;
- }
- if (!isUndefined(from._pf)) {
- to._pf = getParsingFlags(from);
- }
- if (!isUndefined(from._locale)) {
- to._locale = from._locale;
- }
-
- if (momentProperties.length > 0) {
- for (i in momentProperties) {
- prop = momentProperties[i];
- val = from[prop];
- if (!isUndefined(val)) {
- to[prop] = val;
- }
- }
- }
-
- return to;
- }
-
- var updateInProgress = false;
-
- // Moment prototype object
- function Moment(config) {
- copyConfig(this, config);
- this._d = new Date(config._d != null ? config._d.getTime() : NaN);
- // Prevent infinite loop in case updateOffset creates new moment
- // objects.
- if (updateInProgress === false) {
- updateInProgress = true;
- utils_hooks__hooks.updateOffset(this);
- updateInProgress = false;
- }
- }
-
- function isMoment (obj) {
- return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
- }
-
- function absFloor (number) {
- if (number < 0) {
- return Math.ceil(number);
- } else {
- return Math.floor(number);
- }
- }
-
- function toInt(argumentForCoercion) {
- var coercedNumber = +argumentForCoercion,
- value = 0;
-
- if (coercedNumber !== 0 && isFinite(coercedNumber)) {
- value = absFloor(coercedNumber);
- }
-
- return value;
- }
-
- // compare two arrays, return the number of differences
- function compareArrays(array1, array2, dontConvert) {
- var len = Math.min(array1.length, array2.length),
- lengthDiff = Math.abs(array1.length - array2.length),
- diffs = 0,
- i;
- for (i = 0; i < len; i++) {
- if ((dontConvert && array1[i] !== array2[i]) ||
- (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
- diffs++;
- }
- }
- return diffs + lengthDiff;
- }
-
- function warn(msg) {
- if (utils_hooks__hooks.suppressDeprecationWarnings === false &&
- (typeof console !== 'undefined') && console.warn) {
- console.warn('Deprecation warning: ' + msg);
- }
- }
-
- function deprecate(msg, fn) {
- var firstTime = true;
-
- return extend(function () {
- if (utils_hooks__hooks.deprecationHandler != null) {
- utils_hooks__hooks.deprecationHandler(null, msg);
- }
- if (firstTime) {
- warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
- firstTime = false;
- }
- return fn.apply(this, arguments);
- }, fn);
- }
-
- var deprecations = {};
-
- function deprecateSimple(name, msg) {
- if (utils_hooks__hooks.deprecationHandler != null) {
- utils_hooks__hooks.deprecationHandler(name, msg);
- }
- if (!deprecations[name]) {
- warn(msg);
- deprecations[name] = true;
- }
- }
-
- utils_hooks__hooks.suppressDeprecationWarnings = false;
- utils_hooks__hooks.deprecationHandler = null;
-
- function isFunction(input) {
- return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
- }
-
- function isObject(input) {
- return Object.prototype.toString.call(input) === '[object Object]';
- }
-
- function locale_set__set (config) {
- var prop, i;
- for (i in config) {
- prop = config[i];
- if (isFunction(prop)) {
- this[i] = prop;
- } else {
- this['_' + i] = prop;
- }
- }
- this._config = config;
- // Lenient ordinal parsing accepts just a number in addition to
- // number + (possibly) stuff coming from _ordinalParseLenient.
- this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
- }
-
- function mergeConfigs(parentConfig, childConfig) {
- var res = extend({}, parentConfig), prop;
- for (prop in childConfig) {
- if (hasOwnProp(childConfig, prop)) {
- if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
- res[prop] = {};
- extend(res[prop], parentConfig[prop]);
- extend(res[prop], childConfig[prop]);
- } else if (childConfig[prop] != null) {
- res[prop] = childConfig[prop];
- } else {
- delete res[prop];
- }
- }
- }
- return res;
- }
-
- function Locale(config) {
- if (config != null) {
- this.set(config);
- }
- }
-
- var keys;
-
- if (Object.keys) {
- keys = Object.keys;
- } else {
- keys = function (obj) {
- var i, res = [];
- for (i in obj) {
- if (hasOwnProp(obj, i)) {
- res.push(i);
- }
- }
- return res;
- };
- }
-
- // internal storage for locale config files
- var locales = {};
- var globalLocale;
-
- function normalizeLocale(key) {
- return key ? key.toLowerCase().replace('_', '-') : key;
- }
-
- // pick the locale from the array
- // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
- // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
- function chooseLocale(names) {
- var i = 0, j, next, locale, split;
-
- while (i < names.length) {
- split = normalizeLocale(names[i]).split('-');
- j = split.length;
- next = normalizeLocale(names[i + 1]);
- next = next ? next.split('-') : null;
- while (j > 0) {
- locale = loadLocale(split.slice(0, j).join('-'));
- if (locale) {
- return locale;
- }
- if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
- //the next array item is better than a shallower substring of this one
- break;
- }
- j--;
- }
- i++;
- }
- return null;
- }
-
- function loadLocale(name) {
- var oldLocale = null;
- // TODO: Find a better way to register and load all the locales in Node
- if (!locales[name] && (typeof module !== 'undefined') &&
- module && module.exports) {
- try {
- oldLocale = globalLocale._abbr;
- require('./locale/' + name);
- // because defineLocale currently also sets the global locale, we
- // want to undo that for lazy loaded locales
- locale_locales__getSetGlobalLocale(oldLocale);
- } catch (e) { }
- }
- return locales[name];
- }
-
- // This function will load locale and then set the global locale. If
- // no arguments are passed in, it will simply return the current global
- // locale key.
- function locale_locales__getSetGlobalLocale (key, values) {
- var data;
- if (key) {
- if (isUndefined(values)) {
- data = locale_locales__getLocale(key);
- }
- else {
- data = defineLocale(key, values);
- }
-
- if (data) {
- // moment.duration._locale = moment._locale = data;
- globalLocale = data;
- }
- }
-
- return globalLocale._abbr;
- }
-
- function defineLocale (name, config) {
- if (config !== null) {
- config.abbr = name;
- if (locales[name] != null) {
- deprecateSimple('defineLocaleOverride',
- 'use moment.updateLocale(localeName, config) to change ' +
- 'an existing locale. moment.defineLocale(localeName, ' +
- 'config) should only be used for creating a new locale');
- config = mergeConfigs(locales[name]._config, config);
- } else if (config.parentLocale != null) {
- if (locales[config.parentLocale] != null) {
- config = mergeConfigs(locales[config.parentLocale]._config, config);
- } else {
- // treat as if there is no base config
- deprecateSimple('parentLocaleUndefined',
- 'specified parentLocale is not defined yet');
- }
- }
- locales[name] = new Locale(config);
-
- // backwards compat for now: also set the locale
- locale_locales__getSetGlobalLocale(name);
-
- return locales[name];
- } else {
- // useful for testing
- delete locales[name];
- return null;
- }
- }
-
- function updateLocale(name, config) {
- if (config != null) {
- var locale;
- if (locales[name] != null) {
- config = mergeConfigs(locales[name]._config, config);
- }
- locale = new Locale(config);
- locale.parentLocale = locales[name];
- locales[name] = locale;
-
- // backwards compat for now: also set the locale
- locale_locales__getSetGlobalLocale(name);
- } else {
- // pass null for config to unupdate, useful for tests
- if (locales[name] != null) {
- if (locales[name].parentLocale != null) {
- locales[name] = locales[name].parentLocale;
- } else if (locales[name] != null) {
- delete locales[name];
- }
- }
- }
- return locales[name];
- }
-
- // returns locale data
- function locale_locales__getLocale (key) {
- var locale;
-
- if (key && key._locale && key._locale._abbr) {
- key = key._locale._abbr;
- }
-
- if (!key) {
- return globalLocale;
- }
-
- if (!isArray(key)) {
- //short-circuit everything else
- locale = loadLocale(key);
- if (locale) {
- return locale;
- }
- key = [key];
- }
-
- return chooseLocale(key);
- }
-
- function locale_locales__listLocales() {
- return keys(locales);
- }
-
- var aliases = {};
-
- function addUnitAlias (unit, shorthand) {
- var lowerCase = unit.toLowerCase();
- aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
- }
-
- function normalizeUnits(units) {
- return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
- }
-
- function normalizeObjectUnits(inputObject) {
- var normalizedInput = {},
- normalizedProp,
- prop;
-
- for (prop in inputObject) {
- if (hasOwnProp(inputObject, prop)) {
- normalizedProp = normalizeUnits(prop);
- if (normalizedProp) {
- normalizedInput[normalizedProp] = inputObject[prop];
- }
- }
- }
-
- return normalizedInput;
- }
-
- function makeGetSet (unit, keepTime) {
- return function (value) {
- if (value != null) {
- get_set__set(this, unit, value);
- utils_hooks__hooks.updateOffset(this, keepTime);
- return this;
- } else {
- return get_set__get(this, unit);
- }
- };
- }
-
- function get_set__get (mom, unit) {
- return mom.isValid() ?
- mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
- }
-
- function get_set__set (mom, unit, value) {
- if (mom.isValid()) {
- mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
- }
- }
-
- // MOMENTS
-
- function getSet (units, value) {
- var unit;
- if (typeof units === 'object') {
- for (unit in units) {
- this.set(unit, units[unit]);
- }
- } else {
- units = normalizeUnits(units);
- if (isFunction(this[units])) {
- return this[units](value);
- }
- }
- return this;
- }
-
- function zeroFill(number, targetLength, forceSign) {
- var absNumber = '' + Math.abs(number),
- zerosToFill = targetLength - absNumber.length,
- sign = number >= 0;
- return (sign ? (forceSign ? '+' : '') : '-') +
- Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
- }
-
- var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
-
- var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
-
- var formatFunctions = {};
-
- var formatTokenFunctions = {};
-
- // token: 'M'
- // padded: ['MM', 2]
- // ordinal: 'Mo'
- // callback: function () { this.month() + 1 }
- function addFormatToken (token, padded, ordinal, callback) {
- var func = callback;
- if (typeof callback === 'string') {
- func = function () {
- return this[callback]();
- };
- }
- if (token) {
- formatTokenFunctions[token] = func;
- }
- if (padded) {
- formatTokenFunctions[padded[0]] = function () {
- return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
- };
- }
- if (ordinal) {
- formatTokenFunctions[ordinal] = function () {
- return this.localeData().ordinal(func.apply(this, arguments), token);
- };
- }
- }
-
- function removeFormattingTokens(input) {
- if (input.match(/\[[\s\S]/)) {
- return input.replace(/^\[|\]$/g, '');
- }
- return input.replace(/\\/g, '');
- }
-
- function makeFormatFunction(format) {
- var array = format.match(formattingTokens), i, length;
-
- for (i = 0, length = array.length; i < length; i++) {
- if (formatTokenFunctions[array[i]]) {
- array[i] = formatTokenFunctions[array[i]];
- } else {
- array[i] = removeFormattingTokens(array[i]);
- }
- }
-
- return function (mom) {
- var output = '', i;
- for (i = 0; i < length; i++) {
- output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
- }
- return output;
- };
- }
-
- // format date using native date object
- function formatMoment(m, format) {
- if (!m.isValid()) {
- return m.localeData().invalidDate();
- }
-
- format = expandFormat(format, m.localeData());
- formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
-
- return formatFunctions[format](m);
- }
-
- function expandFormat(format, locale) {
- var i = 5;
-
- function replaceLongDateFormatTokens(input) {
- return locale.longDateFormat(input) || input;
- }
-
- localFormattingTokens.lastIndex = 0;
- while (i >= 0 && localFormattingTokens.test(format)) {
- format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
- localFormattingTokens.lastIndex = 0;
- i -= 1;
- }
-
- return format;
- }
-
- var match1 = /\d/; // 0 - 9
- var match2 = /\d\d/; // 00 - 99
- var match3 = /\d{3}/; // 000 - 999
- var match4 = /\d{4}/; // 0000 - 9999
- var match6 = /[+-]?\d{6}/; // -999999 - 999999
- var match1to2 = /\d\d?/; // 0 - 99
- var match3to4 = /\d\d\d\d?/; // 999 - 9999
- var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
- var match1to3 = /\d{1,3}/; // 0 - 999
- var match1to4 = /\d{1,4}/; // 0 - 9999
- var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
-
- var matchUnsigned = /\d+/; // 0 - inf
- var matchSigned = /[+-]?\d+/; // -inf - inf
-
- var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
- var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
-
- var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
-
- // any word (or two) characters or numbers including two/three word month in arabic.
- // includes scottish gaelic two word and hyphenated months
- var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
-
-
- var regexes = {};
-
- function addRegexToken (token, regex, strictRegex) {
- regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
- return (isStrict && strictRegex) ? strictRegex : regex;
- };
- }
-
- function getParseRegexForToken (token, config) {
- if (!hasOwnProp(regexes, token)) {
- return new RegExp(unescapeFormat(token));
- }
-
- return regexes[token](config._strict, config._locale);
- }
-
- // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
- function unescapeFormat(s) {
- return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
- return p1 || p2 || p3 || p4;
- }));
- }
-
- function regexEscape(s) {
- return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
- }
-
- var tokens = {};
-
- function addParseToken (token, callback) {
- var i, func = callback;
- if (typeof token === 'string') {
- token = [token];
- }
- if (typeof callback === 'number') {
- func = function (input, array) {
- array[callback] = toInt(input);
- };
- }
- for (i = 0; i < token.length; i++) {
- tokens[token[i]] = func;
- }
- }
-
- function addWeekParseToken (token, callback) {
- addParseToken(token, function (input, array, config, token) {
- config._w = config._w || {};
- callback(input, config._w, config, token);
- });
- }
-
- function addTimeToArrayFromToken(token, input, config) {
- if (input != null && hasOwnProp(tokens, token)) {
- tokens[token](input, config._a, config, token);
- }
- }
-
- var YEAR = 0;
- var MONTH = 1;
- var DATE = 2;
- var HOUR = 3;
- var MINUTE = 4;
- var SECOND = 5;
- var MILLISECOND = 6;
- var WEEK = 7;
- var WEEKDAY = 8;
-
- var indexOf;
-
- if (Array.prototype.indexOf) {
- indexOf = Array.prototype.indexOf;
- } else {
- indexOf = function (o) {
- // I know
- var i;
- for (i = 0; i < this.length; ++i) {
- if (this[i] === o) {
- return i;
- }
- }
- return -1;
- };
- }
-
- function daysInMonth(year, month) {
- return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
- }
-
- // FORMATTING
-
- addFormatToken('M', ['MM', 2], 'Mo', function () {
- return this.month() + 1;
- });
-
- addFormatToken('MMM', 0, 0, function (format) {
- return this.localeData().monthsShort(this, format);
- });
-
- addFormatToken('MMMM', 0, 0, function (format) {
- return this.localeData().months(this, format);
- });
-
- // ALIASES
-
- addUnitAlias('month', 'M');
-
- // PARSING
-
- addRegexToken('M', match1to2);
- addRegexToken('MM', match1to2, match2);
- addRegexToken('MMM', function (isStrict, locale) {
- return locale.monthsShortRegex(isStrict);
- });
- addRegexToken('MMMM', function (isStrict, locale) {
- return locale.monthsRegex(isStrict);
- });
-
- addParseToken(['M', 'MM'], function (input, array) {
- array[MONTH] = toInt(input) - 1;
- });
-
- addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
- var month = config._locale.monthsParse(input, token, config._strict);
- // if we didn't find a month name, mark the date as invalid.
- if (month != null) {
- array[MONTH] = month;
- } else {
- getParsingFlags(config).invalidMonth = input;
- }
- });
-
- // LOCALES
-
- var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/;
- var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
- function localeMonths (m, format) {
- return isArray(this._months) ? this._months[m.month()] :
- this._months[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
- }
-
- var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
- function localeMonthsShort (m, format) {
- return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
- this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
- }
-
- function units_month__handleStrictParse(monthName, format, strict) {
- var i, ii, mom, llc = monthName.toLocaleLowerCase();
- if (!this._monthsParse) {
- // this is not used
- this._monthsParse = [];
- this._longMonthsParse = [];
- this._shortMonthsParse = [];
- for (i = 0; i < 12; ++i) {
- mom = create_utc__createUTC([2000, i]);
- this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
- this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
- }
- }
-
- if (strict) {
- if (format === 'MMM') {
- ii = indexOf.call(this._shortMonthsParse, llc);
- return ii !== -1 ? ii : null;
- } else {
- ii = indexOf.call(this._longMonthsParse, llc);
- return ii !== -1 ? ii : null;
- }
- } else {
- if (format === 'MMM') {
- ii = indexOf.call(this._shortMonthsParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._longMonthsParse, llc);
- return ii !== -1 ? ii : null;
- } else {
- ii = indexOf.call(this._longMonthsParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._shortMonthsParse, llc);
- return ii !== -1 ? ii : null;
- }
- }
- }
-
- function localeMonthsParse (monthName, format, strict) {
- var i, mom, regex;
-
- if (this._monthsParseExact) {
- return units_month__handleStrictParse.call(this, monthName, format, strict);
- }
-
- if (!this._monthsParse) {
- this._monthsParse = [];
- this._longMonthsParse = [];
- this._shortMonthsParse = [];
- }
-
- // TODO: add sorting
- // Sorting makes sure if one month (or abbr) is a prefix of another
- // see sorting in computeMonthsParse
- for (i = 0; i < 12; i++) {
- // make the regex if we don't have it already
- mom = create_utc__createUTC([2000, i]);
- if (strict && !this._longMonthsParse[i]) {
- this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
- this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
- }
- if (!strict && !this._monthsParse[i]) {
- regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
- this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
- }
- // test the regex
- if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
- return i;
- } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
- return i;
- } else if (!strict && this._monthsParse[i].test(monthName)) {
- return i;
- }
- }
- }
-
- // MOMENTS
-
- function setMonth (mom, value) {
- var dayOfMonth;
-
- if (!mom.isValid()) {
- // No op
- return mom;
- }
-
- if (typeof value === 'string') {
- if (/^\d+$/.test(value)) {
- value = toInt(value);
- } else {
- value = mom.localeData().monthsParse(value);
- // TODO: Another silent failure?
- if (typeof value !== 'number') {
- return mom;
- }
- }
- }
-
- dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
- mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
- return mom;
- }
-
- function getSetMonth (value) {
- if (value != null) {
- setMonth(this, value);
- utils_hooks__hooks.updateOffset(this, true);
- return this;
- } else {
- return get_set__get(this, 'Month');
- }
- }
-
- function getDaysInMonth () {
- return daysInMonth(this.year(), this.month());
- }
-
- var defaultMonthsShortRegex = matchWord;
- function monthsShortRegex (isStrict) {
- if (this._monthsParseExact) {
- if (!hasOwnProp(this, '_monthsRegex')) {
- computeMonthsParse.call(this);
- }
- if (isStrict) {
- return this._monthsShortStrictRegex;
- } else {
- return this._monthsShortRegex;
- }
- } else {
- return this._monthsShortStrictRegex && isStrict ?
- this._monthsShortStrictRegex : this._monthsShortRegex;
- }
- }
-
- var defaultMonthsRegex = matchWord;
- function monthsRegex (isStrict) {
- if (this._monthsParseExact) {
- if (!hasOwnProp(this, '_monthsRegex')) {
- computeMonthsParse.call(this);
- }
- if (isStrict) {
- return this._monthsStrictRegex;
- } else {
- return this._monthsRegex;
- }
- } else {
- return this._monthsStrictRegex && isStrict ?
- this._monthsStrictRegex : this._monthsRegex;
- }
- }
-
- function computeMonthsParse () {
- function cmpLenRev(a, b) {
- return b.length - a.length;
- }
-
- var shortPieces = [], longPieces = [], mixedPieces = [],
- i, mom;
- for (i = 0; i < 12; i++) {
- // make the regex if we don't have it already
- mom = create_utc__createUTC([2000, i]);
- shortPieces.push(this.monthsShort(mom, ''));
- longPieces.push(this.months(mom, ''));
- mixedPieces.push(this.months(mom, ''));
- mixedPieces.push(this.monthsShort(mom, ''));
- }
- // Sorting makes sure if one month (or abbr) is a prefix of another it
- // will match the longer piece.
- shortPieces.sort(cmpLenRev);
- longPieces.sort(cmpLenRev);
- mixedPieces.sort(cmpLenRev);
- for (i = 0; i < 12; i++) {
- shortPieces[i] = regexEscape(shortPieces[i]);
- longPieces[i] = regexEscape(longPieces[i]);
- mixedPieces[i] = regexEscape(mixedPieces[i]);
- }
-
- this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
- this._monthsShortRegex = this._monthsRegex;
- this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
- this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
- }
-
- function checkOverflow (m) {
- var overflow;
- var a = m._a;
-
- if (a && getParsingFlags(m).overflow === -2) {
- overflow =
- a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :
- a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
- a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
- a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE :
- a[SECOND] < 0 || a[SECOND] > 59 ? SECOND :
- a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
- -1;
-
- if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
- overflow = DATE;
- }
- if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
- overflow = WEEK;
- }
- if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
- overflow = WEEKDAY;
- }
-
- getParsingFlags(m).overflow = overflow;
- }
-
- return m;
- }
-
- // iso 8601 regex
- // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
- var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
- var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
-
- var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
-
- var isoDates = [
- ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
- ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
- ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
- ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
- ['YYYY-DDD', /\d{4}-\d{3}/],
- ['YYYY-MM', /\d{4}-\d\d/, false],
- ['YYYYYYMMDD', /[+-]\d{10}/],
- ['YYYYMMDD', /\d{8}/],
- // YYYYMM is NOT allowed by the standard
- ['GGGG[W]WWE', /\d{4}W\d{3}/],
- ['GGGG[W]WW', /\d{4}W\d{2}/, false],
- ['YYYYDDD', /\d{7}/]
- ];
-
- // iso time formats and regexes
- var isoTimes = [
- ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
- ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
- ['HH:mm:ss', /\d\d:\d\d:\d\d/],
- ['HH:mm', /\d\d:\d\d/],
- ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
- ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
- ['HHmmss', /\d\d\d\d\d\d/],
- ['HHmm', /\d\d\d\d/],
- ['HH', /\d\d/]
- ];
-
- var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
-
- // date from iso format
- function configFromISO(config) {
- var i, l,
- string = config._i,
- match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
- allowTime, dateFormat, timeFormat, tzFormat;
-
- if (match) {
- getParsingFlags(config).iso = true;
-
- for (i = 0, l = isoDates.length; i < l; i++) {
- if (isoDates[i][1].exec(match[1])) {
- dateFormat = isoDates[i][0];
- allowTime = isoDates[i][2] !== false;
- break;
- }
- }
- if (dateFormat == null) {
- config._isValid = false;
- return;
- }
- if (match[3]) {
- for (i = 0, l = isoTimes.length; i < l; i++) {
- if (isoTimes[i][1].exec(match[3])) {
- // match[2] should be 'T' or space
- timeFormat = (match[2] || ' ') + isoTimes[i][0];
- break;
- }
- }
- if (timeFormat == null) {
- config._isValid = false;
- return;
- }
- }
- if (!allowTime && timeFormat != null) {
- config._isValid = false;
- return;
- }
- if (match[4]) {
- if (tzRegex.exec(match[4])) {
- tzFormat = 'Z';
- } else {
- config._isValid = false;
- return;
- }
- }
- config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
- configFromStringAndFormat(config);
- } else {
- config._isValid = false;
- }
- }
-
- // date from iso format or fallback
- function configFromString(config) {
- var matched = aspNetJsonRegex.exec(config._i);
-
- if (matched !== null) {
- config._d = new Date(+matched[1]);
- return;
- }
-
- configFromISO(config);
- if (config._isValid === false) {
- delete config._isValid;
- utils_hooks__hooks.createFromInputFallback(config);
- }
- }
-
- utils_hooks__hooks.createFromInputFallback = deprecate(
- 'moment construction falls back to js Date. This is ' +
- 'discouraged and will be removed in upcoming major ' +
- 'release. Please refer to ' +
- 'https://github.com/moment/moment/issues/1407 for more info.',
- function (config) {
- config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
- }
- );
-
- function createDate (y, m, d, h, M, s, ms) {
- //can't just apply() to create a date:
- //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
- var date = new Date(y, m, d, h, M, s, ms);
-
- //the date constructor remaps years 0-99 to 1900-1999
- if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
- date.setFullYear(y);
- }
- return date;
- }
-
- function createUTCDate (y) {
- var date = new Date(Date.UTC.apply(null, arguments));
-
- //the Date.UTC function remaps years 0-99 to 1900-1999
- if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
- date.setUTCFullYear(y);
- }
- return date;
- }
-
- // FORMATTING
-
- addFormatToken('Y', 0, 0, function () {
- var y = this.year();
- return y <= 9999 ? '' + y : '+' + y;
- });
-
- addFormatToken(0, ['YY', 2], 0, function () {
- return this.year() % 100;
- });
-
- addFormatToken(0, ['YYYY', 4], 0, 'year');
- addFormatToken(0, ['YYYYY', 5], 0, 'year');
- addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
-
- // ALIASES
-
- addUnitAlias('year', 'y');
-
- // PARSING
-
- addRegexToken('Y', matchSigned);
- addRegexToken('YY', match1to2, match2);
- addRegexToken('YYYY', match1to4, match4);
- addRegexToken('YYYYY', match1to6, match6);
- addRegexToken('YYYYYY', match1to6, match6);
-
- addParseToken(['YYYYY', 'YYYYYY'], YEAR);
- addParseToken('YYYY', function (input, array) {
- array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
- });
- addParseToken('YY', function (input, array) {
- array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
- });
- addParseToken('Y', function (input, array) {
- array[YEAR] = parseInt(input, 10);
- });
-
- // HELPERS
-
- function daysInYear(year) {
- return isLeapYear(year) ? 366 : 365;
- }
-
- function isLeapYear(year) {
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
- }
-
- // HOOKS
-
- utils_hooks__hooks.parseTwoDigitYear = function (input) {
- return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
- };
-
- // MOMENTS
-
- var getSetYear = makeGetSet('FullYear', true);
-
- function getIsLeapYear () {
- return isLeapYear(this.year());
- }
-
- // start-of-first-week - start-of-year
- function firstWeekOffset(year, dow, doy) {
- var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
- fwd = 7 + dow - doy,
- // first-week day local weekday -- which local weekday is fwd
- fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
-
- return -fwdlw + fwd - 1;
- }
-
- //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
- function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
- var localWeekday = (7 + weekday - dow) % 7,
- weekOffset = firstWeekOffset(year, dow, doy),
- dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
- resYear, resDayOfYear;
-
- if (dayOfYear <= 0) {
- resYear = year - 1;
- resDayOfYear = daysInYear(resYear) + dayOfYear;
- } else if (dayOfYear > daysInYear(year)) {
- resYear = year + 1;
- resDayOfYear = dayOfYear - daysInYear(year);
- } else {
- resYear = year;
- resDayOfYear = dayOfYear;
- }
-
- return {
- year: resYear,
- dayOfYear: resDayOfYear
- };
- }
-
- function weekOfYear(mom, dow, doy) {
- var weekOffset = firstWeekOffset(mom.year(), dow, doy),
- week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
- resWeek, resYear;
-
- if (week < 1) {
- resYear = mom.year() - 1;
- resWeek = week + weeksInYear(resYear, dow, doy);
- } else if (week > weeksInYear(mom.year(), dow, doy)) {
- resWeek = week - weeksInYear(mom.year(), dow, doy);
- resYear = mom.year() + 1;
- } else {
- resYear = mom.year();
- resWeek = week;
- }
-
- return {
- week: resWeek,
- year: resYear
- };
- }
-
- function weeksInYear(year, dow, doy) {
- var weekOffset = firstWeekOffset(year, dow, doy),
- weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
- return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
- }
-
- // Pick the first defined of two or three arguments.
- function defaults(a, b, c) {
- if (a != null) {
- return a;
- }
- if (b != null) {
- return b;
- }
- return c;
- }
-
- function currentDateArray(config) {
- // hooks is actually the exported moment object
- var nowValue = new Date(utils_hooks__hooks.now());
- if (config._useUTC) {
- return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
- }
- return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
- }
-
- // convert an array to a date.
- // the array should mirror the parameters below
- // note: all values past the year are optional and will default to the lowest possible value.
- // [year, month, day , hour, minute, second, millisecond]
- function configFromArray (config) {
- var i, date, input = [], currentDate, yearToUse;
-
- if (config._d) {
- return;
- }
-
- currentDate = currentDateArray(config);
-
- //compute day of the year from weeks and weekdays
- if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
- dayOfYearFromWeekInfo(config);
- }
-
- //if the day of the year is set, figure out what it is
- if (config._dayOfYear) {
- yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
-
- if (config._dayOfYear > daysInYear(yearToUse)) {
- getParsingFlags(config)._overflowDayOfYear = true;
- }
-
- date = createUTCDate(yearToUse, 0, config._dayOfYear);
- config._a[MONTH] = date.getUTCMonth();
- config._a[DATE] = date.getUTCDate();
- }
-
- // Default to current date.
- // * if no year, month, day of month are given, default to today
- // * if day of month is given, default month and year
- // * if month is given, default only year
- // * if year is given, don't default anything
- for (i = 0; i < 3 && config._a[i] == null; ++i) {
- config._a[i] = input[i] = currentDate[i];
- }
-
- // Zero out whatever was not defaulted, including time
- for (; i < 7; i++) {
- config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
- }
-
- // Check for 24:00:00.000
- if (config._a[HOUR] === 24 &&
- config._a[MINUTE] === 0 &&
- config._a[SECOND] === 0 &&
- config._a[MILLISECOND] === 0) {
- config._nextDay = true;
- config._a[HOUR] = 0;
- }
-
- config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
- // Apply timezone offset from input. The actual utcOffset can be changed
- // with parseZone.
- if (config._tzm != null) {
- config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
- }
-
- if (config._nextDay) {
- config._a[HOUR] = 24;
- }
- }
-
- function dayOfYearFromWeekInfo(config) {
- var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
-
- w = config._w;
- if (w.GG != null || w.W != null || w.E != null) {
- dow = 1;
- doy = 4;
-
- // TODO: We need to take the current isoWeekYear, but that depends on
- // how we interpret now (local, utc, fixed offset). So create
- // a now version of current config (take local/utc/offset flags, and
- // create now).
- weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
- week = defaults(w.W, 1);
- weekday = defaults(w.E, 1);
- if (weekday < 1 || weekday > 7) {
- weekdayOverflow = true;
- }
- } else {
- dow = config._locale._week.dow;
- doy = config._locale._week.doy;
-
- weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
- week = defaults(w.w, 1);
-
- if (w.d != null) {
- // weekday -- low day numbers are considered next week
- weekday = w.d;
- if (weekday < 0 || weekday > 6) {
- weekdayOverflow = true;
- }
- } else if (w.e != null) {
- // local weekday -- counting starts from begining of week
- weekday = w.e + dow;
- if (w.e < 0 || w.e > 6) {
- weekdayOverflow = true;
- }
- } else {
- // default to begining of week
- weekday = dow;
- }
- }
- if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
- getParsingFlags(config)._overflowWeeks = true;
- } else if (weekdayOverflow != null) {
- getParsingFlags(config)._overflowWeekday = true;
- } else {
- temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
- config._a[YEAR] = temp.year;
- config._dayOfYear = temp.dayOfYear;
- }
- }
-
- // constant that refers to the ISO standard
- utils_hooks__hooks.ISO_8601 = function () {};
-
- // date from string and format string
- function configFromStringAndFormat(config) {
- // TODO: Move this to another part of the creation flow to prevent circular deps
- if (config._f === utils_hooks__hooks.ISO_8601) {
- configFromISO(config);
- return;
- }
-
- config._a = [];
- getParsingFlags(config).empty = true;
-
- // This array is used to make a Date, either with `new Date` or `Date.UTC`
- var string = '' + config._i,
- i, parsedInput, tokens, token, skipped,
- stringLength = string.length,
- totalParsedInputLength = 0;
-
- tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
-
- for (i = 0; i < tokens.length; i++) {
- token = tokens[i];
- parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
- // console.log('token', token, 'parsedInput', parsedInput,
- // 'regex', getParseRegexForToken(token, config));
- if (parsedInput) {
- skipped = string.substr(0, string.indexOf(parsedInput));
- if (skipped.length > 0) {
- getParsingFlags(config).unusedInput.push(skipped);
- }
- string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
- totalParsedInputLength += parsedInput.length;
- }
- // don't parse if it's not a known token
- if (formatTokenFunctions[token]) {
- if (parsedInput) {
- getParsingFlags(config).empty = false;
- }
- else {
- getParsingFlags(config).unusedTokens.push(token);
- }
- addTimeToArrayFromToken(token, parsedInput, config);
- }
- else if (config._strict && !parsedInput) {
- getParsingFlags(config).unusedTokens.push(token);
- }
- }
-
- // add remaining unparsed input length to the string
- getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
- if (string.length > 0) {
- getParsingFlags(config).unusedInput.push(string);
- }
-
- // clear _12h flag if hour is <= 12
- if (getParsingFlags(config).bigHour === true &&
- config._a[HOUR] <= 12 &&
- config._a[HOUR] > 0) {
- getParsingFlags(config).bigHour = undefined;
- }
-
- getParsingFlags(config).parsedDateParts = config._a.slice(0);
- getParsingFlags(config).meridiem = config._meridiem;
- // handle meridiem
- config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
-
- configFromArray(config);
- checkOverflow(config);
- }
-
-
- function meridiemFixWrap (locale, hour, meridiem) {
- var isPm;
-
- if (meridiem == null) {
- // nothing to do
- return hour;
- }
- if (locale.meridiemHour != null) {
- return locale.meridiemHour(hour, meridiem);
- } else if (locale.isPM != null) {
- // Fallback
- isPm = locale.isPM(meridiem);
- if (isPm && hour < 12) {
- hour += 12;
- }
- if (!isPm && hour === 12) {
- hour = 0;
- }
- return hour;
- } else {
- // this is not supposed to happen
- return hour;
- }
- }
-
- // date from string and array of format strings
- function configFromStringAndArray(config) {
- var tempConfig,
- bestMoment,
-
- scoreToBeat,
- i,
- currentScore;
-
- if (config._f.length === 0) {
- getParsingFlags(config).invalidFormat = true;
- config._d = new Date(NaN);
- return;
- }
-
- for (i = 0; i < config._f.length; i++) {
- currentScore = 0;
- tempConfig = copyConfig({}, config);
- if (config._useUTC != null) {
- tempConfig._useUTC = config._useUTC;
- }
- tempConfig._f = config._f[i];
- configFromStringAndFormat(tempConfig);
-
- if (!valid__isValid(tempConfig)) {
- continue;
- }
-
- // if there is any input that was not parsed add a penalty for that format
- currentScore += getParsingFlags(tempConfig).charsLeftOver;
-
- //or tokens
- currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
-
- getParsingFlags(tempConfig).score = currentScore;
-
- if (scoreToBeat == null || currentScore < scoreToBeat) {
- scoreToBeat = currentScore;
- bestMoment = tempConfig;
- }
- }
-
- extend(config, bestMoment || tempConfig);
- }
-
- function configFromObject(config) {
- if (config._d) {
- return;
- }
-
- var i = normalizeObjectUnits(config._i);
- config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
- return obj && parseInt(obj, 10);
- });
-
- configFromArray(config);
- }
-
- function createFromConfig (config) {
- var res = new Moment(checkOverflow(prepareConfig(config)));
- if (res._nextDay) {
- // Adding is smart enough around DST
- res.add(1, 'd');
- res._nextDay = undefined;
- }
-
- return res;
- }
-
- function prepareConfig (config) {
- var input = config._i,
- format = config._f;
-
- config._locale = config._locale || locale_locales__getLocale(config._l);
-
- if (input === null || (format === undefined && input === '')) {
- return valid__createInvalid({nullInput: true});
- }
-
- if (typeof input === 'string') {
- config._i = input = config._locale.preparse(input);
- }
-
- if (isMoment(input)) {
- return new Moment(checkOverflow(input));
- } else if (isArray(format)) {
- configFromStringAndArray(config);
- } else if (format) {
- configFromStringAndFormat(config);
- } else if (isDate(input)) {
- config._d = input;
- } else {
- configFromInput(config);
- }
-
- if (!valid__isValid(config)) {
- config._d = null;
- }
-
- return config;
- }
-
- function configFromInput(config) {
- var input = config._i;
- if (input === undefined) {
- config._d = new Date(utils_hooks__hooks.now());
- } else if (isDate(input)) {
- config._d = new Date(input.valueOf());
- } else if (typeof input === 'string') {
- configFromString(config);
- } else if (isArray(input)) {
- config._a = map(input.slice(0), function (obj) {
- return parseInt(obj, 10);
- });
- configFromArray(config);
- } else if (typeof(input) === 'object') {
- configFromObject(config);
- } else if (typeof(input) === 'number') {
- // from milliseconds
- config._d = new Date(input);
- } else {
- utils_hooks__hooks.createFromInputFallback(config);
- }
- }
-
- function createLocalOrUTC (input, format, locale, strict, isUTC) {
- var c = {};
-
- if (typeof(locale) === 'boolean') {
- strict = locale;
- locale = undefined;
- }
- // object construction must be done this way.
- // https://github.com/moment/moment/issues/1423
- c._isAMomentObject = true;
- c._useUTC = c._isUTC = isUTC;
- c._l = locale;
- c._i = input;
- c._f = format;
- c._strict = strict;
-
- return createFromConfig(c);
- }
-
- function local__createLocal (input, format, locale, strict) {
- return createLocalOrUTC(input, format, locale, strict, false);
- }
-
- var prototypeMin = deprecate(
- 'moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
- function () {
- var other = local__createLocal.apply(null, arguments);
- if (this.isValid() && other.isValid()) {
- return other < this ? this : other;
- } else {
- return valid__createInvalid();
- }
- }
- );
-
- var prototypeMax = deprecate(
- 'moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
- function () {
- var other = local__createLocal.apply(null, arguments);
- if (this.isValid() && other.isValid()) {
- return other > this ? this : other;
- } else {
- return valid__createInvalid();
- }
- }
- );
-
- // Pick a moment m from moments so that m[fn](other) is true for all
- // other. This relies on the function fn to be transitive.
- //
- // moments should either be an array of moment objects or an array, whose
- // first element is an array of moment objects.
- function pickBy(fn, moments) {
- var res, i;
- if (moments.length === 1 && isArray(moments[0])) {
- moments = moments[0];
- }
- if (!moments.length) {
- return local__createLocal();
- }
- res = moments[0];
- for (i = 1; i < moments.length; ++i) {
- if (!moments[i].isValid() || moments[i][fn](res)) {
- res = moments[i];
- }
- }
- return res;
- }
-
- // TODO: Use [].sort instead?
- function min () {
- var args = [].slice.call(arguments, 0);
-
- return pickBy('isBefore', args);
- }
-
- function max () {
- var args = [].slice.call(arguments, 0);
-
- return pickBy('isAfter', args);
- }
-
- var now = function () {
- return Date.now ? Date.now() : +(new Date());
- };
-
- function Duration (duration) {
- var normalizedInput = normalizeObjectUnits(duration),
- years = normalizedInput.year || 0,
- quarters = normalizedInput.quarter || 0,
- months = normalizedInput.month || 0,
- weeks = normalizedInput.week || 0,
- days = normalizedInput.day || 0,
- hours = normalizedInput.hour || 0,
- minutes = normalizedInput.minute || 0,
- seconds = normalizedInput.second || 0,
- milliseconds = normalizedInput.millisecond || 0;
-
- // representation for dateAddRemove
- this._milliseconds = +milliseconds +
- seconds * 1e3 + // 1000
- minutes * 6e4 + // 1000 * 60
- hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
- // Because of dateAddRemove treats 24 hours as different from a
- // day when working around DST, we need to store them separately
- this._days = +days +
- weeks * 7;
- // It is impossible translate months into days without knowing
- // which months you are are talking about, so we have to store
- // it separately.
- this._months = +months +
- quarters * 3 +
- years * 12;
-
- this._data = {};
-
- this._locale = locale_locales__getLocale();
-
- this._bubble();
- }
-
- function isDuration (obj) {
- return obj instanceof Duration;
- }
-
- // FORMATTING
-
- function offset (token, separator) {
- addFormatToken(token, 0, 0, function () {
- var offset = this.utcOffset();
- var sign = '+';
- if (offset < 0) {
- offset = -offset;
- sign = '-';
- }
- return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
- });
- }
-
- offset('Z', ':');
- offset('ZZ', '');
-
- // PARSING
-
- addRegexToken('Z', matchShortOffset);
- addRegexToken('ZZ', matchShortOffset);
- addParseToken(['Z', 'ZZ'], function (input, array, config) {
- config._useUTC = true;
- config._tzm = offsetFromString(matchShortOffset, input);
- });
-
- // HELPERS
-
- // timezone chunker
- // '+10:00' > ['10', '00']
- // '-1530' > ['-15', '30']
- var chunkOffset = /([\+\-]|\d\d)/gi;
-
- function offsetFromString(matcher, string) {
- var matches = ((string || '').match(matcher) || []);
- var chunk = matches[matches.length - 1] || [];
- var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
- var minutes = +(parts[1] * 60) + toInt(parts[2]);
-
- return parts[0] === '+' ? minutes : -minutes;
- }
-
- // Return a moment from input, that is local/utc/zone equivalent to model.
- function cloneWithOffset(input, model) {
- var res, diff;
- if (model._isUTC) {
- res = model.clone();
- diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf();
- // Use low-level api, because this fn is low-level api.
- res._d.setTime(res._d.valueOf() + diff);
- utils_hooks__hooks.updateOffset(res, false);
- return res;
- } else {
- return local__createLocal(input).local();
- }
- }
-
- function getDateOffset (m) {
- // On Firefox.24 Date#getTimezoneOffset returns a floating point.
- // https://github.com/moment/moment/pull/1871
- return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
- }
-
- // HOOKS
-
- // This function will be called whenever a moment is mutated.
- // It is intended to keep the offset in sync with the timezone.
- utils_hooks__hooks.updateOffset = function () {};
-
- // MOMENTS
-
- // keepLocalTime = true means only change the timezone, without
- // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
- // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
- // +0200, so we adjust the time as needed, to be valid.
- //
- // Keeping the time actually adds/subtracts (one hour)
- // from the actual represented time. That is why we call updateOffset
- // a second time. In case it wants us to change the offset again
- // _changeInProgress == true case, then we have to adjust, because
- // there is no such time in the given timezone.
- function getSetOffset (input, keepLocalTime) {
- var offset = this._offset || 0,
- localAdjust;
- if (!this.isValid()) {
- return input != null ? this : NaN;
- }
- if (input != null) {
- if (typeof input === 'string') {
- input = offsetFromString(matchShortOffset, input);
- } else if (Math.abs(input) < 16) {
- input = input * 60;
- }
- if (!this._isUTC && keepLocalTime) {
- localAdjust = getDateOffset(this);
- }
- this._offset = input;
- this._isUTC = true;
- if (localAdjust != null) {
- this.add(localAdjust, 'm');
- }
- if (offset !== input) {
- if (!keepLocalTime || this._changeInProgress) {
- add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);
- } else if (!this._changeInProgress) {
- this._changeInProgress = true;
- utils_hooks__hooks.updateOffset(this, true);
- this._changeInProgress = null;
- }
- }
- return this;
- } else {
- return this._isUTC ? offset : getDateOffset(this);
- }
- }
-
- function getSetZone (input, keepLocalTime) {
- if (input != null) {
- if (typeof input !== 'string') {
- input = -input;
- }
-
- this.utcOffset(input, keepLocalTime);
-
- return this;
- } else {
- return -this.utcOffset();
- }
- }
-
- function setOffsetToUTC (keepLocalTime) {
- return this.utcOffset(0, keepLocalTime);
- }
-
- function setOffsetToLocal (keepLocalTime) {
- if (this._isUTC) {
- this.utcOffset(0, keepLocalTime);
- this._isUTC = false;
-
- if (keepLocalTime) {
- this.subtract(getDateOffset(this), 'm');
- }
- }
- return this;
- }
-
- function setOffsetToParsedOffset () {
- if (this._tzm) {
- this.utcOffset(this._tzm);
- } else if (typeof this._i === 'string') {
- this.utcOffset(offsetFromString(matchOffset, this._i));
- }
- return this;
- }
-
- function hasAlignedHourOffset (input) {
- if (!this.isValid()) {
- return false;
- }
- input = input ? local__createLocal(input).utcOffset() : 0;
-
- return (this.utcOffset() - input) % 60 === 0;
- }
-
- function isDaylightSavingTime () {
- return (
- this.utcOffset() > this.clone().month(0).utcOffset() ||
- this.utcOffset() > this.clone().month(5).utcOffset()
- );
- }
-
- function isDaylightSavingTimeShifted () {
- if (!isUndefined(this._isDSTShifted)) {
- return this._isDSTShifted;
- }
-
- var c = {};
-
- copyConfig(c, this);
- c = prepareConfig(c);
-
- if (c._a) {
- var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
- this._isDSTShifted = this.isValid() &&
- compareArrays(c._a, other.toArray()) > 0;
- } else {
- this._isDSTShifted = false;
- }
-
- return this._isDSTShifted;
- }
-
- function isLocal () {
- return this.isValid() ? !this._isUTC : false;
- }
-
- function isUtcOffset () {
- return this.isValid() ? this._isUTC : false;
- }
-
- function isUtc () {
- return this.isValid() ? this._isUTC && this._offset === 0 : false;
- }
-
- // ASP.NET json date format regex
- var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/;
-
- // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
- // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
- // and further modified to allow for strings containing both week and day
- var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
-
- function create__createDuration (input, key) {
- var duration = input,
- // matching against regexp is expensive, do it on demand
- match = null,
- sign,
- ret,
- diffRes;
-
- if (isDuration(input)) {
- duration = {
- ms : input._milliseconds,
- d : input._days,
- M : input._months
- };
- } else if (typeof input === 'number') {
- duration = {};
- if (key) {
- duration[key] = input;
- } else {
- duration.milliseconds = input;
- }
- } else if (!!(match = aspNetRegex.exec(input))) {
- sign = (match[1] === '-') ? -1 : 1;
- duration = {
- y : 0,
- d : toInt(match[DATE]) * sign,
- h : toInt(match[HOUR]) * sign,
- m : toInt(match[MINUTE]) * sign,
- s : toInt(match[SECOND]) * sign,
- ms : toInt(match[MILLISECOND]) * sign
- };
- } else if (!!(match = isoRegex.exec(input))) {
- sign = (match[1] === '-') ? -1 : 1;
- duration = {
- y : parseIso(match[2], sign),
- M : parseIso(match[3], sign),
- w : parseIso(match[4], sign),
- d : parseIso(match[5], sign),
- h : parseIso(match[6], sign),
- m : parseIso(match[7], sign),
- s : parseIso(match[8], sign)
- };
- } else if (duration == null) {// checks for null or undefined
- duration = {};
- } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
- diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));
-
- duration = {};
- duration.ms = diffRes.milliseconds;
- duration.M = diffRes.months;
- }
-
- ret = new Duration(duration);
-
- if (isDuration(input) && hasOwnProp(input, '_locale')) {
- ret._locale = input._locale;
- }
-
- return ret;
- }
-
- create__createDuration.fn = Duration.prototype;
-
- function parseIso (inp, sign) {
- // We'd normally use ~~inp for this, but unfortunately it also
- // converts floats to ints.
- // inp may be undefined, so careful calling replace on it.
- var res = inp && parseFloat(inp.replace(',', '.'));
- // apply sign while we're at it
- return (isNaN(res) ? 0 : res) * sign;
- }
-
- function positiveMomentsDifference(base, other) {
- var res = {milliseconds: 0, months: 0};
-
- res.months = other.month() - base.month() +
- (other.year() - base.year()) * 12;
- if (base.clone().add(res.months, 'M').isAfter(other)) {
- --res.months;
- }
-
- res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
-
- return res;
- }
-
- function momentsDifference(base, other) {
- var res;
- if (!(base.isValid() && other.isValid())) {
- return {milliseconds: 0, months: 0};
- }
-
- other = cloneWithOffset(other, base);
- if (base.isBefore(other)) {
- res = positiveMomentsDifference(base, other);
- } else {
- res = positiveMomentsDifference(other, base);
- res.milliseconds = -res.milliseconds;
- res.months = -res.months;
- }
-
- return res;
- }
-
- function absRound (number) {
- if (number < 0) {
- return Math.round(-1 * number) * -1;
- } else {
- return Math.round(number);
- }
- }
-
- // TODO: remove 'name' arg after deprecation is removed
- function createAdder(direction, name) {
- return function (val, period) {
- var dur, tmp;
- //invert the arguments, but complain about it
- if (period !== null && !isNaN(+period)) {
- deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
- tmp = val; val = period; period = tmp;
- }
-
- val = typeof val === 'string' ? +val : val;
- dur = create__createDuration(val, period);
- add_subtract__addSubtract(this, dur, direction);
- return this;
- };
- }
-
- function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {
- var milliseconds = duration._milliseconds,
- days = absRound(duration._days),
- months = absRound(duration._months);
-
- if (!mom.isValid()) {
- // No op
- return;
- }
-
- updateOffset = updateOffset == null ? true : updateOffset;
-
- if (milliseconds) {
- mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
- }
- if (days) {
- get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
- }
- if (months) {
- setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);
- }
- if (updateOffset) {
- utils_hooks__hooks.updateOffset(mom, days || months);
- }
- }
-
- var add_subtract__add = createAdder(1, 'add');
- var add_subtract__subtract = createAdder(-1, 'subtract');
-
- function moment_calendar__calendar (time, formats) {
- // We want to compare the start of today, vs this.
- // Getting start-of-today depends on whether we're local/utc/offset or not.
- var now = time || local__createLocal(),
- sod = cloneWithOffset(now, this).startOf('day'),
- diff = this.diff(sod, 'days', true),
- format = diff < -6 ? 'sameElse' :
- diff < -1 ? 'lastWeek' :
- diff < 0 ? 'lastDay' :
- diff < 1 ? 'sameDay' :
- diff < 2 ? 'nextDay' :
- diff < 7 ? 'nextWeek' : 'sameElse';
-
- var output = formats && (isFunction(formats[format]) ? formats[format]() : formats[format]);
-
- return this.format(output || this.localeData().calendar(format, this, local__createLocal(now)));
- }
-
- function clone () {
- return new Moment(this);
- }
-
- function isAfter (input, units) {
- var localInput = isMoment(input) ? input : local__createLocal(input);
- if (!(this.isValid() && localInput.isValid())) {
- return false;
- }
- units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
- if (units === 'millisecond') {
- return this.valueOf() > localInput.valueOf();
- } else {
- return localInput.valueOf() < this.clone().startOf(units).valueOf();
- }
- }
-
- function isBefore (input, units) {
- var localInput = isMoment(input) ? input : local__createLocal(input);
- if (!(this.isValid() && localInput.isValid())) {
- return false;
- }
- units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
- if (units === 'millisecond') {
- return this.valueOf() < localInput.valueOf();
- } else {
- return this.clone().endOf(units).valueOf() < localInput.valueOf();
- }
- }
-
- function isBetween (from, to, units, inclusivity) {
- inclusivity = inclusivity || '()';
- return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
- (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
- }
-
- function isSame (input, units) {
- var localInput = isMoment(input) ? input : local__createLocal(input),
- inputMs;
- if (!(this.isValid() && localInput.isValid())) {
- return false;
- }
- units = normalizeUnits(units || 'millisecond');
- if (units === 'millisecond') {
- return this.valueOf() === localInput.valueOf();
- } else {
- inputMs = localInput.valueOf();
- return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
- }
- }
-
- function isSameOrAfter (input, units) {
- return this.isSame(input, units) || this.isAfter(input,units);
- }
-
- function isSameOrBefore (input, units) {
- return this.isSame(input, units) || this.isBefore(input,units);
- }
-
- function diff (input, units, asFloat) {
- var that,
- zoneDelta,
- delta, output;
-
- if (!this.isValid()) {
- return NaN;
- }
-
- that = cloneWithOffset(input, this);
-
- if (!that.isValid()) {
- return NaN;
- }
-
- zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
-
- units = normalizeUnits(units);
-
- if (units === 'year' || units === 'month' || units === 'quarter') {
- output = monthDiff(this, that);
- if (units === 'quarter') {
- output = output / 3;
- } else if (units === 'year') {
- output = output / 12;
- }
- } else {
- delta = this - that;
- output = units === 'second' ? delta / 1e3 : // 1000
- units === 'minute' ? delta / 6e4 : // 1000 * 60
- units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
- units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
- units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
- delta;
- }
- return asFloat ? output : absFloor(output);
- }
-
- function monthDiff (a, b) {
- // difference in months
- var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
- // b is in (anchor - 1 month, anchor + 1 month)
- anchor = a.clone().add(wholeMonthDiff, 'months'),
- anchor2, adjust;
-
- if (b - anchor < 0) {
- anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
- // linear across the month
- adjust = (b - anchor) / (anchor - anchor2);
- } else {
- anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
- // linear across the month
- adjust = (b - anchor) / (anchor2 - anchor);
- }
-
- //check for negative zero, return zero if negative zero
- return -(wholeMonthDiff + adjust) || 0;
- }
-
- utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
- utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
-
- function toString () {
- return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
- }
-
- function moment_format__toISOString () {
- var m = this.clone().utc();
- if (0 < m.year() && m.year() <= 9999) {
- if (isFunction(Date.prototype.toISOString)) {
- // native implementation is ~50x faster, use it when we can
- return this.toDate().toISOString();
- } else {
- return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
- }
- } else {
- return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
- }
- }
-
- function format (inputString) {
- if (!inputString) {
- inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat;
- }
- var output = formatMoment(this, inputString);
- return this.localeData().postformat(output);
- }
-
- function from (time, withoutSuffix) {
- if (this.isValid() &&
- ((isMoment(time) && time.isValid()) ||
- local__createLocal(time).isValid())) {
- return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
- } else {
- return this.localeData().invalidDate();
- }
- }
-
- function fromNow (withoutSuffix) {
- return this.from(local__createLocal(), withoutSuffix);
- }
-
- function to (time, withoutSuffix) {
- if (this.isValid() &&
- ((isMoment(time) && time.isValid()) ||
- local__createLocal(time).isValid())) {
- return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
- } else {
- return this.localeData().invalidDate();
- }
- }
-
- function toNow (withoutSuffix) {
- return this.to(local__createLocal(), withoutSuffix);
- }
-
- // If passed a locale key, it will set the locale for this
- // instance. Otherwise, it will return the locale configuration
- // variables for this instance.
- function locale (key) {
- var newLocaleData;
-
- if (key === undefined) {
- return this._locale._abbr;
- } else {
- newLocaleData = locale_locales__getLocale(key);
- if (newLocaleData != null) {
- this._locale = newLocaleData;
- }
- return this;
- }
- }
-
- var lang = deprecate(
- 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
- function (key) {
- if (key === undefined) {
- return this.localeData();
- } else {
- return this.locale(key);
- }
- }
- );
-
- function localeData () {
- return this._locale;
- }
-
- function startOf (units) {
- units = normalizeUnits(units);
- // the following switch intentionally omits break keywords
- // to utilize falling through the cases.
- switch (units) {
- case 'year':
- this.month(0);
- /* falls through */
- case 'quarter':
- case 'month':
- this.date(1);
- /* falls through */
- case 'week':
- case 'isoWeek':
- case 'day':
- case 'date':
- this.hours(0);
- /* falls through */
- case 'hour':
- this.minutes(0);
- /* falls through */
- case 'minute':
- this.seconds(0);
- /* falls through */
- case 'second':
- this.milliseconds(0);
- }
-
- // weeks are a special case
- if (units === 'week') {
- this.weekday(0);
- }
- if (units === 'isoWeek') {
- this.isoWeekday(1);
- }
-
- // quarters are also special
- if (units === 'quarter') {
- this.month(Math.floor(this.month() / 3) * 3);
- }
-
- return this;
- }
-
- function endOf (units) {
- units = normalizeUnits(units);
- if (units === undefined || units === 'millisecond') {
- return this;
- }
-
- // 'date' is an alias for 'day', so it should be considered as such.
- if (units === 'date') {
- units = 'day';
- }
-
- return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
- }
-
- function to_type__valueOf () {
- return this._d.valueOf() - ((this._offset || 0) * 60000);
- }
-
- function unix () {
- return Math.floor(this.valueOf() / 1000);
- }
-
- function toDate () {
- return this._offset ? new Date(this.valueOf()) : this._d;
- }
-
- function toArray () {
- var m = this;
- return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
- }
-
- function toObject () {
- var m = this;
- return {
- years: m.year(),
- months: m.month(),
- date: m.date(),
- hours: m.hours(),
- minutes: m.minutes(),
- seconds: m.seconds(),
- milliseconds: m.milliseconds()
- };
- }
-
- function toJSON () {
- // new Date(NaN).toJSON() === null
- return this.isValid() ? this.toISOString() : null;
- }
-
- function moment_valid__isValid () {
- return valid__isValid(this);
- }
-
- function parsingFlags () {
- return extend({}, getParsingFlags(this));
- }
-
- function invalidAt () {
- return getParsingFlags(this).overflow;
- }
-
- function creationData() {
- return {
- input: this._i,
- format: this._f,
- locale: this._locale,
- isUTC: this._isUTC,
- strict: this._strict
- };
- }
-
- // FORMATTING
-
- addFormatToken(0, ['gg', 2], 0, function () {
- return this.weekYear() % 100;
- });
-
- addFormatToken(0, ['GG', 2], 0, function () {
- return this.isoWeekYear() % 100;
- });
-
- function addWeekYearFormatToken (token, getter) {
- addFormatToken(0, [token, token.length], 0, getter);
- }
-
- addWeekYearFormatToken('gggg', 'weekYear');
- addWeekYearFormatToken('ggggg', 'weekYear');
- addWeekYearFormatToken('GGGG', 'isoWeekYear');
- addWeekYearFormatToken('GGGGG', 'isoWeekYear');
-
- // ALIASES
-
- addUnitAlias('weekYear', 'gg');
- addUnitAlias('isoWeekYear', 'GG');
-
- // PARSING
-
- addRegexToken('G', matchSigned);
- addRegexToken('g', matchSigned);
- addRegexToken('GG', match1to2, match2);
- addRegexToken('gg', match1to2, match2);
- addRegexToken('GGGG', match1to4, match4);
- addRegexToken('gggg', match1to4, match4);
- addRegexToken('GGGGG', match1to6, match6);
- addRegexToken('ggggg', match1to6, match6);
-
- addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
- week[token.substr(0, 2)] = toInt(input);
- });
-
- addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
- week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
- });
-
- // MOMENTS
-
- function getSetWeekYear (input) {
- return getSetWeekYearHelper.call(this,
- input,
- this.week(),
- this.weekday(),
- this.localeData()._week.dow,
- this.localeData()._week.doy);
- }
-
- function getSetISOWeekYear (input) {
- return getSetWeekYearHelper.call(this,
- input, this.isoWeek(), this.isoWeekday(), 1, 4);
- }
-
- function getISOWeeksInYear () {
- return weeksInYear(this.year(), 1, 4);
- }
-
- function getWeeksInYear () {
- var weekInfo = this.localeData()._week;
- return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
- }
-
- function getSetWeekYearHelper(input, week, weekday, dow, doy) {
- var weeksTarget;
- if (input == null) {
- return weekOfYear(this, dow, doy).year;
- } else {
- weeksTarget = weeksInYear(input, dow, doy);
- if (week > weeksTarget) {
- week = weeksTarget;
- }
- return setWeekAll.call(this, input, week, weekday, dow, doy);
- }
- }
-
- function setWeekAll(weekYear, week, weekday, dow, doy) {
- var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
- date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
-
- this.year(date.getUTCFullYear());
- this.month(date.getUTCMonth());
- this.date(date.getUTCDate());
- return this;
- }
-
- // FORMATTING
-
- addFormatToken('Q', 0, 'Qo', 'quarter');
-
- // ALIASES
-
- addUnitAlias('quarter', 'Q');
-
- // PARSING
-
- addRegexToken('Q', match1);
- addParseToken('Q', function (input, array) {
- array[MONTH] = (toInt(input) - 1) * 3;
- });
-
- // MOMENTS
-
- function getSetQuarter (input) {
- return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
- }
-
- // FORMATTING
-
- addFormatToken('w', ['ww', 2], 'wo', 'week');
- addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
-
- // ALIASES
-
- addUnitAlias('week', 'w');
- addUnitAlias('isoWeek', 'W');
-
- // PARSING
-
- addRegexToken('w', match1to2);
- addRegexToken('ww', match1to2, match2);
- addRegexToken('W', match1to2);
- addRegexToken('WW', match1to2, match2);
-
- addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
- week[token.substr(0, 1)] = toInt(input);
- });
-
- // HELPERS
-
- // LOCALES
-
- function localeWeek (mom) {
- return weekOfYear(mom, this._week.dow, this._week.doy).week;
- }
-
- var defaultLocaleWeek = {
- dow : 0, // Sunday is the first day of the week.
- doy : 6 // The week that contains Jan 1st is the first week of the year.
- };
-
- function localeFirstDayOfWeek () {
- return this._week.dow;
- }
-
- function localeFirstDayOfYear () {
- return this._week.doy;
- }
-
- // MOMENTS
-
- function getSetWeek (input) {
- var week = this.localeData().week(this);
- return input == null ? week : this.add((input - week) * 7, 'd');
- }
-
- function getSetISOWeek (input) {
- var week = weekOfYear(this, 1, 4).week;
- return input == null ? week : this.add((input - week) * 7, 'd');
- }
-
- // FORMATTING
-
- addFormatToken('D', ['DD', 2], 'Do', 'date');
-
- // ALIASES
-
- addUnitAlias('date', 'D');
-
- // PARSING
-
- addRegexToken('D', match1to2);
- addRegexToken('DD', match1to2, match2);
- addRegexToken('Do', function (isStrict, locale) {
- return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
- });
-
- addParseToken(['D', 'DD'], DATE);
- addParseToken('Do', function (input, array) {
- array[DATE] = toInt(input.match(match1to2)[0], 10);
- });
-
- // MOMENTS
-
- var getSetDayOfMonth = makeGetSet('Date', true);
-
- // FORMATTING
-
- addFormatToken('d', 0, 'do', 'day');
-
- addFormatToken('dd', 0, 0, function (format) {
- return this.localeData().weekdaysMin(this, format);
- });
-
- addFormatToken('ddd', 0, 0, function (format) {
- return this.localeData().weekdaysShort(this, format);
- });
-
- addFormatToken('dddd', 0, 0, function (format) {
- return this.localeData().weekdays(this, format);
- });
-
- addFormatToken('e', 0, 0, 'weekday');
- addFormatToken('E', 0, 0, 'isoWeekday');
-
- // ALIASES
-
- addUnitAlias('day', 'd');
- addUnitAlias('weekday', 'e');
- addUnitAlias('isoWeekday', 'E');
-
- // PARSING
-
- addRegexToken('d', match1to2);
- addRegexToken('e', match1to2);
- addRegexToken('E', match1to2);
- addRegexToken('dd', function (isStrict, locale) {
- return locale.weekdaysMinRegex(isStrict);
- });
- addRegexToken('ddd', function (isStrict, locale) {
- return locale.weekdaysShortRegex(isStrict);
- });
- addRegexToken('dddd', function (isStrict, locale) {
- return locale.weekdaysRegex(isStrict);
- });
-
- addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
- var weekday = config._locale.weekdaysParse(input, token, config._strict);
- // if we didn't get a weekday name, mark the date as invalid
- if (weekday != null) {
- week.d = weekday;
- } else {
- getParsingFlags(config).invalidWeekday = input;
- }
- });
-
- addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
- week[token] = toInt(input);
- });
-
- // HELPERS
-
- function parseWeekday(input, locale) {
- if (typeof input !== 'string') {
- return input;
- }
-
- if (!isNaN(input)) {
- return parseInt(input, 10);
- }
-
- input = locale.weekdaysParse(input);
- if (typeof input === 'number') {
- return input;
- }
-
- return null;
- }
-
- // LOCALES
-
- var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
- function localeWeekdays (m, format) {
- return isArray(this._weekdays) ? this._weekdays[m.day()] :
- this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
- }
-
- var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
- function localeWeekdaysShort (m) {
- return this._weekdaysShort[m.day()];
- }
-
- var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
- function localeWeekdaysMin (m) {
- return this._weekdaysMin[m.day()];
- }
-
- function day_of_week__handleStrictParse(weekdayName, format, strict) {
- var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
- if (!this._weekdaysParse) {
- this._weekdaysParse = [];
- this._shortWeekdaysParse = [];
- this._minWeekdaysParse = [];
-
- for (i = 0; i < 7; ++i) {
- mom = create_utc__createUTC([2000, 1]).day(i);
- this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
- this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
- this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
- }
- }
-
- if (strict) {
- if (format === 'dddd') {
- ii = indexOf.call(this._weekdaysParse, llc);
- return ii !== -1 ? ii : null;
- } else if (format === 'ddd') {
- ii = indexOf.call(this._shortWeekdaysParse, llc);
- return ii !== -1 ? ii : null;
- } else {
- ii = indexOf.call(this._minWeekdaysParse, llc);
- return ii !== -1 ? ii : null;
- }
- } else {
- if (format === 'dddd') {
- ii = indexOf.call(this._weekdaysParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._shortWeekdaysParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._minWeekdaysParse, llc);
- return ii !== -1 ? ii : null;
- } else if (format === 'ddd') {
- ii = indexOf.call(this._shortWeekdaysParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._weekdaysParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._minWeekdaysParse, llc);
- return ii !== -1 ? ii : null;
- } else {
- ii = indexOf.call(this._minWeekdaysParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._weekdaysParse, llc);
- if (ii !== -1) {
- return ii;
- }
- ii = indexOf.call(this._shortWeekdaysParse, llc);
- return ii !== -1 ? ii : null;
- }
- }
- }
-
- function localeWeekdaysParse (weekdayName, format, strict) {
- var i, mom, regex;
-
- if (this._weekdaysParseExact) {
- return day_of_week__handleStrictParse.call(this, weekdayName, format, strict);
- }
-
- if (!this._weekdaysParse) {
- this._weekdaysParse = [];
- this._minWeekdaysParse = [];
- this._shortWeekdaysParse = [];
- this._fullWeekdaysParse = [];
- }
-
- for (i = 0; i < 7; i++) {
- // make the regex if we don't have it already
-
- mom = create_utc__createUTC([2000, 1]).day(i);
- if (strict && !this._fullWeekdaysParse[i]) {
- this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
- this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
- this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
- }
- if (!this._weekdaysParse[i]) {
- regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
- this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
- }
- // test the regex
- if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
- return i;
- } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
- return i;
- } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
- return i;
- } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
- return i;
- }
- }
- }
-
- // MOMENTS
-
- function getSetDayOfWeek (input) {
- if (!this.isValid()) {
- return input != null ? this : NaN;
- }
- var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
- if (input != null) {
- input = parseWeekday(input, this.localeData());
- return this.add(input - day, 'd');
- } else {
- return day;
- }
- }
-
- function getSetLocaleDayOfWeek (input) {
- if (!this.isValid()) {
- return input != null ? this : NaN;
- }
- var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
- return input == null ? weekday : this.add(input - weekday, 'd');
- }
-
- function getSetISODayOfWeek (input) {
- if (!this.isValid()) {
- return input != null ? this : NaN;
- }
- // behaves the same as moment#day except
- // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
- // as a setter, sunday should belong to the previous week.
- return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
- }
-
- var defaultWeekdaysRegex = matchWord;
- function weekdaysRegex (isStrict) {
- if (this._weekdaysParseExact) {
- if (!hasOwnProp(this, '_weekdaysRegex')) {
- computeWeekdaysParse.call(this);
- }
- if (isStrict) {
- return this._weekdaysStrictRegex;
- } else {
- return this._weekdaysRegex;
- }
- } else {
- return this._weekdaysStrictRegex && isStrict ?
- this._weekdaysStrictRegex : this._weekdaysRegex;
- }
- }
-
- var defaultWeekdaysShortRegex = matchWord;
- function weekdaysShortRegex (isStrict) {
- if (this._weekdaysParseExact) {
- if (!hasOwnProp(this, '_weekdaysRegex')) {
- computeWeekdaysParse.call(this);
- }
- if (isStrict) {
- return this._weekdaysShortStrictRegex;
- } else {
- return this._weekdaysShortRegex;
- }
- } else {
- return this._weekdaysShortStrictRegex && isStrict ?
- this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
- }
- }
-
- var defaultWeekdaysMinRegex = matchWord;
- function weekdaysMinRegex (isStrict) {
- if (this._weekdaysParseExact) {
- if (!hasOwnProp(this, '_weekdaysRegex')) {
- computeWeekdaysParse.call(this);
- }
- if (isStrict) {
- return this._weekdaysMinStrictRegex;
- } else {
- return this._weekdaysMinRegex;
- }
- } else {
- return this._weekdaysMinStrictRegex && isStrict ?
- this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
- }
- }
-
-
- function computeWeekdaysParse () {
- function cmpLenRev(a, b) {
- return b.length - a.length;
- }
-
- var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
- i, mom, minp, shortp, longp;
- for (i = 0; i < 7; i++) {
- // make the regex if we don't have it already
- mom = create_utc__createUTC([2000, 1]).day(i);
- minp = this.weekdaysMin(mom, '');
- shortp = this.weekdaysShort(mom, '');
- longp = this.weekdays(mom, '');
- minPieces.push(minp);
- shortPieces.push(shortp);
- longPieces.push(longp);
- mixedPieces.push(minp);
- mixedPieces.push(shortp);
- mixedPieces.push(longp);
- }
- // Sorting makes sure if one weekday (or abbr) is a prefix of another it
- // will match the longer piece.
- minPieces.sort(cmpLenRev);
- shortPieces.sort(cmpLenRev);
- longPieces.sort(cmpLenRev);
- mixedPieces.sort(cmpLenRev);
- for (i = 0; i < 7; i++) {
- shortPieces[i] = regexEscape(shortPieces[i]);
- longPieces[i] = regexEscape(longPieces[i]);
- mixedPieces[i] = regexEscape(mixedPieces[i]);
- }
-
- this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
- this._weekdaysShortRegex = this._weekdaysRegex;
- this._weekdaysMinRegex = this._weekdaysRegex;
-
- this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
- this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
- this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
- }
-
- // FORMATTING
-
- addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
-
- // ALIASES
-
- addUnitAlias('dayOfYear', 'DDD');
-
- // PARSING
-
- addRegexToken('DDD', match1to3);
- addRegexToken('DDDD', match3);
- addParseToken(['DDD', 'DDDD'], function (input, array, config) {
- config._dayOfYear = toInt(input);
- });
-
- // HELPERS
-
- // MOMENTS
-
- function getSetDayOfYear (input) {
- var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
- return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
- }
-
- // FORMATTING
-
- function hFormat() {
- return this.hours() % 12 || 12;
- }
-
- function kFormat() {
- return this.hours() || 24;
- }
-
- addFormatToken('H', ['HH', 2], 0, 'hour');
- addFormatToken('h', ['hh', 2], 0, hFormat);
- addFormatToken('k', ['kk', 2], 0, kFormat);
-
- addFormatToken('hmm', 0, 0, function () {
- return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
- });
-
- addFormatToken('hmmss', 0, 0, function () {
- return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
- zeroFill(this.seconds(), 2);
- });
-
- addFormatToken('Hmm', 0, 0, function () {
- return '' + this.hours() + zeroFill(this.minutes(), 2);
- });
-
- addFormatToken('Hmmss', 0, 0, function () {
- return '' + this.hours() + zeroFill(this.minutes(), 2) +
- zeroFill(this.seconds(), 2);
- });
-
- function meridiem (token, lowercase) {
- addFormatToken(token, 0, 0, function () {
- return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
- });
- }
-
- meridiem('a', true);
- meridiem('A', false);
-
- // ALIASES
-
- addUnitAlias('hour', 'h');
-
- // PARSING
-
- function matchMeridiem (isStrict, locale) {
- return locale._meridiemParse;
- }
-
- addRegexToken('a', matchMeridiem);
- addRegexToken('A', matchMeridiem);
- addRegexToken('H', match1to2);
- addRegexToken('h', match1to2);
- addRegexToken('HH', match1to2, match2);
- addRegexToken('hh', match1to2, match2);
-
- addRegexToken('hmm', match3to4);
- addRegexToken('hmmss', match5to6);
- addRegexToken('Hmm', match3to4);
- addRegexToken('Hmmss', match5to6);
-
- addParseToken(['H', 'HH'], HOUR);
- addParseToken(['a', 'A'], function (input, array, config) {
- config._isPm = config._locale.isPM(input);
- config._meridiem = input;
- });
- addParseToken(['h', 'hh'], function (input, array, config) {
- array[HOUR] = toInt(input);
- getParsingFlags(config).bigHour = true;
- });
- addParseToken('hmm', function (input, array, config) {
- var pos = input.length - 2;
- array[HOUR] = toInt(input.substr(0, pos));
- array[MINUTE] = toInt(input.substr(pos));
- getParsingFlags(config).bigHour = true;
- });
- addParseToken('hmmss', function (input, array, config) {
- var pos1 = input.length - 4;
- var pos2 = input.length - 2;
- array[HOUR] = toInt(input.substr(0, pos1));
- array[MINUTE] = toInt(input.substr(pos1, 2));
- array[SECOND] = toInt(input.substr(pos2));
- getParsingFlags(config).bigHour = true;
- });
- addParseToken('Hmm', function (input, array, config) {
- var pos = input.length - 2;
- array[HOUR] = toInt(input.substr(0, pos));
- array[MINUTE] = toInt(input.substr(pos));
- });
- addParseToken('Hmmss', function (input, array, config) {
- var pos1 = input.length - 4;
- var pos2 = input.length - 2;
- array[HOUR] = toInt(input.substr(0, pos1));
- array[MINUTE] = toInt(input.substr(pos1, 2));
- array[SECOND] = toInt(input.substr(pos2));
- });
-
- // LOCALES
-
- function localeIsPM (input) {
- // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
- // Using charAt should be more compatible.
- return ((input + '').toLowerCase().charAt(0) === 'p');
- }
-
- var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
- function localeMeridiem (hours, minutes, isLower) {
- if (hours > 11) {
- return isLower ? 'pm' : 'PM';
- } else {
- return isLower ? 'am' : 'AM';
- }
- }
-
-
- // MOMENTS
-
- // Setting the hour should keep the time, because the user explicitly
- // specified which hour he wants. So trying to maintain the same hour (in
- // a new timezone) makes sense. Adding/subtracting hours does not follow
- // this rule.
- var getSetHour = makeGetSet('Hours', true);
-
- // FORMATTING
-
- addFormatToken('m', ['mm', 2], 0, 'minute');
-
- // ALIASES
-
- addUnitAlias('minute', 'm');
-
- // PARSING
-
- addRegexToken('m', match1to2);
- addRegexToken('mm', match1to2, match2);
- addParseToken(['m', 'mm'], MINUTE);
-
- // MOMENTS
-
- var getSetMinute = makeGetSet('Minutes', false);
-
- // FORMATTING
-
- addFormatToken('s', ['ss', 2], 0, 'second');
-
- // ALIASES
-
- addUnitAlias('second', 's');
-
- // PARSING
-
- addRegexToken('s', match1to2);
- addRegexToken('ss', match1to2, match2);
- addParseToken(['s', 'ss'], SECOND);
-
- // MOMENTS
-
- var getSetSecond = makeGetSet('Seconds', false);
-
- // FORMATTING
-
- addFormatToken('S', 0, 0, function () {
- return ~~(this.millisecond() / 100);
- });
-
- addFormatToken(0, ['SS', 2], 0, function () {
- return ~~(this.millisecond() / 10);
- });
-
- addFormatToken(0, ['SSS', 3], 0, 'millisecond');
- addFormatToken(0, ['SSSS', 4], 0, function () {
- return this.millisecond() * 10;
- });
- addFormatToken(0, ['SSSSS', 5], 0, function () {
- return this.millisecond() * 100;
- });
- addFormatToken(0, ['SSSSSS', 6], 0, function () {
- return this.millisecond() * 1000;
- });
- addFormatToken(0, ['SSSSSSS', 7], 0, function () {
- return this.millisecond() * 10000;
- });
- addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
- return this.millisecond() * 100000;
- });
- addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
- return this.millisecond() * 1000000;
- });
-
-
- // ALIASES
-
- addUnitAlias('millisecond', 'ms');
-
- // PARSING
-
- addRegexToken('S', match1to3, match1);
- addRegexToken('SS', match1to3, match2);
- addRegexToken('SSS', match1to3, match3);
-
- var token;
- for (token = 'SSSS'; token.length <= 9; token += 'S') {
- addRegexToken(token, matchUnsigned);
- }
-
- function parseMs(input, array) {
- array[MILLISECOND] = toInt(('0.' + input) * 1000);
- }
-
- for (token = 'S'; token.length <= 9; token += 'S') {
- addParseToken(token, parseMs);
- }
- // MOMENTS
-
- var getSetMillisecond = makeGetSet('Milliseconds', false);
-
- // FORMATTING
-
- addFormatToken('z', 0, 0, 'zoneAbbr');
- addFormatToken('zz', 0, 0, 'zoneName');
-
- // MOMENTS
-
- function getZoneAbbr () {
- return this._isUTC ? 'UTC' : '';
- }
-
- function getZoneName () {
- return this._isUTC ? 'Coordinated Universal Time' : '';
- }
-
- var momentPrototype__proto = Moment.prototype;
-
- momentPrototype__proto.add = add_subtract__add;
- momentPrototype__proto.calendar = moment_calendar__calendar;
- momentPrototype__proto.clone = clone;
- momentPrototype__proto.diff = diff;
- momentPrototype__proto.endOf = endOf;
- momentPrototype__proto.format = format;
- momentPrototype__proto.from = from;
- momentPrototype__proto.fromNow = fromNow;
- momentPrototype__proto.to = to;
- momentPrototype__proto.toNow = toNow;
- momentPrototype__proto.get = getSet;
- momentPrototype__proto.invalidAt = invalidAt;
- momentPrototype__proto.isAfter = isAfter;
- momentPrototype__proto.isBefore = isBefore;
- momentPrototype__proto.isBetween = isBetween;
- momentPrototype__proto.isSame = isSame;
- momentPrototype__proto.isSameOrAfter = isSameOrAfter;
- momentPrototype__proto.isSameOrBefore = isSameOrBefore;
- momentPrototype__proto.isValid = moment_valid__isValid;
- momentPrototype__proto.lang = lang;
- momentPrototype__proto.locale = locale;
- momentPrototype__proto.localeData = localeData;
- momentPrototype__proto.max = prototypeMax;
- momentPrototype__proto.min = prototypeMin;
- momentPrototype__proto.parsingFlags = parsingFlags;
- momentPrototype__proto.set = getSet;
- momentPrototype__proto.startOf = startOf;
- momentPrototype__proto.subtract = add_subtract__subtract;
- momentPrototype__proto.toArray = toArray;
- momentPrototype__proto.toObject = toObject;
- momentPrototype__proto.toDate = toDate;
- momentPrototype__proto.toISOString = moment_format__toISOString;
- momentPrototype__proto.toJSON = toJSON;
- momentPrototype__proto.toString = toString;
- momentPrototype__proto.unix = unix;
- momentPrototype__proto.valueOf = to_type__valueOf;
- momentPrototype__proto.creationData = creationData;
-
- // Year
- momentPrototype__proto.year = getSetYear;
- momentPrototype__proto.isLeapYear = getIsLeapYear;
-
- // Week Year
- momentPrototype__proto.weekYear = getSetWeekYear;
- momentPrototype__proto.isoWeekYear = getSetISOWeekYear;
-
- // Quarter
- momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;
-
- // Month
- momentPrototype__proto.month = getSetMonth;
- momentPrototype__proto.daysInMonth = getDaysInMonth;
-
- // Week
- momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek;
- momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek;
- momentPrototype__proto.weeksInYear = getWeeksInYear;
- momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;
-
- // Day
- momentPrototype__proto.date = getSetDayOfMonth;
- momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek;
- momentPrototype__proto.weekday = getSetLocaleDayOfWeek;
- momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
- momentPrototype__proto.dayOfYear = getSetDayOfYear;
-
- // Hour
- momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;
-
- // Minute
- momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;
-
- // Second
- momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;
-
- // Millisecond
- momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;
-
- // Offset
- momentPrototype__proto.utcOffset = getSetOffset;
- momentPrototype__proto.utc = setOffsetToUTC;
- momentPrototype__proto.local = setOffsetToLocal;
- momentPrototype__proto.parseZone = setOffsetToParsedOffset;
- momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;
- momentPrototype__proto.isDST = isDaylightSavingTime;
- momentPrototype__proto.isDSTShifted = isDaylightSavingTimeShifted;
- momentPrototype__proto.isLocal = isLocal;
- momentPrototype__proto.isUtcOffset = isUtcOffset;
- momentPrototype__proto.isUtc = isUtc;
- momentPrototype__proto.isUTC = isUtc;
-
- // Timezone
- momentPrototype__proto.zoneAbbr = getZoneAbbr;
- momentPrototype__proto.zoneName = getZoneName;
-
- // Deprecations
- momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
- momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
- momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
- momentPrototype__proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);
-
- var momentPrototype = momentPrototype__proto;
-
- function moment__createUnix (input) {
- return local__createLocal(input * 1000);
- }
-
- function moment__createInZone () {
- return local__createLocal.apply(null, arguments).parseZone();
- }
-
- var defaultCalendar = {
- sameDay : '[Today at] LT',
- nextDay : '[Tomorrow at] LT',
- nextWeek : 'dddd [at] LT',
- lastDay : '[Yesterday at] LT',
- lastWeek : '[Last] dddd [at] LT',
- sameElse : 'L'
- };
-
- function locale_calendar__calendar (key, mom, now) {
- var output = this._calendar[key];
- return isFunction(output) ? output.call(mom, now) : output;
- }
-
- var defaultLongDateFormat = {
- LTS : 'h:mm:ss A',
- LT : 'h:mm A',
- L : 'MM/DD/YYYY',
- LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY h:mm A',
- LLLL : 'dddd, MMMM D, YYYY h:mm A'
- };
-
- function longDateFormat (key) {
- var format = this._longDateFormat[key],
- formatUpper = this._longDateFormat[key.toUpperCase()];
-
- if (format || !formatUpper) {
- return format;
- }
-
- this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
- return val.slice(1);
- });
-
- return this._longDateFormat[key];
- }
-
- var defaultInvalidDate = 'Invalid date';
-
- function invalidDate () {
- return this._invalidDate;
- }
-
- var defaultOrdinal = '%d';
- var defaultOrdinalParse = /\d{1,2}/;
-
- function ordinal (number) {
- return this._ordinal.replace('%d', number);
- }
-
- function preParsePostFormat (string) {
- return string;
- }
-
- var defaultRelativeTime = {
- future : 'in %s',
- past : '%s ago',
- s : 'a few seconds',
- m : 'a minute',
- mm : '%d minutes',
- h : 'an hour',
- hh : '%d hours',
- d : 'a day',
- dd : '%d days',
- M : 'a month',
- MM : '%d months',
- y : 'a year',
- yy : '%d years'
- };
-
- function relative__relativeTime (number, withoutSuffix, string, isFuture) {
- var output = this._relativeTime[string];
- return (isFunction(output)) ?
- output(number, withoutSuffix, string, isFuture) :
- output.replace(/%d/i, number);
- }
-
- function pastFuture (diff, output) {
- var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
- return isFunction(format) ? format(output) : format.replace(/%s/i, output);
- }
-
- var prototype__proto = Locale.prototype;
-
- prototype__proto._calendar = defaultCalendar;
- prototype__proto.calendar = locale_calendar__calendar;
- prototype__proto._longDateFormat = defaultLongDateFormat;
- prototype__proto.longDateFormat = longDateFormat;
- prototype__proto._invalidDate = defaultInvalidDate;
- prototype__proto.invalidDate = invalidDate;
- prototype__proto._ordinal = defaultOrdinal;
- prototype__proto.ordinal = ordinal;
- prototype__proto._ordinalParse = defaultOrdinalParse;
- prototype__proto.preparse = preParsePostFormat;
- prototype__proto.postformat = preParsePostFormat;
- prototype__proto._relativeTime = defaultRelativeTime;
- prototype__proto.relativeTime = relative__relativeTime;
- prototype__proto.pastFuture = pastFuture;
- prototype__proto.set = locale_set__set;
-
- // Month
- prototype__proto.months = localeMonths;
- prototype__proto._months = defaultLocaleMonths;
- prototype__proto.monthsShort = localeMonthsShort;
- prototype__proto._monthsShort = defaultLocaleMonthsShort;
- prototype__proto.monthsParse = localeMonthsParse;
- prototype__proto._monthsRegex = defaultMonthsRegex;
- prototype__proto.monthsRegex = monthsRegex;
- prototype__proto._monthsShortRegex = defaultMonthsShortRegex;
- prototype__proto.monthsShortRegex = monthsShortRegex;
-
- // Week
- prototype__proto.week = localeWeek;
- prototype__proto._week = defaultLocaleWeek;
- prototype__proto.firstDayOfYear = localeFirstDayOfYear;
- prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;
-
- // Day of Week
- prototype__proto.weekdays = localeWeekdays;
- prototype__proto._weekdays = defaultLocaleWeekdays;
- prototype__proto.weekdaysMin = localeWeekdaysMin;
- prototype__proto._weekdaysMin = defaultLocaleWeekdaysMin;
- prototype__proto.weekdaysShort = localeWeekdaysShort;
- prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;
- prototype__proto.weekdaysParse = localeWeekdaysParse;
-
- prototype__proto._weekdaysRegex = defaultWeekdaysRegex;
- prototype__proto.weekdaysRegex = weekdaysRegex;
- prototype__proto._weekdaysShortRegex = defaultWeekdaysShortRegex;
- prototype__proto.weekdaysShortRegex = weekdaysShortRegex;
- prototype__proto._weekdaysMinRegex = defaultWeekdaysMinRegex;
- prototype__proto.weekdaysMinRegex = weekdaysMinRegex;
-
- // Hours
- prototype__proto.isPM = localeIsPM;
- prototype__proto._meridiemParse = defaultLocaleMeridiemParse;
- prototype__proto.meridiem = localeMeridiem;
-
- function lists__get (format, index, field, setter) {
- var locale = locale_locales__getLocale();
- var utc = create_utc__createUTC().set(setter, index);
- return locale[field](utc, format);
- }
-
- function listMonthsImpl (format, index, field) {
- if (typeof format === 'number') {
- index = format;
- format = undefined;
- }
-
- format = format || '';
-
- if (index != null) {
- return lists__get(format, index, field, 'month');
- }
-
- var i;
- var out = [];
- for (i = 0; i < 12; i++) {
- out[i] = lists__get(format, i, field, 'month');
- }
- return out;
- }
-
- // ()
- // (5)
- // (fmt, 5)
- // (fmt)
- // (true)
- // (true, 5)
- // (true, fmt, 5)
- // (true, fmt)
- function listWeekdaysImpl (localeSorted, format, index, field) {
- if (typeof localeSorted === 'boolean') {
- if (typeof format === 'number') {
- index = format;
- format = undefined;
- }
-
- format = format || '';
- } else {
- format = localeSorted;
- index = format;
- localeSorted = false;
-
- if (typeof format === 'number') {
- index = format;
- format = undefined;
- }
-
- format = format || '';
- }
-
- var locale = locale_locales__getLocale(),
- shift = localeSorted ? locale._week.dow : 0;
-
- if (index != null) {
- return lists__get(format, (index + shift) % 7, field, 'day');
- }
-
- var i;
- var out = [];
- for (i = 0; i < 7; i++) {
- out[i] = lists__get(format, (i + shift) % 7, field, 'day');
- }
- return out;
- }
-
- function lists__listMonths (format, index) {
- return listMonthsImpl(format, index, 'months');
- }
-
- function lists__listMonthsShort (format, index) {
- return listMonthsImpl(format, index, 'monthsShort');
- }
-
- function lists__listWeekdays (localeSorted, format, index) {
- return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
- }
-
- function lists__listWeekdaysShort (localeSorted, format, index) {
- return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
- }
-
- function lists__listWeekdaysMin (localeSorted, format, index) {
- return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
- }
-
- locale_locales__getSetGlobalLocale('en', {
- ordinalParse: /\d{1,2}(th|st|nd|rd)/,
- ordinal : function (number) {
- var b = number % 10,
- output = (toInt(number % 100 / 10) === 1) ? 'th' :
- (b === 1) ? 'st' :
- (b === 2) ? 'nd' :
- (b === 3) ? 'rd' : 'th';
- return number + output;
- }
- });
-
- // Side effect imports
- utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
- utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);
-
- var mathAbs = Math.abs;
-
- function duration_abs__abs () {
- var data = this._data;
-
- this._milliseconds = mathAbs(this._milliseconds);
- this._days = mathAbs(this._days);
- this._months = mathAbs(this._months);
-
- data.milliseconds = mathAbs(data.milliseconds);
- data.seconds = mathAbs(data.seconds);
- data.minutes = mathAbs(data.minutes);
- data.hours = mathAbs(data.hours);
- data.months = mathAbs(data.months);
- data.years = mathAbs(data.years);
-
- return this;
- }
-
- function duration_add_subtract__addSubtract (duration, input, value, direction) {
- var other = create__createDuration(input, value);
-
- duration._milliseconds += direction * other._milliseconds;
- duration._days += direction * other._days;
- duration._months += direction * other._months;
-
- return duration._bubble();
- }
-
- // supports only 2.0-style add(1, 's') or add(duration)
- function duration_add_subtract__add (input, value) {
- return duration_add_subtract__addSubtract(this, input, value, 1);
- }
-
- // supports only 2.0-style subtract(1, 's') or subtract(duration)
- function duration_add_subtract__subtract (input, value) {
- return duration_add_subtract__addSubtract(this, input, value, -1);
- }
-
- function absCeil (number) {
- if (number < 0) {
- return Math.floor(number);
- } else {
- return Math.ceil(number);
- }
- }
-
- function bubble () {
- var milliseconds = this._milliseconds;
- var days = this._days;
- var months = this._months;
- var data = this._data;
- var seconds, minutes, hours, years, monthsFromDays;
-
- // if we have a mix of positive and negative values, bubble down first
- // check: https://github.com/moment/moment/issues/2166
- if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
- (milliseconds <= 0 && days <= 0 && months <= 0))) {
- milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
- days = 0;
- months = 0;
- }
-
- // The following code bubbles up values, see the tests for
- // examples of what that means.
- data.milliseconds = milliseconds % 1000;
-
- seconds = absFloor(milliseconds / 1000);
- data.seconds = seconds % 60;
-
- minutes = absFloor(seconds / 60);
- data.minutes = minutes % 60;
-
- hours = absFloor(minutes / 60);
- data.hours = hours % 24;
-
- days += absFloor(hours / 24);
-
- // convert days to months
- monthsFromDays = absFloor(daysToMonths(days));
- months += monthsFromDays;
- days -= absCeil(monthsToDays(monthsFromDays));
-
- // 12 months -> 1 year
- years = absFloor(months / 12);
- months %= 12;
-
- data.days = days;
- data.months = months;
- data.years = years;
-
- return this;
- }
-
- function daysToMonths (days) {
- // 400 years have 146097 days (taking into account leap year rules)
- // 400 years have 12 months === 4800
- return days * 4800 / 146097;
- }
-
- function monthsToDays (months) {
- // the reverse of daysToMonths
- return months * 146097 / 4800;
- }
-
- function as (units) {
- var days;
- var months;
- var milliseconds = this._milliseconds;
-
- units = normalizeUnits(units);
-
- if (units === 'month' || units === 'year') {
- days = this._days + milliseconds / 864e5;
- months = this._months + daysToMonths(days);
- return units === 'month' ? months : months / 12;
- } else {
- // handle milliseconds separately because of floating point math errors (issue #1867)
- days = this._days + Math.round(monthsToDays(this._months));
- switch (units) {
- case 'week' : return days / 7 + milliseconds / 6048e5;
- case 'day' : return days + milliseconds / 864e5;
- case 'hour' : return days * 24 + milliseconds / 36e5;
- case 'minute' : return days * 1440 + milliseconds / 6e4;
- case 'second' : return days * 86400 + milliseconds / 1000;
- // Math.floor prevents floating point math errors here
- case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
- default: throw new Error('Unknown unit ' + units);
- }
- }
- }
-
- // TODO: Use this.as('ms')?
- function duration_as__valueOf () {
- return (
- this._milliseconds +
- this._days * 864e5 +
- (this._months % 12) * 2592e6 +
- toInt(this._months / 12) * 31536e6
- );
- }
-
- function makeAs (alias) {
- return function () {
- return this.as(alias);
- };
- }
-
- var asMilliseconds = makeAs('ms');
- var asSeconds = makeAs('s');
- var asMinutes = makeAs('m');
- var asHours = makeAs('h');
- var asDays = makeAs('d');
- var asWeeks = makeAs('w');
- var asMonths = makeAs('M');
- var asYears = makeAs('y');
-
- function duration_get__get (units) {
- units = normalizeUnits(units);
- return this[units + 's']();
- }
-
- function makeGetter(name) {
- return function () {
- return this._data[name];
- };
- }
-
- var milliseconds = makeGetter('milliseconds');
- var seconds = makeGetter('seconds');
- var minutes = makeGetter('minutes');
- var hours = makeGetter('hours');
- var days = makeGetter('days');
- var months = makeGetter('months');
- var years = makeGetter('years');
-
- function weeks () {
- return absFloor(this.days() / 7);
- }
-
- var round = Math.round;
- var thresholds = {
- s: 45, // seconds to minute
- m: 45, // minutes to hour
- h: 22, // hours to day
- d: 26, // days to month
- M: 11 // months to year
- };
-
- // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
- function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
- return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
- }
-
- function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {
- var duration = create__createDuration(posNegDuration).abs();
- var seconds = round(duration.as('s'));
- var minutes = round(duration.as('m'));
- var hours = round(duration.as('h'));
- var days = round(duration.as('d'));
- var months = round(duration.as('M'));
- var years = round(duration.as('y'));
-
- var a = seconds < thresholds.s && ['s', seconds] ||
- minutes <= 1 && ['m'] ||
- minutes < thresholds.m && ['mm', minutes] ||
- hours <= 1 && ['h'] ||
- hours < thresholds.h && ['hh', hours] ||
- days <= 1 && ['d'] ||
- days < thresholds.d && ['dd', days] ||
- months <= 1 && ['M'] ||
- months < thresholds.M && ['MM', months] ||
- years <= 1 && ['y'] || ['yy', years];
-
- a[2] = withoutSuffix;
- a[3] = +posNegDuration > 0;
- a[4] = locale;
- return substituteTimeAgo.apply(null, a);
- }
-
- // This function allows you to set a threshold for relative time strings
- function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {
- if (thresholds[threshold] === undefined) {
- return false;
- }
- if (limit === undefined) {
- return thresholds[threshold];
- }
- thresholds[threshold] = limit;
- return true;
- }
-
- function humanize (withSuffix) {
- var locale = this.localeData();
- var output = duration_humanize__relativeTime(this, !withSuffix, locale);
-
- if (withSuffix) {
- output = locale.pastFuture(+this, output);
- }
-
- return locale.postformat(output);
- }
-
- var iso_string__abs = Math.abs;
-
- function iso_string__toISOString() {
- // for ISO strings we do not use the normal bubbling rules:
- // * milliseconds bubble up until they become hours
- // * days do not bubble at all
- // * months bubble up until they become years
- // This is because there is no context-free conversion between hours and days
- // (think of clock changes)
- // and also not between days and months (28-31 days per month)
- var seconds = iso_string__abs(this._milliseconds) / 1000;
- var days = iso_string__abs(this._days);
- var months = iso_string__abs(this._months);
- var minutes, hours, years;
-
- // 3600 seconds -> 60 minutes -> 1 hour
- minutes = absFloor(seconds / 60);
- hours = absFloor(minutes / 60);
- seconds %= 60;
- minutes %= 60;
-
- // 12 months -> 1 year
- years = absFloor(months / 12);
- months %= 12;
-
-
- // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
- var Y = years;
- var M = months;
- var D = days;
- var h = hours;
- var m = minutes;
- var s = seconds;
- var total = this.asSeconds();
-
- if (!total) {
- // this is the same as C#'s (Noda) and python (isodate)...
- // but not other JS (goog.date)
- return 'P0D';
- }
-
- return (total < 0 ? '-' : '') +
- 'P' +
- (Y ? Y + 'Y' : '') +
- (M ? M + 'M' : '') +
- (D ? D + 'D' : '') +
- ((h || m || s) ? 'T' : '') +
- (h ? h + 'H' : '') +
- (m ? m + 'M' : '') +
- (s ? s + 'S' : '');
- }
-
- var duration_prototype__proto = Duration.prototype;
-
- duration_prototype__proto.abs = duration_abs__abs;
- duration_prototype__proto.add = duration_add_subtract__add;
- duration_prototype__proto.subtract = duration_add_subtract__subtract;
- duration_prototype__proto.as = as;
- duration_prototype__proto.asMilliseconds = asMilliseconds;
- duration_prototype__proto.asSeconds = asSeconds;
- duration_prototype__proto.asMinutes = asMinutes;
- duration_prototype__proto.asHours = asHours;
- duration_prototype__proto.asDays = asDays;
- duration_prototype__proto.asWeeks = asWeeks;
- duration_prototype__proto.asMonths = asMonths;
- duration_prototype__proto.asYears = asYears;
- duration_prototype__proto.valueOf = duration_as__valueOf;
- duration_prototype__proto._bubble = bubble;
- duration_prototype__proto.get = duration_get__get;
- duration_prototype__proto.milliseconds = milliseconds;
- duration_prototype__proto.seconds = seconds;
- duration_prototype__proto.minutes = minutes;
- duration_prototype__proto.hours = hours;
- duration_prototype__proto.days = days;
- duration_prototype__proto.weeks = weeks;
- duration_prototype__proto.months = months;
- duration_prototype__proto.years = years;
- duration_prototype__proto.humanize = humanize;
- duration_prototype__proto.toISOString = iso_string__toISOString;
- duration_prototype__proto.toString = iso_string__toISOString;
- duration_prototype__proto.toJSON = iso_string__toISOString;
- duration_prototype__proto.locale = locale;
- duration_prototype__proto.localeData = localeData;
-
- // Deprecations
- duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
- duration_prototype__proto.lang = lang;
-
- // Side effect imports
-
- // FORMATTING
-
- addFormatToken('X', 0, 0, 'unix');
- addFormatToken('x', 0, 0, 'valueOf');
-
- // PARSING
-
- addRegexToken('x', matchSigned);
- addRegexToken('X', matchTimestamp);
- addParseToken('X', function (input, array, config) {
- config._d = new Date(parseFloat(input, 10) * 1000);
- });
- addParseToken('x', function (input, array, config) {
- config._d = new Date(toInt(input));
- });
-
- // Side effect imports
-
-
- utils_hooks__hooks.version = '2.13.0';
-
- setHookCallback(local__createLocal);
-
- utils_hooks__hooks.fn = momentPrototype;
- utils_hooks__hooks.min = min;
- utils_hooks__hooks.max = max;
- utils_hooks__hooks.now = now;
- utils_hooks__hooks.utc = create_utc__createUTC;
- utils_hooks__hooks.unix = moment__createUnix;
- utils_hooks__hooks.months = lists__listMonths;
- utils_hooks__hooks.isDate = isDate;
- utils_hooks__hooks.locale = locale_locales__getSetGlobalLocale;
- utils_hooks__hooks.invalid = valid__createInvalid;
- utils_hooks__hooks.duration = create__createDuration;
- utils_hooks__hooks.isMoment = isMoment;
- utils_hooks__hooks.weekdays = lists__listWeekdays;
- utils_hooks__hooks.parseZone = moment__createInZone;
- utils_hooks__hooks.localeData = locale_locales__getLocale;
- utils_hooks__hooks.isDuration = isDuration;
- utils_hooks__hooks.monthsShort = lists__listMonthsShort;
- utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin;
- utils_hooks__hooks.defineLocale = defineLocale;
- utils_hooks__hooks.updateLocale = updateLocale;
- utils_hooks__hooks.locales = locale_locales__listLocales;
- utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort;
- utils_hooks__hooks.normalizeUnits = normalizeUnits;
- utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
- utils_hooks__hooks.prototype = momentPrototype;
-
- var _moment = utils_hooks__hooks;
-
- return _moment;
-
-}));
-},{}],7:[function(require,module,exports){
-/**\r
- * @namespace Chart\r
- */\r
-var Chart = require(26)();\r
-\r
-require(25)(Chart);\r
-require(24)(Chart);\r
-require(21)(Chart);\r
-require(22)(Chart);\r
-require(23)(Chart);\r
-require(27)(Chart);\r
-require(31)(Chart);\r
-require(29)(Chart);\r
-require(30)(Chart);\r
-require(32)(Chart);\r
-require(28)(Chart);\r
-require(33)(Chart);\r
-\r
-require(34)(Chart);\r
-require(35)(Chart);\r
-require(36)(Chart);\r
-require(37)(Chart);\r
-\r
-require(40)(Chart);\r
-require(38)(Chart);\r
-require(39)(Chart);\r
-require(41)(Chart);\r
-require(42)(Chart);\r
-require(43)(Chart);\r
-\r
-// Controllers must be loaded after elements\r
-// See Chart.core.datasetController.dataElementType\r
-require(15)(Chart);\r
-require(16)(Chart);\r
-require(17)(Chart);\r
-require(18)(Chart);\r
-require(19)(Chart);\r
-require(20)(Chart);\r
-\r
-require(8)(Chart);\r
-require(9)(Chart);\r
-require(10)(Chart);\r
-require(11)(Chart);\r
-require(12)(Chart);\r
-require(13)(Chart);\r
-require(14)(Chart);\r
-\r
-window.Chart = module.exports = Chart;\r
-
-},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"8":8,"9":9}],8:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Bar = function(context, config) {\r
- config.type = 'bar';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],9:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Bubble = function(context, config) {\r
- config.type = 'bubble';\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],10:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Doughnut = function(context, config) {\r
- config.type = 'doughnut';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],11:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Line = function(context, config) {\r
- config.type = 'line';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],12:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.PolarArea = function(context, config) {\r
- config.type = 'polarArea';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],13:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
- \r
- Chart.Radar = function(context, config) {\r
- config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options);\r
- config.type = 'radar';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};\r
-
-},{}],14:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var defaultConfig = {\r
- hover: {\r
- mode: 'single'\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "linear", // scatter should not use a category axis\r
- position: "bottom",\r
- id: "x-axis-1" // need an ID so datasets can reference the scale\r
- }],\r
- yAxes: [{\r
- type: "linear",\r
- position: "left",\r
- id: "y-axis-1"\r
- }]\r
- },\r
-\r
- tooltips: {\r
- callbacks: {\r
- title: function(tooltipItems, data) {\r
- // Title doesn't make sense for scatter since we format the data as a point\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';\r
- }\r
- }\r
- }\r
- };\r
-\r
- // Register the default config for this type\r
- Chart.defaults.scatter = defaultConfig;\r
-\r
- // Scatter charts use line controllers\r
- Chart.controllers.scatter = Chart.controllers.line;\r
-\r
- Chart.Scatter = function(context, config) {\r
- config.type = 'scatter';\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],15:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.bar = {\r
- hover: {\r
- mode: "label"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "category",\r
-\r
- // Specific to Bar Controller\r
- categoryPercentage: 0.8,\r
- barPercentage: 0.9,\r
-\r
- // grid line settings\r
- gridLines: {\r
- offsetGridLines: true\r
- }\r
- }],\r
- yAxes: [{\r
- type: "linear"\r
- }]\r
- }\r
- };\r
-\r
- Chart.controllers.bar = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Rectangle,\r
-\r
- initialize: function(chart, datasetIndex) {\r
- Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);\r
-\r
- // Use this to indicate that this is a bar dataset.\r
- this.getMeta().bar = true;\r
- },\r
-\r
- // Get the number of datasets that display bars. We use this to correctly calculate the bar width\r
- getBarCount: function getBarCount() {\r
- var me = this;\r
- var barCount = 0;\r
- helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {\r
- var meta = me.chart.getDatasetMeta(datasetIndex);\r
- if (meta.bar && me.chart.isDatasetVisible(datasetIndex)) {\r
- ++barCount;\r
- }\r
- }, me);\r
- return barCount;\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- helpers.each(me.getMeta().data, function(rectangle, index) {\r
- me.updateElement(rectangle, index, reset);\r
- }, me);\r
- },\r
-\r
- updateElement: function updateElement(rectangle, index, reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var scaleBase = yScale.getBasePixel();\r
- var rectangleElementOptions = me.chart.options.elements.rectangle;\r
- var custom = rectangle.custom || {};\r
- var dataset = me.getDataset();\r
-\r
- helpers.extend(rectangle, {\r
- // Utility\r
- _xScale: xScale,\r
- _yScale: yScale,\r
- _datasetIndex: me.index,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: me.calculateBarX(index, me.index),\r
- y: reset ? scaleBase : me.calculateBarY(index, me.index),\r
-\r
- // Tooltip\r
- label: me.chart.data.labels[index],\r
- datasetLabel: dataset.label,\r
-\r
- // Appearance\r
- base: reset ? scaleBase : me.calculateBarBase(me.index, index),\r
- width: me.calculateBarWidth(index),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),\r
- borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,\r
- borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)\r
- }\r
- });\r
- rectangle.pivot();\r
- },\r
-\r
- calculateBarBase: function(datasetIndex, index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var base = 0;\r
-\r
- if (yScale.options.stacked) {\r
- var chart = me.chart;\r
- var datasets = chart.data.datasets;\r
- var value = datasets[datasetIndex].data[index];\r
-\r
- if (value < 0) {\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var negDS = datasets[i];\r
- var negDSMeta = chart.getDatasetMeta(i);\r
- if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\r
- base += negDS.data[index] < 0 ? negDS.data[index] : 0;\r
- }\r
- }\r
- } else {\r
- for (var j = 0; j < datasetIndex; j++) {\r
- var posDS = datasets[j];\r
- var posDSMeta = chart.getDatasetMeta(j);\r
- if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(j)) {\r
- base += posDS.data[index] > 0 ? posDS.data[index] : 0;\r
- }\r
- }\r
- }\r
-\r
- return yScale.getPixelForValue(base);\r
- }\r
-\r
- return yScale.getBasePixel();\r
- },\r
-\r
- getRuler: function(index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var datasetCount = me.getBarCount();\r
-\r
- var tickWidth;\r
-\r
- if (xScale.options.type === 'category') {\r
- tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index);\r
- } else {\r
- // Average width\r
- tickWidth = xScale.width / xScale.ticks.length;\r
- }\r
- var categoryWidth = tickWidth * xScale.options.categoryPercentage;\r
- var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;\r
- var fullBarWidth = categoryWidth / datasetCount;\r
-\r
- if (xScale.ticks.length !== me.chart.data.labels.length) {\r
- var perc = xScale.ticks.length / me.chart.data.labels.length;\r
- fullBarWidth = fullBarWidth * perc;\r
- }\r
-\r
- var barWidth = fullBarWidth * xScale.options.barPercentage;\r
- var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);\r
-\r
- return {\r
- datasetCount: datasetCount,\r
- tickWidth: tickWidth,\r
- categoryWidth: categoryWidth,\r
- categorySpacing: categorySpacing,\r
- fullBarWidth: fullBarWidth,\r
- barWidth: barWidth,\r
- barSpacing: barSpacing\r
- };\r
- },\r
-\r
- calculateBarWidth: function(index) {\r
- var xScale = this.getScaleForId(this.getMeta().xAxisID);\r
- var ruler = this.getRuler(index);\r
- return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;\r
- },\r
-\r
- // Get bar index from the given dataset index accounting for the fact that not all bars are visible\r
- getBarIndex: function(datasetIndex) {\r
- var barIndex = 0;\r
- var meta, j;\r
-\r
- for (j = 0; j < datasetIndex; ++j) {\r
- meta = this.chart.getDatasetMeta(j);\r
- if (meta.bar && this.chart.isDatasetVisible(j)) {\r
- ++barIndex;\r
- }\r
- }\r
-\r
- return barIndex;\r
- },\r
-\r
- calculateBarX: function(index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var barIndex = me.getBarIndex(datasetIndex);\r
-\r
- var ruler = me.getRuler(index);\r
- var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);\r
- leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0;\r
-\r
- if (xScale.options.stacked) {\r
- return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;\r
- }\r
-\r
- return leftTick +\r
- (ruler.barWidth / 2) +\r
- ruler.categorySpacing +\r
- (ruler.barWidth * barIndex) +\r
- (ruler.barSpacing / 2) +\r
- (ruler.barSpacing * barIndex);\r
- },\r
-\r
- calculateBarY: function(index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var value = me.getDataset().data[index];\r
-\r
- if (yScale.options.stacked) {\r
-\r
- var sumPos = 0,\r
- sumNeg = 0;\r
-\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var ds = me.chart.data.datasets[i];\r
- var dsMeta = me.chart.getDatasetMeta(i);\r
- if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) {\r
- if (ds.data[index] < 0) {\r
- sumNeg += ds.data[index] || 0;\r
- } else {\r
- sumPos += ds.data[index] || 0;\r
- }\r
- }\r
- }\r
-\r
- if (value < 0) {\r
- return yScale.getPixelForValue(sumNeg + value);\r
- } else {\r
- return yScale.getPixelForValue(sumPos + value);\r
- }\r
- }\r
-\r
- return yScale.getPixelForValue(value);\r
- },\r
-\r
- draw: function(ease) {\r
- var me = this;\r
- var easingDecimal = ease || 1;\r
- helpers.each(me.getMeta().data, function(rectangle, index) {\r
- var d = me.getDataset().data[index];\r
- if (d !== null && d !== undefined && !isNaN(d)) {\r
- rectangle.transition(easingDecimal).draw();\r
- }\r
- }, me);\r
- },\r
-\r
- setHoverStyle: function(rectangle) {\r
- var dataset = this.chart.data.datasets[rectangle._datasetIndex];\r
- var index = rectangle._index;\r
-\r
- var custom = rectangle.custom || {};\r
- var model = rectangle._model;\r
- model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\r
- },\r
-\r
- removeHoverStyle: function(rectangle) {\r
- var dataset = this.chart.data.datasets[rectangle._datasetIndex];\r
- var index = rectangle._index;\r
- var custom = rectangle.custom || {};\r
- var model = rectangle._model;\r
- var rectangleElementOptions = this.chart.options.elements.rectangle;\r
-\r
- model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);\r
- model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);\r
- model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);\r
- }\r
-\r
- });\r
-\r
-\r
- // including horizontalBar in the bar file, instead of a file of its own\r
- // it extends bar (like pie extends doughnut)\r
- Chart.defaults.horizontalBar = {\r
- hover: {\r
- mode: "label"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "linear",\r
- position: "bottom"\r
- }],\r
- yAxes: [{\r
- position: "left",\r
- type: "category",\r
-\r
- // Specific to Horizontal Bar Controller\r
- categoryPercentage: 0.8,\r
- barPercentage: 0.9,\r
-\r
- // grid line settings\r
- gridLines: {\r
- offsetGridLines: true\r
- }\r
- }]\r
- },\r
- elements: {\r
- rectangle: {\r
- borderSkipped: 'left'\r
- }\r
- },\r
- tooltips: {\r
- callbacks: {\r
- title: function(tooltipItems, data) {\r
- // Pick first xLabel for now\r
- var title = '';\r
-\r
- if (tooltipItems.length > 0) {\r
- if (tooltipItems[0].yLabel) {\r
- title = tooltipItems[0].yLabel;\r
- } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {\r
- title = data.labels[tooltipItems[0].index];\r
- }\r
- }\r
-\r
- return title;\r
- },\r
- label: function(tooltipItem, data) {\r
- var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
- return datasetLabel + ': ' + tooltipItem.xLabel;\r
- }\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.horizontalBar = Chart.controllers.bar.extend({\r
- updateElement: function updateElement(rectangle, index, reset, numBars) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var scaleBase = xScale.getBasePixel();\r
- var custom = rectangle.custom || {};\r
- var dataset = me.getDataset();\r
- var rectangleElementOptions = me.chart.options.elements.rectangle;\r
-\r
- helpers.extend(rectangle, {\r
- // Utility\r
- _xScale: xScale,\r
- _yScale: yScale,\r
- _datasetIndex: me.index,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: reset ? scaleBase : me.calculateBarX(index, me.index),\r
- y: me.calculateBarY(index, me.index),\r
-\r
- // Tooltip\r
- label: me.chart.data.labels[index],\r
- datasetLabel: dataset.label,\r
-\r
- // Appearance\r
- base: reset ? scaleBase : me.calculateBarBase(me.index, index),\r
- height: me.calculateBarHeight(index),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),\r
- borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,\r
- borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)\r
- },\r
-\r
- draw: function () {\r
- var ctx = this._chart.ctx;\r
- var vm = this._view;\r
-\r
- var halfHeight = vm.height / 2,\r
- topY = vm.y - halfHeight,\r
- bottomY = vm.y + halfHeight,\r
- right = vm.base - (vm.base - vm.x),\r
- halfStroke = vm.borderWidth / 2;\r
-\r
- // Canvas doesn't allow us to stroke inside the width so we can\r
- // adjust the sizes to fit if we're setting a stroke on the line\r
- if (vm.borderWidth) {\r
- topY += halfStroke;\r
- bottomY -= halfStroke;\r
- right += halfStroke;\r
- }\r
-\r
- ctx.beginPath();\r
-\r
- ctx.fillStyle = vm.backgroundColor;\r
- ctx.strokeStyle = vm.borderColor;\r
- ctx.lineWidth = vm.borderWidth;\r
-\r
- // Corner points, from bottom-left to bottom-right clockwise\r
- // | 1 2 |\r
- // | 0 3 |\r
- var corners = [\r
- [vm.base, bottomY],\r
- [vm.base, topY],\r
- [right, topY],\r
- [right, bottomY]\r
- ];\r
-\r
- // Find first (starting) corner with fallback to 'bottom'\r
- var borders = ['bottom', 'left', 'top', 'right'];\r
- var startCorner = borders.indexOf(vm.borderSkipped, 0);\r
- if (startCorner === -1)\r
- startCorner = 0;\r
-\r
- function cornerAt(index) {\r
- return corners[(startCorner + index) % 4];\r
- }\r
-\r
- // Draw rectangle from 'startCorner'\r
- ctx.moveTo.apply(ctx, cornerAt(0));\r
- for (var i = 1; i < 4; i++)\r
- ctx.lineTo.apply(ctx, cornerAt(i));\r
-\r
- ctx.fill();\r
- if (vm.borderWidth) {\r
- ctx.stroke();\r
- }\r
- },\r
-\r
- inRange: function (mouseX, mouseY) {\r
- var vm = this._view;\r
- var inRange = false;\r
-\r
- if (vm) {\r
- if (vm.x < vm.base) {\r
- inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base);\r
- } else {\r
- inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x);\r
- }\r
- }\r
-\r
- return inRange;\r
- }\r
- });\r
-\r
- rectangle.pivot();\r
- },\r
-\r
- calculateBarBase: function (datasetIndex, index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var base = 0;\r
-\r
- if (xScale.options.stacked) {\r
-\r
- var value = me.chart.data.datasets[datasetIndex].data[index];\r
-\r
- if (value < 0) {\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var negDS = me.chart.data.datasets[i];\r
- var negDSMeta = me.chart.getDatasetMeta(i);\r
- if (negDSMeta.bar && negDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {\r
- base += negDS.data[index] < 0 ? negDS.data[index] : 0;\r
- }\r
- }\r
- } else {\r
- for (var j = 0; j < datasetIndex; j++) {\r
- var posDS = me.chart.data.datasets[j];\r
- var posDSMeta = me.chart.getDatasetMeta(j);\r
- if (posDSMeta.bar && posDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(j)) {\r
- base += posDS.data[index] > 0 ? posDS.data[index] : 0;\r
- }\r
- }\r
- }\r
-\r
- return xScale.getPixelForValue(base);\r
- }\r
-\r
- return xScale.getBasePixel();\r
- },\r
-\r
- getRuler: function (index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var datasetCount = me.getBarCount();\r
-\r
- var tickHeight;\r
- if (yScale.options.type === 'category') {\r
- tickHeight = yScale.getPixelForTick(index + 1) - yScale.getPixelForTick(index);\r
- } else {\r
- // Average width\r
- tickHeight = yScale.width / yScale.ticks.length;\r
- }\r
- var categoryHeight = tickHeight * yScale.options.categoryPercentage;\r
- var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2;\r
- var fullBarHeight = categoryHeight / datasetCount;\r
-\r
- if (yScale.ticks.length !== me.chart.data.labels.length) {\r
- var perc = yScale.ticks.length / me.chart.data.labels.length;\r
- fullBarHeight = fullBarHeight * perc;\r
- }\r
-\r
- var barHeight = fullBarHeight * yScale.options.barPercentage;\r
- var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage);\r
-\r
- return {\r
- datasetCount: datasetCount,\r
- tickHeight: tickHeight,\r
- categoryHeight: categoryHeight,\r
- categorySpacing: categorySpacing,\r
- fullBarHeight: fullBarHeight,\r
- barHeight: barHeight,\r
- barSpacing: barSpacing,\r
- };\r
- },\r
-\r
- calculateBarHeight: function (index) {\r
- var me = this;\r
- var yScale = me.getScaleForId(me.getMeta().yAxisID);\r
- var ruler = me.getRuler(index);\r
- return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;\r
- },\r
-\r
- calculateBarX: function (index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var value = me.getDataset().data[index];\r
-\r
- if (xScale.options.stacked) {\r
-\r
- var sumPos = 0,\r
- sumNeg = 0;\r
-\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var ds = me.chart.data.datasets[i];\r
- var dsMeta = me.chart.getDatasetMeta(i);\r
- if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {\r
- if (ds.data[index] < 0) {\r
- sumNeg += ds.data[index] || 0;\r
- } else {\r
- sumPos += ds.data[index] || 0;\r
- }\r
- }\r
- }\r
-\r
- if (value < 0) {\r
- return xScale.getPixelForValue(sumNeg + value);\r
- } else {\r
- return xScale.getPixelForValue(sumPos + value);\r
- }\r
- }\r
-\r
- return xScale.getPixelForValue(value);\r
- },\r
-\r
- calculateBarY: function (index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var barIndex = me.getBarIndex(datasetIndex);\r
-\r
- var ruler = me.getRuler(index);\r
- var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);\r
- topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;\r
-\r
- if (yScale.options.stacked) {\r
- return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;\r
- }\r
-\r
- return topTick +\r
- (ruler.barHeight / 2) +\r
- ruler.categorySpacing +\r
- (ruler.barHeight * barIndex) +\r
- (ruler.barSpacing / 2) +\r
- (ruler.barSpacing * barIndex);\r
- }\r
- });\r
-};\r
-
-},{}],16:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.bubble = {\r
- hover: {\r
- mode: "single"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "linear", // bubble should probably use a linear scale by default\r
- position: "bottom",\r
- id: "x-axis-0" // need an ID so datasets can reference the scale\r
- }],\r
- yAxes: [{\r
- type: "linear",\r
- position: "left",\r
- id: "y-axis-0"\r
- }]\r
- },\r
-\r
- tooltips: {\r
- callbacks: {\r
- title: function(tooltipItems, data) {\r
- // Title doesn't make sense for scatter since we format the data as a point\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
- var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\r
- return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')';\r
- }\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.bubble = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Point,\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var points = meta.data;\r
-\r
- // Update Points\r
- helpers.each(points, function(point, index) {\r
- me.updateElement(point, index, reset);\r
- });\r
- },\r
-\r
- updateElement: function(point, index, reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
-\r
- var custom = point.custom || {};\r
- var dataset = me.getDataset();\r
- var data = dataset.data[index];\r
- var pointElementOptions = me.chart.options.elements.point;\r
- var dsIndex = me.index;\r
-\r
- helpers.extend(point, {\r
- // Utility\r
- _xScale: xScale,\r
- _yScale: yScale,\r
- _datasetIndex: dsIndex,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(data, index, dsIndex, me.chart.isCombo),\r
- y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),\r
- // Appearance\r
- radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),\r
-\r
- // Tooltip\r
- hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\r
- }\r
- });\r
-\r
- // Trick to reset the styles of the point\r
- Chart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);\r
-\r
- var model = point._model;\r
- model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));\r
-\r
- point.pivot();\r
- },\r
-\r
- getRadius: function(value) {\r
- return value.r || this.chart.options.elements.point.radius;\r
- },\r
-\r
- setHoverStyle: function(point) {\r
- var me = this;\r
- Chart.DatasetController.prototype.setHoverStyle.call(me, point);\r
-\r
- // Radius\r
- var dataset = me.chart.data.datasets[point._datasetIndex];\r
- var index = point._index;\r
- var custom = point.custom || {};\r
- var model = point._model;\r
- model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);\r
- },\r
-\r
- removeHoverStyle: function(point) {\r
- var me = this;\r
- Chart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);\r
-\r
- var dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];\r
- var custom = point.custom || {};\r
- var model = point._model;\r
-\r
- model.radius = custom.radius ? custom.radius : me.getRadius(dataVal);\r
- }\r
- });\r
-};\r
-
-},{}],17:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- defaults = Chart.defaults;\r
-\r
- defaults.doughnut = {\r
- animation: {\r
- //Boolean - Whether we animate the rotation of the Doughnut\r
- animateRotate: true,\r
- //Boolean - Whether we animate scaling the Doughnut from the centre\r
- animateScale: false\r
- },\r
- aspectRatio: 1,\r
- hover: {\r
- mode: 'single'\r
- },\r
- legendCallback: function(chart) {\r
- var text = [];\r
- text.push('<ul class="' + chart.id + '-legend">');\r
-\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var labels = data.labels;\r
-\r
- if (datasets.length) {\r
- for (var i = 0; i < datasets[0].data.length; ++i) {\r
- text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');\r
- if (labels[i]) {\r
- text.push(labels[i]);\r
- }\r
- text.push('</li>');\r
- }\r
- }\r
-\r
- text.push('</ul>');\r
- return text.join("");\r
- },\r
- legend: {\r
- labels: {\r
- generateLabels: function(chart) {\r
- var data = chart.data;\r
- if (data.labels.length && data.datasets.length) {\r
- return data.labels.map(function(label, i) {\r
- var meta = chart.getDatasetMeta(0);\r
- var ds = data.datasets[0];\r
- var arc = meta.data[i];\r
- var custom = arc.custom || {};\r
- var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
- var arcOpts = chart.options.elements.arc;\r
- var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\r
- var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\r
- var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\r
-\r
- return {\r
- text: label,\r
- fillStyle: fill,\r
- strokeStyle: stroke,\r
- lineWidth: bw,\r
- hidden: isNaN(ds.data[i]) || meta.data[i].hidden,\r
-\r
- // Extra data used for toggling the correct item\r
- index: i\r
- };\r
- });\r
- } else {\r
- return [];\r
- }\r
- }\r
- },\r
-\r
- onClick: function(e, legendItem) {\r
- var index = legendItem.index;\r
- var chart = this.chart;\r
- var i, ilen, meta;\r
-\r
- for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r
- meta = chart.getDatasetMeta(i);\r
- meta.data[index].hidden = !meta.data[index].hidden;\r
- }\r
-\r
- chart.update();\r
- }\r
- },\r
-\r
- //The percentage of the chart that we cut out of the middle.\r
- cutoutPercentage: 50,\r
-\r
- //The rotation of the chart, where the first data arc begins.\r
- rotation: Math.PI * -0.5,\r
-\r
- //The total circumference of the chart.\r
- circumference: Math.PI * 2.0,\r
-\r
- // Need to override these to give a nice default\r
- tooltips: {\r
- callbacks: {\r
- title: function() {\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\r
- }\r
- }\r
- }\r
- };\r
-\r
- defaults.pie = helpers.clone(defaults.doughnut);\r
- helpers.extend(defaults.pie, {\r
- cutoutPercentage: 0\r
- });\r
-\r
-\r
- Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Arc,\r
-\r
- linkScales: helpers.noop,\r
-\r
- // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\r
- getRingIndex: function getRingIndex(datasetIndex) {\r
- var ringIndex = 0;\r
-\r
- for (var j = 0; j < datasetIndex; ++j) {\r
- if (this.chart.isDatasetVisible(j)) {\r
- ++ringIndex;\r
- }\r
- }\r
-\r
- return ringIndex;\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var chart = me.chart,\r
- chartArea = chart.chartArea,\r
- opts = chart.options,\r
- arcOpts = opts.elements.arc,\r
- availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,\r
- availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,\r
- minSize = Math.min(availableWidth, availableHeight),\r
- offset = {\r
- x: 0,\r
- y: 0\r
- },\r
- meta = me.getMeta(),\r
- cutoutPercentage = opts.cutoutPercentage,\r
- circumference = opts.circumference;\r
-\r
- // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc\r
- if (circumference < Math.PI * 2.0) {\r
- var startAngle = opts.rotation % (Math.PI * 2.0);\r
- startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);\r
- var endAngle = startAngle + circumference;\r
- var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};\r
- var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};\r
- var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);\r
- var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);\r
- var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);\r
- var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);\r
- var cutout = cutoutPercentage / 100.0;\r
- var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};\r
- var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};\r
- var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};\r
- minSize = Math.min(availableWidth / size.width, availableHeight / size.height);\r
- offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};\r
- }\r
-\r
- chart.outerRadius = Math.max(minSize / 2, 0);\r
- chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 1, 0);\r
- chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\r
- chart.offsetX = offset.x * chart.outerRadius;\r
- chart.offsetY = offset.y * chart.outerRadius;\r
-\r
- meta.total = me.calculateTotal();\r
-\r
- me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));\r
- me.innerRadius = me.outerRadius - chart.radiusLength;\r
-\r
- helpers.each(meta.data, function(arc, index) {\r
- me.updateElement(arc, index, reset);\r
- });\r
- },\r
-\r
- updateElement: function(arc, index, reset) {\r
- var me = this;\r
- var chart = me.chart,\r
- chartArea = chart.chartArea,\r
- opts = chart.options,\r
- animationOpts = opts.animation,\r
- arcOpts = opts.elements.arc,\r
- centerX = (chartArea.left + chartArea.right) / 2,\r
- centerY = (chartArea.top + chartArea.bottom) / 2,\r
- startAngle = opts.rotation, // non reset case handled later\r
- endAngle = opts.rotation, // non reset case handled later\r
- dataset = me.getDataset(),\r
- circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),\r
- innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,\r
- outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,\r
- custom = arc.custom || {},\r
- valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
-\r
- helpers.extend(arc, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: centerX + chart.offsetX,\r
- y: centerY + chart.offsetY,\r
- startAngle: startAngle,\r
- endAngle: endAngle,\r
- circumference: circumference,\r
- outerRadius: outerRadius,\r
- innerRadius: innerRadius,\r
- label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\r
- }\r
- });\r
-\r
- var model = arc._model;\r
- // Resets the visual styles\r
- this.removeHoverStyle(arc);\r
-\r
- // Set correct angles if not resetting\r
- if (!reset || !animationOpts.animateRotate) {\r
- if (index === 0) {\r
- model.startAngle = opts.rotation;\r
- } else {\r
- model.startAngle = me.getMeta().data[index - 1]._model.endAngle;\r
- }\r
-\r
- model.endAngle = model.startAngle + model.circumference;\r
- }\r
-\r
- arc.pivot();\r
- },\r
-\r
- removeHoverStyle: function(arc) {\r
- Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\r
- },\r
-\r
- calculateTotal: function() {\r
- var dataset = this.getDataset();\r
- var meta = this.getMeta();\r
- var total = 0;\r
- var value;\r
-\r
- helpers.each(meta.data, function(element, index) {\r
- value = dataset.data[index];\r
- if (!isNaN(value) && !element.hidden) {\r
- total += Math.abs(value);\r
- }\r
- });\r
-\r
- return total;\r
- },\r
-\r
- calculateCircumference: function(value) {\r
- var total = this.getMeta().total;\r
- if (total > 0 && !isNaN(value)) {\r
- return (Math.PI * 2.0) * (value / total);\r
- } else {\r
- return 0;\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],18:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.line = {\r
- showLines: true,\r
-\r
- hover: {\r
- mode: "label"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "category",\r
- id: 'x-axis-0'\r
- }],\r
- yAxes: [{\r
- type: "linear",\r
- id: 'y-axis-0'\r
- }]\r
- }\r
- };\r
-\r
- function lineEnabled(dataset, options) {\r
- return helpers.getValueOrDefault(dataset.showLine, options.showLines);\r
- }\r
-\r
- Chart.controllers.line = Chart.DatasetController.extend({\r
-\r
- datasetElementType: Chart.elements.Line,\r
-\r
- dataElementType: Chart.elements.Point,\r
-\r
- addElementAndReset: function(index) {\r
- var me = this;\r
- var options = me.chart.options;\r
- var meta = me.getMeta();\r
-\r
- Chart.DatasetController.prototype.addElementAndReset.call(me, index);\r
-\r
- // Make sure bezier control points are updated\r
- if (lineEnabled(me.getDataset(), options) && meta.dataset._model.tension !== 0) {\r
- me.updateBezierControlPoints();\r
- }\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var line = meta.dataset;\r
- var points = meta.data || [];\r
- var options = me.chart.options;\r
- var lineElementOptions = options.elements.line;\r
- var scale = me.getScaleForId(meta.yAxisID);\r
- var i, ilen, custom;\r
- var dataset = me.getDataset();\r
- var showLine = lineEnabled(dataset, options);\r
-\r
- // Update Line\r
- if (showLine) {\r
- custom = line.custom || {};\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\r
- dataset.lineTension = dataset.tension;\r
- }\r
-\r
- // Utility\r
- line._scale = scale;\r
- line._datasetIndex = me.index;\r
- // Data\r
- line._children = points;\r
- // Model\r
- line._model = {\r
- // Appearance\r
- // The default behavior of lines is to break at null values, according\r
- // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\r
- // This option gives linse the ability to span gaps\r
- spanGaps: dataset.spanGaps ? dataset.spanGaps : false,\r
- tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\r
- borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\r
- borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\r
- borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\r
- borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\r
- borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\r
- fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\r
- // Scale\r
- scaleTop: scale.top,\r
- scaleBottom: scale.bottom,\r
- scaleZero: scale.getBasePixel()\r
- };\r
-\r
- line.pivot();\r
- }\r
-\r
- // Update Points\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- me.updateElement(points[i], i, reset);\r
- }\r
-\r
- if (showLine && line._model.tension !== 0) {\r
- me.updateBezierControlPoints();\r
- }\r
-\r
- // Now pivot the point for animation\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- points[i].pivot();\r
- }\r
- },\r
-\r
- getPointBackgroundColor: function(point, index) {\r
- var backgroundColor = this.chart.options.elements.point.backgroundColor;\r
- var dataset = this.getDataset();\r
- var custom = point.custom || {};\r
-\r
- if (custom.backgroundColor) {\r
- backgroundColor = custom.backgroundColor;\r
- } else if (dataset.pointBackgroundColor) {\r
- backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);\r
- } else if (dataset.backgroundColor) {\r
- backgroundColor = dataset.backgroundColor;\r
- }\r
-\r
- return backgroundColor;\r
- },\r
-\r
- getPointBorderColor: function(point, index) {\r
- var borderColor = this.chart.options.elements.point.borderColor;\r
- var dataset = this.getDataset();\r
- var custom = point.custom || {};\r
-\r
- if (custom.borderColor) {\r
- borderColor = custom.borderColor;\r
- } else if (dataset.pointBorderColor) {\r
- borderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);\r
- } else if (dataset.borderColor) {\r
- borderColor = dataset.borderColor;\r
- }\r
-\r
- return borderColor;\r
- },\r
-\r
- getPointBorderWidth: function(point, index) {\r
- var borderWidth = this.chart.options.elements.point.borderWidth;\r
- var dataset = this.getDataset();\r
- var custom = point.custom || {};\r
-\r
- if (custom.borderWidth) {\r
- borderWidth = custom.borderWidth;\r
- } else if (dataset.pointBorderWidth) {\r
- borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);\r
- } else if (dataset.borderWidth) {\r
- borderWidth = dataset.borderWidth;\r
- }\r
-\r
- return borderWidth;\r
- },\r
-\r
- updateElement: function(point, index, reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var custom = point.custom || {};\r
- var dataset = me.getDataset();\r
- var datasetIndex = me.index;\r
- var value = dataset.data[index];\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var pointOptions = me.chart.options.elements.point;\r
- var x, y;\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\r
- dataset.pointRadius = dataset.radius;\r
- }\r
- if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\r
- dataset.pointHitRadius = dataset.hitRadius;\r
- }\r
-\r
- x = xScale.getPixelForValue(value, index, datasetIndex, me.chart.isCombo);\r
- y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex, me.chart.isCombo);\r
-\r
- // Utility\r
- point._xScale = xScale;\r
- point._yScale = yScale;\r
- point._datasetIndex = datasetIndex;\r
- point._index = index;\r
-\r
- // Desired view properties\r
- point._model = {\r
- x: x,\r
- y: y,\r
- skip: custom.skip || isNaN(x) || isNaN(y),\r
- // Appearance\r
- radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),\r
- pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),\r
- backgroundColor: me.getPointBackgroundColor(point, index),\r
- borderColor: me.getPointBorderColor(point, index),\r
- borderWidth: me.getPointBorderWidth(point, index),\r
- tension: meta.dataset._model ? meta.dataset._model.tension : 0,\r
- // Tooltip\r
- hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)\r
- };\r
- },\r
-\r
- calculatePointY: function(value, index, datasetIndex, isCombo) {\r
- var me = this;\r
- var chart = me.chart;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var sumPos = 0;\r
- var sumNeg = 0;\r
- var i, ds, dsMeta;\r
-\r
- if (yScale.options.stacked) {\r
- for (i = 0; i < datasetIndex; i++) {\r
- ds = chart.data.datasets[i];\r
- dsMeta = chart.getDatasetMeta(i);\r
- if (dsMeta.type === 'line' && chart.isDatasetVisible(i)) {\r
- if (ds.data[index] < 0) {\r
- sumNeg += ds.data[index] || 0;\r
- } else {\r
- sumPos += ds.data[index] || 0;\r
- }\r
- }\r
- }\r
-\r
- if (value < 0) {\r
- return yScale.getPixelForValue(sumNeg + value);\r
- } else {\r
- return yScale.getPixelForValue(sumPos + value);\r
- }\r
- }\r
-\r
- return yScale.getPixelForValue(value);\r
- },\r
-\r
- updateBezierControlPoints: function() {\r
- var meta = this.getMeta();\r
- var area = this.chart.chartArea;\r
- var points = meta.data || [];\r
- var i, ilen, point, model, controlPoints;\r
-\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- point = points[i];\r
- model = point._model;\r
- controlPoints = helpers.splineCurve(\r
- helpers.previousItem(points, i)._model,\r
- model,\r
- helpers.nextItem(points, i)._model,\r
- meta.dataset._model.tension\r
- );\r
-\r
- model.controlPointPreviousX = controlPoints.previous.x;\r
- model.controlPointPreviousY = controlPoints.previous.y;\r
- model.controlPointNextX = controlPoints.next.x;\r
- model.controlPointNextY = controlPoints.next.y;\r
- }\r
- },\r
-\r
- draw: function(ease) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var points = meta.data || [];\r
- var easingDecimal = ease || 1;\r
- var i, ilen;\r
-\r
- // Transition Point Locations\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- points[i].transition(easingDecimal);\r
- }\r
-\r
- // Transition and Draw the line\r
- if (lineEnabled(me.getDataset(), me.chart.options)) {\r
- meta.dataset.transition(easingDecimal).draw();\r
- }\r
-\r
- // Draw the points\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- points[i].draw();\r
- }\r
- },\r
-\r
- setHoverStyle: function(point) {\r
- // Point\r
- var dataset = this.chart.data.datasets[point._datasetIndex];\r
- var index = point._index;\r
- var custom = point.custom || {};\r
- var model = point._model;\r
-\r
- model.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\r
- model.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\r
- },\r
-\r
- removeHoverStyle: function(point) {\r
- var me = this;\r
- var dataset = me.chart.data.datasets[point._datasetIndex];\r
- var index = point._index;\r
- var custom = point.custom || {};\r
- var model = point._model;\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\r
- dataset.pointRadius = dataset.radius;\r
- }\r
-\r
- model.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);\r
- model.backgroundColor = me.getPointBackgroundColor(point, index);\r
- model.borderColor = me.getPointBorderColor(point, index);\r
- model.borderWidth = me.getPointBorderWidth(point, index);\r
- }\r
- });\r
-};\r
-
-},{}],19:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.polarArea = {\r
-\r
- scale: {\r
- type: "radialLinear",\r
- lineArc: true // so that lines are circular\r
- },\r
-\r
- //Boolean - Whether to animate the rotation of the chart\r
- animation: {\r
- animateRotate: true,\r
- animateScale: true\r
- },\r
-\r
- aspectRatio: 1,\r
- legendCallback: function(chart) {\r
- var text = [];\r
- text.push('<ul class="' + chart.id + '-legend">');\r
-\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var labels = data.labels;\r
-\r
- if (datasets.length) {\r
- for (var i = 0; i < datasets[0].data.length; ++i) {\r
- text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '">');\r
- if (labels[i]) {\r
- text.push(labels[i]);\r
- }\r
- text.push('</span></li>');\r
- }\r
- }\r
-\r
- text.push('</ul>');\r
- return text.join("");\r
- },\r
- legend: {\r
- labels: {\r
- generateLabels: function(chart) {\r
- var data = chart.data;\r
- if (data.labels.length && data.datasets.length) {\r
- return data.labels.map(function(label, i) {\r
- var meta = chart.getDatasetMeta(0);\r
- var ds = data.datasets[0];\r
- var arc = meta.data[i];\r
- var custom = arc.custom || {};\r
- var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
- var arcOpts = chart.options.elements.arc;\r
- var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\r
- var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\r
- var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\r
-\r
- return {\r
- text: label,\r
- fillStyle: fill,\r
- strokeStyle: stroke,\r
- lineWidth: bw,\r
- hidden: isNaN(ds.data[i]) || meta.data[i].hidden,\r
-\r
- // Extra data used for toggling the correct item\r
- index: i\r
- };\r
- });\r
- } else {\r
- return [];\r
- }\r
- }\r
- },\r
-\r
- onClick: function(e, legendItem) {\r
- var index = legendItem.index;\r
- var chart = this.chart;\r
- var i, ilen, meta;\r
-\r
- for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r
- meta = chart.getDatasetMeta(i);\r
- meta.data[index].hidden = !meta.data[index].hidden;\r
- }\r
-\r
- chart.update();\r
- }\r
- },\r
-\r
- // Need to override these to give a nice default\r
- tooltips: {\r
- callbacks: {\r
- title: function() {\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;\r
- }\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.polarArea = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Arc,\r
-\r
- linkScales: helpers.noop,\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var chart = me.chart;\r
- var chartArea = chart.chartArea;\r
- var meta = me.getMeta();\r
- var opts = chart.options;\r
- var arcOpts = opts.elements.arc;\r
- var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\r
- chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);\r
- chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\r
- chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\r
-\r
- me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\r
- me.innerRadius = me.outerRadius - chart.radiusLength;\r
-\r
- meta.count = me.countVisibleElements();\r
-\r
- helpers.each(meta.data, function(arc, index) {\r
- me.updateElement(arc, index, reset);\r
- });\r
- },\r
-\r
- updateElement: function(arc, index, reset) {\r
- var me = this;\r
- var chart = me.chart;\r
- var chartArea = chart.chartArea;\r
- var dataset = me.getDataset();\r
- var opts = chart.options;\r
- var animationOpts = opts.animation;\r
- var arcOpts = opts.elements.arc;\r
- var custom = arc.custom || {};\r
- var scale = chart.scale;\r
- var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
- var labels = chart.data.labels;\r
-\r
- var circumference = me.calculateCircumference(dataset.data[index]);\r
- var centerX = (chartArea.left + chartArea.right) / 2;\r
- var centerY = (chartArea.top + chartArea.bottom) / 2;\r
-\r
- // If there is NaN data before us, we need to calculate the starting angle correctly.\r
- // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data\r
- var visibleCount = 0;\r
- var meta = me.getMeta();\r
- for (var i = 0; i < index; ++i) {\r
- if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {\r
- ++visibleCount;\r
- }\r
- }\r
-\r
- var negHalfPI = -0.5 * Math.PI;\r
- var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r
- var startAngle = (negHalfPI) + (circumference * visibleCount);\r
- var endAngle = startAngle + (arc.hidden ? 0 : circumference);\r
-\r
- var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r
-\r
- helpers.extend(arc, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- _index: index,\r
- _scale: scale,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: centerX,\r
- y: centerY,\r
- innerRadius: 0,\r
- outerRadius: reset ? resetRadius : distance,\r
- startAngle: reset && animationOpts.animateRotate ? negHalfPI : startAngle,\r
- endAngle: reset && animationOpts.animateRotate ? negHalfPI : endAngle,\r
- label: getValueAtIndexOrDefault(labels, index, labels[index])\r
- }\r
- });\r
-\r
- // Apply border and fill style\r
- me.removeHoverStyle(arc);\r
-\r
- arc.pivot();\r
- },\r
-\r
- removeHoverStyle: function(arc) {\r
- Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\r
- },\r
-\r
- countVisibleElements: function() {\r
- var dataset = this.getDataset();\r
- var meta = this.getMeta();\r
- var count = 0;\r
-\r
- helpers.each(meta.data, function(element, index) {\r
- if (!isNaN(dataset.data[index]) && !element.hidden) {\r
- count++;\r
- }\r
- });\r
-\r
- return count;\r
- },\r
-\r
- calculateCircumference: function(value) {\r
- var count = this.getMeta().count;\r
- if (count > 0 && !isNaN(value)) {\r
- return (2 * Math.PI) / count;\r
- } else {\r
- return 0;\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],20:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.radar = {\r
- scale: {\r
- type: "radialLinear"\r
- },\r
- elements: {\r
- line: {\r
- tension: 0 // no bezier in radar\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.radar = Chart.DatasetController.extend({\r
-\r
- datasetElementType: Chart.elements.Line,\r
-\r
- dataElementType: Chart.elements.Point,\r
-\r
- linkScales: helpers.noop,\r
-\r
- addElementAndReset: function(index) {\r
- Chart.DatasetController.prototype.addElementAndReset.call(this, index);\r
-\r
- // Make sure bezier control points are updated\r
- this.updateBezierControlPoints();\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var line = meta.dataset;\r
- var points = meta.data;\r
- var custom = line.custom || {};\r
- var dataset = me.getDataset();\r
- var lineElementOptions = me.chart.options.elements.line;\r
- var scale = me.chart.scale;\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\r
- dataset.lineTension = dataset.tension;\r
- }\r
-\r
- helpers.extend(meta.dataset, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- // Data\r
- _children: points,\r
- _loop: true,\r
- // Model\r
- _model: {\r
- // Appearance\r
- tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\r
- borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\r
- fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\r
- borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\r
- borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\r
- borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\r
- borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\r
-\r
- // Scale\r
- scaleTop: scale.top,\r
- scaleBottom: scale.bottom,\r
- scaleZero: scale.getBasePosition()\r
- }\r
- });\r
-\r
- meta.dataset.pivot();\r
-\r
- // Update Points\r
- helpers.each(points, function(point, index) {\r
- me.updateElement(point, index, reset);\r
- }, me);\r
-\r
-\r
- // Update bezier control points\r
- me.updateBezierControlPoints();\r
- },\r
- updateElement: function(point, index, reset) {\r
- var me = this;\r
- var custom = point.custom || {};\r
- var dataset = me.getDataset();\r
- var scale = me.chart.scale;\r
- var pointElementOptions = me.chart.options.elements.point;\r
- var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\r
-\r
- helpers.extend(point, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- _index: index,\r
- _scale: scale,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales\r
- y: reset ? scale.yCenter : pointPosition.y,\r
-\r
- // Appearance\r
- tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, me.chart.options.elements.line.tension),\r
- radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),\r
- borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),\r
- pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),\r
-\r
- // Tooltip\r
- hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\r
- }\r
- });\r
-\r
- point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));\r
- },\r
- updateBezierControlPoints: function() {\r
- var chartArea = this.chart.chartArea;\r
- var meta = this.getMeta();\r
-\r
- helpers.each(meta.data, function(point, index) {\r
- var model = point._model;\r
- var controlPoints = helpers.splineCurve(\r
- helpers.previousItem(meta.data, index, true)._model,\r
- model,\r
- helpers.nextItem(meta.data, index, true)._model,\r
- model.tension\r
- );\r
-\r
- // Prevent the bezier going outside of the bounds of the graph\r
- model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);\r
- model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);\r
-\r
- model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);\r
- model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);\r
-\r
- // Now pivot the point for animation\r
- point.pivot();\r
- });\r
- },\r
-\r
- draw: function(ease) {\r
- var meta = this.getMeta();\r
- var easingDecimal = ease || 1;\r
-\r
- // Transition Point Locations\r
- helpers.each(meta.data, function(point, index) {\r
- point.transition(easingDecimal);\r
- });\r
-\r
- // Transition and Draw the line\r
- meta.dataset.transition(easingDecimal).draw();\r
-\r
- // Draw the points\r
- helpers.each(meta.data, function(point) {\r
- point.draw();\r
- });\r
- },\r
-\r
- setHoverStyle: function(point) {\r
- // Point\r
- var dataset = this.chart.data.datasets[point._datasetIndex];\r
- var custom = point.custom || {};\r
- var index = point._index;\r
- var model = point._model;\r
-\r
- model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\r
- model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\r
- },\r
-\r
- removeHoverStyle: function(point) {\r
- var dataset = this.chart.data.datasets[point._datasetIndex];\r
- var custom = point.custom || {};\r
- var index = point._index;\r
- var model = point._model;\r
- var pointElementOptions = this.chart.options.elements.point;\r
-\r
- model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius);\r
- model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);\r
- model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);\r
- model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);\r
- }\r
- });\r
-};\r
-
-},{}],21:[function(require,module,exports){
-/*global window: false */\r
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.global.animation = {\r
- duration: 1000,\r
- easing: "easeOutQuart",\r
- onProgress: helpers.noop,\r
- onComplete: helpers.noop\r
- };\r
-\r
- Chart.Animation = Chart.Element.extend({\r
- currentStep: null, // the current animation step\r
- numSteps: 60, // default number of steps\r
- easing: "", // the easing to use for this animation\r
- render: null, // render function used by the animation service\r
-\r
- onAnimationProgress: null, // user specified callback to fire on each step of the animation\r
- onAnimationComplete: null // user specified callback to fire when the animation finishes\r
- });\r
-\r
- Chart.animationService = {\r
- frameDuration: 17,\r
- animations: [],\r
- dropFrames: 0,\r
- request: null,\r
- addAnimation: function(chartInstance, animationObject, duration, lazy) {\r
- var me = this;\r
-\r
- if (!lazy) {\r
- chartInstance.animating = true;\r
- }\r
-\r
- for (var index = 0; index < me.animations.length; ++index) {\r
- if (me.animations[index].chartInstance === chartInstance) {\r
- // replacing an in progress animation\r
- me.animations[index].animationObject = animationObject;\r
- return;\r
- }\r
- }\r
-\r
- me.animations.push({\r
- chartInstance: chartInstance,\r
- animationObject: animationObject\r
- });\r
-\r
- // If there are no animations queued, manually kickstart a digest, for lack of a better word\r
- if (me.animations.length === 1) {\r
- me.requestAnimationFrame();\r
- }\r
- },\r
- // Cancel the animation for a given chart instance\r
- cancelAnimation: function(chartInstance) {\r
- var index = helpers.findIndex(this.animations, function(animationWrapper) {\r
- return animationWrapper.chartInstance === chartInstance;\r
- });\r
-\r
- if (index !== -1) {\r
- this.animations.splice(index, 1);\r
- chartInstance.animating = false;\r
- }\r
- },\r
- requestAnimationFrame: function() {\r
- var me = this;\r
- if (me.request === null) {\r
- // Skip animation frame requests until the active one is executed.\r
- // This can happen when processing mouse events, e.g. 'mousemove'\r
- // and 'mouseout' events will trigger multiple renders.\r
- me.request = helpers.requestAnimFrame.call(window, function() {\r
- me.request = null;\r
- me.startDigest();\r
- });\r
- }\r
- },\r
- startDigest: function() {\r
- var me = this;\r
-\r
- var startTime = Date.now();\r
- var framesToDrop = 0;\r
-\r
- if (me.dropFrames > 1) {\r
- framesToDrop = Math.floor(me.dropFrames);\r
- me.dropFrames = me.dropFrames % 1;\r
- }\r
-\r
- var i = 0;\r
- while (i < me.animations.length) {\r
- if (me.animations[i].animationObject.currentStep === null) {\r
- me.animations[i].animationObject.currentStep = 0;\r
- }\r
-\r
- me.animations[i].animationObject.currentStep += 1 + framesToDrop;\r
-\r
- if (me.animations[i].animationObject.currentStep > me.animations[i].animationObject.numSteps) {\r
- me.animations[i].animationObject.currentStep = me.animations[i].animationObject.numSteps;\r
- }\r
-\r
- me.animations[i].animationObject.render(me.animations[i].chartInstance, me.animations[i].animationObject);\r
- if (me.animations[i].animationObject.onAnimationProgress && me.animations[i].animationObject.onAnimationProgress.call) {\r
- me.animations[i].animationObject.onAnimationProgress.call(me.animations[i].chartInstance, me.animations[i]);\r
- }\r
-\r
- if (me.animations[i].animationObject.currentStep === me.animations[i].animationObject.numSteps) {\r
- if (me.animations[i].animationObject.onAnimationComplete && me.animations[i].animationObject.onAnimationComplete.call) {\r
- me.animations[i].animationObject.onAnimationComplete.call(me.animations[i].chartInstance, me.animations[i]);\r
- }\r
-\r
- // executed the last frame. Remove the animation.\r
- me.animations[i].chartInstance.animating = false;\r
-\r
- me.animations.splice(i, 1);\r
- } else {\r
- ++i;\r
- }\r
- }\r
-\r
- var endTime = Date.now();\r
- var dropFrames = (endTime - startTime) / me.frameDuration;\r
-\r
- me.dropFrames += dropFrames;\r
-\r
- // Do we have more stuff to animate?\r
- if (me.animations.length > 0) {\r
- me.requestAnimationFrame();\r
- }\r
- }\r
- };\r
-};
-},{}],22:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- //Create a dictionary of chart types, to allow for extension of existing types\r
- Chart.types = {};\r
-\r
- //Store a reference to each instance - allowing us to globally resize chart instances on window resize.\r
- //Destroy method on the chart will remove the instance of the chart from this reference.\r
- Chart.instances = {};\r
-\r
- // Controllers available for dataset visualization eg. bar, line, slice, etc.\r
- Chart.controllers = {};\r
-\r
- /**\r
- * @class Chart.Controller\r
- * The main controller of a chart.\r
- */\r
- Chart.Controller = function(instance) {\r
-\r
- this.chart = instance;\r
- this.config = instance.config;\r
- this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});\r
- this.id = helpers.uid();\r
-\r
- Object.defineProperty(this, 'data', {\r
- get: function() {\r
- return this.config.data;\r
- }\r
- });\r
-\r
- //Add the chart instance to the global namespace\r
- Chart.instances[this.id] = this;\r
-\r
- if (this.options.responsive) {\r
- // Silent resize before chart draws\r
- this.resize(true);\r
- }\r
-\r
- this.initialize();\r
-\r
- return this;\r
- };\r
-\r
- helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ {\r
-\r
- initialize: function initialize() {\r
- var me = this;\r
- // Before init plugin notification\r
- Chart.plugins.notify('beforeInit', [me]);\r
-\r
- me.bindEvents();\r
-\r
- // Make sure controllers are built first so that each dataset is bound to an axis before the scales\r
- // are built\r
- me.ensureScalesHaveIDs();\r
- me.buildOrUpdateControllers();\r
- me.buildScales();\r
- me.updateLayout();\r
- me.resetElements();\r
- me.initToolTip();\r
- me.update();\r
-\r
- // After init plugin notification\r
- Chart.plugins.notify('afterInit', [me]);\r
-\r
- return me;\r
- },\r
-\r
- clear: function clear() {\r
- helpers.clear(this.chart);\r
- return this;\r
- },\r
-\r
- stop: function stop() {\r
- // Stops any current animation loop occuring\r
- Chart.animationService.cancelAnimation(this);\r
- return this;\r
- },\r
-\r
- resize: function resize(silent) {\r
- var me = this;\r
- var chart = me.chart;\r
- var canvas = chart.canvas;\r
- var newWidth = helpers.getMaximumWidth(canvas);\r
- var aspectRatio = chart.aspectRatio;\r
- var newHeight = (me.options.maintainAspectRatio && isNaN(aspectRatio) === false && isFinite(aspectRatio) && aspectRatio !== 0) ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas);\r
-\r
- var sizeChanged = chart.width !== newWidth || chart.height !== newHeight;\r
-\r
- if (!sizeChanged) {\r
- return me;\r
- }\r
-\r
- canvas.width = chart.width = newWidth;\r
- canvas.height = chart.height = newHeight;\r
-\r
- helpers.retinaScale(chart);\r
-\r
- // Notify any plugins about the resize\r
- var newSize = { width: newWidth, height: newHeight };\r
- Chart.plugins.notify('resize', [me, newSize]);\r
-\r
- // Notify of resize\r
- if (me.options.onResize) {\r
- me.options.onResize(me, newSize);\r
- }\r
-\r
- if (!silent) {\r
- me.stop();\r
- me.update(me.options.responsiveAnimationDuration);\r
- }\r
-\r
- return me;\r
- },\r
-\r
- ensureScalesHaveIDs: function ensureScalesHaveIDs() {\r
- var options = this.options;\r
- var scalesOptions = options.scales || {};\r
- var scaleOptions = options.scale;\r
-\r
- helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {\r
- xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);\r
- });\r
-\r
- helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {\r
- yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);\r
- });\r
-\r
- if (scaleOptions) {\r
- scaleOptions.id = scaleOptions.id || 'scale';\r
- }\r
- },\r
-\r
- /**\r
- * Builds a map of scale ID to scale object for future lookup.\r
- */\r
- buildScales: function buildScales() {\r
- var me = this;\r
- var options = me.options;\r
- var scales = me.scales = {};\r
- var items = [];\r
-\r
- if (options.scales) {\r
- items = items.concat(\r
- (options.scales.xAxes || []).map(function(xAxisOptions) {\r
- return { options: xAxisOptions, dtype: 'category' }; }),\r
- (options.scales.yAxes || []).map(function(yAxisOptions) {\r
- return { options: yAxisOptions, dtype: 'linear' }; }));\r
- }\r
-\r
- if (options.scale) {\r
- items.push({ options: options.scale, dtype: 'radialLinear', isDefault: true });\r
- }\r
-\r
- helpers.each(items, function(item, index) {\r
- var scaleOptions = item.options;\r
- var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);\r
- var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);\r
- if (!scaleClass) {\r
- return;\r
- }\r
-\r
- var scale = new scaleClass({\r
- id: scaleOptions.id,\r
- options: scaleOptions,\r
- ctx: me.chart.ctx,\r
- chart: me\r
- });\r
-\r
- scales[scale.id] = scale;\r
-\r
- // TODO(SB): I think we should be able to remove this custom case (options.scale)\r
- // and consider it as a regular scale part of the "scales"" map only! This would\r
- // make the logic easier and remove some useless? custom code.\r
- if (item.isDefault) {\r
- me.scale = scale;\r
- }\r
- });\r
-\r
- Chart.scaleService.addScalesToLayout(this);\r
- },\r
-\r
- updateLayout: function() {\r
- Chart.layoutService.update(this, this.chart.width, this.chart.height);\r
- },\r
-\r
- buildOrUpdateControllers: function buildOrUpdateControllers() {\r
- var me = this;\r
- var types = [];\r
- var newControllers = [];\r
-\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- var meta = me.getDatasetMeta(datasetIndex);\r
- if (!meta.type) {\r
- meta.type = dataset.type || me.config.type;\r
- }\r
-\r
- types.push(meta.type);\r
-\r
- if (meta.controller) {\r
- meta.controller.updateIndex(datasetIndex);\r
- } else {\r
- meta.controller = new Chart.controllers[meta.type](me, datasetIndex);\r
- newControllers.push(meta.controller);\r
- }\r
- }, me);\r
-\r
- if (types.length > 1) {\r
- for (var i = 1; i < types.length; i++) {\r
- if (types[i] !== types[i - 1]) {\r
- me.isCombo = true;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return newControllers;\r
- },\r
-\r
- resetElements: function resetElements() {\r
- var me = this;\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- me.getDatasetMeta(datasetIndex).controller.reset();\r
- }, me);\r
- },\r
-\r
- update: function update(animationDuration, lazy) {\r
- var me = this;\r
- Chart.plugins.notify('beforeUpdate', [me]);\r
-\r
- // In case the entire data object changed\r
- me.tooltip._data = me.data;\r
-\r
- // Make sure dataset controllers are updated and new controllers are reset\r
- var newControllers = me.buildOrUpdateControllers();\r
-\r
- // Make sure all dataset controllers have correct meta data counts\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();\r
- }, me);\r
-\r
- Chart.layoutService.update(me, me.chart.width, me.chart.height);\r
-\r
- // Apply changes to the dataets that require the scales to have been calculated i.e BorderColor chages\r
- Chart.plugins.notify('afterScaleUpdate', [me]);\r
-\r
- // Can only reset the new controllers after the scales have been updated\r
- helpers.each(newControllers, function(controller) {\r
- controller.reset();\r
- });\r
-\r
- me.updateDatasets();\r
-\r
- // Do this before render so that any plugins that need final scale updates can use it\r
- Chart.plugins.notify('afterUpdate', [me]);\r
-\r
- me.render(animationDuration, lazy);\r
- },\r
-\r
- /**\r
- * @method beforeDatasetsUpdate\r
- * @description Called before all datasets are updated. If a plugin returns false,\r
- * the datasets update will be cancelled until another chart update is triggered.\r
- * @param {Object} instance the chart instance being updated.\r
- * @returns {Boolean} false to cancel the datasets update.\r
- * @memberof Chart.PluginBase\r
- * @since version 2.1.5\r
- * @instance\r
- */\r
-\r
- /**\r
- * @method afterDatasetsUpdate\r
- * @description Called after all datasets have been updated. Note that this\r
- * extension will not be called if the datasets update has been cancelled.\r
- * @param {Object} instance the chart instance being updated.\r
- * @memberof Chart.PluginBase\r
- * @since version 2.1.5\r
- * @instance\r
- */\r
-\r
- /**\r
- * Updates all datasets unless a plugin returns false to the beforeDatasetsUpdate\r
- * extension, in which case no datasets will be updated and the afterDatasetsUpdate\r
- * notification will be skipped.\r
- * @protected\r
- * @instance\r
- */\r
- updateDatasets: function() {\r
- var me = this;\r
- var i, ilen;\r
-\r
- if (Chart.plugins.notify('beforeDatasetsUpdate', [ me ])) {\r
- for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\r
- me.getDatasetMeta(i).controller.update();\r
- }\r
-\r
- Chart.plugins.notify('afterDatasetsUpdate', [ me ]);\r
- }\r
- },\r
-\r
- render: function render(duration, lazy) {\r
- var me = this;\r
- Chart.plugins.notify('beforeRender', [me]);\r
-\r
- var animationOptions = me.options.animation;\r
- if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {\r
- var animation = new Chart.Animation();\r
- animation.numSteps = (duration || animationOptions.duration) / 16.66; //60 fps\r
- animation.easing = animationOptions.easing;\r
-\r
- // render function\r
- animation.render = function(chartInstance, animationObject) {\r
- var easingFunction = helpers.easingEffects[animationObject.easing];\r
- var stepDecimal = animationObject.currentStep / animationObject.numSteps;\r
- var easeDecimal = easingFunction(stepDecimal);\r
-\r
- chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);\r
- };\r
-\r
- // user events\r
- animation.onAnimationProgress = animationOptions.onProgress;\r
- animation.onAnimationComplete = animationOptions.onComplete;\r
-\r
- Chart.animationService.addAnimation(me, animation, duration, lazy);\r
- } else {\r
- me.draw();\r
- if (animationOptions && animationOptions.onComplete && animationOptions.onComplete.call) {\r
- animationOptions.onComplete.call(me);\r
- }\r
- }\r
- return me;\r
- },\r
-\r
- draw: function(ease) {\r
- var me = this;\r
- var easingDecimal = ease || 1;\r
- me.clear();\r
-\r
- Chart.plugins.notify('beforeDraw', [me, easingDecimal]);\r
-\r
- // Draw all the scales\r
- helpers.each(me.boxes, function(box) {\r
- box.draw(me.chartArea);\r
- }, me);\r
- if (me.scale) {\r
- me.scale.draw();\r
- }\r
-\r
- Chart.plugins.notify('beforeDatasetsDraw', [me, easingDecimal]);\r
-\r
- // Draw each dataset via its respective controller (reversed to support proper line stacking)\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- if (me.isDatasetVisible(datasetIndex)) {\r
- me.getDatasetMeta(datasetIndex).controller.draw(ease);\r
- }\r
- }, me, true);\r
-\r
- Chart.plugins.notify('afterDatasetsDraw', [me, easingDecimal]);\r
-\r
- // Finally draw the tooltip\r
- me.tooltip.transition(easingDecimal).draw();\r
-\r
- Chart.plugins.notify('afterDraw', [me, easingDecimal]);\r
- },\r
-\r
- // Get the single element that was clicked on\r
- // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw\r
- getElementAtEvent: function(e) {\r
- var me = this;\r
- var eventPosition = helpers.getRelativePosition(e, me.chart);\r
- var elementsArray = [];\r
-\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- if (me.isDatasetVisible(datasetIndex)) {\r
- var meta = me.getDatasetMeta(datasetIndex);\r
- helpers.each(meta.data, function(element, index) {\r
- if (element.inRange(eventPosition.x, eventPosition.y)) {\r
- elementsArray.push(element);\r
- return elementsArray;\r
- }\r
- });\r
- }\r
- });\r
-\r
- return elementsArray;\r
- },\r
-\r
- getElementsAtEvent: function(e) {\r
- var me = this;\r
- var eventPosition = helpers.getRelativePosition(e, me.chart);\r
- var elementsArray = [];\r
-\r
- var found = (function() {\r
- if (me.data.datasets) {\r
- for (var i = 0; i < me.data.datasets.length; i++) {\r
- var meta = me.getDatasetMeta(i);\r
- if (me.isDatasetVisible(i)) {\r
- for (var j = 0; j < meta.data.length; j++) {\r
- if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) {\r
- return meta.data[j];\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }).call(me);\r
-\r
- if (!found) {\r
- return elementsArray;\r
- }\r
-\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- if (me.isDatasetVisible(datasetIndex)) {\r
- var meta = me.getDatasetMeta(datasetIndex);\r
- elementsArray.push(meta.data[found._index]);\r
- }\r
- }, me);\r
-\r
- return elementsArray;\r
- },\r
-\r
- getElementsAtEventForMode: function(e, mode) {\r
- var me = this;\r
- switch (mode) {\r
- case 'single':\r
- return me.getElementAtEvent(e);\r
- case 'label':\r
- return me.getElementsAtEvent(e);\r
- case 'dataset':\r
- return me.getDatasetAtEvent(e);\r
- default:\r
- return e;\r
- }\r
- },\r
-\r
- getDatasetAtEvent: function(e) {\r
- var elementsArray = this.getElementAtEvent(e);\r
-\r
- if (elementsArray.length > 0) {\r
- elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data;\r
- }\r
-\r
- return elementsArray;\r
- },\r
-\r
- getDatasetMeta: function(datasetIndex) {\r
- var me = this;\r
- var dataset = me.data.datasets[datasetIndex];\r
- if (!dataset._meta) {\r
- dataset._meta = {};\r
- }\r
-\r
- var meta = dataset._meta[me.id];\r
- if (!meta) {\r
- meta = dataset._meta[me.id] = {\r
- type: null,\r
- data: [],\r
- dataset: null,\r
- controller: null,\r
- hidden: null, // See isDatasetVisible() comment\r
- xAxisID: null,\r
- yAxisID: null\r
- };\r
- }\r
-\r
- return meta;\r
- },\r
-\r
- getVisibleDatasetCount: function() {\r
- var count = 0;\r
- for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {\r
- if (this.isDatasetVisible(i)) {\r
- count++;\r
- }\r
- }\r
- return count;\r
- },\r
-\r
- isDatasetVisible: function(datasetIndex) {\r
- var meta = this.getDatasetMeta(datasetIndex);\r
-\r
- // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,\r
- // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.\r
- return typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;\r
- },\r
-\r
- generateLegend: function generateLegend() {\r
- return this.options.legendCallback(this);\r
- },\r
-\r
- destroy: function destroy() {\r
- var me = this;\r
- me.stop();\r
- me.clear();\r
- helpers.unbindEvents(me, me.events);\r
- helpers.removeResizeListener(me.chart.canvas.parentNode);\r
-\r
- // Reset canvas height/width attributes\r
- var canvas = me.chart.canvas;\r
- canvas.width = me.chart.width;\r
- canvas.height = me.chart.height;\r
-\r
- // if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here\r
- if (me.chart.originalDevicePixelRatio !== undefined) {\r
- me.chart.ctx.scale(1 / me.chart.originalDevicePixelRatio, 1 / me.chart.originalDevicePixelRatio);\r
- }\r
-\r
- // Reset to the old style since it may have been changed by the device pixel ratio changes\r
- canvas.style.width = me.chart.originalCanvasStyleWidth;\r
- canvas.style.height = me.chart.originalCanvasStyleHeight;\r
-\r
- Chart.plugins.notify('destroy', [me]);\r
-\r
- delete Chart.instances[me.id];\r
- },\r
-\r
- toBase64Image: function toBase64Image() {\r
- return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);\r
- },\r
-\r
- initToolTip: function initToolTip() {\r
- var me = this;\r
- me.tooltip = new Chart.Tooltip({\r
- _chart: me.chart,\r
- _chartInstance: me,\r
- _data: me.data,\r
- _options: me.options.tooltips\r
- }, me);\r
- },\r
-\r
- bindEvents: function bindEvents() {\r
- var me = this;\r
- helpers.bindEvents(me, me.options.events, function(evt) {\r
- me.eventHandler(evt);\r
- });\r
- },\r
-\r
- updateHoverStyle: function(elements, mode, enabled) {\r
- var method = enabled? 'setHoverStyle' : 'removeHoverStyle';\r
- var element, i, ilen;\r
-\r
- switch (mode) {\r
- case 'single':\r
- elements = [ elements[0] ];\r
- break;\r
- case 'label':\r
- case 'dataset':\r
- // elements = elements;\r
- break;\r
- default:\r
- // unsupported mode\r
- return;\r
- }\r
-\r
- for (i=0, ilen=elements.length; i<ilen; ++i) {\r
- element = elements[i];\r
- if (element) {\r
- this.getDatasetMeta(element._datasetIndex).controller[method](element);\r
- }\r
- }\r
- },\r
-\r
- eventHandler: function eventHandler(e) {\r
- var me = this;\r
- var tooltip = me.tooltip;\r
- var options = me.options || {};\r
- var hoverOptions = options.hover;\r
- var tooltipsOptions = options.tooltips;\r
-\r
- me.lastActive = me.lastActive || [];\r
- me.lastTooltipActive = me.lastTooltipActive || [];\r
-\r
- // Find Active Elements for hover and tooltips\r
- if (e.type === 'mouseout') {\r
- me.active = [];\r
- me.tooltipActive = [];\r
- } else {\r
- me.active = me.getElementsAtEventForMode(e, hoverOptions.mode);\r
- me.tooltipActive = me.getElementsAtEventForMode(e, tooltipsOptions.mode);\r
- }\r
-\r
- // On Hover hook\r
- if (hoverOptions.onHover) {\r
- hoverOptions.onHover.call(me, me.active);\r
- }\r
-\r
- if (e.type === 'mouseup' || e.type === 'click') {\r
- if (options.onClick) {\r
- options.onClick.call(me, e, me.active);\r
- }\r
- if (me.legend && me.legend.handleEvent) {\r
- me.legend.handleEvent(e);\r
- }\r
- }\r
-\r
- // Remove styling for last active (even if it may still be active)\r
- if (me.lastActive.length) {\r
- me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);\r
- }\r
-\r
- // Built in hover styling\r
- if (me.active.length && hoverOptions.mode) {\r
- me.updateHoverStyle(me.active, hoverOptions.mode, true);\r
- }\r
-\r
- // Built in Tooltips\r
- if (tooltipsOptions.enabled || tooltipsOptions.custom) {\r
- tooltip.initialize();\r
- tooltip._active = me.tooltipActive;\r
- tooltip.update(true);\r
- }\r
-\r
- // Hover animations\r
- tooltip.pivot();\r
-\r
- if (!me.animating) {\r
- // If entering, leaving, or changing elements, animate the change via pivot\r
- if (!helpers.arrayEquals(me.active, me.lastActive) ||\r
- !helpers.arrayEquals(me.tooltipActive, me.lastTooltipActive)) {\r
-\r
- me.stop();\r
-\r
- if (tooltipsOptions.enabled || tooltipsOptions.custom) {\r
- tooltip.update(true);\r
- }\r
-\r
- // We only need to render at this point. Updating will cause scales to be\r
- // recomputed generating flicker & using more memory than necessary.\r
- me.render(hoverOptions.animationDuration, true);\r
- }\r
- }\r
-\r
- // Remember Last Actives\r
- me.lastActive = me.active;\r
- me.lastTooltipActive = me.tooltipActive;\r
- return me;\r
- }\r
- });\r
-};\r
-
-},{}],23:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var noop = helpers.noop;\r
-\r
- // Base class for all dataset controllers (line, bar, etc)\r
- Chart.DatasetController = function(chart, datasetIndex) {\r
- this.initialize.call(this, chart, datasetIndex);\r
- };\r
-\r
- helpers.extend(Chart.DatasetController.prototype, {\r
-\r
- /**\r
- * Element type used to generate a meta dataset (e.g. Chart.element.Line).\r
- * @type {Chart.core.element}\r
- */\r
- datasetElementType: null,\r
-\r
- /**\r
- * Element type used to generate a meta data (e.g. Chart.element.Point).\r
- * @type {Chart.core.element}\r
- */\r
- dataElementType: null,\r
-\r
- initialize: function(chart, datasetIndex) {\r
- var me = this;\r
- me.chart = chart;\r
- me.index = datasetIndex;\r
- me.linkScales();\r
- me.addElements();\r
- },\r
-\r
- updateIndex: function(datasetIndex) {\r
- this.index = datasetIndex;\r
- },\r
-\r
- linkScales: function() {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var dataset = me.getDataset();\r
-\r
- if (meta.xAxisID === null) {\r
- meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;\r
- }\r
- if (meta.yAxisID === null) {\r
- meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;\r
- }\r
- },\r
-\r
- getDataset: function() {\r
- return this.chart.data.datasets[this.index];\r
- },\r
-\r
- getMeta: function() {\r
- return this.chart.getDatasetMeta(this.index);\r
- },\r
-\r
- getScaleForId: function(scaleID) {\r
- return this.chart.scales[scaleID];\r
- },\r
-\r
- reset: function() {\r
- this.update(true);\r
- },\r
-\r
- createMetaDataset: function() {\r
- var me = this;\r
- var type = me.datasetElementType;\r
- return type && new type({\r
- _chart: me.chart.chart,\r
- _datasetIndex: me.index\r
- });\r
- },\r
-\r
- createMetaData: function(index) {\r
- var me = this;\r
- var type = me.dataElementType;\r
- return type && new type({\r
- _chart: me.chart.chart,\r
- _datasetIndex: me.index,\r
- _index: index\r
- });\r
- },\r
-\r
- addElements: function() {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var data = me.getDataset().data || [];\r
- var metaData = meta.data;\r
- var i, ilen;\r
-\r
- for (i=0, ilen=data.length; i<ilen; ++i) {\r
- metaData[i] = metaData[i] || me.createMetaData(meta, i);\r
- }\r
-\r
- meta.dataset = meta.dataset || me.createMetaDataset();\r
- },\r
-\r
- addElementAndReset: function(index) {\r
- var me = this;\r
- var element = me.createMetaData(index);\r
- me.getMeta().data.splice(index, 0, element);\r
- me.updateElement(element, index, true);\r
- },\r
-\r
- buildOrUpdateElements: function buildOrUpdateElements() {\r
- // Handle the number of data points changing\r
- var meta = this.getMeta(),\r
- md = meta.data,\r
- numData = this.getDataset().data.length,\r
- numMetaData = md.length;\r
-\r
- // Make sure that we handle number of datapoints changing\r
- if (numData < numMetaData) {\r
- // Remove excess bars for data points that have been removed\r
- md.splice(numData, numMetaData - numData);\r
- } else if (numData > numMetaData) {\r
- // Add new elements\r
- for (var index = numMetaData; index < numData; ++index) {\r
- this.addElementAndReset(index);\r
- }\r
- }\r
- },\r
-\r
- update: noop,\r
-\r
- draw: function(ease) {\r
- var easingDecimal = ease || 1;\r
- helpers.each(this.getMeta().data, function(element, index) {\r
- element.transition(easingDecimal).draw();\r
- });\r
- },\r
-\r
- removeHoverStyle: function(element, elementOpts) {\r
- var dataset = this.chart.data.datasets[element._datasetIndex],\r
- index = element._index,\r
- custom = element.custom || {},\r
- valueOrDefault = helpers.getValueAtIndexOrDefault,\r
- color = helpers.color,\r
- model = element._model;\r
-\r
- model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);\r
- model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);\r
- model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);\r
- },\r
-\r
- setHoverStyle: function(element) {\r
- var dataset = this.chart.data.datasets[element._datasetIndex],\r
- index = element._index,\r
- custom = element.custom || {},\r
- valueOrDefault = helpers.getValueAtIndexOrDefault,\r
- color = helpers.color,\r
- getHoverColor = helpers.getHoverColor,\r
- model = element._model;\r
-\r
- model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\r
- }\r
- });\r
-\r
- Chart.DatasetController.extend = helpers.inherits;\r
-};
-},{}],24:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.elements = {};\r
-\r
- Chart.Element = function(configuration) {\r
- helpers.extend(this, configuration);\r
- this.initialize.apply(this, arguments);\r
- };\r
-\r
- helpers.extend(Chart.Element.prototype, {\r
-\r
- initialize: function() {\r
- this.hidden = false;\r
- },\r
-\r
- pivot: function() {\r
- var me = this;\r
- if (!me._view) {\r
- me._view = helpers.clone(me._model);\r
- }\r
- me._start = helpers.clone(me._view);\r
- return me;\r
- },\r
-\r
- transition: function(ease) {\r
- var me = this;\r
- \r
- if (!me._view) {\r
- me._view = helpers.clone(me._model);\r
- }\r
-\r
- // No animation -> No Transition\r
- if (ease === 1) {\r
- me._view = me._model;\r
- me._start = null;\r
- return me;\r
- }\r
-\r
- if (!me._start) {\r
- me.pivot();\r
- }\r
-\r
- helpers.each(me._model, function(value, key) {\r
-\r
- if (key[0] === '_') {\r
- // Only non-underscored properties\r
- }\r
-\r
- // Init if doesn't exist\r
- else if (!me._view.hasOwnProperty(key)) {\r
- if (typeof value === 'number' && !isNaN(me._view[key])) {\r
- me._view[key] = value * ease;\r
- } else {\r
- me._view[key] = value;\r
- }\r
- }\r
-\r
- // No unnecessary computations\r
- else if (value === me._view[key]) {\r
- // It's the same! Woohoo!\r
- }\r
-\r
- // Color transitions if possible\r
- else if (typeof value === 'string') {\r
- try {\r
- var color = helpers.color(me._model[key]).mix(helpers.color(me._start[key]), ease);\r
- me._view[key] = color.rgbString();\r
- } catch (err) {\r
- me._view[key] = value;\r
- }\r
- }\r
- // Number transitions\r
- else if (typeof value === 'number') {\r
- var startVal = me._start[key] !== undefined && isNaN(me._start[key]) === false ? me._start[key] : 0;\r
- me._view[key] = ((me._model[key] - startVal) * ease) + startVal;\r
- }\r
- // Everything else\r
- else {\r
- me._view[key] = value;\r
- }\r
- }, me);\r
-\r
- return me;\r
- },\r
-\r
- tooltipPosition: function() {\r
- return {\r
- x: this._model.x,\r
- y: this._model.y\r
- };\r
- },\r
-\r
- hasValue: function() {\r
- return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);\r
- }\r
- });\r
-\r
- Chart.Element.extend = helpers.inherits;\r
-\r
-};\r
-
-},{}],25:[function(require,module,exports){
-/*global window: false */\r
-/*global document: false */\r
-"use strict";\r
-\r
-var color = require(2);\r
-\r
-module.exports = function(Chart) {\r
- //Global Chart helpers object for utility methods and classes\r
- var helpers = Chart.helpers = {};\r
-\r
- //-- Basic js utility methods\r
- helpers.each = function(loopable, callback, self, reverse) {\r
- // Check to see if null or undefined firstly.\r
- var i, len;\r
- if (helpers.isArray(loopable)) {\r
- len = loopable.length;\r
- if (reverse) {\r
- for (i = len - 1; i >= 0; i--) {\r
- callback.call(self, loopable[i], i);\r
- }\r
- } else {\r
- for (i = 0; i < len; i++) {\r
- callback.call(self, loopable[i], i);\r
- }\r
- }\r
- } else if (typeof loopable === 'object') {\r
- var keys = Object.keys(loopable);\r
- len = keys.length;\r
- for (i = 0; i < len; i++) {\r
- callback.call(self, loopable[keys[i]], keys[i]);\r
- }\r
- }\r
- };\r
- helpers.clone = function(obj) {\r
- var objClone = {};\r
- helpers.each(obj, function(value, key) {\r
- if (helpers.isArray(value)) {\r
- objClone[key] = value.slice(0);\r
- } else if (typeof value === 'object' && value !== null) {\r
- objClone[key] = helpers.clone(value);\r
- } else {\r
- objClone[key] = value;\r
- }\r
- });\r
- return objClone;\r
- };\r
- helpers.extend = function(base) {\r
- var setFn = function(value, key) { base[key] = value; };\r
- for (var i = 1, ilen = arguments.length; i < ilen; i++) {\r
- helpers.each(arguments[i], setFn);\r
- }\r
- return base;\r
- };\r
- // Need a special merge function to chart configs since they are now grouped\r
- helpers.configMerge = function(_base) {\r
- var base = helpers.clone(_base);\r
- helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {\r
- helpers.each(extension, function(value, key) {\r
- if (key === 'scales') {\r
- // Scale config merging is complex. Add out own function here for that\r
- base[key] = helpers.scaleMerge(base.hasOwnProperty(key) ? base[key] : {}, value);\r
-\r
- } else if (key === 'scale') {\r
- // Used in polar area & radar charts since there is only one scale\r
- base[key] = helpers.configMerge(base.hasOwnProperty(key) ? base[key] : {}, Chart.scaleService.getScaleDefaults(value.type), value);\r
- } else if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {\r
- // In this case we have an array of objects replacing another array. Rather than doing a strict replace,\r
- // merge. This allows easy scale option merging\r
- var baseArray = base[key];\r
-\r
- helpers.each(value, function(valueObj, index) {\r
-\r
- if (index < baseArray.length) {\r
- if (typeof baseArray[index] === 'object' && baseArray[index] !== null && typeof valueObj === 'object' && valueObj !== null) {\r
- // Two objects are coming together. Do a merge of them.\r
- baseArray[index] = helpers.configMerge(baseArray[index], valueObj);\r
- } else {\r
- // Just overwrite in this case since there is nothing to merge\r
- baseArray[index] = valueObj;\r
- }\r
- } else {\r
- baseArray.push(valueObj); // nothing to merge\r
- }\r
- });\r
-\r
- } else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") {\r
- // If we are overwriting an object with an object, do a merge of the properties.\r
- base[key] = helpers.configMerge(base[key], value);\r
-\r
- } else {\r
- // can just overwrite the value in this case\r
- base[key] = value;\r
- }\r
- });\r
- });\r
-\r
- return base;\r
- };\r
- helpers.scaleMerge = function(_base, extension) {\r
- var base = helpers.clone(_base);\r
-\r
- helpers.each(extension, function(value, key) {\r
- if (key === 'xAxes' || key === 'yAxes') {\r
- // These properties are arrays of items\r
- if (base.hasOwnProperty(key)) {\r
- helpers.each(value, function(valueObj, index) {\r
- var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\r
- var axisDefaults = Chart.scaleService.getScaleDefaults(axisType);\r
- if (index >= base[key].length || !base[key][index].type) {\r
- base[key].push(helpers.configMerge(axisDefaults, valueObj));\r
- } else if (valueObj.type && valueObj.type !== base[key][index].type) {\r
- // Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults\r
- base[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);\r
- } else {\r
- // Type is the same\r
- base[key][index] = helpers.configMerge(base[key][index], valueObj);\r
- }\r
- });\r
- } else {\r
- base[key] = [];\r
- helpers.each(value, function(valueObj) {\r
- var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\r
- base[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));\r
- });\r
- }\r
- } else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") {\r
- // If we are overwriting an object with an object, do a merge of the properties.\r
- base[key] = helpers.configMerge(base[key], value);\r
-\r
- } else {\r
- // can just overwrite the value in this case\r
- base[key] = value;\r
- }\r
- });\r
-\r
- return base;\r
- };\r
- helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {\r
- if (value === undefined || value === null) {\r
- return defaultValue;\r
- }\r
-\r
- if (helpers.isArray(value)) {\r
- return index < value.length ? value[index] : defaultValue;\r
- }\r
-\r
- return value;\r
- };\r
- helpers.getValueOrDefault = function(value, defaultValue) {\r
- return value === undefined ? defaultValue : value;\r
- };\r
- helpers.indexOf = Array.prototype.indexOf?\r
- function(array, item) { return array.indexOf(item); } :\r
- function(array, item) {\r
- for (var i = 0, ilen = array.length; i < ilen; ++i) {\r
- if (array[i] === item) {\r
- return i;\r
- }\r
- }\r
- return -1;\r
- };\r
- helpers.where = function(collection, filterCallback) {\r
- if (helpers.isArray(collection) && Array.prototype.filter) {\r
- return collection.filter(filterCallback);\r
- } else {\r
- var filtered = [];\r
-\r
- helpers.each(collection, function(item) {\r
- if (filterCallback(item)) {\r
- filtered.push(item);\r
- }\r
- });\r
-\r
- return filtered;\r
- }\r
- };\r
- helpers.findIndex = Array.prototype.findIndex?\r
- function(array, callback, scope) { return array.findIndex(callback, scope); } :\r
- function(array, callback, scope) {\r
- scope = scope === undefined? array : scope;\r
- for (var i = 0, ilen = array.length; i < ilen; ++i) {\r
- if (callback.call(scope, array[i], i, array)) {\r
- return i;\r
- }\r
- }\r
- return -1;\r
- };\r
- helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {\r
- // Default to start of the array\r
- if (startIndex === undefined || startIndex === null) {\r
- startIndex = -1;\r
- }\r
- for (var i = startIndex + 1; i < arrayToSearch.length; i++) {\r
- var currentItem = arrayToSearch[i];\r
- if (filterCallback(currentItem)) {\r
- return currentItem;\r
- }\r
- }\r
- };\r
- helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {\r
- // Default to end of the array\r
- if (startIndex === undefined || startIndex === null) {\r
- startIndex = arrayToSearch.length;\r
- }\r
- for (var i = startIndex - 1; i >= 0; i--) {\r
- var currentItem = arrayToSearch[i];\r
- if (filterCallback(currentItem)) {\r
- return currentItem;\r
- }\r
- }\r
- };\r
- helpers.inherits = function(extensions) {\r
- //Basic javascript inheritance based on the model created in Backbone.js\r
- var parent = this;\r
- var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function() {\r
- return parent.apply(this, arguments);\r
- };\r
-\r
- var Surrogate = function() {\r
- this.constructor = ChartElement;\r
- };\r
- Surrogate.prototype = parent.prototype;\r
- ChartElement.prototype = new Surrogate();\r
-\r
- ChartElement.extend = helpers.inherits;\r
-\r
- if (extensions) {\r
- helpers.extend(ChartElement.prototype, extensions);\r
- }\r
-\r
- ChartElement.__super__ = parent.prototype;\r
-\r
- return ChartElement;\r
- };\r
- helpers.noop = function() {};\r
- helpers.uid = (function() {\r
- var id = 0;\r
- return function() {\r
- return id++;\r
- };\r
- })();\r
- //-- Math methods\r
- helpers.isNumber = function(n) {\r
- return !isNaN(parseFloat(n)) && isFinite(n);\r
- };\r
- helpers.almostEquals = function(x, y, epsilon) {\r
- return Math.abs(x - y) < epsilon;\r
- };\r
- helpers.max = function(array) {\r
- return array.reduce(function(max, value) {\r
- if (!isNaN(value)) {\r
- return Math.max(max, value);\r
- } else {\r
- return max;\r
- }\r
- }, Number.NEGATIVE_INFINITY);\r
- };\r
- helpers.min = function(array) {\r
- return array.reduce(function(min, value) {\r
- if (!isNaN(value)) {\r
- return Math.min(min, value);\r
- } else {\r
- return min;\r
- }\r
- }, Number.POSITIVE_INFINITY);\r
- };\r
- helpers.sign = Math.sign?\r
- function(x) { return Math.sign(x); } :\r
- function(x) {\r
- x = +x; // convert to a number\r
- if (x === 0 || isNaN(x)) {\r
- return x;\r
- }\r
- return x > 0 ? 1 : -1;\r
- };\r
- helpers.log10 = Math.log10?\r
- function(x) { return Math.log10(x); } :\r
- function(x) {\r
- return Math.log(x) / Math.LN10;\r
- };\r
- helpers.toRadians = function(degrees) {\r
- return degrees * (Math.PI / 180);\r
- };\r
- helpers.toDegrees = function(radians) {\r
- return radians * (180 / Math.PI);\r
- };\r
- // Gets the angle from vertical upright to the point about a centre.\r
- helpers.getAngleFromPoint = function(centrePoint, anglePoint) {\r
- var distanceFromXCenter = anglePoint.x - centrePoint.x,\r
- distanceFromYCenter = anglePoint.y - centrePoint.y,\r
- radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\r
-\r
- var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\r
-\r
- if (angle < (-0.5 * Math.PI)) {\r
- angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\r
- }\r
-\r
- return {\r
- angle: angle,\r
- distance: radialDistanceFromCenter\r
- };\r
- };\r
- helpers.aliasPixel = function(pixelWidth) {\r
- return (pixelWidth % 2 === 0) ? 0 : 0.5;\r
- };\r
- helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {\r
- //Props to Rob Spencer at scaled innovation for his post on splining between points\r
- //http://scaledinnovation.com/analytics/splines/aboutSplines.html\r
-\r
- // This function must also respect "skipped" points\r
-\r
- var previous = firstPoint.skip ? middlePoint : firstPoint,\r
- current = middlePoint,\r
- next = afterPoint.skip ? middlePoint : afterPoint;\r
-\r
- var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));\r
- var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));\r
-\r
- var s01 = d01 / (d01 + d12);\r
- var s12 = d12 / (d01 + d12);\r
-\r
- // If all points are the same, s01 & s02 will be inf\r
- s01 = isNaN(s01) ? 0 : s01;\r
- s12 = isNaN(s12) ? 0 : s12;\r
-\r
- var fa = t * s01; // scaling factor for triangle Ta\r
- var fb = t * s12;\r
-\r
- return {\r
- previous: {\r
- x: current.x - fa * (next.x - previous.x),\r
- y: current.y - fa * (next.y - previous.y)\r
- },\r
- next: {\r
- x: current.x + fb * (next.x - previous.x),\r
- y: current.y + fb * (next.y - previous.y)\r
- }\r
- };\r
- };\r
- helpers.nextItem = function(collection, index, loop) {\r
- if (loop) {\r
- return index >= collection.length - 1 ? collection[0] : collection[index + 1];\r
- }\r
-\r
- return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];\r
- };\r
- helpers.previousItem = function(collection, index, loop) {\r
- if (loop) {\r
- return index <= 0 ? collection[collection.length - 1] : collection[index - 1];\r
- }\r
- return index <= 0 ? collection[0] : collection[index - 1];\r
- };\r
- // Implementation of the nice number algorithm used in determining where axis labels will go\r
- helpers.niceNum = function(range, round) {\r
- var exponent = Math.floor(helpers.log10(range));\r
- var fraction = range / Math.pow(10, exponent);\r
- var niceFraction;\r
-\r
- if (round) {\r
- if (fraction < 1.5) {\r
- niceFraction = 1;\r
- } else if (fraction < 3) {\r
- niceFraction = 2;\r
- } else if (fraction < 7) {\r
- niceFraction = 5;\r
- } else {\r
- niceFraction = 10;\r
- }\r
- } else {\r
- if (fraction <= 1.0) {\r
- niceFraction = 1;\r
- } else if (fraction <= 2) {\r
- niceFraction = 2;\r
- } else if (fraction <= 5) {\r
- niceFraction = 5;\r
- } else {\r
- niceFraction = 10;\r
- }\r
- }\r
-\r
- return niceFraction * Math.pow(10, exponent);\r
- };\r
- //Easing functions adapted from Robert Penner's easing equations\r
- //http://www.robertpenner.com/easing/\r
- var easingEffects = helpers.easingEffects = {\r
- linear: function(t) {\r
- return t;\r
- },\r
- easeInQuad: function(t) {\r
- return t * t;\r
- },\r
- easeOutQuad: function(t) {\r
- return -1 * t * (t - 2);\r
- },\r
- easeInOutQuad: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t;\r
- }\r
- return -1 / 2 * ((--t) * (t - 2) - 1);\r
- },\r
- easeInCubic: function(t) {\r
- return t * t * t;\r
- },\r
- easeOutCubic: function(t) {\r
- return 1 * ((t = t / 1 - 1) * t * t + 1);\r
- },\r
- easeInOutCubic: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t * t;\r
- }\r
- return 1 / 2 * ((t -= 2) * t * t + 2);\r
- },\r
- easeInQuart: function(t) {\r
- return t * t * t * t;\r
- },\r
- easeOutQuart: function(t) {\r
- return -1 * ((t = t / 1 - 1) * t * t * t - 1);\r
- },\r
- easeInOutQuart: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t * t * t;\r
- }\r
- return -1 / 2 * ((t -= 2) * t * t * t - 2);\r
- },\r
- easeInQuint: function(t) {\r
- return 1 * (t /= 1) * t * t * t * t;\r
- },\r
- easeOutQuint: function(t) {\r
- return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\r
- },\r
- easeInOutQuint: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t * t * t * t;\r
- }\r
- return 1 / 2 * ((t -= 2) * t * t * t * t + 2);\r
- },\r
- easeInSine: function(t) {\r
- return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\r
- },\r
- easeOutSine: function(t) {\r
- return 1 * Math.sin(t / 1 * (Math.PI / 2));\r
- },\r
- easeInOutSine: function(t) {\r
- return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\r
- },\r
- easeInExpo: function(t) {\r
- return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\r
- },\r
- easeOutExpo: function(t) {\r
- return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\r
- },\r
- easeInOutExpo: function(t) {\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if (t === 1) {\r
- return 1;\r
- }\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * Math.pow(2, 10 * (t - 1));\r
- }\r
- return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\r
- },\r
- easeInCirc: function(t) {\r
- if (t >= 1) {\r
- return t;\r
- }\r
- return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\r
- },\r
- easeOutCirc: function(t) {\r
- return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\r
- },\r
- easeInOutCirc: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return -1 / 2 * (Math.sqrt(1 - t * t) - 1);\r
- }\r
- return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\r
- },\r
- easeInElastic: function(t) {\r
- var s = 1.70158;\r
- var p = 0;\r
- var a = 1;\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if ((t /= 1) === 1) {\r
- return 1;\r
- }\r
- if (!p) {\r
- p = 1 * 0.3;\r
- }\r
- if (a < Math.abs(1)) {\r
- a = 1;\r
- s = p / 4;\r
- } else {\r
- s = p / (2 * Math.PI) * Math.asin(1 / a);\r
- }\r
- return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\r
- },\r
- easeOutElastic: function(t) {\r
- var s = 1.70158;\r
- var p = 0;\r
- var a = 1;\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if ((t /= 1) === 1) {\r
- return 1;\r
- }\r
- if (!p) {\r
- p = 1 * 0.3;\r
- }\r
- if (a < Math.abs(1)) {\r
- a = 1;\r
- s = p / 4;\r
- } else {\r
- s = p / (2 * Math.PI) * Math.asin(1 / a);\r
- }\r
- return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\r
- },\r
- easeInOutElastic: function(t) {\r
- var s = 1.70158;\r
- var p = 0;\r
- var a = 1;\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if ((t /= 1 / 2) === 2) {\r
- return 1;\r
- }\r
- if (!p) {\r
- p = 1 * (0.3 * 1.5);\r
- }\r
- if (a < Math.abs(1)) {\r
- a = 1;\r
- s = p / 4;\r
- } else {\r
- s = p / (2 * Math.PI) * Math.asin(1 / a);\r
- }\r
- if (t < 1) {\r
- return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\r
- }\r
- return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\r
- },\r
- easeInBack: function(t) {\r
- var s = 1.70158;\r
- return 1 * (t /= 1) * t * ((s + 1) * t - s);\r
- },\r
- easeOutBack: function(t) {\r
- var s = 1.70158;\r
- return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\r
- },\r
- easeInOutBack: function(t) {\r
- var s = 1.70158;\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\r
- }\r
- return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\r
- },\r
- easeInBounce: function(t) {\r
- return 1 - easingEffects.easeOutBounce(1 - t);\r
- },\r
- easeOutBounce: function(t) {\r
- if ((t /= 1) < (1 / 2.75)) {\r
- return 1 * (7.5625 * t * t);\r
- } else if (t < (2 / 2.75)) {\r
- return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\r
- } else if (t < (2.5 / 2.75)) {\r
- return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\r
- } else {\r
- return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\r
- }\r
- },\r
- easeInOutBounce: function(t) {\r
- if (t < 1 / 2) {\r
- return easingEffects.easeInBounce(t * 2) * 0.5;\r
- }\r
- return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\r
- }\r
- };\r
- //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\r
- helpers.requestAnimFrame = (function() {\r
- return window.requestAnimationFrame ||\r
- window.webkitRequestAnimationFrame ||\r
- window.mozRequestAnimationFrame ||\r
- window.oRequestAnimationFrame ||\r
- window.msRequestAnimationFrame ||\r
- function(callback) {\r
- return window.setTimeout(callback, 1000 / 60);\r
- };\r
- })();\r
- helpers.cancelAnimFrame = (function() {\r
- return window.cancelAnimationFrame ||\r
- window.webkitCancelAnimationFrame ||\r
- window.mozCancelAnimationFrame ||\r
- window.oCancelAnimationFrame ||\r
- window.msCancelAnimationFrame ||\r
- function(callback) {\r
- return window.clearTimeout(callback, 1000 / 60);\r
- };\r
- })();\r
- //-- DOM methods\r
- helpers.getRelativePosition = function(evt, chart) {\r
- var mouseX, mouseY;\r
- var e = evt.originalEvent || evt,\r
- canvas = evt.currentTarget || evt.srcElement,\r
- boundingRect = canvas.getBoundingClientRect();\r
-\r
- var touches = e.touches;\r
- if (touches && touches.length > 0) {\r
- mouseX = touches[0].clientX;\r
- mouseY = touches[0].clientY;\r
-\r
- } else {\r
- mouseX = e.clientX;\r
- mouseY = e.clientY;\r
- }\r
-\r
- // Scale mouse coordinates into canvas coordinates\r
- // by following the pattern laid out by 'jerryj' in the comments of\r
- // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/\r
- var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));\r
- var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));\r
- var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));\r
- var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));\r
- var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;\r
- var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;\r
-\r
- // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However\r
- // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here\r
- mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);\r
- mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);\r
-\r
- return {\r
- x: mouseX,\r
- y: mouseY\r
- };\r
-\r
- };\r
- helpers.addEvent = function(node, eventType, method) {\r
- if (node.addEventListener) {\r
- node.addEventListener(eventType, method);\r
- } else if (node.attachEvent) {\r
- node.attachEvent("on" + eventType, method);\r
- } else {\r
- node["on" + eventType] = method;\r
- }\r
- };\r
- helpers.removeEvent = function(node, eventType, handler) {\r
- if (node.removeEventListener) {\r
- node.removeEventListener(eventType, handler, false);\r
- } else if (node.detachEvent) {\r
- node.detachEvent("on" + eventType, handler);\r
- } else {\r
- node["on" + eventType] = helpers.noop;\r
- }\r
- };\r
- helpers.bindEvents = function(chartInstance, arrayOfEvents, handler) {\r
- // Create the events object if it's not already present\r
- var events = chartInstance.events = chartInstance.events || {};\r
-\r
- helpers.each(arrayOfEvents, function(eventName) {\r
- events[eventName] = function() {\r
- handler.apply(chartInstance, arguments);\r
- };\r
- helpers.addEvent(chartInstance.chart.canvas, eventName, events[eventName]);\r
- });\r
- };\r
- helpers.unbindEvents = function(chartInstance, arrayOfEvents) {\r
- var canvas = chartInstance.chart.canvas;\r
- helpers.each(arrayOfEvents, function(handler, eventName) {\r
- helpers.removeEvent(canvas, eventName, handler);\r
- });\r
- };\r
-\r
- // Private helper function to convert max-width/max-height values that may be percentages into a number\r
- function parseMaxStyle(styleValue, node, parentProperty) {\r
- var valueInPixels;\r
- if (typeof(styleValue) === 'string') {\r
- valueInPixels = parseInt(styleValue, 10);\r
-\r
- if (styleValue.indexOf('%') != -1) {\r
- // percentage * size in dimension\r
- valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\r
- }\r
- } else {\r
- valueInPixels = styleValue;\r
- }\r
-\r
- return valueInPixels;\r
- }\r
-\r
- /**\r
- * Returns if the given value contains an effective constraint.\r
- * @private\r
- */\r
- function isConstrainedValue(value) {\r
- return value !== undefined && value !== null && value !== 'none';\r
- }\r
-\r
- // Private helper to get a constraint dimension\r
- // @param domNode : the node to check the constraint on\r
- // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)\r
- // @param percentageProperty : property of parent to use when calculating width as a percentage\r
- // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser\r
- function getConstraintDimension(domNode, maxStyle, percentageProperty) {\r
- var view = document.defaultView;\r
- var parentNode = domNode.parentNode;\r
- var constrainedNode = view.getComputedStyle(domNode)[maxStyle];\r
- var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];\r
- var hasCNode = isConstrainedValue(constrainedNode);\r
- var hasCContainer = isConstrainedValue(constrainedContainer);\r
- var infinity = Number.POSITIVE_INFINITY;\r
-\r
- if (hasCNode || hasCContainer) {\r
- return Math.min(\r
- hasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,\r
- hasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);\r
- }\r
-\r
- return 'none';\r
- }\r
- // returns Number or undefined if no constraint\r
- helpers.getConstraintWidth = function(domNode) {\r
- return getConstraintDimension(domNode, 'max-width', 'clientWidth');\r
- };\r
- // returns Number or undefined if no constraint\r
- helpers.getConstraintHeight = function(domNode) {\r
- return getConstraintDimension(domNode, 'max-height', 'clientHeight');\r
- };\r
- helpers.getMaximumWidth = function(domNode) {\r
- var container = domNode.parentNode;\r
- var padding = parseInt(helpers.getStyle(container, 'padding-left')) + parseInt(helpers.getStyle(container, 'padding-right'));\r
- var w = container.clientWidth - padding;\r
- var cw = helpers.getConstraintWidth(domNode);\r
- return isNaN(cw)? w : Math.min(w, cw);\r
- };\r
- helpers.getMaximumHeight = function(domNode) {\r
- var container = domNode.parentNode;\r
- var padding = parseInt(helpers.getStyle(container, 'padding-top')) + parseInt(helpers.getStyle(container, 'padding-bottom'));\r
- var h = container.clientHeight - padding;\r
- var ch = helpers.getConstraintHeight(domNode);\r
- return isNaN(ch)? h : Math.min(h, ch);\r
- };\r
- helpers.getStyle = function(el, property) {\r
- return el.currentStyle ?\r
- el.currentStyle[property] :\r
- document.defaultView.getComputedStyle(el, null).getPropertyValue(property);\r
- };\r
- helpers.retinaScale = function(chart) {\r
- var ctx = chart.ctx;\r
- var canvas = chart.canvas;\r
- var width = canvas.width;\r
- var height = canvas.height;\r
- var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;\r
-\r
- if (pixelRatio !== 1) {\r
- canvas.height = height * pixelRatio;\r
- canvas.width = width * pixelRatio;\r
- ctx.scale(pixelRatio, pixelRatio);\r
-\r
- // Store the device pixel ratio so that we can go backwards in `destroy`.\r
- // The devicePixelRatio changes with zoom, so there are no guarantees that it is the same\r
- // when destroy is called\r
- chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || pixelRatio;\r
- }\r
-\r
- canvas.style.width = width + 'px';\r
- canvas.style.height = height + 'px';\r
- };\r
- //-- Canvas methods\r
- helpers.clear = function(chart) {\r
- chart.ctx.clearRect(0, 0, chart.width, chart.height);\r
- };\r
- helpers.fontString = function(pixelSize, fontStyle, fontFamily) {\r
- return fontStyle + " " + pixelSize + "px " + fontFamily;\r
- };\r
- helpers.longestText = function(ctx, font, arrayOfThings, cache) {\r
- cache = cache || {};\r
- var data = cache.data = cache.data || {};\r
- var gc = cache.garbageCollect = cache.garbageCollect || [];\r
-\r
- if (cache.font !== font) {\r
- data = cache.data = {};\r
- gc = cache.garbageCollect = [];\r
- cache.font = font;\r
- }\r
-\r
- ctx.font = font;\r
- var longest = 0;\r
- helpers.each(arrayOfThings, function(thing) {\r
- // Undefined strings and arrays should not be measured\r
- if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {\r
- longest = helpers.measureText(ctx, data, gc, longest, thing);\r
- } else if (helpers.isArray(thing)) {\r
- // if it is an array lets measure each element\r
- // to do maybe simplify this function a bit so we can do this more recursively?\r
- helpers.each(thing, function(nestedThing) {\r
- // Undefined strings and arrays should not be measured\r
- if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {\r
- longest = helpers.measureText(ctx, data, gc, longest, nestedThing);\r
- }\r
- });\r
- }\r
- });\r
-\r
- var gcLen = gc.length / 2;\r
- if (gcLen > arrayOfThings.length) {\r
- for (var i = 0; i < gcLen; i++) {\r
- delete data[gc[i]];\r
- }\r
- gc.splice(0, gcLen);\r
- }\r
- return longest;\r
- };\r
- helpers.measureText = function (ctx, data, gc, longest, string) {\r
- var textWidth = data[string];\r
- if (!textWidth) {\r
- textWidth = data[string] = ctx.measureText(string).width;\r
- gc.push(string);\r
- }\r
- if (textWidth > longest) {\r
- longest = textWidth;\r
- }\r
- return longest;\r
- };\r
- helpers.numberOfLabelLines = function(arrayOfThings) {\r
- var numberOfLines = 1;\r
- helpers.each(arrayOfThings, function(thing) {\r
- if (helpers.isArray(thing)) {\r
- if (thing.length > numberOfLines) {\r
- numberOfLines = thing.length;\r
- }\r
- }\r
- });\r
- return numberOfLines;\r
- };\r
- helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {\r
- ctx.beginPath();\r
- ctx.moveTo(x + radius, y);\r
- ctx.lineTo(x + width - radius, y);\r
- ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\r
- ctx.lineTo(x + width, y + height - radius);\r
- ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\r
- ctx.lineTo(x + radius, y + height);\r
- ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\r
- ctx.lineTo(x, y + radius);\r
- ctx.quadraticCurveTo(x, y, x + radius, y);\r
- ctx.closePath();\r
- };\r
- helpers.color = function(c) {\r
- if (!color) {\r
- console.log('Color.js not found!');\r
- return c;\r
- }\r
-\r
- /* global CanvasGradient */\r
- if (c instanceof CanvasGradient) {\r
- return color(Chart.defaults.global.defaultColor);\r
- }\r
-\r
- return color(c);\r
- };\r
- helpers.addResizeListener = function(node, callback) {\r
- // Hide an iframe before the node\r
- var hiddenIframe = document.createElement('iframe');\r
- var hiddenIframeClass = 'chartjs-hidden-iframe';\r
-\r
- if (hiddenIframe.classlist) {\r
- // can use classlist\r
- hiddenIframe.classlist.add(hiddenIframeClass);\r
- } else {\r
- hiddenIframe.setAttribute('class', hiddenIframeClass);\r
- }\r
-\r
- // Set the style\r
- var style = hiddenIframe.style;\r
- style.width = '100%';\r
- style.display = 'block';\r
- style.border = 0;\r
- style.height = 0;\r
- style.margin = 0;\r
- style.position = 'absolute';\r
- style.left = 0;\r
- style.right = 0;\r
- style.top = 0;\r
- style.bottom = 0;\r
-\r
- // Insert the iframe so that contentWindow is available\r
- node.insertBefore(hiddenIframe, node.firstChild);\r
-\r
- (hiddenIframe.contentWindow || hiddenIframe).onresize = function() {\r
- if (callback) {\r
- callback();\r
- }\r
- };\r
- };\r
- helpers.removeResizeListener = function(node) {\r
- var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');\r
-\r
- // Remove the resize detect iframe\r
- if (hiddenIframe) {\r
- hiddenIframe.parentNode.removeChild(hiddenIframe);\r
- }\r
- };\r
- helpers.isArray = Array.isArray?\r
- function(obj) { return Array.isArray(obj); } :\r
- function(obj) {\r
- return Object.prototype.toString.call(obj) === '[object Array]';\r
- };\r
- //! @see http://stackoverflow.com/a/14853974\r
- helpers.arrayEquals = function(a0, a1) {\r
- var i, ilen, v0, v1;\r
-\r
- if (!a0 || !a1 || a0.length != a1.length) {\r
- return false;\r
- }\r
-\r
- for (i = 0, ilen=a0.length; i < ilen; ++i) {\r
- v0 = a0[i];\r
- v1 = a1[i];\r
-\r
- if (v0 instanceof Array && v1 instanceof Array) {\r
- if (!helpers.arrayEquals(v0, v1)) {\r
- return false;\r
- }\r
- } else if (v0 != v1) {\r
- // NOTE: two different object instances will never be equal: {x:20} != {x:20}\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
- };\r
- helpers.callCallback = function(fn, args, _tArg) {\r
- if (fn && typeof fn.call === 'function') {\r
- fn.apply(_tArg, args);\r
- }\r
- };\r
- helpers.getHoverColor = function(color) {\r
- /* global CanvasPattern */\r
- return (color instanceof CanvasPattern) ?\r
- color :\r
- helpers.color(color).saturate(0.5).darken(0.1).rgbString();\r
- };\r
-};\r
-
-},{"2":2}],26:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function() {\r
-\r
- //Occupy the global variable of Chart, and create a simple base class\r
- var Chart = function(context, config) {\r
- var me = this;\r
- var helpers = Chart.helpers;\r
- me.config = config;\r
-\r
- // Support a jQuery'd canvas element\r
- if (context.length && context[0].getContext) {\r
- context = context[0];\r
- }\r
-\r
- // Support a canvas domnode\r
- if (context.getContext) {\r
- context = context.getContext("2d");\r
- }\r
-\r
- me.ctx = context;\r
- me.canvas = context.canvas;\r
-\r
- context.canvas.style.display = context.canvas.style.display || 'block';\r
-\r
- // Figure out what the size of the chart will be.\r
- // If the canvas has a specified width and height, we use those else\r
- // we look to see if the canvas node has a CSS width and height.\r
- // If there is still no height, fill the parent container\r
- me.width = context.canvas.width || parseInt(helpers.getStyle(context.canvas, 'width'), 10) || helpers.getMaximumWidth(context.canvas);\r
- me.height = context.canvas.height || parseInt(helpers.getStyle(context.canvas, 'height'), 10) || helpers.getMaximumHeight(context.canvas);\r
-\r
- me.aspectRatio = me.width / me.height;\r
-\r
- if (isNaN(me.aspectRatio) || isFinite(me.aspectRatio) === false) {\r
- // If the canvas has no size, try and figure out what the aspect ratio will be.\r
- // Some charts prefer square canvases (pie, radar, etc). If that is specified, use that\r
- // else use the canvas default ratio of 2\r
- me.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;\r
- }\r
-\r
- // Store the original style of the element so we can set it back\r
- me.originalCanvasStyleWidth = context.canvas.style.width;\r
- me.originalCanvasStyleHeight = context.canvas.style.height;\r
-\r
- // High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.\r
- helpers.retinaScale(me);\r
-\r
- if (config) {\r
- me.controller = new Chart.Controller(me);\r
- }\r
-\r
- // Always bind this so that if the responsive state changes we still work\r
- helpers.addResizeListener(context.canvas.parentNode, function() {\r
- if (me.controller && me.controller.config.options.responsive) {\r
- me.controller.resize();\r
- }\r
- });\r
-\r
- return me.controller ? me.controller : me;\r
-\r
- };\r
-\r
- //Globally expose the defaults to allow for user updating/changing\r
- Chart.defaults = {\r
- global: {\r
- responsive: true,\r
- responsiveAnimationDuration: 0,\r
- maintainAspectRatio: true,\r
- events: ["mousemove", "mouseout", "click", "touchstart", "touchmove"],\r
- hover: {\r
- onHover: null,\r
- mode: 'single',\r
- animationDuration: 400\r
- },\r
- onClick: null,\r
- defaultColor: 'rgba(0,0,0,0.1)',\r
- defaultFontColor: '#666',\r
- defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",\r
- defaultFontSize: 12,\r
- defaultFontStyle: 'normal',\r
- showLines: true,\r
-\r
- // Element defaults defined in element extensions\r
- elements: {},\r
-\r
- // Legend callback string\r
- legendCallback: function(chart) {\r
- var text = [];\r
- text.push('<ul class="' + chart.id + '-legend">');\r
- for (var i = 0; i < chart.data.datasets.length; i++) {\r
- text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>');\r
- if (chart.data.datasets[i].label) {\r
- text.push(chart.data.datasets[i].label);\r
- }\r
- text.push('</li>');\r
- }\r
- text.push('</ul>');\r
-\r
- return text.join("");\r
- }\r
- }\r
- };\r
-\r
- Chart.Chart = Chart;\r
-\r
- return Chart;\r
-\r
-};\r
-
-},{}],27:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- // The layout service is very self explanatory. It's responsible for the layout within a chart.\r
- // Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\r
- // It is this service's responsibility of carrying out that layout.\r
- Chart.layoutService = {\r
- defaults: {},\r
-\r
- // Register a box to a chartInstance. A box is simply a reference to an object that requires layout. eg. Scales, Legend, Plugins.\r
- addBox: function(chartInstance, box) {\r
- if (!chartInstance.boxes) {\r
- chartInstance.boxes = [];\r
- }\r
- chartInstance.boxes.push(box);\r
- },\r
-\r
- removeBox: function(chartInstance, box) {\r
- if (!chartInstance.boxes) {\r
- return;\r
- }\r
- chartInstance.boxes.splice(chartInstance.boxes.indexOf(box), 1);\r
- },\r
-\r
- // The most important function\r
- update: function(chartInstance, width, height) {\r
-\r
- if (!chartInstance) {\r
- return;\r
- }\r
-\r
- var xPadding = 0;\r
- var yPadding = 0;\r
-\r
- var leftBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "left";\r
- });\r
- var rightBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "right";\r
- });\r
- var topBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "top";\r
- });\r
- var bottomBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "bottom";\r
- });\r
-\r
- // Boxes that overlay the chartarea such as the radialLinear scale\r
- var chartAreaBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "chartArea";\r
- });\r
-\r
- // Ensure that full width boxes are at the very top / bottom\r
- topBoxes.sort(function(a, b) {\r
- return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0);\r
- });\r
- bottomBoxes.sort(function(a, b) {\r
- return (a.options.fullWidth ? 1 : 0) - (b.options.fullWidth ? 1 : 0);\r
- });\r
-\r
- // Essentially we now have any number of boxes on each of the 4 sides.\r
- // Our canvas looks like the following.\r
- // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\r
- // B1 is the bottom axis\r
- // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\r
- // These locations are single-box locations only, when trying to register a chartArea location that is already taken,\r
- // an error will be thrown.\r
- //\r
- // |----------------------------------------------------|\r
- // | T1 (Full Width) |\r
- // |----------------------------------------------------|\r
- // | | | T2 | |\r
- // | |----|-------------------------------------|----|\r
- // | | | C1 | | C2 | |\r
- // | | |----| |----| |\r
- // | | | | |\r
- // | L1 | L2 | ChartArea (C0) | R1 |\r
- // | | | | |\r
- // | | |----| |----| |\r
- // | | | C3 | | C4 | |\r
- // | |----|-------------------------------------|----|\r
- // | | | B1 | |\r
- // |----------------------------------------------------|\r
- // | B2 (Full Width) |\r
- // |----------------------------------------------------|\r
- //\r
- // What we do to find the best sizing, we do the following\r
- // 1. Determine the minimum size of the chart area.\r
- // 2. Split the remaining width equally between each vertical axis\r
- // 3. Split the remaining height equally between each horizontal axis\r
- // 4. Give each layout the maximum size it can be. The layout will return it's minimum size\r
- // 5. Adjust the sizes of each axis based on it's minimum reported size.\r
- // 6. Refit each axis\r
- // 7. Position each axis in the final location\r
- // 8. Tell the chart the final location of the chart area\r
- // 9. Tell any axes that overlay the chart area the positions of the chart area\r
-\r
- // Step 1\r
- var chartWidth = width - (2 * xPadding);\r
- var chartHeight = height - (2 * yPadding);\r
- var chartAreaWidth = chartWidth / 2; // min 50%\r
- var chartAreaHeight = chartHeight / 2; // min 50%\r
-\r
- // Step 2\r
- var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);\r
-\r
- // Step 3\r
- var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);\r
-\r
- // Step 4\r
- var maxChartAreaWidth = chartWidth;\r
- var maxChartAreaHeight = chartHeight;\r
- var minBoxSizes = [];\r
-\r
- helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);\r
-\r
- function getMinimumBoxSize(box) {\r
- var minSize;\r
- var isHorizontal = box.isHorizontal();\r
-\r
- if (isHorizontal) {\r
- minSize = box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);\r
- maxChartAreaHeight -= minSize.height;\r
- } else {\r
- minSize = box.update(verticalBoxWidth, chartAreaHeight);\r
- maxChartAreaWidth -= minSize.width;\r
- }\r
-\r
- minBoxSizes.push({\r
- horizontal: isHorizontal,\r
- minSize: minSize,\r
- box: box\r
- });\r
- }\r
-\r
- // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could\r
- // be if the axes are drawn at their minimum sizes.\r
-\r
- // Steps 5 & 6\r
- var totalLeftBoxesWidth = xPadding;\r
- var totalRightBoxesWidth = xPadding;\r
- var totalTopBoxesHeight = yPadding;\r
- var totalBottomBoxesHeight = yPadding;\r
-\r
- // Update, and calculate the left and right margins for the horizontal boxes\r
- helpers.each(leftBoxes.concat(rightBoxes), fitBox);\r
-\r
- helpers.each(leftBoxes, function(box) {\r
- totalLeftBoxesWidth += box.width;\r
- });\r
-\r
- helpers.each(rightBoxes, function(box) {\r
- totalRightBoxesWidth += box.width;\r
- });\r
-\r
- // Set the Left and Right margins for the horizontal boxes\r
- helpers.each(topBoxes.concat(bottomBoxes), fitBox);\r
-\r
- // Function to fit a box\r
- function fitBox(box) {\r
- var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {\r
- return minBoxSize.box === box;\r
- });\r
-\r
- if (minBoxSize) {\r
- if (box.isHorizontal()) {\r
- var scaleMargin = {\r
- left: totalLeftBoxesWidth,\r
- right: totalRightBoxesWidth,\r
- top: 0,\r
- bottom: 0\r
- };\r
-\r
- // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends\r
- // on the margin. Sometimes they need to increase in size slightly\r
- box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);\r
- } else {\r
- box.update(minBoxSize.minSize.width, maxChartAreaHeight);\r
- }\r
- }\r
- }\r
-\r
- // Figure out how much margin is on the top and bottom of the vertical boxes\r
- helpers.each(topBoxes, function(box) {\r
- totalTopBoxesHeight += box.height;\r
- });\r
-\r
- helpers.each(bottomBoxes, function(box) {\r
- totalBottomBoxesHeight += box.height;\r
- });\r
-\r
- // Let the left layout know the final margin\r
- helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);\r
-\r
- function finalFitVerticalBox(box) {\r
- var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {\r
- return minBoxSize.box === box;\r
- });\r
-\r
- var scaleMargin = {\r
- left: 0,\r
- right: 0,\r
- top: totalTopBoxesHeight,\r
- bottom: totalBottomBoxesHeight\r
- };\r
-\r
- if (minBoxSize) {\r
- box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);\r
- }\r
- }\r
-\r
- // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)\r
- totalLeftBoxesWidth = xPadding;\r
- totalRightBoxesWidth = xPadding;\r
- totalTopBoxesHeight = yPadding;\r
- totalBottomBoxesHeight = yPadding;\r
-\r
- helpers.each(leftBoxes, function(box) {\r
- totalLeftBoxesWidth += box.width;\r
- });\r
-\r
- helpers.each(rightBoxes, function(box) {\r
- totalRightBoxesWidth += box.width;\r
- });\r
-\r
- helpers.each(topBoxes, function(box) {\r
- totalTopBoxesHeight += box.height;\r
- });\r
- helpers.each(bottomBoxes, function(box) {\r
- totalBottomBoxesHeight += box.height;\r
- });\r
-\r
- // Figure out if our chart area changed. This would occur if the dataset layout label rotation\r
- // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do\r
- // without calling `fit` again\r
- var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;\r
- var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;\r
-\r
- if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {\r
- helpers.each(leftBoxes, function(box) {\r
- box.height = newMaxChartAreaHeight;\r
- });\r
-\r
- helpers.each(rightBoxes, function(box) {\r
- box.height = newMaxChartAreaHeight;\r
- });\r
-\r
- helpers.each(topBoxes, function(box) {\r
- if (!box.options.fullWidth) {\r
- box.width = newMaxChartAreaWidth;\r
- }\r
- });\r
-\r
- helpers.each(bottomBoxes, function(box) {\r
- if (!box.options.fullWidth) {\r
- box.width = newMaxChartAreaWidth;\r
- }\r
- });\r
-\r
- maxChartAreaHeight = newMaxChartAreaHeight;\r
- maxChartAreaWidth = newMaxChartAreaWidth;\r
- }\r
-\r
- // Step 7 - Position the boxes\r
- var left = xPadding;\r
- var top = yPadding;\r
- var right = 0;\r
- var bottom = 0;\r
-\r
- helpers.each(leftBoxes.concat(topBoxes), placeBox);\r
-\r
- // Account for chart width and height\r
- left += maxChartAreaWidth;\r
- top += maxChartAreaHeight;\r
-\r
- helpers.each(rightBoxes, placeBox);\r
- helpers.each(bottomBoxes, placeBox);\r
-\r
- function placeBox(box) {\r
- if (box.isHorizontal()) {\r
- box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;\r
- box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth;\r
- box.top = top;\r
- box.bottom = top + box.height;\r
-\r
- // Move to next point\r
- top = box.bottom;\r
-\r
- } else {\r
-\r
- box.left = left;\r
- box.right = left + box.width;\r
- box.top = totalTopBoxesHeight;\r
- box.bottom = totalTopBoxesHeight + maxChartAreaHeight;\r
-\r
- // Move to next point\r
- left = box.right;\r
- }\r
- }\r
-\r
- // Step 8\r
- chartInstance.chartArea = {\r
- left: totalLeftBoxesWidth,\r
- top: totalTopBoxesHeight,\r
- right: totalLeftBoxesWidth + maxChartAreaWidth,\r
- bottom: totalTopBoxesHeight + maxChartAreaHeight\r
- };\r
-\r
- // Step 9\r
- helpers.each(chartAreaBoxes, function(box) {\r
- box.left = chartInstance.chartArea.left;\r
- box.top = chartInstance.chartArea.top;\r
- box.right = chartInstance.chartArea.right;\r
- box.bottom = chartInstance.chartArea.bottom;\r
-\r
- box.update(maxChartAreaWidth, maxChartAreaHeight);\r
- });\r
- }\r
- };\r
-};\r
-
-},{}],28:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var noop = helpers.noop;\r
-\r
- Chart.defaults.global.legend = {\r
-\r
- display: true,\r
- position: 'top',\r
- fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)\r
- reverse: false,\r
-\r
- // a callback that will handle\r
- onClick: function(e, legendItem) {\r
- var index = legendItem.datasetIndex;\r
- var ci = this.chart;\r
- var meta = ci.getDatasetMeta(index);\r
-\r
- // See controller.isDatasetVisible comment\r
- meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;\r
-\r
- // We hid a dataset ... rerender the chart\r
- ci.update();\r
- },\r
-\r
- labels: {\r
- boxWidth: 40,\r
- padding: 10,\r
- // Generates labels shown in the legend\r
- // Valid properties to return:\r
- // text : text to display\r
- // fillStyle : fill of coloured box\r
- // strokeStyle: stroke of coloured box\r
- // hidden : if this legend item refers to a hidden item\r
- // lineCap : cap style for line\r
- // lineDash\r
- // lineDashOffset :\r
- // lineJoin :\r
- // lineWidth :\r
- generateLabels: function(chart) {\r
- var data = chart.data;\r
- return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {\r
- return {\r
- text: dataset.label,\r
- fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),\r
- hidden: !chart.isDatasetVisible(i),\r
- lineCap: dataset.borderCapStyle,\r
- lineDash: dataset.borderDash,\r
- lineDashOffset: dataset.borderDashOffset,\r
- lineJoin: dataset.borderJoinStyle,\r
- lineWidth: dataset.borderWidth,\r
- strokeStyle: dataset.borderColor,\r
-\r
- // Below is extra data used for toggling the datasets\r
- datasetIndex: i\r
- };\r
- }, this) : [];\r
- }\r
- }\r
- };\r
-\r
- Chart.Legend = Chart.Element.extend({\r
-\r
- initialize: function(config) {\r
- helpers.extend(this, config);\r
-\r
- // Contains hit boxes for each dataset (in dataset order)\r
- this.legendHitBoxes = [];\r
-\r
- // Are we in doughnut mode which has a different data type\r
- this.doughnutMode = false;\r
- },\r
-\r
- // These methods are ordered by lifecyle. Utilities then follow.\r
- // Any function defined here is inherited by all legend types.\r
- // Any function can be extended by the legend type\r
-\r
- beforeUpdate: noop,\r
- update: function(maxWidth, maxHeight, margins) {\r
- var me = this;\r
-\r
- // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r
- me.beforeUpdate();\r
-\r
- // Absorb the master measurements\r
- me.maxWidth = maxWidth;\r
- me.maxHeight = maxHeight;\r
- me.margins = margins;\r
-\r
- // Dimensions\r
- me.beforeSetDimensions();\r
- me.setDimensions();\r
- me.afterSetDimensions();\r
- // Labels\r
- me.beforeBuildLabels();\r
- me.buildLabels();\r
- me.afterBuildLabels();\r
-\r
- // Fit\r
- me.beforeFit();\r
- me.fit();\r
- me.afterFit();\r
- //\r
- me.afterUpdate();\r
-\r
- return me.minSize;\r
- },\r
- afterUpdate: noop,\r
-\r
- //\r
-\r
- beforeSetDimensions: noop,\r
- setDimensions: function() {\r
- var me = this;\r
- // Set the unconstrained dimension before label rotation\r
- if (me.isHorizontal()) {\r
- // Reset position before calculating rotation\r
- me.width = me.maxWidth;\r
- me.left = 0;\r
- me.right = me.width;\r
- } else {\r
- me.height = me.maxHeight;\r
-\r
- // Reset position before calculating rotation\r
- me.top = 0;\r
- me.bottom = me.height;\r
- }\r
-\r
- // Reset padding\r
- me.paddingLeft = 0;\r
- me.paddingTop = 0;\r
- me.paddingRight = 0;\r
- me.paddingBottom = 0;\r
-\r
- // Reset minSize\r
- me.minSize = {\r
- width: 0,\r
- height: 0\r
- };\r
- },\r
- afterSetDimensions: noop,\r
-\r
- //\r
-\r
- beforeBuildLabels: noop,\r
- buildLabels: function() {\r
- var me = this;\r
- me.legendItems = me.options.labels.generateLabels.call(me, me.chart);\r
- if(me.options.reverse){\r
- me.legendItems.reverse();\r
- }\r
- },\r
- afterBuildLabels: noop,\r
-\r
- //\r
-\r
- beforeFit: noop,\r
- fit: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var labelOpts = opts.labels;\r
- var display = opts.display;\r
-\r
- var ctx = me.ctx;\r
-\r
- var globalDefault = Chart.defaults.global,\r
- itemOrDefault = helpers.getValueOrDefault,\r
- fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\r
- fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\r
- fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\r
- labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\r
-\r
- // Reset hit boxes\r
- var hitboxes = me.legendHitBoxes = [];\r
-\r
- var minSize = me.minSize;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- if (isHorizontal) {\r
- minSize.width = me.maxWidth; // fill all the width\r
- minSize.height = display ? 10 : 0;\r
- } else {\r
- minSize.width = display ? 10 : 0;\r
- minSize.height = me.maxHeight; // fill all the height\r
- }\r
-\r
- // Increase sizes here\r
- if (display) {\r
- ctx.font = labelFont;\r
-\r
- if (isHorizontal) {\r
- // Labels\r
-\r
- // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one\r
- var lineWidths = me.lineWidths = [0];\r
- var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;\r
-\r
- ctx.textAlign = "left";\r
- ctx.textBaseline = 'top';\r
-\r
- helpers.each(me.legendItems, function(legendItem, i) {\r
- var width = labelOpts.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\r
- if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {\r
- totalHeight += fontSize + (labelOpts.padding);\r
- lineWidths[lineWidths.length] = me.left;\r
- }\r
-\r
- // Store the hitbox width and height here. Final position will be updated in `draw`\r
- hitboxes[i] = {\r
- left: 0,\r
- top: 0,\r
- width: width,\r
- height: fontSize\r
- };\r
-\r
- lineWidths[lineWidths.length - 1] += width + labelOpts.padding;\r
- });\r
-\r
- minSize.height += totalHeight;\r
-\r
- } else {\r
- var vPadding = labelOpts.padding;\r
- var columnWidths = me.columnWidths = [];\r
- var totalWidth = labelOpts.padding;\r
- var currentColWidth = 0;\r
- var currentColHeight = 0;\r
- var itemHeight = fontSize + vPadding;\r
-\r
- helpers.each(me.legendItems, function(legendItem, i) {\r
- var itemWidth = labelOpts.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\r
-\r
- // If too tall, go to new column\r
- if (currentColHeight + itemHeight > minSize.height) {\r
- totalWidth += currentColWidth + labelOpts.padding;\r
- columnWidths.push(currentColWidth); // previous column width\r
-\r
- currentColWidth = 0;\r
- currentColHeight = 0;\r
- }\r
-\r
- // Get max width\r
- currentColWidth = Math.max(currentColWidth, itemWidth);\r
- currentColHeight += itemHeight;\r
-\r
- // Store the hitbox width and height here. Final position will be updated in `draw`\r
- hitboxes[i] = {\r
- left: 0,\r
- top: 0,\r
- width: itemWidth,\r
- height: fontSize\r
- };\r
- });\r
-\r
- totalWidth += currentColWidth;\r
- columnWidths.push(currentColWidth);\r
- minSize.width += totalWidth;\r
- }\r
- }\r
-\r
- me.width = minSize.width;\r
- me.height = minSize.height;\r
- },\r
- afterFit: noop,\r
-\r
- // Shared Methods\r
- isHorizontal: function() {\r
- return this.options.position === "top" || this.options.position === "bottom";\r
- },\r
-\r
- // Actualy draw the legend on the canvas\r
- draw: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var labelOpts = opts.labels;\r
- var globalDefault = Chart.defaults.global,\r
- lineDefault = globalDefault.elements.line,\r
- legendWidth = me.width,\r
- legendHeight = me.height,\r
- lineWidths = me.lineWidths;\r
-\r
- if (opts.display) {\r
- var ctx = me.ctx,\r
- cursor,\r
- itemOrDefault = helpers.getValueOrDefault,\r
- fontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),\r
- fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\r
- fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\r
- fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\r
- labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\r
-\r
- // Canvas setup\r
- ctx.textAlign = "left";\r
- ctx.textBaseline = 'top';\r
- ctx.lineWidth = 0.5;\r
- ctx.strokeStyle = fontColor; // for strikethrough effect\r
- ctx.fillStyle = fontColor; // render in correct colour\r
- ctx.font = labelFont;\r
-\r
- var boxWidth = labelOpts.boxWidth,\r
- hitboxes = me.legendHitBoxes;\r
-\r
- // current position\r
- var drawLegendBox = function(x, y, legendItem) {\r
- // Set the ctx for the box\r
- ctx.save();\r
-\r
- ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);\r
- ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);\r
- ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);\r
- ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);\r
- ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);\r
- ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);\r
-\r
- if (ctx.setLineDash) {\r
- // IE 9 and 10 do not support line dash\r
- ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));\r
- }\r
-\r
- // Draw the box\r
- ctx.strokeRect(x, y, boxWidth, fontSize);\r
- ctx.fillRect(x, y, boxWidth, fontSize);\r
-\r
- ctx.restore();\r
- };\r
- var fillText = function(x, y, legendItem, textWidth) {\r
- ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);\r
-\r
- if (legendItem.hidden) {\r
- // Strikethrough the text if hidden\r
- ctx.beginPath();\r
- ctx.lineWidth = 2;\r
- ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));\r
- ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));\r
- ctx.stroke();\r
- }\r
- };\r
-\r
- // Horizontal\r
- var isHorizontal = me.isHorizontal();\r
- if (isHorizontal) {\r
- cursor = {\r
- x: me.left + ((legendWidth - lineWidths[0]) / 2),\r
- y: me.top + labelOpts.padding,\r
- line: 0\r
- };\r
- } else {\r
- cursor = {\r
- x: me.left + labelOpts.padding,\r
- y: me.top,\r
- line: 0\r
- };\r
- }\r
-\r
- var itemHeight = fontSize + labelOpts.padding;\r
- helpers.each(me.legendItems, function(legendItem, i) {\r
- var textWidth = ctx.measureText(legendItem.text).width,\r
- width = boxWidth + (fontSize / 2) + textWidth,\r
- x = cursor.x,\r
- y = cursor.y;\r
-\r
- if (isHorizontal) {\r
- if (x + width >= legendWidth) {\r
- y = cursor.y += fontSize + (labelOpts.padding);\r
- cursor.line++;\r
- x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);\r
- }\r
- } else {\r
- if (y + itemHeight > me.bottom) {\r
- x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;\r
- y = cursor.y = me.top;\r
- cursor.line++;\r
- }\r
- }\r
- \r
-\r
- drawLegendBox(x, y, legendItem);\r
-\r
- hitboxes[i].left = x;\r
- hitboxes[i].top = y;\r
-\r
- // Fill the actual label\r
- fillText(x, y, legendItem, textWidth);\r
-\r
- if (isHorizontal) {\r
- cursor.x += width + (labelOpts.padding);\r
- } else {\r
- cursor.y += itemHeight;\r
- }\r
- \r
- });\r
- }\r
- },\r
-\r
- // Handle an event\r
- handleEvent: function(e) {\r
- var me = this;\r
- var position = helpers.getRelativePosition(e, me.chart.chart),\r
- x = position.x,\r
- y = position.y,\r
- opts = me.options;\r
-\r
- if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {\r
- // See if we are touching one of the dataset boxes\r
- var lh = me.legendHitBoxes;\r
- for (var i = 0; i < lh.length; ++i) {\r
- var hitBox = lh[i];\r
-\r
- if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {\r
- // Touching an element\r
- if (opts.onClick) {\r
- opts.onClick.call(me, e, me.legendItems[i]);\r
- }\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- });\r
-\r
- // Register the legend plugin\r
- Chart.plugins.register({\r
- beforeInit: function(chartInstance) {\r
- var opts = chartInstance.options;\r
- var legendOpts = opts.legend;\r
-\r
- if (legendOpts) {\r
- chartInstance.legend = new Chart.Legend({\r
- ctx: chartInstance.chart.ctx,\r
- options: legendOpts,\r
- chart: chartInstance\r
- });\r
-\r
- Chart.layoutService.addBox(chartInstance, chartInstance.legend);\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],29:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var noop = Chart.helpers.noop;\r
-\r
- /**\r
- * The plugin service singleton\r
- * @namespace Chart.plugins\r
- * @since 2.1.0\r
- */\r
- Chart.plugins = {\r
- _plugins: [],\r
-\r
- /**\r
- * Registers the given plugin(s) if not already registered.\r
- * @param {Array|Object} plugins plugin instance(s).\r
- */\r
- register: function(plugins) {\r
- var p = this._plugins;\r
- ([]).concat(plugins).forEach(function(plugin) {\r
- if (p.indexOf(plugin) === -1) {\r
- p.push(plugin);\r
- }\r
- });\r
- },\r
-\r
- /**\r
- * Unregisters the given plugin(s) only if registered.\r
- * @param {Array|Object} plugins plugin instance(s).\r
- */\r
- unregister: function(plugins) {\r
- var p = this._plugins;\r
- ([]).concat(plugins).forEach(function(plugin) {\r
- var idx = p.indexOf(plugin);\r
- if (idx !== -1) {\r
- p.splice(idx, 1);\r
- }\r
- });\r
- },\r
-\r
- /**\r
- * Remove all registered p^lugins.\r
- * @since 2.1.5\r
- */\r
- clear: function() {\r
- this._plugins = [];\r
- },\r
-\r
- /**\r
- * Returns the number of registered plugins?\r
- * @returns {Number}\r
- * @since 2.1.5\r
- */\r
- count: function() {\r
- return this._plugins.length;\r
- },\r
-\r
- /**\r
- * Returns all registered plugin intances.\r
- * @returns {Array} array of plugin objects.\r
- * @since 2.1.5\r
- */\r
- getAll: function() {\r
- return this._plugins;\r
- },\r
-\r
- /**\r
- * Calls registered plugins on the specified extension, with the given args. This\r
- * method immediately returns as soon as a plugin explicitly returns false. The\r
- * returned value can be used, for instance, to interrupt the current action.\r
- * @param {String} extension the name of the plugin method to call (e.g. 'beforeUpdate').\r
- * @param {Array} [args] extra arguments to apply to the extension call.\r
- * @returns {Boolean} false if any of the plugins return false, else returns true.\r
- */\r
- notify: function(extension, args) {\r
- var plugins = this._plugins;\r
- var ilen = plugins.length;\r
- var i, plugin;\r
-\r
- for (i=0; i<ilen; ++i) {\r
- plugin = plugins[i];\r
- if (typeof plugin[extension] === 'function') {\r
- if (plugin[extension].apply(plugin, args || []) === false) {\r
- return false;\r
- }\r
- }\r
- }\r
-\r
- return true;\r
- }\r
- };\r
-\r
- /**\r
- * Plugin extension methods.\r
- * @interface Chart.PluginBase\r
- * @since 2.1.0\r
- */\r
- Chart.PluginBase = Chart.Element.extend({\r
- // Called at start of chart init\r
- beforeInit: noop,\r
-\r
- // Called at end of chart init\r
- afterInit: noop,\r
-\r
- // Called at start of update\r
- beforeUpdate: noop,\r
-\r
- // Called at end of update\r
- afterUpdate: noop,\r
-\r
- // Called at start of draw\r
- beforeDraw: noop,\r
-\r
- // Called at end of draw\r
- afterDraw: noop,\r
-\r
- // Called during destroy\r
- destroy: noop\r
- });\r
-\r
- /**\r
- * Provided for backward compatibility, use Chart.plugins instead\r
- * @namespace Chart.pluginService\r
- * @deprecated since version 2.1.5\r
- * @todo remove me at version 3\r
- */\r
- Chart.pluginService = Chart.plugins;\r
-};\r
-
-},{}],30:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.scale = {\r
- display: true,\r
- position: "left",\r
-\r
- // grid line settings\r
- gridLines: {\r
- display: true,\r
- color: "rgba(0, 0, 0, 0.1)",\r
- lineWidth: 1,\r
- drawBorder: true,\r
- drawOnChartArea: true,\r
- drawTicks: true,\r
- tickMarkLength: 10,\r
- zeroLineWidth: 1,\r
- zeroLineColor: "rgba(0,0,0,0.25)",\r
- offsetGridLines: false\r
- },\r
-\r
- // scale label\r
- scaleLabel: {\r
- // actual label\r
- labelString: '',\r
-\r
- // display property\r
- display: false\r
- },\r
-\r
- // label settings\r
- ticks: {\r
- beginAtZero: false,\r
- minRotation: 0,\r
- maxRotation: 50,\r
- mirror: false,\r
- padding: 10,\r
- reverse: false,\r
- display: true,\r
- autoSkip: true,\r
- autoSkipPadding: 0,\r
- labelOffset: 0,\r
- // We pass through arrays to be rendered as multiline labels, we convert Others to strings here.\r
- callback: function(value) {\r
- return helpers.isArray(value) ? value : '' + value;\r
- }\r
- }\r
- };\r
-\r
- Chart.Scale = Chart.Element.extend({\r
-\r
- // These methods are ordered by lifecyle. Utilities then follow.\r
- // Any function defined here is inherited by all scale types.\r
- // Any function can be extended by the scale type\r
-\r
- beforeUpdate: function() {\r
- helpers.callCallback(this.options.beforeUpdate, [this]);\r
- },\r
- update: function(maxWidth, maxHeight, margins) {\r
- var me = this;\r
-\r
- // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r
- me.beforeUpdate();\r
-\r
- // Absorb the master measurements\r
- me.maxWidth = maxWidth;\r
- me.maxHeight = maxHeight;\r
- me.margins = helpers.extend({\r
- left: 0,\r
- right: 0,\r
- top: 0,\r
- bottom: 0\r
- }, margins);\r
-\r
- // Dimensions\r
- me.beforeSetDimensions();\r
- me.setDimensions();\r
- me.afterSetDimensions();\r
-\r
- // Data min/max\r
- me.beforeDataLimits();\r
- me.determineDataLimits();\r
- me.afterDataLimits();\r
-\r
- // Ticks\r
- me.beforeBuildTicks();\r
- me.buildTicks();\r
- me.afterBuildTicks();\r
-\r
- me.beforeTickToLabelConversion();\r
- me.convertTicksToLabels();\r
- me.afterTickToLabelConversion();\r
-\r
- // Tick Rotation\r
- me.beforeCalculateTickRotation();\r
- me.calculateTickRotation();\r
- me.afterCalculateTickRotation();\r
- // Fit\r
- me.beforeFit();\r
- me.fit();\r
- me.afterFit();\r
- //\r
- me.afterUpdate();\r
-\r
- return me.minSize;\r
-\r
- },\r
- afterUpdate: function() {\r
- helpers.callCallback(this.options.afterUpdate, [this]);\r
- },\r
-\r
- //\r
-\r
- beforeSetDimensions: function() {\r
- helpers.callCallback(this.options.beforeSetDimensions, [this]);\r
- },\r
- setDimensions: function() {\r
- var me = this;\r
- // Set the unconstrained dimension before label rotation\r
- if (me.isHorizontal()) {\r
- // Reset position before calculating rotation\r
- me.width = me.maxWidth;\r
- me.left = 0;\r
- me.right = me.width;\r
- } else {\r
- me.height = me.maxHeight;\r
-\r
- // Reset position before calculating rotation\r
- me.top = 0;\r
- me.bottom = me.height;\r
- }\r
-\r
- // Reset padding\r
- me.paddingLeft = 0;\r
- me.paddingTop = 0;\r
- me.paddingRight = 0;\r
- me.paddingBottom = 0;\r
- },\r
- afterSetDimensions: function() {\r
- helpers.callCallback(this.options.afterSetDimensions, [this]);\r
- },\r
-\r
- // Data limits\r
- beforeDataLimits: function() {\r
- helpers.callCallback(this.options.beforeDataLimits, [this]);\r
- },\r
- determineDataLimits: helpers.noop,\r
- afterDataLimits: function() {\r
- helpers.callCallback(this.options.afterDataLimits, [this]);\r
- },\r
-\r
- //\r
- beforeBuildTicks: function() {\r
- helpers.callCallback(this.options.beforeBuildTicks, [this]);\r
- },\r
- buildTicks: helpers.noop,\r
- afterBuildTicks: function() {\r
- helpers.callCallback(this.options.afterBuildTicks, [this]);\r
- },\r
-\r
- beforeTickToLabelConversion: function() {\r
- helpers.callCallback(this.options.beforeTickToLabelConversion, [this]);\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- // Convert ticks to strings\r
- me.ticks = me.ticks.map(function(numericalTick, index, ticks) {\r
- if (me.options.ticks.userCallback) {\r
- return me.options.ticks.userCallback(numericalTick, index, ticks);\r
- }\r
- return me.options.ticks.callback(numericalTick, index, ticks);\r
- },\r
- me);\r
- },\r
- afterTickToLabelConversion: function() {\r
- helpers.callCallback(this.options.afterTickToLabelConversion, [this]);\r
- },\r
-\r
- //\r
-\r
- beforeCalculateTickRotation: function() {\r
- helpers.callCallback(this.options.beforeCalculateTickRotation, [this]);\r
- },\r
- calculateTickRotation: function() {\r
- var me = this;\r
- var context = me.ctx;\r
- var globalDefaults = Chart.defaults.global;\r
- var optionTicks = me.options.ticks;\r
-\r
- //Get the width of each grid by calculating the difference\r
- //between x offsets between 0 and 1.\r
- var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
- context.font = tickLabelFont;\r
-\r
- var firstWidth = context.measureText(me.ticks[0]).width;\r
- var lastWidth = context.measureText(me.ticks[me.ticks.length - 1]).width;\r
- var firstRotated;\r
-\r
- me.labelRotation = optionTicks.minRotation || 0;\r
- me.paddingRight = 0;\r
- me.paddingLeft = 0;\r
-\r
- if (me.options.display) {\r
- if (me.isHorizontal()) {\r
- me.paddingRight = lastWidth / 2 + 3;\r
- me.paddingLeft = firstWidth / 2 + 3;\r
-\r
- if (!me.longestTextCache) {\r
- me.longestTextCache = {};\r
- }\r
- var originalLabelWidth = helpers.longestText(context, tickLabelFont, me.ticks, me.longestTextCache);\r
- var labelWidth = originalLabelWidth;\r
- var cosRotation;\r
- var sinRotation;\r
-\r
- // Allow 3 pixels x2 padding either side for label readability\r
- // only the index matters for a dataset scale, but we want a consistent interface between scales\r
- var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;\r
-\r
- //Max label rotation can be set or default to 90 - also act as a loop counter\r
- while (labelWidth > tickWidth && me.labelRotation < optionTicks.maxRotation) {\r
- cosRotation = Math.cos(helpers.toRadians(me.labelRotation));\r
- sinRotation = Math.sin(helpers.toRadians(me.labelRotation));\r
-\r
- firstRotated = cosRotation * firstWidth;\r
-\r
- // We're right aligning the text now.\r
- if (firstRotated + tickFontSize / 2 > me.yLabelWidth) {\r
- me.paddingLeft = firstRotated + tickFontSize / 2;\r
- }\r
-\r
- me.paddingRight = tickFontSize / 2;\r
-\r
- if (sinRotation * originalLabelWidth > me.maxHeight) {\r
- // go back one step\r
- me.labelRotation--;\r
- break;\r
- }\r
-\r
- me.labelRotation++;\r
- labelWidth = cosRotation * originalLabelWidth;\r
- }\r
- }\r
- }\r
-\r
- if (me.margins) {\r
- me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\r
- me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\r
- }\r
- },\r
- afterCalculateTickRotation: function() {\r
- helpers.callCallback(this.options.afterCalculateTickRotation, [this]);\r
- },\r
-\r
- //\r
-\r
- beforeFit: function() {\r
- helpers.callCallback(this.options.beforeFit, [this]);\r
- },\r
- fit: function() {\r
- var me = this;\r
- // Reset\r
- var minSize = me.minSize = {\r
- width: 0,\r
- height: 0\r
- };\r
-\r
- var opts = me.options;\r
- var globalDefaults = Chart.defaults.global;\r
- var tickOpts = opts.ticks;\r
- var scaleLabelOpts = opts.scaleLabel;\r
- var display = opts.display;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
-\r
- var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabelOpts.fontSize, globalDefaults.defaultFontSize);\r
- var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabelOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabelOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);\r
-\r
- var tickMarkLength = opts.gridLines.tickMarkLength;\r
-\r
- // Width\r
- if (isHorizontal) {\r
- // subtract the margins to line up with the chartArea if we are a full width scale\r
- minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;\r
- } else {\r
- minSize.width = display ? tickMarkLength : 0;\r
- }\r
-\r
- // height\r
- if (isHorizontal) {\r
- minSize.height = display ? tickMarkLength : 0;\r
- } else {\r
- minSize.height = me.maxHeight; // fill all the height\r
- }\r
-\r
- // Are we showing a title for the scale?\r
- if (scaleLabelOpts.display && display) {\r
- if (isHorizontal) {\r
- minSize.height += (scaleLabelFontSize * 1.5);\r
- } else {\r
- minSize.width += (scaleLabelFontSize * 1.5);\r
- }\r
- }\r
-\r
- if (tickOpts.display && display) {\r
- // Don't bother fitting the ticks if we are not showing them\r
- if (!me.longestTextCache) {\r
- me.longestTextCache = {};\r
- }\r
-\r
- var largestTextWidth = helpers.longestText(me.ctx, tickLabelFont, me.ticks, me.longestTextCache);\r
- var tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);\r
- var lineSpace = tickFontSize * 0.5;\r
-\r
- if (isHorizontal) {\r
- // A horizontal axis is more constrained by the height.\r
- me.longestLabelWidth = largestTextWidth;\r
-\r
- // TODO - improve this calculation\r
- var labelHeight = (Math.sin(helpers.toRadians(me.labelRotation)) * me.longestLabelWidth) + (tickFontSize * tallestLabelHeightInLines) + (lineSpace * tallestLabelHeightInLines);\r
-\r
- minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);\r
- me.ctx.font = tickLabelFont;\r
-\r
- var firstLabelWidth = me.ctx.measureText(me.ticks[0]).width;\r
- var lastLabelWidth = me.ctx.measureText(me.ticks[me.ticks.length - 1]).width;\r
-\r
- // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated\r
- // by the font height\r
- var cosRotation = Math.cos(helpers.toRadians(me.labelRotation));\r
- var sinRotation = Math.sin(helpers.toRadians(me.labelRotation));\r
- me.paddingLeft = me.labelRotation !== 0 ? (cosRotation * firstLabelWidth) + 3 : firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges\r
- me.paddingRight = me.labelRotation !== 0 ? (sinRotation * (tickFontSize / 2)) + 3 : lastLabelWidth / 2 + 3; // when rotated\r
- } else {\r
- // A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first\r
- var maxLabelWidth = me.maxWidth - minSize.width;\r
-\r
- // Account for padding\r
- var mirror = tickOpts.mirror;\r
- if (!mirror) {\r
- largestTextWidth += me.options.ticks.padding;\r
- } else {\r
- // If mirrored text is on the inside so don't expand\r
- largestTextWidth = 0;\r
- }\r
-\r
- if (largestTextWidth < maxLabelWidth) {\r
- // We don't need all the room\r
- minSize.width += largestTextWidth;\r
- } else {\r
- // Expand to max size\r
- minSize.width = me.maxWidth;\r
- }\r
-\r
- me.paddingTop = tickFontSize / 2;\r
- me.paddingBottom = tickFontSize / 2;\r
- }\r
- }\r
-\r
- if (me.margins) {\r
- me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\r
- me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);\r
- me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\r
- me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);\r
- }\r
-\r
- me.width = minSize.width;\r
- me.height = minSize.height;\r
-\r
- },\r
- afterFit: function() {\r
- helpers.callCallback(this.options.afterFit, [this]);\r
- },\r
-\r
- // Shared Methods\r
- isHorizontal: function() {\r
- return this.options.position === "top" || this.options.position === "bottom";\r
- },\r
- isFullWidth: function() {\r
- return (this.options.fullWidth);\r
- },\r
-\r
- // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not\r
- getRightValue: function getRightValue(rawValue) {\r
- // Null and undefined values first\r
- if (rawValue === null || typeof(rawValue) === 'undefined') {\r
- return NaN;\r
- }\r
- // isNaN(object) returns true, so make sure NaN is checking for a number\r
- if (typeof(rawValue) === 'number' && isNaN(rawValue)) {\r
- return NaN;\r
- }\r
- // If it is in fact an object, dive in one more level\r
- if (typeof(rawValue) === "object") {\r
- if ((rawValue instanceof Date) || (rawValue.isValid)) {\r
- return rawValue;\r
- } else {\r
- return getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);\r
- }\r
- }\r
-\r
- // Value is good, return it\r
- return rawValue;\r
- },\r
-\r
- // Used to get the value to display in the tooltip for the data at the given index\r
- // function getLabelForIndex(index, datasetIndex)\r
- getLabelForIndex: helpers.noop,\r
-\r
- // Used to get data value locations. Value can either be an index or a numerical value\r
- getPixelForValue: helpers.noop,\r
-\r
- // Used to get the data value from a given pixel. This is the inverse of getPixelForValue\r
- getValueForPixel: helpers.noop,\r
-\r
- // Used for tick location, should\r
- getPixelForTick: function(index, includeOffset) {\r
- var me = this;\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\r
- var pixel = (tickWidth * index) + me.paddingLeft;\r
-\r
- if (includeOffset) {\r
- pixel += tickWidth / 2;\r
- }\r
-\r
- var finalVal = me.left + Math.round(pixel);\r
- finalVal += me.isFullWidth() ? me.margins.left : 0;\r
- return finalVal;\r
- } else {\r
- var innerHeight = me.height - (me.paddingTop + me.paddingBottom);\r
- return me.top + (index * (innerHeight / (me.ticks.length - 1)));\r
- }\r
- },\r
-\r
- // Utility for getting the pixel location of a percentage of scale\r
- getPixelForDecimal: function(decimal /*, includeOffset*/ ) {\r
- var me = this;\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var valueOffset = (innerWidth * decimal) + me.paddingLeft;\r
-\r
- var finalVal = me.left + Math.round(valueOffset);\r
- finalVal += me.isFullWidth() ? me.margins.left : 0;\r
- return finalVal;\r
- } else {\r
- return me.top + (decimal * me.height);\r
- }\r
- },\r
-\r
- getBasePixel: function() {\r
- var me = this;\r
- var min = me.min;\r
- var max = me.max;\r
-\r
- return me.getPixelForValue(\r
- me.beginAtZero? 0:\r
- min < 0 && max < 0? max :\r
- min > 0 && max > 0? min :\r
- 0);\r
- },\r
-\r
- // Actualy draw the scale on the canvas\r
- // @param {rectangle} chartArea : the area of the chart to draw full grid lines on\r
- draw: function(chartArea) {\r
- var me = this;\r
- var options = me.options;\r
- if (!options.display) {\r
- return;\r
- }\r
-\r
- var context = me.ctx;\r
- var globalDefaults = Chart.defaults.global;\r
- var optionTicks = options.ticks;\r
- var gridLines = options.gridLines;\r
- var scaleLabel = options.scaleLabel;\r
-\r
- var isRotated = me.labelRotation !== 0;\r
- var skipRatio;\r
- var useAutoskipper = optionTicks.autoSkip;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- // figure out the maximum number of gridlines to show\r
- var maxTicks;\r
- if (optionTicks.maxTicksLimit) {\r
- maxTicks = optionTicks.maxTicksLimit;\r
- }\r
-\r
- var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);\r
- var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
- var tl = gridLines.tickMarkLength;\r
-\r
- var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);\r
- var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize);\r
- var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle);\r
- var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily);\r
- var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);\r
-\r
- var labelRotationRadians = helpers.toRadians(me.labelRotation);\r
- var cosRotation = Math.cos(labelRotationRadians);\r
- var sinRotation = Math.sin(labelRotationRadians);\r
- var longestRotatedLabel = me.longestLabelWidth * cosRotation;\r
- var rotatedLabelHeight = tickFontSize * sinRotation;\r
-\r
- // Make sure we draw text in the correct color and font\r
- context.fillStyle = tickFontColor;\r
-\r
- var itemsToDraw = [];\r
-\r
- if (isHorizontal) {\r
- skipRatio = false;\r
-\r
- // Only calculate the skip ratio with the half width of longestRotateLabel if we got an actual rotation\r
- // See #2584\r
- if (isRotated) {\r
- longestRotatedLabel /= 2;\r
- }\r
-\r
- if ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {\r
- skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));\r
- }\r
-\r
- // if they defined a max number of optionTicks,\r
- // increase skipRatio until that number is met\r
- if (maxTicks && me.ticks.length > maxTicks) {\r
- while (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {\r
- if (!skipRatio) {\r
- skipRatio = 1;\r
- }\r
- skipRatio += 1;\r
- }\r
- }\r
-\r
- if (!useAutoskipper) {\r
- skipRatio = false;\r
- }\r
- }\r
-\r
-\r
- var xTickStart = options.position === "right" ? me.left : me.right - tl;\r
- var xTickEnd = options.position === "right" ? me.left + tl : me.right;\r
- var yTickStart = options.position === "bottom" ? me.top : me.bottom - tl;\r
- var yTickEnd = options.position === "bottom" ? me.top + tl : me.bottom;\r
-\r
- helpers.each(me.ticks, function(label, index) {\r
- // If the callback returned a null or undefined value, do not draw this line\r
- if (label === undefined || label === null) {\r
- return;\r
- }\r
-\r
- var isLastTick = me.ticks.length === index + 1;\r
-\r
- // Since we always show the last tick,we need may need to hide the last shown one before\r
- var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);\r
- if (shouldSkip && !isLastTick || (label === undefined || label === null)) {\r
- return;\r
- }\r
-\r
- var lineWidth, lineColor;\r
- if (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {\r
- // Draw the first index specially\r
- lineWidth = gridLines.zeroLineWidth;\r
- lineColor = gridLines.zeroLineColor;\r
- } else {\r
- lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);\r
- lineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);\r
- }\r
-\r
- // Common properties\r
- var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;\r
- var textAlign, textBaseline = 'middle';\r
-\r
- if (isHorizontal) {\r
- if (!isRotated) {\r
- textBaseline = options.position === 'top' ? 'bottom' : 'top';\r
- }\r
-\r
- textAlign = isRotated ? 'right' : 'center';\r
-\r
- var xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines\r
- labelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)\r
- labelY = (isRotated) ? me.top + 12 : options.position === 'top' ? me.bottom - tl : me.top + tl;\r
-\r
- tx1 = tx2 = x1 = x2 = xLineValue;\r
- ty1 = yTickStart;\r
- ty2 = yTickEnd;\r
- y1 = chartArea.top;\r
- y2 = chartArea.bottom;\r
- } else {\r
- if (options.position === 'left') {\r
- if (optionTicks.mirror) {\r
- labelX = me.right + optionTicks.padding;\r
- textAlign = 'left';\r
- } else {\r
- labelX = me.right - optionTicks.padding;\r
- textAlign = 'right';\r
- }\r
- } else {\r
- // right side\r
- if (optionTicks.mirror) {\r
- labelX = me.left - optionTicks.padding;\r
- textAlign = 'right';\r
- } else {\r
- labelX = me.left + optionTicks.padding;\r
- textAlign = 'left';\r
- }\r
- }\r
-\r
- var yLineValue = me.getPixelForTick(index); // xvalues for grid lines\r
- yLineValue += helpers.aliasPixel(lineWidth);\r
- labelY = me.getPixelForTick(index, gridLines.offsetGridLines);\r
-\r
- tx1 = xTickStart;\r
- tx2 = xTickEnd;\r
- x1 = chartArea.left;\r
- x2 = chartArea.right;\r
- ty1 = ty2 = y1 = y2 = yLineValue;\r
- }\r
-\r
- itemsToDraw.push({\r
- tx1: tx1,\r
- ty1: ty1,\r
- tx2: tx2,\r
- ty2: ty2,\r
- x1: x1,\r
- y1: y1,\r
- x2: x2,\r
- y2: y2,\r
- labelX: labelX,\r
- labelY: labelY,\r
- glWidth: lineWidth,\r
- glColor: lineColor,\r
- rotation: -1 * labelRotationRadians,\r
- label: label,\r
- textBaseline: textBaseline,\r
- textAlign: textAlign\r
- });\r
- });\r
-\r
- // Draw all of the tick labels, tick marks, and grid lines at the correct places\r
- helpers.each(itemsToDraw, function(itemToDraw) {\r
- if (gridLines.display) {\r
- context.lineWidth = itemToDraw.glWidth;\r
- context.strokeStyle = itemToDraw.glColor;\r
-\r
- context.beginPath();\r
-\r
- if (gridLines.drawTicks) {\r
- context.moveTo(itemToDraw.tx1, itemToDraw.ty1);\r
- context.lineTo(itemToDraw.tx2, itemToDraw.ty2);\r
- }\r
-\r
- if (gridLines.drawOnChartArea) {\r
- context.moveTo(itemToDraw.x1, itemToDraw.y1);\r
- context.lineTo(itemToDraw.x2, itemToDraw.y2);\r
- }\r
-\r
- context.stroke();\r
- }\r
-\r
- if (optionTicks.display) {\r
- context.save();\r
- context.translate(itemToDraw.labelX, itemToDraw.labelY);\r
- context.rotate(itemToDraw.rotation);\r
- context.font = tickLabelFont;\r
- context.textBaseline = itemToDraw.textBaseline;\r
- context.textAlign = itemToDraw.textAlign;\r
-\r
- var label = itemToDraw.label;\r
- if (helpers.isArray(label)) {\r
- for (var i = 0, y = 0; i < label.length; ++i) {\r
- // We just make sure the multiline element is a string here..\r
- context.fillText('' + label[i], 0, y);\r
- // apply same lineSpacing as calculated @ L#320\r
- y += (tickFontSize * 1.5);\r
- }\r
- } else {\r
- context.fillText(label, 0, 0);\r
- }\r
- context.restore();\r
- }\r
- });\r
-\r
- if (scaleLabel.display) {\r
- // Draw the scale label\r
- var scaleLabelX;\r
- var scaleLabelY;\r
- var rotation = 0;\r
-\r
- if (isHorizontal) {\r
- scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width\r
- scaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFontSize / 2) : me.top + (scaleLabelFontSize / 2);\r
- } else {\r
- var isLeft = options.position === 'left';\r
- scaleLabelX = isLeft ? me.left + (scaleLabelFontSize / 2) : me.right - (scaleLabelFontSize / 2);\r
- scaleLabelY = me.top + ((me.bottom - me.top) / 2);\r
- rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;\r
- }\r
- \r
- context.save();\r
- context.translate(scaleLabelX, scaleLabelY);\r
- context.rotate(rotation);\r
- context.textAlign = 'center';\r
- context.textBaseline = 'middle';\r
- context.fillStyle = scaleLabelFontColor; // render in correct colour\r
- context.font = scaleLabelFont;\r
- context.fillText(scaleLabel.labelString, 0, 0);\r
- context.restore();\r
- }\r
-\r
- if (gridLines.drawBorder) {\r
- // Draw the line at the edge of the axis\r
- context.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);\r
- context.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);\r
- var x1 = me.left,\r
- x2 = me.right,\r
- y1 = me.top,\r
- y2 = me.bottom;\r
-\r
- var aliasPixel = helpers.aliasPixel(context.lineWidth);\r
- if (isHorizontal) {\r
- y1 = y2 = options.position === 'top' ? me.bottom : me.top;\r
- y1 += aliasPixel;\r
- y2 += aliasPixel;\r
- } else {\r
- x1 = x2 = options.position === 'left' ? me.right : me.left;\r
- x1 += aliasPixel;\r
- x2 += aliasPixel;\r
- }\r
-\r
- context.beginPath();\r
- context.moveTo(x1, y1);\r
- context.lineTo(x2, y2);\r
- context.stroke();\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],31:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.scaleService = {\r
- // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then\r
- // use the new chart options to grab the correct scale\r
- constructors: {},\r
- // Use a registration function so that we can move to an ES6 map when we no longer need to support\r
- // old browsers\r
-\r
- // Scale config defaults\r
- defaults: {},\r
- registerScaleType: function(type, scaleConstructor, defaults) {\r
- this.constructors[type] = scaleConstructor;\r
- this.defaults[type] = helpers.clone(defaults);\r
- },\r
- getScaleConstructor: function(type) {\r
- return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;\r
- },\r
- getScaleDefaults: function(type) {\r
- // Return the scale defaults merged with the global settings so that we always use the latest ones\r
- return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};\r
- },\r
- updateScaleDefaults: function(type, additions) {\r
- var defaults = this.defaults;\r
- if (defaults.hasOwnProperty(type)) {\r
- defaults[type] = helpers.extend(defaults[type], additions);\r
- }\r
- },\r
- addScalesToLayout: function(chartInstance) {\r
- // Adds each scale to the chart.boxes array to be sized accordingly\r
- helpers.each(chartInstance.scales, function(scale) {\r
- Chart.layoutService.addBox(chartInstance, scale);\r
- });\r
- }\r
- };\r
-};
-},{}],32:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.global.title = {\r
- display: false,\r
- position: 'top',\r
- fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)\r
-\r
- fontStyle: 'bold',\r
- padding: 10,\r
-\r
- // actual title\r
- text: ''\r
- };\r
-\r
- var noop = helpers.noop;\r
- Chart.Title = Chart.Element.extend({\r
-\r
- initialize: function(config) {\r
- var me = this;\r
- helpers.extend(me, config);\r
- me.options = helpers.configMerge(Chart.defaults.global.title, config.options);\r
-\r
- // Contains hit boxes for each dataset (in dataset order)\r
- me.legendHitBoxes = [];\r
- },\r
-\r
- // These methods are ordered by lifecyle. Utilities then follow.\r
-\r
- beforeUpdate: function () {\r
- var chartOpts = this.chart.options;\r
- if (chartOpts && chartOpts.title) {\r
- this.options = helpers.configMerge(Chart.defaults.global.title, chartOpts.title);\r
- }\r
- },\r
- update: function(maxWidth, maxHeight, margins) {\r
- var me = this;\r
-\r
- // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r
- me.beforeUpdate();\r
-\r
- // Absorb the master measurements\r
- me.maxWidth = maxWidth;\r
- me.maxHeight = maxHeight;\r
- me.margins = margins;\r
-\r
- // Dimensions\r
- me.beforeSetDimensions();\r
- me.setDimensions();\r
- me.afterSetDimensions();\r
- // Labels\r
- me.beforeBuildLabels();\r
- me.buildLabels();\r
- me.afterBuildLabels();\r
-\r
- // Fit\r
- me.beforeFit();\r
- me.fit();\r
- me.afterFit();\r
- //\r
- me.afterUpdate();\r
-\r
- return me.minSize;\r
-\r
- },\r
- afterUpdate: noop,\r
-\r
- //\r
-\r
- beforeSetDimensions: noop,\r
- setDimensions: function() {\r
- var me = this;\r
- // Set the unconstrained dimension before label rotation\r
- if (me.isHorizontal()) {\r
- // Reset position before calculating rotation\r
- me.width = me.maxWidth;\r
- me.left = 0;\r
- me.right = me.width;\r
- } else {\r
- me.height = me.maxHeight;\r
-\r
- // Reset position before calculating rotation\r
- me.top = 0;\r
- me.bottom = me.height;\r
- }\r
-\r
- // Reset padding\r
- me.paddingLeft = 0;\r
- me.paddingTop = 0;\r
- me.paddingRight = 0;\r
- me.paddingBottom = 0;\r
-\r
- // Reset minSize\r
- me.minSize = {\r
- width: 0,\r
- height: 0\r
- };\r
- },\r
- afterSetDimensions: noop,\r
-\r
- //\r
-\r
- beforeBuildLabels: noop,\r
- buildLabels: noop,\r
- afterBuildLabels: noop,\r
-\r
- //\r
-\r
- beforeFit: noop,\r
- fit: function() {\r
-\r
- var me = this,\r
- ctx = me.ctx,\r
- valueOrDefault = helpers.getValueOrDefault,\r
- opts = me.options,\r
- globalDefaults = Chart.defaults.global,\r
- display = opts.display,\r
- fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\r
- minSize = me.minSize;\r
-\r
- if (me.isHorizontal()) {\r
- minSize.width = me.maxWidth; // fill all the width\r
- minSize.height = display ? fontSize + (opts.padding * 2) : 0;\r
- } else {\r
- minSize.width = display ? fontSize + (opts.padding * 2) : 0;\r
- minSize.height = me.maxHeight; // fill all the height\r
- }\r
-\r
- me.width = minSize.width;\r
- me.height = minSize.height;\r
-\r
- },\r
- afterFit: noop,\r
-\r
- // Shared Methods\r
- isHorizontal: function() {\r
- var pos = this.options.position;\r
- return pos === "top" || pos === "bottom";\r
- },\r
-\r
- // Actualy draw the title block on the canvas\r
- draw: function() {\r
- var me = this,\r
- ctx = me.ctx,\r
- valueOrDefault = helpers.getValueOrDefault,\r
- opts = me.options,\r
- globalDefaults = Chart.defaults.global;\r
-\r
- if (opts.display) {\r
- var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\r
- fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),\r
- fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),\r
- titleFont = helpers.fontString(fontSize, fontStyle, fontFamily),\r
- rotation = 0,\r
- titleX,\r
- titleY,\r
- top = me.top,\r
- left = me.left,\r
- bottom = me.bottom,\r
- right = me.right;\r
-\r
- ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour\r
- ctx.font = titleFont;\r
-\r
- // Horizontal\r
- if (me.isHorizontal()) {\r
- titleX = left + ((right - left) / 2); // midpoint of the width\r
- titleY = top + ((bottom - top) / 2); // midpoint of the height\r
- } else {\r
- titleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);\r
- titleY = top + ((bottom - top) / 2);\r
- rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);\r
- }\r
-\r
- ctx.save();\r
- ctx.translate(titleX, titleY);\r
- ctx.rotate(rotation);\r
- ctx.textAlign = 'center';\r
- ctx.textBaseline = 'middle';\r
- ctx.fillText(opts.text, 0, 0);\r
- ctx.restore();\r
- }\r
- }\r
- });\r
-\r
- // Register the title plugin\r
- Chart.plugins.register({\r
- beforeInit: function(chartInstance) {\r
- var opts = chartInstance.options;\r
- var titleOpts = opts.title;\r
-\r
- if (titleOpts) {\r
- chartInstance.titleBlock = new Chart.Title({\r
- ctx: chartInstance.chart.ctx,\r
- options: titleOpts,\r
- chart: chartInstance\r
- });\r
-\r
- Chart.layoutService.addBox(chartInstance, chartInstance.titleBlock);\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],33:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.global.tooltips = {\r
- enabled: true,\r
- custom: null,\r
- mode: 'single',\r
- backgroundColor: "rgba(0,0,0,0.8)",\r
- titleFontStyle: "bold",\r
- titleSpacing: 2,\r
- titleMarginBottom: 6,\r
- titleFontColor: "#fff",\r
- titleAlign: "left",\r
- bodySpacing: 2,\r
- bodyFontColor: "#fff",\r
- bodyAlign: "left",\r
- footerFontStyle: "bold",\r
- footerSpacing: 2,\r
- footerMarginTop: 6,\r
- footerFontColor: "#fff",\r
- footerAlign: "left",\r
- yPadding: 6,\r
- xPadding: 6,\r
- yAlign : 'center',\r
- xAlign : 'center',\r
- caretSize: 5,\r
- cornerRadius: 6,\r
- multiKeyBackground: '#fff',\r
- callbacks: {\r
- // Args are: (tooltipItems, data)\r
- beforeTitle: helpers.noop,\r
- title: function(tooltipItems, data) {\r
- // Pick first xLabel for now\r
- var title = '';\r
- var labels = data.labels;\r
- var labelCount = labels ? labels.length : 0;\r
-\r
- if (tooltipItems.length > 0) {\r
- var item = tooltipItems[0];\r
-\r
- if (item.xLabel) {\r
- title = item.xLabel;\r
- } else if (labelCount > 0 && item.index < labelCount) {\r
- title = labels[item.index];\r
- }\r
- }\r
-\r
- return title;\r
- },\r
- afterTitle: helpers.noop,\r
-\r
- // Args are: (tooltipItems, data)\r
- beforeBody: helpers.noop,\r
-\r
- // Args are: (tooltipItem, data)\r
- beforeLabel: helpers.noop,\r
- label: function(tooltipItem, data) {\r
- var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
- return datasetLabel + ': ' + tooltipItem.yLabel;\r
- },\r
- labelColor: function(tooltipItem, chartInstance) {\r
- var meta = chartInstance.getDatasetMeta(tooltipItem.datasetIndex);\r
- var activeElement = meta.data[tooltipItem.index];\r
- var view = activeElement._view;\r
- return {\r
- borderColor: view.borderColor,\r
- backgroundColor: view.backgroundColor\r
- };\r
- },\r
- afterLabel: helpers.noop,\r
-\r
- // Args are: (tooltipItems, data)\r
- afterBody: helpers.noop,\r
-\r
- // Args are: (tooltipItems, data)\r
- beforeFooter: helpers.noop,\r
- footer: helpers.noop,\r
- afterFooter: helpers.noop\r
- }\r
- };\r
-\r
- // Helper to push or concat based on if the 2nd parameter is an array or not\r
- function pushOrConcat(base, toPush) {\r
- if (toPush) {\r
- if (helpers.isArray(toPush)) {\r
- //base = base.concat(toPush);\r
- Array.prototype.push.apply(base, toPush);\r
- } else {\r
- base.push(toPush);\r
- }\r
- }\r
-\r
- return base;\r
- }\r
-\r
- function getAveragePosition(elements) {\r
- if (!elements.length) {\r
- return false;\r
- }\r
-\r
- var i, len;\r
- var xPositions = [];\r
- var yPositions = [];\r
-\r
- for (i = 0, len = elements.length; i < len; ++i) {\r
- var el = elements[i];\r
- if (el && el.hasValue()){\r
- var pos = el.tooltipPosition();\r
- xPositions.push(pos.x);\r
- yPositions.push(pos.y);\r
- }\r
- }\r
-\r
- var x = 0,\r
- y = 0;\r
- for (i = 0, len - xPositions.length; i < len; ++i) {\r
- x += xPositions[i];\r
- y += yPositions[i];\r
- }\r
-\r
- return {\r
- x: Math.round(x / xPositions.length),\r
- y: Math.round(y / xPositions.length)\r
- };\r
- }\r
-\r
- // Private helper to create a tooltip iteam model\r
- // @param element : the chart element (point, arc, bar) to create the tooltip item for\r
- // @return : new tooltip item\r
- function createTooltipItem(element) {\r
- var xScale = element._xScale;\r
- var yScale = element._yScale || element._scale; // handle radar || polarArea charts\r
- var index = element._index,\r
- datasetIndex = element._datasetIndex;\r
-\r
- return {\r
- xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',\r
- yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',\r
- index: index,\r
- datasetIndex: datasetIndex\r
- };\r
- }\r
-\r
- Chart.Tooltip = Chart.Element.extend({\r
- initialize: function() {\r
- var me = this;\r
- var globalDefaults = Chart.defaults.global;\r
- var tooltipOpts = me._options;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
-\r
- helpers.extend(me, {\r
- _model: {\r
- // Positioning\r
- xPadding: tooltipOpts.xPadding,\r
- yPadding: tooltipOpts.yPadding,\r
- xAlign : tooltipOpts.yAlign,\r
- yAlign : tooltipOpts.xAlign,\r
-\r
- // Body\r
- bodyFontColor: tooltipOpts.bodyFontColor,\r
- _bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),\r
- _bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),\r
- _bodyAlign: tooltipOpts.bodyAlign,\r
- bodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),\r
- bodySpacing: tooltipOpts.bodySpacing,\r
-\r
- // Title\r
- titleFontColor: tooltipOpts.titleFontColor,\r
- _titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),\r
- _titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),\r
- titleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),\r
- _titleAlign: tooltipOpts.titleAlign,\r
- titleSpacing: tooltipOpts.titleSpacing,\r
- titleMarginBottom: tooltipOpts.titleMarginBottom,\r
-\r
- // Footer\r
- footerFontColor: tooltipOpts.footerFontColor,\r
- _footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),\r
- _footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),\r
- footerFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),\r
- _footerAlign: tooltipOpts.footerAlign,\r
- footerSpacing: tooltipOpts.footerSpacing,\r
- footerMarginTop: tooltipOpts.footerMarginTop,\r
-\r
- // Appearance\r
- caretSize: tooltipOpts.caretSize,\r
- cornerRadius: tooltipOpts.cornerRadius,\r
- backgroundColor: tooltipOpts.backgroundColor,\r
- opacity: 0,\r
- legendColorBackground: tooltipOpts.multiKeyBackground\r
- }\r
- });\r
- },\r
-\r
- // Get the title\r
- // Args are: (tooltipItem, data)\r
- getTitle: function() {\r
- var me = this;\r
- var opts = me._options;\r
- var callbacks = opts.callbacks;\r
-\r
- var beforeTitle = callbacks.beforeTitle.apply(me, arguments),\r
- title = callbacks.title.apply(me, arguments),\r
- afterTitle = callbacks.afterTitle.apply(me, arguments);\r
-\r
- var lines = [];\r
- lines = pushOrConcat(lines, beforeTitle);\r
- lines = pushOrConcat(lines, title);\r
- lines = pushOrConcat(lines, afterTitle);\r
-\r
- return lines;\r
- },\r
-\r
- // Args are: (tooltipItem, data)\r
- getBeforeBody: function() {\r
- var lines = this._options.callbacks.beforeBody.apply(this, arguments);\r
- return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\r
- },\r
-\r
- // Args are: (tooltipItem, data)\r
- getBody: function(tooltipItems, data) {\r
- var me = this;\r
- var callbacks = me._options.callbacks;\r
- var bodyItems = [];\r
-\r
- helpers.each(tooltipItems, function(tooltipItem) {\r
- var bodyItem = {\r
- before: [],\r
- lines: [],\r
- after: []\r
- };\r
- pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));\r
- pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));\r
- pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));\r
-\r
- bodyItems.push(bodyItem);\r
- });\r
-\r
- return bodyItems;\r
- },\r
-\r
- // Args are: (tooltipItem, data)\r
- getAfterBody: function() {\r
- var lines = this._options.callbacks.afterBody.apply(this, arguments);\r
- return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\r
- },\r
-\r
- // Get the footer and beforeFooter and afterFooter lines\r
- // Args are: (tooltipItem, data)\r
- getFooter: function() {\r
- var me = this;\r
- var callbacks = me._options.callbacks;\r
-\r
- var beforeFooter = callbacks.beforeFooter.apply(me, arguments);\r
- var footer = callbacks.footer.apply(me, arguments);\r
- var afterFooter = callbacks.afterFooter.apply(me, arguments);\r
-\r
- var lines = [];\r
- lines = pushOrConcat(lines, beforeFooter);\r
- lines = pushOrConcat(lines, footer);\r
- lines = pushOrConcat(lines, afterFooter);\r
-\r
- return lines;\r
- },\r
-\r
- update: function(changed) {\r
- var me = this;\r
- var opts = me._options;\r
- var model = me._model;\r
- var active = me._active;\r
-\r
- var data = me._data;\r
- var chartInstance = me._chartInstance;\r
-\r
- var i, len;\r
-\r
- if (active.length) {\r
- model.opacity = 1;\r
-\r
- var labelColors = [],\r
- tooltipPosition = getAveragePosition(active);\r
-\r
- var tooltipItems = [];\r
- for (i = 0, len = active.length; i < len; ++i) {\r
- tooltipItems.push(createTooltipItem(active[i]));\r
- }\r
-\r
- // If the user provided a sorting function, use it to modify the tooltip items\r
- if (opts.itemSort) {\r
- tooltipItems = tooltipItems.sort(opts.itemSort);\r
- }\r
-\r
- // If there is more than one item, show color items\r
- if (active.length > 1) {\r
- helpers.each(tooltipItems, function(tooltipItem) {\r
- labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, chartInstance));\r
- });\r
- }\r
-\r
- // Build the Text Lines\r
- helpers.extend(model, {\r
- title: me.getTitle(tooltipItems, data),\r
- beforeBody: me.getBeforeBody(tooltipItems, data),\r
- body: me.getBody(tooltipItems, data),\r
- afterBody: me.getAfterBody(tooltipItems, data),\r
- footer: me.getFooter(tooltipItems, data),\r
- x: Math.round(tooltipPosition.x),\r
- y: Math.round(tooltipPosition.y),\r
- caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),\r
- labelColors: labelColors\r
- });\r
-\r
- // We need to determine alignment of\r
- var tooltipSize = me.getTooltipSize(model);\r
- me.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas\r
-\r
- helpers.extend(model, me.getBackgroundPoint(model, tooltipSize));\r
- } else {\r
- me._model.opacity = 0;\r
- }\r
-\r
- if (changed && opts.custom) {\r
- opts.custom.call(me, model);\r
- }\r
-\r
- return me;\r
- },\r
- getTooltipSize: function getTooltipSize(vm) {\r
- var ctx = this._chart.ctx;\r
-\r
- var size = {\r
- height: vm.yPadding * 2, // Tooltip Padding\r
- width: 0\r
- };\r
-\r
- // Count of all lines in the body\r
- var body = vm.body;\r
- var combinedBodyLength = body.reduce(function(count, bodyItem) {\r
- return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;\r
- }, 0);\r
- combinedBodyLength += vm.beforeBody.length + vm.afterBody.length;\r
-\r
- var titleLineCount = vm.title.length;\r
- var footerLineCount = vm.footer.length;\r
- var titleFontSize = vm.titleFontSize,\r
- bodyFontSize = vm.bodyFontSize,\r
- footerFontSize = vm.footerFontSize;\r
-\r
- size.height += titleLineCount * titleFontSize; // Title Lines\r
- size.height += (titleLineCount - 1) * vm.titleSpacing; // Title Line Spacing\r
- size.height += titleLineCount ? vm.titleMarginBottom : 0; // Title's bottom Margin\r
- size.height += combinedBodyLength * bodyFontSize; // Body Lines\r
- size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing\r
- size.height += footerLineCount ? vm.footerMarginTop : 0; // Footer Margin\r
- size.height += footerLineCount * (footerFontSize); // Footer Lines\r
- size.height += footerLineCount ? (footerLineCount - 1) * vm.footerSpacing : 0; // Footer Line Spacing\r
-\r
- // Title width\r
- var widthPadding = 0;\r
- var maxLineWidth = function(line) {\r
- size.width = Math.max(size.width, ctx.measureText(line).width + widthPadding);\r
- };\r
-\r
- ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\r
- helpers.each(vm.title, maxLineWidth);\r
-\r
- // Body width\r
- ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\r
- helpers.each(vm.beforeBody.concat(vm.afterBody), maxLineWidth);\r
-\r
- // Body lines may include some extra width due to the color box\r
- widthPadding = body.length > 1 ? (bodyFontSize + 2) : 0;\r
- helpers.each(body, function(bodyItem) {\r
- helpers.each(bodyItem.before, maxLineWidth);\r
- helpers.each(bodyItem.lines, maxLineWidth);\r
- helpers.each(bodyItem.after, maxLineWidth);\r
- });\r
-\r
- // Reset back to 0\r
- widthPadding = 0;\r
-\r
- // Footer width\r
- ctx.font = helpers.fontString(footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\r
- helpers.each(vm.footer, maxLineWidth);\r
-\r
- // Add padding\r
- size.width += 2 * vm.xPadding;\r
-\r
- return size;\r
- },\r
- determineAlignment: function determineAlignment(size) {\r
- var me = this;\r
- var model = me._model;\r
- var chart = me._chart;\r
- var chartArea = me._chartInstance.chartArea;\r
-\r
- if (model.y < size.height) {\r
- model.yAlign = 'top';\r
- } else if (model.y > (chart.height - size.height)) {\r
- model.yAlign = 'bottom';\r
- }\r
-\r
- var lf, rf; // functions to determine left, right alignment\r
- var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart\r
- var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges\r
- var midX = (chartArea.left + chartArea.right) / 2;\r
- var midY = (chartArea.top + chartArea.bottom) / 2;\r
-\r
- if (model.yAlign === 'center') {\r
- lf = function(x) {\r
- return x <= midX;\r
- };\r
- rf = function(x) {\r
- return x > midX;\r
- };\r
- } else {\r
- lf = function(x) {\r
- return x <= (size.width / 2);\r
- };\r
- rf = function(x) {\r
- return x >= (chart.width - (size.width / 2));\r
- };\r
- }\r
-\r
- olf = function(x) {\r
- return x + size.width > chart.width;\r
- };\r
- orf = function(x) {\r
- return x - size.width < 0;\r
- };\r
- yf = function(y) {\r
- return y <= midY ? 'top' : 'bottom';\r
- };\r
-\r
- if (lf(model.x)) {\r
- model.xAlign = 'left';\r
-\r
- // Is tooltip too wide and goes over the right side of the chart.?\r
- if (olf(model.x)) {\r
- model.xAlign = 'center';\r
- model.yAlign = yf(model.y);\r
- }\r
- } else if (rf(model.x)) {\r
- model.xAlign = 'right';\r
-\r
- // Is tooltip too wide and goes outside left edge of canvas?\r
- if (orf(model.x)) {\r
- model.xAlign = 'center';\r
- model.yAlign = yf(model.y);\r
- }\r
- }\r
- },\r
- getBackgroundPoint: function getBackgroundPoint(vm, size) {\r
- // Background Position\r
- var pt = {\r
- x: vm.x,\r
- y: vm.y\r
- };\r
-\r
- var caretSize = vm.caretSize,\r
- caretPadding = vm.caretPadding,\r
- cornerRadius = vm.cornerRadius,\r
- xAlign = vm.xAlign,\r
- yAlign = vm.yAlign,\r
- paddingAndSize = caretSize + caretPadding,\r
- radiusAndPadding = cornerRadius + caretPadding;\r
-\r
- if (xAlign === 'right') {\r
- pt.x -= size.width;\r
- } else if (xAlign === 'center') {\r
- pt.x -= (size.width / 2);\r
- }\r
-\r
- if (yAlign === 'top') {\r
- pt.y += paddingAndSize;\r
- } else if (yAlign === 'bottom') {\r
- pt.y -= size.height + paddingAndSize;\r
- } else {\r
- pt.y -= (size.height / 2);\r
- }\r
-\r
- if (yAlign === 'center') {\r
- if (xAlign === 'left') {\r
- pt.x += paddingAndSize;\r
- } else if (xAlign === 'right') {\r
- pt.x -= paddingAndSize;\r
- }\r
- } else {\r
- if (xAlign === 'left') {\r
- pt.x -= radiusAndPadding;\r
- } else if (xAlign === 'right') {\r
- pt.x += radiusAndPadding;\r
- }\r
- }\r
-\r
- return pt;\r
- },\r
- drawCaret: function drawCaret(tooltipPoint, size, opacity, caretPadding) {\r
- var vm = this._view;\r
- var ctx = this._chart.ctx;\r
- var x1, x2, x3;\r
- var y1, y2, y3;\r
- var caretSize = vm.caretSize;\r
- var cornerRadius = vm.cornerRadius;\r
- var xAlign = vm.xAlign,\r
- yAlign = vm.yAlign;\r
- var ptX = tooltipPoint.x,\r
- ptY = tooltipPoint.y;\r
- var width = size.width,\r
- height = size.height;\r
-\r
- if (yAlign === 'center') {\r
- // Left or right side\r
- if (xAlign === 'left') {\r
- x1 = ptX;\r
- x2 = x1 - caretSize;\r
- x3 = x1;\r
- } else {\r
- x1 = ptX + width;\r
- x2 = x1 + caretSize;\r
- x3 = x1;\r
- }\r
-\r
- y2 = ptY + (height / 2);\r
- y1 = y2 - caretSize;\r
- y3 = y2 + caretSize;\r
- } else {\r
- if (xAlign === 'left') {\r
- x1 = ptX + cornerRadius;\r
- x2 = x1 + caretSize;\r
- x3 = x2 + caretSize;\r
- } else if (xAlign === 'right') {\r
- x1 = ptX + width - cornerRadius;\r
- x2 = x1 - caretSize;\r
- x3 = x2 - caretSize;\r
- } else {\r
- x2 = ptX + (width / 2);\r
- x1 = x2 - caretSize;\r
- x3 = x2 + caretSize;\r
- }\r
-\r
- if (yAlign === 'top') {\r
- y1 = ptY;\r
- y2 = y1 - caretSize;\r
- y3 = y1;\r
- } else {\r
- y1 = ptY + height;\r
- y2 = y1 + caretSize;\r
- y3 = y1;\r
- }\r
- }\r
-\r
- var bgColor = helpers.color(vm.backgroundColor);\r
- ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();\r
- ctx.beginPath();\r
- ctx.moveTo(x1, y1);\r
- ctx.lineTo(x2, y2);\r
- ctx.lineTo(x3, y3);\r
- ctx.closePath();\r
- ctx.fill();\r
- },\r
- drawTitle: function drawTitle(pt, vm, ctx, opacity) {\r
- var title = vm.title;\r
-\r
- if (title.length) {\r
- ctx.textAlign = vm._titleAlign;\r
- ctx.textBaseline = "top";\r
-\r
- var titleFontSize = vm.titleFontSize,\r
- titleSpacing = vm.titleSpacing;\r
-\r
- var titleFontColor = helpers.color(vm.titleFontColor);\r
- ctx.fillStyle = titleFontColor.alpha(opacity * titleFontColor.alpha()).rgbString();\r
- ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\r
-\r
- var i, len;\r
- for (i = 0, len = title.length; i < len; ++i) {\r
- ctx.fillText(title[i], pt.x, pt.y);\r
- pt.y += titleFontSize + titleSpacing; // Line Height and spacing\r
-\r
- if (i + 1 === title.length) {\r
- pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing\r
- }\r
- }\r
- }\r
- },\r
- drawBody: function drawBody(pt, vm, ctx, opacity) {\r
- var bodyFontSize = vm.bodyFontSize;\r
- var bodySpacing = vm.bodySpacing;\r
- var body = vm.body;\r
-\r
- ctx.textAlign = vm._bodyAlign;\r
- ctx.textBaseline = "top";\r
-\r
- var bodyFontColor = helpers.color(vm.bodyFontColor);\r
- var textColor = bodyFontColor.alpha(opacity * bodyFontColor.alpha()).rgbString();\r
- ctx.fillStyle = textColor;\r
- ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\r
-\r
- // Before Body\r
- var xLinePadding = 0;\r
- var fillLineOfText = function(line) {\r
- ctx.fillText(line, pt.x + xLinePadding, pt.y);\r
- pt.y += bodyFontSize + bodySpacing;\r
- };\r
-\r
- // Before body lines\r
- helpers.each(vm.beforeBody, fillLineOfText);\r
-\r
- var drawColorBoxes = body.length > 1;\r
- xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;\r
-\r
- // Draw body lines now\r
- helpers.each(body, function(bodyItem, i) {\r
- helpers.each(bodyItem.before, fillLineOfText);\r
-\r
- helpers.each(bodyItem.lines, function(line) {\r
- // Draw Legend-like boxes if needed\r
- if (drawColorBoxes) {\r
- // Fill a white rect so that colours merge nicely if the opacity is < 1\r
- ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();\r
- ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\r
-\r
- // Border\r
- ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();\r
- ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\r
-\r
- // Inner square\r
- ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();\r
- ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);\r
-\r
- ctx.fillStyle = textColor;\r
- }\r
-\r
- fillLineOfText(line);\r
- });\r
-\r
- helpers.each(bodyItem.after, fillLineOfText);\r
- });\r
-\r
- // Reset back to 0 for after body\r
- xLinePadding = 0;\r
-\r
- // After body lines\r
- helpers.each(vm.afterBody, fillLineOfText);\r
- pt.y -= bodySpacing; // Remove last body spacing\r
- },\r
- drawFooter: function drawFooter(pt, vm, ctx, opacity) {\r
- var footer = vm.footer;\r
-\r
- if (footer.length) {\r
- pt.y += vm.footerMarginTop;\r
-\r
- ctx.textAlign = vm._footerAlign;\r
- ctx.textBaseline = "top";\r
-\r
- var footerFontColor = helpers.color(vm.footerFontColor);\r
- ctx.fillStyle = footerFontColor.alpha(opacity * footerFontColor.alpha()).rgbString();\r
- ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\r
-\r
- helpers.each(footer, function(line) {\r
- ctx.fillText(line, pt.x, pt.y);\r
- pt.y += vm.footerFontSize + vm.footerSpacing;\r
- });\r
- }\r
- },\r
- draw: function draw() {\r
- var ctx = this._chart.ctx;\r
- var vm = this._view;\r
-\r
- if (vm.opacity === 0) {\r
- return;\r
- }\r
-\r
- var tooltipSize = this.getTooltipSize(vm);\r
- var pt = {\r
- x: vm.x,\r
- y: vm.y\r
- };\r
-\r
- // IE11/Edge does not like very small opacities, so snap to 0\r
- var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;\r
-\r
- if (this._options.enabled) {\r
- // Draw Background\r
- var bgColor = helpers.color(vm.backgroundColor);\r
- ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();\r
- helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);\r
- ctx.fill();\r
-\r
- // Draw Caret\r
- this.drawCaret(pt, tooltipSize, opacity, vm.caretPadding);\r
-\r
- // Draw Title, Body, and Footer\r
- pt.x += vm.xPadding;\r
- pt.y += vm.yPadding;\r
-\r
- // Titles\r
- this.drawTitle(pt, vm, ctx, opacity);\r
-\r
- // Body\r
- this.drawBody(pt, vm, ctx, opacity);\r
-\r
- // Footer\r
- this.drawFooter(pt, vm, ctx, opacity);\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],34:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart, moment) {\r
-\r
- var helpers = Chart.helpers,\r
- globalOpts = Chart.defaults.global;\r
-\r
- globalOpts.elements.arc = {\r
- backgroundColor: globalOpts.defaultColor,\r
- borderColor: "#fff",\r
- borderWidth: 2\r
- };\r
-\r
- Chart.elements.Arc = Chart.Element.extend({\r
- inLabelRange: function(mouseX) {\r
- var vm = this._view;\r
-\r
- if (vm) {\r
- return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\r
- } else {\r
- return false;\r
- }\r
- },\r
- inRange: function(chartX, chartY) {\r
- var vm = this._view;\r
-\r
- if (vm) {\r
- var pointRelativePosition = helpers.getAngleFromPoint(vm, {\r
- x: chartX,\r
- y: chartY\r
- }),\r
- angle = pointRelativePosition.angle,\r
- distance = pointRelativePosition.distance;\r
-\r
- //Sanitise angle range\r
- var startAngle = vm.startAngle;\r
- var endAngle = vm.endAngle;\r
- while (endAngle < startAngle) {\r
- endAngle += 2.0 * Math.PI;\r
- }\r
- while (angle > endAngle) {\r
- angle -= 2.0 * Math.PI;\r
- }\r
- while (angle < startAngle) {\r
- angle += 2.0 * Math.PI;\r
- }\r
-\r
- //Check if within the range of the open/close angle\r
- var betweenAngles = (angle >= startAngle && angle <= endAngle),\r
- withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\r
-\r
- return (betweenAngles && withinRadius);\r
- } else {\r
- return false;\r
- }\r
- },\r
- tooltipPosition: function() {\r
- var vm = this._view;\r
-\r
- var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),\r
- rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\r
- return {\r
- x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\r
- y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\r
- };\r
- },\r
- draw: function() {\r
-\r
- var ctx = this._chart.ctx,\r
- vm = this._view,\r
- sA = vm.startAngle,\r
- eA = vm.endAngle;\r
-\r
- ctx.beginPath();\r
-\r
- ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);\r
- ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);\r
-\r
- ctx.closePath();\r
- ctx.strokeStyle = vm.borderColor;\r
- ctx.lineWidth = vm.borderWidth;\r
-\r
- ctx.fillStyle = vm.backgroundColor;\r
-\r
- ctx.fill();\r
- ctx.lineJoin = 'bevel';\r
-\r
- if (vm.borderWidth) {\r
- ctx.stroke();\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],35:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var globalDefaults = Chart.defaults.global;\r
-\r
- Chart.defaults.global.elements.line = {\r
- tension: 0.4,\r
- backgroundColor: globalDefaults.defaultColor,\r
- borderWidth: 3,\r
- borderColor: globalDefaults.defaultColor,\r
- borderCapStyle: 'butt',\r
- borderDash: [],\r
- borderDashOffset: 0.0,\r
- borderJoinStyle: 'miter',\r
- fill: true // do we fill in the area between the line and its base axis\r
- };\r
-\r
- Chart.elements.Line = Chart.Element.extend({\r
- lineToNextPoint: function(previousPoint, point, nextPoint, skipHandler, previousSkipHandler) {\r
- var me = this;\r
- var ctx = me._chart.ctx;\r
- var spanGaps = me._view ? me._view.spanGaps : false;\r
-\r
- if (point._view.skip && !spanGaps) {\r
- skipHandler.call(me, previousPoint, point, nextPoint);\r
- } else if (previousPoint._view.skip && !spanGaps) {\r
- previousSkipHandler.call(me, previousPoint, point, nextPoint);\r
- } else if (point._view.tension === 0) {\r
- ctx.lineTo(point._view.x, point._view.y);\r
- } else {\r
- // Line between points\r
- ctx.bezierCurveTo(\r
- previousPoint._view.controlPointNextX,\r
- previousPoint._view.controlPointNextY,\r
- point._view.controlPointPreviousX,\r
- point._view.controlPointPreviousY,\r
- point._view.x,\r
- point._view.y\r
- );\r
- }\r
- },\r
-\r
- draw: function() {\r
- var me = this;\r
-\r
- var vm = me._view;\r
- var ctx = me._chart.ctx;\r
- var first = me._children[0];\r
- var last = me._children[me._children.length - 1];\r
-\r
- function loopBackToStart(drawLineToCenter) {\r
- if (!first._view.skip && !last._view.skip) {\r
- // Draw a bezier line from last to first\r
- ctx.bezierCurveTo(\r
- last._view.controlPointNextX,\r
- last._view.controlPointNextY,\r
- first._view.controlPointPreviousX,\r
- first._view.controlPointPreviousY,\r
- first._view.x,\r
- first._view.y\r
- );\r
- } else if (drawLineToCenter) {\r
- // Go to center\r
- ctx.lineTo(me._view.scaleZero.x, me._view.scaleZero.y);\r
- }\r
- }\r
-\r
- ctx.save();\r
-\r
- // If we had points and want to fill this line, do so.\r
- if (me._children.length > 0 && vm.fill) {\r
- // Draw the background first (so the border is always on top)\r
- ctx.beginPath();\r
-\r
- helpers.each(me._children, function(point, index) {\r
- var previous = helpers.previousItem(me._children, index);\r
- var next = helpers.nextItem(me._children, index);\r
-\r
- // First point moves to it's starting position no matter what\r
- if (index === 0) {\r
- if (me._loop) {\r
- ctx.moveTo(vm.scaleZero.x, vm.scaleZero.y);\r
- } else {\r
- ctx.moveTo(point._view.x, vm.scaleZero);\r
- }\r
-\r
- if (point._view.skip) {\r
- if (!me._loop) {\r
- ctx.moveTo(next._view.x, me._view.scaleZero);\r
- }\r
- } else {\r
- ctx.lineTo(point._view.x, point._view.y);\r
- }\r
- } else {\r
- me.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {\r
- if (me._loop) {\r
- // Go to center\r
- ctx.lineTo(me._view.scaleZero.x, me._view.scaleZero.y);\r
- } else {\r
- ctx.lineTo(previousPoint._view.x, me._view.scaleZero);\r
- ctx.moveTo(nextPoint._view.x, me._view.scaleZero);\r
- }\r
- }, function(previousPoint, point) {\r
- // If we skipped the last point, draw a line to ourselves so that the fill is nice\r
- ctx.lineTo(point._view.x, point._view.y);\r
- });\r
- }\r
- }, me);\r
-\r
- // For radial scales, loop back around to the first point\r
- if (me._loop) {\r
- loopBackToStart(true);\r
- } else {\r
- //Round off the line by going to the base of the chart, back to the start, then fill.\r
- ctx.lineTo(me._children[me._children.length - 1]._view.x, vm.scaleZero);\r
- ctx.lineTo(me._children[0]._view.x, vm.scaleZero);\r
- }\r
-\r
- ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;\r
- ctx.closePath();\r
- ctx.fill();\r
- }\r
-\r
- var globalOptionLineElements = globalDefaults.elements.line;\r
- // Now draw the line between all the points with any borders\r
- ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\r
-\r
- // IE 9 and 10 do not support line dash\r
- if (ctx.setLineDash) {\r
- ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\r
- }\r
-\r
- ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;\r
- ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\r
- ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;\r
- ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\r
- ctx.beginPath();\r
-\r
- helpers.each(me._children, function(point, index) {\r
- var previous = helpers.previousItem(me._children, index);\r
- var next = helpers.nextItem(me._children, index);\r
-\r
- if (index === 0) {\r
- ctx.moveTo(point._view.x, point._view.y);\r
- } else {\r
- me.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {\r
- ctx.moveTo(nextPoint._view.x, nextPoint._view.y);\r
- }, function(previousPoint, point) {\r
- // If we skipped the last point, move up to our point preventing a line from being drawn\r
- ctx.moveTo(point._view.x, point._view.y);\r
- });\r
- }\r
- }, me);\r
-\r
- if (me._loop && me._children.length > 0) {\r
- loopBackToStart();\r
- }\r
-\r
- ctx.stroke();\r
- ctx.restore();\r
- }\r
- });\r
-};
-},{}],36:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- globalOpts = Chart.defaults.global,\r
- defaultColor = globalOpts.defaultColor;\r
-\r
- globalOpts.elements.point = {\r
- radius: 3,\r
- pointStyle: 'circle',\r
- backgroundColor: defaultColor,\r
- borderWidth: 1,\r
- borderColor: defaultColor,\r
- // Hover\r
- hitRadius: 1,\r
- hoverRadius: 4,\r
- hoverBorderWidth: 1\r
- };\r
-\r
- Chart.elements.Point = Chart.Element.extend({\r
- inRange: function(mouseX, mouseY) {\r
- var vm = this._view;\r
- return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\r
- },\r
- inLabelRange: function(mouseX) {\r
- var vm = this._view;\r
- return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\r
- },\r
- tooltipPosition: function() {\r
- var vm = this._view;\r
- return {\r
- x: vm.x,\r
- y: vm.y,\r
- padding: vm.radius + vm.borderWidth\r
- };\r
- },\r
- draw: function() {\r
- var vm = this._view;\r
- var ctx = this._chart.ctx;\r
- var pointStyle = vm.pointStyle;\r
- var radius = vm.radius;\r
- var x = vm.x;\r
- var y = vm.y;\r
- var type, edgeLength, xOffset, yOffset, height, size;\r
-\r
- if (vm.skip) {\r
- return;\r
- }\r
-\r
- if (typeof pointStyle === 'object') {\r
- type = pointStyle.toString();\r
- if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\r
- ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);\r
- return;\r
- }\r
- }\r
-\r
- if (isNaN(radius) || radius <= 0) {\r
- return;\r
- }\r
-\r
- ctx.strokeStyle = vm.borderColor || defaultColor;\r
- ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);\r
- ctx.fillStyle = vm.backgroundColor || defaultColor;\r
-\r
- switch (pointStyle) {\r
- // Default includes circle\r
- default:\r
- ctx.beginPath();\r
- ctx.arc(x, y, radius, 0, Math.PI * 2);\r
- ctx.closePath();\r
- ctx.fill();\r
- break;\r
- case 'triangle':\r
- ctx.beginPath();\r
- edgeLength = 3 * radius / Math.sqrt(3);\r
- height = edgeLength * Math.sqrt(3) / 2;\r
- ctx.moveTo(x - edgeLength / 2, y + height / 3);\r
- ctx.lineTo(x + edgeLength / 2, y + height / 3);\r
- ctx.lineTo(x, y - 2 * height / 3);\r
- ctx.closePath();\r
- ctx.fill();\r
- break;\r
- case 'rect':\r
- size = 1 / Math.SQRT2 * radius;\r
- ctx.fillRect(x - size, y - size, 2 * size, 2 * size);\r
- ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);\r
- break;\r
- case 'rectRot':\r
- size = 1 / Math.SQRT2 * radius;\r
- ctx.beginPath();\r
- ctx.moveTo(x - size, y);\r
- ctx.lineTo(x, y + size);\r
- ctx.lineTo(x + size, y);\r
- ctx.lineTo(x, y - size);\r
- ctx.closePath();\r
- ctx.fill();\r
- break;\r
- case 'cross':\r
- ctx.beginPath();\r
- ctx.moveTo(x, y + radius);\r
- ctx.lineTo(x, y - radius);\r
- ctx.moveTo(x - radius, y);\r
- ctx.lineTo(x + radius, y);\r
- ctx.closePath();\r
- break;\r
- case 'crossRot':\r
- ctx.beginPath();\r
- xOffset = Math.cos(Math.PI / 4) * radius;\r
- yOffset = Math.sin(Math.PI / 4) * radius;\r
- ctx.moveTo(x - xOffset, y - yOffset);\r
- ctx.lineTo(x + xOffset, y + yOffset);\r
- ctx.moveTo(x - xOffset, y + yOffset);\r
- ctx.lineTo(x + xOffset, y - yOffset);\r
- ctx.closePath();\r
- break;\r
- case 'star':\r
- ctx.beginPath();\r
- ctx.moveTo(x, y + radius);\r
- ctx.lineTo(x, y - radius);\r
- ctx.moveTo(x - radius, y);\r
- ctx.lineTo(x + radius, y);\r
- xOffset = Math.cos(Math.PI / 4) * radius;\r
- yOffset = Math.sin(Math.PI / 4) * radius;\r
- ctx.moveTo(x - xOffset, y - yOffset);\r
- ctx.lineTo(x + xOffset, y + yOffset);\r
- ctx.moveTo(x - xOffset, y + yOffset);\r
- ctx.lineTo(x + xOffset, y - yOffset);\r
- ctx.closePath();\r
- break;\r
- case 'line':\r
- ctx.beginPath();\r
- ctx.moveTo(x - radius, y);\r
- ctx.lineTo(x + radius, y);\r
- ctx.closePath();\r
- break;\r
- case 'dash':\r
- ctx.beginPath();\r
- ctx.moveTo(x, y);\r
- ctx.lineTo(x + radius, y);\r
- ctx.closePath();\r
- break;\r
- }\r
-\r
- ctx.stroke();\r
- }\r
- });\r
-};\r
-
-},{}],37:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- globalOpts = Chart.defaults.global;\r
-\r
- globalOpts.elements.rectangle = {\r
- backgroundColor: globalOpts.defaultColor,\r
- borderWidth: 0,\r
- borderColor: globalOpts.defaultColor,\r
- borderSkipped: 'bottom'\r
- };\r
-\r
- Chart.elements.Rectangle = Chart.Element.extend({\r
- draw: function() {\r
- var ctx = this._chart.ctx;\r
- var vm = this._view;\r
-\r
- var halfWidth = vm.width / 2,\r
- leftX = vm.x - halfWidth,\r
- rightX = vm.x + halfWidth,\r
- top = vm.base - (vm.base - vm.y),\r
- halfStroke = vm.borderWidth / 2;\r
-\r
- // Canvas doesn't allow us to stroke inside the width so we can\r
- // adjust the sizes to fit if we're setting a stroke on the line\r
- if (vm.borderWidth) {\r
- leftX += halfStroke;\r
- rightX -= halfStroke;\r
- top += halfStroke;\r
- }\r
-\r
- ctx.beginPath();\r
- ctx.fillStyle = vm.backgroundColor;\r
- ctx.strokeStyle = vm.borderColor;\r
- ctx.lineWidth = vm.borderWidth;\r
-\r
- // Corner points, from bottom-left to bottom-right clockwise\r
- // | 1 2 |\r
- // | 0 3 |\r
- var corners = [\r
- [leftX, vm.base],\r
- [leftX, top],\r
- [rightX, top],\r
- [rightX, vm.base]\r
- ];\r
-\r
- // Find first (starting) corner with fallback to 'bottom' \r
- var borders = ['bottom', 'left', 'top', 'right'];\r
- var startCorner = borders.indexOf(vm.borderSkipped, 0);\r
- if (startCorner === -1)\r
- startCorner = 0;\r
-\r
- function cornerAt(index) {\r
- return corners[(startCorner + index) % 4];\r
- }\r
-\r
- // Draw rectangle from 'startCorner'\r
- ctx.moveTo.apply(ctx, cornerAt(0));\r
- for (var i = 1; i < 4; i++)\r
- ctx.lineTo.apply(ctx, cornerAt(i));\r
-\r
- ctx.fill();\r
- if (vm.borderWidth) {\r
- ctx.stroke();\r
- }\r
- },\r
- height: function() {\r
- var vm = this._view;\r
- return vm.base - vm.y;\r
- },\r
- inRange: function(mouseX, mouseY) {\r
- var vm = this._view;\r
- return vm ? \r
- (vm.y < vm.base ? \r
- (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.y && mouseY <= vm.base) :\r
- (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.base && mouseY <= vm.y)) :\r
- false;\r
- },\r
- inLabelRange: function(mouseX) {\r
- var vm = this._view;\r
- return vm ? (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) : false;\r
- },\r
- tooltipPosition: function() {\r
- var vm = this._view;\r
- return {\r
- x: vm.x,\r
- y: vm.y\r
- };\r
- }\r
- });\r
-\r
-};
-},{}],38:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- // Default config for a category scale\r
- var defaultConfig = {\r
- position: "bottom"\r
- };\r
-\r
- var DatasetScale = Chart.Scale.extend({\r
- // Implement this so that \r
- determineDataLimits: function() {\r
- var me = this;\r
- me.minIndex = 0;\r
- me.maxIndex = me.chart.data.labels.length - 1;\r
- var findIndex;\r
-\r
- if (me.options.ticks.min !== undefined) {\r
- // user specified min value\r
- findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.min);\r
- me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;\r
- }\r
-\r
- if (me.options.ticks.max !== undefined) {\r
- // user specified max value\r
- findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.max);\r
- me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;\r
- }\r
-\r
- me.min = me.chart.data.labels[me.minIndex];\r
- me.max = me.chart.data.labels[me.maxIndex];\r
- },\r
-\r
- buildTicks: function(index) {\r
- var me = this;\r
- // If we are viewing some subset of labels, slice the original array\r
- me.ticks = (me.minIndex === 0 && me.maxIndex === me.chart.data.labels.length - 1) ? me.chart.data.labels : me.chart.data.labels.slice(me.minIndex, me.maxIndex + 1);\r
- },\r
-\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return this.ticks[index];\r
- },\r
-\r
- // Used to get data value locations. Value can either be an index or a numerical value\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- var me = this;\r
- // 1 is added because we need the length but we have the indexes\r
- var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\r
-\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var valueWidth = innerWidth / offsetAmt;\r
- var widthOffset = (valueWidth * (index - me.minIndex)) + me.paddingLeft;\r
-\r
- if (me.options.gridLines.offsetGridLines && includeOffset) {\r
- widthOffset += (valueWidth / 2);\r
- }\r
-\r
- return me.left + Math.round(widthOffset);\r
- } else {\r
- var innerHeight = me.height - (me.paddingTop + me.paddingBottom);\r
- var valueHeight = innerHeight / offsetAmt;\r
- var heightOffset = (valueHeight * (index - me.minIndex)) + me.paddingTop;\r
-\r
- if (me.options.gridLines.offsetGridLines && includeOffset) {\r
- heightOffset += (valueHeight / 2);\r
- }\r
-\r
- return me.top + Math.round(heightOffset);\r
- }\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var value;\r
- var offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\r
- var horz = me.isHorizontal();\r
- var innerDimension = horz ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);\r
- var valueDimension = innerDimension / offsetAmt;\r
-\r
- if (me.options.gridLines.offsetGridLines) {\r
- pixel -= (valueDimension / 2);\r
- }\r
- pixel -= horz ? me.paddingLeft : me.paddingTop;\r
-\r
- if (pixel <= 0) {\r
- value = 0;\r
- } else {\r
- value = Math.round(pixel / valueDimension);\r
- }\r
-\r
- return value;\r
- }\r
- });\r
-\r
- Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);\r
-\r
-};
-},{}],39:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- var defaultConfig = {\r
- position: "left",\r
- ticks: {\r
- callback: function(tickValue, index, ticks) {\r
- // If we have lots of ticks, don't use the ones\r
- var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];\r
-\r
- // If we have a number like 2.5 as the delta, figure out how many decimal places we need\r
- if (Math.abs(delta) > 1) {\r
- if (tickValue !== Math.floor(tickValue)) {\r
- // not an integer\r
- delta = tickValue - Math.floor(tickValue);\r
- }\r
- }\r
-\r
- var logDelta = helpers.log10(Math.abs(delta));\r
- var tickString = '';\r
-\r
- if (tickValue !== 0) {\r
- var numDecimal = -1 * Math.floor(logDelta);\r
- numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places\r
- tickString = tickValue.toFixed(numDecimal);\r
- } else {\r
- tickString = '0'; // never show decimal places for 0\r
- }\r
-\r
- return tickString;\r
- }\r
- }\r
- };\r
-\r
- var LinearScale = Chart.LinearScaleBase.extend({\r
- determineDataLimits: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var chart = me.chart;\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- function IDMatches(meta) {\r
- return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\r
- }\r
-\r
- // First Calculate the range\r
- me.min = null;\r
- me.max = null;\r
-\r
- if (opts.stacked) {\r
- var valuesPerType = {};\r
- var hasPositiveValues = false;\r
- var hasNegativeValues = false;\r
-\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (valuesPerType[meta.type] === undefined) {\r
- valuesPerType[meta.type] = {\r
- positiveValues: [],\r
- negativeValues: []\r
- };\r
- }\r
-\r
- // Store these per type\r
- var positiveValues = valuesPerType[meta.type].positiveValues;\r
- var negativeValues = valuesPerType[meta.type].negativeValues;\r
-\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- positiveValues[index] = positiveValues[index] || 0;\r
- negativeValues[index] = negativeValues[index] || 0;\r
-\r
- if (opts.relativePoints) {\r
- positiveValues[index] = 100;\r
- } else {\r
- if (value < 0) {\r
- hasNegativeValues = true;\r
- negativeValues[index] += value;\r
- } else {\r
- hasPositiveValues = true;\r
- positiveValues[index] += value;\r
- }\r
- }\r
- });\r
- }\r
- });\r
-\r
- helpers.each(valuesPerType, function(valuesForType) {\r
- var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);\r
- var minVal = helpers.min(values);\r
- var maxVal = helpers.max(values);\r
- me.min = me.min === null ? minVal : Math.min(me.min, minVal);\r
- me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\r
- });\r
-\r
- } else {\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- if (me.min === null) {\r
- me.min = value;\r
- } else if (value < me.min) {\r
- me.min = value;\r
- }\r
-\r
- if (me.max === null) {\r
- me.max = value;\r
- } else if (value > me.max) {\r
- me.max = value;\r
- }\r
- });\r
- }\r
- });\r
- }\r
-\r
- // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\r
- this.handleTickRangeOptions();\r
- },\r
- getTickLimit: function() {\r
- var maxTicks;\r
- var me = this;\r
- var tickOpts = me.options.ticks;\r
-\r
- if (me.isHorizontal()) {\r
- maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));\r
- } else {\r
- // The factor of 2 used to scale the font size has been experimentally determined.\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);\r
- maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));\r
- }\r
-\r
- return maxTicks;\r
- },\r
- // Called after the ticks are built. We need \r
- handleDirectionalChanges: function() {\r
- if (!this.isHorizontal()) {\r
- // We are in a vertical orientation. The top value is the highest. So reverse the array\r
- this.ticks.reverse();\r
- }\r
- },\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\r
- },\r
- // Utils\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- // This must be called after fit has been run so that\r
- // this.left, this.top, this.right, and this.bottom have been defined\r
- var me = this;\r
- var paddingLeft = me.paddingLeft;\r
- var paddingBottom = me.paddingBottom;\r
- var start = me.start;\r
-\r
- var rightValue = +me.getRightValue(value);\r
- var pixel;\r
- var innerDimension;\r
- var range = me.end - start;\r
-\r
- if (me.isHorizontal()) {\r
- innerDimension = me.width - (paddingLeft + me.paddingRight);\r
- pixel = me.left + (innerDimension / range * (rightValue - start));\r
- return Math.round(pixel + paddingLeft);\r
- } else {\r
- innerDimension = me.height - (me.paddingTop + paddingBottom);\r
- pixel = (me.bottom - paddingBottom) - (innerDimension / range * (rightValue - start));\r
- return Math.round(pixel);\r
- }\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var isHorizontal = me.isHorizontal();\r
- var paddingLeft = me.paddingLeft;\r
- var paddingBottom = me.paddingBottom;\r
- var innerDimension = isHorizontal ? me.width - (paddingLeft + me.paddingRight) : me.height - (me.paddingTop + paddingBottom);\r
- var offset = (isHorizontal ? pixel - me.left - paddingLeft : me.bottom - paddingBottom - pixel) / innerDimension;\r
- return me.start + ((me.end - me.start) * offset);\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.ticksAsNumbers[index], null, null, includeOffset);\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("linear", LinearScale, defaultConfig);\r
-\r
-};
-},{}],40:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- noop = helpers.noop;\r
-\r
- Chart.LinearScaleBase = Chart.Scale.extend({\r
- handleTickRangeOptions: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
-\r
- // If we are forcing it to begin at 0, but 0 will already be rendered on the chart,\r
- // do nothing since that would make the chart weird. If the user really wants a weird chart\r
- // axis, they can manually override it\r
- if (tickOpts.beginAtZero) {\r
- var minSign = helpers.sign(me.min);\r
- var maxSign = helpers.sign(me.max);\r
-\r
- if (minSign < 0 && maxSign < 0) {\r
- // move the top up to 0\r
- me.max = 0;\r
- } else if (minSign > 0 && maxSign > 0) {\r
- // move the botttom down to 0\r
- me.min = 0;\r
- }\r
- }\r
-\r
- if (tickOpts.min !== undefined) {\r
- me.min = tickOpts.min;\r
- } else if (tickOpts.suggestedMin !== undefined) {\r
- me.min = Math.min(me.min, tickOpts.suggestedMin);\r
- }\r
-\r
- if (tickOpts.max !== undefined) {\r
- me.max = tickOpts.max;\r
- } else if (tickOpts.suggestedMax !== undefined) {\r
- me.max = Math.max(me.max, tickOpts.suggestedMax);\r
- }\r
-\r
- if (me.min === me.max) {\r
- me.max++;\r
-\r
- if (!tickOpts.beginAtZero) {\r
- me.min--;\r
- }\r
- }\r
- },\r
- getTickLimit: noop,\r
- handleDirectionalChanges: noop,\r
-\r
- buildTicks: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- var ticks = me.ticks = [];\r
-\r
- // Figure out what the max number of ticks we can support it is based on the size of\r
- // the axis area. For now, we say that the minimum tick spacing in pixels must be 50\r
- // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\r
- // the graph\r
-\r
- var maxTicks = me.getTickLimit();\r
-\r
- // Make sure we always have at least 2 ticks\r
- maxTicks = Math.max(2, maxTicks);\r
-\r
- // To get a "nice" value for the tick spacing, we will use the appropriately named\r
- // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks\r
- // for details.\r
-\r
- var spacing;\r
- var fixedStepSizeSet = (tickOpts.fixedStepSize && tickOpts.fixedStepSize > 0) || (tickOpts.stepSize && tickOpts.stepSize > 0);\r
- if (fixedStepSizeSet) {\r
- spacing = getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize);\r
- } else {\r
- var niceRange = helpers.niceNum(me.max - me.min, false);\r
- spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);\r
- }\r
- var niceMin = Math.floor(me.min / spacing) * spacing;\r
- var niceMax = Math.ceil(me.max / spacing) * spacing;\r
- var numSpaces = (niceMax - niceMin) / spacing;\r
-\r
- // If very close to our rounded value, use it.\r
- if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\r
- numSpaces = Math.round(numSpaces);\r
- } else {\r
- numSpaces = Math.ceil(numSpaces);\r
- }\r
-\r
- // Put the values into the ticks array\r
- ticks.push(tickOpts.min !== undefined ? tickOpts.min : niceMin);\r
- for (var j = 1; j < numSpaces; ++j) {\r
- ticks.push(niceMin + (j * spacing));\r
- }\r
- ticks.push(tickOpts.max !== undefined ? tickOpts.max : niceMax);\r
-\r
- me.handleDirectionalChanges();\r
-\r
- // At this point, we need to update our max and min given the tick values since we have expanded the\r
- // range of the scale\r
- me.max = helpers.max(ticks);\r
- me.min = helpers.min(ticks);\r
-\r
- if (tickOpts.reverse) {\r
- ticks.reverse();\r
-\r
- me.start = me.max;\r
- me.end = me.min;\r
- } else {\r
- me.start = me.min;\r
- me.end = me.max;\r
- }\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- me.ticksAsNumbers = me.ticks.slice();\r
- me.zeroLineIndex = me.ticks.indexOf(0);\r
-\r
- Chart.Scale.prototype.convertTicksToLabels.call(me);\r
- },\r
- });\r
-};
-},{}],41:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- var defaultConfig = {\r
- position: "left",\r
-\r
- // label settings\r
- ticks: {\r
- callback: function(value, index, arr) {\r
- var remain = value / (Math.pow(10, Math.floor(helpers.log10(value))));\r
-\r
- if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) {\r
- return value.toExponential();\r
- } else {\r
- return '';\r
- }\r
- }\r
- }\r
- };\r
-\r
- var LogarithmicScale = Chart.Scale.extend({\r
- determineDataLimits: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var chart = me.chart;\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
- var isHorizontal = me.isHorizontal();\r
- function IDMatches(meta) {\r
- return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\r
- }\r
-\r
- // Calculate Range\r
- me.min = null;\r
- me.max = null;\r
-\r
- if (opts.stacked) {\r
- var valuesPerType = {};\r
-\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- if (valuesPerType[meta.type] === undefined) {\r
- valuesPerType[meta.type] = [];\r
- }\r
-\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var values = valuesPerType[meta.type];\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- values[index] = values[index] || 0;\r
-\r
- if (opts.relativePoints) {\r
- values[index] = 100;\r
- } else {\r
- // Don't need to split positive and negative since the log scale can't handle a 0 crossing\r
- values[index] += value;\r
- }\r
- });\r
- }\r
- });\r
-\r
- helpers.each(valuesPerType, function(valuesForType) {\r
- var minVal = helpers.min(valuesForType);\r
- var maxVal = helpers.max(valuesForType);\r
- me.min = me.min === null ? minVal : Math.min(me.min, minVal);\r
- me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\r
- });\r
-\r
- } else {\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- if (me.min === null) {\r
- me.min = value;\r
- } else if (value < me.min) {\r
- me.min = value;\r
- }\r
-\r
- if (me.max === null) {\r
- me.max = value;\r
- } else if (value > me.max) {\r
- me.max = value;\r
- }\r
- });\r
- }\r
- });\r
- }\r
-\r
- me.min = getValueOrDefault(tickOpts.min, me.min);\r
- me.max = getValueOrDefault(tickOpts.max, me.max);\r
-\r
- if (me.min === me.max) {\r
- if (me.min !== 0 && me.min !== null) {\r
- me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);\r
- me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);\r
- } else {\r
- me.min = 1;\r
- me.max = 10;\r
- }\r
- }\r
- },\r
- buildTicks: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
-\r
- // Reset the ticks array. Later on, we will draw a grid line at these positions\r
- // The array simply contains the numerical value of the spots where ticks will be\r
- var ticks = me.ticks = [];\r
-\r
- // Figure out what the max number of ticks we can support it is based on the size of\r
- // the axis area. For now, we say that the minimum tick spacing in pixels must be 50\r
- // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\r
- // the graph\r
-\r
- var tickVal = getValueOrDefault(tickOpts.min, Math.pow(10, Math.floor(helpers.log10(me.min))));\r
-\r
- while (tickVal < me.max) {\r
- ticks.push(tickVal);\r
-\r
- var exp = Math.floor(helpers.log10(tickVal));\r
- var significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;\r
-\r
- if (significand === 10) {\r
- significand = 1;\r
- ++exp;\r
- }\r
-\r
- tickVal = significand * Math.pow(10, exp);\r
- }\r
-\r
- var lastTick = getValueOrDefault(tickOpts.max, tickVal);\r
- ticks.push(lastTick);\r
-\r
- if (!me.isHorizontal()) {\r
- // We are in a vertical orientation. The top value is the highest. So reverse the array\r
- ticks.reverse();\r
- }\r
-\r
- // At this point, we need to update our max and min given the tick values since we have expanded the\r
- // range of the scale\r
- me.max = helpers.max(ticks);\r
- me.min = helpers.min(ticks);\r
-\r
- if (tickOpts.reverse) {\r
- ticks.reverse();\r
-\r
- me.start = me.max;\r
- me.end = me.min;\r
- } else {\r
- me.start = me.min;\r
- me.end = me.max;\r
- }\r
- },\r
- convertTicksToLabels: function() {\r
- this.tickValues = this.ticks.slice();\r
-\r
- Chart.Scale.prototype.convertTicksToLabels.call(this);\r
- },\r
- // Get the correct tooltip label\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.tickValues[index], null, null, includeOffset);\r
- },\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- var me = this;\r
- var innerDimension;\r
- var pixel;\r
-\r
- var start = me.start;\r
- var newVal = +me.getRightValue(value);\r
- var range = helpers.log10(me.end) - helpers.log10(start);\r
- var paddingTop = me.paddingTop;\r
- var paddingBottom = me.paddingBottom;\r
- var paddingLeft = me.paddingLeft;\r
-\r
- if (me.isHorizontal()) {\r
-\r
- if (newVal === 0) {\r
- pixel = me.left + paddingLeft;\r
- } else {\r
- innerDimension = me.width - (paddingLeft + me.paddingRight);\r
- pixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\r
- pixel += paddingLeft;\r
- }\r
- } else {\r
- // Bottom - top since pixels increase downard on a screen\r
- if (newVal === 0) {\r
- pixel = me.top + paddingTop;\r
- } else {\r
- innerDimension = me.height - (paddingTop + paddingBottom);\r
- pixel = (me.bottom - paddingBottom) - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\r
- }\r
- }\r
-\r
- return pixel;\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var offset;\r
- var range = helpers.log10(me.end) - helpers.log10(me.start);\r
- var value;\r
- var innerDimension;\r
-\r
- if (me.isHorizontal()) {\r
- innerDimension = me.width - (me.paddingLeft + me.paddingRight);\r
- value = me.start * Math.pow(10, (pixel - me.left - me.paddingLeft) * range / innerDimension);\r
- } else {\r
- innerDimension = me.height - (me.paddingTop + me.paddingBottom);\r
- value = Math.pow(10, (me.bottom - me.paddingBottom - pixel) * range / innerDimension) / me.start;\r
- }\r
-\r
- return value;\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);\r
-\r
-};
-},{}],42:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var globalDefaults = Chart.defaults.global;\r
-\r
- var defaultConfig = {\r
- display: true,\r
-\r
- //Boolean - Whether to animate scaling the chart from the centre\r
- animate: true,\r
- lineArc: false,\r
- position: "chartArea",\r
-\r
- angleLines: {\r
- display: true,\r
- color: "rgba(0, 0, 0, 0.1)",\r
- lineWidth: 1\r
- },\r
-\r
- // label settings\r
- ticks: {\r
- //Boolean - Show a backdrop to the scale label\r
- showLabelBackdrop: true,\r
-\r
- //String - The colour of the label backdrop\r
- backdropColor: "rgba(255,255,255,0.75)",\r
-\r
- //Number - The backdrop padding above & below the label in pixels\r
- backdropPaddingY: 2,\r
-\r
- //Number - The backdrop padding to the side of the label in pixels\r
- backdropPaddingX: 2\r
- },\r
-\r
- pointLabels: {\r
- //Number - Point label font size in pixels\r
- fontSize: 10,\r
-\r
- //Function - Used to convert point labels\r
- callback: function(label) {\r
- return label;\r
- }\r
- }\r
- };\r
-\r
- var LinearRadialScale = Chart.LinearScaleBase.extend({\r
- getValueCount: function() {\r
- return this.chart.data.labels.length;\r
- },\r
- setDimensions: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- // Set the unconstrained dimension before label rotation\r
- me.width = me.maxWidth;\r
- me.height = me.maxHeight;\r
- me.xCenter = Math.round(me.width / 2);\r
- me.yCenter = Math.round(me.height / 2);\r
-\r
- var minSize = helpers.min([me.height, me.width]);\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);\r
- },\r
- determineDataLimits: function() {\r
- var me = this;\r
- var chart = me.chart;\r
- me.min = null;\r
- me.max = null;\r
-\r
-\r
- helpers.each(chart.data.datasets, function(dataset, datasetIndex) {\r
- if (chart.isDatasetVisible(datasetIndex)) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
-\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- if (me.min === null) {\r
- me.min = value;\r
- } else if (value < me.min) {\r
- me.min = value;\r
- }\r
-\r
- if (me.max === null) {\r
- me.max = value;\r
- } else if (value > me.max) {\r
- me.max = value;\r
- }\r
- });\r
- }\r
- });\r
-\r
- // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\r
- me.handleTickRangeOptions();\r
- },\r
- getTickLimit: function() {\r
- var tickOpts = this.options.ticks;\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);\r
-\r
- // Point labels\r
- me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);\r
- },\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\r
- },\r
- fit: function() {\r
- /*\r
- * Right, this is really confusing and there is a lot of maths going on here\r
- * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\r
- *\r
- * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\r
- *\r
- * Solution:\r
- *\r
- * We assume the radius of the polygon is half the size of the canvas at first\r
- * at each index we check if the text overlaps.\r
- *\r
- * Where it does, we store that angle and that index.\r
- *\r
- * After finding the largest index and angle we calculate how much we need to remove\r
- * from the shape radius to move the point inwards by that x.\r
- *\r
- * We average the left and right distances to get the maximum shape radius that can fit in the box\r
- * along with labels.\r
- *\r
- * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\r
- * on each side, removing that from the size, halving it and adding the left x protrusion width.\r
- *\r
- * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\r
- * and position it in the most space efficient manner\r
- *\r
- * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\r
- */\r
-\r
- var pointLabels = this.options.pointLabels;\r
- var pointLabelFontSize = helpers.getValueOrDefault(pointLabels.fontSize, globalDefaults.defaultFontSize);\r
- var pointLabeFontStyle = helpers.getValueOrDefault(pointLabels.fontStyle, globalDefaults.defaultFontStyle);\r
- var pointLabeFontFamily = helpers.getValueOrDefault(pointLabels.fontFamily, globalDefaults.defaultFontFamily);\r
- var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);\r
-\r
- // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\r
- // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\r
- var largestPossibleRadius = helpers.min([(this.height / 2 - pointLabelFontSize - 5), this.width / 2]),\r
- pointPosition,\r
- i,\r
- textWidth,\r
- halfTextWidth,\r
- furthestRight = this.width,\r
- furthestRightIndex,\r
- furthestRightAngle,\r
- furthestLeft = 0,\r
- furthestLeftIndex,\r
- furthestLeftAngle,\r
- xProtrusionLeft,\r
- xProtrusionRight,\r
- radiusReductionRight,\r
- radiusReductionLeft,\r
- maxWidthRadius;\r
- this.ctx.font = pointLabeFont;\r
-\r
- for (i = 0; i < this.getValueCount(); i++) {\r
- // 5px to space the text slightly out - similar to what we do in the draw function.\r
- pointPosition = this.getPointPosition(i, largestPossibleRadius);\r
- textWidth = this.ctx.measureText(this.pointLabels[i] ? this.pointLabels[i] : '').width + 5;\r
- if (i === 0 || i === this.getValueCount() / 2) {\r
- // If we're at index zero, or exactly the middle, we're at exactly the top/bottom\r
- // of the radar chart, so text will be aligned centrally, so we'll half it and compare\r
- // w/left and right text sizes\r
- halfTextWidth = textWidth / 2;\r
- if (pointPosition.x + halfTextWidth > furthestRight) {\r
- furthestRight = pointPosition.x + halfTextWidth;\r
- furthestRightIndex = i;\r
- }\r
- if (pointPosition.x - halfTextWidth < furthestLeft) {\r
- furthestLeft = pointPosition.x - halfTextWidth;\r
- furthestLeftIndex = i;\r
- }\r
- } else if (i < this.getValueCount() / 2) {\r
- // Less than half the values means we'll left align the text\r
- if (pointPosition.x + textWidth > furthestRight) {\r
- furthestRight = pointPosition.x + textWidth;\r
- furthestRightIndex = i;\r
- }\r
- } else if (i > this.getValueCount() / 2) {\r
- // More than half the values means we'll right align the text\r
- if (pointPosition.x - textWidth < furthestLeft) {\r
- furthestLeft = pointPosition.x - textWidth;\r
- furthestLeftIndex = i;\r
- }\r
- }\r
- }\r
-\r
- xProtrusionLeft = furthestLeft;\r
- xProtrusionRight = Math.ceil(furthestRight - this.width);\r
-\r
- furthestRightAngle = this.getIndexAngle(furthestRightIndex);\r
- furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);\r
-\r
- radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI / 2);\r
- radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI / 2);\r
-\r
- // Ensure we actually need to reduce the size of the chart\r
- radiusReductionRight = (helpers.isNumber(radiusReductionRight)) ? radiusReductionRight : 0;\r
- radiusReductionLeft = (helpers.isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;\r
-\r
- this.drawingArea = Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2);\r
- this.setCenterPoint(radiusReductionLeft, radiusReductionRight);\r
- },\r
- setCenterPoint: function(leftMovement, rightMovement) {\r
- var me = this;\r
- var maxRight = me.width - rightMovement - me.drawingArea,\r
- maxLeft = leftMovement + me.drawingArea;\r
-\r
- me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);\r
- // Always vertically in the centre as the text height doesn't change\r
- me.yCenter = Math.round((me.height / 2) + me.top);\r
- },\r
-\r
- getIndexAngle: function(index) {\r
- var angleMultiplier = (Math.PI * 2) / this.getValueCount();\r
- // Start from the top instead of right, so remove a quarter of the circle\r
-\r
- return index * angleMultiplier - (Math.PI / 2);\r
- },\r
- getDistanceFromCenterForValue: function(value) {\r
- var me = this;\r
-\r
- if (value === null) {\r
- return 0; // null always in center\r
- }\r
-\r
- // Take into account half font size + the yPadding of the top value\r
- var scalingFactor = me.drawingArea / (me.max - me.min);\r
- if (me.options.reverse) {\r
- return (me.max - value) * scalingFactor;\r
- } else {\r
- return (value - me.min) * scalingFactor;\r
- }\r
- },\r
- getPointPosition: function(index, distanceFromCenter) {\r
- var me = this;\r
- var thisAngle = me.getIndexAngle(index);\r
- return {\r
- x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,\r
- y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter\r
- };\r
- },\r
- getPointPositionForValue: function(index, value) {\r
- return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\r
- },\r
-\r
- getBasePosition: function() {\r
- var me = this;\r
- var min = me.min;\r
- var max = me.max;\r
-\r
- return me.getPointPositionForValue(0,\r
- me.beginAtZero? 0:\r
- min < 0 && max < 0? max :\r
- min > 0 && max > 0? min :\r
- 0);\r
- },\r
-\r
- draw: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var gridLineOpts = opts.gridLines;\r
- var tickOpts = opts.ticks;\r
- var angleLineOpts = opts.angleLines;\r
- var pointLabelOpts = opts.pointLabels;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
-\r
- if (opts.display) {\r
- var ctx = me.ctx;\r
-\r
- // Tick Font\r
- var tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
-\r
- helpers.each(me.ticks, function(label, index) {\r
- // Don't draw a centre value (if it is minimum)\r
- if (index > 0 || opts.reverse) {\r
- var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\r
- var yHeight = me.yCenter - yCenterOffset;\r
-\r
- // Draw circular lines around the scale\r
- if (gridLineOpts.display && index !== 0) {\r
- ctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);\r
- ctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);\r
-\r
- if (opts.lineArc) {\r
- // Draw circular arcs between the points\r
- ctx.beginPath();\r
- ctx.arc(me.xCenter, me.yCenter, yCenterOffset, 0, Math.PI * 2);\r
- ctx.closePath();\r
- ctx.stroke();\r
- } else {\r
- // Draw straight lines connecting each index\r
- ctx.beginPath();\r
- for (var i = 0; i < me.getValueCount(); i++) {\r
- var pointPosition = me.getPointPosition(i, yCenterOffset);\r
- if (i === 0) {\r
- ctx.moveTo(pointPosition.x, pointPosition.y);\r
- } else {\r
- ctx.lineTo(pointPosition.x, pointPosition.y);\r
- }\r
- }\r
- ctx.closePath();\r
- ctx.stroke();\r
- }\r
- }\r
-\r
- if (tickOpts.display) {\r
- var tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);\r
- ctx.font = tickLabelFont;\r
-\r
- if (tickOpts.showLabelBackdrop) {\r
- var labelWidth = ctx.measureText(label).width;\r
- ctx.fillStyle = tickOpts.backdropColor;\r
- ctx.fillRect(\r
- me.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,\r
- yHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,\r
- labelWidth + tickOpts.backdropPaddingX * 2,\r
- tickFontSize + tickOpts.backdropPaddingY * 2\r
- );\r
- }\r
-\r
- ctx.textAlign = 'center';\r
- ctx.textBaseline = "middle";\r
- ctx.fillStyle = tickFontColor;\r
- ctx.fillText(label, me.xCenter, yHeight);\r
- }\r
- }\r
- });\r
-\r
- if (!opts.lineArc) {\r
- ctx.lineWidth = angleLineOpts.lineWidth;\r
- ctx.strokeStyle = angleLineOpts.color;\r
-\r
- var outerDistance = me.getDistanceFromCenterForValue(opts.reverse ? me.min : me.max);\r
-\r
- // Point Label Font\r
- var pointLabelFontSize = getValueOrDefault(pointLabelOpts.fontSize, globalDefaults.defaultFontSize);\r
- var pointLabeFontStyle = getValueOrDefault(pointLabelOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var pointLabeFontFamily = getValueOrDefault(pointLabelOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);\r
-\r
- for (var i = me.getValueCount() - 1; i >= 0; i--) {\r
- if (angleLineOpts.display) {\r
- var outerPosition = me.getPointPosition(i, outerDistance);\r
- ctx.beginPath();\r
- ctx.moveTo(me.xCenter, me.yCenter);\r
- ctx.lineTo(outerPosition.x, outerPosition.y);\r
- ctx.stroke();\r
- ctx.closePath();\r
- }\r
- // Extra 3px out for some label spacing\r
- var pointLabelPosition = me.getPointPosition(i, outerDistance + 5);\r
-\r
- // Keep this in loop since we may support array properties here\r
- var pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);\r
- ctx.font = pointLabeFont;\r
- ctx.fillStyle = pointLabelFontColor;\r
-\r
- var pointLabels = me.pointLabels,\r
- labelsCount = pointLabels.length,\r
- halfLabelsCount = pointLabels.length / 2,\r
- quarterLabelsCount = halfLabelsCount / 2,\r
- upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),\r
- exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);\r
- if (i === 0) {\r
- ctx.textAlign = 'center';\r
- } else if (i === halfLabelsCount) {\r
- ctx.textAlign = 'center';\r
- } else if (i < halfLabelsCount) {\r
- ctx.textAlign = 'left';\r
- } else {\r
- ctx.textAlign = 'right';\r
- }\r
-\r
- // Set the correct text baseline based on outer positioning\r
- if (exactQuarter) {\r
- ctx.textBaseline = 'middle';\r
- } else if (upperHalf) {\r
- ctx.textBaseline = 'bottom';\r
- } else {\r
- ctx.textBaseline = 'top';\r
- }\r
-\r
- ctx.fillText(pointLabels[i] ? pointLabels[i] : '', pointLabelPosition.x, pointLabelPosition.y);\r
- }\r
- }\r
- }\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("radialLinear", LinearRadialScale, defaultConfig);\r
-\r
-};\r
-
-},{}],43:[function(require,module,exports){
-/*global window: false */\r
-"use strict";\r
-\r
-var moment = require(6);\r
-moment = typeof(moment) === 'function' ? moment : window.moment;\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var time = {\r
- units: [{\r
- name: 'millisecond',\r
- steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]\r
- }, {\r
- name: 'second',\r
- steps: [1, 2, 5, 10, 30]\r
- }, {\r
- name: 'minute',\r
- steps: [1, 2, 5, 10, 30]\r
- }, {\r
- name: 'hour',\r
- steps: [1, 2, 3, 6, 12]\r
- }, {\r
- name: 'day',\r
- steps: [1, 2, 5]\r
- }, {\r
- name: 'week',\r
- maxStep: 4\r
- }, {\r
- name: 'month',\r
- maxStep: 3\r
- }, {\r
- name: 'quarter',\r
- maxStep: 4\r
- }, {\r
- name: 'year',\r
- maxStep: false\r
- }]\r
- };\r
-\r
- var defaultConfig = {\r
- position: "bottom",\r
-\r
- time: {\r
- parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment\r
- format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/\r
- unit: false, // false == automatic or override with week, month, year, etc.\r
- round: false, // none, or override with week, month, year, etc.\r
- displayFormat: false, // DEPRECATED\r
- isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/\r
-\r
- // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/\r
- displayFormats: {\r
- 'millisecond': 'h:mm:ss.SSS a', // 11:20:01.123 AM,\r
- 'second': 'h:mm:ss a', // 11:20:01 AM\r
- 'minute': 'h:mm:ss a', // 11:20:01 AM\r
- 'hour': 'MMM D, hA', // Sept 4, 5PM\r
- 'day': 'll', // Sep 4 2015\r
- 'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?\r
- 'month': 'MMM YYYY', // Sept 2015\r
- 'quarter': '[Q]Q - YYYY', // Q3\r
- 'year': 'YYYY' // 2015\r
- }\r
- },\r
- ticks: {\r
- autoSkip: false\r
- }\r
- };\r
-\r
- var TimeScale = Chart.Scale.extend({\r
- initialize: function() {\r
- if (!moment) {\r
- throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');\r
- }\r
-\r
- Chart.Scale.prototype.initialize.call(this);\r
- },\r
- getLabelMoment: function(datasetIndex, index) {\r
- return this.labelMoments[datasetIndex][index];\r
- },\r
- getMomentStartOf: function(tick) {\r
- var me = this;\r
- if (me.options.time.unit === 'week' && me.options.time.isoWeekday !== false) {\r
- return tick.clone().startOf('isoWeek').isoWeekday(me.options.time.isoWeekday);\r
- } else {\r
- return tick.clone().startOf(me.tickUnit);\r
- }\r
- },\r
- determineDataLimits: function() {\r
- var me = this;\r
- me.labelMoments = [];\r
-\r
- // Only parse these once. If the dataset does not have data as x,y pairs, we will use\r
- // these\r
- var scaleLabelMoments = [];\r
- if (me.chart.data.labels && me.chart.data.labels.length > 0) {\r
- helpers.each(me.chart.data.labels, function(label, index) {\r
- var labelMoment = me.parseTime(label);\r
-\r
- if (labelMoment.isValid()) {\r
- if (me.options.time.round) {\r
- labelMoment.startOf(me.options.time.round);\r
- }\r
- scaleLabelMoments.push(labelMoment);\r
- }\r
- }, me);\r
-\r
- me.firstTick = moment.min.call(me, scaleLabelMoments);\r
- me.lastTick = moment.max.call(me, scaleLabelMoments);\r
- } else {\r
- me.firstTick = null;\r
- me.lastTick = null;\r
- }\r
-\r
- helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {\r
- var momentsForDataset = [];\r
- var datasetVisible = me.chart.isDatasetVisible(datasetIndex);\r
-\r
- if (typeof dataset.data[0] === 'object' && dataset.data[0] !== null) {\r
- helpers.each(dataset.data, function(value, index) {\r
- var labelMoment = me.parseTime(me.getRightValue(value));\r
-\r
- if (labelMoment.isValid()) {\r
- if (me.options.time.round) {\r
- labelMoment.startOf(me.options.time.round);\r
- }\r
- momentsForDataset.push(labelMoment);\r
-\r
- if (datasetVisible) {\r
- // May have gone outside the scale ranges, make sure we keep the first and last ticks updated\r
- me.firstTick = me.firstTick !== null ? moment.min(me.firstTick, labelMoment) : labelMoment;\r
- me.lastTick = me.lastTick !== null ? moment.max(me.lastTick, labelMoment) : labelMoment;\r
- }\r
- }\r
- }, me);\r
- } else {\r
- // We have no labels. Use the ones from the scale\r
- momentsForDataset = scaleLabelMoments;\r
- }\r
-\r
- me.labelMoments.push(momentsForDataset);\r
- }, me);\r
-\r
- // Set these after we've done all the data\r
- if (me.options.time.min) {\r
- me.firstTick = me.parseTime(me.options.time.min);\r
- }\r
-\r
- if (me.options.time.max) {\r
- me.lastTick = me.parseTime(me.options.time.max);\r
- }\r
-\r
- // We will modify these, so clone for later\r
- me.firstTick = (me.firstTick || moment()).clone();\r
- me.lastTick = (me.lastTick || moment()).clone();\r
- },\r
- buildTicks: function(index) {\r
- var me = this;\r
-\r
- me.ctx.save();\r
- var tickFontSize = helpers.getValueOrDefault(me.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(me.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(me.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
- me.ctx.font = tickLabelFont;\r
-\r
- me.ticks = [];\r
- me.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step\r
- me.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc)\r
-\r
- // Set unit override if applicable\r
- if (me.options.time.unit) {\r
- me.tickUnit = me.options.time.unit || 'day';\r
- me.displayFormat = me.options.time.displayFormats[me.tickUnit];\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);\r
- me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, 1);\r
- } else {\r
- // Determine the smallest needed unit of the time\r
- var innerWidth = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);\r
-\r
- // Crude approximation of what the label length might be\r
- var tempFirstLabel = me.tickFormatFunction(me.firstTick, 0, []);\r
- var tickLabelWidth = me.ctx.measureText(tempFirstLabel).width;\r
- var cosRotation = Math.cos(helpers.toRadians(me.options.ticks.maxRotation));\r
- var sinRotation = Math.sin(helpers.toRadians(me.options.ticks.maxRotation));\r
- tickLabelWidth = (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);\r
- var labelCapacity = innerWidth / (tickLabelWidth);\r
-\r
- // Start as small as possible\r
- me.tickUnit = 'millisecond';\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);\r
- me.displayFormat = me.options.time.displayFormats[me.tickUnit];\r
-\r
- var unitDefinitionIndex = 0;\r
- var unitDefinition = time.units[unitDefinitionIndex];\r
-\r
- // While we aren't ideal and we don't have units left\r
- while (unitDefinitionIndex < time.units.length) {\r
- // Can we scale this unit. If `false` we can scale infinitely\r
- me.unitScale = 1;\r
-\r
- if (helpers.isArray(unitDefinition.steps) && Math.ceil(me.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) {\r
- // Use one of the prefedined steps\r
- for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {\r
- if (unitDefinition.steps[idx] >= Math.ceil(me.scaleSizeInUnits / labelCapacity)) {\r
- me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, unitDefinition.steps[idx]);\r
- break;\r
- }\r
- }\r
-\r
- break;\r
- } else if ((unitDefinition.maxStep === false) || (Math.ceil(me.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep)) {\r
- // We have a max step. Scale this unit\r
- me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, Math.ceil(me.scaleSizeInUnits / labelCapacity));\r
- break;\r
- } else {\r
- // Move to the next unit up\r
- ++unitDefinitionIndex;\r
- unitDefinition = time.units[unitDefinitionIndex];\r
-\r
- me.tickUnit = unitDefinition.name;\r
- var leadingUnitBuffer = me.firstTick.diff(me.getMomentStartOf(me.firstTick), me.tickUnit, true);\r
- var trailingUnitBuffer = me.getMomentStartOf(me.lastTick.clone().add(1, me.tickUnit)).diff(me.lastTick, me.tickUnit, true);\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true) + leadingUnitBuffer + trailingUnitBuffer;\r
- me.displayFormat = me.options.time.displayFormats[unitDefinition.name];\r
- }\r
- }\r
- }\r
-\r
- var roundedStart;\r
-\r
- // Only round the first tick if we have no hard minimum\r
- if (!me.options.time.min) {\r
- me.firstTick = me.getMomentStartOf(me.firstTick);\r
- roundedStart = me.firstTick;\r
- } else {\r
- roundedStart = me.getMomentStartOf(me.firstTick);\r
- }\r
-\r
- // Only round the last tick if we have no hard maximum\r
- if (!me.options.time.max) {\r
- var roundedEnd = me.getMomentStartOf(me.lastTick);\r
- if (roundedEnd.diff(me.lastTick, me.tickUnit, true) !== 0) {\r
- // Do not use end of because we need me to be in the next time unit\r
- me.lastTick = me.getMomentStartOf(me.lastTick.add(1, me.tickUnit));\r
- }\r
- }\r
-\r
- me.smallestLabelSeparation = me.width;\r
-\r
- helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {\r
- for (var i = 1; i < me.labelMoments[datasetIndex].length; i++) {\r
- me.smallestLabelSeparation = Math.min(me.smallestLabelSeparation, me.labelMoments[datasetIndex][i].diff(me.labelMoments[datasetIndex][i - 1], me.tickUnit, true));\r
- }\r
- }, me);\r
-\r
- // Tick displayFormat override\r
- if (me.options.time.displayFormat) {\r
- me.displayFormat = me.options.time.displayFormat;\r
- }\r
-\r
- // first tick. will have been rounded correctly if options.time.min is not specified\r
- me.ticks.push(me.firstTick.clone());\r
-\r
- // For every unit in between the first and last moment, create a moment and add it to the ticks tick\r
- for (var i = 1; i <= me.scaleSizeInUnits; ++i) {\r
- var newTick = roundedStart.clone().add(i, me.tickUnit);\r
-\r
- // Are we greater than the max time\r
- if (me.options.time.max && newTick.diff(me.lastTick, me.tickUnit, true) >= 0) {\r
- break;\r
- }\r
-\r
- if (i % me.unitScale === 0) {\r
- me.ticks.push(newTick);\r
- }\r
- }\r
-\r
- // Always show the right tick\r
- var diff = me.ticks[me.ticks.length - 1].diff(me.lastTick, me.tickUnit);\r
- if (diff !== 0 || me.scaleSizeInUnits === 0) {\r
- // this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart\r
- // but the last tick was not rounded.\r
- if (me.options.time.max) {\r
- me.ticks.push(me.lastTick.clone());\r
- me.scaleSizeInUnits = me.lastTick.diff(me.ticks[0], me.tickUnit, true);\r
- } else {\r
- me.ticks.push(me.lastTick.clone());\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);\r
- }\r
- }\r
-\r
- me.ctx.restore();\r
- },\r
- // Get tooltip label\r
- getLabelForIndex: function(index, datasetIndex) {\r
- var me = this;\r
- var label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';\r
-\r
- if (typeof me.chart.data.datasets[datasetIndex].data[0] === 'object') {\r
- label = me.getRightValue(me.chart.data.datasets[datasetIndex].data[index]);\r
- }\r
-\r
- // Format nicely\r
- if (me.options.time.tooltipFormat) {\r
- label = me.parseTime(label).format(me.options.time.tooltipFormat);\r
- }\r
-\r
- return label;\r
- },\r
- // Function to format an individual tick mark\r
- tickFormatFunction: function tickFormatFunction(tick, index, ticks) {\r
- var formattedTick = tick.format(this.displayFormat);\r
- var tickOpts = this.options.ticks;\r
- var callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);\r
-\r
- if (callback) {\r
- return callback(formattedTick, index, ticks);\r
- } else {\r
- return formattedTick;\r
- }\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- me.tickMoments = me.ticks;\r
- me.ticks = me.ticks.map(me.tickFormatFunction, me);\r
- },\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- var me = this;\r
- var labelMoment = value && value.isValid && value.isValid() ? value : me.getLabelMoment(datasetIndex, index);\r
-\r
- if (labelMoment) {\r
- var offset = labelMoment.diff(me.firstTick, me.tickUnit, true);\r
-\r
- var decimal = offset / me.scaleSizeInUnits;\r
-\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var valueWidth = innerWidth / Math.max(me.ticks.length - 1, 1);\r
- var valueOffset = (innerWidth * decimal) + me.paddingLeft;\r
-\r
- return me.left + Math.round(valueOffset);\r
- } else {\r
- var innerHeight = me.height - (me.paddingTop + me.paddingBottom);\r
- var valueHeight = innerHeight / Math.max(me.ticks.length - 1, 1);\r
- var heightOffset = (innerHeight * decimal) + me.paddingTop;\r
-\r
- return me.top + Math.round(heightOffset);\r
- }\r
- }\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.tickMoments[index], null, null, includeOffset);\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var innerDimension = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);\r
- var offset = (pixel - (me.isHorizontal() ? me.left + me.paddingLeft : me.top + me.paddingTop)) / innerDimension;\r
- offset *= me.scaleSizeInUnits;\r
- return me.firstTick.clone().add(moment.duration(offset, me.tickUnit).asSeconds(), 'seconds');\r
- },\r
- parseTime: function(label) {\r
- var me = this;\r
- if (typeof me.options.time.parser === 'string') {\r
- return moment(label, me.options.time.parser);\r
- }\r
- if (typeof me.options.time.parser === 'function') {\r
- return me.options.time.parser(label);\r
- }\r
- // Date objects\r
- if (typeof label.getMonth === 'function' || typeof label === 'number') {\r
- return moment(label);\r
- }\r
- // Moment support\r
- if (label.isValid && label.isValid()) {\r
- return label;\r
- }\r
- // Custom parsing (return an instance of moment)\r
- if (typeof me.options.time.format !== 'string' && me.options.time.format.call) {\r
- console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale");\r
- return me.options.time.format(label);\r
- }\r
- // Moment format parsing\r
- return moment(label, me.options.time.format);\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("time", TimeScale, defaultConfig);\r
-\r
-};\r
-
-},{"6":6}]},{},[7])(7)
-});
\ No newline at end of file
+++ /dev/null
-/*!
- * Chart.js
- * http://chartjs.org/
- * Version: 2.1.6
- *
- * Copyright 2016 Nick Downie
- * Released under the MIT license
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
- */
-!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){var t;return function e(t,n,i){function a(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[o]={exports:{}};t[o][0].call(d.exports,function(e){var n=t[o][1][e];return a(n?n:e)},d,d.exports,e,t,n,i)}return n[o].exports}for(var r="function"==typeof require&&require,o=0;o<i.length;o++)a(i[o]);return a}({1:[function(t,e,n){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,n=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,a=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,r=/(\w+)/,o=[0,0,0],s=1,l=t.match(e);if(l){l=l[1];for(var u=0;u<o.length;u++)o[u]=parseInt(l[u]+l[u],16)}else if(l=t.match(n)){l=l[1];for(var u=0;u<o.length;u++)o[u]=parseInt(l.slice(2*u,2*u+2),16)}else if(l=t.match(i)){for(var u=0;u<o.length;u++)o[u]=parseInt(l[u+1]);s=parseFloat(l[4])}else if(l=t.match(a)){for(var u=0;u<o.length;u++)o[u]=Math.round(2.55*parseFloat(l[u+1]));s=parseFloat(l[4])}else if(l=t.match(r)){if("transparent"==l[1])return[0,0,0,0];if(o=x[l[1]],!o)return}for(var u=0;u<o.length;u++)o[u]=b(o[u],0,255);return s=s||0==s?b(s,0,1):1,o[3]=s,o}}function a(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),r=b(parseFloat(n[2]),0,100),o=b(parseFloat(n[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[a,r,o,s]}}}function r(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),r=b(parseFloat(n[2]),0,100),o=b(parseFloat(n[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[a,r,o,s]}}}function o(t){var e=i(t);return e&&e.slice(0,3)}function s(t){var e=a(t);return e&&e.slice(0,3)}function l(t){var e=i(t);return e?e[3]:(e=a(t))?e[3]:(e=r(t))?e[3]:void 0}function u(t){return"#"+y(t[0])+y(t[1])+y(t[2])}function d(t,e){return 1>e||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(1>e||t[3]&&t[3]<1)return f(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"}function f(t,e){var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgba("+n+"%, "+i+"%, "+a+"%, "+(e||t[3]||1)+")"}function g(t,e){return 1>e||t[3]&&t[3]<1?p(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function v(t){return k[t.slice(0,3)]}function b(t,e,n){return Math.min(Math.max(e,t),n)}function y(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var x=t(5);e.exports={getRgba:i,getHsla:a,getRgb:o,getHsl:s,getHwb:r,getAlpha:l,hexString:u,rgbString:d,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:p,hwbString:m,keyword:v};var k={};for(var _ in x)k[x[_]]=_},{5:5}],2:[function(t,e,n){var i=t(4),a=t(1),r=function(t){if(t instanceof r)return t;if(!(this instanceof r))return new r(t);this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;if("string"==typeof t)if(e=a.getRgba(t))this.setValues("rgb",e);else if(e=a.getHsla(t))this.setValues("hsl",e);else{if(!(e=a.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}else if("object"==typeof t)if(e=t,void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}};r.prototype={rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=0>t?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=.03928>=i?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return 128>e},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;3>e;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=0>n?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=this,i=t,a=void 0===e?.5:e,r=2*a-1,o=n.alpha()-i.alpha(),s=((r*o===-1?r:(r+o)/(1+r*o))+1)/2,l=1-s;return this.rgb(s*n.red()+l*i.red(),s*n.green()+l*i.green(),s*n.blue()+l*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new r,i=this.values,a=n.values;for(var o in i)i.hasOwnProperty(o)&&(t=i[o],e={}.toString.call(t),"[object Array]"===e?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return n}},r.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},r.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},r.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},r.prototype.setValues=function(t,e){var n,a=this.values,r=this.spaces,o=this.maxes,s=1;if("alpha"===t)s=e;else if(e.length)a[t]=e.slice(0,t.length),s=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];s=e.a}else if(void 0!==e[r[t][0]]){var l=r[t];for(n=0;n<t.length;n++)a[t][n]=e[l[n]];s=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===s?a.alpha:s)),"alpha"===t)return!1;var u;for(n=0;n<t.length;n++)u=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(u);for(var d in r)d!==t&&(a[d]=i[t][d](a[t]));return!0},r.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},r.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=r),e.exports=r},{1:1,4:4}],3:[function(t,e,n){function i(t){var e,n,i,a=t[0]/255,r=t[1]/255,o=t[2]/255,s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),e=Math.min(60*e,360),0>e&&(e+=360),i=(s+l)/2,n=l==s?0:.5>=i?u/(l+s):u/(2-l-s),[e,100*n,100*i]}function a(t){var e,n,i,a=t[0],r=t[1],o=t[2],s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return n=0==l?0:u/l*1e3/10,l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),e=Math.min(60*e,360),0>e&&(e+=360),i=l/255*1e3/10,[e,n,i]}function o(t){var e=t[0],n=t[1],a=t[2],r=i(t)[0],o=1/255*Math.min(e,Math.min(n,a)),a=1-1/255*Math.max(e,Math.max(n,a));return[r,100*o,100*a]}function s(t){var e,n,i,a,r=t[0]/255,o=t[1]/255,s=t[2]/255;return a=Math.min(1-r,1-o,1-s),e=(1-r-a)/(1-a)||0,n=(1-o-a)/(1-a)||0,i=(1-s-a)/(1-a)||0,[100*e,100*n,100*i,100*a]}function l(t){return Q[JSON.stringify(t)]}function u(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var a=.4124*e+.3576*n+.1805*i,r=.2126*e+.7152*n+.0722*i,o=.0193*e+.1192*n+.9505*i;return[100*a,100*r,100*o]}function d(t){var e,n,i,a=u(t),r=a[0],o=a[1],s=a[2];return r/=95.047,o/=100,s/=108.883,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*o-16,n=500*(r-o),i=200*(o-s),[e,n,i]}function c(t){return Y(d(t))}function h(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return r=255*l,[r,r,r];n=.5>l?l*(1+s):l+s-l*s,e=2*l-n,a=[0,0,0];for(var u=0;3>u;u++)i=o+1/3*-(u-1),0>i&&i++,i>1&&i--,r=1>6*i?e+6*(n-e)*i:1>2*i?n:2>3*i?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a}function f(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return 0===r?[0,0,0]:(r*=2,a*=1>=r?r:2-r,n=(r+a)/2,e=2*a/(r+a),[i,100*e,100*n])}function p(t){return o(h(t))}function m(t){return s(h(t))}function v(t){return l(h(t))}function y(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r)),i=255*i;switch(a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}}function x(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return n=(2-a)*r,e=a*r,e/=1>=n?n:2-n,e=e||0,n/=2,[i,100*e,100*n]}function k(t){return o(y(t))}function _(t){return s(y(t))}function w(t){return l(y(t))}function S(t){var e,n,i,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),n=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),a=s+i*(n-s),e){default:case 6:case 0:r=n,g=a,b=s;break;case 1:r=a,g=n,b=s;break;case 2:r=s,g=n,b=a;break;case 3:r=s,g=a,b=n;break;case 4:r=a,g=s,b=n;break;case 5:r=n,g=s,b=a}return[255*r,255*g,255*b]}function M(t){return i(S(t))}function D(t){return a(S(t))}function C(t){return s(S(t))}function T(t){return l(S(t))}function P(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100,s=t[3]/100;return e=1-Math.min(1,a*(1-s)+s),n=1-Math.min(1,r*(1-s)+s),i=1-Math.min(1,o*(1-s)+s),[255*e,255*n,255*i]}function F(t){return i(P(t))}function A(t){return a(P(t))}function I(t){return o(P(t))}function O(t){return l(P(t))}function R(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return e=3.2406*a+-1.5372*r+o*-.4986,n=a*-.9689+1.8758*r+.0415*o,i=.0557*a+r*-.204+1.057*o,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e=12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n=12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i=12.92*i,e=Math.min(Math.max(0,e),1),n=Math.min(Math.max(0,n),1),i=Math.min(Math.max(0,i),1),[255*e,255*n,255*i]}function W(t){var e,n,i,a=t[0],r=t[1],o=t[2];return a/=95.047,r/=100,o/=108.883,a=a>.008856?Math.pow(a,1/3):7.787*a+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,e=116*r-16,n=500*(a-r),i=200*(r-o),[e,n,i]}function V(t){return Y(W(t))}function L(t){var e,n,i,a,r=t[0],o=t[1],s=t[2];return 8>=r?(n=100*r/903.3,a=7.787*(n/100)+16/116):(n=100*Math.pow((r+16)/116,3),a=Math.pow(n/100,1/3)),e=.008856>=e/95.047?e=95.047*(o/500+a-16/116)/7.787:95.047*Math.pow(o/500+a,3),i=.008859>=i/108.883?i=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3),[e,n,i]}function Y(t){var e,n,i,a=t[0],r=t[1],o=t[2];return e=Math.atan2(o,r),n=360*e/2/Math.PI,0>n&&(n+=360),i=Math.sqrt(r*r+o*o),[a,i,n]}function B(t){return R(L(t))}function z(t){var e,n,i,a=t[0],r=t[1],o=t[2];return i=o/360*2*Math.PI,e=r*Math.cos(i),n=r*Math.sin(i),[a,e,n]}function H(t){return L(z(t))}function N(t){return B(z(t))}function E(t){return X[t]}function U(t){return i(E(t))}function j(t){return a(E(t))}function G(t){return o(E(t))}function q(t){return s(E(t))}function Z(t){return d(E(t))}function J(t){return u(E(t))}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:y,hsv2hsl:x,hsv2hwb:k,hsv2cmyk:_,hsv2keyword:w,hwb2rgb:S,hwb2hsl:M,hwb2hsv:D,hwb2cmyk:C,hwb2keyword:T,cmyk2rgb:P,cmyk2hsl:F,cmyk2hsv:A,cmyk2hwb:I,cmyk2keyword:O,keyword2rgb:E,keyword2hsl:U,keyword2hsv:j,keyword2hwb:G,keyword2cmyk:q,keyword2lab:Z,keyword2xyz:J,xyz2rgb:R,xyz2lab:W,xyz2lch:V,lab2xyz:L,lab2rgb:B,lab2lch:Y,lch2lab:z,lch2xyz:H,lch2rgb:N};var X={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Q={};for(var $ in X)Q[JSON.stringify(X[$])]=$},{}],4:[function(t,e,n){var i=t(3),a=function(){return new u};for(var r in i){a[r+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(r);var o=/(\w+)2(\w+)/.exec(r),s=o[1],l=o[2];a[s]=a[s]||{},a[s][l]=a[r]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=i[t](e);if("string"==typeof n||void 0===n)return n;for(var a=0;a<n.length;a++)n[a]=Math.round(n[a]);return n}}(r)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var n=this.space,i=this.convs[n];e=a[n][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{3:3}],5:[function(t,e,n){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],6:[function(e,n,i){!function(e,a){"object"==typeof i&&"undefined"!=typeof n?n.exports=a():"function"==typeof t&&t.amd?t(a):e.moment=a()}(this,function(){"use strict";function t(){return li.apply(null,arguments)}function i(t){li=t}function a(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function r(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function o(t,e){var n,i=[];for(n=0;n<t.length;++n)i.push(e(t[n],n));return i}function s(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function l(t,e){for(var n in e)s(e,n)&&(t[n]=e[n]);return s(e,"toString")&&(t.toString=e.toString),s(e,"valueOf")&&(t.valueOf=e.valueOf),t}function u(t,e,n,i){return Lt(t,e,n,i,!0).utc()}function d(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null}}function c(t){return null==t._pf&&(t._pf=d()),t._pf}function h(t){if(null==t._isValid){var e=c(t),n=ui.call(e.parsedDateParts,function(t){return null!=t});t._isValid=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n),t._strict&&(t._isValid=t._isValid&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour)}return t._isValid}function f(t){var e=u(NaN);return null!=t?l(c(e),t):c(e).userInvalidated=!0,e}function g(t){return void 0===t}function p(t,e){var n,i,a;if(g(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),g(e._i)||(t._i=e._i),g(e._f)||(t._f=e._f),g(e._l)||(t._l=e._l),g(e._strict)||(t._strict=e._strict),g(e._tzm)||(t._tzm=e._tzm),g(e._isUTC)||(t._isUTC=e._isUTC),g(e._offset)||(t._offset=e._offset),g(e._pf)||(t._pf=c(e)),g(e._locale)||(t._locale=e._locale),di.length>0)for(n in di)i=di[n],a=e[i],g(a)||(t[i]=a);return t}function m(e){p(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),ci===!1&&(ci=!0,t.updateOffset(this),ci=!1)}function v(t){return t instanceof m||null!=t&&null!=t._isAMomentObject}function b(t){return 0>t?Math.ceil(t):Math.floor(t)}function y(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=b(e)),n}function x(t,e,n){var i,a=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),o=0;for(i=0;a>i;i++)(n&&t[i]!==e[i]||!n&&y(t[i])!==y(e[i]))&&o++;return o+r}function k(e){t.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function _(e,n){var i=!0;return l(function(){return null!=t.deprecationHandler&&t.deprecationHandler(null,e),i&&(k(e+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),i=!1),n.apply(this,arguments)},n)}function w(e,n){null!=t.deprecationHandler&&t.deprecationHandler(e,n),hi[e]||(k(n),hi[e]=!0)}function S(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function M(t){return"[object Object]"===Object.prototype.toString.call(t)}function D(t){var e,n;for(n in t)e=t[n],S(e)?this[n]=e:this["_"+n]=e;this._config=t,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function C(t,e){var n,i=l({},t);for(n in e)s(e,n)&&(M(t[n])&&M(e[n])?(i[n]={},l(i[n],t[n]),l(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);return i}function T(t){null!=t&&this.set(t)}function P(t){return t?t.toLowerCase().replace("_","-"):t}function F(t){for(var e,n,i,a,r=0;r<t.length;){for(a=P(t[r]).split("-"),e=a.length,n=P(t[r+1]),n=n?n.split("-"):null;e>0;){if(i=A(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&x(a,n,!0)>=e-1)break;e--}r++}return null}function A(t){var i=null;if(!mi[t]&&"undefined"!=typeof n&&n&&n.exports)try{i=gi._abbr,e("./locale/"+t),I(i)}catch(a){}return mi[t]}function I(t,e){var n;return t&&(n=g(e)?W(t):O(t,e),n&&(gi=n)),gi._abbr}function O(t,e){return null!==e?(e.abbr=t,null!=mi[t]?(w("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale"),e=C(mi[t]._config,e)):null!=e.parentLocale&&(null!=mi[e.parentLocale]?e=C(mi[e.parentLocale]._config,e):w("parentLocaleUndefined","specified parentLocale is not defined yet")),mi[t]=new T(e),I(t),mi[t]):(delete mi[t],null)}function R(t,e){if(null!=e){var n;null!=mi[t]&&(e=C(mi[t]._config,e)),n=new T(e),n.parentLocale=mi[t],mi[t]=n,I(t)}else null!=mi[t]&&(null!=mi[t].parentLocale?mi[t]=mi[t].parentLocale:null!=mi[t]&&delete mi[t]);return mi[t]}function W(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return gi;if(!a(t)){if(e=A(t))return e;t=[t]}return F(t)}function V(){return fi(mi)}function L(t,e){var n=t.toLowerCase();vi[n]=vi[n+"s"]=vi[e]=t}function Y(t){return"string"==typeof t?vi[t]||vi[t.toLowerCase()]:void 0}function B(t){var e,n,i={};for(n in t)s(t,n)&&(e=Y(n),e&&(i[e]=t[n]));return i}function z(e,n){return function(i){return null!=i?(N(this,e,i),t.updateOffset(this,n),this):H(this,e)}}function H(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function N(t,e,n){t.isValid()&&t._d["set"+(t._isUTC?"UTC":"")+e](n)}function E(t,e){var n;if("object"==typeof t)for(n in t)this.set(n,t[n]);else if(t=Y(t),S(this[t]))return this[t](e);return this}function U(t,e,n){var i=""+Math.abs(t),a=e-i.length,r=t>=0;return(r?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}function j(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(ki[t]=a),e&&(ki[e[0]]=function(){return U(a.apply(this,arguments),e[1],e[2])}),n&&(ki[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function G(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function q(t){var e,n,i=t.match(bi);for(e=0,n=i.length;n>e;e++)ki[i[e]]?i[e]=ki[i[e]]:i[e]=G(i[e]);return function(e){var a,r="";for(a=0;n>a;a++)r+=i[a]instanceof Function?i[a].call(e,t):i[a];return r}}function Z(t,e){return t.isValid()?(e=J(e,t.localeData()),xi[e]=xi[e]||q(e),xi[e](t)):t.localeData().invalidDate()}function J(t,e){function n(t){return e.longDateFormat(t)||t}var i=5;for(yi.lastIndex=0;i>=0&&yi.test(t);)t=t.replace(yi,n),yi.lastIndex=0,i-=1;return t}function X(t,e,n){Bi[t]=S(e)?e:function(t,i){return t&&n?n:e}}function Q(t,e){return s(Bi,t)?Bi[t](e._strict,e._locale):new RegExp($(t))}function $(t){return K(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,a){return e||n||i||a}))}function K(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tt(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),"number"==typeof e&&(i=function(t,n){n[e]=y(t)}),n=0;n<t.length;n++)zi[t[n]]=i}function et(t,e){tt(t,function(t,n,i,a){i._w=i._w||{},e(t,i._w,i,a)})}function nt(t,e,n){null!=e&&s(zi,t)&&zi[t](e,n._a,n,t)}function it(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function at(t,e){return a(this._months)?this._months[t.month()]:this._months[Xi.test(e)?"format":"standalone"][t.month()]}function rt(t,e){return a(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[Xi.test(e)?"format":"standalone"][t.month()]}function ot(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;12>i;++i)r=u([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?(a=pi.call(this._shortMonthsParse,o),-1!==a?a:null):(a=pi.call(this._longMonthsParse,o),-1!==a?a:null):"MMM"===e?(a=pi.call(this._shortMonthsParse,o),-1!==a?a:(a=pi.call(this._longMonthsParse,o),-1!==a?a:null)):(a=pi.call(this._longMonthsParse,o),-1!==a?a:(a=pi.call(this._shortMonthsParse,o),-1!==a?a:null))}function st(t,e,n){var i,a,r;if(this._monthsParseExact)return ot.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;12>i;i++){if(a=u([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}}function lt(t,e){var n;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=y(e);else if(e=t.localeData().monthsParse(e),"number"!=typeof e)return t;return n=Math.min(t.date(),it(t.year(),e)),
-t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),t}function ut(e){return null!=e?(lt(this,e),t.updateOffset(this,!0),this):H(this,"Month")}function dt(){return it(this.year(),this.month())}function ct(t){return this._monthsParseExact?(s(this,"_monthsRegex")||ft.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex}function ht(t){return this._monthsParseExact?(s(this,"_monthsRegex")||ft.call(this),t?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex}function ft(){function t(t,e){return e.length-t.length}var e,n,i=[],a=[],r=[];for(e=0;12>e;e++)n=u([2e3,e]),i.push(this.monthsShort(n,"")),a.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(i.sort(t),a.sort(t),r.sort(t),e=0;12>e;e++)i[e]=K(i[e]),a[e]=K(a[e]),r[e]=K(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+i.join("|")+")","i")}function gt(t){var e,n=t._a;return n&&-2===c(t).overflow&&(e=n[Ni]<0||n[Ni]>11?Ni:n[Ei]<1||n[Ei]>it(n[Hi],n[Ni])?Ei:n[Ui]<0||n[Ui]>24||24===n[Ui]&&(0!==n[ji]||0!==n[Gi]||0!==n[qi])?Ui:n[ji]<0||n[ji]>59?ji:n[Gi]<0||n[Gi]>59?Gi:n[qi]<0||n[qi]>999?qi:-1,c(t)._overflowDayOfYear&&(Hi>e||e>Ei)&&(e=Ei),c(t)._overflowWeeks&&-1===e&&(e=Zi),c(t)._overflowWeekday&&-1===e&&(e=Ji),c(t).overflow=e),t}function pt(t){var e,n,i,a,r,o,s=t._i,l=ea.exec(s)||na.exec(s);if(l){for(c(t).iso=!0,e=0,n=aa.length;n>e;e++)if(aa[e][1].exec(l[1])){a=aa[e][0],i=aa[e][2]!==!1;break}if(null==a)return void(t._isValid=!1);if(l[3]){for(e=0,n=ra.length;n>e;e++)if(ra[e][1].exec(l[3])){r=(l[2]||" ")+ra[e][0];break}if(null==r)return void(t._isValid=!1)}if(!i&&null!=r)return void(t._isValid=!1);if(l[4]){if(!ia.exec(l[4]))return void(t._isValid=!1);o="Z"}t._f=a+(r||"")+(o||""),Ft(t)}else t._isValid=!1}function mt(e){var n=oa.exec(e._i);return null!==n?void(e._d=new Date(+n[1])):(pt(e),void(e._isValid===!1&&(delete e._isValid,t.createFromInputFallback(e))))}function vt(t,e,n,i,a,r,o){var s=new Date(t,e,n,i,a,r,o);return 100>t&&t>=0&&isFinite(s.getFullYear())&&s.setFullYear(t),s}function bt(t){var e=new Date(Date.UTC.apply(null,arguments));return 100>t&&t>=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function yt(t){return xt(t)?366:365}function xt(t){return t%4===0&&t%100!==0||t%400===0}function kt(){return xt(this.year())}function _t(t,e,n){var i=7+e-n,a=(7+bt(t,0,i).getUTCDay()-e)%7;return-a+i-1}function wt(t,e,n,i,a){var r,o,s=(7+n-i)%7,l=_t(t,i,a),u=1+7*(e-1)+s+l;return 0>=u?(r=t-1,o=yt(r)+u):u>yt(t)?(r=t+1,o=u-yt(t)):(r=t,o=u),{year:r,dayOfYear:o}}function St(t,e,n){var i,a,r=_t(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return 1>o?(a=t.year()-1,i=o+Mt(a,e,n)):o>Mt(t.year(),e,n)?(i=o-Mt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Mt(t,e,n){var i=_t(t,e,n),a=_t(t+1,e,n);return(yt(t)-i+a)/7}function Dt(t,e,n){return null!=t?t:null!=e?e:n}function Ct(e){var n=new Date(t.now());return e._useUTC?[n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()]:[n.getFullYear(),n.getMonth(),n.getDate()]}function Tt(t){var e,n,i,a,r=[];if(!t._d){for(i=Ct(t),t._w&&null==t._a[Ei]&&null==t._a[Ni]&&Pt(t),t._dayOfYear&&(a=Dt(t._a[Hi],i[Hi]),t._dayOfYear>yt(a)&&(c(t)._overflowDayOfYear=!0),n=bt(a,0,t._dayOfYear),t._a[Ni]=n.getUTCMonth(),t._a[Ei]=n.getUTCDate()),e=0;3>e&&null==t._a[e];++e)t._a[e]=r[e]=i[e];for(;7>e;e++)t._a[e]=r[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[Ui]&&0===t._a[ji]&&0===t._a[Gi]&&0===t._a[qi]&&(t._nextDay=!0,t._a[Ui]=0),t._d=(t._useUTC?bt:vt).apply(null,r),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[Ui]=24)}}function Pt(t){var e,n,i,a,r,o,s,l;e=t._w,null!=e.GG||null!=e.W||null!=e.E?(r=1,o=4,n=Dt(e.GG,t._a[Hi],St(Yt(),1,4).year),i=Dt(e.W,1),a=Dt(e.E,1),(1>a||a>7)&&(l=!0)):(r=t._locale._week.dow,o=t._locale._week.doy,n=Dt(e.gg,t._a[Hi],St(Yt(),r,o).year),i=Dt(e.w,1),null!=e.d?(a=e.d,(0>a||a>6)&&(l=!0)):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r),1>i||i>Mt(n,r,o)?c(t)._overflowWeeks=!0:null!=l?c(t)._overflowWeekday=!0:(s=wt(n,i,a,r,o),t._a[Hi]=s.year,t._dayOfYear=s.dayOfYear)}function Ft(e){if(e._f===t.ISO_8601)return void pt(e);e._a=[],c(e).empty=!0;var n,i,a,r,o,s=""+e._i,l=s.length,u=0;for(a=J(e._f,e._locale).match(bi)||[],n=0;n<a.length;n++)r=a[n],i=(s.match(Q(r,e))||[])[0],i&&(o=s.substr(0,s.indexOf(i)),o.length>0&&c(e).unusedInput.push(o),s=s.slice(s.indexOf(i)+i.length),u+=i.length),ki[r]?(i?c(e).empty=!1:c(e).unusedTokens.push(r),nt(r,i,e)):e._strict&&!i&&c(e).unusedTokens.push(r);c(e).charsLeftOver=l-u,s.length>0&&c(e).unusedInput.push(s),c(e).bigHour===!0&&e._a[Ui]<=12&&e._a[Ui]>0&&(c(e).bigHour=void 0),c(e).parsedDateParts=e._a.slice(0),c(e).meridiem=e._meridiem,e._a[Ui]=At(e._locale,e._a[Ui],e._meridiem),Tt(e),gt(e)}function At(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?(i=t.isPM(n),i&&12>e&&(e+=12),i||12!==e||(e=0),e):e}function It(t){var e,n,i,a,r;if(0===t._f.length)return c(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;a<t._f.length;a++)r=0,e=p({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[a],Ft(e),h(e)&&(r+=c(e).charsLeftOver,r+=10*c(e).unusedTokens.length,c(e).score=r,(null==i||i>r)&&(i=r,n=e));l(t,n||e)}function Ot(t){if(!t._d){var e=B(t._i);t._a=o([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)}),Tt(t)}}function Rt(t){var e=new m(gt(Wt(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function Wt(t){var e=t._i,n=t._f;return t._locale=t._locale||W(t._l),null===e||void 0===n&&""===e?f({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),v(e)?new m(gt(e)):(a(n)?It(t):n?Ft(t):r(e)?t._d=e:Vt(t),h(t)||(t._d=null),t))}function Vt(e){var n=e._i;void 0===n?e._d=new Date(t.now()):r(n)?e._d=new Date(n.valueOf()):"string"==typeof n?mt(e):a(n)?(e._a=o(n.slice(0),function(t){return parseInt(t,10)}),Tt(e)):"object"==typeof n?Ot(e):"number"==typeof n?e._d=new Date(n):t.createFromInputFallback(e)}function Lt(t,e,n,i,a){var r={};return"boolean"==typeof n&&(i=n,n=void 0),r._isAMomentObject=!0,r._useUTC=r._isUTC=a,r._l=n,r._i=t,r._f=e,r._strict=i,Rt(r)}function Yt(t,e,n,i){return Lt(t,e,n,i,!1)}function Bt(t,e){var n,i;if(1===e.length&&a(e[0])&&(e=e[0]),!e.length)return Yt();for(n=e[0],i=1;i<e.length;++i)(!e[i].isValid()||e[i][t](n))&&(n=e[i]);return n}function zt(){var t=[].slice.call(arguments,0);return Bt("isBefore",t)}function Ht(){var t=[].slice.call(arguments,0);return Bt("isAfter",t)}function Nt(t){var e=B(t),n=e.year||0,i=e.quarter||0,a=e.month||0,r=e.week||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._milliseconds=+d+1e3*u+6e4*l+1e3*s*60*60,this._days=+o+7*r,this._months=+a+3*i+12*n,this._data={},this._locale=W(),this._bubble()}function Et(t){return t instanceof Nt}function Ut(t,e){j(t,0,0,function(){var t=this.utcOffset(),n="+";return 0>t&&(t=-t,n="-"),n+U(~~(t/60),2)+e+U(~~t%60,2)})}function jt(t,e){var n=(e||"").match(t)||[],i=n[n.length-1]||[],a=(i+"").match(ca)||["-",0,0],r=+(60*a[1])+y(a[2]);return"+"===a[0]?r:-r}function Gt(e,n){var i,a;return n._isUTC?(i=n.clone(),a=(v(e)||r(e)?e.valueOf():Yt(e).valueOf())-i.valueOf(),i._d.setTime(i._d.valueOf()+a),t.updateOffset(i,!1),i):Yt(e).local()}function qt(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Zt(e,n){var i,a=this._offset||0;return this.isValid()?null!=e?("string"==typeof e?e=jt(Vi,e):Math.abs(e)<16&&(e=60*e),!this._isUTC&&n&&(i=qt(this)),this._offset=e,this._isUTC=!0,null!=i&&this.add(i,"m"),a!==e&&(!n||this._changeInProgress?ce(this,re(e-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,t.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?a:qt(this):null!=e?this:NaN}function Jt(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}function Xt(t){return this.utcOffset(0,t)}function Qt(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(qt(this),"m")),this}function $t(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(jt(Wi,this._i)),this}function Kt(t){return this.isValid()?(t=t?Yt(t).utcOffset():0,(this.utcOffset()-t)%60===0):!1}function te(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function ee(){if(!g(this._isDSTShifted))return this._isDSTShifted;var t={};if(p(t,this),t=Wt(t),t._a){var e=t._isUTC?u(t._a):Yt(t._a);this._isDSTShifted=this.isValid()&&x(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function ne(){return this.isValid()?!this._isUTC:!1}function ie(){return this.isValid()?this._isUTC:!1}function ae(){return this.isValid()?this._isUTC&&0===this._offset:!1}function re(t,e){var n,i,a,r=t,o=null;return Et(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:"number"==typeof t?(r={},e?r[e]=t:r.milliseconds=t):(o=ha.exec(t))?(n="-"===o[1]?-1:1,r={y:0,d:y(o[Ei])*n,h:y(o[Ui])*n,m:y(o[ji])*n,s:y(o[Gi])*n,ms:y(o[qi])*n}):(o=fa.exec(t))?(n="-"===o[1]?-1:1,r={y:oe(o[2],n),M:oe(o[3],n),w:oe(o[4],n),d:oe(o[5],n),h:oe(o[6],n),m:oe(o[7],n),s:oe(o[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(a=le(Yt(r.from),Yt(r.to)),r={},r.ms=a.milliseconds,r.M=a.months),i=new Nt(r),Et(t)&&s(t,"_locale")&&(i._locale=t._locale),i}function oe(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function se(t,e){var n={milliseconds:0,months:0};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function le(t,e){var n;return t.isValid()&&e.isValid()?(e=Gt(e,t),t.isBefore(e)?n=se(t,e):(n=se(e,t),n.milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function ue(t){return 0>t?-1*Math.round(-1*t):Math.round(t)}function de(t,e){return function(n,i){var a,r;return null===i||isNaN(+i)||(w(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period)."),r=n,n=i,i=r),n="string"==typeof n?+n:n,a=re(n,i),ce(this,a,t),this}}function ce(e,n,i,a){var r=n._milliseconds,o=ue(n._days),s=ue(n._months);e.isValid()&&(a=null==a?!0:a,r&&e._d.setTime(e._d.valueOf()+r*i),o&&N(e,"Date",H(e,"Date")+o*i),s&<(e,H(e,"Month")+s*i),a&&t.updateOffset(e,o||s))}function he(t,e){var n=t||Yt(),i=Gt(n,this).startOf("day"),a=this.diff(i,"days",!0),r=-6>a?"sameElse":-1>a?"lastWeek":0>a?"lastDay":1>a?"sameDay":2>a?"nextDay":7>a?"nextWeek":"sameElse",o=e&&(S(e[r])?e[r]():e[r]);return this.format(o||this.localeData().calendar(r,this,Yt(n)))}function fe(){return new m(this)}function ge(t,e){var n=v(t)?t:Yt(t);return this.isValid()&&n.isValid()?(e=Y(g(e)?"millisecond":e),"millisecond"===e?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(e).valueOf()):!1}function pe(t,e){var n=v(t)?t:Yt(t);return this.isValid()&&n.isValid()?(e=Y(g(e)?"millisecond":e),"millisecond"===e?this.valueOf()<n.valueOf():this.clone().endOf(e).valueOf()<n.valueOf()):!1}function me(t,e,n,i){return i=i||"()",("("===i[0]?this.isAfter(t,n):!this.isBefore(t,n))&&(")"===i[1]?this.isBefore(e,n):!this.isAfter(e,n))}function ve(t,e){var n,i=v(t)?t:Yt(t);return this.isValid()&&i.isValid()?(e=Y(e||"millisecond"),"millisecond"===e?this.valueOf()===i.valueOf():(n=i.valueOf(),this.clone().startOf(e).valueOf()<=n&&n<=this.clone().endOf(e).valueOf())):!1}function be(t,e){return this.isSame(t,e)||this.isAfter(t,e)}function ye(t,e){return this.isSame(t,e)||this.isBefore(t,e)}function xe(t,e,n){var i,a,r,o;return this.isValid()?(i=Gt(t,this),i.isValid()?(a=6e4*(i.utcOffset()-this.utcOffset()),e=Y(e),"year"===e||"month"===e||"quarter"===e?(o=ke(this,i),"quarter"===e?o/=3:"year"===e&&(o/=12)):(r=this-i,o="second"===e?r/1e3:"minute"===e?r/6e4:"hour"===e?r/36e5:"day"===e?(r-a)/864e5:"week"===e?(r-a)/6048e5:r),n?o:b(o)):NaN):NaN}function ke(t,e){var n,i,a=12*(e.year()-t.year())+(e.month()-t.month()),r=t.clone().add(a,"months");return 0>e-r?(n=t.clone().add(a-1,"months"),i=(e-r)/(r-n)):(n=t.clone().add(a+1,"months"),i=(e-r)/(n-r)),-(a+i)||0}function _e(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function we(){var t=this.clone().utc();return 0<t.year()&&t.year()<=9999?S(Date.prototype.toISOString)?this.toDate().toISOString():Z(t,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):Z(t,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function Se(e){e||(e=this.isUtc()?t.defaultFormatUtc:t.defaultFormat);var n=Z(this,e);return this.localeData().postformat(n)}function Me(t,e){return this.isValid()&&(v(t)&&t.isValid()||Yt(t).isValid())?re({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function De(t){return this.from(Yt(),t)}function Ce(t,e){return this.isValid()&&(v(t)&&t.isValid()||Yt(t).isValid())?re({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function Te(t){return this.to(Yt(),t)}function Pe(t){var e;return void 0===t?this._locale._abbr:(e=W(t),null!=e&&(this._locale=e),this)}function Fe(){return this._locale}function Ae(t){switch(t=Y(t)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===t&&this.weekday(0),"isoWeek"===t&&this.isoWeekday(1),"quarter"===t&&this.month(3*Math.floor(this.month()/3)),this}function Ie(t){return t=Y(t),void 0===t||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))}function Oe(){return this._d.valueOf()-6e4*(this._offset||0)}function Re(){return Math.floor(this.valueOf()/1e3)}function We(){return this._offset?new Date(this.valueOf()):this._d}function Ve(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]}function Le(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}}function Ye(){return this.isValid()?this.toISOString():null}function Be(){return h(this)}function ze(){return l({},c(this))}function He(){return c(this).overflow}function Ne(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Ee(t,e){j(0,[t,t.length],0,e)}function Ue(t){return Ze.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function je(t){return Ze.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)}function Ge(){return Mt(this.year(),1,4)}function qe(){var t=this.localeData()._week;return Mt(this.year(),t.dow,t.doy)}function Ze(t,e,n,i,a){var r;return null==t?St(this,i,a).year:(r=Mt(t,i,a),e>r&&(e=r),Je.call(this,t,e,n,i,a))}function Je(t,e,n,i,a){var r=wt(t,e,n,i,a),o=bt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function Xe(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)}function Qe(t){return St(t,this._week.dow,this._week.doy).week}function $e(){return this._week.dow}function Ke(){return this._week.doy}function tn(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")}function en(t){var e=St(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")}function nn(t,e){return"string"!=typeof t?t:isNaN(t)?(t=e.weekdaysParse(t),"number"==typeof t?t:null):parseInt(t,10)}function an(t,e){return a(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]}function rn(t){return this._weekdaysShort[t.day()]}function on(t){return this._weekdaysMin[t.day()]}function sn(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;7>i;++i)r=u([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?(a=pi.call(this._weekdaysParse,o),-1!==a?a:null):"ddd"===e?(a=pi.call(this._shortWeekdaysParse,o),-1!==a?a:null):(a=pi.call(this._minWeekdaysParse,o),-1!==a?a:null):"dddd"===e?(a=pi.call(this._weekdaysParse,o),-1!==a?a:(a=pi.call(this._shortWeekdaysParse,o),-1!==a?a:(a=pi.call(this._minWeekdaysParse,o),-1!==a?a:null))):"ddd"===e?(a=pi.call(this._shortWeekdaysParse,o),-1!==a?a:(a=pi.call(this._weekdaysParse,o),-1!==a?a:(a=pi.call(this._minWeekdaysParse,o),-1!==a?a:null))):(a=pi.call(this._minWeekdaysParse,o),-1!==a?a:(a=pi.call(this._weekdaysParse,o),-1!==a?a:(a=pi.call(this._shortWeekdaysParse,o),-1!==a?a:null)))}function ln(t,e,n){var i,a,r;if(this._weekdaysParseExact)return sn.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;7>i;i++){if(a=u([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".",".?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}}function un(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=nn(t,this.localeData()),this.add(t-e,"d")):e}function dn(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")}function cn(t){return this.isValid()?null==t?this.day()||7:this.day(this.day()%7?t:t-7):null!=t?this:NaN}function hn(t){return this._weekdaysParseExact?(s(this,"_weekdaysRegex")||pn.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex}function fn(t){return this._weekdaysParseExact?(s(this,"_weekdaysRegex")||pn.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex}function gn(t){return this._weekdaysParseExact?(s(this,"_weekdaysRegex")||pn.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex}function pn(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],d=[];for(e=0;7>e;e++)n=u([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),d.push(i),d.push(a),d.push(r);for(o.sort(t),s.sort(t),l.sort(t),d.sort(t),e=0;7>e;e++)s[e]=K(s[e]),l[e]=K(l[e]),d[e]=K(d[e]);this._weekdaysRegex=new RegExp("^("+d.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function mn(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")}function vn(){return this.hours()%12||12}function bn(){return this.hours()||24}function yn(t,e){j(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function xn(t,e){return e._meridiemParse}function kn(t){return"p"===(t+"").toLowerCase().charAt(0)}function _n(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"}function wn(t,e){e[qi]=y(1e3*("0."+t))}function Sn(){return this._isUTC?"UTC":""}function Mn(){return this._isUTC?"Coordinated Universal Time":""}function Dn(t){return Yt(1e3*t)}function Cn(){return Yt.apply(null,arguments).parseZone()}function Tn(t,e,n){var i=this._calendar[t];return S(i)?i.call(e,n):i}function Pn(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])}function Fn(){return this._invalidDate}function An(t){return this._ordinal.replace("%d",t)}function In(t){return t}function On(t,e,n,i){var a=this._relativeTime[n];return S(a)?a(t,e,n,i):a.replace(/%d/i,t)}function Rn(t,e){var n=this._relativeTime[t>0?"future":"past"];return S(n)?n(e):n.replace(/%s/i,e)}function Wn(t,e,n,i){var a=W(),r=u().set(i,e);return a[n](r,t)}function Vn(t,e,n){if("number"==typeof t&&(e=t,t=void 0),t=t||"",null!=e)return Wn(t,e,n,"month");var i,a=[];for(i=0;12>i;i++)a[i]=Wn(t,i,n,"month");return a}function Ln(t,e,n,i){"boolean"==typeof t?("number"==typeof e&&(n=e,e=void 0),e=e||""):(e=t,n=e,t=!1,"number"==typeof e&&(n=e,e=void 0),e=e||"");var a=W(),r=t?a._week.dow:0;if(null!=n)return Wn(e,(n+r)%7,i,"day");var o,s=[];for(o=0;7>o;o++)s[o]=Wn(e,(o+r)%7,i,"day");return s}function Yn(t,e){return Vn(t,e,"months")}function Bn(t,e){return Vn(t,e,"monthsShort")}function zn(t,e,n){return Ln(t,e,n,"weekdays")}function Hn(t,e,n){return Ln(t,e,n,"weekdaysShort")}function Nn(t,e,n){return Ln(t,e,n,"weekdaysMin")}function En(){var t=this._data;return this._milliseconds=za(this._milliseconds),this._days=za(this._days),this._months=za(this._months),t.milliseconds=za(t.milliseconds),t.seconds=za(t.seconds),t.minutes=za(t.minutes),t.hours=za(t.hours),t.months=za(t.months),t.years=za(t.years),this}function Un(t,e,n,i){var a=re(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function jn(t,e){return Un(this,t,e,1)}function Gn(t,e){return Un(this,t,e,-1)}function qn(t){return 0>t?Math.floor(t):Math.ceil(t)}function Zn(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||0>=r&&0>=o&&0>=s||(r+=864e5*qn(Xn(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=b(r/1e3),l.seconds=t%60,e=b(t/60),l.minutes=e%60,n=b(e/60),l.hours=n%24,o+=b(n/24),a=b(Jn(o)),s+=a,o-=qn(Xn(a)),i=b(s/12),s%=12,l.days=o,l.months=s,l.years=i,this}function Jn(t){return 4800*t/146097}function Xn(t){return 146097*t/4800}function Qn(t){var e,n,i=this._milliseconds;if(t=Y(t),"month"===t||"year"===t)return e=this._days+i/864e5,n=this._months+Jn(e),"month"===t?n:n/12;switch(e=this._days+Math.round(Xn(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}}function $n(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*y(this._months/12)}function Kn(t){return function(){return this.as(t)}}function ti(t){return t=Y(t),this[t+"s"]()}function ei(t){return function(){return this._data[t]}}function ni(){return b(this.days()/7)}function ii(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}function ai(t,e,n){var i=re(t).abs(),a=nr(i.as("s")),r=nr(i.as("m")),o=nr(i.as("h")),s=nr(i.as("d")),l=nr(i.as("M")),u=nr(i.as("y")),d=a<ir.s&&["s",a]||1>=r&&["m"]||r<ir.m&&["mm",r]||1>=o&&["h"]||o<ir.h&&["hh",o]||1>=s&&["d"]||s<ir.d&&["dd",s]||1>=l&&["M"]||l<ir.M&&["MM",l]||1>=u&&["y"]||["yy",u];return d[2]=e,d[3]=+t>0,d[4]=n,ii.apply(null,d)}function ri(t,e){return void 0===ir[t]?!1:void 0===e?ir[t]:(ir[t]=e,!0)}function oi(t){var e=this.localeData(),n=ai(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)}function si(){var t,e,n,i=ar(this._milliseconds)/1e3,a=ar(this._days),r=ar(this._months);t=b(i/60),e=b(t/60),i%=60,t%=60,n=b(r/12),r%=12;var o=n,s=r,l=a,u=e,d=t,c=i,h=this.asSeconds();return h?(0>h?"-":"")+"P"+(o?o+"Y":"")+(s?s+"M":"")+(l?l+"D":"")+(u||d||c?"T":"")+(u?u+"H":"")+(d?d+"M":"")+(c?c+"S":""):"P0D"}var li,ui;ui=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this),n=e.length>>>0,i=0;n>i;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1};var di=t.momentProperties=[],ci=!1,hi={};t.suppressDeprecationWarnings=!1,t.deprecationHandler=null;var fi;fi=Object.keys?Object.keys:function(t){var e,n=[];for(e in t)s(t,e)&&n.push(e);return n};var gi,pi,mi={},vi={},bi=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,yi=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,xi={},ki={},_i=/\d/,wi=/\d\d/,Si=/\d{3}/,Mi=/\d{4}/,Di=/[+-]?\d{6}/,Ci=/\d\d?/,Ti=/\d\d\d\d?/,Pi=/\d\d\d\d\d\d?/,Fi=/\d{1,3}/,Ai=/\d{1,4}/,Ii=/[+-]?\d{1,6}/,Oi=/\d+/,Ri=/[+-]?\d+/,Wi=/Z|[+-]\d\d:?\d\d/gi,Vi=/Z|[+-]\d\d(?::?\d\d)?/gi,Li=/[+-]?\d+(\.\d{1,3})?/,Yi=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Bi={},zi={},Hi=0,Ni=1,Ei=2,Ui=3,ji=4,Gi=5,qi=6,Zi=7,Ji=8;pi=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1},j("M",["MM",2],"Mo",function(){return this.month()+1}),j("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),j("MMMM",0,0,function(t){return this.localeData().months(this,t)}),L("month","M"),X("M",Ci),X("MM",Ci,wi),X("MMM",function(t,e){return e.monthsShortRegex(t)}),X("MMMM",function(t,e){return e.monthsRegex(t)}),tt(["M","MM"],function(t,e){e[Ni]=y(t)-1}),tt(["MMM","MMMM"],function(t,e,n,i){var a=n._locale.monthsParse(t,i,n._strict);null!=a?e[Ni]=a:c(n).invalidMonth=t});var Xi=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,Qi="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),$i="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Ki=Yi,ta=Yi,ea=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,na=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,ia=/Z|[+-]\d\d(?::?\d\d)?/,aa=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],ra=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],oa=/^\/?Date\((\-?\d+)/i;t.createFromInputFallback=_("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),j("Y",0,0,function(){var t=this.year();return 9999>=t?""+t:"+"+t}),j(0,["YY",2],0,function(){return this.year()%100}),j(0,["YYYY",4],0,"year"),j(0,["YYYYY",5],0,"year"),j(0,["YYYYYY",6,!0],0,"year"),L("year","y"),X("Y",Ri),X("YY",Ci,wi),X("YYYY",Ai,Mi),X("YYYYY",Ii,Di),X("YYYYYY",Ii,Di),tt(["YYYYY","YYYYYY"],Hi),tt("YYYY",function(e,n){n[Hi]=2===e.length?t.parseTwoDigitYear(e):y(e)}),tt("YY",function(e,n){n[Hi]=t.parseTwoDigitYear(e)}),tt("Y",function(t,e){e[Hi]=parseInt(t,10)}),t.parseTwoDigitYear=function(t){return y(t)+(y(t)>68?1900:2e3)};var sa=z("FullYear",!0);t.ISO_8601=function(){};var la=_("moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var t=Yt.apply(null,arguments);return this.isValid()&&t.isValid()?this>t?this:t:f()}),ua=_("moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var t=Yt.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:f()}),da=function(){return Date.now?Date.now():+new Date};Ut("Z",":"),Ut("ZZ",""),X("Z",Vi),X("ZZ",Vi),tt(["Z","ZZ"],function(t,e,n){n._useUTC=!0,n._tzm=jt(Vi,t)});var ca=/([\+\-]|\d\d)/gi;t.updateOffset=function(){};var ha=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,fa=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;re.fn=Nt.prototype;var ga=de(1,"add"),pa=de(-1,"subtract");t.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",t.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var ma=_("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});j(0,["gg",2],0,function(){return this.weekYear()%100}),j(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Ee("gggg","weekYear"),Ee("ggggg","weekYear"),Ee("GGGG","isoWeekYear"),Ee("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),X("G",Ri),X("g",Ri),X("GG",Ci,wi),X("gg",Ci,wi),X("GGGG",Ai,Mi),X("gggg",Ai,Mi),X("GGGGG",Ii,Di),X("ggggg",Ii,Di),et(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=y(t)}),et(["gg","GG"],function(e,n,i,a){n[a]=t.parseTwoDigitYear(e)}),j("Q",0,"Qo","quarter"),L("quarter","Q"),X("Q",_i),tt("Q",function(t,e){e[Ni]=3*(y(t)-1)}),j("w",["ww",2],"wo","week"),j("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),X("w",Ci),X("ww",Ci,wi),X("W",Ci),X("WW",Ci,wi),et(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=y(t)});var va={dow:0,doy:6};j("D",["DD",2],"Do","date"),L("date","D"),X("D",Ci),X("DD",Ci,wi),X("Do",function(t,e){return t?e._ordinalParse:e._ordinalParseLenient}),tt(["D","DD"],Ei),tt("Do",function(t,e){e[Ei]=y(t.match(Ci)[0],10)});var ba=z("Date",!0);j("d",0,"do","day"),j("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),j("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),j("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),j("e",0,0,"weekday"),j("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),X("d",Ci),X("e",Ci),X("E",Ci),X("dd",function(t,e){return e.weekdaysMinRegex(t)}),X("ddd",function(t,e){return e.weekdaysShortRegex(t)}),X("dddd",function(t,e){return e.weekdaysRegex(t)}),et(["dd","ddd","dddd"],function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:c(n).invalidWeekday=t}),et(["d","e","E"],function(t,e,n,i){e[i]=y(t)});var ya="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),xa="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),ka="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),_a=Yi,wa=Yi,Sa=Yi;j("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),X("DDD",Fi),X("DDDD",Si),tt(["DDD","DDDD"],function(t,e,n){n._dayOfYear=y(t)}),j("H",["HH",2],0,"hour"),j("h",["hh",2],0,vn),j("k",["kk",2],0,bn),j("hmm",0,0,function(){return""+vn.apply(this)+U(this.minutes(),2)}),j("hmmss",0,0,function(){return""+vn.apply(this)+U(this.minutes(),2)+U(this.seconds(),2)}),j("Hmm",0,0,function(){return""+this.hours()+U(this.minutes(),2)}),j("Hmmss",0,0,function(){return""+this.hours()+U(this.minutes(),2)+U(this.seconds(),2)}),yn("a",!0),yn("A",!1),L("hour","h"),X("a",xn),X("A",xn),X("H",Ci),X("h",Ci),X("HH",Ci,wi),X("hh",Ci,wi),X("hmm",Ti),X("hmmss",Pi),X("Hmm",Ti),X("Hmmss",Pi),tt(["H","HH"],Ui),tt(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),tt(["h","hh"],function(t,e,n){e[Ui]=y(t),c(n).bigHour=!0}),tt("hmm",function(t,e,n){var i=t.length-2;e[Ui]=y(t.substr(0,i)),e[ji]=y(t.substr(i)),
-c(n).bigHour=!0}),tt("hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[Ui]=y(t.substr(0,i)),e[ji]=y(t.substr(i,2)),e[Gi]=y(t.substr(a)),c(n).bigHour=!0}),tt("Hmm",function(t,e,n){var i=t.length-2;e[Ui]=y(t.substr(0,i)),e[ji]=y(t.substr(i))}),tt("Hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[Ui]=y(t.substr(0,i)),e[ji]=y(t.substr(i,2)),e[Gi]=y(t.substr(a))});var Ma=/[ap]\.?m?\.?/i,Da=z("Hours",!0);j("m",["mm",2],0,"minute"),L("minute","m"),X("m",Ci),X("mm",Ci,wi),tt(["m","mm"],ji);var Ca=z("Minutes",!1);j("s",["ss",2],0,"second"),L("second","s"),X("s",Ci),X("ss",Ci,wi),tt(["s","ss"],Gi);var Ta=z("Seconds",!1);j("S",0,0,function(){return~~(this.millisecond()/100)}),j(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),j(0,["SSS",3],0,"millisecond"),j(0,["SSSS",4],0,function(){return 10*this.millisecond()}),j(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),j(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),j(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),j(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),j(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),L("millisecond","ms"),X("S",Fi,_i),X("SS",Fi,wi),X("SSS",Fi,Si);var Pa;for(Pa="SSSS";Pa.length<=9;Pa+="S")X(Pa,Oi);for(Pa="S";Pa.length<=9;Pa+="S")tt(Pa,wn);var Fa=z("Milliseconds",!1);j("z",0,0,"zoneAbbr"),j("zz",0,0,"zoneName");var Aa=m.prototype;Aa.add=ga,Aa.calendar=he,Aa.clone=fe,Aa.diff=xe,Aa.endOf=Ie,Aa.format=Se,Aa.from=Me,Aa.fromNow=De,Aa.to=Ce,Aa.toNow=Te,Aa.get=E,Aa.invalidAt=He,Aa.isAfter=ge,Aa.isBefore=pe,Aa.isBetween=me,Aa.isSame=ve,Aa.isSameOrAfter=be,Aa.isSameOrBefore=ye,Aa.isValid=Be,Aa.lang=ma,Aa.locale=Pe,Aa.localeData=Fe,Aa.max=ua,Aa.min=la,Aa.parsingFlags=ze,Aa.set=E,Aa.startOf=Ae,Aa.subtract=pa,Aa.toArray=Ve,Aa.toObject=Le,Aa.toDate=We,Aa.toISOString=we,Aa.toJSON=Ye,Aa.toString=_e,Aa.unix=Re,Aa.valueOf=Oe,Aa.creationData=Ne,Aa.year=sa,Aa.isLeapYear=kt,Aa.weekYear=Ue,Aa.isoWeekYear=je,Aa.quarter=Aa.quarters=Xe,Aa.month=ut,Aa.daysInMonth=dt,Aa.week=Aa.weeks=tn,Aa.isoWeek=Aa.isoWeeks=en,Aa.weeksInYear=qe,Aa.isoWeeksInYear=Ge,Aa.date=ba,Aa.day=Aa.days=un,Aa.weekday=dn,Aa.isoWeekday=cn,Aa.dayOfYear=mn,Aa.hour=Aa.hours=Da,Aa.minute=Aa.minutes=Ca,Aa.second=Aa.seconds=Ta,Aa.millisecond=Aa.milliseconds=Fa,Aa.utcOffset=Zt,Aa.utc=Xt,Aa.local=Qt,Aa.parseZone=$t,Aa.hasAlignedHourOffset=Kt,Aa.isDST=te,Aa.isDSTShifted=ee,Aa.isLocal=ne,Aa.isUtcOffset=ie,Aa.isUtc=ae,Aa.isUTC=ae,Aa.zoneAbbr=Sn,Aa.zoneName=Mn,Aa.dates=_("dates accessor is deprecated. Use date instead.",ba),Aa.months=_("months accessor is deprecated. Use month instead",ut),Aa.years=_("years accessor is deprecated. Use year instead",sa),Aa.zone=_("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Jt);var Ia=Aa,Oa={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Ra={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Wa="Invalid date",Va="%d",La=/\d{1,2}/,Ya={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Ba=T.prototype;Ba._calendar=Oa,Ba.calendar=Tn,Ba._longDateFormat=Ra,Ba.longDateFormat=Pn,Ba._invalidDate=Wa,Ba.invalidDate=Fn,Ba._ordinal=Va,Ba.ordinal=An,Ba._ordinalParse=La,Ba.preparse=In,Ba.postformat=In,Ba._relativeTime=Ya,Ba.relativeTime=On,Ba.pastFuture=Rn,Ba.set=D,Ba.months=at,Ba._months=Qi,Ba.monthsShort=rt,Ba._monthsShort=$i,Ba.monthsParse=st,Ba._monthsRegex=ta,Ba.monthsRegex=ht,Ba._monthsShortRegex=Ki,Ba.monthsShortRegex=ct,Ba.week=Qe,Ba._week=va,Ba.firstDayOfYear=Ke,Ba.firstDayOfWeek=$e,Ba.weekdays=an,Ba._weekdays=ya,Ba.weekdaysMin=on,Ba._weekdaysMin=ka,Ba.weekdaysShort=rn,Ba._weekdaysShort=xa,Ba.weekdaysParse=ln,Ba._weekdaysRegex=_a,Ba.weekdaysRegex=hn,Ba._weekdaysShortRegex=wa,Ba.weekdaysShortRegex=fn,Ba._weekdaysMinRegex=Sa,Ba.weekdaysMinRegex=gn,Ba.isPM=kn,Ba._meridiemParse=Ma,Ba.meridiem=_n,I("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10,n=1===y(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+n}}),t.lang=_("moment.lang is deprecated. Use moment.locale instead.",I),t.langData=_("moment.langData is deprecated. Use moment.localeData instead.",W);var za=Math.abs,Ha=Kn("ms"),Na=Kn("s"),Ea=Kn("m"),Ua=Kn("h"),ja=Kn("d"),Ga=Kn("w"),qa=Kn("M"),Za=Kn("y"),Ja=ei("milliseconds"),Xa=ei("seconds"),Qa=ei("minutes"),$a=ei("hours"),Ka=ei("days"),tr=ei("months"),er=ei("years"),nr=Math.round,ir={s:45,m:45,h:22,d:26,M:11},ar=Math.abs,rr=Nt.prototype;rr.abs=En,rr.add=jn,rr.subtract=Gn,rr.as=Qn,rr.asMilliseconds=Ha,rr.asSeconds=Na,rr.asMinutes=Ea,rr.asHours=Ua,rr.asDays=ja,rr.asWeeks=Ga,rr.asMonths=qa,rr.asYears=Za,rr.valueOf=$n,rr._bubble=Zn,rr.get=ti,rr.milliseconds=Ja,rr.seconds=Xa,rr.minutes=Qa,rr.hours=$a,rr.days=Ka,rr.weeks=ni,rr.months=tr,rr.years=er,rr.humanize=oi,rr.toISOString=si,rr.toString=si,rr.toJSON=si,rr.locale=Pe,rr.localeData=Fe,rr.toIsoString=_("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",si),rr.lang=ma,j("X",0,0,"unix"),j("x",0,0,"valueOf"),X("x",Ri),X("X",Li),tt("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),tt("x",function(t,e,n){n._d=new Date(y(t))}),t.version="2.13.0",i(Yt),t.fn=Ia,t.min=zt,t.max=Ht,t.now=da,t.utc=u,t.unix=Dn,t.months=Yn,t.isDate=r,t.locale=I,t.invalid=f,t.duration=re,t.isMoment=v,t.weekdays=zn,t.parseZone=Cn,t.localeData=W,t.isDuration=Et,t.monthsShort=Bn,t.weekdaysMin=Nn,t.defineLocale=O,t.updateLocale=R,t.locales=V,t.weekdaysShort=Hn,t.normalizeUnits=Y,t.relativeTimeThreshold=ri,t.prototype=Ia;var or=t;return or})},{}],7:[function(t,e,n){var i=t(26)();t(25)(i),t(24)(i),t(21)(i),t(22)(i),t(23)(i),t(27)(i),t(31)(i),t(29)(i),t(30)(i),t(32)(i),t(28)(i),t(33)(i),t(34)(i),t(35)(i),t(36)(i),t(37)(i),t(40)(i),t(38)(i),t(39)(i),t(41)(i),t(42)(i),t(43)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i),window.Chart=e.exports=i},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,8:8,9:9}],8:[function(t,e,n){"use strict";e.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},{}],9:[function(t,e,n){"use strict";e.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},{}],10:[function(t,e,n){"use strict";e.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},{}],11:[function(t,e,n){"use strict";e.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},{}],12:[function(t,e,n){"use strict";e.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},{}],13:[function(t,e,n){"use strict";e.exports=function(t){t.Radar=function(e,n){return n.options=t.helpers.configMerge({aspectRatio:1},n.options),n.type="radar",new t(e,n)}}},{}],14:[function(t,e,n){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(t,e){return""},label:function(t,e){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},{}],15:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(e,n){t.DatasetController.prototype.initialize.call(this,e,n),this.getMeta().bar=!0},getBarCount:function(){var t=this,n=0;return e.each(t.chart.data.datasets,function(e,i){var a=t.chart.getDatasetMeta(i);a.bar&&t.chart.isDatasetVisible(i)&&++n},t),n},update:function(t){var n=this;e.each(n.getMeta().data,function(e,i){n.updateElement(e,i,t)},n)},updateElement:function(t,n,i){var a=this,r=a.getMeta(),o=a.getScaleForId(r.xAxisID),s=a.getScaleForId(r.yAxisID),l=s.getBasePixel(),u=a.chart.options.elements.rectangle,d=t.custom||{},c=a.getDataset();e.extend(t,{_xScale:o,_yScale:s,_datasetIndex:a.index,_index:n,_model:{x:a.calculateBarX(n,a.index),y:i?l:a.calculateBarY(n,a.index),label:a.chart.data.labels[n],datasetLabel:c.label,base:i?l:a.calculateBarBase(a.index,n),width:a.calculateBarWidth(n),backgroundColor:d.backgroundColor?d.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,n,u.backgroundColor),borderSkipped:d.borderSkipped?d.borderSkipped:u.borderSkipped,borderColor:d.borderColor?d.borderColor:e.getValueAtIndexOrDefault(c.borderColor,n,u.borderColor),borderWidth:d.borderWidth?d.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,n,u.borderWidth)}}),t.pivot()},calculateBarBase:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=0;if(a.options.stacked){var o=n.chart,s=o.data.datasets,l=s[t].data[e];if(0>l)for(var u=0;t>u;u++){var d=s[u],c=o.getDatasetMeta(u);c.bar&&c.yAxisID===a.id&&o.isDatasetVisible(u)&&(r+=d.data[e]<0?d.data[e]:0)}else for(var h=0;t>h;h++){var f=s[h],g=o.getDatasetMeta(h);g.bar&&g.yAxisID===a.id&&o.isDatasetVisible(h)&&(r+=f.data[e]>0?f.data[e]:0)}return a.getPixelForValue(r)}return a.getBasePixel()},getRuler:function(t){var e,n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=n.getBarCount();e="category"===a.options.type?a.getPixelForTick(t+1)-a.getPixelForTick(t):a.width/a.ticks.length;var o=e*a.options.categoryPercentage,s=(e-e*a.options.categoryPercentage)/2,l=o/r;if(a.ticks.length!==n.chart.data.labels.length){var u=a.ticks.length/n.chart.data.labels.length;l*=u}var d=l*a.options.barPercentage,c=l-l*a.options.barPercentage;return{datasetCount:r,tickWidth:e,categoryWidth:o,categorySpacing:s,fullBarWidth:l,barWidth:d,barSpacing:c}},calculateBarWidth:function(t){var e=this.getScaleForId(this.getMeta().xAxisID),n=this.getRuler(t);return e.options.stacked?n.categoryWidth:n.barWidth},getBarIndex:function(t){var e,n,i=0;for(n=0;t>n;++n)e=this.chart.getDatasetMeta(n),e.bar&&this.chart.isDatasetVisible(n)&&++i;return i},calculateBarX:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=n.getBarIndex(e),o=n.getRuler(t),s=a.getPixelForValue(null,t,e,n.chart.isCombo);return s-=n.chart.isCombo?o.tickWidth/2:0,a.options.stacked?s+o.categoryWidth/2+o.categorySpacing:s+o.barWidth/2+o.categorySpacing+o.barWidth*r+o.barSpacing/2+o.barSpacing*r},calculateBarY:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=n.getDataset().data[t];if(a.options.stacked){for(var o=0,s=0,l=0;e>l;l++){var u=n.chart.data.datasets[l],d=n.chart.getDatasetMeta(l);d.bar&&d.yAxisID===a.id&&n.chart.isDatasetVisible(l)&&(u.data[t]<0?s+=u.data[t]||0:o+=u.data[t]||0)}return 0>r?a.getPixelForValue(s+r):a.getPixelForValue(o+r)}return a.getPixelForValue(r)},draw:function(t){var n=this,i=t||1;e.each(n.getMeta().data,function(t,e){var a=n.getDataset().data[e];null===a||void 0===a||isNaN(a)||t.transition(i).draw()},n)},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model;r.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.hoverBackgroundColor,i,e.getHoverColor(r.backgroundColor)),r.borderColor=a.hoverBorderColor?a.hoverBorderColor:e.getValueAtIndexOrDefault(n.hoverBorderColor,i,e.getHoverColor(r.borderColor)),r.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:e.getValueAtIndexOrDefault(n.hoverBorderWidth,i,r.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model,o=this.chart.options.elements.rectangle;r.backgroundColor=a.backgroundColor?a.backgroundColor:e.getValueAtIndexOrDefault(n.backgroundColor,i,o.backgroundColor),r.borderColor=a.borderColor?a.borderColor:e.getValueAtIndexOrDefault(n.borderColor,i,o.borderColor),r.borderWidth=a.borderWidth?a.borderWidth:e.getValueAtIndexOrDefault(n.borderWidth,i,o.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(n=e.labels[t[0].index])),n},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({updateElement:function(t,n,i,a){var r=this,o=r.getMeta(),s=r.getScaleForId(o.xAxisID),l=r.getScaleForId(o.yAxisID),u=s.getBasePixel(),d=t.custom||{},c=r.getDataset(),h=r.chart.options.elements.rectangle;e.extend(t,{_xScale:s,_yScale:l,_datasetIndex:r.index,_index:n,_model:{x:i?u:r.calculateBarX(n,r.index),y:r.calculateBarY(n,r.index),label:r.chart.data.labels[n],datasetLabel:c.label,base:i?u:r.calculateBarBase(r.index,n),height:r.calculateBarHeight(n),backgroundColor:d.backgroundColor?d.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,n,h.backgroundColor),borderSkipped:d.borderSkipped?d.borderSkipped:h.borderSkipped,borderColor:d.borderColor?d.borderColor:e.getValueAtIndexOrDefault(c.borderColor,n,h.borderColor),borderWidth:d.borderWidth?d.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,n,h.borderWidth)},draw:function(){function t(t){return l[(d+t)%4]}var e=this._chart.ctx,n=this._view,i=n.height/2,a=n.y-i,r=n.y+i,o=n.base-(n.base-n.x),s=n.borderWidth/2;n.borderWidth&&(a+=s,r-=s,o+=s),e.beginPath(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,e.lineWidth=n.borderWidth;var l=[[n.base,r],[n.base,a],[o,a],[o,r]],u=["bottom","left","top","right"],d=u.indexOf(n.borderSkipped,0);-1===d&&(d=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),n.borderWidth&&e.stroke()},inRange:function(t,e){var n=this._view,i=!1;return n&&(i=n.x<n.base?e>=n.y-n.height/2&&e<=n.y+n.height/2&&t>=n.x&&t<=n.base:e>=n.y-n.height/2&&e<=n.y+n.height/2&&t>=n.base&&t<=n.x),i}}),t.pivot()},calculateBarBase:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=0;if(a.options.stacked){var o=n.chart.data.datasets[t].data[e];if(0>o)for(var s=0;t>s;s++){var l=n.chart.data.datasets[s],u=n.chart.getDatasetMeta(s);u.bar&&u.xAxisID===a.id&&n.chart.isDatasetVisible(s)&&(r+=l.data[e]<0?l.data[e]:0)}else for(var d=0;t>d;d++){var c=n.chart.data.datasets[d],h=n.chart.getDatasetMeta(d);h.bar&&h.xAxisID===a.id&&n.chart.isDatasetVisible(d)&&(r+=c.data[e]>0?c.data[e]:0)}return a.getPixelForValue(r)}return a.getBasePixel()},getRuler:function(t){var e,n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=n.getBarCount();e="category"===a.options.type?a.getPixelForTick(t+1)-a.getPixelForTick(t):a.width/a.ticks.length;var o=e*a.options.categoryPercentage,s=(e-e*a.options.categoryPercentage)/2,l=o/r;if(a.ticks.length!==n.chart.data.labels.length){var u=a.ticks.length/n.chart.data.labels.length;l*=u}var d=l*a.options.barPercentage,c=l-l*a.options.barPercentage;return{datasetCount:r,tickHeight:e,categoryHeight:o,categorySpacing:s,fullBarHeight:l,barHeight:d,barSpacing:c}},calculateBarHeight:function(t){var e=this,n=e.getScaleForId(e.getMeta().yAxisID),i=e.getRuler(t);return n.options.stacked?i.categoryHeight:i.barHeight},calculateBarX:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=n.getDataset().data[t];if(a.options.stacked){for(var o=0,s=0,l=0;e>l;l++){var u=n.chart.data.datasets[l],d=n.chart.getDatasetMeta(l);d.bar&&d.xAxisID===a.id&&n.chart.isDatasetVisible(l)&&(u.data[t]<0?s+=u.data[t]||0:o+=u.data[t]||0)}return 0>r?a.getPixelForValue(s+r):a.getPixelForValue(o+r)}return a.getPixelForValue(r)},calculateBarY:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=n.getBarIndex(e),o=n.getRuler(t),s=a.getPixelForValue(null,t,e,n.chart.isCombo);return s-=n.chart.isCombo?o.tickHeight/2:0,a.options.stacked?s+o.categoryHeight/2+o.categorySpacing:s+o.barHeight/2+o.categorySpacing+o.barHeight*r+o.barSpacing/2+o.barSpacing*r}})}},{}],16:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(t,e){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+i.x+", "+i.y+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var n=this,i=n.getMeta(),a=i.data;e.each(a,function(e,i){n.updateElement(e,i,t)})},updateElement:function(n,i,a){var r=this,o=r.getMeta(),s=r.getScaleForId(o.xAxisID),l=r.getScaleForId(o.yAxisID),u=n.custom||{},d=r.getDataset(),c=d.data[i],h=r.chart.options.elements.point,f=r.index;e.extend(n,{_xScale:s,_yScale:l,_datasetIndex:f,_index:i,_model:{x:a?s.getPixelForDecimal(.5):s.getPixelForValue(c,i,f,r.chart.isCombo),y:a?l.getBasePixel():l.getPixelForValue(c,i,f),radius:a?0:u.radius?u.radius:r.getRadius(c),hitRadius:u.hitRadius?u.hitRadius:e.getValueAtIndexOrDefault(d.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(r,n,h);var g=n._model;g.skip=u.skip?u.skip:isNaN(g.x)||isNaN(g.y),n.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(n){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,n);var a=i.chart.data.datasets[n._datasetIndex],r=n._index,o=n.custom||{},s=n._model;s.radius=o.hoverRadius?o.hoverRadius:e.getValueAtIndexOrDefault(a.hoverRadius,r,i.chart.options.elements.point.hoverRadius)+i.getRadius(a.data[r])},removeHoverStyle:function(e){var n=this;t.DatasetController.prototype.removeHoverStyle.call(n,e,n.chart.options.elements.point);var i=n.chart.data.datasets[e._datasetIndex].data[e._index],a=e.custom||{},r=e._model;r.radius=a.radius?a.radius:n.getRadius(i)}})}},{}],17:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults;n.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var r=t.getDatasetMeta(0),o=n.datasets[0],s=r.data[a],l=s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(o.backgroundColor,a,d.backgroundColor),h=l.borderColor?l.borderColor:u(o.borderColor,a,d.borderColor),f=l.borderWidth?l.borderWidth:u(o.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(o.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;i>n;++n)a=o.getDatasetMeta(n),a.data[r].hidden=!a.data[r].hidden;o.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+e.datasets[t.datasetIndex].data[t.index]}}}},n.pie=e.clone(n.doughnut),e.extend(n.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,n=0;t>n;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var n=this,i=n.chart,a=i.chartArea,r=i.options,o=r.elements.arc,s=a.right-a.left-o.borderWidth,l=a.bottom-a.top-o.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=n.getMeta(),h=r.cutoutPercentage,f=r.circumference;if(f<2*Math.PI){var g=r.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(p),y:Math.sin(p)},b=0>=g&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,y=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,x=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,_=h/100,w={x:x?-1:Math.min(m.x*(m.x<0?1:_),v.x*(v.x<0?1:_)),y:k?-1:Math.min(m.y*(m.y<0?1:_),v.y*(v.y<0?1:_))},S={x:b?1:Math.max(m.x*(m.x>0?1:_),v.x*(v.x>0?1:_)),y:y?1:Math.max(m.y*(m.y>0?1:_),v.y*(v.y>0?1:_))},M={width:.5*(S.x-w.x),height:.5*(S.y-w.y)};u=Math.min(s/M.width,l/M.height),d={x:(S.x+w.x)*-.5,y:(S.y+w.y)*-.5}}i.outerRadius=Math.max(u/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=n.calculateTotal(),n.outerRadius=i.outerRadius-i.radiusLength*n.getRingIndex(n.index),n.innerRadius=n.outerRadius-i.radiusLength,e.each(c.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){var a=this,r=a.chart,o=r.chartArea,s=r.options,l=s.animation,u=(s.elements.arc,(o.left+o.right)/2),d=(o.top+o.bottom)/2,c=s.rotation,h=s.rotation,f=a.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:a.calculateCircumference(f.data[n])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:a.innerRadius,m=i&&l.animateScale?0:a.outerRadius,v=(t.custom||{},e.getValueAtIndexOrDefault);e.extend(t,{_datasetIndex:a.index,_index:n,_model:{x:u+r.offsetX,y:d+r.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,n,r.data.labels[n])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(0===n?b.startAngle=s.rotation:b.startAngle=a.getMeta().data[n-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,n=this.getDataset(),i=this.getMeta(),a=0;return e.each(i.data,function(e,i){t=n.data[i],isNaN(t)||e.hidden||(a+=Math.abs(t))}),a},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0}})}},{}],18:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return n.getValueOrDefault(t.showLine,e.showLines)}var n=t.helpers;t.defaults.line={showLines:!0,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,addElementAndReset:function(n){var i=this,a=i.chart.options,r=i.getMeta();t.DatasetController.prototype.addElementAndReset.call(i,n),e(i.getDataset(),a)&&0!==r.dataset._model.tension&&i.updateBezierControlPoints()},update:function(t){var i,a,r,o=this,s=o.getMeta(),l=s.dataset,u=s.data||[],d=o.chart.options,c=d.elements.line,h=o.getScaleForId(s.yAxisID),f=o.getDataset(),g=e(f,d);for(g&&(r=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=o.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:!1,tension:r.tension?r.tension:n.getValueOrDefault(f.lineTension,c.tension),backgroundColor:r.backgroundColor?r.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:f.borderWidth||c.borderWidth,borderColor:r.borderColor?r.borderColor:f.borderColor||c.borderColor,borderCapStyle:r.borderCapStyle?r.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:r.borderDash?r.borderDash:f.borderDash||c.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:r.fill?r.fill:void 0!==f.fill?f.fill:c.fill,scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},l.pivot()),i=0,a=u.length;a>i;++i)o.updateElement(u[i],i,t);for(g&&0!==l._model.tension&&o.updateBezierControlPoints(),i=0,a=u.length;a>i;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,a=this.getDataset(),r=t.custom||{};return r.backgroundColor?i=r.backgroundColor:a.pointBackgroundColor?i=n.getValueAtIndexOrDefault(a.pointBackgroundColor,e,i):a.backgroundColor&&(i=a.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,a=this.getDataset(),r=t.custom||{};return r.borderColor?i=r.borderColor:a.pointBorderColor?i=n.getValueAtIndexOrDefault(a.pointBorderColor,e,i):a.borderColor&&(i=a.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,a=this.getDataset(),r=t.custom||{};return r.borderWidth?i=r.borderWidth:a.pointBorderWidth?i=n.getValueAtIndexOrDefault(a.pointBorderWidth,e,i):a.borderWidth&&(i=a.borderWidth),i},updateElement:function(t,e,i){var a,r,o=this,s=o.getMeta(),l=t.custom||{},u=o.getDataset(),d=o.index,c=u.data[e],h=o.getScaleForId(s.yAxisID),f=o.getScaleForId(s.xAxisID),g=o.chart.options.elements.point;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),a=f.getPixelForValue(c,e,d,o.chart.isCombo),r=i?h.getBasePixel():o.calculatePointY(c,e,d,o.chart.isCombo),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:a,y:r,skip:l.skip||isNaN(a)||isNaN(r),radius:l.radius||n.getValueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||n.getValueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:o.getPointBackgroundColor(t,e),borderColor:o.getPointBorderColor(t,e),borderWidth:o.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,hitRadius:l.hitRadius||n.getValueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,n,i){var a,r,o,s=this,l=s.chart,u=s.getMeta(),d=s.getScaleForId(u.yAxisID),c=0,h=0;if(d.options.stacked){for(a=0;n>a;a++)r=l.data.datasets[a],o=l.getDatasetMeta(a),"line"===o.type&&l.isDatasetVisible(a)&&(r.data[e]<0?h+=r.data[e]||0:c+=r.data[e]||0);return 0>t?d.getPixelForValue(h+t):d.getPixelForValue(c+t)}return d.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,i,a,r,o=this.getMeta(),s=(this.chart.chartArea,o.data||[]);for(t=0,e=s.length;e>t;++t)i=s[t],a=i._model,r=n.splineCurve(n.previousItem(s,t)._model,a,n.nextItem(s,t)._model,o.dataset._model.tension),a.controlPointPreviousX=r.previous.x,a.controlPointPreviousY=r.previous.y,a.controlPointNextX=r.next.x,a.controlPointNextY=r.next.y},draw:function(t){var n,i,a=this,r=a.getMeta(),o=r.data||[],s=t||1;for(n=0,i=o.length;i>n;++n)o[n].transition(s);for(e(a.getDataset(),a.chart.options)&&r.dataset.transition(s).draw(),n=0,i=o.length;i>n;++n)o[n].draw()},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model;r.radius=a.hoverRadius||n.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),r.backgroundColor=a.hoverBackgroundColor||n.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,n.getHoverColor(r.backgroundColor)),r.borderColor=a.hoverBorderColor||n.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,n.getHoverColor(r.borderColor)),r.borderWidth=a.hoverBorderWidth||n.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,r.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),o.radius=r.radius||n.getValueAtIndexOrDefault(i.pointRadius,a,e.chart.options.elements.point.radius),o.backgroundColor=e.getPointBackgroundColor(t,a),o.borderColor=e.getPointBorderColor(t,a),o.borderWidth=e.getPointBorderWidth(t,a)}})}},{}],19:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0},animation:{animateRotate:!0,animateScale:!0},aspectRatio:1,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'">'),a[r]&&e.push(a[r]),e.push("</span></li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var r=t.getDatasetMeta(0),o=n.datasets[0],s=r.data[a],l=s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(o.backgroundColor,a,d.backgroundColor),h=l.borderColor?l.borderColor:u(o.borderColor,a,d.borderColor),f=l.borderWidth?l.borderWidth:u(o.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(o.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;i>n;++n)a=o.getDatasetMeta(n),a.data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var n=this,i=n.chart,a=i.chartArea,r=n.getMeta(),o=i.options,s=o.elements.arc,l=Math.min(a.right-a.left,a.bottom-a.top);i.outerRadius=Math.max((l-s.borderWidth/2)/2,0),i.innerRadius=Math.max(o.cutoutPercentage?i.outerRadius/100*o.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),n.outerRadius=i.outerRadius-i.radiusLength*n.index,n.innerRadius=n.outerRadius-i.radiusLength,r.count=n.countVisibleElements(),e.each(r.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){for(var a=this,r=a.chart,o=r.chartArea,s=a.getDataset(),l=r.options,u=l.animation,d=(l.elements.arc,t.custom||{},r.scale),c=e.getValueAtIndexOrDefault,h=r.data.labels,f=a.calculateCircumference(s.data[n]),g=(o.left+o.right)/2,p=(o.top+o.bottom)/2,m=0,v=a.getMeta(),b=0;n>b;++b)isNaN(s.data[b])||v.data[b].hidden||++m;var y=-.5*Math.PI,x=t.hidden?0:d.getDistanceFromCenterForValue(s.data[n]),k=y+f*m,_=k+(t.hidden?0:f),w=u.animateScale?0:d.getDistanceFromCenterForValue(s.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:d,_model:{x:g,y:p,innerRadius:0,outerRadius:i?w:x,startAngle:i&&u.animateRotate?y:k,endAngle:i&&u.animateRotate?y:_,label:c(h,n,h[n])}}),a.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),n=this.getMeta(),i=0;return e.each(n.data,function(e,n){isNaN(t.data[n])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,addElementAndReset:function(e){t.DatasetController.prototype.addElementAndReset.call(this,e),this.updateBezierControlPoints()},update:function(t){var n=this,i=n.getMeta(),a=i.dataset,r=i.data,o=a.custom||{},s=n.getDataset(),l=n.chart.options.elements.line,u=n.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),e.extend(i.dataset,{_datasetIndex:n.index,_children:r,_loop:!0,
-_model:{tension:o.tension?o.tension:e.getValueOrDefault(s.lineTension,l.tension),backgroundColor:o.backgroundColor?o.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:s.borderWidth||l.borderWidth,borderColor:o.borderColor?o.borderColor:s.borderColor||l.borderColor,fill:o.fill?o.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:o.borderCapStyle?o.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:o.borderDash?o.borderDash:s.borderDash||l.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle,scaleTop:u.top,scaleBottom:u.bottom,scaleZero:u.getBasePosition()}}),i.dataset.pivot(),e.each(r,function(e,i){n.updateElement(e,i,t)},n),n.updateBezierControlPoints()},updateElement:function(t,n,i){var a=this,r=t.custom||{},o=a.getDataset(),s=a.chart.scale,l=a.chart.options.elements.point,u=s.getPointPositionForValue(n,o.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:r.tension?r.tension:e.getValueOrDefault(o.tension,a.chart.options.elements.line.tension),radius:r.radius?r.radius:e.getValueAtIndexOrDefault(o.pointRadius,n,l.radius),backgroundColor:r.backgroundColor?r.backgroundColor:e.getValueAtIndexOrDefault(o.pointBackgroundColor,n,l.backgroundColor),borderColor:r.borderColor?r.borderColor:e.getValueAtIndexOrDefault(o.pointBorderColor,n,l.borderColor),borderWidth:r.borderWidth?r.borderWidth:e.getValueAtIndexOrDefault(o.pointBorderWidth,n,l.borderWidth),pointStyle:r.pointStyle?r.pointStyle:e.getValueAtIndexOrDefault(o.pointStyle,n,l.pointStyle),hitRadius:r.hitRadius?r.hitRadius:e.getValueAtIndexOrDefault(o.hitRadius,n,l.hitRadius)}}),t._model.skip=r.skip?r.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,n=this.getMeta();e.each(n.data,function(i,a){var r=i._model,o=e.splineCurve(e.previousItem(n.data,a,!0)._model,r,e.nextItem(n.data,a,!0)._model,r.tension);r.controlPointPreviousX=Math.max(Math.min(o.previous.x,t.right),t.left),r.controlPointPreviousY=Math.max(Math.min(o.previous.y,t.bottom),t.top),r.controlPointNextX=Math.max(Math.min(o.next.x,t.right),t.left),r.controlPointNextY=Math.max(Math.min(o.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var n=this.getMeta(),i=t||1;e.each(n.data,function(t,e){t.transition(i)}),n.dataset.transition(i).draw(),e.each(n.data,function(t){t.draw()})},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,r=t._model;r.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(n.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),r.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.pointHoverBackgroundColor,a,e.getHoverColor(r.backgroundColor)),r.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(n.pointHoverBorderColor,a,e.getHoverColor(r.borderColor)),r.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(n.pointHoverBorderWidth,a,r.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,r=t._model,o=this.chart.options.elements.point;r.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(n.radius,a,o.radius),r.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(n.pointBackgroundColor,a,o.backgroundColor),r.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(n.pointBorderColor,a,o.borderColor),r.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(n.pointBorderWidth,a,o.borderWidth)}})}},{}],21:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,n,i){var a=this;i||(t.animating=!0);for(var r=0;r<a.animations.length;++r)if(a.animations[r].chartInstance===t)return void(a.animations[r].animationObject=e);a.animations.push({chartInstance:t,animationObject:e}),1===a.animations.length&&a.requestAnimationFrame()},cancelAnimation:function(t){var n=e.findIndex(this.animations,function(e){return e.chartInstance===t});-1!==n&&(this.animations.splice(n,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),n=0;t.dropFrames>1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;i<t.animations.length;)null===t.animations[i].animationObject.currentStep&&(t.animations[i].animationObject.currentStep=0),t.animations[i].animationObject.currentStep+=1+n,t.animations[i].animationObject.currentStep>t.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var a=Date.now(),r=(a-e)/t.frameDuration;t.dropFrames+=r,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.types={},t.instances={},t.controllers={},t.Controller=function(n){return this.chart=n,this.config=n.config,this.options=this.config.options=e.configMerge(t.defaults.global,t.defaults[this.config.type],this.config.options||{}),this.id=e.uid(),Object.defineProperty(this,"data",{get:function(){return this.config.data}}),t.instances[this.id]=this,this.options.responsive&&this.resize(!0),this.initialize(),this},e.extend(t.Controller.prototype,{initialize:function(){var e=this;return t.plugins.notify("beforeInit",[e]),e.bindEvents(),e.ensureScalesHaveIDs(),e.buildOrUpdateControllers(),e.buildScales(),e.updateLayout(),e.resetElements(),e.initToolTip(),e.update(),t.plugins.notify("afterInit",[e]),e},clear:function(){return e.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(n){var i=this,a=i.chart,r=a.canvas,o=e.getMaximumWidth(r),s=a.aspectRatio,l=i.options.maintainAspectRatio&&isNaN(s)===!1&&isFinite(s)&&0!==s?o/s:e.getMaximumHeight(r),u=a.width!==o||a.height!==l;if(!u)return i;r.width=a.width=o,r.height=a.height=l,e.retinaScale(a);var d={width:o,height:l};return t.plugins.notify("resize",[i,d]),i.options.onResize&&i.options.onResize(i,d),n||(i.stop(),i.update(i.options.responsiveAnimationDuration)),i},ensureScalesHaveIDs:function(){var t=this.options,n=t.scales||{},i=t.scale;e.each(n.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),e.each(n.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildScales:function(){var n=this,i=n.options,a=n.scales={},r=[];i.scales&&(r=r.concat((i.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(i.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),i.scale&&r.push({options:i.scale,dtype:"radialLinear",isDefault:!0}),e.each(r,function(i,r){var o=i.options,s=e.getValueOrDefault(o.type,i.dtype),l=t.scaleService.getScaleConstructor(s);if(l){var u=new l({id:o.id,options:o,ctx:n.chart.ctx,chart:n});a[u.id]=u,i.isDefault&&(n.scale=u)}}),t.scaleService.addScalesToLayout(this)},updateLayout:function(){t.layoutService.update(this,this.chart.width,this.chart.height)},buildOrUpdateControllers:function(){var n=this,i=[],a=[];if(e.each(n.data.datasets,function(e,r){var o=n.getDatasetMeta(r);o.type||(o.type=e.type||n.config.type),i.push(o.type),o.controller?o.controller.updateIndex(r):(o.controller=new t.controllers[o.type](n,r),a.push(o.controller))},n),i.length>1)for(var r=1;r<i.length;r++)if(i[r]!==i[r-1]){n.isCombo=!0;break}return a},resetElements:function(){var t=this;e.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},update:function(n,i){var a=this;t.plugins.notify("beforeUpdate",[a]),a.tooltip._data=a.data;var r=a.buildOrUpdateControllers();e.each(a.data.datasets,function(t,e){a.getDatasetMeta(e).controller.buildOrUpdateElements()},a),t.layoutService.update(a,a.chart.width,a.chart.height),t.plugins.notify("afterScaleUpdate",[a]),e.each(r,function(t){t.reset()}),a.updateDatasets(),t.plugins.notify("afterUpdate",[a]),a.render(n,i)},updateDatasets:function(){var e,n,i=this;if(t.plugins.notify("beforeDatasetsUpdate",[i])){for(e=0,n=i.data.datasets.length;n>e;++e)i.getDatasetMeta(e).controller.update();t.plugins.notify("afterDatasetsUpdate",[i])}},render:function(n,i){var a=this;t.plugins.notify("beforeRender",[a]);var r=a.options.animation;if(r&&("undefined"!=typeof n&&0!==n||"undefined"==typeof n&&0!==r.duration)){var o=new t.Animation;o.numSteps=(n||r.duration)/16.66,o.easing=r.easing,o.render=function(t,n){var i=e.easingEffects[n.easing],a=n.currentStep/n.numSteps,r=i(a);t.draw(r,a,n.currentStep)},o.onAnimationProgress=r.onProgress,o.onAnimationComplete=r.onComplete,t.animationService.addAnimation(a,o,n,i)}else a.draw(),r&&r.onComplete&&r.onComplete.call&&r.onComplete.call(a);return a},draw:function(n){var i=this,a=n||1;i.clear(),t.plugins.notify("beforeDraw",[i,a]),e.each(i.boxes,function(t){t.draw(i.chartArea)},i),i.scale&&i.scale.draw(),t.plugins.notify("beforeDatasetsDraw",[i,a]),e.each(i.data.datasets,function(t,e){i.isDatasetVisible(e)&&i.getDatasetMeta(e).controller.draw(n)},i,!0),t.plugins.notify("afterDatasetsDraw",[i,a]),i.tooltip.transition(a).draw(),t.plugins.notify("afterDraw",[i,a])},getElementAtEvent:function(t){var n=this,i=e.getRelativePosition(t,n.chart),a=[];return e.each(n.data.datasets,function(t,r){if(n.isDatasetVisible(r)){var o=n.getDatasetMeta(r);e.each(o.data,function(t,e){return t.inRange(i.x,i.y)?(a.push(t),a):void 0})}}),a},getElementsAtEvent:function(t){var n=this,i=e.getRelativePosition(t,n.chart),a=[],r=function(){if(n.data.datasets)for(var t=0;t<n.data.datasets.length;t++){var e=n.getDatasetMeta(t);if(n.isDatasetVisible(t))for(var a=0;a<e.data.length;a++)if(e.data[a].inRange(i.x,i.y))return e.data[a]}}.call(n);return r?(e.each(n.data.datasets,function(t,e){if(n.isDatasetVisible(e)){var i=n.getDatasetMeta(e);a.push(i.data[r._index])}},n),a):a},getElementsAtEventForMode:function(t,e){var n=this;switch(e){case"single":return n.getElementAtEvent(t);case"label":return n.getElementsAtEvent(t);case"dataset":return n.getDatasetAtEvent(t);default:return t}},getDatasetAtEvent:function(t){var e=this.getElementAtEvent(t);return e.length>0&&(e=this.getDatasetMeta(e[0]._datasetIndex).data),e},getDatasetMeta:function(t){var e=this,n=e.data.datasets[t];n._meta||(n._meta={});var i=n._meta[e.id];return i||(i=n._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;n>e;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var n=this;n.stop(),n.clear(),e.unbindEvents(n,n.events),e.removeResizeListener(n.chart.canvas.parentNode);var i=n.chart.canvas;i.width=n.chart.width,i.height=n.chart.height,void 0!==n.chart.originalDevicePixelRatio&&n.chart.ctx.scale(1/n.chart.originalDevicePixelRatio,1/n.chart.originalDevicePixelRatio),i.style.width=n.chart.originalCanvasStyleWidth,i.style.height=n.chart.originalCanvasStyleHeight,t.plugins.notify("destroy",[n]),delete t.instances[n.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e.chart,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this;e.bindEvents(t,t.options.events,function(e){t.eventHandler(e)})},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"setHoverStyle":"removeHoverStyle";switch(e){case"single":t=[t[0]];break;case"label":case"dataset":break;default:return}for(a=0,r=t.length;r>a;++a)i=t[a],i&&this.getDatasetMeta(i._datasetIndex).controller[o](i)},eventHandler:function(t){var n=this,i=n.tooltip,a=n.options||{},r=a.hover,o=a.tooltips;return n.lastActive=n.lastActive||[],n.lastTooltipActive=n.lastTooltipActive||[],"mouseout"===t.type?(n.active=[],n.tooltipActive=[]):(n.active=n.getElementsAtEventForMode(t,r.mode),n.tooltipActive=n.getElementsAtEventForMode(t,o.mode)),r.onHover&&r.onHover.call(n,n.active),("mouseup"===t.type||"click"===t.type)&&(a.onClick&&a.onClick.call(n,t,n.active),n.legend&&n.legend.handleEvent&&n.legend.handleEvent(t)),n.lastActive.length&&n.updateHoverStyle(n.lastActive,r.mode,!1),n.active.length&&r.mode&&n.updateHoverStyle(n.active,r.mode,!0),(o.enabled||o.custom)&&(i.initialize(),i._active=n.tooltipActive,i.update(!0)),i.pivot(),n.animating||e.arrayEquals(n.active,n.lastActive)&&e.arrayEquals(n.tooltipActive,n.lastTooltipActive)||(n.stop(),(o.enabled||o.custom)&&i.update(!0),n.render(r.animationDuration,!0)),n.lastActive=n.active,n.lastTooltipActive=n.tooltipActive,n}})}},{}],23:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=e.noop;t.DatasetController=function(t,e){this.initialize.call(this,t,e)},e.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null===e.xAxisID&&(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=n.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],r=i.data;for(t=0,e=a.length;e>t;++t)r[t]=r[t]||n.createMetaData(i,t);i.dataset=i.dataset||n.createMetaDataset()},addElementAndReset:function(t){var e=this,n=e.createMetaData(t);e.getMeta().data.splice(t,0,n),e.updateElement(n,t,!0)},buildOrUpdateElements:function(){var t=this.getMeta(),e=t.data,n=this.getDataset().data.length,i=e.length;if(i>n)e.splice(n,i-n);else if(n>i)for(var a=i;n>a;++a)this.addElementAndReset(a)},update:n,draw:function(t){var n=t||1;e.each(this.getMeta().data,function(t,e){t.transition(n).draw()})},removeHoverStyle:function(t,n){var i=this.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=e.getValueAtIndexOrDefault,s=(e.color,t._model);s.backgroundColor=r.backgroundColor?r.backgroundColor:o(i.backgroundColor,a,n.backgroundColor),s.borderColor=r.borderColor?r.borderColor:o(i.borderColor,a,n.borderColor),s.borderWidth=r.borderWidth?r.borderWidth:o(i.borderWidth,a,n.borderWidth)},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=e.getValueAtIndexOrDefault,o=(e.color,e.getHoverColor),s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:r(n.hoverBackgroundColor,i,o(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:r(n.hoverBorderColor,i,o(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:r(n.hoverBorderWidth,i,s.borderWidth)}}),t.DatasetController.extend=e.inherits}},{}],24:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=e.clone(t._model)),t._start=e.clone(t._view),t},transition:function(t){var n=this;return n._view||(n._view=e.clone(n._model)),1===t?(n._view=n._model,n._start=null,n):(n._start||n.pivot(),e.each(n._model,function(i,a){if("_"===a[0]);else if(n._view.hasOwnProperty(a))if(i===n._view[a]);else if("string"==typeof i)try{var r=e.color(n._model[a]).mix(e.color(n._start[a]),t);n._view[a]=r.rgbString()}catch(o){n._view[a]=i}else if("number"==typeof i){var s=void 0!==n._start[a]&&isNaN(n._start[a])===!1?n._start[a]:0;n._view[a]=(n._model[a]-s)*t+s}else n._view[a]=i;else"number"!=typeof i||isNaN(n._view[a])?n._view[a]=i:n._view[a]=i*t},n),n)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],25:[function(t,e,n){"use strict";var i=t(2);e.exports=function(t){function e(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!=t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function n(t){return void 0!==t&&null!==t&&"none"!==t}function a(t,i,a){var r=document.defaultView,o=t.parentNode,s=r.getComputedStyle(t)[i],l=r.getComputedStyle(o)[i],u=n(s),d=n(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,o,a):c):"none"}var r=t.helpers={};r.each=function(t,e,n,i){var a,o;if(r.isArray(t))if(o=t.length,i)for(a=o-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;o>a;a++)e.call(n,t[a],a);else if("object"==typeof t){var s=Object.keys(t);for(o=s.length,a=0;o>a;a++)e.call(n,t[s[a]],s[a])}},r.clone=function(t){var e={};return r.each(t,function(t,n){r.isArray(t)?e[n]=t.slice(0):"object"==typeof t&&null!==t?e[n]=r.clone(t):e[n]=t}),e},r.extend=function(t){for(var e=function(e,n){t[n]=e},n=1,i=arguments.length;i>n;n++)r.each(arguments[n],e);return t},r.configMerge=function(e){var n=r.clone(e);return r.each(Array.prototype.slice.call(arguments,1),function(e){r.each(e,function(e,i){if("scales"===i)n[i]=r.scaleMerge(n.hasOwnProperty(i)?n[i]:{},e);else if("scale"===i)n[i]=r.configMerge(n.hasOwnProperty(i)?n[i]:{},t.scaleService.getScaleDefaults(e.type),e);else if(n.hasOwnProperty(i)&&r.isArray(n[i])&&r.isArray(e)){var a=n[i];r.each(e,function(t,e){e<a.length?"object"==typeof a[e]&&null!==a[e]&&"object"==typeof t&&null!==t?a[e]=r.configMerge(a[e],t):a[e]=t:a.push(t)})}else n.hasOwnProperty(i)&&"object"==typeof n[i]&&null!==n[i]&&"object"==typeof e?n[i]=r.configMerge(n[i],e):n[i]=e})}),n},r.scaleMerge=function(e,n){var i=r.clone(e);return r.each(n,function(e,n){"xAxes"===n||"yAxes"===n?i.hasOwnProperty(n)?r.each(e,function(e,a){var o=r.getValueOrDefault(e.type,"xAxes"===n?"category":"linear"),s=t.scaleService.getScaleDefaults(o);a>=i[n].length||!i[n][a].type?i[n].push(r.configMerge(s,e)):e.type&&e.type!==i[n][a].type?i[n][a]=r.configMerge(i[n][a],s,e):i[n][a]=r.configMerge(i[n][a],e)}):(i[n]=[],r.each(e,function(e){var a=r.getValueOrDefault(e.type,"xAxes"===n?"category":"linear");i[n].push(r.configMerge(t.scaleService.getScaleDefaults(a),e))})):i.hasOwnProperty(n)&&"object"==typeof i[n]&&null!==i[n]&&"object"==typeof e?i[n]=r.configMerge(i[n],e):i[n]=e}),i},r.getValueAtIndexOrDefault=function(t,e,n){return void 0===t||null===t?n:r.isArray(t)?e<t.length?t[e]:n:t},r.getValueOrDefault=function(t,e){return void 0===t?e:t},r.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var n=0,i=t.length;i>n;++n)if(t[n]===e)return n;return-1},r.where=function(t,e){if(r.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return r.each(t,function(t){e(t)&&n.push(t)}),n},r.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;a>i;++i)if(e.call(n,t[i],i,t))return i;return-1},r.findNextWhere=function(t,e,n){(void 0===n||null===n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},r.findPreviousWhere=function(t,e,n){(void 0===n||null===n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},r.inherits=function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=r.inherits,t&&r.extend(n.prototype,t),n.__super__=e.prototype,n},r.noop=function(){},r.uid=function(){var t=0;return function(){return t++}}(),r.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},r.almostEquals=function(t,e,n){return Math.abs(t-e)<n},r.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},r.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},r.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},r.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},r.toRadians=function(t){return t*(Math.PI/180)},r.toDegrees=function(t){return t*(180/Math.PI)},r.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},r.aliasPixel=function(t){return t%2===0?0:.5},r.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:r.x-c*(o.x-a.x),y:r.y-c*(o.y-a.y)},next:{x:r.x+h*(o.x-a.x),y:r.y+h*(o.y-a.y)}}},r.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},r.previousItem=function(t,e,n){return n?0>=e?t[t.length-1]:t[e-1]:0>=e?t[0]:t[e-1]},r.niceNum=function(t,e){var n,i=Math.floor(r.log10(t)),a=t/Math.pow(10,i);return n=e?1.5>a?1:3>a?2:7>a?5:10:1>=a?1:2>=a?2:5>=a?5:10,n*Math.pow(10,i)};var o=r.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2===(t/=.5)?1:(n||(n=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),1>t?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-o.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*o.easeInBounce(2*t):.5*o.easeOutBounce(2*t-1)+.5}};r.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),r.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),r.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,o=t.currentTarget||t.srcElement,s=o.getBoundingClientRect(),l=a.touches;l&&l.length>0?(n=l[0].clientX,i=l[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(r.getStyle(o,"padding-left")),d=parseFloat(r.getStyle(o,"padding-top")),c=parseFloat(r.getStyle(o,"padding-right")),h=parseFloat(r.getStyle(o,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return n=Math.round((n-s.left-u)/f*o.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*o.height/e.currentDevicePixelRatio),{x:n,y:i}},r.addEvent=function(t,e,n){t.addEventListener?t.addEventListener(e,n):t.attachEvent?t.attachEvent("on"+e,n):t["on"+e]=n},r.removeEvent=function(t,e,n){t.removeEventListener?t.removeEventListener(e,n,!1):t.detachEvent?t.detachEvent("on"+e,n):t["on"+e]=r.noop},r.bindEvents=function(t,e,n){var i=t.events=t.events||{};r.each(e,function(e){i[e]=function(){n.apply(t,arguments)},r.addEvent(t.chart.canvas,e,i[e])})},r.unbindEvents=function(t,e){var n=t.chart.canvas;r.each(e,function(t,e){r.removeEvent(n,e,t)})},r.getConstraintWidth=function(t){return a(t,"max-width","clientWidth")},r.getConstraintHeight=function(t){return a(t,"max-height","clientHeight")},r.getMaximumWidth=function(t){var e=t.parentNode,n=parseInt(r.getStyle(e,"padding-left"))+parseInt(r.getStyle(e,"padding-right")),i=e.clientWidth-n,a=r.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},r.getMaximumHeight=function(t){var e=t.parentNode,n=parseInt(r.getStyle(e,"padding-top"))+parseInt(r.getStyle(e,"padding-bottom")),i=e.clientHeight-n,a=r.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},r.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},r.retinaScale=function(t){var e=t.ctx,n=t.canvas,i=n.width,a=n.height,r=t.currentDevicePixelRatio=window.devicePixelRatio||1;1!==r&&(n.height=a*r,n.width=i*r,e.scale(r,r),t.originalDevicePixelRatio=t.originalDevicePixelRatio||r),n.style.width=i+"px",n.style.height=a+"px"},r.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},r.fontString=function(t,e,n){return e+" "+t+"px "+n},r.longestText=function(t,e,n,i){i=i||{};var a=i.data=i.data||{},o=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},o=i.garbageCollect=[],i.font=e),t.font=e;var s=0;r.each(n,function(e){void 0!==e&&null!==e&&r.isArray(e)!==!0?s=r.measureText(t,a,o,s,e):r.isArray(e)&&r.each(e,function(e){void 0===e||null===e||r.isArray(e)||(s=r.measureText(t,a,o,s,e))})});var l=o.length/2;if(l>n.length){for(var u=0;l>u;u++)delete a[o[u]];o.splice(0,l)}return s},r.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},r.numberOfLabelLines=function(t){var e=1;return r.each(t,function(t){r.isArray(t)&&t.length>e&&(e=t.length)}),e},r.drawRoundedRectangle=function(t,e,n,i,a,r){t.beginPath(),t.moveTo(e+r,n),t.lineTo(e+i-r,n),t.quadraticCurveTo(e+i,n,e+i,n+r),t.lineTo(e+i,n+a-r),t.quadraticCurveTo(e+i,n+a,e+i-r,n+a),t.lineTo(e+r,n+a),t.quadraticCurveTo(e,n+a,e,n+a-r),t.lineTo(e,n+r),t.quadraticCurveTo(e,n,e+r,n),t.closePath()},r.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.log("Color.js not found!"),e)},r.addResizeListener=function(t,e){var n=document.createElement("iframe"),i="chartjs-hidden-iframe";n.classlist?n.classlist.add(i):n.setAttribute("class",i);var a=n.style;a.width="100%",a.display="block",a.border=0,a.height=0,a.margin=0,a.position="absolute",a.left=0,a.right=0,a.top=0,a.bottom=0,t.insertBefore(n,t.firstChild),(n.contentWindow||n).onresize=function(){e&&e()}},r.removeResizeListener=function(t){var e=t.querySelector(".chartjs-hidden-iframe");e&&e.parentNode.removeChild(e)},r.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},r.arrayEquals=function(t,e){var n,i,a,o;if(!t||!e||t.length!=e.length)return!1;for(n=0,i=t.length;i>n;++n)if(a=t[n],o=e[n],a instanceof Array&&o instanceof Array){if(!r.arrayEquals(a,o))return!1}else if(a!=o)return!1;return!0},r.callCallback=function(t,e,n){t&&"function"==typeof t.call&&t.apply(n,e)},r.getHoverColor=function(t){return t instanceof CanvasPattern?t:r.color(t).saturate(.5).darken(.1).rgbString()}}},{2:2}],26:[function(t,e,n){"use strict";e.exports=function(){var t=function(e,n){var i=this,a=t.helpers;return i.config=n,e.length&&e[0].getContext&&(e=e[0]),e.getContext&&(e=e.getContext("2d")),i.ctx=e,i.canvas=e.canvas,e.canvas.style.display=e.canvas.style.display||"block",i.width=e.canvas.width||parseInt(a.getStyle(e.canvas,"width"),10)||a.getMaximumWidth(e.canvas),i.height=e.canvas.height||parseInt(a.getStyle(e.canvas,"height"),10)||a.getMaximumHeight(e.canvas),i.aspectRatio=i.width/i.height,(isNaN(i.aspectRatio)||isFinite(i.aspectRatio)===!1)&&(i.aspectRatio=void 0!==n.aspectRatio?n.aspectRatio:2),i.originalCanvasStyleWidth=e.canvas.style.width,i.originalCanvasStyleHeight=e.canvas.style.height,a.retinaScale(i),n&&(i.controller=new t.Controller(i)),a.addResizeListener(e.canvas.parentNode,function(){i.controller&&i.controller.config.options.responsive&&i.controller.resize()}),i.controller?i.controller:i};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"single",animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var n=0;n<t.data.datasets.length;n++)e.push('<li><span style="background-color:'+t.data.datasets[n].backgroundColor+'"></span>'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],27:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){
-t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,n,i){function a(t){var e,n=t.isHorizontal();n?(e=t.update(t.options.fullWidth?p:k,x),_-=e.height):(e=t.update(y,b),k-=e.width),w.push({horizontal:n,minSize:e,box:t})}function r(t){var n=e.findNextWhere(w,function(e){return e.box===t});if(n)if(t.isHorizontal()){var i={left:S,right:M,top:0,bottom:0};t.update(t.options.fullWidth?p:k,m/2,i)}else t.update(n.minSize.width,_)}function o(t){var n=e.findNextWhere(w,function(e){return e.box===t}),i={left:0,right:0,top:D,bottom:C};n&&t.update(n.minSize.width,_,i)}function s(t){t.isHorizontal()?(t.left=t.options.fullWidth?l:S,t.right=t.options.fullWidth?n-l:S+k,t.top=A,t.bottom=A+t.height,A=t.bottom):(t.left=F,t.right=F+t.width,t.top=D,t.bottom=D+_,F=t.right)}if(t){var l=0,u=0,d=e.where(t.boxes,function(t){return"left"===t.options.position}),c=e.where(t.boxes,function(t){return"right"===t.options.position}),h=e.where(t.boxes,function(t){return"top"===t.options.position}),f=e.where(t.boxes,function(t){return"bottom"===t.options.position}),g=e.where(t.boxes,function(t){return"chartArea"===t.options.position});h.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),f.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var p=n-2*l,m=i-2*u,v=p/2,b=m/2,y=(n-v)/(d.length+c.length),x=(i-b)/(h.length+f.length),k=p,_=m,w=[];e.each(d.concat(c,h,f),a);var S=l,M=l,D=u,C=u;e.each(d.concat(c),r),e.each(d,function(t){S+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h.concat(f),r),e.each(h,function(t){D+=t.height}),e.each(f,function(t){C+=t.height}),e.each(d.concat(c),o),S=l,M=l,D=u,C=u,e.each(d,function(t){S+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h,function(t){D+=t.height}),e.each(f,function(t){C+=t.height});var T=i-D-C,P=n-S-M;(P!==k||T!==_)&&(e.each(d,function(t){t.height=T}),e.each(c,function(t){t.height=T}),e.each(h,function(t){t.options.fullWidth||(t.width=P)}),e.each(f,function(t){t.options.fullWidth||(t.width=P)}),_=T,k=P);var F=l,A=u;e.each(d.concat(h),s),F+=k,A+=_,e.each(c,s),e.each(f,s),t.chartArea={left:S,top:D,right:S+k,bottom:D+_},e.each(g,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(k,_)})}}}}},{}],28:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=e.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},labels:{boxWidth:40,padding:10,generateLabels:function(t){var n=t.data;return e.isArray(n.datasets)?n.datasets.map(function(n,i){return{text:n.label,fillStyle:e.isArray(n.backgroundColor)?n.backgroundColor[0]:n.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:n.borderCapStyle,lineDash:n.borderDash,lineDashOffset:n.borderDashOffset,lineJoin:n.borderJoinStyle,lineWidth:n.borderWidth,strokeStyle:n.borderColor,datasetIndex:i}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){e.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:n,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:n,beforeSetDimensions:n,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:n,beforeBuildLabels:n,buildLabels:function(){var t=this;t.legendItems=t.options.labels.generateLabels.call(t,t.chart),t.options.reverse&&t.legendItems.reverse()},afterBuildLabels:n,beforeFit:n,fit:function(){var n=this,i=n.options,a=i.labels,r=i.display,o=n.ctx,s=t.defaults.global,l=e.getValueOrDefault,u=l(a.fontSize,s.defaultFontSize),d=l(a.fontStyle,s.defaultFontStyle),c=l(a.fontFamily,s.defaultFontFamily),h=e.fontString(u,d,c),f=n.legendHitBoxes=[],g=n.minSize,p=n.isHorizontal();if(p?(g.width=n.maxWidth,g.height=r?10:0):(g.width=r?10:0,g.height=n.maxHeight),r)if(o.font=h,p){var m=n.lineWidths=[0],v=n.legendItems.length?u+a.padding:0;o.textAlign="left",o.textBaseline="top",e.each(n.legendItems,function(t,e){var i=a.boxWidth+u/2+o.measureText(t.text).width;m[m.length-1]+i+a.padding>=n.width&&(v+=u+a.padding,m[m.length]=n.left),f[e]={left:0,top:0,width:i,height:u},m[m.length-1]+=i+a.padding}),g.height+=v}else{var b=a.padding,y=n.columnWidths=[],x=a.padding,k=0,_=0,w=u+b;e.each(n.legendItems,function(t,e){var n=a.boxWidth+u/2+o.measureText(t.text).width;_+w>g.height&&(x+=k+a.padding,y.push(k),k=0,_=0),k=Math.max(k,n),_+=w,f[e]={left:0,top:0,width:n,height:u}}),x+=k,y.push(k),g.width+=x}n.width=g.width,n.height=g.height},afterFit:n,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var n=this,i=n.options,a=i.labels,r=t.defaults.global,o=r.elements.line,s=n.width,l=(n.height,n.lineWidths);if(i.display){var u,d=n.ctx,c=e.getValueOrDefault,h=c(a.fontColor,r.defaultFontColor),f=c(a.fontSize,r.defaultFontSize),g=c(a.fontStyle,r.defaultFontStyle),p=c(a.fontFamily,r.defaultFontFamily),m=e.fontString(f,g,p);d.textAlign="left",d.textBaseline="top",d.lineWidth=.5,d.strokeStyle=h,d.fillStyle=h,d.font=m;var v=a.boxWidth,b=n.legendHitBoxes,y=function(t,e,n){d.save(),d.fillStyle=c(n.fillStyle,r.defaultColor),d.lineCap=c(n.lineCap,o.borderCapStyle),d.lineDashOffset=c(n.lineDashOffset,o.borderDashOffset),d.lineJoin=c(n.lineJoin,o.borderJoinStyle),d.lineWidth=c(n.lineWidth,o.borderWidth),d.strokeStyle=c(n.strokeStyle,r.defaultColor),d.setLineDash&&d.setLineDash(c(n.lineDash,o.borderDash)),d.strokeRect(t,e,v,f),d.fillRect(t,e,v,f),d.restore()},x=function(t,e,n,i){d.fillText(n.text,v+f/2+t,e),n.hidden&&(d.beginPath(),d.lineWidth=2,d.moveTo(v+f/2+t,e+f/2),d.lineTo(v+f/2+t+i,e+f/2),d.stroke())},k=n.isHorizontal();u=k?{x:n.left+(s-l[0])/2,y:n.top+a.padding,line:0}:{x:n.left+a.padding,y:n.top,line:0};var _=f+a.padding;e.each(n.legendItems,function(t,e){var i=d.measureText(t.text).width,r=v+f/2+i,o=u.x,c=u.y;k?o+r>=s&&(c=u.y+=f+a.padding,u.line++,o=u.x=n.left+(s-l[u.line])/2):c+_>n.bottom&&(o=u.x=o+n.columnWidths[u.line]+a.padding,c=u.y=n.top,u.line++),y(o,c,t),b[e].left=o,b[e].top=c,x(o,c,t,i),k?u.x+=r+a.padding:u.y+=_})}},handleEvent:function(t){var n=this,i=e.getRelativePosition(t,n.chart.chart),a=i.x,r=i.y,o=n.options;if(a>=n.left&&a<=n.right&&r>=n.top&&r<=n.bottom)for(var s=n.legendHitBoxes,l=0;l<s.length;++l){var u=s[l];if(a>=u.left&&a<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){o.onClick&&o.onClick.call(n,t,n.legendItems[l]);break}}}}),t.plugins.register({beforeInit:function(e){var n=e.options,i=n.legend;i&&(e.legend=new t.Legend({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.legend))}})}},{}],29:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers.noop;t.plugins={_plugins:[],register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)})},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)})},clear:function(){this._plugins=[]},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e){var n,i,a=this._plugins,r=a.length;for(n=0;r>n;++n)if(i=a[n],"function"==typeof i[t]&&i[t].apply(i,e||[])===!1)return!1;return!0}},t.PluginBase=t.Element.extend({beforeInit:e,afterInit:e,beforeUpdate:e,afterUpdate:e,beforeDraw:e,afterDraw:e,destroy:e}),t.pluginService=t.plugins}},{}],30:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:10,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:function(t){return e.isArray(t)?t:""+t}}},t.Scale=t.Element.extend({beforeUpdate:function(){e.callCallback(this.options.beforeUpdate,[this])},update:function(t,n,i){var a=this;return a.beforeUpdate(),a.maxWidth=t,a.maxHeight=n,a.margins=e.extend({left:0,right:0,top:0,bottom:0},i),a.beforeSetDimensions(),a.setDimensions(),a.afterSetDimensions(),a.beforeDataLimits(),a.determineDataLimits(),a.afterDataLimits(),a.beforeBuildTicks(),a.buildTicks(),a.afterBuildTicks(),a.beforeTickToLabelConversion(),a.convertTicksToLabels(),a.afterTickToLabelConversion(),a.beforeCalculateTickRotation(),a.calculateTickRotation(),a.afterCalculateTickRotation(),a.beforeFit(),a.fit(),a.afterFit(),a.afterUpdate(),a.minSize},afterUpdate:function(){e.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){e.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){e.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){e.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:e.noop,afterDataLimits:function(){e.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){e.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:e.noop,afterBuildTicks:function(){e.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){e.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this;t.ticks=t.ticks.map(function(e,n,i){return t.options.ticks.userCallback?t.options.ticks.userCallback(e,n,i):t.options.ticks.callback(e,n,i)},t)},afterTickToLabelConversion:function(){e.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){e.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var n=this,i=n.ctx,a=t.defaults.global,r=n.options.ticks,o=e.getValueOrDefault(r.fontSize,a.defaultFontSize),s=e.getValueOrDefault(r.fontStyle,a.defaultFontStyle),l=e.getValueOrDefault(r.fontFamily,a.defaultFontFamily),u=e.fontString(o,s,l);i.font=u;var d,c=i.measureText(n.ticks[0]).width,h=i.measureText(n.ticks[n.ticks.length-1]).width;if(n.labelRotation=r.minRotation||0,n.paddingRight=0,n.paddingLeft=0,n.options.display&&n.isHorizontal()){n.paddingRight=h/2+3,n.paddingLeft=c/2+3,n.longestTextCache||(n.longestTextCache={});for(var f,g,p=e.longestText(i,u,n.ticks,n.longestTextCache),m=p,v=n.getPixelForTick(1)-n.getPixelForTick(0)-6;m>v&&n.labelRotation<r.maxRotation;){if(f=Math.cos(e.toRadians(n.labelRotation)),g=Math.sin(e.toRadians(n.labelRotation)),d=f*c,d+o/2>n.yLabelWidth&&(n.paddingLeft=d+o/2),n.paddingRight=o/2,g*p>n.maxHeight){n.labelRotation--;break}n.labelRotation++,m=f*p}}n.margins&&(n.paddingLeft=Math.max(n.paddingLeft-n.margins.left,0),n.paddingRight=Math.max(n.paddingRight-n.margins.right,0))},afterCalculateTickRotation:function(){e.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){e.callCallback(this.options.beforeFit,[this])},fit:function(){var n=this,i=n.minSize={width:0,height:0},a=n.options,r=t.defaults.global,o=a.ticks,s=a.scaleLabel,l=a.display,u=n.isHorizontal(),d=e.getValueOrDefault(o.fontSize,r.defaultFontSize),c=e.getValueOrDefault(o.fontStyle,r.defaultFontStyle),h=e.getValueOrDefault(o.fontFamily,r.defaultFontFamily),f=e.fontString(d,c,h),g=e.getValueOrDefault(s.fontSize,r.defaultFontSize),p=e.getValueOrDefault(s.fontStyle,r.defaultFontStyle),m=e.getValueOrDefault(s.fontFamily,r.defaultFontFamily),v=(e.fontString(g,p,m),a.gridLines.tickMarkLength);if(u?i.width=n.isFullWidth()?n.maxWidth-n.margins.left-n.margins.right:n.maxWidth:i.width=l?v:0,u?i.height=l?v:0:i.height=n.maxHeight,s.display&&l&&(u?i.height+=1.5*g:i.width+=1.5*g),o.display&&l){n.longestTextCache||(n.longestTextCache={});var b=e.longestText(n.ctx,f,n.ticks,n.longestTextCache),y=e.numberOfLabelLines(n.ticks),x=.5*d;if(u){n.longestLabelWidth=b;var k=Math.sin(e.toRadians(n.labelRotation))*n.longestLabelWidth+d*y+x*y;i.height=Math.min(n.maxHeight,i.height+k),n.ctx.font=f;var _=n.ctx.measureText(n.ticks[0]).width,w=n.ctx.measureText(n.ticks[n.ticks.length-1]).width,S=Math.cos(e.toRadians(n.labelRotation)),M=Math.sin(e.toRadians(n.labelRotation));n.paddingLeft=0!==n.labelRotation?S*_+3:_/2+3,n.paddingRight=0!==n.labelRotation?M*(d/2)+3:w/2+3}else{var D=n.maxWidth-i.width,C=o.mirror;C?b=0:b+=n.options.ticks.padding,D>b?i.width+=b:i.width=n.maxWidth,n.paddingTop=d/2,n.paddingBottom=d/2}}n.margins&&(n.paddingLeft=Math.max(n.paddingLeft-n.margins.left,0),n.paddingTop=Math.max(n.paddingTop-n.margins.top,0),n.paddingRight=Math.max(n.paddingRight-n.margins.right,0),n.paddingBottom=Math.max(n.paddingBottom-n.margins.bottom,0)),n.width=i.width,n.height=i.height},afterFit:function(){e.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function n(t){return null===t||"undefined"==typeof t?NaN:"number"==typeof t&&isNaN(t)?NaN:"object"==typeof t?t instanceof Date||t.isValid?t:n(this.isHorizontal()?t.x:t.y):t},getLabelForIndex:e.noop,getPixelForValue:e.noop,getValueForPixel:e.noop,getPixelForTick:function(t,e){var n=this;if(n.isHorizontal()){var i=n.width-(n.paddingLeft+n.paddingRight),a=i/Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),r=a*t+n.paddingLeft;e&&(r+=a/2);var o=n.left+Math.round(r);return o+=n.isFullWidth()?n.margins.left:0}var s=n.height-(n.paddingTop+n.paddingBottom);return n.top+t*(s/(n.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var n=e.width-(e.paddingLeft+e.paddingRight),i=n*t+e.paddingLeft,a=e.left+Math.round(i);return a+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){var t=this,e=t.min,n=t.max;return t.getPixelForValue(t.beginAtZero?0:0>e&&0>n?n:e>0&&n>0?e:0)},draw:function(n){var i=this,a=i.options;if(a.display){var r,o,s=i.ctx,l=t.defaults.global,u=a.ticks,d=a.gridLines,c=a.scaleLabel,h=0!==i.labelRotation,f=u.autoSkip,g=i.isHorizontal();u.maxTicksLimit&&(o=u.maxTicksLimit);var p=e.getValueOrDefault(u.fontColor,l.defaultFontColor),m=e.getValueOrDefault(u.fontSize,l.defaultFontSize),v=e.getValueOrDefault(u.fontStyle,l.defaultFontStyle),b=e.getValueOrDefault(u.fontFamily,l.defaultFontFamily),y=e.fontString(m,v,b),x=d.tickMarkLength,k=e.getValueOrDefault(c.fontColor,l.defaultFontColor),_=e.getValueOrDefault(c.fontSize,l.defaultFontSize),w=e.getValueOrDefault(c.fontStyle,l.defaultFontStyle),S=e.getValueOrDefault(c.fontFamily,l.defaultFontFamily),M=e.fontString(_,w,S),D=e.toRadians(i.labelRotation),C=Math.cos(D),T=(Math.sin(D),i.longestLabelWidth*C);s.fillStyle=p;var P=[];if(g){if(r=!1,h&&(T/=2),(T+u.autoSkipPadding)*i.ticks.length>i.width-(i.paddingLeft+i.paddingRight)&&(r=1+Math.floor((T+u.autoSkipPadding)*i.ticks.length/(i.width-(i.paddingLeft+i.paddingRight)))),o&&i.ticks.length>o)for(;!r||i.ticks.length/(r||1)>o;)r||(r=1),r+=1;f||(r=!1)}var F="right"===a.position?i.left:i.right-x,A="right"===a.position?i.left+x:i.right,I="bottom"===a.position?i.top:i.bottom-x,O="bottom"===a.position?i.top+x:i.bottom;if(e.each(i.ticks,function(t,o){if(void 0!==t&&null!==t){var s=i.ticks.length===o+1,l=r>1&&o%r>0||o%r===0&&o+r>=i.ticks.length;if((!l||s)&&void 0!==t&&null!==t){var c,f;o===("undefined"!=typeof i.zeroLineIndex?i.zeroLineIndex:0)?(c=d.zeroLineWidth,f=d.zeroLineColor):(c=e.getValueAtIndexOrDefault(d.lineWidth,o),f=e.getValueAtIndexOrDefault(d.color,o));var p,m,v,b,y,k,_,w,S,M,C,T="middle";if(g){h||(T="top"===a.position?"bottom":"top"),C=h?"right":"center";var R=i.getPixelForTick(o)+e.aliasPixel(c);S=i.getPixelForTick(o,d.offsetGridLines)+u.labelOffset,M=h?i.top+12:"top"===a.position?i.bottom-x:i.top+x,p=v=y=_=R,m=I,b=O,k=n.top,w=n.bottom}else{"left"===a.position?u.mirror?(S=i.right+u.padding,C="left"):(S=i.right-u.padding,C="right"):u.mirror?(S=i.left-u.padding,C="right"):(S=i.left+u.padding,C="left");var W=i.getPixelForTick(o);W+=e.aliasPixel(c),M=i.getPixelForTick(o,d.offsetGridLines),p=F,v=A,y=n.left,_=n.right,m=b=k=w=W}P.push({tx1:p,ty1:m,tx2:v,ty2:b,x1:y,y1:k,x2:_,y2:w,labelX:S,labelY:M,glWidth:c,glColor:f,rotation:-1*D,label:t,textBaseline:T,textAlign:C})}}}),e.each(P,function(t){if(d.display&&(s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.beginPath(),d.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),d.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke()),u.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=y,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var n=t.label;if(e.isArray(n))for(var i=0,a=0;i<n.length;++i)s.fillText(""+n[i],0,a),a+=1.5*m;else s.fillText(n,0,0);s.restore()}}),c.display){var R,W,V=0;if(g)R=i.left+(i.right-i.left)/2,W="bottom"===a.position?i.bottom-_/2:i.top+_/2;else{var L="left"===a.position;R=L?i.left+_/2:i.right-_/2,W=i.top+(i.bottom-i.top)/2,V=L?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(R,W),s.rotate(V),s.textAlign="center",s.textBaseline="middle",s.fillStyle=k,s.font=M,s.fillText(c.labelString,0,0),s.restore()}if(d.drawBorder){s.lineWidth=e.getValueAtIndexOrDefault(d.lineWidth,0),s.strokeStyle=e.getValueAtIndexOrDefault(d.color,0);var Y=i.left,B=i.right,z=i.top,H=i.bottom,N=e.aliasPixel(s.lineWidth);g?(z=H="top"===a.position?i.bottom:i.top,z+=N,H+=N):(Y=B="left"===a.position?i.right:i.left,Y+=N,B+=N),s.beginPath(),s.moveTo(Y,z),s.lineTo(B,H),s.stroke()}}}})}},{}],31:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,n,i){this.constructors[t]=n,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(n){return this.defaults.hasOwnProperty(n)?e.scaleMerge(t.defaults.scale,this.defaults[n]):{}},updateScaleDefaults:function(t,n){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],n))},addScalesToLayout:function(n){e.each(n.scales,function(e){t.layoutService.addBox(n,e)})}}}},{}],32:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var n=e.noop;t.Title=t.Element.extend({initialize:function(n){var i=this;e.extend(i,n),i.options=e.configMerge(t.defaults.global.title,n.options),i.legendHitBoxes=[]},beforeUpdate:function(){var n=this.chart.options;n&&n.title&&(this.options=e.configMerge(t.defaults.global.title,n.title))},update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:n,beforeSetDimensions:n,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:n,beforeBuildLabels:n,buildLabels:n,afterBuildLabels:n,beforeFit:n,fit:function(){var n=this,i=(n.ctx,e.getValueOrDefault),a=n.options,r=t.defaults.global,o=a.display,s=i(a.fontSize,r.defaultFontSize),l=n.minSize;n.isHorizontal()?(l.width=n.maxWidth,l.height=o?s+2*a.padding:0):(l.width=o?s+2*a.padding:0,l.height=n.maxHeight),n.width=l.width,n.height=l.height},afterFit:n,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var n=this,i=n.ctx,a=e.getValueOrDefault,r=n.options,o=t.defaults.global;if(r.display){var s,l,u=a(r.fontSize,o.defaultFontSize),d=a(r.fontStyle,o.defaultFontStyle),c=a(r.fontFamily,o.defaultFontFamily),h=e.fontString(u,d,c),f=0,g=n.top,p=n.left,m=n.bottom,v=n.right;i.fillStyle=a(r.fontColor,o.defaultFontColor),i.font=h,n.isHorizontal()?(s=p+(v-p)/2,l=g+(m-g)/2):(s="left"===r.position?p+u/2:v-u/2,l=g+(m-g)/2,f=Math.PI*("left"===r.position?-.5:.5)),i.save(),i.translate(s,l),i.rotate(f),i.textAlign="center",i.textBaseline="middle",i.fillText(r.text,0,0),i.restore()}}}),t.plugins.register({beforeInit:function(e){var n=e.options,i=n.title;i&&(e.titleBlock=new t.Title({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.titleBlock))}})}},{}],33:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return e&&(a.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function n(t){if(!t.length)return!1;var e,n,i=[],a=[];for(e=0,n=t.length;n>e;++e){var r=t[e];if(r&&r.hasValue()){var o=r.tooltipPosition();i.push(o.x),a.push(o.y)}}var s=0,l=0;for(e=0,n-i.length;n>e;++e)s+=i[e],l+=a[e];return{x:Math.round(s/i.length),y:Math.round(l/i.length)}}function i(t){var e=t._xScale,n=t._yScale||t._scale,i=t._index,a=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,a):"",yLabel:n?n.getLabelForIndex(i,a):"",index:i,datasetIndex:a}}var a=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"single",backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,yAlign:"center",xAlign:"center",caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",callbacks:{beforeTitle:a.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:a.noop,beforeBody:a.noop,beforeLabel:a.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n+": "+t.yLabel},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex),i=n.data[t.index],a=i._view;return{borderColor:a.borderColor,backgroundColor:a.backgroundColor}},afterLabel:a.noop,afterBody:a.noop,beforeFooter:a.noop,footer:a.noop,afterFooter:a.noop}},t.Tooltip=t.Element.extend({initialize:function(){var e=this,n=t.defaults.global,i=e._options,r=a.getValueOrDefault;a.extend(e,{_model:{xPadding:i.xPadding,yPadding:i.yPadding,xAlign:i.yAlign,yAlign:i.xAlign,bodyFontColor:i.bodyFontColor,_bodyFontFamily:r(i.bodyFontFamily,n.defaultFontFamily),_bodyFontStyle:r(i.bodyFontStyle,n.defaultFontStyle),_bodyAlign:i.bodyAlign,bodyFontSize:r(i.bodyFontSize,n.defaultFontSize),bodySpacing:i.bodySpacing,titleFontColor:i.titleFontColor,_titleFontFamily:r(i.titleFontFamily,n.defaultFontFamily),_titleFontStyle:r(i.titleFontStyle,n.defaultFontStyle),titleFontSize:r(i.titleFontSize,n.defaultFontSize),_titleAlign:i.titleAlign,titleSpacing:i.titleSpacing,titleMarginBottom:i.titleMarginBottom,footerFontColor:i.footerFontColor,_footerFontFamily:r(i.footerFontFamily,n.defaultFontFamily),_footerFontStyle:r(i.footerFontStyle,n.defaultFontStyle),footerFontSize:r(i.footerFontSize,n.defaultFontSize),_footerAlign:i.footerAlign,footerSpacing:i.footerSpacing,footerMarginTop:i.footerMarginTop,caretSize:i.caretSize,cornerRadius:i.cornerRadius,backgroundColor:i.backgroundColor,opacity:0,legendColorBackground:i.multiKeyBackground}})},getTitle:function(){var t=this,n=t._options,i=n.callbacks,a=i.beforeTitle.apply(t,arguments),r=i.title.apply(t,arguments),o=i.afterTitle.apply(t,arguments),s=[];return s=e(s,a),s=e(s,r),s=e(s,o)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return a.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,n){var i=this,r=i._options.callbacks,o=[];return a.each(t,function(t){var a={before:[],lines:[],after:[]};e(a.before,r.beforeLabel.call(i,t,n)),e(a.lines,r.label.call(i,t,n)),e(a.after,r.afterLabel.call(i,t,n)),o.push(a)}),o},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return a.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,n=t._options.callbacks,i=n.beforeFooter.apply(t,arguments),a=n.footer.apply(t,arguments),r=n.afterFooter.apply(t,arguments),o=[];return o=e(o,i),o=e(o,a),o=e(o,r)},update:function(t){var e,r,o=this,s=o._options,l=o._model,u=o._active,d=o._data,c=o._chartInstance;if(u.length){l.opacity=1;var h=[],f=n(u),g=[];for(e=0,r=u.length;r>e;++e)g.push(i(u[e]));s.itemSort&&(g=g.sort(s.itemSort)),u.length>1&&a.each(g,function(t){h.push(s.callbacks.labelColor.call(o,t,c))}),a.extend(l,{title:o.getTitle(g,d),beforeBody:o.getBeforeBody(g,d),body:o.getBody(g,d),afterBody:o.getAfterBody(g,d),footer:o.getFooter(g,d),x:Math.round(f.x),y:Math.round(f.y),caretPadding:a.getValueOrDefault(f.padding,2),labelColors:h});var p=o.getTooltipSize(l);o.determineAlignment(p),a.extend(l,o.getBackgroundPoint(l,p))}else o._model.opacity=0;return t&&s.custom&&s.custom.call(o,l),o},getTooltipSize:function(t){var e=this._chart.ctx,n={height:2*t.yPadding,width:0},i=t.body,r=i.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);r+=t.beforeBody.length+t.afterBody.length;var o=t.title.length,s=t.footer.length,l=t.titleFontSize,u=t.bodyFontSize,d=t.footerFontSize;n.height+=o*l,n.height+=(o-1)*t.titleSpacing,n.height+=o?t.titleMarginBottom:0,n.height+=r*u,n.height+=r?(r-1)*t.bodySpacing:0,n.height+=s?t.footerMarginTop:0,n.height+=s*d,n.height+=s?(s-1)*t.footerSpacing:0;var c=0,h=function(t){n.width=Math.max(n.width,e.measureText(t).width+c)};return e.font=a.fontString(l,t._titleFontStyle,t._titleFontFamily),a.each(t.title,h),e.font=a.fontString(u,t._bodyFontStyle,t._bodyFontFamily),a.each(t.beforeBody.concat(t.afterBody),h),c=i.length>1?u+2:0,a.each(i,function(t){a.each(t.before,h),a.each(t.lines,h),a.each(t.after,h)}),c=0,e.font=a.fontString(d,t._footerFontStyle,t._footerFontFamily),a.each(t.footer,h),n.width+=2*t.xPadding,n},determineAlignment:function(t){var e=this,n=e._model,i=e._chart,a=e._chartInstance.chartArea;n.y<t.height?n.yAlign="top":n.y>i.height-t.height&&(n.yAlign="bottom");var r,o,s,l,u,d=(a.left+a.right)/2,c=(a.top+a.bottom)/2;"center"===n.yAlign?(r=function(t){return d>=t},o=function(t){return t>d}):(r=function(e){return e<=t.width/2},o=function(e){return e>=i.width-t.width/2}),s=function(e){return e+t.width>i.width},l=function(e){return e-t.width<0},u=function(t){return c>=t?"top":"bottom"},r(n.x)?(n.xAlign="left",s(n.x)&&(n.xAlign="center",n.yAlign=u(n.y))):o(n.x)&&(n.xAlign="right",l(n.x)&&(n.xAlign="center",n.yAlign=u(n.y)))},getBackgroundPoint:function(t,e){var n={x:t.x,y:t.y},i=t.caretSize,a=t.caretPadding,r=t.cornerRadius,o=t.xAlign,s=t.yAlign,l=i+a,u=r+a;return"right"===o?n.x-=e.width:"center"===o&&(n.x-=e.width/2),"top"===s?n.y+=l:"bottom"===s?n.y-=e.height+l:n.y-=e.height/2,"center"===s?"left"===o?n.x+=l:"right"===o&&(n.x-=l):"left"===o?n.x-=u:"right"===o&&(n.x+=u),n},drawCaret:function(t,e,n,i){var r,o,s,l,u,d,c=this._view,h=this._chart.ctx,f=c.caretSize,g=c.cornerRadius,p=c.xAlign,m=c.yAlign,v=t.x,b=t.y,y=e.width,x=e.height;"center"===m?("left"===p?(r=v,o=r-f,s=r):(r=v+y,o=r+f,s=r),u=b+x/2,l=u-f,d=u+f):("left"===p?(r=v+g,o=r+f,s=o+f):"right"===p?(r=v+y-g,o=r-f,s=o-f):(o=v+y/2,r=o-f,s=o+f),"top"===m?(l=b,u=l-f,d=l):(l=b+x,u=l+f,d=l));var k=a.color(c.backgroundColor);h.fillStyle=k.alpha(n*k.alpha()).rgbString(),h.beginPath(),h.moveTo(r,l),h.lineTo(o,u),h.lineTo(s,d),h.closePath(),h.fill()},drawTitle:function(t,e,n,i){var r=e.title;if(r.length){n.textAlign=e._titleAlign,n.textBaseline="top";var o=e.titleFontSize,s=e.titleSpacing,l=a.color(e.titleFontColor);n.fillStyle=l.alpha(i*l.alpha()).rgbString(),n.font=a.fontString(o,e._titleFontStyle,e._titleFontFamily);var u,d;for(u=0,d=r.length;d>u;++u)n.fillText(r[u],t.x,t.y),t.y+=o+s,u+1===r.length&&(t.y+=e.titleMarginBottom-s)}},drawBody:function(t,e,n,i){var r=e.bodyFontSize,o=e.bodySpacing,s=e.body;n.textAlign=e._bodyAlign,n.textBaseline="top";var l=a.color(e.bodyFontColor),u=l.alpha(i*l.alpha()).rgbString();n.fillStyle=u,n.font=a.fontString(r,e._bodyFontStyle,e._bodyFontFamily);var d=0,c=function(e){n.fillText(e,t.x+d,t.y),t.y+=r+o};a.each(e.beforeBody,c);var h=s.length>1;d=h?r+2:0,a.each(s,function(o,s){a.each(o.before,c),a.each(o.lines,function(o){h&&(n.fillStyle=a.color(e.legendColorBackground).alpha(i).rgbaString(),n.fillRect(t.x,t.y,r,r),n.strokeStyle=a.color(e.labelColors[s].borderColor).alpha(i).rgbaString(),n.strokeRect(t.x,t.y,r,r),n.fillStyle=a.color(e.labelColors[s].backgroundColor).alpha(i).rgbaString(),n.fillRect(t.x+1,t.y+1,r-2,r-2),n.fillStyle=u),c(o)}),a.each(o.after,c)}),d=0,a.each(e.afterBody,c),t.y-=o},drawFooter:function(t,e,n,i){var r=e.footer;if(r.length){t.y+=e.footerMarginTop,n.textAlign=e._footerAlign,n.textBaseline="top";var o=a.color(e.footerFontColor);n.fillStyle=o.alpha(i*o.alpha()).rgbString(),n.font=a.fontString(e.footerFontSize,e._footerFontStyle,e._footerFontFamily),a.each(r,function(i){n.fillText(i,t.x,t.y),t.y+=e.footerFontSize+e.footerSpacing})}},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n=this.getTooltipSize(e),i={x:e.x,y:e.y},r=Math.abs(e.opacity<.001)?0:e.opacity;if(this._options.enabled){var o=a.color(e.backgroundColor);t.fillStyle=o.alpha(r*o.alpha()).rgbString(),a.drawRoundedRectangle(t,i.x,i.y,n.width,n.height,e.cornerRadius),t.fill(),this.drawCaret(i,n,r,e.caretPadding),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,r),this.drawBody(i,e,t,r),this.drawFooter(i,e,t,r)}}}})}},{}],34:[function(t,e,n){"use strict";e.exports=function(t,e){var n=t.helpers,i=t.defaults.global;i.elements.arc={backgroundColor:i.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2):!1},inRange:function(t,e){var i=this._view;if(i){for(var a=n.getAngleFromPoint(i,{x:t,y:e}),r=a.angle,o=a.distance,s=i.startAngle,l=i.endAngle;s>l;)l+=2*Math.PI;for(;r>l;)r-=2*Math.PI;for(;s>r;)r+=2*Math.PI;var u=r>=s&&l>=r,d=o>=i.innerRadius&&o<=i.outerRadius;return u&&d}return!1},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t=this._chart.ctx,e=this._view,n=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,i),t.arc(e.x,e.y,e.innerRadius,i,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],35:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:n.defaultColor,borderWidth:3,borderColor:n.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",fill:!0},t.elements.Line=t.Element.extend({lineToNextPoint:function(t,e,n,i,a){var r=this,o=r._chart.ctx,s=r._view?r._view.spanGaps:!1;e._view.skip&&!s?i.call(r,t,e,n):t._view.skip&&!s?a.call(r,t,e,n):0===e._view.tension?o.lineTo(e._view.x,e._view.y):o.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,e._view.controlPointPreviousX,e._view.controlPointPreviousY,e._view.x,e._view.y)},draw:function(){function t(t){o._view.skip||s._view.skip?t&&r.lineTo(i._view.scaleZero.x,i._view.scaleZero.y):r.bezierCurveTo(s._view.controlPointNextX,s._view.controlPointNextY,o._view.controlPointPreviousX,o._view.controlPointPreviousY,o._view.x,o._view.y)}var i=this,a=i._view,r=i._chart.ctx,o=i._children[0],s=i._children[i._children.length-1];
-r.save(),i._children.length>0&&a.fill&&(r.beginPath(),e.each(i._children,function(t,n){var o=e.previousItem(i._children,n),s=e.nextItem(i._children,n);0===n?(i._loop?r.moveTo(a.scaleZero.x,a.scaleZero.y):r.moveTo(t._view.x,a.scaleZero),t._view.skip?i._loop||r.moveTo(s._view.x,i._view.scaleZero):r.lineTo(t._view.x,t._view.y)):i.lineToNextPoint(o,t,s,function(t,e,n){i._loop?r.lineTo(i._view.scaleZero.x,i._view.scaleZero.y):(r.lineTo(t._view.x,i._view.scaleZero),r.moveTo(n._view.x,i._view.scaleZero))},function(t,e){r.lineTo(e._view.x,e._view.y)})},i),i._loop?t(!0):(r.lineTo(i._children[i._children.length-1]._view.x,a.scaleZero),r.lineTo(i._children[0]._view.x,a.scaleZero)),r.fillStyle=a.backgroundColor||n.defaultColor,r.closePath(),r.fill());var l=n.elements.line;r.lineCap=a.borderCapStyle||l.borderCapStyle,r.setLineDash&&r.setLineDash(a.borderDash||l.borderDash),r.lineDashOffset=a.borderDashOffset||l.borderDashOffset,r.lineJoin=a.borderJoinStyle||l.borderJoinStyle,r.lineWidth=a.borderWidth||l.borderWidth,r.strokeStyle=a.borderColor||n.defaultColor,r.beginPath(),e.each(i._children,function(t,n){var a=e.previousItem(i._children,n),o=e.nextItem(i._children,n);0===n?r.moveTo(t._view.x,t._view.y):i.lineToNextPoint(a,t,o,function(t,e,n){r.moveTo(n._view.x,n._view.y)},function(t,e){r.moveTo(e._view.x,e._view.y)})},i),i._loop&&i._children.length>0&&t(),r.stroke(),r.restore()}})}},{}],36:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global,i=n.defaultColor;n.elements.point={radius:3,pointStyle:"circle",backgroundColor:i,borderWidth:1,borderColor:i,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var n=this._view;return n?Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2):!1},inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2):!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(){var t,a,r,o,s,l,u=this._view,d=this._chart.ctx,c=u.pointStyle,h=u.radius,f=u.x,g=u.y;if(!u.skip){if("object"==typeof c&&(t=c.toString(),"[object HTMLImageElement]"===t||"[object HTMLCanvasElement]"===t))return void d.drawImage(c,f-c.width/2,g-c.height/2);if(!(isNaN(h)||0>=h)){switch(d.strokeStyle=u.borderColor||i,d.lineWidth=e.getValueOrDefault(u.borderWidth,n.elements.point.borderWidth),d.fillStyle=u.backgroundColor||i,c){default:d.beginPath(),d.arc(f,g,h,0,2*Math.PI),d.closePath(),d.fill();break;case"triangle":d.beginPath(),a=3*h/Math.sqrt(3),s=a*Math.sqrt(3)/2,d.moveTo(f-a/2,g+s/3),d.lineTo(f+a/2,g+s/3),d.lineTo(f,g-2*s/3),d.closePath(),d.fill();break;case"rect":l=1/Math.SQRT2*h,d.fillRect(f-l,g-l,2*l,2*l),d.strokeRect(f-l,g-l,2*l,2*l);break;case"rectRot":l=1/Math.SQRT2*h,d.beginPath(),d.moveTo(f-l,g),d.lineTo(f,g+l),d.lineTo(f+l,g),d.lineTo(f,g-l),d.closePath(),d.fill();break;case"cross":d.beginPath(),d.moveTo(f,g+h),d.lineTo(f,g-h),d.moveTo(f-h,g),d.lineTo(f+h,g),d.closePath();break;case"crossRot":d.beginPath(),r=Math.cos(Math.PI/4)*h,o=Math.sin(Math.PI/4)*h,d.moveTo(f-r,g-o),d.lineTo(f+r,g+o),d.moveTo(f-r,g+o),d.lineTo(f+r,g-o),d.closePath();break;case"star":d.beginPath(),d.moveTo(f,g+h),d.lineTo(f,g-h),d.moveTo(f-h,g),d.lineTo(f+h,g),r=Math.cos(Math.PI/4)*h,o=Math.sin(Math.PI/4)*h,d.moveTo(f-r,g-o),d.lineTo(f+r,g+o),d.moveTo(f-r,g+o),d.lineTo(f+r,g-o),d.closePath();break;case"line":d.beginPath(),d.moveTo(f-h,g),d.lineTo(f+h,g),d.closePath();break;case"dash":d.beginPath(),d.moveTo(f,g),d.lineTo(f+h,g),d.closePath()}d.stroke()}}}})}},{}],37:[function(t,e,n){"use strict";e.exports=function(t){var e=(t.helpers,t.defaults.global);e.elements.rectangle={backgroundColor:e.defaultColor,borderWidth:0,borderColor:e.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return l[(d+t)%4]}var e=this._chart.ctx,n=this._view,i=n.width/2,a=n.x-i,r=n.x+i,o=n.base-(n.base-n.y),s=n.borderWidth/2;n.borderWidth&&(a+=s,r-=s,o+=s),e.beginPath(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,e.lineWidth=n.borderWidth;var l=[[a,n.base],[a,o],[r,o],[r,n.base]],u=["bottom","left","top","right"],d=u.indexOf(n.borderSkipped,0);-1===d&&(d=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),n.borderWidth&&e.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var n=this._view;return n?n.y<n.base?t>=n.x-n.width/2&&t<=n.x+n.width/2&&e>=n.y&&e<=n.base:t>=n.x-n.width/2&&t<=n.x+n.width/2&&e>=n.base&&e<=n.y:!1},inLabelRange:function(t){var e=this._view;return e?t>=e.x-e.width/2&&t<=e.x+e.width/2:!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],38:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"bottom"},i=t.Scale.extend({determineDataLimits:function(){var t=this;t.minIndex=0,t.maxIndex=t.chart.data.labels.length-1;var n;void 0!==t.options.ticks.min&&(n=e.indexOf(t.chart.data.labels,t.options.ticks.min),t.minIndex=-1!==n?n:t.minIndex),void 0!==t.options.ticks.max&&(n=e.indexOf(t.chart.data.labels,t.options.ticks.max),t.maxIndex=-1!==n?n:t.maxIndex),t.min=t.chart.data.labels[t.minIndex],t.max=t.chart.data.labels[t.maxIndex]},buildTicks:function(t){var e=this;e.ticks=0===e.minIndex&&e.maxIndex===e.chart.data.labels.length-1?e.chart.data.labels:e.chart.data.labels.slice(e.minIndex,e.maxIndex+1)},getLabelForIndex:function(t,e){return this.ticks[t]},getPixelForValue:function(t,e,n,i){var a=this,r=Math.max(a.maxIndex+1-a.minIndex-(a.options.gridLines.offsetGridLines?0:1),1);if(a.isHorizontal()){var o=a.width-(a.paddingLeft+a.paddingRight),s=o/r,l=s*(e-a.minIndex)+a.paddingLeft;return a.options.gridLines.offsetGridLines&&i&&(l+=s/2),a.left+Math.round(l)}var u=a.height-(a.paddingTop+a.paddingBottom),d=u/r,c=d*(e-a.minIndex)+a.paddingTop;return a.options.gridLines.offsetGridLines&&i&&(c+=d/2),a.top+Math.round(c)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,n=this,i=Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),a=n.isHorizontal(),r=a?n.width-(n.paddingLeft+n.paddingRight):n.height-(n.paddingTop+n.paddingBottom),o=r/i;return n.options.gridLines.offsetGridLines&&(t-=o/2),t-=a?n.paddingLeft:n.paddingTop,e=0>=t?0:Math.round(t/o)}});t.scaleService.registerScaleType("category",i,n)}},{}],39:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:function(t,n,i){var a=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var r=e.log10(Math.abs(a)),o="";if(0!==t){var s=-1*Math.floor(r);s=Math.max(Math.min(s,20),0),o=t.toFixed(s)}else o="0";return o}}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return s?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=(i.ticks,n.chart),r=a.data,o=r.datasets,s=n.isHorizontal();if(n.min=null,n.max=null,i.stacked){var l={},u=!1,d=!1;e.each(o,function(r,o){var s=a.getDatasetMeta(o);void 0===l[s.type]&&(l[s.type]={positiveValues:[],negativeValues:[]});var c=l[s.type].positiveValues,h=l[s.type].negativeValues;a.isDatasetVisible(o)&&t(s)&&e.each(r.data,function(t,e){var a=+n.getRightValue(t);isNaN(a)||s.data[e].hidden||(c[e]=c[e]||0,h[e]=h[e]||0,i.relativePoints?c[e]=100:0>a?(d=!0,h[e]+=a):(u=!0,c[e]+=a))})}),e.each(l,function(t){var i=t.positiveValues.concat(t.negativeValues),a=e.min(i),r=e.max(i);n.min=null===n.min?a:Math.min(n.min,a),n.max=null===n.max?r:Math.max(n.max,r)})}else e.each(o,function(i,r){var o=a.getDatasetMeta(r);a.isDatasetVisible(r)&&t(o)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||o.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var n,i=this,a=i.options.ticks;if(i.isHorizontal())n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.width/50));else{var r=e.getValueOrDefault(a.fontSize,t.defaults.global.defaultFontSize);n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.height/(2*r)))}return n},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t,e,n,i){var a,r,o=this,s=o.paddingLeft,l=o.paddingBottom,u=o.start,d=+o.getRightValue(t),c=o.end-u;return o.isHorizontal()?(r=o.width-(s+o.paddingRight),a=o.left+r/c*(d-u),Math.round(a+s)):(r=o.height-(o.paddingTop+l),a=o.bottom-l-r/c*(d-u),Math.round(a))},getValueForPixel:function(t){var e=this,n=e.isHorizontal(),i=e.paddingLeft,a=e.paddingBottom,r=n?e.width-(i+e.paddingRight):e.height-(e.paddingTop+a),o=(n?t-e.left-i:e.bottom-a-t)/r;return e.start+(e.end-e.start)*o},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticksAsNumbers[t],null,null,e)}});t.scaleService.registerScaleType("linear",i,n)}},{}],40:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,n=t.options,i=n.ticks;if(i.beginAtZero){var a=e.sign(t.min),r=e.sign(t.max);0>a&&0>r?t.max=0:a>0&&r>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:n,handleDirectionalChanges:n,buildTicks:function(){var t=this,n=t.options,i=n.ticks,a=e.getValueOrDefault,r=(t.isHorizontal(),t.ticks=[]),o=t.getTickLimit();o=Math.max(2,o);var s,l=i.fixedStepSize&&i.fixedStepSize>0||i.stepSize&&i.stepSize>0;if(l)s=a(i.fixedStepSize,i.stepSize);else{var u=e.niceNum(t.max-t.min,!1);s=e.niceNum(u/(o-1),!0)}var d=Math.floor(t.min/s)*s,c=Math.ceil(t.max/s)*s,h=(c-d)/s;h=e.almostEquals(h,Math.round(h),s/1e3)?Math.round(h):Math.ceil(h),r.push(void 0!==i.min?i.min:d);for(var f=1;h>f;++f)r.push(d+f*s);r.push(void 0!==i.max?i.max:c),t.handleDirectionalChanges(),t.max=e.max(r),t.min=e.min(r),i.reverse?(r.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],41:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:function(t,n,i){var a=t/Math.pow(10,Math.floor(e.log10(t)));return 1===a||2===a||5===a||0===n||n===i.length-1?t.toExponential():""}}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return u?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=i.ticks,r=n.chart,o=r.data,s=o.datasets,l=e.getValueOrDefault,u=n.isHorizontal();if(n.min=null,n.max=null,i.stacked){var d={};e.each(s,function(a,o){var s=r.getDatasetMeta(o);r.isDatasetVisible(o)&&t(s)&&(void 0===d[s.type]&&(d[s.type]=[]),e.each(a.data,function(t,e){var a=d[s.type],r=+n.getRightValue(t);isNaN(r)||s.data[e].hidden||(a[e]=a[e]||0,i.relativePoints?a[e]=100:a[e]+=r)}))}),e.each(d,function(t){var i=e.min(t),a=e.max(t);n.min=null===n.min?i:Math.min(n.min,i),n.max=null===n.max?a:Math.max(n.max,a)})}else e.each(s,function(i,a){var o=r.getDatasetMeta(a);r.isDatasetVisible(a)&&t(o)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||o.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i))})});n.min=l(a.min,n.min),n.max=l(a.max,n.max),n.min===n.max&&(0!==n.min&&null!==n.min?(n.min=Math.pow(10,Math.floor(e.log10(n.min))-1),n.max=Math.pow(10,Math.floor(e.log10(n.max))+1)):(n.min=1,n.max=10))},buildTicks:function(){for(var t=this,n=t.options,i=n.ticks,a=e.getValueOrDefault,r=t.ticks=[],o=a(i.min,Math.pow(10,Math.floor(e.log10(t.min))));o<t.max;){r.push(o);var s=Math.floor(e.log10(o)),l=Math.floor(o/Math.pow(10,s))+1;10===l&&(l=1,++s),o=l*Math.pow(10,s)}var u=a(i.max,o);r.push(u),t.isHorizontal()||r.reverse(),t.max=e.max(r),t.min=e.min(r),i.reverse?(r.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t,e){return this.getPixelForValue(this.tickValues[t],null,null,e)},getPixelForValue:function(t,n,i,a){var r,o,s=this,l=s.start,u=+s.getRightValue(t),d=e.log10(s.end)-e.log10(l),c=s.paddingTop,h=s.paddingBottom,f=s.paddingLeft;return s.isHorizontal()?0===u?o=s.left+f:(r=s.width-(f+s.paddingRight),o=s.left+r/d*(e.log10(u)-e.log10(l)),o+=f):0===u?o=s.top+c:(r=s.height-(c+h),o=s.bottom-h-r/d*(e.log10(u)-e.log10(l))),o},getValueForPixel:function(t){var n,i,a=this,r=e.log10(a.end)-e.log10(a.start);return a.isHorizontal()?(i=a.width-(a.paddingLeft+a.paddingRight),n=a.start*Math.pow(10,(t-a.left-a.paddingLeft)*r/i)):(i=a.height-(a.paddingTop+a.paddingBottom),n=Math.pow(10,(a.bottom-a.paddingBottom-t)*r/i)/a.start),n}});t.scaleService.registerScaleType("logarithmic",i,n)}},{}],42:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global,i={display:!0,animate:!0,lineArc:!1,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2},pointLabels:{fontSize:10,callback:function(t){return t}}},a=t.LinearScaleBase.extend({getValueCount:function(){return this.chart.data.labels.length},setDimensions:function(){var t=this,i=t.options,a=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var r=e.min([t.height,t.width]),o=e.getValueOrDefault(a.fontSize,n.defaultFontSize);t.drawingArea=i.display?r/2-(o/2+a.backdropPaddingY):r/2},determineDataLimits:function(){var t=this,n=t.chart;t.min=null,t.max=null,e.each(n.data.datasets,function(i,a){if(n.isDatasetVisible(a)){var r=n.getDatasetMeta(a);e.each(i.data,function(e,n){var i=+t.getRightValue(e);isNaN(i)||r.data[n].hidden||(null===t.min?t.min=i:i<t.min&&(t.min=i),null===t.max?t.max=i:i>t.max&&(t.max=i))})}}),t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=e.getValueOrDefault(t.fontSize,n.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,i,a,r,o,s,l,u,d,c,h,f,g=this.options.pointLabels,p=e.getValueOrDefault(g.fontSize,n.defaultFontSize),m=e.getValueOrDefault(g.fontStyle,n.defaultFontStyle),v=e.getValueOrDefault(g.fontFamily,n.defaultFontFamily),b=e.fontString(p,m,v),y=e.min([this.height/2-p-5,this.width/2]),x=this.width,k=0;for(this.ctx.font=b,i=0;i<this.getValueCount();i++)t=this.getPointPosition(i,y),a=this.ctx.measureText(this.pointLabels[i]?this.pointLabels[i]:"").width+5,0===i||i===this.getValueCount()/2?(r=a/2,t.x+r>x&&(x=t.x+r,o=i),t.x-r<k&&(k=t.x-r,l=i)):i<this.getValueCount()/2?t.x+a>x&&(x=t.x+a,o=i):i>this.getValueCount()/2&&t.x-a<k&&(k=t.x-a,l=i);d=k,c=Math.ceil(x-this.width),s=this.getIndexAngle(o),u=this.getIndexAngle(l),h=c/Math.sin(s+Math.PI/2),f=d/Math.sin(u+Math.PI/2),h=e.isNumber(h)?h:0,f=e.isNumber(f)?f:0,this.drawingArea=Math.round(y-(f+h)/2),this.setCenterPoint(f,h)},setCenterPoint:function(t,e){var n=this,i=n.width-e-n.drawingArea,a=t+n.drawingArea;n.xCenter=Math.round((a+i)/2+n.left),n.yCenter=Math.round(n.height/2+n.top)},getIndexAngle:function(t){var e=2*Math.PI/this.getValueCount();return t*e-Math.PI/2},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var n=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this,i=n.getIndexAngle(t);return{x:Math.round(Math.cos(i)*e)+n.xCenter,y:Math.round(Math.sin(i)*e)+n.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,n=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:0>e&&0>n?n:e>0&&n>0?e:0)},draw:function(){var t=this,i=t.options,a=i.gridLines,r=i.ticks,o=i.angleLines,s=i.pointLabels,l=e.getValueOrDefault;if(i.display){var u=t.ctx,d=l(r.fontSize,n.defaultFontSize),c=l(r.fontStyle,n.defaultFontStyle),h=l(r.fontFamily,n.defaultFontFamily),f=e.fontString(d,c,h);if(e.each(t.ticks,function(o,s){if(s>0||i.reverse){var c=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]),h=t.yCenter-c;if(a.display&&0!==s)if(u.strokeStyle=e.getValueAtIndexOrDefault(a.color,s-1),u.lineWidth=e.getValueAtIndexOrDefault(a.lineWidth,s-1),i.lineArc)u.beginPath(),u.arc(t.xCenter,t.yCenter,c,0,2*Math.PI),u.closePath(),u.stroke();else{u.beginPath();for(var g=0;g<t.getValueCount();g++){var p=t.getPointPosition(g,c);0===g?u.moveTo(p.x,p.y):u.lineTo(p.x,p.y)}u.closePath(),u.stroke()}if(r.display){var m=l(r.fontColor,n.defaultFontColor);if(u.font=f,r.showLabelBackdrop){var v=u.measureText(o).width;u.fillStyle=r.backdropColor,u.fillRect(t.xCenter-v/2-r.backdropPaddingX,h-d/2-r.backdropPaddingY,v+2*r.backdropPaddingX,d+2*r.backdropPaddingY)}u.textAlign="center",u.textBaseline="middle",u.fillStyle=m,u.fillText(o,t.xCenter,h)}}}),!i.lineArc){u.lineWidth=o.lineWidth,u.strokeStyle=o.color;for(var g=t.getDistanceFromCenterForValue(i.reverse?t.min:t.max),p=l(s.fontSize,n.defaultFontSize),m=l(s.fontStyle,n.defaultFontStyle),v=l(s.fontFamily,n.defaultFontFamily),b=e.fontString(p,m,v),y=t.getValueCount()-1;y>=0;y--){if(o.display){var x=t.getPointPosition(y,g);u.beginPath(),u.moveTo(t.xCenter,t.yCenter),u.lineTo(x.x,x.y),u.stroke(),u.closePath()}var k=t.getPointPosition(y,g+5),_=l(s.fontColor,n.defaultFontColor);u.font=b,u.fillStyle=_;var w=t.pointLabels,S=w.length,M=w.length/2,D=M/2,C=D>y||y>S-D,T=y===D||y===S-D;0===y?u.textAlign="center":y===M?u.textAlign="center":M>y?u.textAlign="left":u.textAlign="right",T?u.textBaseline="middle":C?u.textBaseline="bottom":u.textBaseline="top",u.fillText(w[y]?w[y]:"",k.x,k.y)}}}}});t.scaleService.registerScaleType("radialLinear",a,i)}},{}],43:[function(t,e,n){"use strict";var i=t(6);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,n={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},a={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},r=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return this.labelMoments[t][e]},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var n=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e,i){var a=t.parseTime(e);a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),n.push(a))},t),t.firstTick=i.min.call(t,n),t.lastTick=i.max.call(t,n)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(a,r){var o=[],s=t.chart.isDatasetVisible(r);"object"==typeof a.data[0]&&null!==a.data[0]?e.each(a.data,function(e,n){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),o.push(a),s&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,a):a,t.lastTick=null!==t.lastTick?i.max(t.lastTick,a):a))},t):o=n,t.labelMoments.push(o)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildTicks:function(i){var a=this;a.ctx.save();var r=e.getValueOrDefault(a.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=e.getValueOrDefault(a.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),s=e.getValueOrDefault(a.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),l=e.fontString(r,o,s);if(a.ctx.font=l,a.ticks=[],a.unitScale=1,a.scaleSizeInUnits=0,a.options.time.unit)a.tickUnit=a.options.time.unit||"day",a.displayFormat=a.options.time.displayFormats[a.tickUnit],a.scaleSizeInUnits=a.lastTick.diff(a.firstTick,a.tickUnit,!0),a.unitScale=e.getValueOrDefault(a.options.time.unitStepSize,1);else{var u=a.isHorizontal()?a.width-(a.paddingLeft+a.paddingRight):a.height-(a.paddingTop+a.paddingBottom),d=a.tickFormatFunction(a.firstTick,0,[]),c=a.ctx.measureText(d).width,h=Math.cos(e.toRadians(a.options.ticks.maxRotation)),f=Math.sin(e.toRadians(a.options.ticks.maxRotation));c=c*h+r*f;var g=u/c;a.tickUnit="millisecond",a.scaleSizeInUnits=a.lastTick.diff(a.firstTick,a.tickUnit,!0),a.displayFormat=a.options.time.displayFormats[a.tickUnit];for(var p=0,m=n.units[p];p<n.units.length;){if(a.unitScale=1,e.isArray(m.steps)&&Math.ceil(a.scaleSizeInUnits/g)<e.max(m.steps)){for(var v=0;v<m.steps.length;++v)if(m.steps[v]>=Math.ceil(a.scaleSizeInUnits/g)){a.unitScale=e.getValueOrDefault(a.options.time.unitStepSize,m.steps[v]);break}break}if(m.maxStep===!1||Math.ceil(a.scaleSizeInUnits/g)<m.maxStep){a.unitScale=e.getValueOrDefault(a.options.time.unitStepSize,Math.ceil(a.scaleSizeInUnits/g));break}++p,m=n.units[p],a.tickUnit=m.name;var b=a.firstTick.diff(a.getMomentStartOf(a.firstTick),a.tickUnit,!0),y=a.getMomentStartOf(a.lastTick.clone().add(1,a.tickUnit)).diff(a.lastTick,a.tickUnit,!0);a.scaleSizeInUnits=a.lastTick.diff(a.firstTick,a.tickUnit,!0)+b+y,a.displayFormat=a.options.time.displayFormats[m.name]}}var x;if(a.options.time.min?x=a.getMomentStartOf(a.firstTick):(a.firstTick=a.getMomentStartOf(a.firstTick),x=a.firstTick),!a.options.time.max){var k=a.getMomentStartOf(a.lastTick);0!==k.diff(a.lastTick,a.tickUnit,!0)&&(a.lastTick=a.getMomentStartOf(a.lastTick.add(1,a.tickUnit)))}a.smallestLabelSeparation=a.width,e.each(a.chart.data.datasets,function(t,e){for(var n=1;n<a.labelMoments[e].length;n++)a.smallestLabelSeparation=Math.min(a.smallestLabelSeparation,a.labelMoments[e][n].diff(a.labelMoments[e][n-1],a.tickUnit,!0))},a),a.options.time.displayFormat&&(a.displayFormat=a.options.time.displayFormat),a.ticks.push(a.firstTick.clone());for(var _=1;_<=a.scaleSizeInUnits;++_){var w=x.clone().add(_,a.tickUnit);if(a.options.time.max&&w.diff(a.lastTick,a.tickUnit,!0)>=0)break;_%a.unitScale===0&&a.ticks.push(w)}var S=a.ticks[a.ticks.length-1].diff(a.lastTick,a.tickUnit);(0!==S||0===a.scaleSizeInUnits)&&(a.options.time.max?(a.ticks.push(a.lastTick.clone()),a.scaleSizeInUnits=a.lastTick.diff(a.ticks[0],a.tickUnit,!0)):(a.ticks.push(a.lastTick.clone()),a.scaleSizeInUnits=a.lastTick.diff(a.firstTick,a.tickUnit,!0))),a.ctx.restore()},getLabelForIndex:function(t,e){var n=this,i=n.chart.data.labels&&t<n.chart.data.labels.length?n.chart.data.labels[t]:"";return"object"==typeof n.chart.data.datasets[e].data[0]&&(i=n.getRightValue(n.chart.data.datasets[e].data[t])),n.options.time.tooltipFormat&&(i=n.parseTime(i).format(n.options.time.tooltipFormat)),i},tickFormatFunction:function(t,n,i){var a=t.format(this.displayFormat),r=this.options.ticks,o=e.getValueOrDefault(r.callback,r.userCallback);return o?o(a,n,i):a},convertTicksToLabels:function(){var t=this;t.tickMoments=t.ticks,t.ticks=t.ticks.map(t.tickFormatFunction,t)},getPixelForValue:function(t,e,n,i){var a=this,r=t&&t.isValid&&t.isValid()?t:a.getLabelMoment(n,e);if(r){var o=r.diff(a.firstTick,a.tickUnit,!0),s=o/a.scaleSizeInUnits;if(a.isHorizontal()){var l=a.width-(a.paddingLeft+a.paddingRight),u=(l/Math.max(a.ticks.length-1,1),l*s+a.paddingLeft);return a.left+Math.round(u)}var d=a.height-(a.paddingTop+a.paddingBottom),c=(d/Math.max(a.ticks.length-1,1),d*s+a.paddingTop);return a.top+Math.round(c)}},getPixelForTick:function(t,e){return this.getPixelForValue(this.tickMoments[t],null,null,e)},getValueForPixel:function(t){var e=this,n=e.isHorizontal()?e.width-(e.paddingLeft+e.paddingRight):e.height-(e.paddingTop+e.paddingBottom),a=(t-(e.isHorizontal()?e.left+e.paddingLeft:e.top+e.paddingTop))/n;return a*=e.scaleSizeInUnits,e.firstTick.clone().add(i.duration(a,e.tickUnit).asSeconds(),"seconds")},parseTime:function(t){var e=this;return"string"==typeof e.options.time.parser?i(t,e.options.time.parser):"function"==typeof e.options.time.parser?e.options.time.parser(t):"function"==typeof t.getMonth||"number"==typeof t?i(t):t.isValid&&t.isValid()?t:"string"!=typeof e.options.time.format&&e.options.time.format.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"),e.options.time.format(t)):i(t,e.options.time.format)}});t.scaleService.registerScaleType("time",r,a)}},{6:6}]},{},[7])(7)});
\ No newline at end of file
+++ /dev/null
-/*!
- * Chart.js
- * http://chartjs.org/
- * Version: 2.1.6
- *
- * Copyright 2016 Nick Downie
- * Released under the MIT license
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
- */
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-
-},{}],2:[function(require,module,exports){
-/* MIT license */\r
-var colorNames = require(6);\r
-\r
-module.exports = {\r
- getRgba: getRgba,\r
- getHsla: getHsla,\r
- getRgb: getRgb,\r
- getHsl: getHsl,\r
- getHwb: getHwb,\r
- getAlpha: getAlpha,\r
-\r
- hexString: hexString,\r
- rgbString: rgbString,\r
- rgbaString: rgbaString,\r
- percentString: percentString,\r
- percentaString: percentaString,\r
- hslString: hslString,\r
- hslaString: hslaString,\r
- hwbString: hwbString,\r
- keyword: keyword\r
-}\r
-\r
-function getRgba(string) {\r
- if (!string) {\r
- return;\r
- }\r
- var abbr = /^#([a-fA-F0-9]{3})$/,\r
- hex = /^#([a-fA-F0-9]{6})$/,\r
- rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,\r
- per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,\r
- keyword = /(\w+)/;\r
-\r
- var rgb = [0, 0, 0],\r
- a = 1,\r
- match = string.match(abbr);\r
- if (match) {\r
- match = match[1];\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = parseInt(match[i] + match[i], 16);\r
- }\r
- }\r
- else if (match = string.match(hex)) {\r
- match = match[1];\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);\r
- }\r
- }\r
- else if (match = string.match(rgba)) {\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = parseInt(match[i + 1]);\r
- }\r
- a = parseFloat(match[4]);\r
- }\r
- else if (match = string.match(per)) {\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);\r
- }\r
- a = parseFloat(match[4]);\r
- }\r
- else if (match = string.match(keyword)) {\r
- if (match[1] == "transparent") {\r
- return [0, 0, 0, 0];\r
- }\r
- rgb = colorNames[match[1]];\r
- if (!rgb) {\r
- return;\r
- }\r
- }\r
-\r
- for (var i = 0; i < rgb.length; i++) {\r
- rgb[i] = scale(rgb[i], 0, 255);\r
- }\r
- if (!a && a != 0) {\r
- a = 1;\r
- }\r
- else {\r
- a = scale(a, 0, 1);\r
- }\r
- rgb[3] = a;\r
- return rgb;\r
-}\r
-\r
-function getHsla(string) {\r
- if (!string) {\r
- return;\r
- }\r
- var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;\r
- var match = string.match(hsl);\r
- if (match) {\r
- var alpha = parseFloat(match[4]);\r
- var h = scale(parseInt(match[1]), 0, 360),\r
- s = scale(parseFloat(match[2]), 0, 100),\r
- l = scale(parseFloat(match[3]), 0, 100),\r
- a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r
- return [h, s, l, a];\r
- }\r
-}\r
-\r
-function getHwb(string) {\r
- if (!string) {\r
- return;\r
- }\r
- var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;\r
- var match = string.match(hwb);\r
- if (match) {\r
- var alpha = parseFloat(match[4]);\r
- var h = scale(parseInt(match[1]), 0, 360),\r
- w = scale(parseFloat(match[2]), 0, 100),\r
- b = scale(parseFloat(match[3]), 0, 100),\r
- a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r
- return [h, w, b, a];\r
- }\r
-}\r
-\r
-function getRgb(string) {\r
- var rgba = getRgba(string);\r
- return rgba && rgba.slice(0, 3);\r
-}\r
-\r
-function getHsl(string) {\r
- var hsla = getHsla(string);\r
- return hsla && hsla.slice(0, 3);\r
-}\r
-\r
-function getAlpha(string) {\r
- var vals = getRgba(string);\r
- if (vals) {\r
- return vals[3];\r
- }\r
- else if (vals = getHsla(string)) {\r
- return vals[3];\r
- }\r
- else if (vals = getHwb(string)) {\r
- return vals[3];\r
- }\r
-}\r
-\r
-// generators\r
-function hexString(rgb) {\r
- return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])\r
- + hexDouble(rgb[2]);\r
-}\r
-\r
-function rgbString(rgba, alpha) {\r
- if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r
- return rgbaString(rgba, alpha);\r
- }\r
- return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";\r
-}\r
-\r
-function rgbaString(rgba, alpha) {\r
- if (alpha === undefined) {\r
- alpha = (rgba[3] !== undefined ? rgba[3] : 1);\r
- }\r
- return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]\r
- + ", " + alpha + ")";\r
-}\r
-\r
-function percentString(rgba, alpha) {\r
- if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r
- return percentaString(rgba, alpha);\r
- }\r
- var r = Math.round(rgba[0]/255 * 100),\r
- g = Math.round(rgba[1]/255 * 100),\r
- b = Math.round(rgba[2]/255 * 100);\r
-\r
- return "rgb(" + r + "%, " + g + "%, " + b + "%)";\r
-}\r
-\r
-function percentaString(rgba, alpha) {\r
- var r = Math.round(rgba[0]/255 * 100),\r
- g = Math.round(rgba[1]/255 * 100),\r
- b = Math.round(rgba[2]/255 * 100);\r
- return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";\r
-}\r
-\r
-function hslString(hsla, alpha) {\r
- if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {\r
- return hslaString(hsla, alpha);\r
- }\r
- return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";\r
-}\r
-\r
-function hslaString(hsla, alpha) {\r
- if (alpha === undefined) {\r
- alpha = (hsla[3] !== undefined ? hsla[3] : 1);\r
- }\r
- return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "\r
- + alpha + ")";\r
-}\r
-\r
-// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax\r
-// (hwb have alpha optional & 1 is default value)\r
-function hwbString(hwb, alpha) {\r
- if (alpha === undefined) {\r
- alpha = (hwb[3] !== undefined ? hwb[3] : 1);\r
- }\r
- return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"\r
- + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";\r
-}\r
-\r
-function keyword(rgb) {\r
- return reverseNames[rgb.slice(0, 3)];\r
-}\r
-\r
-// helpers\r
-function scale(num, min, max) {\r
- return Math.min(Math.max(min, num), max);\r
-}\r
-\r
-function hexDouble(num) {\r
- var str = num.toString(16).toUpperCase();\r
- return (str.length < 2) ? "0" + str : str;\r
-}\r
-\r
-\r
-//create a list of reverse color names\r
-var reverseNames = {};\r
-for (var name in colorNames) {\r
- reverseNames[colorNames[name]] = name;\r
-}\r
-
-},{"6":6}],3:[function(require,module,exports){
-/* MIT license */\r
-var convert = require(5);\r
-var string = require(2);\r
-\r
-var Color = function (obj) {\r
- if (obj instanceof Color) {\r
- return obj;\r
- }\r
- if (!(this instanceof Color)) {\r
- return new Color(obj);\r
- }\r
-\r
- this.values = {\r
- rgb: [0, 0, 0],\r
- hsl: [0, 0, 0],\r
- hsv: [0, 0, 0],\r
- hwb: [0, 0, 0],\r
- cmyk: [0, 0, 0, 0],\r
- alpha: 1\r
- };\r
-\r
- // parse Color() argument\r
- var vals;\r
- if (typeof obj === 'string') {\r
- vals = string.getRgba(obj);\r
- if (vals) {\r
- this.setValues('rgb', vals);\r
- } else if (vals = string.getHsla(obj)) {\r
- this.setValues('hsl', vals);\r
- } else if (vals = string.getHwb(obj)) {\r
- this.setValues('hwb', vals);\r
- } else {\r
- throw new Error('Unable to parse color from string "' + obj + '"');\r
- }\r
- } else if (typeof obj === 'object') {\r
- vals = obj;\r
- if (vals.r !== undefined || vals.red !== undefined) {\r
- this.setValues('rgb', vals);\r
- } else if (vals.l !== undefined || vals.lightness !== undefined) {\r
- this.setValues('hsl', vals);\r
- } else if (vals.v !== undefined || vals.value !== undefined) {\r
- this.setValues('hsv', vals);\r
- } else if (vals.w !== undefined || vals.whiteness !== undefined) {\r
- this.setValues('hwb', vals);\r
- } else if (vals.c !== undefined || vals.cyan !== undefined) {\r
- this.setValues('cmyk', vals);\r
- } else {\r
- throw new Error('Unable to parse color from object ' + JSON.stringify(obj));\r
- }\r
- }\r
-};\r
-\r
-Color.prototype = {\r
- rgb: function () {\r
- return this.setSpace('rgb', arguments);\r
- },\r
- hsl: function () {\r
- return this.setSpace('hsl', arguments);\r
- },\r
- hsv: function () {\r
- return this.setSpace('hsv', arguments);\r
- },\r
- hwb: function () {\r
- return this.setSpace('hwb', arguments);\r
- },\r
- cmyk: function () {\r
- return this.setSpace('cmyk', arguments);\r
- },\r
-\r
- rgbArray: function () {\r
- return this.values.rgb;\r
- },\r
- hslArray: function () {\r
- return this.values.hsl;\r
- },\r
- hsvArray: function () {\r
- return this.values.hsv;\r
- },\r
- hwbArray: function () {\r
- var values = this.values;\r
- if (values.alpha !== 1) {\r
- return values.hwb.concat([values.alpha]);\r
- }\r
- return values.hwb;\r
- },\r
- cmykArray: function () {\r
- return this.values.cmyk;\r
- },\r
- rgbaArray: function () {\r
- var values = this.values;\r
- return values.rgb.concat([values.alpha]);\r
- },\r
- hslaArray: function () {\r
- var values = this.values;\r
- return values.hsl.concat([values.alpha]);\r
- },\r
- alpha: function (val) {\r
- if (val === undefined) {\r
- return this.values.alpha;\r
- }\r
- this.setValues('alpha', val);\r
- return this;\r
- },\r
-\r
- red: function (val) {\r
- return this.setChannel('rgb', 0, val);\r
- },\r
- green: function (val) {\r
- return this.setChannel('rgb', 1, val);\r
- },\r
- blue: function (val) {\r
- return this.setChannel('rgb', 2, val);\r
- },\r
- hue: function (val) {\r
- if (val) {\r
- val %= 360;\r
- val = val < 0 ? 360 + val : val;\r
- }\r
- return this.setChannel('hsl', 0, val);\r
- },\r
- saturation: function (val) {\r
- return this.setChannel('hsl', 1, val);\r
- },\r
- lightness: function (val) {\r
- return this.setChannel('hsl', 2, val);\r
- },\r
- saturationv: function (val) {\r
- return this.setChannel('hsv', 1, val);\r
- },\r
- whiteness: function (val) {\r
- return this.setChannel('hwb', 1, val);\r
- },\r
- blackness: function (val) {\r
- return this.setChannel('hwb', 2, val);\r
- },\r
- value: function (val) {\r
- return this.setChannel('hsv', 2, val);\r
- },\r
- cyan: function (val) {\r
- return this.setChannel('cmyk', 0, val);\r
- },\r
- magenta: function (val) {\r
- return this.setChannel('cmyk', 1, val);\r
- },\r
- yellow: function (val) {\r
- return this.setChannel('cmyk', 2, val);\r
- },\r
- black: function (val) {\r
- return this.setChannel('cmyk', 3, val);\r
- },\r
-\r
- hexString: function () {\r
- return string.hexString(this.values.rgb);\r
- },\r
- rgbString: function () {\r
- return string.rgbString(this.values.rgb, this.values.alpha);\r
- },\r
- rgbaString: function () {\r
- return string.rgbaString(this.values.rgb, this.values.alpha);\r
- },\r
- percentString: function () {\r
- return string.percentString(this.values.rgb, this.values.alpha);\r
- },\r
- hslString: function () {\r
- return string.hslString(this.values.hsl, this.values.alpha);\r
- },\r
- hslaString: function () {\r
- return string.hslaString(this.values.hsl, this.values.alpha);\r
- },\r
- hwbString: function () {\r
- return string.hwbString(this.values.hwb, this.values.alpha);\r
- },\r
- keyword: function () {\r
- return string.keyword(this.values.rgb, this.values.alpha);\r
- },\r
-\r
- rgbNumber: function () {\r
- var rgb = this.values.rgb;\r
- return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\r
- },\r
-\r
- luminosity: function () {\r
- // http://www.w3.org/TR/WCAG20/#relativeluminancedef\r
- var rgb = this.values.rgb;\r
- var lum = [];\r
- for (var i = 0; i < rgb.length; i++) {\r
- var chan = rgb[i] / 255;\r
- lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\r
- }\r
- return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\r
- },\r
-\r
- contrast: function (color2) {\r
- // http://www.w3.org/TR/WCAG20/#contrast-ratiodef\r
- var lum1 = this.luminosity();\r
- var lum2 = color2.luminosity();\r
- if (lum1 > lum2) {\r
- return (lum1 + 0.05) / (lum2 + 0.05);\r
- }\r
- return (lum2 + 0.05) / (lum1 + 0.05);\r
- },\r
-\r
- level: function (color2) {\r
- var contrastRatio = this.contrast(color2);\r
- if (contrastRatio >= 7.1) {\r
- return 'AAA';\r
- }\r
-\r
- return (contrastRatio >= 4.5) ? 'AA' : '';\r
- },\r
-\r
- dark: function () {\r
- // YIQ equation from http://24ways.org/2010/calculating-color-contrast\r
- var rgb = this.values.rgb;\r
- var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\r
- return yiq < 128;\r
- },\r
-\r
- light: function () {\r
- return !this.dark();\r
- },\r
-\r
- negate: function () {\r
- var rgb = [];\r
- for (var i = 0; i < 3; i++) {\r
- rgb[i] = 255 - this.values.rgb[i];\r
- }\r
- this.setValues('rgb', rgb);\r
- return this;\r
- },\r
-\r
- lighten: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[2] += hsl[2] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- darken: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[2] -= hsl[2] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- saturate: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[1] += hsl[1] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- desaturate: function (ratio) {\r
- var hsl = this.values.hsl;\r
- hsl[1] -= hsl[1] * ratio;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- whiten: function (ratio) {\r
- var hwb = this.values.hwb;\r
- hwb[1] += hwb[1] * ratio;\r
- this.setValues('hwb', hwb);\r
- return this;\r
- },\r
-\r
- blacken: function (ratio) {\r
- var hwb = this.values.hwb;\r
- hwb[2] += hwb[2] * ratio;\r
- this.setValues('hwb', hwb);\r
- return this;\r
- },\r
-\r
- greyscale: function () {\r
- var rgb = this.values.rgb;\r
- // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\r
- var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\r
- this.setValues('rgb', [val, val, val]);\r
- return this;\r
- },\r
-\r
- clearer: function (ratio) {\r
- var alpha = this.values.alpha;\r
- this.setValues('alpha', alpha - (alpha * ratio));\r
- return this;\r
- },\r
-\r
- opaquer: function (ratio) {\r
- var alpha = this.values.alpha;\r
- this.setValues('alpha', alpha + (alpha * ratio));\r
- return this;\r
- },\r
-\r
- rotate: function (degrees) {\r
- var hsl = this.values.hsl;\r
- var hue = (hsl[0] + degrees) % 360;\r
- hsl[0] = hue < 0 ? 360 + hue : hue;\r
- this.setValues('hsl', hsl);\r
- return this;\r
- },\r
-\r
- /**\r
- * Ported from sass implementation in C\r
- * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\r
- */\r
- mix: function (mixinColor, weight) {\r
- var color1 = this;\r
- var color2 = mixinColor;\r
- var p = weight === undefined ? 0.5 : weight;\r
-\r
- var w = 2 * p - 1;\r
- var a = color1.alpha() - color2.alpha();\r
-\r
- var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\r
- var w2 = 1 - w1;\r
-\r
- return this\r
- .rgb(\r
- w1 * color1.red() + w2 * color2.red(),\r
- w1 * color1.green() + w2 * color2.green(),\r
- w1 * color1.blue() + w2 * color2.blue()\r
- )\r
- .alpha(color1.alpha() * p + color2.alpha() * (1 - p));\r
- },\r
-\r
- toJSON: function () {\r
- return this.rgb();\r
- },\r
-\r
- clone: function () {\r
- // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,\r
- // making the final build way to big to embed in Chart.js. So let's do it manually,\r
- // assuming that values to clone are 1 dimension arrays containing only numbers,\r
- // except 'alpha' which is a number.\r
- var result = new Color();\r
- var source = this.values;\r
- var target = result.values;\r
- var value, type;\r
-\r
- for (var prop in source) {\r
- if (source.hasOwnProperty(prop)) {\r
- value = source[prop];\r
- type = ({}).toString.call(value);\r
- if (type === '[object Array]') {\r
- target[prop] = value.slice(0);\r
- } else if (type === '[object Number]') {\r
- target[prop] = value;\r
- } else {\r
- console.error('unexpected color value:', value);\r
- }\r
- }\r
- }\r
-\r
- return result;\r
- }\r
-};\r
-\r
-Color.prototype.spaces = {\r
- rgb: ['red', 'green', 'blue'],\r
- hsl: ['hue', 'saturation', 'lightness'],\r
- hsv: ['hue', 'saturation', 'value'],\r
- hwb: ['hue', 'whiteness', 'blackness'],\r
- cmyk: ['cyan', 'magenta', 'yellow', 'black']\r
-};\r
-\r
-Color.prototype.maxes = {\r
- rgb: [255, 255, 255],\r
- hsl: [360, 100, 100],\r
- hsv: [360, 100, 100],\r
- hwb: [360, 100, 100],\r
- cmyk: [100, 100, 100, 100]\r
-};\r
-\r
-Color.prototype.getValues = function (space) {\r
- var values = this.values;\r
- var vals = {};\r
-\r
- for (var i = 0; i < space.length; i++) {\r
- vals[space.charAt(i)] = values[space][i];\r
- }\r
-\r
- if (values.alpha !== 1) {\r
- vals.a = values.alpha;\r
- }\r
-\r
- // {r: 255, g: 255, b: 255, a: 0.4}\r
- return vals;\r
-};\r
-\r
-Color.prototype.setValues = function (space, vals) {\r
- var values = this.values;\r
- var spaces = this.spaces;\r
- var maxes = this.maxes;\r
- var alpha = 1;\r
- var i;\r
-\r
- if (space === 'alpha') {\r
- alpha = vals;\r
- } else if (vals.length) {\r
- // [10, 10, 10]\r
- values[space] = vals.slice(0, space.length);\r
- alpha = vals[space.length];\r
- } else if (vals[space.charAt(0)] !== undefined) {\r
- // {r: 10, g: 10, b: 10}\r
- for (i = 0; i < space.length; i++) {\r
- values[space][i] = vals[space.charAt(i)];\r
- }\r
-\r
- alpha = vals.a;\r
- } else if (vals[spaces[space][0]] !== undefined) {\r
- // {red: 10, green: 10, blue: 10}\r
- var chans = spaces[space];\r
-\r
- for (i = 0; i < space.length; i++) {\r
- values[space][i] = vals[chans[i]];\r
- }\r
-\r
- alpha = vals.alpha;\r
- }\r
-\r
- values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));\r
-\r
- if (space === 'alpha') {\r
- return false;\r
- }\r
-\r
- var capped;\r
-\r
- // cap values of the space prior converting all values\r
- for (i = 0; i < space.length; i++) {\r
- capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));\r
- values[space][i] = Math.round(capped);\r
- }\r
-\r
- // convert to all the other color spaces\r
- for (var sname in spaces) {\r
- if (sname !== space) {\r
- values[sname] = convert[space][sname](values[space]);\r
- }\r
- }\r
-\r
- return true;\r
-};\r
-\r
-Color.prototype.setSpace = function (space, args) {\r
- var vals = args[0];\r
-\r
- if (vals === undefined) {\r
- // color.rgb()\r
- return this.getValues(space);\r
- }\r
-\r
- // color.rgb(10, 10, 10)\r
- if (typeof vals === 'number') {\r
- vals = Array.prototype.slice.call(args);\r
- }\r
-\r
- this.setValues(space, vals);\r
- return this;\r
-};\r
-\r
-Color.prototype.setChannel = function (space, index, val) {\r
- var svalues = this.values[space];\r
- if (val === undefined) {\r
- // color.red()\r
- return svalues[index];\r
- } else if (val === svalues[index]) {\r
- // color.red(color.red())\r
- return this;\r
- }\r
-\r
- // color.red(100)\r
- svalues[index] = val;\r
- this.setValues(space, svalues);\r
-\r
- return this;\r
-};\r
-\r
-if (typeof window !== 'undefined') {\r
- window.Color = Color;\r
-}\r
-\r
-module.exports = Color;\r
-
-},{"2":2,"5":5}],4:[function(require,module,exports){
-/* MIT license */
-
-module.exports = {
- rgb2hsl: rgb2hsl,
- rgb2hsv: rgb2hsv,
- rgb2hwb: rgb2hwb,
- rgb2cmyk: rgb2cmyk,
- rgb2keyword: rgb2keyword,
- rgb2xyz: rgb2xyz,
- rgb2lab: rgb2lab,
- rgb2lch: rgb2lch,
-
- hsl2rgb: hsl2rgb,
- hsl2hsv: hsl2hsv,
- hsl2hwb: hsl2hwb,
- hsl2cmyk: hsl2cmyk,
- hsl2keyword: hsl2keyword,
-
- hsv2rgb: hsv2rgb,
- hsv2hsl: hsv2hsl,
- hsv2hwb: hsv2hwb,
- hsv2cmyk: hsv2cmyk,
- hsv2keyword: hsv2keyword,
-
- hwb2rgb: hwb2rgb,
- hwb2hsl: hwb2hsl,
- hwb2hsv: hwb2hsv,
- hwb2cmyk: hwb2cmyk,
- hwb2keyword: hwb2keyword,
-
- cmyk2rgb: cmyk2rgb,
- cmyk2hsl: cmyk2hsl,
- cmyk2hsv: cmyk2hsv,
- cmyk2hwb: cmyk2hwb,
- cmyk2keyword: cmyk2keyword,
-
- keyword2rgb: keyword2rgb,
- keyword2hsl: keyword2hsl,
- keyword2hsv: keyword2hsv,
- keyword2hwb: keyword2hwb,
- keyword2cmyk: keyword2cmyk,
- keyword2lab: keyword2lab,
- keyword2xyz: keyword2xyz,
-
- xyz2rgb: xyz2rgb,
- xyz2lab: xyz2lab,
- xyz2lch: xyz2lch,
-
- lab2xyz: lab2xyz,
- lab2rgb: lab2rgb,
- lab2lch: lab2lch,
-
- lch2lab: lch2lab,
- lch2xyz: lch2xyz,
- lch2rgb: lch2rgb
-}
-
-
-function rgb2hsl(rgb) {
- var r = rgb[0]/255,
- g = rgb[1]/255,
- b = rgb[2]/255,
- min = Math.min(r, g, b),
- max = Math.max(r, g, b),
- delta = max - min,
- h, s, l;
-
- if (max == min)
- h = 0;
- else if (r == max)
- h = (g - b) / delta;
- else if (g == max)
- h = 2 + (b - r) / delta;
- else if (b == max)
- h = 4 + (r - g)/ delta;
-
- h = Math.min(h * 60, 360);
-
- if (h < 0)
- h += 360;
-
- l = (min + max) / 2;
-
- if (max == min)
- s = 0;
- else if (l <= 0.5)
- s = delta / (max + min);
- else
- s = delta / (2 - max - min);
-
- return [h, s * 100, l * 100];
-}
-
-function rgb2hsv(rgb) {
- var r = rgb[0],
- g = rgb[1],
- b = rgb[2],
- min = Math.min(r, g, b),
- max = Math.max(r, g, b),
- delta = max - min,
- h, s, v;
-
- if (max == 0)
- s = 0;
- else
- s = (delta/max * 1000)/10;
-
- if (max == min)
- h = 0;
- else if (r == max)
- h = (g - b) / delta;
- else if (g == max)
- h = 2 + (b - r) / delta;
- else if (b == max)
- h = 4 + (r - g) / delta;
-
- h = Math.min(h * 60, 360);
-
- if (h < 0)
- h += 360;
-
- v = ((max / 255) * 1000) / 10;
-
- return [h, s, v];
-}
-
-function rgb2hwb(rgb) {
- var r = rgb[0],
- g = rgb[1],
- b = rgb[2],
- h = rgb2hsl(rgb)[0],
- w = 1/255 * Math.min(r, Math.min(g, b)),
- b = 1 - 1/255 * Math.max(r, Math.max(g, b));
-
- return [h, w * 100, b * 100];
-}
-
-function rgb2cmyk(rgb) {
- var r = rgb[0] / 255,
- g = rgb[1] / 255,
- b = rgb[2] / 255,
- c, m, y, k;
-
- k = Math.min(1 - r, 1 - g, 1 - b);
- c = (1 - r - k) / (1 - k) || 0;
- m = (1 - g - k) / (1 - k) || 0;
- y = (1 - b - k) / (1 - k) || 0;
- return [c * 100, m * 100, y * 100, k * 100];
-}
-
-function rgb2keyword(rgb) {
- return reverseKeywords[JSON.stringify(rgb)];
-}
-
-function rgb2xyz(rgb) {
- var r = rgb[0] / 255,
- g = rgb[1] / 255,
- b = rgb[2] / 255;
-
- // assume sRGB
- r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
- g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
- b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
-
- var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
- var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
- var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
-
- return [x * 100, y *100, z * 100];
-}
-
-function rgb2lab(rgb) {
- var xyz = rgb2xyz(rgb),
- x = xyz[0],
- y = xyz[1],
- z = xyz[2],
- l, a, b;
-
- x /= 95.047;
- y /= 100;
- z /= 108.883;
-
- x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
- y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
- z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
-
- l = (116 * y) - 16;
- a = 500 * (x - y);
- b = 200 * (y - z);
-
- return [l, a, b];
-}
-
-function rgb2lch(args) {
- return lab2lch(rgb2lab(args));
-}
-
-function hsl2rgb(hsl) {
- var h = hsl[0] / 360,
- s = hsl[1] / 100,
- l = hsl[2] / 100,
- t1, t2, t3, rgb, val;
-
- if (s == 0) {
- val = l * 255;
- return [val, val, val];
- }
-
- if (l < 0.5)
- t2 = l * (1 + s);
- else
- t2 = l + s - l * s;
- t1 = 2 * l - t2;
-
- rgb = [0, 0, 0];
- for (var i = 0; i < 3; i++) {
- t3 = h + 1 / 3 * - (i - 1);
- t3 < 0 && t3++;
- t3 > 1 && t3--;
-
- if (6 * t3 < 1)
- val = t1 + (t2 - t1) * 6 * t3;
- else if (2 * t3 < 1)
- val = t2;
- else if (3 * t3 < 2)
- val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
- else
- val = t1;
-
- rgb[i] = val * 255;
- }
-
- return rgb;
-}
-
-function hsl2hsv(hsl) {
- var h = hsl[0],
- s = hsl[1] / 100,
- l = hsl[2] / 100,
- sv, v;
-
- if(l === 0) {
- // no need to do calc on black
- // also avoids divide by 0 error
- return [0, 0, 0];
- }
-
- l *= 2;
- s *= (l <= 1) ? l : 2 - l;
- v = (l + s) / 2;
- sv = (2 * s) / (l + s);
- return [h, sv * 100, v * 100];
-}
-
-function hsl2hwb(args) {
- return rgb2hwb(hsl2rgb(args));
-}
-
-function hsl2cmyk(args) {
- return rgb2cmyk(hsl2rgb(args));
-}
-
-function hsl2keyword(args) {
- return rgb2keyword(hsl2rgb(args));
-}
-
-
-function hsv2rgb(hsv) {
- var h = hsv[0] / 60,
- s = hsv[1] / 100,
- v = hsv[2] / 100,
- hi = Math.floor(h) % 6;
-
- var f = h - Math.floor(h),
- p = 255 * v * (1 - s),
- q = 255 * v * (1 - (s * f)),
- t = 255 * v * (1 - (s * (1 - f))),
- v = 255 * v;
-
- switch(hi) {
- case 0:
- return [v, t, p];
- case 1:
- return [q, v, p];
- case 2:
- return [p, v, t];
- case 3:
- return [p, q, v];
- case 4:
- return [t, p, v];
- case 5:
- return [v, p, q];
- }
-}
-
-function hsv2hsl(hsv) {
- var h = hsv[0],
- s = hsv[1] / 100,
- v = hsv[2] / 100,
- sl, l;
-
- l = (2 - s) * v;
- sl = s * v;
- sl /= (l <= 1) ? l : 2 - l;
- sl = sl || 0;
- l /= 2;
- return [h, sl * 100, l * 100];
-}
-
-function hsv2hwb(args) {
- return rgb2hwb(hsv2rgb(args))
-}
-
-function hsv2cmyk(args) {
- return rgb2cmyk(hsv2rgb(args));
-}
-
-function hsv2keyword(args) {
- return rgb2keyword(hsv2rgb(args));
-}
-
-// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
-function hwb2rgb(hwb) {
- var h = hwb[0] / 360,
- wh = hwb[1] / 100,
- bl = hwb[2] / 100,
- ratio = wh + bl,
- i, v, f, n;
-
- // wh + bl cant be > 1
- if (ratio > 1) {
- wh /= ratio;
- bl /= ratio;
- }
-
- i = Math.floor(6 * h);
- v = 1 - bl;
- f = 6 * h - i;
- if ((i & 0x01) != 0) {
- f = 1 - f;
- }
- n = wh + f * (v - wh); // linear interpolation
-
- switch (i) {
- default:
- case 6:
- case 0: r = v; g = n; b = wh; break;
- case 1: r = n; g = v; b = wh; break;
- case 2: r = wh; g = v; b = n; break;
- case 3: r = wh; g = n; b = v; break;
- case 4: r = n; g = wh; b = v; break;
- case 5: r = v; g = wh; b = n; break;
- }
-
- return [r * 255, g * 255, b * 255];
-}
-
-function hwb2hsl(args) {
- return rgb2hsl(hwb2rgb(args));
-}
-
-function hwb2hsv(args) {
- return rgb2hsv(hwb2rgb(args));
-}
-
-function hwb2cmyk(args) {
- return rgb2cmyk(hwb2rgb(args));
-}
-
-function hwb2keyword(args) {
- return rgb2keyword(hwb2rgb(args));
-}
-
-function cmyk2rgb(cmyk) {
- var c = cmyk[0] / 100,
- m = cmyk[1] / 100,
- y = cmyk[2] / 100,
- k = cmyk[3] / 100,
- r, g, b;
-
- r = 1 - Math.min(1, c * (1 - k) + k);
- g = 1 - Math.min(1, m * (1 - k) + k);
- b = 1 - Math.min(1, y * (1 - k) + k);
- return [r * 255, g * 255, b * 255];
-}
-
-function cmyk2hsl(args) {
- return rgb2hsl(cmyk2rgb(args));
-}
-
-function cmyk2hsv(args) {
- return rgb2hsv(cmyk2rgb(args));
-}
-
-function cmyk2hwb(args) {
- return rgb2hwb(cmyk2rgb(args));
-}
-
-function cmyk2keyword(args) {
- return rgb2keyword(cmyk2rgb(args));
-}
-
-
-function xyz2rgb(xyz) {
- var x = xyz[0] / 100,
- y = xyz[1] / 100,
- z = xyz[2] / 100,
- r, g, b;
-
- r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
- g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
- b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
-
- // assume sRGB
- r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
- : r = (r * 12.92);
-
- g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
- : g = (g * 12.92);
-
- b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
- : b = (b * 12.92);
-
- r = Math.min(Math.max(0, r), 1);
- g = Math.min(Math.max(0, g), 1);
- b = Math.min(Math.max(0, b), 1);
-
- return [r * 255, g * 255, b * 255];
-}
-
-function xyz2lab(xyz) {
- var x = xyz[0],
- y = xyz[1],
- z = xyz[2],
- l, a, b;
-
- x /= 95.047;
- y /= 100;
- z /= 108.883;
-
- x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
- y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
- z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
-
- l = (116 * y) - 16;
- a = 500 * (x - y);
- b = 200 * (y - z);
-
- return [l, a, b];
-}
-
-function xyz2lch(args) {
- return lab2lch(xyz2lab(args));
-}
-
-function lab2xyz(lab) {
- var l = lab[0],
- a = lab[1],
- b = lab[2],
- x, y, z, y2;
-
- if (l <= 8) {
- y = (l * 100) / 903.3;
- y2 = (7.787 * (y / 100)) + (16 / 116);
- } else {
- y = 100 * Math.pow((l + 16) / 116, 3);
- y2 = Math.pow(y / 100, 1/3);
- }
-
- x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
-
- z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
-
- return [x, y, z];
-}
-
-function lab2lch(lab) {
- var l = lab[0],
- a = lab[1],
- b = lab[2],
- hr, h, c;
-
- hr = Math.atan2(b, a);
- h = hr * 360 / 2 / Math.PI;
- if (h < 0) {
- h += 360;
- }
- c = Math.sqrt(a * a + b * b);
- return [l, c, h];
-}
-
-function lab2rgb(args) {
- return xyz2rgb(lab2xyz(args));
-}
-
-function lch2lab(lch) {
- var l = lch[0],
- c = lch[1],
- h = lch[2],
- a, b, hr;
-
- hr = h / 360 * 2 * Math.PI;
- a = c * Math.cos(hr);
- b = c * Math.sin(hr);
- return [l, a, b];
-}
-
-function lch2xyz(args) {
- return lab2xyz(lch2lab(args));
-}
-
-function lch2rgb(args) {
- return lab2rgb(lch2lab(args));
-}
-
-function keyword2rgb(keyword) {
- return cssKeywords[keyword];
-}
-
-function keyword2hsl(args) {
- return rgb2hsl(keyword2rgb(args));
-}
-
-function keyword2hsv(args) {
- return rgb2hsv(keyword2rgb(args));
-}
-
-function keyword2hwb(args) {
- return rgb2hwb(keyword2rgb(args));
-}
-
-function keyword2cmyk(args) {
- return rgb2cmyk(keyword2rgb(args));
-}
-
-function keyword2lab(args) {
- return rgb2lab(keyword2rgb(args));
-}
-
-function keyword2xyz(args) {
- return rgb2xyz(keyword2rgb(args));
-}
-
-var cssKeywords = {
- aliceblue: [240,248,255],
- antiquewhite: [250,235,215],
- aqua: [0,255,255],
- aquamarine: [127,255,212],
- azure: [240,255,255],
- beige: [245,245,220],
- bisque: [255,228,196],
- black: [0,0,0],
- blanchedalmond: [255,235,205],
- blue: [0,0,255],
- blueviolet: [138,43,226],
- brown: [165,42,42],
- burlywood: [222,184,135],
- cadetblue: [95,158,160],
- chartreuse: [127,255,0],
- chocolate: [210,105,30],
- coral: [255,127,80],
- cornflowerblue: [100,149,237],
- cornsilk: [255,248,220],
- crimson: [220,20,60],
- cyan: [0,255,255],
- darkblue: [0,0,139],
- darkcyan: [0,139,139],
- darkgoldenrod: [184,134,11],
- darkgray: [169,169,169],
- darkgreen: [0,100,0],
- darkgrey: [169,169,169],
- darkkhaki: [189,183,107],
- darkmagenta: [139,0,139],
- darkolivegreen: [85,107,47],
- darkorange: [255,140,0],
- darkorchid: [153,50,204],
- darkred: [139,0,0],
- darksalmon: [233,150,122],
- darkseagreen: [143,188,143],
- darkslateblue: [72,61,139],
- darkslategray: [47,79,79],
- darkslategrey: [47,79,79],
- darkturquoise: [0,206,209],
- darkviolet: [148,0,211],
- deeppink: [255,20,147],
- deepskyblue: [0,191,255],
- dimgray: [105,105,105],
- dimgrey: [105,105,105],
- dodgerblue: [30,144,255],
- firebrick: [178,34,34],
- floralwhite: [255,250,240],
- forestgreen: [34,139,34],
- fuchsia: [255,0,255],
- gainsboro: [220,220,220],
- ghostwhite: [248,248,255],
- gold: [255,215,0],
- goldenrod: [218,165,32],
- gray: [128,128,128],
- green: [0,128,0],
- greenyellow: [173,255,47],
- grey: [128,128,128],
- honeydew: [240,255,240],
- hotpink: [255,105,180],
- indianred: [205,92,92],
- indigo: [75,0,130],
- ivory: [255,255,240],
- khaki: [240,230,140],
- lavender: [230,230,250],
- lavenderblush: [255,240,245],
- lawngreen: [124,252,0],
- lemonchiffon: [255,250,205],
- lightblue: [173,216,230],
- lightcoral: [240,128,128],
- lightcyan: [224,255,255],
- lightgoldenrodyellow: [250,250,210],
- lightgray: [211,211,211],
- lightgreen: [144,238,144],
- lightgrey: [211,211,211],
- lightpink: [255,182,193],
- lightsalmon: [255,160,122],
- lightseagreen: [32,178,170],
- lightskyblue: [135,206,250],
- lightslategray: [119,136,153],
- lightslategrey: [119,136,153],
- lightsteelblue: [176,196,222],
- lightyellow: [255,255,224],
- lime: [0,255,0],
- limegreen: [50,205,50],
- linen: [250,240,230],
- magenta: [255,0,255],
- maroon: [128,0,0],
- mediumaquamarine: [102,205,170],
- mediumblue: [0,0,205],
- mediumorchid: [186,85,211],
- mediumpurple: [147,112,219],
- mediumseagreen: [60,179,113],
- mediumslateblue: [123,104,238],
- mediumspringgreen: [0,250,154],
- mediumturquoise: [72,209,204],
- mediumvioletred: [199,21,133],
- midnightblue: [25,25,112],
- mintcream: [245,255,250],
- mistyrose: [255,228,225],
- moccasin: [255,228,181],
- navajowhite: [255,222,173],
- navy: [0,0,128],
- oldlace: [253,245,230],
- olive: [128,128,0],
- olivedrab: [107,142,35],
- orange: [255,165,0],
- orangered: [255,69,0],
- orchid: [218,112,214],
- palegoldenrod: [238,232,170],
- palegreen: [152,251,152],
- paleturquoise: [175,238,238],
- palevioletred: [219,112,147],
- papayawhip: [255,239,213],
- peachpuff: [255,218,185],
- peru: [205,133,63],
- pink: [255,192,203],
- plum: [221,160,221],
- powderblue: [176,224,230],
- purple: [128,0,128],
- rebeccapurple: [102, 51, 153],
- red: [255,0,0],
- rosybrown: [188,143,143],
- royalblue: [65,105,225],
- saddlebrown: [139,69,19],
- salmon: [250,128,114],
- sandybrown: [244,164,96],
- seagreen: [46,139,87],
- seashell: [255,245,238],
- sienna: [160,82,45],
- silver: [192,192,192],
- skyblue: [135,206,235],
- slateblue: [106,90,205],
- slategray: [112,128,144],
- slategrey: [112,128,144],
- snow: [255,250,250],
- springgreen: [0,255,127],
- steelblue: [70,130,180],
- tan: [210,180,140],
- teal: [0,128,128],
- thistle: [216,191,216],
- tomato: [255,99,71],
- turquoise: [64,224,208],
- violet: [238,130,238],
- wheat: [245,222,179],
- white: [255,255,255],
- whitesmoke: [245,245,245],
- yellow: [255,255,0],
- yellowgreen: [154,205,50]
-};
-
-var reverseKeywords = {};
-for (var key in cssKeywords) {
- reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
-}
-
-},{}],5:[function(require,module,exports){
-var conversions = require(4);
-
-var convert = function() {
- return new Converter();
-}
-
-for (var func in conversions) {
- // export Raw versions
- convert[func + "Raw"] = (function(func) {
- // accept array or plain args
- return function(arg) {
- if (typeof arg == "number")
- arg = Array.prototype.slice.call(arguments);
- return conversions[func](arg);
- }
- })(func);
-
- var pair = /(\w+)2(\w+)/.exec(func),
- from = pair[1],
- to = pair[2];
-
- // export rgb2hsl and ["rgb"]["hsl"]
- convert[from] = convert[from] || {};
-
- convert[from][to] = convert[func] = (function(func) {
- return function(arg) {
- if (typeof arg == "number")
- arg = Array.prototype.slice.call(arguments);
-
- var val = conversions[func](arg);
- if (typeof val == "string" || val === undefined)
- return val; // keyword
-
- for (var i = 0; i < val.length; i++)
- val[i] = Math.round(val[i]);
- return val;
- }
- })(func);
-}
-
-
-/* Converter does lazy conversion and caching */
-var Converter = function() {
- this.convs = {};
-};
-
-/* Either get the values for a space or
- set the values for a space, depending on args */
-Converter.prototype.routeSpace = function(space, args) {
- var values = args[0];
- if (values === undefined) {
- // color.rgb()
- return this.getValues(space);
- }
- // color.rgb(10, 10, 10)
- if (typeof values == "number") {
- values = Array.prototype.slice.call(args);
- }
-
- return this.setValues(space, values);
-};
-
-/* Set the values for a space, invalidating cache */
-Converter.prototype.setValues = function(space, values) {
- this.space = space;
- this.convs = {};
- this.convs[space] = values;
- return this;
-};
-
-/* Get the values for a space. If there's already
- a conversion for the space, fetch it, otherwise
- compute it */
-Converter.prototype.getValues = function(space) {
- var vals = this.convs[space];
- if (!vals) {
- var fspace = this.space,
- from = this.convs[fspace];
- vals = convert[fspace][space](from);
-
- this.convs[space] = vals;
- }
- return vals;
-};
-
-["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
- Converter.prototype[space] = function(vals) {
- return this.routeSpace(space, arguments);
- }
-});
-
-module.exports = convert;
-},{"4":4}],6:[function(require,module,exports){
-module.exports = {\r
- "aliceblue": [240, 248, 255],\r
- "antiquewhite": [250, 235, 215],\r
- "aqua": [0, 255, 255],\r
- "aquamarine": [127, 255, 212],\r
- "azure": [240, 255, 255],\r
- "beige": [245, 245, 220],\r
- "bisque": [255, 228, 196],\r
- "black": [0, 0, 0],\r
- "blanchedalmond": [255, 235, 205],\r
- "blue": [0, 0, 255],\r
- "blueviolet": [138, 43, 226],\r
- "brown": [165, 42, 42],\r
- "burlywood": [222, 184, 135],\r
- "cadetblue": [95, 158, 160],\r
- "chartreuse": [127, 255, 0],\r
- "chocolate": [210, 105, 30],\r
- "coral": [255, 127, 80],\r
- "cornflowerblue": [100, 149, 237],\r
- "cornsilk": [255, 248, 220],\r
- "crimson": [220, 20, 60],\r
- "cyan": [0, 255, 255],\r
- "darkblue": [0, 0, 139],\r
- "darkcyan": [0, 139, 139],\r
- "darkgoldenrod": [184, 134, 11],\r
- "darkgray": [169, 169, 169],\r
- "darkgreen": [0, 100, 0],\r
- "darkgrey": [169, 169, 169],\r
- "darkkhaki": [189, 183, 107],\r
- "darkmagenta": [139, 0, 139],\r
- "darkolivegreen": [85, 107, 47],\r
- "darkorange": [255, 140, 0],\r
- "darkorchid": [153, 50, 204],\r
- "darkred": [139, 0, 0],\r
- "darksalmon": [233, 150, 122],\r
- "darkseagreen": [143, 188, 143],\r
- "darkslateblue": [72, 61, 139],\r
- "darkslategray": [47, 79, 79],\r
- "darkslategrey": [47, 79, 79],\r
- "darkturquoise": [0, 206, 209],\r
- "darkviolet": [148, 0, 211],\r
- "deeppink": [255, 20, 147],\r
- "deepskyblue": [0, 191, 255],\r
- "dimgray": [105, 105, 105],\r
- "dimgrey": [105, 105, 105],\r
- "dodgerblue": [30, 144, 255],\r
- "firebrick": [178, 34, 34],\r
- "floralwhite": [255, 250, 240],\r
- "forestgreen": [34, 139, 34],\r
- "fuchsia": [255, 0, 255],\r
- "gainsboro": [220, 220, 220],\r
- "ghostwhite": [248, 248, 255],\r
- "gold": [255, 215, 0],\r
- "goldenrod": [218, 165, 32],\r
- "gray": [128, 128, 128],\r
- "green": [0, 128, 0],\r
- "greenyellow": [173, 255, 47],\r
- "grey": [128, 128, 128],\r
- "honeydew": [240, 255, 240],\r
- "hotpink": [255, 105, 180],\r
- "indianred": [205, 92, 92],\r
- "indigo": [75, 0, 130],\r
- "ivory": [255, 255, 240],\r
- "khaki": [240, 230, 140],\r
- "lavender": [230, 230, 250],\r
- "lavenderblush": [255, 240, 245],\r
- "lawngreen": [124, 252, 0],\r
- "lemonchiffon": [255, 250, 205],\r
- "lightblue": [173, 216, 230],\r
- "lightcoral": [240, 128, 128],\r
- "lightcyan": [224, 255, 255],\r
- "lightgoldenrodyellow": [250, 250, 210],\r
- "lightgray": [211, 211, 211],\r
- "lightgreen": [144, 238, 144],\r
- "lightgrey": [211, 211, 211],\r
- "lightpink": [255, 182, 193],\r
- "lightsalmon": [255, 160, 122],\r
- "lightseagreen": [32, 178, 170],\r
- "lightskyblue": [135, 206, 250],\r
- "lightslategray": [119, 136, 153],\r
- "lightslategrey": [119, 136, 153],\r
- "lightsteelblue": [176, 196, 222],\r
- "lightyellow": [255, 255, 224],\r
- "lime": [0, 255, 0],\r
- "limegreen": [50, 205, 50],\r
- "linen": [250, 240, 230],\r
- "magenta": [255, 0, 255],\r
- "maroon": [128, 0, 0],\r
- "mediumaquamarine": [102, 205, 170],\r
- "mediumblue": [0, 0, 205],\r
- "mediumorchid": [186, 85, 211],\r
- "mediumpurple": [147, 112, 219],\r
- "mediumseagreen": [60, 179, 113],\r
- "mediumslateblue": [123, 104, 238],\r
- "mediumspringgreen": [0, 250, 154],\r
- "mediumturquoise": [72, 209, 204],\r
- "mediumvioletred": [199, 21, 133],\r
- "midnightblue": [25, 25, 112],\r
- "mintcream": [245, 255, 250],\r
- "mistyrose": [255, 228, 225],\r
- "moccasin": [255, 228, 181],\r
- "navajowhite": [255, 222, 173],\r
- "navy": [0, 0, 128],\r
- "oldlace": [253, 245, 230],\r
- "olive": [128, 128, 0],\r
- "olivedrab": [107, 142, 35],\r
- "orange": [255, 165, 0],\r
- "orangered": [255, 69, 0],\r
- "orchid": [218, 112, 214],\r
- "palegoldenrod": [238, 232, 170],\r
- "palegreen": [152, 251, 152],\r
- "paleturquoise": [175, 238, 238],\r
- "palevioletred": [219, 112, 147],\r
- "papayawhip": [255, 239, 213],\r
- "peachpuff": [255, 218, 185],\r
- "peru": [205, 133, 63],\r
- "pink": [255, 192, 203],\r
- "plum": [221, 160, 221],\r
- "powderblue": [176, 224, 230],\r
- "purple": [128, 0, 128],\r
- "rebeccapurple": [102, 51, 153],\r
- "red": [255, 0, 0],\r
- "rosybrown": [188, 143, 143],\r
- "royalblue": [65, 105, 225],\r
- "saddlebrown": [139, 69, 19],\r
- "salmon": [250, 128, 114],\r
- "sandybrown": [244, 164, 96],\r
- "seagreen": [46, 139, 87],\r
- "seashell": [255, 245, 238],\r
- "sienna": [160, 82, 45],\r
- "silver": [192, 192, 192],\r
- "skyblue": [135, 206, 235],\r
- "slateblue": [106, 90, 205],\r
- "slategray": [112, 128, 144],\r
- "slategrey": [112, 128, 144],\r
- "snow": [255, 250, 250],\r
- "springgreen": [0, 255, 127],\r
- "steelblue": [70, 130, 180],\r
- "tan": [210, 180, 140],\r
- "teal": [0, 128, 128],\r
- "thistle": [216, 191, 216],\r
- "tomato": [255, 99, 71],\r
- "turquoise": [64, 224, 208],\r
- "violet": [238, 130, 238],\r
- "wheat": [245, 222, 179],\r
- "white": [255, 255, 255],\r
- "whitesmoke": [245, 245, 245],\r
- "yellow": [255, 255, 0],\r
- "yellowgreen": [154, 205, 50]\r
-};
-},{}],7:[function(require,module,exports){
-/**\r
- * @namespace Chart\r
- */\r
-var Chart = require(26)();\r
-\r
-require(25)(Chart);\r
-require(24)(Chart);\r
-require(21)(Chart);\r
-require(22)(Chart);\r
-require(23)(Chart);\r
-require(27)(Chart);\r
-require(31)(Chart);\r
-require(29)(Chart);\r
-require(30)(Chart);\r
-require(32)(Chart);\r
-require(28)(Chart);\r
-require(33)(Chart);\r
-\r
-require(34)(Chart);\r
-require(35)(Chart);\r
-require(36)(Chart);\r
-require(37)(Chart);\r
-\r
-require(40)(Chart);\r
-require(38)(Chart);\r
-require(39)(Chart);\r
-require(41)(Chart);\r
-require(42)(Chart);\r
-require(43)(Chart);\r
-\r
-// Controllers must be loaded after elements\r
-// See Chart.core.datasetController.dataElementType\r
-require(15)(Chart);\r
-require(16)(Chart);\r
-require(17)(Chart);\r
-require(18)(Chart);\r
-require(19)(Chart);\r
-require(20)(Chart);\r
-\r
-require(8)(Chart);\r
-require(9)(Chart);\r
-require(10)(Chart);\r
-require(11)(Chart);\r
-require(12)(Chart);\r
-require(13)(Chart);\r
-require(14)(Chart);\r
-\r
-window.Chart = module.exports = Chart;\r
-
-},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"8":8,"9":9}],8:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Bar = function(context, config) {\r
- config.type = 'bar';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],9:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Bubble = function(context, config) {\r
- config.type = 'bubble';\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],10:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Doughnut = function(context, config) {\r
- config.type = 'doughnut';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],11:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.Line = function(context, config) {\r
- config.type = 'line';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],12:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- Chart.PolarArea = function(context, config) {\r
- config.type = 'polarArea';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],13:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
- \r
- Chart.Radar = function(context, config) {\r
- config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options);\r
- config.type = 'radar';\r
-\r
- return new Chart(context, config);\r
- };\r
-\r
-};\r
-
-},{}],14:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var defaultConfig = {\r
- hover: {\r
- mode: 'single'\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "linear", // scatter should not use a category axis\r
- position: "bottom",\r
- id: "x-axis-1" // need an ID so datasets can reference the scale\r
- }],\r
- yAxes: [{\r
- type: "linear",\r
- position: "left",\r
- id: "y-axis-1"\r
- }]\r
- },\r
-\r
- tooltips: {\r
- callbacks: {\r
- title: function(tooltipItems, data) {\r
- // Title doesn't make sense for scatter since we format the data as a point\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';\r
- }\r
- }\r
- }\r
- };\r
-\r
- // Register the default config for this type\r
- Chart.defaults.scatter = defaultConfig;\r
-\r
- // Scatter charts use line controllers\r
- Chart.controllers.scatter = Chart.controllers.line;\r
-\r
- Chart.Scatter = function(context, config) {\r
- config.type = 'scatter';\r
- return new Chart(context, config);\r
- };\r
-\r
-};
-},{}],15:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.bar = {\r
- hover: {\r
- mode: "label"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "category",\r
-\r
- // Specific to Bar Controller\r
- categoryPercentage: 0.8,\r
- barPercentage: 0.9,\r
-\r
- // grid line settings\r
- gridLines: {\r
- offsetGridLines: true\r
- }\r
- }],\r
- yAxes: [{\r
- type: "linear"\r
- }]\r
- }\r
- };\r
-\r
- Chart.controllers.bar = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Rectangle,\r
-\r
- initialize: function(chart, datasetIndex) {\r
- Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);\r
-\r
- // Use this to indicate that this is a bar dataset.\r
- this.getMeta().bar = true;\r
- },\r
-\r
- // Get the number of datasets that display bars. We use this to correctly calculate the bar width\r
- getBarCount: function getBarCount() {\r
- var me = this;\r
- var barCount = 0;\r
- helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {\r
- var meta = me.chart.getDatasetMeta(datasetIndex);\r
- if (meta.bar && me.chart.isDatasetVisible(datasetIndex)) {\r
- ++barCount;\r
- }\r
- }, me);\r
- return barCount;\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- helpers.each(me.getMeta().data, function(rectangle, index) {\r
- me.updateElement(rectangle, index, reset);\r
- }, me);\r
- },\r
-\r
- updateElement: function updateElement(rectangle, index, reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var scaleBase = yScale.getBasePixel();\r
- var rectangleElementOptions = me.chart.options.elements.rectangle;\r
- var custom = rectangle.custom || {};\r
- var dataset = me.getDataset();\r
-\r
- helpers.extend(rectangle, {\r
- // Utility\r
- _xScale: xScale,\r
- _yScale: yScale,\r
- _datasetIndex: me.index,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: me.calculateBarX(index, me.index),\r
- y: reset ? scaleBase : me.calculateBarY(index, me.index),\r
-\r
- // Tooltip\r
- label: me.chart.data.labels[index],\r
- datasetLabel: dataset.label,\r
-\r
- // Appearance\r
- base: reset ? scaleBase : me.calculateBarBase(me.index, index),\r
- width: me.calculateBarWidth(index),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),\r
- borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,\r
- borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)\r
- }\r
- });\r
- rectangle.pivot();\r
- },\r
-\r
- calculateBarBase: function(datasetIndex, index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var base = 0;\r
-\r
- if (yScale.options.stacked) {\r
- var chart = me.chart;\r
- var datasets = chart.data.datasets;\r
- var value = datasets[datasetIndex].data[index];\r
-\r
- if (value < 0) {\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var negDS = datasets[i];\r
- var negDSMeta = chart.getDatasetMeta(i);\r
- if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\r
- base += negDS.data[index] < 0 ? negDS.data[index] : 0;\r
- }\r
- }\r
- } else {\r
- for (var j = 0; j < datasetIndex; j++) {\r
- var posDS = datasets[j];\r
- var posDSMeta = chart.getDatasetMeta(j);\r
- if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(j)) {\r
- base += posDS.data[index] > 0 ? posDS.data[index] : 0;\r
- }\r
- }\r
- }\r
-\r
- return yScale.getPixelForValue(base);\r
- }\r
-\r
- return yScale.getBasePixel();\r
- },\r
-\r
- getRuler: function(index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var datasetCount = me.getBarCount();\r
-\r
- var tickWidth;\r
-\r
- if (xScale.options.type === 'category') {\r
- tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index);\r
- } else {\r
- // Average width\r
- tickWidth = xScale.width / xScale.ticks.length;\r
- }\r
- var categoryWidth = tickWidth * xScale.options.categoryPercentage;\r
- var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;\r
- var fullBarWidth = categoryWidth / datasetCount;\r
-\r
- if (xScale.ticks.length !== me.chart.data.labels.length) {\r
- var perc = xScale.ticks.length / me.chart.data.labels.length;\r
- fullBarWidth = fullBarWidth * perc;\r
- }\r
-\r
- var barWidth = fullBarWidth * xScale.options.barPercentage;\r
- var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);\r
-\r
- return {\r
- datasetCount: datasetCount,\r
- tickWidth: tickWidth,\r
- categoryWidth: categoryWidth,\r
- categorySpacing: categorySpacing,\r
- fullBarWidth: fullBarWidth,\r
- barWidth: barWidth,\r
- barSpacing: barSpacing\r
- };\r
- },\r
-\r
- calculateBarWidth: function(index) {\r
- var xScale = this.getScaleForId(this.getMeta().xAxisID);\r
- var ruler = this.getRuler(index);\r
- return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;\r
- },\r
-\r
- // Get bar index from the given dataset index accounting for the fact that not all bars are visible\r
- getBarIndex: function(datasetIndex) {\r
- var barIndex = 0;\r
- var meta, j;\r
-\r
- for (j = 0; j < datasetIndex; ++j) {\r
- meta = this.chart.getDatasetMeta(j);\r
- if (meta.bar && this.chart.isDatasetVisible(j)) {\r
- ++barIndex;\r
- }\r
- }\r
-\r
- return barIndex;\r
- },\r
-\r
- calculateBarX: function(index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var barIndex = me.getBarIndex(datasetIndex);\r
-\r
- var ruler = me.getRuler(index);\r
- var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);\r
- leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0;\r
-\r
- if (xScale.options.stacked) {\r
- return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;\r
- }\r
-\r
- return leftTick +\r
- (ruler.barWidth / 2) +\r
- ruler.categorySpacing +\r
- (ruler.barWidth * barIndex) +\r
- (ruler.barSpacing / 2) +\r
- (ruler.barSpacing * barIndex);\r
- },\r
-\r
- calculateBarY: function(index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var value = me.getDataset().data[index];\r
-\r
- if (yScale.options.stacked) {\r
-\r
- var sumPos = 0,\r
- sumNeg = 0;\r
-\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var ds = me.chart.data.datasets[i];\r
- var dsMeta = me.chart.getDatasetMeta(i);\r
- if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) {\r
- if (ds.data[index] < 0) {\r
- sumNeg += ds.data[index] || 0;\r
- } else {\r
- sumPos += ds.data[index] || 0;\r
- }\r
- }\r
- }\r
-\r
- if (value < 0) {\r
- return yScale.getPixelForValue(sumNeg + value);\r
- } else {\r
- return yScale.getPixelForValue(sumPos + value);\r
- }\r
- }\r
-\r
- return yScale.getPixelForValue(value);\r
- },\r
-\r
- draw: function(ease) {\r
- var me = this;\r
- var easingDecimal = ease || 1;\r
- helpers.each(me.getMeta().data, function(rectangle, index) {\r
- var d = me.getDataset().data[index];\r
- if (d !== null && d !== undefined && !isNaN(d)) {\r
- rectangle.transition(easingDecimal).draw();\r
- }\r
- }, me);\r
- },\r
-\r
- setHoverStyle: function(rectangle) {\r
- var dataset = this.chart.data.datasets[rectangle._datasetIndex];\r
- var index = rectangle._index;\r
-\r
- var custom = rectangle.custom || {};\r
- var model = rectangle._model;\r
- model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\r
- },\r
-\r
- removeHoverStyle: function(rectangle) {\r
- var dataset = this.chart.data.datasets[rectangle._datasetIndex];\r
- var index = rectangle._index;\r
- var custom = rectangle.custom || {};\r
- var model = rectangle._model;\r
- var rectangleElementOptions = this.chart.options.elements.rectangle;\r
-\r
- model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);\r
- model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);\r
- model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);\r
- }\r
-\r
- });\r
-\r
-\r
- // including horizontalBar in the bar file, instead of a file of its own\r
- // it extends bar (like pie extends doughnut)\r
- Chart.defaults.horizontalBar = {\r
- hover: {\r
- mode: "label"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "linear",\r
- position: "bottom"\r
- }],\r
- yAxes: [{\r
- position: "left",\r
- type: "category",\r
-\r
- // Specific to Horizontal Bar Controller\r
- categoryPercentage: 0.8,\r
- barPercentage: 0.9,\r
-\r
- // grid line settings\r
- gridLines: {\r
- offsetGridLines: true\r
- }\r
- }]\r
- },\r
- elements: {\r
- rectangle: {\r
- borderSkipped: 'left'\r
- }\r
- },\r
- tooltips: {\r
- callbacks: {\r
- title: function(tooltipItems, data) {\r
- // Pick first xLabel for now\r
- var title = '';\r
-\r
- if (tooltipItems.length > 0) {\r
- if (tooltipItems[0].yLabel) {\r
- title = tooltipItems[0].yLabel;\r
- } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {\r
- title = data.labels[tooltipItems[0].index];\r
- }\r
- }\r
-\r
- return title;\r
- },\r
- label: function(tooltipItem, data) {\r
- var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
- return datasetLabel + ': ' + tooltipItem.xLabel;\r
- }\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.horizontalBar = Chart.controllers.bar.extend({\r
- updateElement: function updateElement(rectangle, index, reset, numBars) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var scaleBase = xScale.getBasePixel();\r
- var custom = rectangle.custom || {};\r
- var dataset = me.getDataset();\r
- var rectangleElementOptions = me.chart.options.elements.rectangle;\r
-\r
- helpers.extend(rectangle, {\r
- // Utility\r
- _xScale: xScale,\r
- _yScale: yScale,\r
- _datasetIndex: me.index,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: reset ? scaleBase : me.calculateBarX(index, me.index),\r
- y: me.calculateBarY(index, me.index),\r
-\r
- // Tooltip\r
- label: me.chart.data.labels[index],\r
- datasetLabel: dataset.label,\r
-\r
- // Appearance\r
- base: reset ? scaleBase : me.calculateBarBase(me.index, index),\r
- height: me.calculateBarHeight(index),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),\r
- borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,\r
- borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)\r
- },\r
-\r
- draw: function () {\r
- var ctx = this._chart.ctx;\r
- var vm = this._view;\r
-\r
- var halfHeight = vm.height / 2,\r
- topY = vm.y - halfHeight,\r
- bottomY = vm.y + halfHeight,\r
- right = vm.base - (vm.base - vm.x),\r
- halfStroke = vm.borderWidth / 2;\r
-\r
- // Canvas doesn't allow us to stroke inside the width so we can\r
- // adjust the sizes to fit if we're setting a stroke on the line\r
- if (vm.borderWidth) {\r
- topY += halfStroke;\r
- bottomY -= halfStroke;\r
- right += halfStroke;\r
- }\r
-\r
- ctx.beginPath();\r
-\r
- ctx.fillStyle = vm.backgroundColor;\r
- ctx.strokeStyle = vm.borderColor;\r
- ctx.lineWidth = vm.borderWidth;\r
-\r
- // Corner points, from bottom-left to bottom-right clockwise\r
- // | 1 2 |\r
- // | 0 3 |\r
- var corners = [\r
- [vm.base, bottomY],\r
- [vm.base, topY],\r
- [right, topY],\r
- [right, bottomY]\r
- ];\r
-\r
- // Find first (starting) corner with fallback to 'bottom'\r
- var borders = ['bottom', 'left', 'top', 'right'];\r
- var startCorner = borders.indexOf(vm.borderSkipped, 0);\r
- if (startCorner === -1)\r
- startCorner = 0;\r
-\r
- function cornerAt(index) {\r
- return corners[(startCorner + index) % 4];\r
- }\r
-\r
- // Draw rectangle from 'startCorner'\r
- ctx.moveTo.apply(ctx, cornerAt(0));\r
- for (var i = 1; i < 4; i++)\r
- ctx.lineTo.apply(ctx, cornerAt(i));\r
-\r
- ctx.fill();\r
- if (vm.borderWidth) {\r
- ctx.stroke();\r
- }\r
- },\r
-\r
- inRange: function (mouseX, mouseY) {\r
- var vm = this._view;\r
- var inRange = false;\r
-\r
- if (vm) {\r
- if (vm.x < vm.base) {\r
- inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base);\r
- } else {\r
- inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x);\r
- }\r
- }\r
-\r
- return inRange;\r
- }\r
- });\r
-\r
- rectangle.pivot();\r
- },\r
-\r
- calculateBarBase: function (datasetIndex, index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var base = 0;\r
-\r
- if (xScale.options.stacked) {\r
-\r
- var value = me.chart.data.datasets[datasetIndex].data[index];\r
-\r
- if (value < 0) {\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var negDS = me.chart.data.datasets[i];\r
- var negDSMeta = me.chart.getDatasetMeta(i);\r
- if (negDSMeta.bar && negDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {\r
- base += negDS.data[index] < 0 ? negDS.data[index] : 0;\r
- }\r
- }\r
- } else {\r
- for (var j = 0; j < datasetIndex; j++) {\r
- var posDS = me.chart.data.datasets[j];\r
- var posDSMeta = me.chart.getDatasetMeta(j);\r
- if (posDSMeta.bar && posDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(j)) {\r
- base += posDS.data[index] > 0 ? posDS.data[index] : 0;\r
- }\r
- }\r
- }\r
-\r
- return xScale.getPixelForValue(base);\r
- }\r
-\r
- return xScale.getBasePixel();\r
- },\r
-\r
- getRuler: function (index) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var datasetCount = me.getBarCount();\r
-\r
- var tickHeight;\r
- if (yScale.options.type === 'category') {\r
- tickHeight = yScale.getPixelForTick(index + 1) - yScale.getPixelForTick(index);\r
- } else {\r
- // Average width\r
- tickHeight = yScale.width / yScale.ticks.length;\r
- }\r
- var categoryHeight = tickHeight * yScale.options.categoryPercentage;\r
- var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2;\r
- var fullBarHeight = categoryHeight / datasetCount;\r
-\r
- if (yScale.ticks.length !== me.chart.data.labels.length) {\r
- var perc = yScale.ticks.length / me.chart.data.labels.length;\r
- fullBarHeight = fullBarHeight * perc;\r
- }\r
-\r
- var barHeight = fullBarHeight * yScale.options.barPercentage;\r
- var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage);\r
-\r
- return {\r
- datasetCount: datasetCount,\r
- tickHeight: tickHeight,\r
- categoryHeight: categoryHeight,\r
- categorySpacing: categorySpacing,\r
- fullBarHeight: fullBarHeight,\r
- barHeight: barHeight,\r
- barSpacing: barSpacing,\r
- };\r
- },\r
-\r
- calculateBarHeight: function (index) {\r
- var me = this;\r
- var yScale = me.getScaleForId(me.getMeta().yAxisID);\r
- var ruler = me.getRuler(index);\r
- return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;\r
- },\r
-\r
- calculateBarX: function (index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var value = me.getDataset().data[index];\r
-\r
- if (xScale.options.stacked) {\r
-\r
- var sumPos = 0,\r
- sumNeg = 0;\r
-\r
- for (var i = 0; i < datasetIndex; i++) {\r
- var ds = me.chart.data.datasets[i];\r
- var dsMeta = me.chart.getDatasetMeta(i);\r
- if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {\r
- if (ds.data[index] < 0) {\r
- sumNeg += ds.data[index] || 0;\r
- } else {\r
- sumPos += ds.data[index] || 0;\r
- }\r
- }\r
- }\r
-\r
- if (value < 0) {\r
- return xScale.getPixelForValue(sumNeg + value);\r
- } else {\r
- return xScale.getPixelForValue(sumPos + value);\r
- }\r
- }\r
-\r
- return xScale.getPixelForValue(value);\r
- },\r
-\r
- calculateBarY: function (index, datasetIndex) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var barIndex = me.getBarIndex(datasetIndex);\r
-\r
- var ruler = me.getRuler(index);\r
- var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);\r
- topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;\r
-\r
- if (yScale.options.stacked) {\r
- return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;\r
- }\r
-\r
- return topTick +\r
- (ruler.barHeight / 2) +\r
- ruler.categorySpacing +\r
- (ruler.barHeight * barIndex) +\r
- (ruler.barSpacing / 2) +\r
- (ruler.barSpacing * barIndex);\r
- }\r
- });\r
-};\r
-
-},{}],16:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.bubble = {\r
- hover: {\r
- mode: "single"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "linear", // bubble should probably use a linear scale by default\r
- position: "bottom",\r
- id: "x-axis-0" // need an ID so datasets can reference the scale\r
- }],\r
- yAxes: [{\r
- type: "linear",\r
- position: "left",\r
- id: "y-axis-0"\r
- }]\r
- },\r
-\r
- tooltips: {\r
- callbacks: {\r
- title: function(tooltipItems, data) {\r
- // Title doesn't make sense for scatter since we format the data as a point\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
- var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\r
- return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')';\r
- }\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.bubble = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Point,\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var points = meta.data;\r
-\r
- // Update Points\r
- helpers.each(points, function(point, index) {\r
- me.updateElement(point, index, reset);\r
- });\r
- },\r
-\r
- updateElement: function(point, index, reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
-\r
- var custom = point.custom || {};\r
- var dataset = me.getDataset();\r
- var data = dataset.data[index];\r
- var pointElementOptions = me.chart.options.elements.point;\r
- var dsIndex = me.index;\r
-\r
- helpers.extend(point, {\r
- // Utility\r
- _xScale: xScale,\r
- _yScale: yScale,\r
- _datasetIndex: dsIndex,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(data, index, dsIndex, me.chart.isCombo),\r
- y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),\r
- // Appearance\r
- radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),\r
-\r
- // Tooltip\r
- hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\r
- }\r
- });\r
-\r
- // Trick to reset the styles of the point\r
- Chart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);\r
-\r
- var model = point._model;\r
- model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));\r
-\r
- point.pivot();\r
- },\r
-\r
- getRadius: function(value) {\r
- return value.r || this.chart.options.elements.point.radius;\r
- },\r
-\r
- setHoverStyle: function(point) {\r
- var me = this;\r
- Chart.DatasetController.prototype.setHoverStyle.call(me, point);\r
-\r
- // Radius\r
- var dataset = me.chart.data.datasets[point._datasetIndex];\r
- var index = point._index;\r
- var custom = point.custom || {};\r
- var model = point._model;\r
- model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);\r
- },\r
-\r
- removeHoverStyle: function(point) {\r
- var me = this;\r
- Chart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);\r
-\r
- var dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];\r
- var custom = point.custom || {};\r
- var model = point._model;\r
-\r
- model.radius = custom.radius ? custom.radius : me.getRadius(dataVal);\r
- }\r
- });\r
-};\r
-
-},{}],17:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- defaults = Chart.defaults;\r
-\r
- defaults.doughnut = {\r
- animation: {\r
- //Boolean - Whether we animate the rotation of the Doughnut\r
- animateRotate: true,\r
- //Boolean - Whether we animate scaling the Doughnut from the centre\r
- animateScale: false\r
- },\r
- aspectRatio: 1,\r
- hover: {\r
- mode: 'single'\r
- },\r
- legendCallback: function(chart) {\r
- var text = [];\r
- text.push('<ul class="' + chart.id + '-legend">');\r
-\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var labels = data.labels;\r
-\r
- if (datasets.length) {\r
- for (var i = 0; i < datasets[0].data.length; ++i) {\r
- text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');\r
- if (labels[i]) {\r
- text.push(labels[i]);\r
- }\r
- text.push('</li>');\r
- }\r
- }\r
-\r
- text.push('</ul>');\r
- return text.join("");\r
- },\r
- legend: {\r
- labels: {\r
- generateLabels: function(chart) {\r
- var data = chart.data;\r
- if (data.labels.length && data.datasets.length) {\r
- return data.labels.map(function(label, i) {\r
- var meta = chart.getDatasetMeta(0);\r
- var ds = data.datasets[0];\r
- var arc = meta.data[i];\r
- var custom = arc.custom || {};\r
- var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
- var arcOpts = chart.options.elements.arc;\r
- var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\r
- var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\r
- var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\r
-\r
- return {\r
- text: label,\r
- fillStyle: fill,\r
- strokeStyle: stroke,\r
- lineWidth: bw,\r
- hidden: isNaN(ds.data[i]) || meta.data[i].hidden,\r
-\r
- // Extra data used for toggling the correct item\r
- index: i\r
- };\r
- });\r
- } else {\r
- return [];\r
- }\r
- }\r
- },\r
-\r
- onClick: function(e, legendItem) {\r
- var index = legendItem.index;\r
- var chart = this.chart;\r
- var i, ilen, meta;\r
-\r
- for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r
- meta = chart.getDatasetMeta(i);\r
- meta.data[index].hidden = !meta.data[index].hidden;\r
- }\r
-\r
- chart.update();\r
- }\r
- },\r
-\r
- //The percentage of the chart that we cut out of the middle.\r
- cutoutPercentage: 50,\r
-\r
- //The rotation of the chart, where the first data arc begins.\r
- rotation: Math.PI * -0.5,\r
-\r
- //The total circumference of the chart.\r
- circumference: Math.PI * 2.0,\r
-\r
- // Need to override these to give a nice default\r
- tooltips: {\r
- callbacks: {\r
- title: function() {\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\r
- }\r
- }\r
- }\r
- };\r
-\r
- defaults.pie = helpers.clone(defaults.doughnut);\r
- helpers.extend(defaults.pie, {\r
- cutoutPercentage: 0\r
- });\r
-\r
-\r
- Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Arc,\r
-\r
- linkScales: helpers.noop,\r
-\r
- // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\r
- getRingIndex: function getRingIndex(datasetIndex) {\r
- var ringIndex = 0;\r
-\r
- for (var j = 0; j < datasetIndex; ++j) {\r
- if (this.chart.isDatasetVisible(j)) {\r
- ++ringIndex;\r
- }\r
- }\r
-\r
- return ringIndex;\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var chart = me.chart,\r
- chartArea = chart.chartArea,\r
- opts = chart.options,\r
- arcOpts = opts.elements.arc,\r
- availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,\r
- availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,\r
- minSize = Math.min(availableWidth, availableHeight),\r
- offset = {\r
- x: 0,\r
- y: 0\r
- },\r
- meta = me.getMeta(),\r
- cutoutPercentage = opts.cutoutPercentage,\r
- circumference = opts.circumference;\r
-\r
- // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc\r
- if (circumference < Math.PI * 2.0) {\r
- var startAngle = opts.rotation % (Math.PI * 2.0);\r
- startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);\r
- var endAngle = startAngle + circumference;\r
- var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};\r
- var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};\r
- var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);\r
- var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);\r
- var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);\r
- var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);\r
- var cutout = cutoutPercentage / 100.0;\r
- var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};\r
- var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};\r
- var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};\r
- minSize = Math.min(availableWidth / size.width, availableHeight / size.height);\r
- offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};\r
- }\r
-\r
- chart.outerRadius = Math.max(minSize / 2, 0);\r
- chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 1, 0);\r
- chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\r
- chart.offsetX = offset.x * chart.outerRadius;\r
- chart.offsetY = offset.y * chart.outerRadius;\r
-\r
- meta.total = me.calculateTotal();\r
-\r
- me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));\r
- me.innerRadius = me.outerRadius - chart.radiusLength;\r
-\r
- helpers.each(meta.data, function(arc, index) {\r
- me.updateElement(arc, index, reset);\r
- });\r
- },\r
-\r
- updateElement: function(arc, index, reset) {\r
- var me = this;\r
- var chart = me.chart,\r
- chartArea = chart.chartArea,\r
- opts = chart.options,\r
- animationOpts = opts.animation,\r
- arcOpts = opts.elements.arc,\r
- centerX = (chartArea.left + chartArea.right) / 2,\r
- centerY = (chartArea.top + chartArea.bottom) / 2,\r
- startAngle = opts.rotation, // non reset case handled later\r
- endAngle = opts.rotation, // non reset case handled later\r
- dataset = me.getDataset(),\r
- circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),\r
- innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,\r
- outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,\r
- custom = arc.custom || {},\r
- valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
-\r
- helpers.extend(arc, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- _index: index,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: centerX + chart.offsetX,\r
- y: centerY + chart.offsetY,\r
- startAngle: startAngle,\r
- endAngle: endAngle,\r
- circumference: circumference,\r
- outerRadius: outerRadius,\r
- innerRadius: innerRadius,\r
- label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\r
- }\r
- });\r
-\r
- var model = arc._model;\r
- // Resets the visual styles\r
- this.removeHoverStyle(arc);\r
-\r
- // Set correct angles if not resetting\r
- if (!reset || !animationOpts.animateRotate) {\r
- if (index === 0) {\r
- model.startAngle = opts.rotation;\r
- } else {\r
- model.startAngle = me.getMeta().data[index - 1]._model.endAngle;\r
- }\r
-\r
- model.endAngle = model.startAngle + model.circumference;\r
- }\r
-\r
- arc.pivot();\r
- },\r
-\r
- removeHoverStyle: function(arc) {\r
- Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\r
- },\r
-\r
- calculateTotal: function() {\r
- var dataset = this.getDataset();\r
- var meta = this.getMeta();\r
- var total = 0;\r
- var value;\r
-\r
- helpers.each(meta.data, function(element, index) {\r
- value = dataset.data[index];\r
- if (!isNaN(value) && !element.hidden) {\r
- total += Math.abs(value);\r
- }\r
- });\r
-\r
- return total;\r
- },\r
-\r
- calculateCircumference: function(value) {\r
- var total = this.getMeta().total;\r
- if (total > 0 && !isNaN(value)) {\r
- return (Math.PI * 2.0) * (value / total);\r
- } else {\r
- return 0;\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],18:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.line = {\r
- showLines: true,\r
-\r
- hover: {\r
- mode: "label"\r
- },\r
-\r
- scales: {\r
- xAxes: [{\r
- type: "category",\r
- id: 'x-axis-0'\r
- }],\r
- yAxes: [{\r
- type: "linear",\r
- id: 'y-axis-0'\r
- }]\r
- }\r
- };\r
-\r
- function lineEnabled(dataset, options) {\r
- return helpers.getValueOrDefault(dataset.showLine, options.showLines);\r
- }\r
-\r
- Chart.controllers.line = Chart.DatasetController.extend({\r
-\r
- datasetElementType: Chart.elements.Line,\r
-\r
- dataElementType: Chart.elements.Point,\r
-\r
- addElementAndReset: function(index) {\r
- var me = this;\r
- var options = me.chart.options;\r
- var meta = me.getMeta();\r
-\r
- Chart.DatasetController.prototype.addElementAndReset.call(me, index);\r
-\r
- // Make sure bezier control points are updated\r
- if (lineEnabled(me.getDataset(), options) && meta.dataset._model.tension !== 0) {\r
- me.updateBezierControlPoints();\r
- }\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var line = meta.dataset;\r
- var points = meta.data || [];\r
- var options = me.chart.options;\r
- var lineElementOptions = options.elements.line;\r
- var scale = me.getScaleForId(meta.yAxisID);\r
- var i, ilen, custom;\r
- var dataset = me.getDataset();\r
- var showLine = lineEnabled(dataset, options);\r
-\r
- // Update Line\r
- if (showLine) {\r
- custom = line.custom || {};\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\r
- dataset.lineTension = dataset.tension;\r
- }\r
-\r
- // Utility\r
- line._scale = scale;\r
- line._datasetIndex = me.index;\r
- // Data\r
- line._children = points;\r
- // Model\r
- line._model = {\r
- // Appearance\r
- // The default behavior of lines is to break at null values, according\r
- // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\r
- // This option gives linse the ability to span gaps\r
- spanGaps: dataset.spanGaps ? dataset.spanGaps : false,\r
- tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\r
- borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\r
- borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\r
- borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\r
- borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\r
- borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\r
- fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\r
- // Scale\r
- scaleTop: scale.top,\r
- scaleBottom: scale.bottom,\r
- scaleZero: scale.getBasePixel()\r
- };\r
-\r
- line.pivot();\r
- }\r
-\r
- // Update Points\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- me.updateElement(points[i], i, reset);\r
- }\r
-\r
- if (showLine && line._model.tension !== 0) {\r
- me.updateBezierControlPoints();\r
- }\r
-\r
- // Now pivot the point for animation\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- points[i].pivot();\r
- }\r
- },\r
-\r
- getPointBackgroundColor: function(point, index) {\r
- var backgroundColor = this.chart.options.elements.point.backgroundColor;\r
- var dataset = this.getDataset();\r
- var custom = point.custom || {};\r
-\r
- if (custom.backgroundColor) {\r
- backgroundColor = custom.backgroundColor;\r
- } else if (dataset.pointBackgroundColor) {\r
- backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);\r
- } else if (dataset.backgroundColor) {\r
- backgroundColor = dataset.backgroundColor;\r
- }\r
-\r
- return backgroundColor;\r
- },\r
-\r
- getPointBorderColor: function(point, index) {\r
- var borderColor = this.chart.options.elements.point.borderColor;\r
- var dataset = this.getDataset();\r
- var custom = point.custom || {};\r
-\r
- if (custom.borderColor) {\r
- borderColor = custom.borderColor;\r
- } else if (dataset.pointBorderColor) {\r
- borderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);\r
- } else if (dataset.borderColor) {\r
- borderColor = dataset.borderColor;\r
- }\r
-\r
- return borderColor;\r
- },\r
-\r
- getPointBorderWidth: function(point, index) {\r
- var borderWidth = this.chart.options.elements.point.borderWidth;\r
- var dataset = this.getDataset();\r
- var custom = point.custom || {};\r
-\r
- if (custom.borderWidth) {\r
- borderWidth = custom.borderWidth;\r
- } else if (dataset.pointBorderWidth) {\r
- borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);\r
- } else if (dataset.borderWidth) {\r
- borderWidth = dataset.borderWidth;\r
- }\r
-\r
- return borderWidth;\r
- },\r
-\r
- updateElement: function(point, index, reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var custom = point.custom || {};\r
- var dataset = me.getDataset();\r
- var datasetIndex = me.index;\r
- var value = dataset.data[index];\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var xScale = me.getScaleForId(meta.xAxisID);\r
- var pointOptions = me.chart.options.elements.point;\r
- var x, y;\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\r
- dataset.pointRadius = dataset.radius;\r
- }\r
- if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\r
- dataset.pointHitRadius = dataset.hitRadius;\r
- }\r
-\r
- x = xScale.getPixelForValue(value, index, datasetIndex, me.chart.isCombo);\r
- y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex, me.chart.isCombo);\r
-\r
- // Utility\r
- point._xScale = xScale;\r
- point._yScale = yScale;\r
- point._datasetIndex = datasetIndex;\r
- point._index = index;\r
-\r
- // Desired view properties\r
- point._model = {\r
- x: x,\r
- y: y,\r
- skip: custom.skip || isNaN(x) || isNaN(y),\r
- // Appearance\r
- radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),\r
- pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),\r
- backgroundColor: me.getPointBackgroundColor(point, index),\r
- borderColor: me.getPointBorderColor(point, index),\r
- borderWidth: me.getPointBorderWidth(point, index),\r
- tension: meta.dataset._model ? meta.dataset._model.tension : 0,\r
- // Tooltip\r
- hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)\r
- };\r
- },\r
-\r
- calculatePointY: function(value, index, datasetIndex, isCombo) {\r
- var me = this;\r
- var chart = me.chart;\r
- var meta = me.getMeta();\r
- var yScale = me.getScaleForId(meta.yAxisID);\r
- var sumPos = 0;\r
- var sumNeg = 0;\r
- var i, ds, dsMeta;\r
-\r
- if (yScale.options.stacked) {\r
- for (i = 0; i < datasetIndex; i++) {\r
- ds = chart.data.datasets[i];\r
- dsMeta = chart.getDatasetMeta(i);\r
- if (dsMeta.type === 'line' && chart.isDatasetVisible(i)) {\r
- if (ds.data[index] < 0) {\r
- sumNeg += ds.data[index] || 0;\r
- } else {\r
- sumPos += ds.data[index] || 0;\r
- }\r
- }\r
- }\r
-\r
- if (value < 0) {\r
- return yScale.getPixelForValue(sumNeg + value);\r
- } else {\r
- return yScale.getPixelForValue(sumPos + value);\r
- }\r
- }\r
-\r
- return yScale.getPixelForValue(value);\r
- },\r
-\r
- updateBezierControlPoints: function() {\r
- var meta = this.getMeta();\r
- var area = this.chart.chartArea;\r
- var points = meta.data || [];\r
- var i, ilen, point, model, controlPoints;\r
-\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- point = points[i];\r
- model = point._model;\r
- controlPoints = helpers.splineCurve(\r
- helpers.previousItem(points, i)._model,\r
- model,\r
- helpers.nextItem(points, i)._model,\r
- meta.dataset._model.tension\r
- );\r
-\r
- model.controlPointPreviousX = controlPoints.previous.x;\r
- model.controlPointPreviousY = controlPoints.previous.y;\r
- model.controlPointNextX = controlPoints.next.x;\r
- model.controlPointNextY = controlPoints.next.y;\r
- }\r
- },\r
-\r
- draw: function(ease) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var points = meta.data || [];\r
- var easingDecimal = ease || 1;\r
- var i, ilen;\r
-\r
- // Transition Point Locations\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- points[i].transition(easingDecimal);\r
- }\r
-\r
- // Transition and Draw the line\r
- if (lineEnabled(me.getDataset(), me.chart.options)) {\r
- meta.dataset.transition(easingDecimal).draw();\r
- }\r
-\r
- // Draw the points\r
- for (i=0, ilen=points.length; i<ilen; ++i) {\r
- points[i].draw();\r
- }\r
- },\r
-\r
- setHoverStyle: function(point) {\r
- // Point\r
- var dataset = this.chart.data.datasets[point._datasetIndex];\r
- var index = point._index;\r
- var custom = point.custom || {};\r
- var model = point._model;\r
-\r
- model.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\r
- model.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\r
- },\r
-\r
- removeHoverStyle: function(point) {\r
- var me = this;\r
- var dataset = me.chart.data.datasets[point._datasetIndex];\r
- var index = point._index;\r
- var custom = point.custom || {};\r
- var model = point._model;\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\r
- dataset.pointRadius = dataset.radius;\r
- }\r
-\r
- model.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);\r
- model.backgroundColor = me.getPointBackgroundColor(point, index);\r
- model.borderColor = me.getPointBorderColor(point, index);\r
- model.borderWidth = me.getPointBorderWidth(point, index);\r
- }\r
- });\r
-};\r
-
-},{}],19:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.polarArea = {\r
-\r
- scale: {\r
- type: "radialLinear",\r
- lineArc: true // so that lines are circular\r
- },\r
-\r
- //Boolean - Whether to animate the rotation of the chart\r
- animation: {\r
- animateRotate: true,\r
- animateScale: true\r
- },\r
-\r
- aspectRatio: 1,\r
- legendCallback: function(chart) {\r
- var text = [];\r
- text.push('<ul class="' + chart.id + '-legend">');\r
-\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var labels = data.labels;\r
-\r
- if (datasets.length) {\r
- for (var i = 0; i < datasets[0].data.length; ++i) {\r
- text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '">');\r
- if (labels[i]) {\r
- text.push(labels[i]);\r
- }\r
- text.push('</span></li>');\r
- }\r
- }\r
-\r
- text.push('</ul>');\r
- return text.join("");\r
- },\r
- legend: {\r
- labels: {\r
- generateLabels: function(chart) {\r
- var data = chart.data;\r
- if (data.labels.length && data.datasets.length) {\r
- return data.labels.map(function(label, i) {\r
- var meta = chart.getDatasetMeta(0);\r
- var ds = data.datasets[0];\r
- var arc = meta.data[i];\r
- var custom = arc.custom || {};\r
- var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
- var arcOpts = chart.options.elements.arc;\r
- var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\r
- var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\r
- var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\r
-\r
- return {\r
- text: label,\r
- fillStyle: fill,\r
- strokeStyle: stroke,\r
- lineWidth: bw,\r
- hidden: isNaN(ds.data[i]) || meta.data[i].hidden,\r
-\r
- // Extra data used for toggling the correct item\r
- index: i\r
- };\r
- });\r
- } else {\r
- return [];\r
- }\r
- }\r
- },\r
-\r
- onClick: function(e, legendItem) {\r
- var index = legendItem.index;\r
- var chart = this.chart;\r
- var i, ilen, meta;\r
-\r
- for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r
- meta = chart.getDatasetMeta(i);\r
- meta.data[index].hidden = !meta.data[index].hidden;\r
- }\r
-\r
- chart.update();\r
- }\r
- },\r
-\r
- // Need to override these to give a nice default\r
- tooltips: {\r
- callbacks: {\r
- title: function() {\r
- return '';\r
- },\r
- label: function(tooltipItem, data) {\r
- return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;\r
- }\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.polarArea = Chart.DatasetController.extend({\r
-\r
- dataElementType: Chart.elements.Arc,\r
-\r
- linkScales: helpers.noop,\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var chart = me.chart;\r
- var chartArea = chart.chartArea;\r
- var meta = me.getMeta();\r
- var opts = chart.options;\r
- var arcOpts = opts.elements.arc;\r
- var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\r
- chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);\r
- chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\r
- chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\r
-\r
- me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\r
- me.innerRadius = me.outerRadius - chart.radiusLength;\r
-\r
- meta.count = me.countVisibleElements();\r
-\r
- helpers.each(meta.data, function(arc, index) {\r
- me.updateElement(arc, index, reset);\r
- });\r
- },\r
-\r
- updateElement: function(arc, index, reset) {\r
- var me = this;\r
- var chart = me.chart;\r
- var chartArea = chart.chartArea;\r
- var dataset = me.getDataset();\r
- var opts = chart.options;\r
- var animationOpts = opts.animation;\r
- var arcOpts = opts.elements.arc;\r
- var custom = arc.custom || {};\r
- var scale = chart.scale;\r
- var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
- var labels = chart.data.labels;\r
-\r
- var circumference = me.calculateCircumference(dataset.data[index]);\r
- var centerX = (chartArea.left + chartArea.right) / 2;\r
- var centerY = (chartArea.top + chartArea.bottom) / 2;\r
-\r
- // If there is NaN data before us, we need to calculate the starting angle correctly.\r
- // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data\r
- var visibleCount = 0;\r
- var meta = me.getMeta();\r
- for (var i = 0; i < index; ++i) {\r
- if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {\r
- ++visibleCount;\r
- }\r
- }\r
-\r
- var negHalfPI = -0.5 * Math.PI;\r
- var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r
- var startAngle = (negHalfPI) + (circumference * visibleCount);\r
- var endAngle = startAngle + (arc.hidden ? 0 : circumference);\r
-\r
- var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r
-\r
- helpers.extend(arc, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- _index: index,\r
- _scale: scale,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: centerX,\r
- y: centerY,\r
- innerRadius: 0,\r
- outerRadius: reset ? resetRadius : distance,\r
- startAngle: reset && animationOpts.animateRotate ? negHalfPI : startAngle,\r
- endAngle: reset && animationOpts.animateRotate ? negHalfPI : endAngle,\r
- label: getValueAtIndexOrDefault(labels, index, labels[index])\r
- }\r
- });\r
-\r
- // Apply border and fill style\r
- me.removeHoverStyle(arc);\r
-\r
- arc.pivot();\r
- },\r
-\r
- removeHoverStyle: function(arc) {\r
- Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\r
- },\r
-\r
- countVisibleElements: function() {\r
- var dataset = this.getDataset();\r
- var meta = this.getMeta();\r
- var count = 0;\r
-\r
- helpers.each(meta.data, function(element, index) {\r
- if (!isNaN(dataset.data[index]) && !element.hidden) {\r
- count++;\r
- }\r
- });\r
-\r
- return count;\r
- },\r
-\r
- calculateCircumference: function(value) {\r
- var count = this.getMeta().count;\r
- if (count > 0 && !isNaN(value)) {\r
- return (2 * Math.PI) / count;\r
- } else {\r
- return 0;\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],20:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.radar = {\r
- scale: {\r
- type: "radialLinear"\r
- },\r
- elements: {\r
- line: {\r
- tension: 0 // no bezier in radar\r
- }\r
- }\r
- };\r
-\r
- Chart.controllers.radar = Chart.DatasetController.extend({\r
-\r
- datasetElementType: Chart.elements.Line,\r
-\r
- dataElementType: Chart.elements.Point,\r
-\r
- linkScales: helpers.noop,\r
-\r
- addElementAndReset: function(index) {\r
- Chart.DatasetController.prototype.addElementAndReset.call(this, index);\r
-\r
- // Make sure bezier control points are updated\r
- this.updateBezierControlPoints();\r
- },\r
-\r
- update: function update(reset) {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var line = meta.dataset;\r
- var points = meta.data;\r
- var custom = line.custom || {};\r
- var dataset = me.getDataset();\r
- var lineElementOptions = me.chart.options.elements.line;\r
- var scale = me.chart.scale;\r
-\r
- // Compatibility: If the properties are defined with only the old name, use those values\r
- if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\r
- dataset.lineTension = dataset.tension;\r
- }\r
-\r
- helpers.extend(meta.dataset, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- // Data\r
- _children: points,\r
- _loop: true,\r
- // Model\r
- _model: {\r
- // Appearance\r
- tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\r
- borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\r
- fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\r
- borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\r
- borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\r
- borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\r
- borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\r
-\r
- // Scale\r
- scaleTop: scale.top,\r
- scaleBottom: scale.bottom,\r
- scaleZero: scale.getBasePosition()\r
- }\r
- });\r
-\r
- meta.dataset.pivot();\r
-\r
- // Update Points\r
- helpers.each(points, function(point, index) {\r
- me.updateElement(point, index, reset);\r
- }, me);\r
-\r
-\r
- // Update bezier control points\r
- me.updateBezierControlPoints();\r
- },\r
- updateElement: function(point, index, reset) {\r
- var me = this;\r
- var custom = point.custom || {};\r
- var dataset = me.getDataset();\r
- var scale = me.chart.scale;\r
- var pointElementOptions = me.chart.options.elements.point;\r
- var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\r
-\r
- helpers.extend(point, {\r
- // Utility\r
- _datasetIndex: me.index,\r
- _index: index,\r
- _scale: scale,\r
-\r
- // Desired view properties\r
- _model: {\r
- x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales\r
- y: reset ? scale.yCenter : pointPosition.y,\r
-\r
- // Appearance\r
- tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, me.chart.options.elements.line.tension),\r
- radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),\r
- backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),\r
- borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),\r
- borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),\r
- pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),\r
-\r
- // Tooltip\r
- hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\r
- }\r
- });\r
-\r
- point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));\r
- },\r
- updateBezierControlPoints: function() {\r
- var chartArea = this.chart.chartArea;\r
- var meta = this.getMeta();\r
-\r
- helpers.each(meta.data, function(point, index) {\r
- var model = point._model;\r
- var controlPoints = helpers.splineCurve(\r
- helpers.previousItem(meta.data, index, true)._model,\r
- model,\r
- helpers.nextItem(meta.data, index, true)._model,\r
- model.tension\r
- );\r
-\r
- // Prevent the bezier going outside of the bounds of the graph\r
- model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);\r
- model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);\r
-\r
- model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);\r
- model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);\r
-\r
- // Now pivot the point for animation\r
- point.pivot();\r
- });\r
- },\r
-\r
- draw: function(ease) {\r
- var meta = this.getMeta();\r
- var easingDecimal = ease || 1;\r
-\r
- // Transition Point Locations\r
- helpers.each(meta.data, function(point, index) {\r
- point.transition(easingDecimal);\r
- });\r
-\r
- // Transition and Draw the line\r
- meta.dataset.transition(easingDecimal).draw();\r
-\r
- // Draw the points\r
- helpers.each(meta.data, function(point) {\r
- point.draw();\r
- });\r
- },\r
-\r
- setHoverStyle: function(point) {\r
- // Point\r
- var dataset = this.chart.data.datasets[point._datasetIndex];\r
- var custom = point.custom || {};\r
- var index = point._index;\r
- var model = point._model;\r
-\r
- model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\r
- model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\r
- },\r
-\r
- removeHoverStyle: function(point) {\r
- var dataset = this.chart.data.datasets[point._datasetIndex];\r
- var custom = point.custom || {};\r
- var index = point._index;\r
- var model = point._model;\r
- var pointElementOptions = this.chart.options.elements.point;\r
-\r
- model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius);\r
- model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);\r
- model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);\r
- model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);\r
- }\r
- });\r
-};\r
-
-},{}],21:[function(require,module,exports){
-/*global window: false */\r
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.global.animation = {\r
- duration: 1000,\r
- easing: "easeOutQuart",\r
- onProgress: helpers.noop,\r
- onComplete: helpers.noop\r
- };\r
-\r
- Chart.Animation = Chart.Element.extend({\r
- currentStep: null, // the current animation step\r
- numSteps: 60, // default number of steps\r
- easing: "", // the easing to use for this animation\r
- render: null, // render function used by the animation service\r
-\r
- onAnimationProgress: null, // user specified callback to fire on each step of the animation\r
- onAnimationComplete: null // user specified callback to fire when the animation finishes\r
- });\r
-\r
- Chart.animationService = {\r
- frameDuration: 17,\r
- animations: [],\r
- dropFrames: 0,\r
- request: null,\r
- addAnimation: function(chartInstance, animationObject, duration, lazy) {\r
- var me = this;\r
-\r
- if (!lazy) {\r
- chartInstance.animating = true;\r
- }\r
-\r
- for (var index = 0; index < me.animations.length; ++index) {\r
- if (me.animations[index].chartInstance === chartInstance) {\r
- // replacing an in progress animation\r
- me.animations[index].animationObject = animationObject;\r
- return;\r
- }\r
- }\r
-\r
- me.animations.push({\r
- chartInstance: chartInstance,\r
- animationObject: animationObject\r
- });\r
-\r
- // If there are no animations queued, manually kickstart a digest, for lack of a better word\r
- if (me.animations.length === 1) {\r
- me.requestAnimationFrame();\r
- }\r
- },\r
- // Cancel the animation for a given chart instance\r
- cancelAnimation: function(chartInstance) {\r
- var index = helpers.findIndex(this.animations, function(animationWrapper) {\r
- return animationWrapper.chartInstance === chartInstance;\r
- });\r
-\r
- if (index !== -1) {\r
- this.animations.splice(index, 1);\r
- chartInstance.animating = false;\r
- }\r
- },\r
- requestAnimationFrame: function() {\r
- var me = this;\r
- if (me.request === null) {\r
- // Skip animation frame requests until the active one is executed.\r
- // This can happen when processing mouse events, e.g. 'mousemove'\r
- // and 'mouseout' events will trigger multiple renders.\r
- me.request = helpers.requestAnimFrame.call(window, function() {\r
- me.request = null;\r
- me.startDigest();\r
- });\r
- }\r
- },\r
- startDigest: function() {\r
- var me = this;\r
-\r
- var startTime = Date.now();\r
- var framesToDrop = 0;\r
-\r
- if (me.dropFrames > 1) {\r
- framesToDrop = Math.floor(me.dropFrames);\r
- me.dropFrames = me.dropFrames % 1;\r
- }\r
-\r
- var i = 0;\r
- while (i < me.animations.length) {\r
- if (me.animations[i].animationObject.currentStep === null) {\r
- me.animations[i].animationObject.currentStep = 0;\r
- }\r
-\r
- me.animations[i].animationObject.currentStep += 1 + framesToDrop;\r
-\r
- if (me.animations[i].animationObject.currentStep > me.animations[i].animationObject.numSteps) {\r
- me.animations[i].animationObject.currentStep = me.animations[i].animationObject.numSteps;\r
- }\r
-\r
- me.animations[i].animationObject.render(me.animations[i].chartInstance, me.animations[i].animationObject);\r
- if (me.animations[i].animationObject.onAnimationProgress && me.animations[i].animationObject.onAnimationProgress.call) {\r
- me.animations[i].animationObject.onAnimationProgress.call(me.animations[i].chartInstance, me.animations[i]);\r
- }\r
-\r
- if (me.animations[i].animationObject.currentStep === me.animations[i].animationObject.numSteps) {\r
- if (me.animations[i].animationObject.onAnimationComplete && me.animations[i].animationObject.onAnimationComplete.call) {\r
- me.animations[i].animationObject.onAnimationComplete.call(me.animations[i].chartInstance, me.animations[i]);\r
- }\r
-\r
- // executed the last frame. Remove the animation.\r
- me.animations[i].chartInstance.animating = false;\r
-\r
- me.animations.splice(i, 1);\r
- } else {\r
- ++i;\r
- }\r
- }\r
-\r
- var endTime = Date.now();\r
- var dropFrames = (endTime - startTime) / me.frameDuration;\r
-\r
- me.dropFrames += dropFrames;\r
-\r
- // Do we have more stuff to animate?\r
- if (me.animations.length > 0) {\r
- me.requestAnimationFrame();\r
- }\r
- }\r
- };\r
-};
-},{}],22:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- //Create a dictionary of chart types, to allow for extension of existing types\r
- Chart.types = {};\r
-\r
- //Store a reference to each instance - allowing us to globally resize chart instances on window resize.\r
- //Destroy method on the chart will remove the instance of the chart from this reference.\r
- Chart.instances = {};\r
-\r
- // Controllers available for dataset visualization eg. bar, line, slice, etc.\r
- Chart.controllers = {};\r
-\r
- /**\r
- * @class Chart.Controller\r
- * The main controller of a chart.\r
- */\r
- Chart.Controller = function(instance) {\r
-\r
- this.chart = instance;\r
- this.config = instance.config;\r
- this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});\r
- this.id = helpers.uid();\r
-\r
- Object.defineProperty(this, 'data', {\r
- get: function() {\r
- return this.config.data;\r
- }\r
- });\r
-\r
- //Add the chart instance to the global namespace\r
- Chart.instances[this.id] = this;\r
-\r
- if (this.options.responsive) {\r
- // Silent resize before chart draws\r
- this.resize(true);\r
- }\r
-\r
- this.initialize();\r
-\r
- return this;\r
- };\r
-\r
- helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ {\r
-\r
- initialize: function initialize() {\r
- var me = this;\r
- // Before init plugin notification\r
- Chart.plugins.notify('beforeInit', [me]);\r
-\r
- me.bindEvents();\r
-\r
- // Make sure controllers are built first so that each dataset is bound to an axis before the scales\r
- // are built\r
- me.ensureScalesHaveIDs();\r
- me.buildOrUpdateControllers();\r
- me.buildScales();\r
- me.updateLayout();\r
- me.resetElements();\r
- me.initToolTip();\r
- me.update();\r
-\r
- // After init plugin notification\r
- Chart.plugins.notify('afterInit', [me]);\r
-\r
- return me;\r
- },\r
-\r
- clear: function clear() {\r
- helpers.clear(this.chart);\r
- return this;\r
- },\r
-\r
- stop: function stop() {\r
- // Stops any current animation loop occuring\r
- Chart.animationService.cancelAnimation(this);\r
- return this;\r
- },\r
-\r
- resize: function resize(silent) {\r
- var me = this;\r
- var chart = me.chart;\r
- var canvas = chart.canvas;\r
- var newWidth = helpers.getMaximumWidth(canvas);\r
- var aspectRatio = chart.aspectRatio;\r
- var newHeight = (me.options.maintainAspectRatio && isNaN(aspectRatio) === false && isFinite(aspectRatio) && aspectRatio !== 0) ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas);\r
-\r
- var sizeChanged = chart.width !== newWidth || chart.height !== newHeight;\r
-\r
- if (!sizeChanged) {\r
- return me;\r
- }\r
-\r
- canvas.width = chart.width = newWidth;\r
- canvas.height = chart.height = newHeight;\r
-\r
- helpers.retinaScale(chart);\r
-\r
- // Notify any plugins about the resize\r
- var newSize = { width: newWidth, height: newHeight };\r
- Chart.plugins.notify('resize', [me, newSize]);\r
-\r
- // Notify of resize\r
- if (me.options.onResize) {\r
- me.options.onResize(me, newSize);\r
- }\r
-\r
- if (!silent) {\r
- me.stop();\r
- me.update(me.options.responsiveAnimationDuration);\r
- }\r
-\r
- return me;\r
- },\r
-\r
- ensureScalesHaveIDs: function ensureScalesHaveIDs() {\r
- var options = this.options;\r
- var scalesOptions = options.scales || {};\r
- var scaleOptions = options.scale;\r
-\r
- helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {\r
- xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);\r
- });\r
-\r
- helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {\r
- yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);\r
- });\r
-\r
- if (scaleOptions) {\r
- scaleOptions.id = scaleOptions.id || 'scale';\r
- }\r
- },\r
-\r
- /**\r
- * Builds a map of scale ID to scale object for future lookup.\r
- */\r
- buildScales: function buildScales() {\r
- var me = this;\r
- var options = me.options;\r
- var scales = me.scales = {};\r
- var items = [];\r
-\r
- if (options.scales) {\r
- items = items.concat(\r
- (options.scales.xAxes || []).map(function(xAxisOptions) {\r
- return { options: xAxisOptions, dtype: 'category' }; }),\r
- (options.scales.yAxes || []).map(function(yAxisOptions) {\r
- return { options: yAxisOptions, dtype: 'linear' }; }));\r
- }\r
-\r
- if (options.scale) {\r
- items.push({ options: options.scale, dtype: 'radialLinear', isDefault: true });\r
- }\r
-\r
- helpers.each(items, function(item, index) {\r
- var scaleOptions = item.options;\r
- var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);\r
- var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);\r
- if (!scaleClass) {\r
- return;\r
- }\r
-\r
- var scale = new scaleClass({\r
- id: scaleOptions.id,\r
- options: scaleOptions,\r
- ctx: me.chart.ctx,\r
- chart: me\r
- });\r
-\r
- scales[scale.id] = scale;\r
-\r
- // TODO(SB): I think we should be able to remove this custom case (options.scale)\r
- // and consider it as a regular scale part of the "scales"" map only! This would\r
- // make the logic easier and remove some useless? custom code.\r
- if (item.isDefault) {\r
- me.scale = scale;\r
- }\r
- });\r
-\r
- Chart.scaleService.addScalesToLayout(this);\r
- },\r
-\r
- updateLayout: function() {\r
- Chart.layoutService.update(this, this.chart.width, this.chart.height);\r
- },\r
-\r
- buildOrUpdateControllers: function buildOrUpdateControllers() {\r
- var me = this;\r
- var types = [];\r
- var newControllers = [];\r
-\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- var meta = me.getDatasetMeta(datasetIndex);\r
- if (!meta.type) {\r
- meta.type = dataset.type || me.config.type;\r
- }\r
-\r
- types.push(meta.type);\r
-\r
- if (meta.controller) {\r
- meta.controller.updateIndex(datasetIndex);\r
- } else {\r
- meta.controller = new Chart.controllers[meta.type](me, datasetIndex);\r
- newControllers.push(meta.controller);\r
- }\r
- }, me);\r
-\r
- if (types.length > 1) {\r
- for (var i = 1; i < types.length; i++) {\r
- if (types[i] !== types[i - 1]) {\r
- me.isCombo = true;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return newControllers;\r
- },\r
-\r
- resetElements: function resetElements() {\r
- var me = this;\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- me.getDatasetMeta(datasetIndex).controller.reset();\r
- }, me);\r
- },\r
-\r
- update: function update(animationDuration, lazy) {\r
- var me = this;\r
- Chart.plugins.notify('beforeUpdate', [me]);\r
-\r
- // In case the entire data object changed\r
- me.tooltip._data = me.data;\r
-\r
- // Make sure dataset controllers are updated and new controllers are reset\r
- var newControllers = me.buildOrUpdateControllers();\r
-\r
- // Make sure all dataset controllers have correct meta data counts\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();\r
- }, me);\r
-\r
- Chart.layoutService.update(me, me.chart.width, me.chart.height);\r
-\r
- // Apply changes to the dataets that require the scales to have been calculated i.e BorderColor chages\r
- Chart.plugins.notify('afterScaleUpdate', [me]);\r
-\r
- // Can only reset the new controllers after the scales have been updated\r
- helpers.each(newControllers, function(controller) {\r
- controller.reset();\r
- });\r
-\r
- me.updateDatasets();\r
-\r
- // Do this before render so that any plugins that need final scale updates can use it\r
- Chart.plugins.notify('afterUpdate', [me]);\r
-\r
- me.render(animationDuration, lazy);\r
- },\r
-\r
- /**\r
- * @method beforeDatasetsUpdate\r
- * @description Called before all datasets are updated. If a plugin returns false,\r
- * the datasets update will be cancelled until another chart update is triggered.\r
- * @param {Object} instance the chart instance being updated.\r
- * @returns {Boolean} false to cancel the datasets update.\r
- * @memberof Chart.PluginBase\r
- * @since version 2.1.5\r
- * @instance\r
- */\r
-\r
- /**\r
- * @method afterDatasetsUpdate\r
- * @description Called after all datasets have been updated. Note that this\r
- * extension will not be called if the datasets update has been cancelled.\r
- * @param {Object} instance the chart instance being updated.\r
- * @memberof Chart.PluginBase\r
- * @since version 2.1.5\r
- * @instance\r
- */\r
-\r
- /**\r
- * Updates all datasets unless a plugin returns false to the beforeDatasetsUpdate\r
- * extension, in which case no datasets will be updated and the afterDatasetsUpdate\r
- * notification will be skipped.\r
- * @protected\r
- * @instance\r
- */\r
- updateDatasets: function() {\r
- var me = this;\r
- var i, ilen;\r
-\r
- if (Chart.plugins.notify('beforeDatasetsUpdate', [ me ])) {\r
- for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\r
- me.getDatasetMeta(i).controller.update();\r
- }\r
-\r
- Chart.plugins.notify('afterDatasetsUpdate', [ me ]);\r
- }\r
- },\r
-\r
- render: function render(duration, lazy) {\r
- var me = this;\r
- Chart.plugins.notify('beforeRender', [me]);\r
-\r
- var animationOptions = me.options.animation;\r
- if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {\r
- var animation = new Chart.Animation();\r
- animation.numSteps = (duration || animationOptions.duration) / 16.66; //60 fps\r
- animation.easing = animationOptions.easing;\r
-\r
- // render function\r
- animation.render = function(chartInstance, animationObject) {\r
- var easingFunction = helpers.easingEffects[animationObject.easing];\r
- var stepDecimal = animationObject.currentStep / animationObject.numSteps;\r
- var easeDecimal = easingFunction(stepDecimal);\r
-\r
- chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);\r
- };\r
-\r
- // user events\r
- animation.onAnimationProgress = animationOptions.onProgress;\r
- animation.onAnimationComplete = animationOptions.onComplete;\r
-\r
- Chart.animationService.addAnimation(me, animation, duration, lazy);\r
- } else {\r
- me.draw();\r
- if (animationOptions && animationOptions.onComplete && animationOptions.onComplete.call) {\r
- animationOptions.onComplete.call(me);\r
- }\r
- }\r
- return me;\r
- },\r
-\r
- draw: function(ease) {\r
- var me = this;\r
- var easingDecimal = ease || 1;\r
- me.clear();\r
-\r
- Chart.plugins.notify('beforeDraw', [me, easingDecimal]);\r
-\r
- // Draw all the scales\r
- helpers.each(me.boxes, function(box) {\r
- box.draw(me.chartArea);\r
- }, me);\r
- if (me.scale) {\r
- me.scale.draw();\r
- }\r
-\r
- Chart.plugins.notify('beforeDatasetsDraw', [me, easingDecimal]);\r
-\r
- // Draw each dataset via its respective controller (reversed to support proper line stacking)\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- if (me.isDatasetVisible(datasetIndex)) {\r
- me.getDatasetMeta(datasetIndex).controller.draw(ease);\r
- }\r
- }, me, true);\r
-\r
- Chart.plugins.notify('afterDatasetsDraw', [me, easingDecimal]);\r
-\r
- // Finally draw the tooltip\r
- me.tooltip.transition(easingDecimal).draw();\r
-\r
- Chart.plugins.notify('afterDraw', [me, easingDecimal]);\r
- },\r
-\r
- // Get the single element that was clicked on\r
- // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw\r
- getElementAtEvent: function(e) {\r
- var me = this;\r
- var eventPosition = helpers.getRelativePosition(e, me.chart);\r
- var elementsArray = [];\r
-\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- if (me.isDatasetVisible(datasetIndex)) {\r
- var meta = me.getDatasetMeta(datasetIndex);\r
- helpers.each(meta.data, function(element, index) {\r
- if (element.inRange(eventPosition.x, eventPosition.y)) {\r
- elementsArray.push(element);\r
- return elementsArray;\r
- }\r
- });\r
- }\r
- });\r
-\r
- return elementsArray;\r
- },\r
-\r
- getElementsAtEvent: function(e) {\r
- var me = this;\r
- var eventPosition = helpers.getRelativePosition(e, me.chart);\r
- var elementsArray = [];\r
-\r
- var found = (function() {\r
- if (me.data.datasets) {\r
- for (var i = 0; i < me.data.datasets.length; i++) {\r
- var meta = me.getDatasetMeta(i);\r
- if (me.isDatasetVisible(i)) {\r
- for (var j = 0; j < meta.data.length; j++) {\r
- if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) {\r
- return meta.data[j];\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }).call(me);\r
-\r
- if (!found) {\r
- return elementsArray;\r
- }\r
-\r
- helpers.each(me.data.datasets, function(dataset, datasetIndex) {\r
- if (me.isDatasetVisible(datasetIndex)) {\r
- var meta = me.getDatasetMeta(datasetIndex);\r
- elementsArray.push(meta.data[found._index]);\r
- }\r
- }, me);\r
-\r
- return elementsArray;\r
- },\r
-\r
- getElementsAtEventForMode: function(e, mode) {\r
- var me = this;\r
- switch (mode) {\r
- case 'single':\r
- return me.getElementAtEvent(e);\r
- case 'label':\r
- return me.getElementsAtEvent(e);\r
- case 'dataset':\r
- return me.getDatasetAtEvent(e);\r
- default:\r
- return e;\r
- }\r
- },\r
-\r
- getDatasetAtEvent: function(e) {\r
- var elementsArray = this.getElementAtEvent(e);\r
-\r
- if (elementsArray.length > 0) {\r
- elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data;\r
- }\r
-\r
- return elementsArray;\r
- },\r
-\r
- getDatasetMeta: function(datasetIndex) {\r
- var me = this;\r
- var dataset = me.data.datasets[datasetIndex];\r
- if (!dataset._meta) {\r
- dataset._meta = {};\r
- }\r
-\r
- var meta = dataset._meta[me.id];\r
- if (!meta) {\r
- meta = dataset._meta[me.id] = {\r
- type: null,\r
- data: [],\r
- dataset: null,\r
- controller: null,\r
- hidden: null, // See isDatasetVisible() comment\r
- xAxisID: null,\r
- yAxisID: null\r
- };\r
- }\r
-\r
- return meta;\r
- },\r
-\r
- getVisibleDatasetCount: function() {\r
- var count = 0;\r
- for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {\r
- if (this.isDatasetVisible(i)) {\r
- count++;\r
- }\r
- }\r
- return count;\r
- },\r
-\r
- isDatasetVisible: function(datasetIndex) {\r
- var meta = this.getDatasetMeta(datasetIndex);\r
-\r
- // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,\r
- // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.\r
- return typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;\r
- },\r
-\r
- generateLegend: function generateLegend() {\r
- return this.options.legendCallback(this);\r
- },\r
-\r
- destroy: function destroy() {\r
- var me = this;\r
- me.stop();\r
- me.clear();\r
- helpers.unbindEvents(me, me.events);\r
- helpers.removeResizeListener(me.chart.canvas.parentNode);\r
-\r
- // Reset canvas height/width attributes\r
- var canvas = me.chart.canvas;\r
- canvas.width = me.chart.width;\r
- canvas.height = me.chart.height;\r
-\r
- // if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here\r
- if (me.chart.originalDevicePixelRatio !== undefined) {\r
- me.chart.ctx.scale(1 / me.chart.originalDevicePixelRatio, 1 / me.chart.originalDevicePixelRatio);\r
- }\r
-\r
- // Reset to the old style since it may have been changed by the device pixel ratio changes\r
- canvas.style.width = me.chart.originalCanvasStyleWidth;\r
- canvas.style.height = me.chart.originalCanvasStyleHeight;\r
-\r
- Chart.plugins.notify('destroy', [me]);\r
-\r
- delete Chart.instances[me.id];\r
- },\r
-\r
- toBase64Image: function toBase64Image() {\r
- return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);\r
- },\r
-\r
- initToolTip: function initToolTip() {\r
- var me = this;\r
- me.tooltip = new Chart.Tooltip({\r
- _chart: me.chart,\r
- _chartInstance: me,\r
- _data: me.data,\r
- _options: me.options.tooltips\r
- }, me);\r
- },\r
-\r
- bindEvents: function bindEvents() {\r
- var me = this;\r
- helpers.bindEvents(me, me.options.events, function(evt) {\r
- me.eventHandler(evt);\r
- });\r
- },\r
-\r
- updateHoverStyle: function(elements, mode, enabled) {\r
- var method = enabled? 'setHoverStyle' : 'removeHoverStyle';\r
- var element, i, ilen;\r
-\r
- switch (mode) {\r
- case 'single':\r
- elements = [ elements[0] ];\r
- break;\r
- case 'label':\r
- case 'dataset':\r
- // elements = elements;\r
- break;\r
- default:\r
- // unsupported mode\r
- return;\r
- }\r
-\r
- for (i=0, ilen=elements.length; i<ilen; ++i) {\r
- element = elements[i];\r
- if (element) {\r
- this.getDatasetMeta(element._datasetIndex).controller[method](element);\r
- }\r
- }\r
- },\r
-\r
- eventHandler: function eventHandler(e) {\r
- var me = this;\r
- var tooltip = me.tooltip;\r
- var options = me.options || {};\r
- var hoverOptions = options.hover;\r
- var tooltipsOptions = options.tooltips;\r
-\r
- me.lastActive = me.lastActive || [];\r
- me.lastTooltipActive = me.lastTooltipActive || [];\r
-\r
- // Find Active Elements for hover and tooltips\r
- if (e.type === 'mouseout') {\r
- me.active = [];\r
- me.tooltipActive = [];\r
- } else {\r
- me.active = me.getElementsAtEventForMode(e, hoverOptions.mode);\r
- me.tooltipActive = me.getElementsAtEventForMode(e, tooltipsOptions.mode);\r
- }\r
-\r
- // On Hover hook\r
- if (hoverOptions.onHover) {\r
- hoverOptions.onHover.call(me, me.active);\r
- }\r
-\r
- if (e.type === 'mouseup' || e.type === 'click') {\r
- if (options.onClick) {\r
- options.onClick.call(me, e, me.active);\r
- }\r
- if (me.legend && me.legend.handleEvent) {\r
- me.legend.handleEvent(e);\r
- }\r
- }\r
-\r
- // Remove styling for last active (even if it may still be active)\r
- if (me.lastActive.length) {\r
- me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);\r
- }\r
-\r
- // Built in hover styling\r
- if (me.active.length && hoverOptions.mode) {\r
- me.updateHoverStyle(me.active, hoverOptions.mode, true);\r
- }\r
-\r
- // Built in Tooltips\r
- if (tooltipsOptions.enabled || tooltipsOptions.custom) {\r
- tooltip.initialize();\r
- tooltip._active = me.tooltipActive;\r
- tooltip.update(true);\r
- }\r
-\r
- // Hover animations\r
- tooltip.pivot();\r
-\r
- if (!me.animating) {\r
- // If entering, leaving, or changing elements, animate the change via pivot\r
- if (!helpers.arrayEquals(me.active, me.lastActive) ||\r
- !helpers.arrayEquals(me.tooltipActive, me.lastTooltipActive)) {\r
-\r
- me.stop();\r
-\r
- if (tooltipsOptions.enabled || tooltipsOptions.custom) {\r
- tooltip.update(true);\r
- }\r
-\r
- // We only need to render at this point. Updating will cause scales to be\r
- // recomputed generating flicker & using more memory than necessary.\r
- me.render(hoverOptions.animationDuration, true);\r
- }\r
- }\r
-\r
- // Remember Last Actives\r
- me.lastActive = me.active;\r
- me.lastTooltipActive = me.tooltipActive;\r
- return me;\r
- }\r
- });\r
-};\r
-
-},{}],23:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var noop = helpers.noop;\r
-\r
- // Base class for all dataset controllers (line, bar, etc)\r
- Chart.DatasetController = function(chart, datasetIndex) {\r
- this.initialize.call(this, chart, datasetIndex);\r
- };\r
-\r
- helpers.extend(Chart.DatasetController.prototype, {\r
-\r
- /**\r
- * Element type used to generate a meta dataset (e.g. Chart.element.Line).\r
- * @type {Chart.core.element}\r
- */\r
- datasetElementType: null,\r
-\r
- /**\r
- * Element type used to generate a meta data (e.g. Chart.element.Point).\r
- * @type {Chart.core.element}\r
- */\r
- dataElementType: null,\r
-\r
- initialize: function(chart, datasetIndex) {\r
- var me = this;\r
- me.chart = chart;\r
- me.index = datasetIndex;\r
- me.linkScales();\r
- me.addElements();\r
- },\r
-\r
- updateIndex: function(datasetIndex) {\r
- this.index = datasetIndex;\r
- },\r
-\r
- linkScales: function() {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var dataset = me.getDataset();\r
-\r
- if (meta.xAxisID === null) {\r
- meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;\r
- }\r
- if (meta.yAxisID === null) {\r
- meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;\r
- }\r
- },\r
-\r
- getDataset: function() {\r
- return this.chart.data.datasets[this.index];\r
- },\r
-\r
- getMeta: function() {\r
- return this.chart.getDatasetMeta(this.index);\r
- },\r
-\r
- getScaleForId: function(scaleID) {\r
- return this.chart.scales[scaleID];\r
- },\r
-\r
- reset: function() {\r
- this.update(true);\r
- },\r
-\r
- createMetaDataset: function() {\r
- var me = this;\r
- var type = me.datasetElementType;\r
- return type && new type({\r
- _chart: me.chart.chart,\r
- _datasetIndex: me.index\r
- });\r
- },\r
-\r
- createMetaData: function(index) {\r
- var me = this;\r
- var type = me.dataElementType;\r
- return type && new type({\r
- _chart: me.chart.chart,\r
- _datasetIndex: me.index,\r
- _index: index\r
- });\r
- },\r
-\r
- addElements: function() {\r
- var me = this;\r
- var meta = me.getMeta();\r
- var data = me.getDataset().data || [];\r
- var metaData = meta.data;\r
- var i, ilen;\r
-\r
- for (i=0, ilen=data.length; i<ilen; ++i) {\r
- metaData[i] = metaData[i] || me.createMetaData(meta, i);\r
- }\r
-\r
- meta.dataset = meta.dataset || me.createMetaDataset();\r
- },\r
-\r
- addElementAndReset: function(index) {\r
- var me = this;\r
- var element = me.createMetaData(index);\r
- me.getMeta().data.splice(index, 0, element);\r
- me.updateElement(element, index, true);\r
- },\r
-\r
- buildOrUpdateElements: function buildOrUpdateElements() {\r
- // Handle the number of data points changing\r
- var meta = this.getMeta(),\r
- md = meta.data,\r
- numData = this.getDataset().data.length,\r
- numMetaData = md.length;\r
-\r
- // Make sure that we handle number of datapoints changing\r
- if (numData < numMetaData) {\r
- // Remove excess bars for data points that have been removed\r
- md.splice(numData, numMetaData - numData);\r
- } else if (numData > numMetaData) {\r
- // Add new elements\r
- for (var index = numMetaData; index < numData; ++index) {\r
- this.addElementAndReset(index);\r
- }\r
- }\r
- },\r
-\r
- update: noop,\r
-\r
- draw: function(ease) {\r
- var easingDecimal = ease || 1;\r
- helpers.each(this.getMeta().data, function(element, index) {\r
- element.transition(easingDecimal).draw();\r
- });\r
- },\r
-\r
- removeHoverStyle: function(element, elementOpts) {\r
- var dataset = this.chart.data.datasets[element._datasetIndex],\r
- index = element._index,\r
- custom = element.custom || {},\r
- valueOrDefault = helpers.getValueAtIndexOrDefault,\r
- color = helpers.color,\r
- model = element._model;\r
-\r
- model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);\r
- model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);\r
- model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);\r
- },\r
-\r
- setHoverStyle: function(element) {\r
- var dataset = this.chart.data.datasets[element._datasetIndex],\r
- index = element._index,\r
- custom = element.custom || {},\r
- valueOrDefault = helpers.getValueAtIndexOrDefault,\r
- color = helpers.color,\r
- getHoverColor = helpers.getHoverColor,\r
- model = element._model;\r
-\r
- model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));\r
- model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));\r
- model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\r
- }\r
- });\r
-\r
- Chart.DatasetController.extend = helpers.inherits;\r
-};
-},{}],24:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.elements = {};\r
-\r
- Chart.Element = function(configuration) {\r
- helpers.extend(this, configuration);\r
- this.initialize.apply(this, arguments);\r
- };\r
-\r
- helpers.extend(Chart.Element.prototype, {\r
-\r
- initialize: function() {\r
- this.hidden = false;\r
- },\r
-\r
- pivot: function() {\r
- var me = this;\r
- if (!me._view) {\r
- me._view = helpers.clone(me._model);\r
- }\r
- me._start = helpers.clone(me._view);\r
- return me;\r
- },\r
-\r
- transition: function(ease) {\r
- var me = this;\r
- \r
- if (!me._view) {\r
- me._view = helpers.clone(me._model);\r
- }\r
-\r
- // No animation -> No Transition\r
- if (ease === 1) {\r
- me._view = me._model;\r
- me._start = null;\r
- return me;\r
- }\r
-\r
- if (!me._start) {\r
- me.pivot();\r
- }\r
-\r
- helpers.each(me._model, function(value, key) {\r
-\r
- if (key[0] === '_') {\r
- // Only non-underscored properties\r
- }\r
-\r
- // Init if doesn't exist\r
- else if (!me._view.hasOwnProperty(key)) {\r
- if (typeof value === 'number' && !isNaN(me._view[key])) {\r
- me._view[key] = value * ease;\r
- } else {\r
- me._view[key] = value;\r
- }\r
- }\r
-\r
- // No unnecessary computations\r
- else if (value === me._view[key]) {\r
- // It's the same! Woohoo!\r
- }\r
-\r
- // Color transitions if possible\r
- else if (typeof value === 'string') {\r
- try {\r
- var color = helpers.color(me._model[key]).mix(helpers.color(me._start[key]), ease);\r
- me._view[key] = color.rgbString();\r
- } catch (err) {\r
- me._view[key] = value;\r
- }\r
- }\r
- // Number transitions\r
- else if (typeof value === 'number') {\r
- var startVal = me._start[key] !== undefined && isNaN(me._start[key]) === false ? me._start[key] : 0;\r
- me._view[key] = ((me._model[key] - startVal) * ease) + startVal;\r
- }\r
- // Everything else\r
- else {\r
- me._view[key] = value;\r
- }\r
- }, me);\r
-\r
- return me;\r
- },\r
-\r
- tooltipPosition: function() {\r
- return {\r
- x: this._model.x,\r
- y: this._model.y\r
- };\r
- },\r
-\r
- hasValue: function() {\r
- return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);\r
- }\r
- });\r
-\r
- Chart.Element.extend = helpers.inherits;\r
-\r
-};\r
-
-},{}],25:[function(require,module,exports){
-/*global window: false */\r
-/*global document: false */\r
-"use strict";\r
-\r
-var color = require(3);\r
-\r
-module.exports = function(Chart) {\r
- //Global Chart helpers object for utility methods and classes\r
- var helpers = Chart.helpers = {};\r
-\r
- //-- Basic js utility methods\r
- helpers.each = function(loopable, callback, self, reverse) {\r
- // Check to see if null or undefined firstly.\r
- var i, len;\r
- if (helpers.isArray(loopable)) {\r
- len = loopable.length;\r
- if (reverse) {\r
- for (i = len - 1; i >= 0; i--) {\r
- callback.call(self, loopable[i], i);\r
- }\r
- } else {\r
- for (i = 0; i < len; i++) {\r
- callback.call(self, loopable[i], i);\r
- }\r
- }\r
- } else if (typeof loopable === 'object') {\r
- var keys = Object.keys(loopable);\r
- len = keys.length;\r
- for (i = 0; i < len; i++) {\r
- callback.call(self, loopable[keys[i]], keys[i]);\r
- }\r
- }\r
- };\r
- helpers.clone = function(obj) {\r
- var objClone = {};\r
- helpers.each(obj, function(value, key) {\r
- if (helpers.isArray(value)) {\r
- objClone[key] = value.slice(0);\r
- } else if (typeof value === 'object' && value !== null) {\r
- objClone[key] = helpers.clone(value);\r
- } else {\r
- objClone[key] = value;\r
- }\r
- });\r
- return objClone;\r
- };\r
- helpers.extend = function(base) {\r
- var setFn = function(value, key) { base[key] = value; };\r
- for (var i = 1, ilen = arguments.length; i < ilen; i++) {\r
- helpers.each(arguments[i], setFn);\r
- }\r
- return base;\r
- };\r
- // Need a special merge function to chart configs since they are now grouped\r
- helpers.configMerge = function(_base) {\r
- var base = helpers.clone(_base);\r
- helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {\r
- helpers.each(extension, function(value, key) {\r
- if (key === 'scales') {\r
- // Scale config merging is complex. Add out own function here for that\r
- base[key] = helpers.scaleMerge(base.hasOwnProperty(key) ? base[key] : {}, value);\r
-\r
- } else if (key === 'scale') {\r
- // Used in polar area & radar charts since there is only one scale\r
- base[key] = helpers.configMerge(base.hasOwnProperty(key) ? base[key] : {}, Chart.scaleService.getScaleDefaults(value.type), value);\r
- } else if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {\r
- // In this case we have an array of objects replacing another array. Rather than doing a strict replace,\r
- // merge. This allows easy scale option merging\r
- var baseArray = base[key];\r
-\r
- helpers.each(value, function(valueObj, index) {\r
-\r
- if (index < baseArray.length) {\r
- if (typeof baseArray[index] === 'object' && baseArray[index] !== null && typeof valueObj === 'object' && valueObj !== null) {\r
- // Two objects are coming together. Do a merge of them.\r
- baseArray[index] = helpers.configMerge(baseArray[index], valueObj);\r
- } else {\r
- // Just overwrite in this case since there is nothing to merge\r
- baseArray[index] = valueObj;\r
- }\r
- } else {\r
- baseArray.push(valueObj); // nothing to merge\r
- }\r
- });\r
-\r
- } else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") {\r
- // If we are overwriting an object with an object, do a merge of the properties.\r
- base[key] = helpers.configMerge(base[key], value);\r
-\r
- } else {\r
- // can just overwrite the value in this case\r
- base[key] = value;\r
- }\r
- });\r
- });\r
-\r
- return base;\r
- };\r
- helpers.scaleMerge = function(_base, extension) {\r
- var base = helpers.clone(_base);\r
-\r
- helpers.each(extension, function(value, key) {\r
- if (key === 'xAxes' || key === 'yAxes') {\r
- // These properties are arrays of items\r
- if (base.hasOwnProperty(key)) {\r
- helpers.each(value, function(valueObj, index) {\r
- var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\r
- var axisDefaults = Chart.scaleService.getScaleDefaults(axisType);\r
- if (index >= base[key].length || !base[key][index].type) {\r
- base[key].push(helpers.configMerge(axisDefaults, valueObj));\r
- } else if (valueObj.type && valueObj.type !== base[key][index].type) {\r
- // Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults\r
- base[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);\r
- } else {\r
- // Type is the same\r
- base[key][index] = helpers.configMerge(base[key][index], valueObj);\r
- }\r
- });\r
- } else {\r
- base[key] = [];\r
- helpers.each(value, function(valueObj) {\r
- var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\r
- base[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));\r
- });\r
- }\r
- } else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") {\r
- // If we are overwriting an object with an object, do a merge of the properties.\r
- base[key] = helpers.configMerge(base[key], value);\r
-\r
- } else {\r
- // can just overwrite the value in this case\r
- base[key] = value;\r
- }\r
- });\r
-\r
- return base;\r
- };\r
- helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {\r
- if (value === undefined || value === null) {\r
- return defaultValue;\r
- }\r
-\r
- if (helpers.isArray(value)) {\r
- return index < value.length ? value[index] : defaultValue;\r
- }\r
-\r
- return value;\r
- };\r
- helpers.getValueOrDefault = function(value, defaultValue) {\r
- return value === undefined ? defaultValue : value;\r
- };\r
- helpers.indexOf = Array.prototype.indexOf?\r
- function(array, item) { return array.indexOf(item); } :\r
- function(array, item) {\r
- for (var i = 0, ilen = array.length; i < ilen; ++i) {\r
- if (array[i] === item) {\r
- return i;\r
- }\r
- }\r
- return -1;\r
- };\r
- helpers.where = function(collection, filterCallback) {\r
- if (helpers.isArray(collection) && Array.prototype.filter) {\r
- return collection.filter(filterCallback);\r
- } else {\r
- var filtered = [];\r
-\r
- helpers.each(collection, function(item) {\r
- if (filterCallback(item)) {\r
- filtered.push(item);\r
- }\r
- });\r
-\r
- return filtered;\r
- }\r
- };\r
- helpers.findIndex = Array.prototype.findIndex?\r
- function(array, callback, scope) { return array.findIndex(callback, scope); } :\r
- function(array, callback, scope) {\r
- scope = scope === undefined? array : scope;\r
- for (var i = 0, ilen = array.length; i < ilen; ++i) {\r
- if (callback.call(scope, array[i], i, array)) {\r
- return i;\r
- }\r
- }\r
- return -1;\r
- };\r
- helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {\r
- // Default to start of the array\r
- if (startIndex === undefined || startIndex === null) {\r
- startIndex = -1;\r
- }\r
- for (var i = startIndex + 1; i < arrayToSearch.length; i++) {\r
- var currentItem = arrayToSearch[i];\r
- if (filterCallback(currentItem)) {\r
- return currentItem;\r
- }\r
- }\r
- };\r
- helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {\r
- // Default to end of the array\r
- if (startIndex === undefined || startIndex === null) {\r
- startIndex = arrayToSearch.length;\r
- }\r
- for (var i = startIndex - 1; i >= 0; i--) {\r
- var currentItem = arrayToSearch[i];\r
- if (filterCallback(currentItem)) {\r
- return currentItem;\r
- }\r
- }\r
- };\r
- helpers.inherits = function(extensions) {\r
- //Basic javascript inheritance based on the model created in Backbone.js\r
- var parent = this;\r
- var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function() {\r
- return parent.apply(this, arguments);\r
- };\r
-\r
- var Surrogate = function() {\r
- this.constructor = ChartElement;\r
- };\r
- Surrogate.prototype = parent.prototype;\r
- ChartElement.prototype = new Surrogate();\r
-\r
- ChartElement.extend = helpers.inherits;\r
-\r
- if (extensions) {\r
- helpers.extend(ChartElement.prototype, extensions);\r
- }\r
-\r
- ChartElement.__super__ = parent.prototype;\r
-\r
- return ChartElement;\r
- };\r
- helpers.noop = function() {};\r
- helpers.uid = (function() {\r
- var id = 0;\r
- return function() {\r
- return id++;\r
- };\r
- })();\r
- //-- Math methods\r
- helpers.isNumber = function(n) {\r
- return !isNaN(parseFloat(n)) && isFinite(n);\r
- };\r
- helpers.almostEquals = function(x, y, epsilon) {\r
- return Math.abs(x - y) < epsilon;\r
- };\r
- helpers.max = function(array) {\r
- return array.reduce(function(max, value) {\r
- if (!isNaN(value)) {\r
- return Math.max(max, value);\r
- } else {\r
- return max;\r
- }\r
- }, Number.NEGATIVE_INFINITY);\r
- };\r
- helpers.min = function(array) {\r
- return array.reduce(function(min, value) {\r
- if (!isNaN(value)) {\r
- return Math.min(min, value);\r
- } else {\r
- return min;\r
- }\r
- }, Number.POSITIVE_INFINITY);\r
- };\r
- helpers.sign = Math.sign?\r
- function(x) { return Math.sign(x); } :\r
- function(x) {\r
- x = +x; // convert to a number\r
- if (x === 0 || isNaN(x)) {\r
- return x;\r
- }\r
- return x > 0 ? 1 : -1;\r
- };\r
- helpers.log10 = Math.log10?\r
- function(x) { return Math.log10(x); } :\r
- function(x) {\r
- return Math.log(x) / Math.LN10;\r
- };\r
- helpers.toRadians = function(degrees) {\r
- return degrees * (Math.PI / 180);\r
- };\r
- helpers.toDegrees = function(radians) {\r
- return radians * (180 / Math.PI);\r
- };\r
- // Gets the angle from vertical upright to the point about a centre.\r
- helpers.getAngleFromPoint = function(centrePoint, anglePoint) {\r
- var distanceFromXCenter = anglePoint.x - centrePoint.x,\r
- distanceFromYCenter = anglePoint.y - centrePoint.y,\r
- radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\r
-\r
- var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\r
-\r
- if (angle < (-0.5 * Math.PI)) {\r
- angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\r
- }\r
-\r
- return {\r
- angle: angle,\r
- distance: radialDistanceFromCenter\r
- };\r
- };\r
- helpers.aliasPixel = function(pixelWidth) {\r
- return (pixelWidth % 2 === 0) ? 0 : 0.5;\r
- };\r
- helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {\r
- //Props to Rob Spencer at scaled innovation for his post on splining between points\r
- //http://scaledinnovation.com/analytics/splines/aboutSplines.html\r
-\r
- // This function must also respect "skipped" points\r
-\r
- var previous = firstPoint.skip ? middlePoint : firstPoint,\r
- current = middlePoint,\r
- next = afterPoint.skip ? middlePoint : afterPoint;\r
-\r
- var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));\r
- var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));\r
-\r
- var s01 = d01 / (d01 + d12);\r
- var s12 = d12 / (d01 + d12);\r
-\r
- // If all points are the same, s01 & s02 will be inf\r
- s01 = isNaN(s01) ? 0 : s01;\r
- s12 = isNaN(s12) ? 0 : s12;\r
-\r
- var fa = t * s01; // scaling factor for triangle Ta\r
- var fb = t * s12;\r
-\r
- return {\r
- previous: {\r
- x: current.x - fa * (next.x - previous.x),\r
- y: current.y - fa * (next.y - previous.y)\r
- },\r
- next: {\r
- x: current.x + fb * (next.x - previous.x),\r
- y: current.y + fb * (next.y - previous.y)\r
- }\r
- };\r
- };\r
- helpers.nextItem = function(collection, index, loop) {\r
- if (loop) {\r
- return index >= collection.length - 1 ? collection[0] : collection[index + 1];\r
- }\r
-\r
- return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];\r
- };\r
- helpers.previousItem = function(collection, index, loop) {\r
- if (loop) {\r
- return index <= 0 ? collection[collection.length - 1] : collection[index - 1];\r
- }\r
- return index <= 0 ? collection[0] : collection[index - 1];\r
- };\r
- // Implementation of the nice number algorithm used in determining where axis labels will go\r
- helpers.niceNum = function(range, round) {\r
- var exponent = Math.floor(helpers.log10(range));\r
- var fraction = range / Math.pow(10, exponent);\r
- var niceFraction;\r
-\r
- if (round) {\r
- if (fraction < 1.5) {\r
- niceFraction = 1;\r
- } else if (fraction < 3) {\r
- niceFraction = 2;\r
- } else if (fraction < 7) {\r
- niceFraction = 5;\r
- } else {\r
- niceFraction = 10;\r
- }\r
- } else {\r
- if (fraction <= 1.0) {\r
- niceFraction = 1;\r
- } else if (fraction <= 2) {\r
- niceFraction = 2;\r
- } else if (fraction <= 5) {\r
- niceFraction = 5;\r
- } else {\r
- niceFraction = 10;\r
- }\r
- }\r
-\r
- return niceFraction * Math.pow(10, exponent);\r
- };\r
- //Easing functions adapted from Robert Penner's easing equations\r
- //http://www.robertpenner.com/easing/\r
- var easingEffects = helpers.easingEffects = {\r
- linear: function(t) {\r
- return t;\r
- },\r
- easeInQuad: function(t) {\r
- return t * t;\r
- },\r
- easeOutQuad: function(t) {\r
- return -1 * t * (t - 2);\r
- },\r
- easeInOutQuad: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t;\r
- }\r
- return -1 / 2 * ((--t) * (t - 2) - 1);\r
- },\r
- easeInCubic: function(t) {\r
- return t * t * t;\r
- },\r
- easeOutCubic: function(t) {\r
- return 1 * ((t = t / 1 - 1) * t * t + 1);\r
- },\r
- easeInOutCubic: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t * t;\r
- }\r
- return 1 / 2 * ((t -= 2) * t * t + 2);\r
- },\r
- easeInQuart: function(t) {\r
- return t * t * t * t;\r
- },\r
- easeOutQuart: function(t) {\r
- return -1 * ((t = t / 1 - 1) * t * t * t - 1);\r
- },\r
- easeInOutQuart: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t * t * t;\r
- }\r
- return -1 / 2 * ((t -= 2) * t * t * t - 2);\r
- },\r
- easeInQuint: function(t) {\r
- return 1 * (t /= 1) * t * t * t * t;\r
- },\r
- easeOutQuint: function(t) {\r
- return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\r
- },\r
- easeInOutQuint: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * t * t * t * t * t;\r
- }\r
- return 1 / 2 * ((t -= 2) * t * t * t * t + 2);\r
- },\r
- easeInSine: function(t) {\r
- return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\r
- },\r
- easeOutSine: function(t) {\r
- return 1 * Math.sin(t / 1 * (Math.PI / 2));\r
- },\r
- easeInOutSine: function(t) {\r
- return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\r
- },\r
- easeInExpo: function(t) {\r
- return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\r
- },\r
- easeOutExpo: function(t) {\r
- return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\r
- },\r
- easeInOutExpo: function(t) {\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if (t === 1) {\r
- return 1;\r
- }\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * Math.pow(2, 10 * (t - 1));\r
- }\r
- return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\r
- },\r
- easeInCirc: function(t) {\r
- if (t >= 1) {\r
- return t;\r
- }\r
- return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\r
- },\r
- easeOutCirc: function(t) {\r
- return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\r
- },\r
- easeInOutCirc: function(t) {\r
- if ((t /= 1 / 2) < 1) {\r
- return -1 / 2 * (Math.sqrt(1 - t * t) - 1);\r
- }\r
- return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\r
- },\r
- easeInElastic: function(t) {\r
- var s = 1.70158;\r
- var p = 0;\r
- var a = 1;\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if ((t /= 1) === 1) {\r
- return 1;\r
- }\r
- if (!p) {\r
- p = 1 * 0.3;\r
- }\r
- if (a < Math.abs(1)) {\r
- a = 1;\r
- s = p / 4;\r
- } else {\r
- s = p / (2 * Math.PI) * Math.asin(1 / a);\r
- }\r
- return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\r
- },\r
- easeOutElastic: function(t) {\r
- var s = 1.70158;\r
- var p = 0;\r
- var a = 1;\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if ((t /= 1) === 1) {\r
- return 1;\r
- }\r
- if (!p) {\r
- p = 1 * 0.3;\r
- }\r
- if (a < Math.abs(1)) {\r
- a = 1;\r
- s = p / 4;\r
- } else {\r
- s = p / (2 * Math.PI) * Math.asin(1 / a);\r
- }\r
- return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\r
- },\r
- easeInOutElastic: function(t) {\r
- var s = 1.70158;\r
- var p = 0;\r
- var a = 1;\r
- if (t === 0) {\r
- return 0;\r
- }\r
- if ((t /= 1 / 2) === 2) {\r
- return 1;\r
- }\r
- if (!p) {\r
- p = 1 * (0.3 * 1.5);\r
- }\r
- if (a < Math.abs(1)) {\r
- a = 1;\r
- s = p / 4;\r
- } else {\r
- s = p / (2 * Math.PI) * Math.asin(1 / a);\r
- }\r
- if (t < 1) {\r
- return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\r
- }\r
- return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\r
- },\r
- easeInBack: function(t) {\r
- var s = 1.70158;\r
- return 1 * (t /= 1) * t * ((s + 1) * t - s);\r
- },\r
- easeOutBack: function(t) {\r
- var s = 1.70158;\r
- return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\r
- },\r
- easeInOutBack: function(t) {\r
- var s = 1.70158;\r
- if ((t /= 1 / 2) < 1) {\r
- return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\r
- }\r
- return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\r
- },\r
- easeInBounce: function(t) {\r
- return 1 - easingEffects.easeOutBounce(1 - t);\r
- },\r
- easeOutBounce: function(t) {\r
- if ((t /= 1) < (1 / 2.75)) {\r
- return 1 * (7.5625 * t * t);\r
- } else if (t < (2 / 2.75)) {\r
- return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\r
- } else if (t < (2.5 / 2.75)) {\r
- return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\r
- } else {\r
- return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\r
- }\r
- },\r
- easeInOutBounce: function(t) {\r
- if (t < 1 / 2) {\r
- return easingEffects.easeInBounce(t * 2) * 0.5;\r
- }\r
- return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\r
- }\r
- };\r
- //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\r
- helpers.requestAnimFrame = (function() {\r
- return window.requestAnimationFrame ||\r
- window.webkitRequestAnimationFrame ||\r
- window.mozRequestAnimationFrame ||\r
- window.oRequestAnimationFrame ||\r
- window.msRequestAnimationFrame ||\r
- function(callback) {\r
- return window.setTimeout(callback, 1000 / 60);\r
- };\r
- })();\r
- helpers.cancelAnimFrame = (function() {\r
- return window.cancelAnimationFrame ||\r
- window.webkitCancelAnimationFrame ||\r
- window.mozCancelAnimationFrame ||\r
- window.oCancelAnimationFrame ||\r
- window.msCancelAnimationFrame ||\r
- function(callback) {\r
- return window.clearTimeout(callback, 1000 / 60);\r
- };\r
- })();\r
- //-- DOM methods\r
- helpers.getRelativePosition = function(evt, chart) {\r
- var mouseX, mouseY;\r
- var e = evt.originalEvent || evt,\r
- canvas = evt.currentTarget || evt.srcElement,\r
- boundingRect = canvas.getBoundingClientRect();\r
-\r
- var touches = e.touches;\r
- if (touches && touches.length > 0) {\r
- mouseX = touches[0].clientX;\r
- mouseY = touches[0].clientY;\r
-\r
- } else {\r
- mouseX = e.clientX;\r
- mouseY = e.clientY;\r
- }\r
-\r
- // Scale mouse coordinates into canvas coordinates\r
- // by following the pattern laid out by 'jerryj' in the comments of\r
- // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/\r
- var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));\r
- var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));\r
- var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));\r
- var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));\r
- var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;\r
- var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;\r
-\r
- // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However\r
- // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here\r
- mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);\r
- mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);\r
-\r
- return {\r
- x: mouseX,\r
- y: mouseY\r
- };\r
-\r
- };\r
- helpers.addEvent = function(node, eventType, method) {\r
- if (node.addEventListener) {\r
- node.addEventListener(eventType, method);\r
- } else if (node.attachEvent) {\r
- node.attachEvent("on" + eventType, method);\r
- } else {\r
- node["on" + eventType] = method;\r
- }\r
- };\r
- helpers.removeEvent = function(node, eventType, handler) {\r
- if (node.removeEventListener) {\r
- node.removeEventListener(eventType, handler, false);\r
- } else if (node.detachEvent) {\r
- node.detachEvent("on" + eventType, handler);\r
- } else {\r
- node["on" + eventType] = helpers.noop;\r
- }\r
- };\r
- helpers.bindEvents = function(chartInstance, arrayOfEvents, handler) {\r
- // Create the events object if it's not already present\r
- var events = chartInstance.events = chartInstance.events || {};\r
-\r
- helpers.each(arrayOfEvents, function(eventName) {\r
- events[eventName] = function() {\r
- handler.apply(chartInstance, arguments);\r
- };\r
- helpers.addEvent(chartInstance.chart.canvas, eventName, events[eventName]);\r
- });\r
- };\r
- helpers.unbindEvents = function(chartInstance, arrayOfEvents) {\r
- var canvas = chartInstance.chart.canvas;\r
- helpers.each(arrayOfEvents, function(handler, eventName) {\r
- helpers.removeEvent(canvas, eventName, handler);\r
- });\r
- };\r
-\r
- // Private helper function to convert max-width/max-height values that may be percentages into a number\r
- function parseMaxStyle(styleValue, node, parentProperty) {\r
- var valueInPixels;\r
- if (typeof(styleValue) === 'string') {\r
- valueInPixels = parseInt(styleValue, 10);\r
-\r
- if (styleValue.indexOf('%') != -1) {\r
- // percentage * size in dimension\r
- valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\r
- }\r
- } else {\r
- valueInPixels = styleValue;\r
- }\r
-\r
- return valueInPixels;\r
- }\r
-\r
- /**\r
- * Returns if the given value contains an effective constraint.\r
- * @private\r
- */\r
- function isConstrainedValue(value) {\r
- return value !== undefined && value !== null && value !== 'none';\r
- }\r
-\r
- // Private helper to get a constraint dimension\r
- // @param domNode : the node to check the constraint on\r
- // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)\r
- // @param percentageProperty : property of parent to use when calculating width as a percentage\r
- // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser\r
- function getConstraintDimension(domNode, maxStyle, percentageProperty) {\r
- var view = document.defaultView;\r
- var parentNode = domNode.parentNode;\r
- var constrainedNode = view.getComputedStyle(domNode)[maxStyle];\r
- var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];\r
- var hasCNode = isConstrainedValue(constrainedNode);\r
- var hasCContainer = isConstrainedValue(constrainedContainer);\r
- var infinity = Number.POSITIVE_INFINITY;\r
-\r
- if (hasCNode || hasCContainer) {\r
- return Math.min(\r
- hasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,\r
- hasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);\r
- }\r
-\r
- return 'none';\r
- }\r
- // returns Number or undefined if no constraint\r
- helpers.getConstraintWidth = function(domNode) {\r
- return getConstraintDimension(domNode, 'max-width', 'clientWidth');\r
- };\r
- // returns Number or undefined if no constraint\r
- helpers.getConstraintHeight = function(domNode) {\r
- return getConstraintDimension(domNode, 'max-height', 'clientHeight');\r
- };\r
- helpers.getMaximumWidth = function(domNode) {\r
- var container = domNode.parentNode;\r
- var padding = parseInt(helpers.getStyle(container, 'padding-left')) + parseInt(helpers.getStyle(container, 'padding-right'));\r
- var w = container.clientWidth - padding;\r
- var cw = helpers.getConstraintWidth(domNode);\r
- return isNaN(cw)? w : Math.min(w, cw);\r
- };\r
- helpers.getMaximumHeight = function(domNode) {\r
- var container = domNode.parentNode;\r
- var padding = parseInt(helpers.getStyle(container, 'padding-top')) + parseInt(helpers.getStyle(container, 'padding-bottom'));\r
- var h = container.clientHeight - padding;\r
- var ch = helpers.getConstraintHeight(domNode);\r
- return isNaN(ch)? h : Math.min(h, ch);\r
- };\r
- helpers.getStyle = function(el, property) {\r
- return el.currentStyle ?\r
- el.currentStyle[property] :\r
- document.defaultView.getComputedStyle(el, null).getPropertyValue(property);\r
- };\r
- helpers.retinaScale = function(chart) {\r
- var ctx = chart.ctx;\r
- var canvas = chart.canvas;\r
- var width = canvas.width;\r
- var height = canvas.height;\r
- var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;\r
-\r
- if (pixelRatio !== 1) {\r
- canvas.height = height * pixelRatio;\r
- canvas.width = width * pixelRatio;\r
- ctx.scale(pixelRatio, pixelRatio);\r
-\r
- // Store the device pixel ratio so that we can go backwards in `destroy`.\r
- // The devicePixelRatio changes with zoom, so there are no guarantees that it is the same\r
- // when destroy is called\r
- chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || pixelRatio;\r
- }\r
-\r
- canvas.style.width = width + 'px';\r
- canvas.style.height = height + 'px';\r
- };\r
- //-- Canvas methods\r
- helpers.clear = function(chart) {\r
- chart.ctx.clearRect(0, 0, chart.width, chart.height);\r
- };\r
- helpers.fontString = function(pixelSize, fontStyle, fontFamily) {\r
- return fontStyle + " " + pixelSize + "px " + fontFamily;\r
- };\r
- helpers.longestText = function(ctx, font, arrayOfThings, cache) {\r
- cache = cache || {};\r
- var data = cache.data = cache.data || {};\r
- var gc = cache.garbageCollect = cache.garbageCollect || [];\r
-\r
- if (cache.font !== font) {\r
- data = cache.data = {};\r
- gc = cache.garbageCollect = [];\r
- cache.font = font;\r
- }\r
-\r
- ctx.font = font;\r
- var longest = 0;\r
- helpers.each(arrayOfThings, function(thing) {\r
- // Undefined strings and arrays should not be measured\r
- if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {\r
- longest = helpers.measureText(ctx, data, gc, longest, thing);\r
- } else if (helpers.isArray(thing)) {\r
- // if it is an array lets measure each element\r
- // to do maybe simplify this function a bit so we can do this more recursively?\r
- helpers.each(thing, function(nestedThing) {\r
- // Undefined strings and arrays should not be measured\r
- if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {\r
- longest = helpers.measureText(ctx, data, gc, longest, nestedThing);\r
- }\r
- });\r
- }\r
- });\r
-\r
- var gcLen = gc.length / 2;\r
- if (gcLen > arrayOfThings.length) {\r
- for (var i = 0; i < gcLen; i++) {\r
- delete data[gc[i]];\r
- }\r
- gc.splice(0, gcLen);\r
- }\r
- return longest;\r
- };\r
- helpers.measureText = function (ctx, data, gc, longest, string) {\r
- var textWidth = data[string];\r
- if (!textWidth) {\r
- textWidth = data[string] = ctx.measureText(string).width;\r
- gc.push(string);\r
- }\r
- if (textWidth > longest) {\r
- longest = textWidth;\r
- }\r
- return longest;\r
- };\r
- helpers.numberOfLabelLines = function(arrayOfThings) {\r
- var numberOfLines = 1;\r
- helpers.each(arrayOfThings, function(thing) {\r
- if (helpers.isArray(thing)) {\r
- if (thing.length > numberOfLines) {\r
- numberOfLines = thing.length;\r
- }\r
- }\r
- });\r
- return numberOfLines;\r
- };\r
- helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {\r
- ctx.beginPath();\r
- ctx.moveTo(x + radius, y);\r
- ctx.lineTo(x + width - radius, y);\r
- ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\r
- ctx.lineTo(x + width, y + height - radius);\r
- ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\r
- ctx.lineTo(x + radius, y + height);\r
- ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\r
- ctx.lineTo(x, y + radius);\r
- ctx.quadraticCurveTo(x, y, x + radius, y);\r
- ctx.closePath();\r
- };\r
- helpers.color = function(c) {\r
- if (!color) {\r
- console.log('Color.js not found!');\r
- return c;\r
- }\r
-\r
- /* global CanvasGradient */\r
- if (c instanceof CanvasGradient) {\r
- return color(Chart.defaults.global.defaultColor);\r
- }\r
-\r
- return color(c);\r
- };\r
- helpers.addResizeListener = function(node, callback) {\r
- // Hide an iframe before the node\r
- var hiddenIframe = document.createElement('iframe');\r
- var hiddenIframeClass = 'chartjs-hidden-iframe';\r
-\r
- if (hiddenIframe.classlist) {\r
- // can use classlist\r
- hiddenIframe.classlist.add(hiddenIframeClass);\r
- } else {\r
- hiddenIframe.setAttribute('class', hiddenIframeClass);\r
- }\r
-\r
- // Set the style\r
- var style = hiddenIframe.style;\r
- style.width = '100%';\r
- style.display = 'block';\r
- style.border = 0;\r
- style.height = 0;\r
- style.margin = 0;\r
- style.position = 'absolute';\r
- style.left = 0;\r
- style.right = 0;\r
- style.top = 0;\r
- style.bottom = 0;\r
-\r
- // Insert the iframe so that contentWindow is available\r
- node.insertBefore(hiddenIframe, node.firstChild);\r
-\r
- (hiddenIframe.contentWindow || hiddenIframe).onresize = function() {\r
- if (callback) {\r
- callback();\r
- }\r
- };\r
- };\r
- helpers.removeResizeListener = function(node) {\r
- var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');\r
-\r
- // Remove the resize detect iframe\r
- if (hiddenIframe) {\r
- hiddenIframe.parentNode.removeChild(hiddenIframe);\r
- }\r
- };\r
- helpers.isArray = Array.isArray?\r
- function(obj) { return Array.isArray(obj); } :\r
- function(obj) {\r
- return Object.prototype.toString.call(obj) === '[object Array]';\r
- };\r
- //! @see http://stackoverflow.com/a/14853974\r
- helpers.arrayEquals = function(a0, a1) {\r
- var i, ilen, v0, v1;\r
-\r
- if (!a0 || !a1 || a0.length != a1.length) {\r
- return false;\r
- }\r
-\r
- for (i = 0, ilen=a0.length; i < ilen; ++i) {\r
- v0 = a0[i];\r
- v1 = a1[i];\r
-\r
- if (v0 instanceof Array && v1 instanceof Array) {\r
- if (!helpers.arrayEquals(v0, v1)) {\r
- return false;\r
- }\r
- } else if (v0 != v1) {\r
- // NOTE: two different object instances will never be equal: {x:20} != {x:20}\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
- };\r
- helpers.callCallback = function(fn, args, _tArg) {\r
- if (fn && typeof fn.call === 'function') {\r
- fn.apply(_tArg, args);\r
- }\r
- };\r
- helpers.getHoverColor = function(color) {\r
- /* global CanvasPattern */\r
- return (color instanceof CanvasPattern) ?\r
- color :\r
- helpers.color(color).saturate(0.5).darken(0.1).rgbString();\r
- };\r
-};\r
-
-},{"3":3}],26:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function() {\r
-\r
- //Occupy the global variable of Chart, and create a simple base class\r
- var Chart = function(context, config) {\r
- var me = this;\r
- var helpers = Chart.helpers;\r
- me.config = config;\r
-\r
- // Support a jQuery'd canvas element\r
- if (context.length && context[0].getContext) {\r
- context = context[0];\r
- }\r
-\r
- // Support a canvas domnode\r
- if (context.getContext) {\r
- context = context.getContext("2d");\r
- }\r
-\r
- me.ctx = context;\r
- me.canvas = context.canvas;\r
-\r
- context.canvas.style.display = context.canvas.style.display || 'block';\r
-\r
- // Figure out what the size of the chart will be.\r
- // If the canvas has a specified width and height, we use those else\r
- // we look to see if the canvas node has a CSS width and height.\r
- // If there is still no height, fill the parent container\r
- me.width = context.canvas.width || parseInt(helpers.getStyle(context.canvas, 'width'), 10) || helpers.getMaximumWidth(context.canvas);\r
- me.height = context.canvas.height || parseInt(helpers.getStyle(context.canvas, 'height'), 10) || helpers.getMaximumHeight(context.canvas);\r
-\r
- me.aspectRatio = me.width / me.height;\r
-\r
- if (isNaN(me.aspectRatio) || isFinite(me.aspectRatio) === false) {\r
- // If the canvas has no size, try and figure out what the aspect ratio will be.\r
- // Some charts prefer square canvases (pie, radar, etc). If that is specified, use that\r
- // else use the canvas default ratio of 2\r
- me.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;\r
- }\r
-\r
- // Store the original style of the element so we can set it back\r
- me.originalCanvasStyleWidth = context.canvas.style.width;\r
- me.originalCanvasStyleHeight = context.canvas.style.height;\r
-\r
- // High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.\r
- helpers.retinaScale(me);\r
-\r
- if (config) {\r
- me.controller = new Chart.Controller(me);\r
- }\r
-\r
- // Always bind this so that if the responsive state changes we still work\r
- helpers.addResizeListener(context.canvas.parentNode, function() {\r
- if (me.controller && me.controller.config.options.responsive) {\r
- me.controller.resize();\r
- }\r
- });\r
-\r
- return me.controller ? me.controller : me;\r
-\r
- };\r
-\r
- //Globally expose the defaults to allow for user updating/changing\r
- Chart.defaults = {\r
- global: {\r
- responsive: true,\r
- responsiveAnimationDuration: 0,\r
- maintainAspectRatio: true,\r
- events: ["mousemove", "mouseout", "click", "touchstart", "touchmove"],\r
- hover: {\r
- onHover: null,\r
- mode: 'single',\r
- animationDuration: 400\r
- },\r
- onClick: null,\r
- defaultColor: 'rgba(0,0,0,0.1)',\r
- defaultFontColor: '#666',\r
- defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",\r
- defaultFontSize: 12,\r
- defaultFontStyle: 'normal',\r
- showLines: true,\r
-\r
- // Element defaults defined in element extensions\r
- elements: {},\r
-\r
- // Legend callback string\r
- legendCallback: function(chart) {\r
- var text = [];\r
- text.push('<ul class="' + chart.id + '-legend">');\r
- for (var i = 0; i < chart.data.datasets.length; i++) {\r
- text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>');\r
- if (chart.data.datasets[i].label) {\r
- text.push(chart.data.datasets[i].label);\r
- }\r
- text.push('</li>');\r
- }\r
- text.push('</ul>');\r
-\r
- return text.join("");\r
- }\r
- }\r
- };\r
-\r
- Chart.Chart = Chart;\r
-\r
- return Chart;\r
-\r
-};\r
-
-},{}],27:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- // The layout service is very self explanatory. It's responsible for the layout within a chart.\r
- // Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\r
- // It is this service's responsibility of carrying out that layout.\r
- Chart.layoutService = {\r
- defaults: {},\r
-\r
- // Register a box to a chartInstance. A box is simply a reference to an object that requires layout. eg. Scales, Legend, Plugins.\r
- addBox: function(chartInstance, box) {\r
- if (!chartInstance.boxes) {\r
- chartInstance.boxes = [];\r
- }\r
- chartInstance.boxes.push(box);\r
- },\r
-\r
- removeBox: function(chartInstance, box) {\r
- if (!chartInstance.boxes) {\r
- return;\r
- }\r
- chartInstance.boxes.splice(chartInstance.boxes.indexOf(box), 1);\r
- },\r
-\r
- // The most important function\r
- update: function(chartInstance, width, height) {\r
-\r
- if (!chartInstance) {\r
- return;\r
- }\r
-\r
- var xPadding = 0;\r
- var yPadding = 0;\r
-\r
- var leftBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "left";\r
- });\r
- var rightBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "right";\r
- });\r
- var topBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "top";\r
- });\r
- var bottomBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "bottom";\r
- });\r
-\r
- // Boxes that overlay the chartarea such as the radialLinear scale\r
- var chartAreaBoxes = helpers.where(chartInstance.boxes, function(box) {\r
- return box.options.position === "chartArea";\r
- });\r
-\r
- // Ensure that full width boxes are at the very top / bottom\r
- topBoxes.sort(function(a, b) {\r
- return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0);\r
- });\r
- bottomBoxes.sort(function(a, b) {\r
- return (a.options.fullWidth ? 1 : 0) - (b.options.fullWidth ? 1 : 0);\r
- });\r
-\r
- // Essentially we now have any number of boxes on each of the 4 sides.\r
- // Our canvas looks like the following.\r
- // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\r
- // B1 is the bottom axis\r
- // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\r
- // These locations are single-box locations only, when trying to register a chartArea location that is already taken,\r
- // an error will be thrown.\r
- //\r
- // |----------------------------------------------------|\r
- // | T1 (Full Width) |\r
- // |----------------------------------------------------|\r
- // | | | T2 | |\r
- // | |----|-------------------------------------|----|\r
- // | | | C1 | | C2 | |\r
- // | | |----| |----| |\r
- // | | | | |\r
- // | L1 | L2 | ChartArea (C0) | R1 |\r
- // | | | | |\r
- // | | |----| |----| |\r
- // | | | C3 | | C4 | |\r
- // | |----|-------------------------------------|----|\r
- // | | | B1 | |\r
- // |----------------------------------------------------|\r
- // | B2 (Full Width) |\r
- // |----------------------------------------------------|\r
- //\r
- // What we do to find the best sizing, we do the following\r
- // 1. Determine the minimum size of the chart area.\r
- // 2. Split the remaining width equally between each vertical axis\r
- // 3. Split the remaining height equally between each horizontal axis\r
- // 4. Give each layout the maximum size it can be. The layout will return it's minimum size\r
- // 5. Adjust the sizes of each axis based on it's minimum reported size.\r
- // 6. Refit each axis\r
- // 7. Position each axis in the final location\r
- // 8. Tell the chart the final location of the chart area\r
- // 9. Tell any axes that overlay the chart area the positions of the chart area\r
-\r
- // Step 1\r
- var chartWidth = width - (2 * xPadding);\r
- var chartHeight = height - (2 * yPadding);\r
- var chartAreaWidth = chartWidth / 2; // min 50%\r
- var chartAreaHeight = chartHeight / 2; // min 50%\r
-\r
- // Step 2\r
- var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);\r
-\r
- // Step 3\r
- var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);\r
-\r
- // Step 4\r
- var maxChartAreaWidth = chartWidth;\r
- var maxChartAreaHeight = chartHeight;\r
- var minBoxSizes = [];\r
-\r
- helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);\r
-\r
- function getMinimumBoxSize(box) {\r
- var minSize;\r
- var isHorizontal = box.isHorizontal();\r
-\r
- if (isHorizontal) {\r
- minSize = box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);\r
- maxChartAreaHeight -= minSize.height;\r
- } else {\r
- minSize = box.update(verticalBoxWidth, chartAreaHeight);\r
- maxChartAreaWidth -= minSize.width;\r
- }\r
-\r
- minBoxSizes.push({\r
- horizontal: isHorizontal,\r
- minSize: minSize,\r
- box: box\r
- });\r
- }\r
-\r
- // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could\r
- // be if the axes are drawn at their minimum sizes.\r
-\r
- // Steps 5 & 6\r
- var totalLeftBoxesWidth = xPadding;\r
- var totalRightBoxesWidth = xPadding;\r
- var totalTopBoxesHeight = yPadding;\r
- var totalBottomBoxesHeight = yPadding;\r
-\r
- // Update, and calculate the left and right margins for the horizontal boxes\r
- helpers.each(leftBoxes.concat(rightBoxes), fitBox);\r
-\r
- helpers.each(leftBoxes, function(box) {\r
- totalLeftBoxesWidth += box.width;\r
- });\r
-\r
- helpers.each(rightBoxes, function(box) {\r
- totalRightBoxesWidth += box.width;\r
- });\r
-\r
- // Set the Left and Right margins for the horizontal boxes\r
- helpers.each(topBoxes.concat(bottomBoxes), fitBox);\r
-\r
- // Function to fit a box\r
- function fitBox(box) {\r
- var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {\r
- return minBoxSize.box === box;\r
- });\r
-\r
- if (minBoxSize) {\r
- if (box.isHorizontal()) {\r
- var scaleMargin = {\r
- left: totalLeftBoxesWidth,\r
- right: totalRightBoxesWidth,\r
- top: 0,\r
- bottom: 0\r
- };\r
-\r
- // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends\r
- // on the margin. Sometimes they need to increase in size slightly\r
- box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);\r
- } else {\r
- box.update(minBoxSize.minSize.width, maxChartAreaHeight);\r
- }\r
- }\r
- }\r
-\r
- // Figure out how much margin is on the top and bottom of the vertical boxes\r
- helpers.each(topBoxes, function(box) {\r
- totalTopBoxesHeight += box.height;\r
- });\r
-\r
- helpers.each(bottomBoxes, function(box) {\r
- totalBottomBoxesHeight += box.height;\r
- });\r
-\r
- // Let the left layout know the final margin\r
- helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);\r
-\r
- function finalFitVerticalBox(box) {\r
- var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {\r
- return minBoxSize.box === box;\r
- });\r
-\r
- var scaleMargin = {\r
- left: 0,\r
- right: 0,\r
- top: totalTopBoxesHeight,\r
- bottom: totalBottomBoxesHeight\r
- };\r
-\r
- if (minBoxSize) {\r
- box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);\r
- }\r
- }\r
-\r
- // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)\r
- totalLeftBoxesWidth = xPadding;\r
- totalRightBoxesWidth = xPadding;\r
- totalTopBoxesHeight = yPadding;\r
- totalBottomBoxesHeight = yPadding;\r
-\r
- helpers.each(leftBoxes, function(box) {\r
- totalLeftBoxesWidth += box.width;\r
- });\r
-\r
- helpers.each(rightBoxes, function(box) {\r
- totalRightBoxesWidth += box.width;\r
- });\r
-\r
- helpers.each(topBoxes, function(box) {\r
- totalTopBoxesHeight += box.height;\r
- });\r
- helpers.each(bottomBoxes, function(box) {\r
- totalBottomBoxesHeight += box.height;\r
- });\r
-\r
- // Figure out if our chart area changed. This would occur if the dataset layout label rotation\r
- // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do\r
- // without calling `fit` again\r
- var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;\r
- var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;\r
-\r
- if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {\r
- helpers.each(leftBoxes, function(box) {\r
- box.height = newMaxChartAreaHeight;\r
- });\r
-\r
- helpers.each(rightBoxes, function(box) {\r
- box.height = newMaxChartAreaHeight;\r
- });\r
-\r
- helpers.each(topBoxes, function(box) {\r
- if (!box.options.fullWidth) {\r
- box.width = newMaxChartAreaWidth;\r
- }\r
- });\r
-\r
- helpers.each(bottomBoxes, function(box) {\r
- if (!box.options.fullWidth) {\r
- box.width = newMaxChartAreaWidth;\r
- }\r
- });\r
-\r
- maxChartAreaHeight = newMaxChartAreaHeight;\r
- maxChartAreaWidth = newMaxChartAreaWidth;\r
- }\r
-\r
- // Step 7 - Position the boxes\r
- var left = xPadding;\r
- var top = yPadding;\r
- var right = 0;\r
- var bottom = 0;\r
-\r
- helpers.each(leftBoxes.concat(topBoxes), placeBox);\r
-\r
- // Account for chart width and height\r
- left += maxChartAreaWidth;\r
- top += maxChartAreaHeight;\r
-\r
- helpers.each(rightBoxes, placeBox);\r
- helpers.each(bottomBoxes, placeBox);\r
-\r
- function placeBox(box) {\r
- if (box.isHorizontal()) {\r
- box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;\r
- box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth;\r
- box.top = top;\r
- box.bottom = top + box.height;\r
-\r
- // Move to next point\r
- top = box.bottom;\r
-\r
- } else {\r
-\r
- box.left = left;\r
- box.right = left + box.width;\r
- box.top = totalTopBoxesHeight;\r
- box.bottom = totalTopBoxesHeight + maxChartAreaHeight;\r
-\r
- // Move to next point\r
- left = box.right;\r
- }\r
- }\r
-\r
- // Step 8\r
- chartInstance.chartArea = {\r
- left: totalLeftBoxesWidth,\r
- top: totalTopBoxesHeight,\r
- right: totalLeftBoxesWidth + maxChartAreaWidth,\r
- bottom: totalTopBoxesHeight + maxChartAreaHeight\r
- };\r
-\r
- // Step 9\r
- helpers.each(chartAreaBoxes, function(box) {\r
- box.left = chartInstance.chartArea.left;\r
- box.top = chartInstance.chartArea.top;\r
- box.right = chartInstance.chartArea.right;\r
- box.bottom = chartInstance.chartArea.bottom;\r
-\r
- box.update(maxChartAreaWidth, maxChartAreaHeight);\r
- });\r
- }\r
- };\r
-};\r
-
-},{}],28:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var noop = helpers.noop;\r
-\r
- Chart.defaults.global.legend = {\r
-\r
- display: true,\r
- position: 'top',\r
- fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)\r
- reverse: false,\r
-\r
- // a callback that will handle\r
- onClick: function(e, legendItem) {\r
- var index = legendItem.datasetIndex;\r
- var ci = this.chart;\r
- var meta = ci.getDatasetMeta(index);\r
-\r
- // See controller.isDatasetVisible comment\r
- meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;\r
-\r
- // We hid a dataset ... rerender the chart\r
- ci.update();\r
- },\r
-\r
- labels: {\r
- boxWidth: 40,\r
- padding: 10,\r
- // Generates labels shown in the legend\r
- // Valid properties to return:\r
- // text : text to display\r
- // fillStyle : fill of coloured box\r
- // strokeStyle: stroke of coloured box\r
- // hidden : if this legend item refers to a hidden item\r
- // lineCap : cap style for line\r
- // lineDash\r
- // lineDashOffset :\r
- // lineJoin :\r
- // lineWidth :\r
- generateLabels: function(chart) {\r
- var data = chart.data;\r
- return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {\r
- return {\r
- text: dataset.label,\r
- fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),\r
- hidden: !chart.isDatasetVisible(i),\r
- lineCap: dataset.borderCapStyle,\r
- lineDash: dataset.borderDash,\r
- lineDashOffset: dataset.borderDashOffset,\r
- lineJoin: dataset.borderJoinStyle,\r
- lineWidth: dataset.borderWidth,\r
- strokeStyle: dataset.borderColor,\r
-\r
- // Below is extra data used for toggling the datasets\r
- datasetIndex: i\r
- };\r
- }, this) : [];\r
- }\r
- }\r
- };\r
-\r
- Chart.Legend = Chart.Element.extend({\r
-\r
- initialize: function(config) {\r
- helpers.extend(this, config);\r
-\r
- // Contains hit boxes for each dataset (in dataset order)\r
- this.legendHitBoxes = [];\r
-\r
- // Are we in doughnut mode which has a different data type\r
- this.doughnutMode = false;\r
- },\r
-\r
- // These methods are ordered by lifecyle. Utilities then follow.\r
- // Any function defined here is inherited by all legend types.\r
- // Any function can be extended by the legend type\r
-\r
- beforeUpdate: noop,\r
- update: function(maxWidth, maxHeight, margins) {\r
- var me = this;\r
-\r
- // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r
- me.beforeUpdate();\r
-\r
- // Absorb the master measurements\r
- me.maxWidth = maxWidth;\r
- me.maxHeight = maxHeight;\r
- me.margins = margins;\r
-\r
- // Dimensions\r
- me.beforeSetDimensions();\r
- me.setDimensions();\r
- me.afterSetDimensions();\r
- // Labels\r
- me.beforeBuildLabels();\r
- me.buildLabels();\r
- me.afterBuildLabels();\r
-\r
- // Fit\r
- me.beforeFit();\r
- me.fit();\r
- me.afterFit();\r
- //\r
- me.afterUpdate();\r
-\r
- return me.minSize;\r
- },\r
- afterUpdate: noop,\r
-\r
- //\r
-\r
- beforeSetDimensions: noop,\r
- setDimensions: function() {\r
- var me = this;\r
- // Set the unconstrained dimension before label rotation\r
- if (me.isHorizontal()) {\r
- // Reset position before calculating rotation\r
- me.width = me.maxWidth;\r
- me.left = 0;\r
- me.right = me.width;\r
- } else {\r
- me.height = me.maxHeight;\r
-\r
- // Reset position before calculating rotation\r
- me.top = 0;\r
- me.bottom = me.height;\r
- }\r
-\r
- // Reset padding\r
- me.paddingLeft = 0;\r
- me.paddingTop = 0;\r
- me.paddingRight = 0;\r
- me.paddingBottom = 0;\r
-\r
- // Reset minSize\r
- me.minSize = {\r
- width: 0,\r
- height: 0\r
- };\r
- },\r
- afterSetDimensions: noop,\r
-\r
- //\r
-\r
- beforeBuildLabels: noop,\r
- buildLabels: function() {\r
- var me = this;\r
- me.legendItems = me.options.labels.generateLabels.call(me, me.chart);\r
- if(me.options.reverse){\r
- me.legendItems.reverse();\r
- }\r
- },\r
- afterBuildLabels: noop,\r
-\r
- //\r
-\r
- beforeFit: noop,\r
- fit: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var labelOpts = opts.labels;\r
- var display = opts.display;\r
-\r
- var ctx = me.ctx;\r
-\r
- var globalDefault = Chart.defaults.global,\r
- itemOrDefault = helpers.getValueOrDefault,\r
- fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\r
- fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\r
- fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\r
- labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\r
-\r
- // Reset hit boxes\r
- var hitboxes = me.legendHitBoxes = [];\r
-\r
- var minSize = me.minSize;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- if (isHorizontal) {\r
- minSize.width = me.maxWidth; // fill all the width\r
- minSize.height = display ? 10 : 0;\r
- } else {\r
- minSize.width = display ? 10 : 0;\r
- minSize.height = me.maxHeight; // fill all the height\r
- }\r
-\r
- // Increase sizes here\r
- if (display) {\r
- ctx.font = labelFont;\r
-\r
- if (isHorizontal) {\r
- // Labels\r
-\r
- // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one\r
- var lineWidths = me.lineWidths = [0];\r
- var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;\r
-\r
- ctx.textAlign = "left";\r
- ctx.textBaseline = 'top';\r
-\r
- helpers.each(me.legendItems, function(legendItem, i) {\r
- var width = labelOpts.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\r
- if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {\r
- totalHeight += fontSize + (labelOpts.padding);\r
- lineWidths[lineWidths.length] = me.left;\r
- }\r
-\r
- // Store the hitbox width and height here. Final position will be updated in `draw`\r
- hitboxes[i] = {\r
- left: 0,\r
- top: 0,\r
- width: width,\r
- height: fontSize\r
- };\r
-\r
- lineWidths[lineWidths.length - 1] += width + labelOpts.padding;\r
- });\r
-\r
- minSize.height += totalHeight;\r
-\r
- } else {\r
- var vPadding = labelOpts.padding;\r
- var columnWidths = me.columnWidths = [];\r
- var totalWidth = labelOpts.padding;\r
- var currentColWidth = 0;\r
- var currentColHeight = 0;\r
- var itemHeight = fontSize + vPadding;\r
-\r
- helpers.each(me.legendItems, function(legendItem, i) {\r
- var itemWidth = labelOpts.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\r
-\r
- // If too tall, go to new column\r
- if (currentColHeight + itemHeight > minSize.height) {\r
- totalWidth += currentColWidth + labelOpts.padding;\r
- columnWidths.push(currentColWidth); // previous column width\r
-\r
- currentColWidth = 0;\r
- currentColHeight = 0;\r
- }\r
-\r
- // Get max width\r
- currentColWidth = Math.max(currentColWidth, itemWidth);\r
- currentColHeight += itemHeight;\r
-\r
- // Store the hitbox width and height here. Final position will be updated in `draw`\r
- hitboxes[i] = {\r
- left: 0,\r
- top: 0,\r
- width: itemWidth,\r
- height: fontSize\r
- };\r
- });\r
-\r
- totalWidth += currentColWidth;\r
- columnWidths.push(currentColWidth);\r
- minSize.width += totalWidth;\r
- }\r
- }\r
-\r
- me.width = minSize.width;\r
- me.height = minSize.height;\r
- },\r
- afterFit: noop,\r
-\r
- // Shared Methods\r
- isHorizontal: function() {\r
- return this.options.position === "top" || this.options.position === "bottom";\r
- },\r
-\r
- // Actualy draw the legend on the canvas\r
- draw: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var labelOpts = opts.labels;\r
- var globalDefault = Chart.defaults.global,\r
- lineDefault = globalDefault.elements.line,\r
- legendWidth = me.width,\r
- legendHeight = me.height,\r
- lineWidths = me.lineWidths;\r
-\r
- if (opts.display) {\r
- var ctx = me.ctx,\r
- cursor,\r
- itemOrDefault = helpers.getValueOrDefault,\r
- fontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),\r
- fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\r
- fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\r
- fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\r
- labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\r
-\r
- // Canvas setup\r
- ctx.textAlign = "left";\r
- ctx.textBaseline = 'top';\r
- ctx.lineWidth = 0.5;\r
- ctx.strokeStyle = fontColor; // for strikethrough effect\r
- ctx.fillStyle = fontColor; // render in correct colour\r
- ctx.font = labelFont;\r
-\r
- var boxWidth = labelOpts.boxWidth,\r
- hitboxes = me.legendHitBoxes;\r
-\r
- // current position\r
- var drawLegendBox = function(x, y, legendItem) {\r
- // Set the ctx for the box\r
- ctx.save();\r
-\r
- ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);\r
- ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);\r
- ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);\r
- ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);\r
- ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);\r
- ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);\r
-\r
- if (ctx.setLineDash) {\r
- // IE 9 and 10 do not support line dash\r
- ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));\r
- }\r
-\r
- // Draw the box\r
- ctx.strokeRect(x, y, boxWidth, fontSize);\r
- ctx.fillRect(x, y, boxWidth, fontSize);\r
-\r
- ctx.restore();\r
- };\r
- var fillText = function(x, y, legendItem, textWidth) {\r
- ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);\r
-\r
- if (legendItem.hidden) {\r
- // Strikethrough the text if hidden\r
- ctx.beginPath();\r
- ctx.lineWidth = 2;\r
- ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));\r
- ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));\r
- ctx.stroke();\r
- }\r
- };\r
-\r
- // Horizontal\r
- var isHorizontal = me.isHorizontal();\r
- if (isHorizontal) {\r
- cursor = {\r
- x: me.left + ((legendWidth - lineWidths[0]) / 2),\r
- y: me.top + labelOpts.padding,\r
- line: 0\r
- };\r
- } else {\r
- cursor = {\r
- x: me.left + labelOpts.padding,\r
- y: me.top,\r
- line: 0\r
- };\r
- }\r
-\r
- var itemHeight = fontSize + labelOpts.padding;\r
- helpers.each(me.legendItems, function(legendItem, i) {\r
- var textWidth = ctx.measureText(legendItem.text).width,\r
- width = boxWidth + (fontSize / 2) + textWidth,\r
- x = cursor.x,\r
- y = cursor.y;\r
-\r
- if (isHorizontal) {\r
- if (x + width >= legendWidth) {\r
- y = cursor.y += fontSize + (labelOpts.padding);\r
- cursor.line++;\r
- x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);\r
- }\r
- } else {\r
- if (y + itemHeight > me.bottom) {\r
- x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;\r
- y = cursor.y = me.top;\r
- cursor.line++;\r
- }\r
- }\r
- \r
-\r
- drawLegendBox(x, y, legendItem);\r
-\r
- hitboxes[i].left = x;\r
- hitboxes[i].top = y;\r
-\r
- // Fill the actual label\r
- fillText(x, y, legendItem, textWidth);\r
-\r
- if (isHorizontal) {\r
- cursor.x += width + (labelOpts.padding);\r
- } else {\r
- cursor.y += itemHeight;\r
- }\r
- \r
- });\r
- }\r
- },\r
-\r
- // Handle an event\r
- handleEvent: function(e) {\r
- var me = this;\r
- var position = helpers.getRelativePosition(e, me.chart.chart),\r
- x = position.x,\r
- y = position.y,\r
- opts = me.options;\r
-\r
- if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {\r
- // See if we are touching one of the dataset boxes\r
- var lh = me.legendHitBoxes;\r
- for (var i = 0; i < lh.length; ++i) {\r
- var hitBox = lh[i];\r
-\r
- if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {\r
- // Touching an element\r
- if (opts.onClick) {\r
- opts.onClick.call(me, e, me.legendItems[i]);\r
- }\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- });\r
-\r
- // Register the legend plugin\r
- Chart.plugins.register({\r
- beforeInit: function(chartInstance) {\r
- var opts = chartInstance.options;\r
- var legendOpts = opts.legend;\r
-\r
- if (legendOpts) {\r
- chartInstance.legend = new Chart.Legend({\r
- ctx: chartInstance.chart.ctx,\r
- options: legendOpts,\r
- chart: chartInstance\r
- });\r
-\r
- Chart.layoutService.addBox(chartInstance, chartInstance.legend);\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],29:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var noop = Chart.helpers.noop;\r
-\r
- /**\r
- * The plugin service singleton\r
- * @namespace Chart.plugins\r
- * @since 2.1.0\r
- */\r
- Chart.plugins = {\r
- _plugins: [],\r
-\r
- /**\r
- * Registers the given plugin(s) if not already registered.\r
- * @param {Array|Object} plugins plugin instance(s).\r
- */\r
- register: function(plugins) {\r
- var p = this._plugins;\r
- ([]).concat(plugins).forEach(function(plugin) {\r
- if (p.indexOf(plugin) === -1) {\r
- p.push(plugin);\r
- }\r
- });\r
- },\r
-\r
- /**\r
- * Unregisters the given plugin(s) only if registered.\r
- * @param {Array|Object} plugins plugin instance(s).\r
- */\r
- unregister: function(plugins) {\r
- var p = this._plugins;\r
- ([]).concat(plugins).forEach(function(plugin) {\r
- var idx = p.indexOf(plugin);\r
- if (idx !== -1) {\r
- p.splice(idx, 1);\r
- }\r
- });\r
- },\r
-\r
- /**\r
- * Remove all registered p^lugins.\r
- * @since 2.1.5\r
- */\r
- clear: function() {\r
- this._plugins = [];\r
- },\r
-\r
- /**\r
- * Returns the number of registered plugins?\r
- * @returns {Number}\r
- * @since 2.1.5\r
- */\r
- count: function() {\r
- return this._plugins.length;\r
- },\r
-\r
- /**\r
- * Returns all registered plugin intances.\r
- * @returns {Array} array of plugin objects.\r
- * @since 2.1.5\r
- */\r
- getAll: function() {\r
- return this._plugins;\r
- },\r
-\r
- /**\r
- * Calls registered plugins on the specified extension, with the given args. This\r
- * method immediately returns as soon as a plugin explicitly returns false. The\r
- * returned value can be used, for instance, to interrupt the current action.\r
- * @param {String} extension the name of the plugin method to call (e.g. 'beforeUpdate').\r
- * @param {Array} [args] extra arguments to apply to the extension call.\r
- * @returns {Boolean} false if any of the plugins return false, else returns true.\r
- */\r
- notify: function(extension, args) {\r
- var plugins = this._plugins;\r
- var ilen = plugins.length;\r
- var i, plugin;\r
-\r
- for (i=0; i<ilen; ++i) {\r
- plugin = plugins[i];\r
- if (typeof plugin[extension] === 'function') {\r
- if (plugin[extension].apply(plugin, args || []) === false) {\r
- return false;\r
- }\r
- }\r
- }\r
-\r
- return true;\r
- }\r
- };\r
-\r
- /**\r
- * Plugin extension methods.\r
- * @interface Chart.PluginBase\r
- * @since 2.1.0\r
- */\r
- Chart.PluginBase = Chart.Element.extend({\r
- // Called at start of chart init\r
- beforeInit: noop,\r
-\r
- // Called at end of chart init\r
- afterInit: noop,\r
-\r
- // Called at start of update\r
- beforeUpdate: noop,\r
-\r
- // Called at end of update\r
- afterUpdate: noop,\r
-\r
- // Called at start of draw\r
- beforeDraw: noop,\r
-\r
- // Called at end of draw\r
- afterDraw: noop,\r
-\r
- // Called during destroy\r
- destroy: noop\r
- });\r
-\r
- /**\r
- * Provided for backward compatibility, use Chart.plugins instead\r
- * @namespace Chart.pluginService\r
- * @deprecated since version 2.1.5\r
- * @todo remove me at version 3\r
- */\r
- Chart.pluginService = Chart.plugins;\r
-};\r
-
-},{}],30:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.scale = {\r
- display: true,\r
- position: "left",\r
-\r
- // grid line settings\r
- gridLines: {\r
- display: true,\r
- color: "rgba(0, 0, 0, 0.1)",\r
- lineWidth: 1,\r
- drawBorder: true,\r
- drawOnChartArea: true,\r
- drawTicks: true,\r
- tickMarkLength: 10,\r
- zeroLineWidth: 1,\r
- zeroLineColor: "rgba(0,0,0,0.25)",\r
- offsetGridLines: false\r
- },\r
-\r
- // scale label\r
- scaleLabel: {\r
- // actual label\r
- labelString: '',\r
-\r
- // display property\r
- display: false\r
- },\r
-\r
- // label settings\r
- ticks: {\r
- beginAtZero: false,\r
- minRotation: 0,\r
- maxRotation: 50,\r
- mirror: false,\r
- padding: 10,\r
- reverse: false,\r
- display: true,\r
- autoSkip: true,\r
- autoSkipPadding: 0,\r
- labelOffset: 0,\r
- // We pass through arrays to be rendered as multiline labels, we convert Others to strings here.\r
- callback: function(value) {\r
- return helpers.isArray(value) ? value : '' + value;\r
- }\r
- }\r
- };\r
-\r
- Chart.Scale = Chart.Element.extend({\r
-\r
- // These methods are ordered by lifecyle. Utilities then follow.\r
- // Any function defined here is inherited by all scale types.\r
- // Any function can be extended by the scale type\r
-\r
- beforeUpdate: function() {\r
- helpers.callCallback(this.options.beforeUpdate, [this]);\r
- },\r
- update: function(maxWidth, maxHeight, margins) {\r
- var me = this;\r
-\r
- // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r
- me.beforeUpdate();\r
-\r
- // Absorb the master measurements\r
- me.maxWidth = maxWidth;\r
- me.maxHeight = maxHeight;\r
- me.margins = helpers.extend({\r
- left: 0,\r
- right: 0,\r
- top: 0,\r
- bottom: 0\r
- }, margins);\r
-\r
- // Dimensions\r
- me.beforeSetDimensions();\r
- me.setDimensions();\r
- me.afterSetDimensions();\r
-\r
- // Data min/max\r
- me.beforeDataLimits();\r
- me.determineDataLimits();\r
- me.afterDataLimits();\r
-\r
- // Ticks\r
- me.beforeBuildTicks();\r
- me.buildTicks();\r
- me.afterBuildTicks();\r
-\r
- me.beforeTickToLabelConversion();\r
- me.convertTicksToLabels();\r
- me.afterTickToLabelConversion();\r
-\r
- // Tick Rotation\r
- me.beforeCalculateTickRotation();\r
- me.calculateTickRotation();\r
- me.afterCalculateTickRotation();\r
- // Fit\r
- me.beforeFit();\r
- me.fit();\r
- me.afterFit();\r
- //\r
- me.afterUpdate();\r
-\r
- return me.minSize;\r
-\r
- },\r
- afterUpdate: function() {\r
- helpers.callCallback(this.options.afterUpdate, [this]);\r
- },\r
-\r
- //\r
-\r
- beforeSetDimensions: function() {\r
- helpers.callCallback(this.options.beforeSetDimensions, [this]);\r
- },\r
- setDimensions: function() {\r
- var me = this;\r
- // Set the unconstrained dimension before label rotation\r
- if (me.isHorizontal()) {\r
- // Reset position before calculating rotation\r
- me.width = me.maxWidth;\r
- me.left = 0;\r
- me.right = me.width;\r
- } else {\r
- me.height = me.maxHeight;\r
-\r
- // Reset position before calculating rotation\r
- me.top = 0;\r
- me.bottom = me.height;\r
- }\r
-\r
- // Reset padding\r
- me.paddingLeft = 0;\r
- me.paddingTop = 0;\r
- me.paddingRight = 0;\r
- me.paddingBottom = 0;\r
- },\r
- afterSetDimensions: function() {\r
- helpers.callCallback(this.options.afterSetDimensions, [this]);\r
- },\r
-\r
- // Data limits\r
- beforeDataLimits: function() {\r
- helpers.callCallback(this.options.beforeDataLimits, [this]);\r
- },\r
- determineDataLimits: helpers.noop,\r
- afterDataLimits: function() {\r
- helpers.callCallback(this.options.afterDataLimits, [this]);\r
- },\r
-\r
- //\r
- beforeBuildTicks: function() {\r
- helpers.callCallback(this.options.beforeBuildTicks, [this]);\r
- },\r
- buildTicks: helpers.noop,\r
- afterBuildTicks: function() {\r
- helpers.callCallback(this.options.afterBuildTicks, [this]);\r
- },\r
-\r
- beforeTickToLabelConversion: function() {\r
- helpers.callCallback(this.options.beforeTickToLabelConversion, [this]);\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- // Convert ticks to strings\r
- me.ticks = me.ticks.map(function(numericalTick, index, ticks) {\r
- if (me.options.ticks.userCallback) {\r
- return me.options.ticks.userCallback(numericalTick, index, ticks);\r
- }\r
- return me.options.ticks.callback(numericalTick, index, ticks);\r
- },\r
- me);\r
- },\r
- afterTickToLabelConversion: function() {\r
- helpers.callCallback(this.options.afterTickToLabelConversion, [this]);\r
- },\r
-\r
- //\r
-\r
- beforeCalculateTickRotation: function() {\r
- helpers.callCallback(this.options.beforeCalculateTickRotation, [this]);\r
- },\r
- calculateTickRotation: function() {\r
- var me = this;\r
- var context = me.ctx;\r
- var globalDefaults = Chart.defaults.global;\r
- var optionTicks = me.options.ticks;\r
-\r
- //Get the width of each grid by calculating the difference\r
- //between x offsets between 0 and 1.\r
- var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
- context.font = tickLabelFont;\r
-\r
- var firstWidth = context.measureText(me.ticks[0]).width;\r
- var lastWidth = context.measureText(me.ticks[me.ticks.length - 1]).width;\r
- var firstRotated;\r
-\r
- me.labelRotation = optionTicks.minRotation || 0;\r
- me.paddingRight = 0;\r
- me.paddingLeft = 0;\r
-\r
- if (me.options.display) {\r
- if (me.isHorizontal()) {\r
- me.paddingRight = lastWidth / 2 + 3;\r
- me.paddingLeft = firstWidth / 2 + 3;\r
-\r
- if (!me.longestTextCache) {\r
- me.longestTextCache = {};\r
- }\r
- var originalLabelWidth = helpers.longestText(context, tickLabelFont, me.ticks, me.longestTextCache);\r
- var labelWidth = originalLabelWidth;\r
- var cosRotation;\r
- var sinRotation;\r
-\r
- // Allow 3 pixels x2 padding either side for label readability\r
- // only the index matters for a dataset scale, but we want a consistent interface between scales\r
- var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;\r
-\r
- //Max label rotation can be set or default to 90 - also act as a loop counter\r
- while (labelWidth > tickWidth && me.labelRotation < optionTicks.maxRotation) {\r
- cosRotation = Math.cos(helpers.toRadians(me.labelRotation));\r
- sinRotation = Math.sin(helpers.toRadians(me.labelRotation));\r
-\r
- firstRotated = cosRotation * firstWidth;\r
-\r
- // We're right aligning the text now.\r
- if (firstRotated + tickFontSize / 2 > me.yLabelWidth) {\r
- me.paddingLeft = firstRotated + tickFontSize / 2;\r
- }\r
-\r
- me.paddingRight = tickFontSize / 2;\r
-\r
- if (sinRotation * originalLabelWidth > me.maxHeight) {\r
- // go back one step\r
- me.labelRotation--;\r
- break;\r
- }\r
-\r
- me.labelRotation++;\r
- labelWidth = cosRotation * originalLabelWidth;\r
- }\r
- }\r
- }\r
-\r
- if (me.margins) {\r
- me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\r
- me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\r
- }\r
- },\r
- afterCalculateTickRotation: function() {\r
- helpers.callCallback(this.options.afterCalculateTickRotation, [this]);\r
- },\r
-\r
- //\r
-\r
- beforeFit: function() {\r
- helpers.callCallback(this.options.beforeFit, [this]);\r
- },\r
- fit: function() {\r
- var me = this;\r
- // Reset\r
- var minSize = me.minSize = {\r
- width: 0,\r
- height: 0\r
- };\r
-\r
- var opts = me.options;\r
- var globalDefaults = Chart.defaults.global;\r
- var tickOpts = opts.ticks;\r
- var scaleLabelOpts = opts.scaleLabel;\r
- var display = opts.display;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
-\r
- var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabelOpts.fontSize, globalDefaults.defaultFontSize);\r
- var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabelOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabelOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);\r
-\r
- var tickMarkLength = opts.gridLines.tickMarkLength;\r
-\r
- // Width\r
- if (isHorizontal) {\r
- // subtract the margins to line up with the chartArea if we are a full width scale\r
- minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;\r
- } else {\r
- minSize.width = display ? tickMarkLength : 0;\r
- }\r
-\r
- // height\r
- if (isHorizontal) {\r
- minSize.height = display ? tickMarkLength : 0;\r
- } else {\r
- minSize.height = me.maxHeight; // fill all the height\r
- }\r
-\r
- // Are we showing a title for the scale?\r
- if (scaleLabelOpts.display && display) {\r
- if (isHorizontal) {\r
- minSize.height += (scaleLabelFontSize * 1.5);\r
- } else {\r
- minSize.width += (scaleLabelFontSize * 1.5);\r
- }\r
- }\r
-\r
- if (tickOpts.display && display) {\r
- // Don't bother fitting the ticks if we are not showing them\r
- if (!me.longestTextCache) {\r
- me.longestTextCache = {};\r
- }\r
-\r
- var largestTextWidth = helpers.longestText(me.ctx, tickLabelFont, me.ticks, me.longestTextCache);\r
- var tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);\r
- var lineSpace = tickFontSize * 0.5;\r
-\r
- if (isHorizontal) {\r
- // A horizontal axis is more constrained by the height.\r
- me.longestLabelWidth = largestTextWidth;\r
-\r
- // TODO - improve this calculation\r
- var labelHeight = (Math.sin(helpers.toRadians(me.labelRotation)) * me.longestLabelWidth) + (tickFontSize * tallestLabelHeightInLines) + (lineSpace * tallestLabelHeightInLines);\r
-\r
- minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);\r
- me.ctx.font = tickLabelFont;\r
-\r
- var firstLabelWidth = me.ctx.measureText(me.ticks[0]).width;\r
- var lastLabelWidth = me.ctx.measureText(me.ticks[me.ticks.length - 1]).width;\r
-\r
- // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated\r
- // by the font height\r
- var cosRotation = Math.cos(helpers.toRadians(me.labelRotation));\r
- var sinRotation = Math.sin(helpers.toRadians(me.labelRotation));\r
- me.paddingLeft = me.labelRotation !== 0 ? (cosRotation * firstLabelWidth) + 3 : firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges\r
- me.paddingRight = me.labelRotation !== 0 ? (sinRotation * (tickFontSize / 2)) + 3 : lastLabelWidth / 2 + 3; // when rotated\r
- } else {\r
- // A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first\r
- var maxLabelWidth = me.maxWidth - minSize.width;\r
-\r
- // Account for padding\r
- var mirror = tickOpts.mirror;\r
- if (!mirror) {\r
- largestTextWidth += me.options.ticks.padding;\r
- } else {\r
- // If mirrored text is on the inside so don't expand\r
- largestTextWidth = 0;\r
- }\r
-\r
- if (largestTextWidth < maxLabelWidth) {\r
- // We don't need all the room\r
- minSize.width += largestTextWidth;\r
- } else {\r
- // Expand to max size\r
- minSize.width = me.maxWidth;\r
- }\r
-\r
- me.paddingTop = tickFontSize / 2;\r
- me.paddingBottom = tickFontSize / 2;\r
- }\r
- }\r
-\r
- if (me.margins) {\r
- me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\r
- me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);\r
- me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\r
- me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);\r
- }\r
-\r
- me.width = minSize.width;\r
- me.height = minSize.height;\r
-\r
- },\r
- afterFit: function() {\r
- helpers.callCallback(this.options.afterFit, [this]);\r
- },\r
-\r
- // Shared Methods\r
- isHorizontal: function() {\r
- return this.options.position === "top" || this.options.position === "bottom";\r
- },\r
- isFullWidth: function() {\r
- return (this.options.fullWidth);\r
- },\r
-\r
- // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not\r
- getRightValue: function getRightValue(rawValue) {\r
- // Null and undefined values first\r
- if (rawValue === null || typeof(rawValue) === 'undefined') {\r
- return NaN;\r
- }\r
- // isNaN(object) returns true, so make sure NaN is checking for a number\r
- if (typeof(rawValue) === 'number' && isNaN(rawValue)) {\r
- return NaN;\r
- }\r
- // If it is in fact an object, dive in one more level\r
- if (typeof(rawValue) === "object") {\r
- if ((rawValue instanceof Date) || (rawValue.isValid)) {\r
- return rawValue;\r
- } else {\r
- return getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);\r
- }\r
- }\r
-\r
- // Value is good, return it\r
- return rawValue;\r
- },\r
-\r
- // Used to get the value to display in the tooltip for the data at the given index\r
- // function getLabelForIndex(index, datasetIndex)\r
- getLabelForIndex: helpers.noop,\r
-\r
- // Used to get data value locations. Value can either be an index or a numerical value\r
- getPixelForValue: helpers.noop,\r
-\r
- // Used to get the data value from a given pixel. This is the inverse of getPixelForValue\r
- getValueForPixel: helpers.noop,\r
-\r
- // Used for tick location, should\r
- getPixelForTick: function(index, includeOffset) {\r
- var me = this;\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\r
- var pixel = (tickWidth * index) + me.paddingLeft;\r
-\r
- if (includeOffset) {\r
- pixel += tickWidth / 2;\r
- }\r
-\r
- var finalVal = me.left + Math.round(pixel);\r
- finalVal += me.isFullWidth() ? me.margins.left : 0;\r
- return finalVal;\r
- } else {\r
- var innerHeight = me.height - (me.paddingTop + me.paddingBottom);\r
- return me.top + (index * (innerHeight / (me.ticks.length - 1)));\r
- }\r
- },\r
-\r
- // Utility for getting the pixel location of a percentage of scale\r
- getPixelForDecimal: function(decimal /*, includeOffset*/ ) {\r
- var me = this;\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var valueOffset = (innerWidth * decimal) + me.paddingLeft;\r
-\r
- var finalVal = me.left + Math.round(valueOffset);\r
- finalVal += me.isFullWidth() ? me.margins.left : 0;\r
- return finalVal;\r
- } else {\r
- return me.top + (decimal * me.height);\r
- }\r
- },\r
-\r
- getBasePixel: function() {\r
- var me = this;\r
- var min = me.min;\r
- var max = me.max;\r
-\r
- return me.getPixelForValue(\r
- me.beginAtZero? 0:\r
- min < 0 && max < 0? max :\r
- min > 0 && max > 0? min :\r
- 0);\r
- },\r
-\r
- // Actualy draw the scale on the canvas\r
- // @param {rectangle} chartArea : the area of the chart to draw full grid lines on\r
- draw: function(chartArea) {\r
- var me = this;\r
- var options = me.options;\r
- if (!options.display) {\r
- return;\r
- }\r
-\r
- var context = me.ctx;\r
- var globalDefaults = Chart.defaults.global;\r
- var optionTicks = options.ticks;\r
- var gridLines = options.gridLines;\r
- var scaleLabel = options.scaleLabel;\r
-\r
- var isRotated = me.labelRotation !== 0;\r
- var skipRatio;\r
- var useAutoskipper = optionTicks.autoSkip;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- // figure out the maximum number of gridlines to show\r
- var maxTicks;\r
- if (optionTicks.maxTicksLimit) {\r
- maxTicks = optionTicks.maxTicksLimit;\r
- }\r
-\r
- var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);\r
- var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
- var tl = gridLines.tickMarkLength;\r
-\r
- var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);\r
- var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize);\r
- var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle);\r
- var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily);\r
- var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);\r
-\r
- var labelRotationRadians = helpers.toRadians(me.labelRotation);\r
- var cosRotation = Math.cos(labelRotationRadians);\r
- var sinRotation = Math.sin(labelRotationRadians);\r
- var longestRotatedLabel = me.longestLabelWidth * cosRotation;\r
- var rotatedLabelHeight = tickFontSize * sinRotation;\r
-\r
- // Make sure we draw text in the correct color and font\r
- context.fillStyle = tickFontColor;\r
-\r
- var itemsToDraw = [];\r
-\r
- if (isHorizontal) {\r
- skipRatio = false;\r
-\r
- // Only calculate the skip ratio with the half width of longestRotateLabel if we got an actual rotation\r
- // See #2584\r
- if (isRotated) {\r
- longestRotatedLabel /= 2;\r
- }\r
-\r
- if ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {\r
- skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));\r
- }\r
-\r
- // if they defined a max number of optionTicks,\r
- // increase skipRatio until that number is met\r
- if (maxTicks && me.ticks.length > maxTicks) {\r
- while (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {\r
- if (!skipRatio) {\r
- skipRatio = 1;\r
- }\r
- skipRatio += 1;\r
- }\r
- }\r
-\r
- if (!useAutoskipper) {\r
- skipRatio = false;\r
- }\r
- }\r
-\r
-\r
- var xTickStart = options.position === "right" ? me.left : me.right - tl;\r
- var xTickEnd = options.position === "right" ? me.left + tl : me.right;\r
- var yTickStart = options.position === "bottom" ? me.top : me.bottom - tl;\r
- var yTickEnd = options.position === "bottom" ? me.top + tl : me.bottom;\r
-\r
- helpers.each(me.ticks, function(label, index) {\r
- // If the callback returned a null or undefined value, do not draw this line\r
- if (label === undefined || label === null) {\r
- return;\r
- }\r
-\r
- var isLastTick = me.ticks.length === index + 1;\r
-\r
- // Since we always show the last tick,we need may need to hide the last shown one before\r
- var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);\r
- if (shouldSkip && !isLastTick || (label === undefined || label === null)) {\r
- return;\r
- }\r
-\r
- var lineWidth, lineColor;\r
- if (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {\r
- // Draw the first index specially\r
- lineWidth = gridLines.zeroLineWidth;\r
- lineColor = gridLines.zeroLineColor;\r
- } else {\r
- lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);\r
- lineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);\r
- }\r
-\r
- // Common properties\r
- var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;\r
- var textAlign, textBaseline = 'middle';\r
-\r
- if (isHorizontal) {\r
- if (!isRotated) {\r
- textBaseline = options.position === 'top' ? 'bottom' : 'top';\r
- }\r
-\r
- textAlign = isRotated ? 'right' : 'center';\r
-\r
- var xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines\r
- labelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)\r
- labelY = (isRotated) ? me.top + 12 : options.position === 'top' ? me.bottom - tl : me.top + tl;\r
-\r
- tx1 = tx2 = x1 = x2 = xLineValue;\r
- ty1 = yTickStart;\r
- ty2 = yTickEnd;\r
- y1 = chartArea.top;\r
- y2 = chartArea.bottom;\r
- } else {\r
- if (options.position === 'left') {\r
- if (optionTicks.mirror) {\r
- labelX = me.right + optionTicks.padding;\r
- textAlign = 'left';\r
- } else {\r
- labelX = me.right - optionTicks.padding;\r
- textAlign = 'right';\r
- }\r
- } else {\r
- // right side\r
- if (optionTicks.mirror) {\r
- labelX = me.left - optionTicks.padding;\r
- textAlign = 'right';\r
- } else {\r
- labelX = me.left + optionTicks.padding;\r
- textAlign = 'left';\r
- }\r
- }\r
-\r
- var yLineValue = me.getPixelForTick(index); // xvalues for grid lines\r
- yLineValue += helpers.aliasPixel(lineWidth);\r
- labelY = me.getPixelForTick(index, gridLines.offsetGridLines);\r
-\r
- tx1 = xTickStart;\r
- tx2 = xTickEnd;\r
- x1 = chartArea.left;\r
- x2 = chartArea.right;\r
- ty1 = ty2 = y1 = y2 = yLineValue;\r
- }\r
-\r
- itemsToDraw.push({\r
- tx1: tx1,\r
- ty1: ty1,\r
- tx2: tx2,\r
- ty2: ty2,\r
- x1: x1,\r
- y1: y1,\r
- x2: x2,\r
- y2: y2,\r
- labelX: labelX,\r
- labelY: labelY,\r
- glWidth: lineWidth,\r
- glColor: lineColor,\r
- rotation: -1 * labelRotationRadians,\r
- label: label,\r
- textBaseline: textBaseline,\r
- textAlign: textAlign\r
- });\r
- });\r
-\r
- // Draw all of the tick labels, tick marks, and grid lines at the correct places\r
- helpers.each(itemsToDraw, function(itemToDraw) {\r
- if (gridLines.display) {\r
- context.lineWidth = itemToDraw.glWidth;\r
- context.strokeStyle = itemToDraw.glColor;\r
-\r
- context.beginPath();\r
-\r
- if (gridLines.drawTicks) {\r
- context.moveTo(itemToDraw.tx1, itemToDraw.ty1);\r
- context.lineTo(itemToDraw.tx2, itemToDraw.ty2);\r
- }\r
-\r
- if (gridLines.drawOnChartArea) {\r
- context.moveTo(itemToDraw.x1, itemToDraw.y1);\r
- context.lineTo(itemToDraw.x2, itemToDraw.y2);\r
- }\r
-\r
- context.stroke();\r
- }\r
-\r
- if (optionTicks.display) {\r
- context.save();\r
- context.translate(itemToDraw.labelX, itemToDraw.labelY);\r
- context.rotate(itemToDraw.rotation);\r
- context.font = tickLabelFont;\r
- context.textBaseline = itemToDraw.textBaseline;\r
- context.textAlign = itemToDraw.textAlign;\r
-\r
- var label = itemToDraw.label;\r
- if (helpers.isArray(label)) {\r
- for (var i = 0, y = 0; i < label.length; ++i) {\r
- // We just make sure the multiline element is a string here..\r
- context.fillText('' + label[i], 0, y);\r
- // apply same lineSpacing as calculated @ L#320\r
- y += (tickFontSize * 1.5);\r
- }\r
- } else {\r
- context.fillText(label, 0, 0);\r
- }\r
- context.restore();\r
- }\r
- });\r
-\r
- if (scaleLabel.display) {\r
- // Draw the scale label\r
- var scaleLabelX;\r
- var scaleLabelY;\r
- var rotation = 0;\r
-\r
- if (isHorizontal) {\r
- scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width\r
- scaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFontSize / 2) : me.top + (scaleLabelFontSize / 2);\r
- } else {\r
- var isLeft = options.position === 'left';\r
- scaleLabelX = isLeft ? me.left + (scaleLabelFontSize / 2) : me.right - (scaleLabelFontSize / 2);\r
- scaleLabelY = me.top + ((me.bottom - me.top) / 2);\r
- rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;\r
- }\r
- \r
- context.save();\r
- context.translate(scaleLabelX, scaleLabelY);\r
- context.rotate(rotation);\r
- context.textAlign = 'center';\r
- context.textBaseline = 'middle';\r
- context.fillStyle = scaleLabelFontColor; // render in correct colour\r
- context.font = scaleLabelFont;\r
- context.fillText(scaleLabel.labelString, 0, 0);\r
- context.restore();\r
- }\r
-\r
- if (gridLines.drawBorder) {\r
- // Draw the line at the edge of the axis\r
- context.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);\r
- context.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);\r
- var x1 = me.left,\r
- x2 = me.right,\r
- y1 = me.top,\r
- y2 = me.bottom;\r
-\r
- var aliasPixel = helpers.aliasPixel(context.lineWidth);\r
- if (isHorizontal) {\r
- y1 = y2 = options.position === 'top' ? me.bottom : me.top;\r
- y1 += aliasPixel;\r
- y2 += aliasPixel;\r
- } else {\r
- x1 = x2 = options.position === 'left' ? me.right : me.left;\r
- x1 += aliasPixel;\r
- x2 += aliasPixel;\r
- }\r
-\r
- context.beginPath();\r
- context.moveTo(x1, y1);\r
- context.lineTo(x2, y2);\r
- context.stroke();\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],31:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.scaleService = {\r
- // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then\r
- // use the new chart options to grab the correct scale\r
- constructors: {},\r
- // Use a registration function so that we can move to an ES6 map when we no longer need to support\r
- // old browsers\r
-\r
- // Scale config defaults\r
- defaults: {},\r
- registerScaleType: function(type, scaleConstructor, defaults) {\r
- this.constructors[type] = scaleConstructor;\r
- this.defaults[type] = helpers.clone(defaults);\r
- },\r
- getScaleConstructor: function(type) {\r
- return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;\r
- },\r
- getScaleDefaults: function(type) {\r
- // Return the scale defaults merged with the global settings so that we always use the latest ones\r
- return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};\r
- },\r
- updateScaleDefaults: function(type, additions) {\r
- var defaults = this.defaults;\r
- if (defaults.hasOwnProperty(type)) {\r
- defaults[type] = helpers.extend(defaults[type], additions);\r
- }\r
- },\r
- addScalesToLayout: function(chartInstance) {\r
- // Adds each scale to the chart.boxes array to be sized accordingly\r
- helpers.each(chartInstance.scales, function(scale) {\r
- Chart.layoutService.addBox(chartInstance, scale);\r
- });\r
- }\r
- };\r
-};
-},{}],32:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.global.title = {\r
- display: false,\r
- position: 'top',\r
- fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)\r
-\r
- fontStyle: 'bold',\r
- padding: 10,\r
-\r
- // actual title\r
- text: ''\r
- };\r
-\r
- var noop = helpers.noop;\r
- Chart.Title = Chart.Element.extend({\r
-\r
- initialize: function(config) {\r
- var me = this;\r
- helpers.extend(me, config);\r
- me.options = helpers.configMerge(Chart.defaults.global.title, config.options);\r
-\r
- // Contains hit boxes for each dataset (in dataset order)\r
- me.legendHitBoxes = [];\r
- },\r
-\r
- // These methods are ordered by lifecyle. Utilities then follow.\r
-\r
- beforeUpdate: function () {\r
- var chartOpts = this.chart.options;\r
- if (chartOpts && chartOpts.title) {\r
- this.options = helpers.configMerge(Chart.defaults.global.title, chartOpts.title);\r
- }\r
- },\r
- update: function(maxWidth, maxHeight, margins) {\r
- var me = this;\r
-\r
- // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r
- me.beforeUpdate();\r
-\r
- // Absorb the master measurements\r
- me.maxWidth = maxWidth;\r
- me.maxHeight = maxHeight;\r
- me.margins = margins;\r
-\r
- // Dimensions\r
- me.beforeSetDimensions();\r
- me.setDimensions();\r
- me.afterSetDimensions();\r
- // Labels\r
- me.beforeBuildLabels();\r
- me.buildLabels();\r
- me.afterBuildLabels();\r
-\r
- // Fit\r
- me.beforeFit();\r
- me.fit();\r
- me.afterFit();\r
- //\r
- me.afterUpdate();\r
-\r
- return me.minSize;\r
-\r
- },\r
- afterUpdate: noop,\r
-\r
- //\r
-\r
- beforeSetDimensions: noop,\r
- setDimensions: function() {\r
- var me = this;\r
- // Set the unconstrained dimension before label rotation\r
- if (me.isHorizontal()) {\r
- // Reset position before calculating rotation\r
- me.width = me.maxWidth;\r
- me.left = 0;\r
- me.right = me.width;\r
- } else {\r
- me.height = me.maxHeight;\r
-\r
- // Reset position before calculating rotation\r
- me.top = 0;\r
- me.bottom = me.height;\r
- }\r
-\r
- // Reset padding\r
- me.paddingLeft = 0;\r
- me.paddingTop = 0;\r
- me.paddingRight = 0;\r
- me.paddingBottom = 0;\r
-\r
- // Reset minSize\r
- me.minSize = {\r
- width: 0,\r
- height: 0\r
- };\r
- },\r
- afterSetDimensions: noop,\r
-\r
- //\r
-\r
- beforeBuildLabels: noop,\r
- buildLabels: noop,\r
- afterBuildLabels: noop,\r
-\r
- //\r
-\r
- beforeFit: noop,\r
- fit: function() {\r
-\r
- var me = this,\r
- ctx = me.ctx,\r
- valueOrDefault = helpers.getValueOrDefault,\r
- opts = me.options,\r
- globalDefaults = Chart.defaults.global,\r
- display = opts.display,\r
- fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\r
- minSize = me.minSize;\r
-\r
- if (me.isHorizontal()) {\r
- minSize.width = me.maxWidth; // fill all the width\r
- minSize.height = display ? fontSize + (opts.padding * 2) : 0;\r
- } else {\r
- minSize.width = display ? fontSize + (opts.padding * 2) : 0;\r
- minSize.height = me.maxHeight; // fill all the height\r
- }\r
-\r
- me.width = minSize.width;\r
- me.height = minSize.height;\r
-\r
- },\r
- afterFit: noop,\r
-\r
- // Shared Methods\r
- isHorizontal: function() {\r
- var pos = this.options.position;\r
- return pos === "top" || pos === "bottom";\r
- },\r
-\r
- // Actualy draw the title block on the canvas\r
- draw: function() {\r
- var me = this,\r
- ctx = me.ctx,\r
- valueOrDefault = helpers.getValueOrDefault,\r
- opts = me.options,\r
- globalDefaults = Chart.defaults.global;\r
-\r
- if (opts.display) {\r
- var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\r
- fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),\r
- fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),\r
- titleFont = helpers.fontString(fontSize, fontStyle, fontFamily),\r
- rotation = 0,\r
- titleX,\r
- titleY,\r
- top = me.top,\r
- left = me.left,\r
- bottom = me.bottom,\r
- right = me.right;\r
-\r
- ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour\r
- ctx.font = titleFont;\r
-\r
- // Horizontal\r
- if (me.isHorizontal()) {\r
- titleX = left + ((right - left) / 2); // midpoint of the width\r
- titleY = top + ((bottom - top) / 2); // midpoint of the height\r
- } else {\r
- titleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);\r
- titleY = top + ((bottom - top) / 2);\r
- rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);\r
- }\r
-\r
- ctx.save();\r
- ctx.translate(titleX, titleY);\r
- ctx.rotate(rotation);\r
- ctx.textAlign = 'center';\r
- ctx.textBaseline = 'middle';\r
- ctx.fillText(opts.text, 0, 0);\r
- ctx.restore();\r
- }\r
- }\r
- });\r
-\r
- // Register the title plugin\r
- Chart.plugins.register({\r
- beforeInit: function(chartInstance) {\r
- var opts = chartInstance.options;\r
- var titleOpts = opts.title;\r
-\r
- if (titleOpts) {\r
- chartInstance.titleBlock = new Chart.Title({\r
- ctx: chartInstance.chart.ctx,\r
- options: titleOpts,\r
- chart: chartInstance\r
- });\r
-\r
- Chart.layoutService.addBox(chartInstance, chartInstance.titleBlock);\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],33:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- Chart.defaults.global.tooltips = {\r
- enabled: true,\r
- custom: null,\r
- mode: 'single',\r
- backgroundColor: "rgba(0,0,0,0.8)",\r
- titleFontStyle: "bold",\r
- titleSpacing: 2,\r
- titleMarginBottom: 6,\r
- titleFontColor: "#fff",\r
- titleAlign: "left",\r
- bodySpacing: 2,\r
- bodyFontColor: "#fff",\r
- bodyAlign: "left",\r
- footerFontStyle: "bold",\r
- footerSpacing: 2,\r
- footerMarginTop: 6,\r
- footerFontColor: "#fff",\r
- footerAlign: "left",\r
- yPadding: 6,\r
- xPadding: 6,\r
- yAlign : 'center',\r
- xAlign : 'center',\r
- caretSize: 5,\r
- cornerRadius: 6,\r
- multiKeyBackground: '#fff',\r
- callbacks: {\r
- // Args are: (tooltipItems, data)\r
- beforeTitle: helpers.noop,\r
- title: function(tooltipItems, data) {\r
- // Pick first xLabel for now\r
- var title = '';\r
- var labels = data.labels;\r
- var labelCount = labels ? labels.length : 0;\r
-\r
- if (tooltipItems.length > 0) {\r
- var item = tooltipItems[0];\r
-\r
- if (item.xLabel) {\r
- title = item.xLabel;\r
- } else if (labelCount > 0 && item.index < labelCount) {\r
- title = labels[item.index];\r
- }\r
- }\r
-\r
- return title;\r
- },\r
- afterTitle: helpers.noop,\r
-\r
- // Args are: (tooltipItems, data)\r
- beforeBody: helpers.noop,\r
-\r
- // Args are: (tooltipItem, data)\r
- beforeLabel: helpers.noop,\r
- label: function(tooltipItem, data) {\r
- var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
- return datasetLabel + ': ' + tooltipItem.yLabel;\r
- },\r
- labelColor: function(tooltipItem, chartInstance) {\r
- var meta = chartInstance.getDatasetMeta(tooltipItem.datasetIndex);\r
- var activeElement = meta.data[tooltipItem.index];\r
- var view = activeElement._view;\r
- return {\r
- borderColor: view.borderColor,\r
- backgroundColor: view.backgroundColor\r
- };\r
- },\r
- afterLabel: helpers.noop,\r
-\r
- // Args are: (tooltipItems, data)\r
- afterBody: helpers.noop,\r
-\r
- // Args are: (tooltipItems, data)\r
- beforeFooter: helpers.noop,\r
- footer: helpers.noop,\r
- afterFooter: helpers.noop\r
- }\r
- };\r
-\r
- // Helper to push or concat based on if the 2nd parameter is an array or not\r
- function pushOrConcat(base, toPush) {\r
- if (toPush) {\r
- if (helpers.isArray(toPush)) {\r
- //base = base.concat(toPush);\r
- Array.prototype.push.apply(base, toPush);\r
- } else {\r
- base.push(toPush);\r
- }\r
- }\r
-\r
- return base;\r
- }\r
-\r
- function getAveragePosition(elements) {\r
- if (!elements.length) {\r
- return false;\r
- }\r
-\r
- var i, len;\r
- var xPositions = [];\r
- var yPositions = [];\r
-\r
- for (i = 0, len = elements.length; i < len; ++i) {\r
- var el = elements[i];\r
- if (el && el.hasValue()){\r
- var pos = el.tooltipPosition();\r
- xPositions.push(pos.x);\r
- yPositions.push(pos.y);\r
- }\r
- }\r
-\r
- var x = 0,\r
- y = 0;\r
- for (i = 0, len - xPositions.length; i < len; ++i) {\r
- x += xPositions[i];\r
- y += yPositions[i];\r
- }\r
-\r
- return {\r
- x: Math.round(x / xPositions.length),\r
- y: Math.round(y / xPositions.length)\r
- };\r
- }\r
-\r
- // Private helper to create a tooltip iteam model\r
- // @param element : the chart element (point, arc, bar) to create the tooltip item for\r
- // @return : new tooltip item\r
- function createTooltipItem(element) {\r
- var xScale = element._xScale;\r
- var yScale = element._yScale || element._scale; // handle radar || polarArea charts\r
- var index = element._index,\r
- datasetIndex = element._datasetIndex;\r
-\r
- return {\r
- xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',\r
- yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',\r
- index: index,\r
- datasetIndex: datasetIndex\r
- };\r
- }\r
-\r
- Chart.Tooltip = Chart.Element.extend({\r
- initialize: function() {\r
- var me = this;\r
- var globalDefaults = Chart.defaults.global;\r
- var tooltipOpts = me._options;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
-\r
- helpers.extend(me, {\r
- _model: {\r
- // Positioning\r
- xPadding: tooltipOpts.xPadding,\r
- yPadding: tooltipOpts.yPadding,\r
- xAlign : tooltipOpts.yAlign,\r
- yAlign : tooltipOpts.xAlign,\r
-\r
- // Body\r
- bodyFontColor: tooltipOpts.bodyFontColor,\r
- _bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),\r
- _bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),\r
- _bodyAlign: tooltipOpts.bodyAlign,\r
- bodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),\r
- bodySpacing: tooltipOpts.bodySpacing,\r
-\r
- // Title\r
- titleFontColor: tooltipOpts.titleFontColor,\r
- _titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),\r
- _titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),\r
- titleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),\r
- _titleAlign: tooltipOpts.titleAlign,\r
- titleSpacing: tooltipOpts.titleSpacing,\r
- titleMarginBottom: tooltipOpts.titleMarginBottom,\r
-\r
- // Footer\r
- footerFontColor: tooltipOpts.footerFontColor,\r
- _footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),\r
- _footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),\r
- footerFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),\r
- _footerAlign: tooltipOpts.footerAlign,\r
- footerSpacing: tooltipOpts.footerSpacing,\r
- footerMarginTop: tooltipOpts.footerMarginTop,\r
-\r
- // Appearance\r
- caretSize: tooltipOpts.caretSize,\r
- cornerRadius: tooltipOpts.cornerRadius,\r
- backgroundColor: tooltipOpts.backgroundColor,\r
- opacity: 0,\r
- legendColorBackground: tooltipOpts.multiKeyBackground\r
- }\r
- });\r
- },\r
-\r
- // Get the title\r
- // Args are: (tooltipItem, data)\r
- getTitle: function() {\r
- var me = this;\r
- var opts = me._options;\r
- var callbacks = opts.callbacks;\r
-\r
- var beforeTitle = callbacks.beforeTitle.apply(me, arguments),\r
- title = callbacks.title.apply(me, arguments),\r
- afterTitle = callbacks.afterTitle.apply(me, arguments);\r
-\r
- var lines = [];\r
- lines = pushOrConcat(lines, beforeTitle);\r
- lines = pushOrConcat(lines, title);\r
- lines = pushOrConcat(lines, afterTitle);\r
-\r
- return lines;\r
- },\r
-\r
- // Args are: (tooltipItem, data)\r
- getBeforeBody: function() {\r
- var lines = this._options.callbacks.beforeBody.apply(this, arguments);\r
- return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\r
- },\r
-\r
- // Args are: (tooltipItem, data)\r
- getBody: function(tooltipItems, data) {\r
- var me = this;\r
- var callbacks = me._options.callbacks;\r
- var bodyItems = [];\r
-\r
- helpers.each(tooltipItems, function(tooltipItem) {\r
- var bodyItem = {\r
- before: [],\r
- lines: [],\r
- after: []\r
- };\r
- pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));\r
- pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));\r
- pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));\r
-\r
- bodyItems.push(bodyItem);\r
- });\r
-\r
- return bodyItems;\r
- },\r
-\r
- // Args are: (tooltipItem, data)\r
- getAfterBody: function() {\r
- var lines = this._options.callbacks.afterBody.apply(this, arguments);\r
- return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\r
- },\r
-\r
- // Get the footer and beforeFooter and afterFooter lines\r
- // Args are: (tooltipItem, data)\r
- getFooter: function() {\r
- var me = this;\r
- var callbacks = me._options.callbacks;\r
-\r
- var beforeFooter = callbacks.beforeFooter.apply(me, arguments);\r
- var footer = callbacks.footer.apply(me, arguments);\r
- var afterFooter = callbacks.afterFooter.apply(me, arguments);\r
-\r
- var lines = [];\r
- lines = pushOrConcat(lines, beforeFooter);\r
- lines = pushOrConcat(lines, footer);\r
- lines = pushOrConcat(lines, afterFooter);\r
-\r
- return lines;\r
- },\r
-\r
- update: function(changed) {\r
- var me = this;\r
- var opts = me._options;\r
- var model = me._model;\r
- var active = me._active;\r
-\r
- var data = me._data;\r
- var chartInstance = me._chartInstance;\r
-\r
- var i, len;\r
-\r
- if (active.length) {\r
- model.opacity = 1;\r
-\r
- var labelColors = [],\r
- tooltipPosition = getAveragePosition(active);\r
-\r
- var tooltipItems = [];\r
- for (i = 0, len = active.length; i < len; ++i) {\r
- tooltipItems.push(createTooltipItem(active[i]));\r
- }\r
-\r
- // If the user provided a sorting function, use it to modify the tooltip items\r
- if (opts.itemSort) {\r
- tooltipItems = tooltipItems.sort(opts.itemSort);\r
- }\r
-\r
- // If there is more than one item, show color items\r
- if (active.length > 1) {\r
- helpers.each(tooltipItems, function(tooltipItem) {\r
- labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, chartInstance));\r
- });\r
- }\r
-\r
- // Build the Text Lines\r
- helpers.extend(model, {\r
- title: me.getTitle(tooltipItems, data),\r
- beforeBody: me.getBeforeBody(tooltipItems, data),\r
- body: me.getBody(tooltipItems, data),\r
- afterBody: me.getAfterBody(tooltipItems, data),\r
- footer: me.getFooter(tooltipItems, data),\r
- x: Math.round(tooltipPosition.x),\r
- y: Math.round(tooltipPosition.y),\r
- caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),\r
- labelColors: labelColors\r
- });\r
-\r
- // We need to determine alignment of\r
- var tooltipSize = me.getTooltipSize(model);\r
- me.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas\r
-\r
- helpers.extend(model, me.getBackgroundPoint(model, tooltipSize));\r
- } else {\r
- me._model.opacity = 0;\r
- }\r
-\r
- if (changed && opts.custom) {\r
- opts.custom.call(me, model);\r
- }\r
-\r
- return me;\r
- },\r
- getTooltipSize: function getTooltipSize(vm) {\r
- var ctx = this._chart.ctx;\r
-\r
- var size = {\r
- height: vm.yPadding * 2, // Tooltip Padding\r
- width: 0\r
- };\r
-\r
- // Count of all lines in the body\r
- var body = vm.body;\r
- var combinedBodyLength = body.reduce(function(count, bodyItem) {\r
- return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;\r
- }, 0);\r
- combinedBodyLength += vm.beforeBody.length + vm.afterBody.length;\r
-\r
- var titleLineCount = vm.title.length;\r
- var footerLineCount = vm.footer.length;\r
- var titleFontSize = vm.titleFontSize,\r
- bodyFontSize = vm.bodyFontSize,\r
- footerFontSize = vm.footerFontSize;\r
-\r
- size.height += titleLineCount * titleFontSize; // Title Lines\r
- size.height += (titleLineCount - 1) * vm.titleSpacing; // Title Line Spacing\r
- size.height += titleLineCount ? vm.titleMarginBottom : 0; // Title's bottom Margin\r
- size.height += combinedBodyLength * bodyFontSize; // Body Lines\r
- size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing\r
- size.height += footerLineCount ? vm.footerMarginTop : 0; // Footer Margin\r
- size.height += footerLineCount * (footerFontSize); // Footer Lines\r
- size.height += footerLineCount ? (footerLineCount - 1) * vm.footerSpacing : 0; // Footer Line Spacing\r
-\r
- // Title width\r
- var widthPadding = 0;\r
- var maxLineWidth = function(line) {\r
- size.width = Math.max(size.width, ctx.measureText(line).width + widthPadding);\r
- };\r
-\r
- ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\r
- helpers.each(vm.title, maxLineWidth);\r
-\r
- // Body width\r
- ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\r
- helpers.each(vm.beforeBody.concat(vm.afterBody), maxLineWidth);\r
-\r
- // Body lines may include some extra width due to the color box\r
- widthPadding = body.length > 1 ? (bodyFontSize + 2) : 0;\r
- helpers.each(body, function(bodyItem) {\r
- helpers.each(bodyItem.before, maxLineWidth);\r
- helpers.each(bodyItem.lines, maxLineWidth);\r
- helpers.each(bodyItem.after, maxLineWidth);\r
- });\r
-\r
- // Reset back to 0\r
- widthPadding = 0;\r
-\r
- // Footer width\r
- ctx.font = helpers.fontString(footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\r
- helpers.each(vm.footer, maxLineWidth);\r
-\r
- // Add padding\r
- size.width += 2 * vm.xPadding;\r
-\r
- return size;\r
- },\r
- determineAlignment: function determineAlignment(size) {\r
- var me = this;\r
- var model = me._model;\r
- var chart = me._chart;\r
- var chartArea = me._chartInstance.chartArea;\r
-\r
- if (model.y < size.height) {\r
- model.yAlign = 'top';\r
- } else if (model.y > (chart.height - size.height)) {\r
- model.yAlign = 'bottom';\r
- }\r
-\r
- var lf, rf; // functions to determine left, right alignment\r
- var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart\r
- var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges\r
- var midX = (chartArea.left + chartArea.right) / 2;\r
- var midY = (chartArea.top + chartArea.bottom) / 2;\r
-\r
- if (model.yAlign === 'center') {\r
- lf = function(x) {\r
- return x <= midX;\r
- };\r
- rf = function(x) {\r
- return x > midX;\r
- };\r
- } else {\r
- lf = function(x) {\r
- return x <= (size.width / 2);\r
- };\r
- rf = function(x) {\r
- return x >= (chart.width - (size.width / 2));\r
- };\r
- }\r
-\r
- olf = function(x) {\r
- return x + size.width > chart.width;\r
- };\r
- orf = function(x) {\r
- return x - size.width < 0;\r
- };\r
- yf = function(y) {\r
- return y <= midY ? 'top' : 'bottom';\r
- };\r
-\r
- if (lf(model.x)) {\r
- model.xAlign = 'left';\r
-\r
- // Is tooltip too wide and goes over the right side of the chart.?\r
- if (olf(model.x)) {\r
- model.xAlign = 'center';\r
- model.yAlign = yf(model.y);\r
- }\r
- } else if (rf(model.x)) {\r
- model.xAlign = 'right';\r
-\r
- // Is tooltip too wide and goes outside left edge of canvas?\r
- if (orf(model.x)) {\r
- model.xAlign = 'center';\r
- model.yAlign = yf(model.y);\r
- }\r
- }\r
- },\r
- getBackgroundPoint: function getBackgroundPoint(vm, size) {\r
- // Background Position\r
- var pt = {\r
- x: vm.x,\r
- y: vm.y\r
- };\r
-\r
- var caretSize = vm.caretSize,\r
- caretPadding = vm.caretPadding,\r
- cornerRadius = vm.cornerRadius,\r
- xAlign = vm.xAlign,\r
- yAlign = vm.yAlign,\r
- paddingAndSize = caretSize + caretPadding,\r
- radiusAndPadding = cornerRadius + caretPadding;\r
-\r
- if (xAlign === 'right') {\r
- pt.x -= size.width;\r
- } else if (xAlign === 'center') {\r
- pt.x -= (size.width / 2);\r
- }\r
-\r
- if (yAlign === 'top') {\r
- pt.y += paddingAndSize;\r
- } else if (yAlign === 'bottom') {\r
- pt.y -= size.height + paddingAndSize;\r
- } else {\r
- pt.y -= (size.height / 2);\r
- }\r
-\r
- if (yAlign === 'center') {\r
- if (xAlign === 'left') {\r
- pt.x += paddingAndSize;\r
- } else if (xAlign === 'right') {\r
- pt.x -= paddingAndSize;\r
- }\r
- } else {\r
- if (xAlign === 'left') {\r
- pt.x -= radiusAndPadding;\r
- } else if (xAlign === 'right') {\r
- pt.x += radiusAndPadding;\r
- }\r
- }\r
-\r
- return pt;\r
- },\r
- drawCaret: function drawCaret(tooltipPoint, size, opacity, caretPadding) {\r
- var vm = this._view;\r
- var ctx = this._chart.ctx;\r
- var x1, x2, x3;\r
- var y1, y2, y3;\r
- var caretSize = vm.caretSize;\r
- var cornerRadius = vm.cornerRadius;\r
- var xAlign = vm.xAlign,\r
- yAlign = vm.yAlign;\r
- var ptX = tooltipPoint.x,\r
- ptY = tooltipPoint.y;\r
- var width = size.width,\r
- height = size.height;\r
-\r
- if (yAlign === 'center') {\r
- // Left or right side\r
- if (xAlign === 'left') {\r
- x1 = ptX;\r
- x2 = x1 - caretSize;\r
- x3 = x1;\r
- } else {\r
- x1 = ptX + width;\r
- x2 = x1 + caretSize;\r
- x3 = x1;\r
- }\r
-\r
- y2 = ptY + (height / 2);\r
- y1 = y2 - caretSize;\r
- y3 = y2 + caretSize;\r
- } else {\r
- if (xAlign === 'left') {\r
- x1 = ptX + cornerRadius;\r
- x2 = x1 + caretSize;\r
- x3 = x2 + caretSize;\r
- } else if (xAlign === 'right') {\r
- x1 = ptX + width - cornerRadius;\r
- x2 = x1 - caretSize;\r
- x3 = x2 - caretSize;\r
- } else {\r
- x2 = ptX + (width / 2);\r
- x1 = x2 - caretSize;\r
- x3 = x2 + caretSize;\r
- }\r
-\r
- if (yAlign === 'top') {\r
- y1 = ptY;\r
- y2 = y1 - caretSize;\r
- y3 = y1;\r
- } else {\r
- y1 = ptY + height;\r
- y2 = y1 + caretSize;\r
- y3 = y1;\r
- }\r
- }\r
-\r
- var bgColor = helpers.color(vm.backgroundColor);\r
- ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();\r
- ctx.beginPath();\r
- ctx.moveTo(x1, y1);\r
- ctx.lineTo(x2, y2);\r
- ctx.lineTo(x3, y3);\r
- ctx.closePath();\r
- ctx.fill();\r
- },\r
- drawTitle: function drawTitle(pt, vm, ctx, opacity) {\r
- var title = vm.title;\r
-\r
- if (title.length) {\r
- ctx.textAlign = vm._titleAlign;\r
- ctx.textBaseline = "top";\r
-\r
- var titleFontSize = vm.titleFontSize,\r
- titleSpacing = vm.titleSpacing;\r
-\r
- var titleFontColor = helpers.color(vm.titleFontColor);\r
- ctx.fillStyle = titleFontColor.alpha(opacity * titleFontColor.alpha()).rgbString();\r
- ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\r
-\r
- var i, len;\r
- for (i = 0, len = title.length; i < len; ++i) {\r
- ctx.fillText(title[i], pt.x, pt.y);\r
- pt.y += titleFontSize + titleSpacing; // Line Height and spacing\r
-\r
- if (i + 1 === title.length) {\r
- pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing\r
- }\r
- }\r
- }\r
- },\r
- drawBody: function drawBody(pt, vm, ctx, opacity) {\r
- var bodyFontSize = vm.bodyFontSize;\r
- var bodySpacing = vm.bodySpacing;\r
- var body = vm.body;\r
-\r
- ctx.textAlign = vm._bodyAlign;\r
- ctx.textBaseline = "top";\r
-\r
- var bodyFontColor = helpers.color(vm.bodyFontColor);\r
- var textColor = bodyFontColor.alpha(opacity * bodyFontColor.alpha()).rgbString();\r
- ctx.fillStyle = textColor;\r
- ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\r
-\r
- // Before Body\r
- var xLinePadding = 0;\r
- var fillLineOfText = function(line) {\r
- ctx.fillText(line, pt.x + xLinePadding, pt.y);\r
- pt.y += bodyFontSize + bodySpacing;\r
- };\r
-\r
- // Before body lines\r
- helpers.each(vm.beforeBody, fillLineOfText);\r
-\r
- var drawColorBoxes = body.length > 1;\r
- xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;\r
-\r
- // Draw body lines now\r
- helpers.each(body, function(bodyItem, i) {\r
- helpers.each(bodyItem.before, fillLineOfText);\r
-\r
- helpers.each(bodyItem.lines, function(line) {\r
- // Draw Legend-like boxes if needed\r
- if (drawColorBoxes) {\r
- // Fill a white rect so that colours merge nicely if the opacity is < 1\r
- ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();\r
- ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\r
-\r
- // Border\r
- ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();\r
- ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\r
-\r
- // Inner square\r
- ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();\r
- ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);\r
-\r
- ctx.fillStyle = textColor;\r
- }\r
-\r
- fillLineOfText(line);\r
- });\r
-\r
- helpers.each(bodyItem.after, fillLineOfText);\r
- });\r
-\r
- // Reset back to 0 for after body\r
- xLinePadding = 0;\r
-\r
- // After body lines\r
- helpers.each(vm.afterBody, fillLineOfText);\r
- pt.y -= bodySpacing; // Remove last body spacing\r
- },\r
- drawFooter: function drawFooter(pt, vm, ctx, opacity) {\r
- var footer = vm.footer;\r
-\r
- if (footer.length) {\r
- pt.y += vm.footerMarginTop;\r
-\r
- ctx.textAlign = vm._footerAlign;\r
- ctx.textBaseline = "top";\r
-\r
- var footerFontColor = helpers.color(vm.footerFontColor);\r
- ctx.fillStyle = footerFontColor.alpha(opacity * footerFontColor.alpha()).rgbString();\r
- ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\r
-\r
- helpers.each(footer, function(line) {\r
- ctx.fillText(line, pt.x, pt.y);\r
- pt.y += vm.footerFontSize + vm.footerSpacing;\r
- });\r
- }\r
- },\r
- draw: function draw() {\r
- var ctx = this._chart.ctx;\r
- var vm = this._view;\r
-\r
- if (vm.opacity === 0) {\r
- return;\r
- }\r
-\r
- var tooltipSize = this.getTooltipSize(vm);\r
- var pt = {\r
- x: vm.x,\r
- y: vm.y\r
- };\r
-\r
- // IE11/Edge does not like very small opacities, so snap to 0\r
- var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;\r
-\r
- if (this._options.enabled) {\r
- // Draw Background\r
- var bgColor = helpers.color(vm.backgroundColor);\r
- ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();\r
- helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);\r
- ctx.fill();\r
-\r
- // Draw Caret\r
- this.drawCaret(pt, tooltipSize, opacity, vm.caretPadding);\r
-\r
- // Draw Title, Body, and Footer\r
- pt.x += vm.xPadding;\r
- pt.y += vm.yPadding;\r
-\r
- // Titles\r
- this.drawTitle(pt, vm, ctx, opacity);\r
-\r
- // Body\r
- this.drawBody(pt, vm, ctx, opacity);\r
-\r
- // Footer\r
- this.drawFooter(pt, vm, ctx, opacity);\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],34:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart, moment) {\r
-\r
- var helpers = Chart.helpers,\r
- globalOpts = Chart.defaults.global;\r
-\r
- globalOpts.elements.arc = {\r
- backgroundColor: globalOpts.defaultColor,\r
- borderColor: "#fff",\r
- borderWidth: 2\r
- };\r
-\r
- Chart.elements.Arc = Chart.Element.extend({\r
- inLabelRange: function(mouseX) {\r
- var vm = this._view;\r
-\r
- if (vm) {\r
- return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\r
- } else {\r
- return false;\r
- }\r
- },\r
- inRange: function(chartX, chartY) {\r
- var vm = this._view;\r
-\r
- if (vm) {\r
- var pointRelativePosition = helpers.getAngleFromPoint(vm, {\r
- x: chartX,\r
- y: chartY\r
- }),\r
- angle = pointRelativePosition.angle,\r
- distance = pointRelativePosition.distance;\r
-\r
- //Sanitise angle range\r
- var startAngle = vm.startAngle;\r
- var endAngle = vm.endAngle;\r
- while (endAngle < startAngle) {\r
- endAngle += 2.0 * Math.PI;\r
- }\r
- while (angle > endAngle) {\r
- angle -= 2.0 * Math.PI;\r
- }\r
- while (angle < startAngle) {\r
- angle += 2.0 * Math.PI;\r
- }\r
-\r
- //Check if within the range of the open/close angle\r
- var betweenAngles = (angle >= startAngle && angle <= endAngle),\r
- withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\r
-\r
- return (betweenAngles && withinRadius);\r
- } else {\r
- return false;\r
- }\r
- },\r
- tooltipPosition: function() {\r
- var vm = this._view;\r
-\r
- var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),\r
- rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\r
- return {\r
- x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\r
- y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\r
- };\r
- },\r
- draw: function() {\r
-\r
- var ctx = this._chart.ctx,\r
- vm = this._view,\r
- sA = vm.startAngle,\r
- eA = vm.endAngle;\r
-\r
- ctx.beginPath();\r
-\r
- ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);\r
- ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);\r
-\r
- ctx.closePath();\r
- ctx.strokeStyle = vm.borderColor;\r
- ctx.lineWidth = vm.borderWidth;\r
-\r
- ctx.fillStyle = vm.backgroundColor;\r
-\r
- ctx.fill();\r
- ctx.lineJoin = 'bevel';\r
-\r
- if (vm.borderWidth) {\r
- ctx.stroke();\r
- }\r
- }\r
- });\r
-};\r
-
-},{}],35:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var globalDefaults = Chart.defaults.global;\r
-\r
- Chart.defaults.global.elements.line = {\r
- tension: 0.4,\r
- backgroundColor: globalDefaults.defaultColor,\r
- borderWidth: 3,\r
- borderColor: globalDefaults.defaultColor,\r
- borderCapStyle: 'butt',\r
- borderDash: [],\r
- borderDashOffset: 0.0,\r
- borderJoinStyle: 'miter',\r
- fill: true // do we fill in the area between the line and its base axis\r
- };\r
-\r
- Chart.elements.Line = Chart.Element.extend({\r
- lineToNextPoint: function(previousPoint, point, nextPoint, skipHandler, previousSkipHandler) {\r
- var me = this;\r
- var ctx = me._chart.ctx;\r
- var spanGaps = me._view ? me._view.spanGaps : false;\r
-\r
- if (point._view.skip && !spanGaps) {\r
- skipHandler.call(me, previousPoint, point, nextPoint);\r
- } else if (previousPoint._view.skip && !spanGaps) {\r
- previousSkipHandler.call(me, previousPoint, point, nextPoint);\r
- } else if (point._view.tension === 0) {\r
- ctx.lineTo(point._view.x, point._view.y);\r
- } else {\r
- // Line between points\r
- ctx.bezierCurveTo(\r
- previousPoint._view.controlPointNextX,\r
- previousPoint._view.controlPointNextY,\r
- point._view.controlPointPreviousX,\r
- point._view.controlPointPreviousY,\r
- point._view.x,\r
- point._view.y\r
- );\r
- }\r
- },\r
-\r
- draw: function() {\r
- var me = this;\r
-\r
- var vm = me._view;\r
- var ctx = me._chart.ctx;\r
- var first = me._children[0];\r
- var last = me._children[me._children.length - 1];\r
-\r
- function loopBackToStart(drawLineToCenter) {\r
- if (!first._view.skip && !last._view.skip) {\r
- // Draw a bezier line from last to first\r
- ctx.bezierCurveTo(\r
- last._view.controlPointNextX,\r
- last._view.controlPointNextY,\r
- first._view.controlPointPreviousX,\r
- first._view.controlPointPreviousY,\r
- first._view.x,\r
- first._view.y\r
- );\r
- } else if (drawLineToCenter) {\r
- // Go to center\r
- ctx.lineTo(me._view.scaleZero.x, me._view.scaleZero.y);\r
- }\r
- }\r
-\r
- ctx.save();\r
-\r
- // If we had points and want to fill this line, do so.\r
- if (me._children.length > 0 && vm.fill) {\r
- // Draw the background first (so the border is always on top)\r
- ctx.beginPath();\r
-\r
- helpers.each(me._children, function(point, index) {\r
- var previous = helpers.previousItem(me._children, index);\r
- var next = helpers.nextItem(me._children, index);\r
-\r
- // First point moves to it's starting position no matter what\r
- if (index === 0) {\r
- if (me._loop) {\r
- ctx.moveTo(vm.scaleZero.x, vm.scaleZero.y);\r
- } else {\r
- ctx.moveTo(point._view.x, vm.scaleZero);\r
- }\r
-\r
- if (point._view.skip) {\r
- if (!me._loop) {\r
- ctx.moveTo(next._view.x, me._view.scaleZero);\r
- }\r
- } else {\r
- ctx.lineTo(point._view.x, point._view.y);\r
- }\r
- } else {\r
- me.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {\r
- if (me._loop) {\r
- // Go to center\r
- ctx.lineTo(me._view.scaleZero.x, me._view.scaleZero.y);\r
- } else {\r
- ctx.lineTo(previousPoint._view.x, me._view.scaleZero);\r
- ctx.moveTo(nextPoint._view.x, me._view.scaleZero);\r
- }\r
- }, function(previousPoint, point) {\r
- // If we skipped the last point, draw a line to ourselves so that the fill is nice\r
- ctx.lineTo(point._view.x, point._view.y);\r
- });\r
- }\r
- }, me);\r
-\r
- // For radial scales, loop back around to the first point\r
- if (me._loop) {\r
- loopBackToStart(true);\r
- } else {\r
- //Round off the line by going to the base of the chart, back to the start, then fill.\r
- ctx.lineTo(me._children[me._children.length - 1]._view.x, vm.scaleZero);\r
- ctx.lineTo(me._children[0]._view.x, vm.scaleZero);\r
- }\r
-\r
- ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;\r
- ctx.closePath();\r
- ctx.fill();\r
- }\r
-\r
- var globalOptionLineElements = globalDefaults.elements.line;\r
- // Now draw the line between all the points with any borders\r
- ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\r
-\r
- // IE 9 and 10 do not support line dash\r
- if (ctx.setLineDash) {\r
- ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\r
- }\r
-\r
- ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;\r
- ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\r
- ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;\r
- ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\r
- ctx.beginPath();\r
-\r
- helpers.each(me._children, function(point, index) {\r
- var previous = helpers.previousItem(me._children, index);\r
- var next = helpers.nextItem(me._children, index);\r
-\r
- if (index === 0) {\r
- ctx.moveTo(point._view.x, point._view.y);\r
- } else {\r
- me.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {\r
- ctx.moveTo(nextPoint._view.x, nextPoint._view.y);\r
- }, function(previousPoint, point) {\r
- // If we skipped the last point, move up to our point preventing a line from being drawn\r
- ctx.moveTo(point._view.x, point._view.y);\r
- });\r
- }\r
- }, me);\r
-\r
- if (me._loop && me._children.length > 0) {\r
- loopBackToStart();\r
- }\r
-\r
- ctx.stroke();\r
- ctx.restore();\r
- }\r
- });\r
-};
-},{}],36:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- globalOpts = Chart.defaults.global,\r
- defaultColor = globalOpts.defaultColor;\r
-\r
- globalOpts.elements.point = {\r
- radius: 3,\r
- pointStyle: 'circle',\r
- backgroundColor: defaultColor,\r
- borderWidth: 1,\r
- borderColor: defaultColor,\r
- // Hover\r
- hitRadius: 1,\r
- hoverRadius: 4,\r
- hoverBorderWidth: 1\r
- };\r
-\r
- Chart.elements.Point = Chart.Element.extend({\r
- inRange: function(mouseX, mouseY) {\r
- var vm = this._view;\r
- return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\r
- },\r
- inLabelRange: function(mouseX) {\r
- var vm = this._view;\r
- return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\r
- },\r
- tooltipPosition: function() {\r
- var vm = this._view;\r
- return {\r
- x: vm.x,\r
- y: vm.y,\r
- padding: vm.radius + vm.borderWidth\r
- };\r
- },\r
- draw: function() {\r
- var vm = this._view;\r
- var ctx = this._chart.ctx;\r
- var pointStyle = vm.pointStyle;\r
- var radius = vm.radius;\r
- var x = vm.x;\r
- var y = vm.y;\r
- var type, edgeLength, xOffset, yOffset, height, size;\r
-\r
- if (vm.skip) {\r
- return;\r
- }\r
-\r
- if (typeof pointStyle === 'object') {\r
- type = pointStyle.toString();\r
- if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\r
- ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);\r
- return;\r
- }\r
- }\r
-\r
- if (isNaN(radius) || radius <= 0) {\r
- return;\r
- }\r
-\r
- ctx.strokeStyle = vm.borderColor || defaultColor;\r
- ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);\r
- ctx.fillStyle = vm.backgroundColor || defaultColor;\r
-\r
- switch (pointStyle) {\r
- // Default includes circle\r
- default:\r
- ctx.beginPath();\r
- ctx.arc(x, y, radius, 0, Math.PI * 2);\r
- ctx.closePath();\r
- ctx.fill();\r
- break;\r
- case 'triangle':\r
- ctx.beginPath();\r
- edgeLength = 3 * radius / Math.sqrt(3);\r
- height = edgeLength * Math.sqrt(3) / 2;\r
- ctx.moveTo(x - edgeLength / 2, y + height / 3);\r
- ctx.lineTo(x + edgeLength / 2, y + height / 3);\r
- ctx.lineTo(x, y - 2 * height / 3);\r
- ctx.closePath();\r
- ctx.fill();\r
- break;\r
- case 'rect':\r
- size = 1 / Math.SQRT2 * radius;\r
- ctx.fillRect(x - size, y - size, 2 * size, 2 * size);\r
- ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);\r
- break;\r
- case 'rectRot':\r
- size = 1 / Math.SQRT2 * radius;\r
- ctx.beginPath();\r
- ctx.moveTo(x - size, y);\r
- ctx.lineTo(x, y + size);\r
- ctx.lineTo(x + size, y);\r
- ctx.lineTo(x, y - size);\r
- ctx.closePath();\r
- ctx.fill();\r
- break;\r
- case 'cross':\r
- ctx.beginPath();\r
- ctx.moveTo(x, y + radius);\r
- ctx.lineTo(x, y - radius);\r
- ctx.moveTo(x - radius, y);\r
- ctx.lineTo(x + radius, y);\r
- ctx.closePath();\r
- break;\r
- case 'crossRot':\r
- ctx.beginPath();\r
- xOffset = Math.cos(Math.PI / 4) * radius;\r
- yOffset = Math.sin(Math.PI / 4) * radius;\r
- ctx.moveTo(x - xOffset, y - yOffset);\r
- ctx.lineTo(x + xOffset, y + yOffset);\r
- ctx.moveTo(x - xOffset, y + yOffset);\r
- ctx.lineTo(x + xOffset, y - yOffset);\r
- ctx.closePath();\r
- break;\r
- case 'star':\r
- ctx.beginPath();\r
- ctx.moveTo(x, y + radius);\r
- ctx.lineTo(x, y - radius);\r
- ctx.moveTo(x - radius, y);\r
- ctx.lineTo(x + radius, y);\r
- xOffset = Math.cos(Math.PI / 4) * radius;\r
- yOffset = Math.sin(Math.PI / 4) * radius;\r
- ctx.moveTo(x - xOffset, y - yOffset);\r
- ctx.lineTo(x + xOffset, y + yOffset);\r
- ctx.moveTo(x - xOffset, y + yOffset);\r
- ctx.lineTo(x + xOffset, y - yOffset);\r
- ctx.closePath();\r
- break;\r
- case 'line':\r
- ctx.beginPath();\r
- ctx.moveTo(x - radius, y);\r
- ctx.lineTo(x + radius, y);\r
- ctx.closePath();\r
- break;\r
- case 'dash':\r
- ctx.beginPath();\r
- ctx.moveTo(x, y);\r
- ctx.lineTo(x + radius, y);\r
- ctx.closePath();\r
- break;\r
- }\r
-\r
- ctx.stroke();\r
- }\r
- });\r
-};\r
-
-},{}],37:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- globalOpts = Chart.defaults.global;\r
-\r
- globalOpts.elements.rectangle = {\r
- backgroundColor: globalOpts.defaultColor,\r
- borderWidth: 0,\r
- borderColor: globalOpts.defaultColor,\r
- borderSkipped: 'bottom'\r
- };\r
-\r
- Chart.elements.Rectangle = Chart.Element.extend({\r
- draw: function() {\r
- var ctx = this._chart.ctx;\r
- var vm = this._view;\r
-\r
- var halfWidth = vm.width / 2,\r
- leftX = vm.x - halfWidth,\r
- rightX = vm.x + halfWidth,\r
- top = vm.base - (vm.base - vm.y),\r
- halfStroke = vm.borderWidth / 2;\r
-\r
- // Canvas doesn't allow us to stroke inside the width so we can\r
- // adjust the sizes to fit if we're setting a stroke on the line\r
- if (vm.borderWidth) {\r
- leftX += halfStroke;\r
- rightX -= halfStroke;\r
- top += halfStroke;\r
- }\r
-\r
- ctx.beginPath();\r
- ctx.fillStyle = vm.backgroundColor;\r
- ctx.strokeStyle = vm.borderColor;\r
- ctx.lineWidth = vm.borderWidth;\r
-\r
- // Corner points, from bottom-left to bottom-right clockwise\r
- // | 1 2 |\r
- // | 0 3 |\r
- var corners = [\r
- [leftX, vm.base],\r
- [leftX, top],\r
- [rightX, top],\r
- [rightX, vm.base]\r
- ];\r
-\r
- // Find first (starting) corner with fallback to 'bottom' \r
- var borders = ['bottom', 'left', 'top', 'right'];\r
- var startCorner = borders.indexOf(vm.borderSkipped, 0);\r
- if (startCorner === -1)\r
- startCorner = 0;\r
-\r
- function cornerAt(index) {\r
- return corners[(startCorner + index) % 4];\r
- }\r
-\r
- // Draw rectangle from 'startCorner'\r
- ctx.moveTo.apply(ctx, cornerAt(0));\r
- for (var i = 1; i < 4; i++)\r
- ctx.lineTo.apply(ctx, cornerAt(i));\r
-\r
- ctx.fill();\r
- if (vm.borderWidth) {\r
- ctx.stroke();\r
- }\r
- },\r
- height: function() {\r
- var vm = this._view;\r
- return vm.base - vm.y;\r
- },\r
- inRange: function(mouseX, mouseY) {\r
- var vm = this._view;\r
- return vm ? \r
- (vm.y < vm.base ? \r
- (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.y && mouseY <= vm.base) :\r
- (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.base && mouseY <= vm.y)) :\r
- false;\r
- },\r
- inLabelRange: function(mouseX) {\r
- var vm = this._view;\r
- return vm ? (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) : false;\r
- },\r
- tooltipPosition: function() {\r
- var vm = this._view;\r
- return {\r
- x: vm.x,\r
- y: vm.y\r
- };\r
- }\r
- });\r
-\r
-};
-},{}],38:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- // Default config for a category scale\r
- var defaultConfig = {\r
- position: "bottom"\r
- };\r
-\r
- var DatasetScale = Chart.Scale.extend({\r
- // Implement this so that \r
- determineDataLimits: function() {\r
- var me = this;\r
- me.minIndex = 0;\r
- me.maxIndex = me.chart.data.labels.length - 1;\r
- var findIndex;\r
-\r
- if (me.options.ticks.min !== undefined) {\r
- // user specified min value\r
- findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.min);\r
- me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;\r
- }\r
-\r
- if (me.options.ticks.max !== undefined) {\r
- // user specified max value\r
- findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.max);\r
- me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;\r
- }\r
-\r
- me.min = me.chart.data.labels[me.minIndex];\r
- me.max = me.chart.data.labels[me.maxIndex];\r
- },\r
-\r
- buildTicks: function(index) {\r
- var me = this;\r
- // If we are viewing some subset of labels, slice the original array\r
- me.ticks = (me.minIndex === 0 && me.maxIndex === me.chart.data.labels.length - 1) ? me.chart.data.labels : me.chart.data.labels.slice(me.minIndex, me.maxIndex + 1);\r
- },\r
-\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return this.ticks[index];\r
- },\r
-\r
- // Used to get data value locations. Value can either be an index or a numerical value\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- var me = this;\r
- // 1 is added because we need the length but we have the indexes\r
- var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\r
-\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var valueWidth = innerWidth / offsetAmt;\r
- var widthOffset = (valueWidth * (index - me.minIndex)) + me.paddingLeft;\r
-\r
- if (me.options.gridLines.offsetGridLines && includeOffset) {\r
- widthOffset += (valueWidth / 2);\r
- }\r
-\r
- return me.left + Math.round(widthOffset);\r
- } else {\r
- var innerHeight = me.height - (me.paddingTop + me.paddingBottom);\r
- var valueHeight = innerHeight / offsetAmt;\r
- var heightOffset = (valueHeight * (index - me.minIndex)) + me.paddingTop;\r
-\r
- if (me.options.gridLines.offsetGridLines && includeOffset) {\r
- heightOffset += (valueHeight / 2);\r
- }\r
-\r
- return me.top + Math.round(heightOffset);\r
- }\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var value;\r
- var offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\r
- var horz = me.isHorizontal();\r
- var innerDimension = horz ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);\r
- var valueDimension = innerDimension / offsetAmt;\r
-\r
- if (me.options.gridLines.offsetGridLines) {\r
- pixel -= (valueDimension / 2);\r
- }\r
- pixel -= horz ? me.paddingLeft : me.paddingTop;\r
-\r
- if (pixel <= 0) {\r
- value = 0;\r
- } else {\r
- value = Math.round(pixel / valueDimension);\r
- }\r
-\r
- return value;\r
- }\r
- });\r
-\r
- Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);\r
-\r
-};
-},{}],39:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- var defaultConfig = {\r
- position: "left",\r
- ticks: {\r
- callback: function(tickValue, index, ticks) {\r
- // If we have lots of ticks, don't use the ones\r
- var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];\r
-\r
- // If we have a number like 2.5 as the delta, figure out how many decimal places we need\r
- if (Math.abs(delta) > 1) {\r
- if (tickValue !== Math.floor(tickValue)) {\r
- // not an integer\r
- delta = tickValue - Math.floor(tickValue);\r
- }\r
- }\r
-\r
- var logDelta = helpers.log10(Math.abs(delta));\r
- var tickString = '';\r
-\r
- if (tickValue !== 0) {\r
- var numDecimal = -1 * Math.floor(logDelta);\r
- numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places\r
- tickString = tickValue.toFixed(numDecimal);\r
- } else {\r
- tickString = '0'; // never show decimal places for 0\r
- }\r
-\r
- return tickString;\r
- }\r
- }\r
- };\r
-\r
- var LinearScale = Chart.LinearScaleBase.extend({\r
- determineDataLimits: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var chart = me.chart;\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- function IDMatches(meta) {\r
- return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\r
- }\r
-\r
- // First Calculate the range\r
- me.min = null;\r
- me.max = null;\r
-\r
- if (opts.stacked) {\r
- var valuesPerType = {};\r
- var hasPositiveValues = false;\r
- var hasNegativeValues = false;\r
-\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (valuesPerType[meta.type] === undefined) {\r
- valuesPerType[meta.type] = {\r
- positiveValues: [],\r
- negativeValues: []\r
- };\r
- }\r
-\r
- // Store these per type\r
- var positiveValues = valuesPerType[meta.type].positiveValues;\r
- var negativeValues = valuesPerType[meta.type].negativeValues;\r
-\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- positiveValues[index] = positiveValues[index] || 0;\r
- negativeValues[index] = negativeValues[index] || 0;\r
-\r
- if (opts.relativePoints) {\r
- positiveValues[index] = 100;\r
- } else {\r
- if (value < 0) {\r
- hasNegativeValues = true;\r
- negativeValues[index] += value;\r
- } else {\r
- hasPositiveValues = true;\r
- positiveValues[index] += value;\r
- }\r
- }\r
- });\r
- }\r
- });\r
-\r
- helpers.each(valuesPerType, function(valuesForType) {\r
- var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);\r
- var minVal = helpers.min(values);\r
- var maxVal = helpers.max(values);\r
- me.min = me.min === null ? minVal : Math.min(me.min, minVal);\r
- me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\r
- });\r
-\r
- } else {\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- if (me.min === null) {\r
- me.min = value;\r
- } else if (value < me.min) {\r
- me.min = value;\r
- }\r
-\r
- if (me.max === null) {\r
- me.max = value;\r
- } else if (value > me.max) {\r
- me.max = value;\r
- }\r
- });\r
- }\r
- });\r
- }\r
-\r
- // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\r
- this.handleTickRangeOptions();\r
- },\r
- getTickLimit: function() {\r
- var maxTicks;\r
- var me = this;\r
- var tickOpts = me.options.ticks;\r
-\r
- if (me.isHorizontal()) {\r
- maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));\r
- } else {\r
- // The factor of 2 used to scale the font size has been experimentally determined.\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);\r
- maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));\r
- }\r
-\r
- return maxTicks;\r
- },\r
- // Called after the ticks are built. We need \r
- handleDirectionalChanges: function() {\r
- if (!this.isHorizontal()) {\r
- // We are in a vertical orientation. The top value is the highest. So reverse the array\r
- this.ticks.reverse();\r
- }\r
- },\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\r
- },\r
- // Utils\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- // This must be called after fit has been run so that\r
- // this.left, this.top, this.right, and this.bottom have been defined\r
- var me = this;\r
- var paddingLeft = me.paddingLeft;\r
- var paddingBottom = me.paddingBottom;\r
- var start = me.start;\r
-\r
- var rightValue = +me.getRightValue(value);\r
- var pixel;\r
- var innerDimension;\r
- var range = me.end - start;\r
-\r
- if (me.isHorizontal()) {\r
- innerDimension = me.width - (paddingLeft + me.paddingRight);\r
- pixel = me.left + (innerDimension / range * (rightValue - start));\r
- return Math.round(pixel + paddingLeft);\r
- } else {\r
- innerDimension = me.height - (me.paddingTop + paddingBottom);\r
- pixel = (me.bottom - paddingBottom) - (innerDimension / range * (rightValue - start));\r
- return Math.round(pixel);\r
- }\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var isHorizontal = me.isHorizontal();\r
- var paddingLeft = me.paddingLeft;\r
- var paddingBottom = me.paddingBottom;\r
- var innerDimension = isHorizontal ? me.width - (paddingLeft + me.paddingRight) : me.height - (me.paddingTop + paddingBottom);\r
- var offset = (isHorizontal ? pixel - me.left - paddingLeft : me.bottom - paddingBottom - pixel) / innerDimension;\r
- return me.start + ((me.end - me.start) * offset);\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.ticksAsNumbers[index], null, null, includeOffset);\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("linear", LinearScale, defaultConfig);\r
-\r
-};
-},{}],40:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers,\r
- noop = helpers.noop;\r
-\r
- Chart.LinearScaleBase = Chart.Scale.extend({\r
- handleTickRangeOptions: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
-\r
- // If we are forcing it to begin at 0, but 0 will already be rendered on the chart,\r
- // do nothing since that would make the chart weird. If the user really wants a weird chart\r
- // axis, they can manually override it\r
- if (tickOpts.beginAtZero) {\r
- var minSign = helpers.sign(me.min);\r
- var maxSign = helpers.sign(me.max);\r
-\r
- if (minSign < 0 && maxSign < 0) {\r
- // move the top up to 0\r
- me.max = 0;\r
- } else if (minSign > 0 && maxSign > 0) {\r
- // move the botttom down to 0\r
- me.min = 0;\r
- }\r
- }\r
-\r
- if (tickOpts.min !== undefined) {\r
- me.min = tickOpts.min;\r
- } else if (tickOpts.suggestedMin !== undefined) {\r
- me.min = Math.min(me.min, tickOpts.suggestedMin);\r
- }\r
-\r
- if (tickOpts.max !== undefined) {\r
- me.max = tickOpts.max;\r
- } else if (tickOpts.suggestedMax !== undefined) {\r
- me.max = Math.max(me.max, tickOpts.suggestedMax);\r
- }\r
-\r
- if (me.min === me.max) {\r
- me.max++;\r
-\r
- if (!tickOpts.beginAtZero) {\r
- me.min--;\r
- }\r
- }\r
- },\r
- getTickLimit: noop,\r
- handleDirectionalChanges: noop,\r
-\r
- buildTicks: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
- var isHorizontal = me.isHorizontal();\r
-\r
- var ticks = me.ticks = [];\r
-\r
- // Figure out what the max number of ticks we can support it is based on the size of\r
- // the axis area. For now, we say that the minimum tick spacing in pixels must be 50\r
- // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\r
- // the graph\r
-\r
- var maxTicks = me.getTickLimit();\r
-\r
- // Make sure we always have at least 2 ticks\r
- maxTicks = Math.max(2, maxTicks);\r
-\r
- // To get a "nice" value for the tick spacing, we will use the appropriately named\r
- // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks\r
- // for details.\r
-\r
- var spacing;\r
- var fixedStepSizeSet = (tickOpts.fixedStepSize && tickOpts.fixedStepSize > 0) || (tickOpts.stepSize && tickOpts.stepSize > 0);\r
- if (fixedStepSizeSet) {\r
- spacing = getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize);\r
- } else {\r
- var niceRange = helpers.niceNum(me.max - me.min, false);\r
- spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);\r
- }\r
- var niceMin = Math.floor(me.min / spacing) * spacing;\r
- var niceMax = Math.ceil(me.max / spacing) * spacing;\r
- var numSpaces = (niceMax - niceMin) / spacing;\r
-\r
- // If very close to our rounded value, use it.\r
- if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\r
- numSpaces = Math.round(numSpaces);\r
- } else {\r
- numSpaces = Math.ceil(numSpaces);\r
- }\r
-\r
- // Put the values into the ticks array\r
- ticks.push(tickOpts.min !== undefined ? tickOpts.min : niceMin);\r
- for (var j = 1; j < numSpaces; ++j) {\r
- ticks.push(niceMin + (j * spacing));\r
- }\r
- ticks.push(tickOpts.max !== undefined ? tickOpts.max : niceMax);\r
-\r
- me.handleDirectionalChanges();\r
-\r
- // At this point, we need to update our max and min given the tick values since we have expanded the\r
- // range of the scale\r
- me.max = helpers.max(ticks);\r
- me.min = helpers.min(ticks);\r
-\r
- if (tickOpts.reverse) {\r
- ticks.reverse();\r
-\r
- me.start = me.max;\r
- me.end = me.min;\r
- } else {\r
- me.start = me.min;\r
- me.end = me.max;\r
- }\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- me.ticksAsNumbers = me.ticks.slice();\r
- me.zeroLineIndex = me.ticks.indexOf(0);\r
-\r
- Chart.Scale.prototype.convertTicksToLabels.call(me);\r
- },\r
- });\r
-};
-},{}],41:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
-\r
- var defaultConfig = {\r
- position: "left",\r
-\r
- // label settings\r
- ticks: {\r
- callback: function(value, index, arr) {\r
- var remain = value / (Math.pow(10, Math.floor(helpers.log10(value))));\r
-\r
- if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) {\r
- return value.toExponential();\r
- } else {\r
- return '';\r
- }\r
- }\r
- }\r
- };\r
-\r
- var LogarithmicScale = Chart.Scale.extend({\r
- determineDataLimits: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var chart = me.chart;\r
- var data = chart.data;\r
- var datasets = data.datasets;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
- var isHorizontal = me.isHorizontal();\r
- function IDMatches(meta) {\r
- return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\r
- }\r
-\r
- // Calculate Range\r
- me.min = null;\r
- me.max = null;\r
-\r
- if (opts.stacked) {\r
- var valuesPerType = {};\r
-\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- if (valuesPerType[meta.type] === undefined) {\r
- valuesPerType[meta.type] = [];\r
- }\r
-\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var values = valuesPerType[meta.type];\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- values[index] = values[index] || 0;\r
-\r
- if (opts.relativePoints) {\r
- values[index] = 100;\r
- } else {\r
- // Don't need to split positive and negative since the log scale can't handle a 0 crossing\r
- values[index] += value;\r
- }\r
- });\r
- }\r
- });\r
-\r
- helpers.each(valuesPerType, function(valuesForType) {\r
- var minVal = helpers.min(valuesForType);\r
- var maxVal = helpers.max(valuesForType);\r
- me.min = me.min === null ? minVal : Math.min(me.min, minVal);\r
- me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\r
- });\r
-\r
- } else {\r
- helpers.each(datasets, function(dataset, datasetIndex) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
- if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- if (me.min === null) {\r
- me.min = value;\r
- } else if (value < me.min) {\r
- me.min = value;\r
- }\r
-\r
- if (me.max === null) {\r
- me.max = value;\r
- } else if (value > me.max) {\r
- me.max = value;\r
- }\r
- });\r
- }\r
- });\r
- }\r
-\r
- me.min = getValueOrDefault(tickOpts.min, me.min);\r
- me.max = getValueOrDefault(tickOpts.max, me.max);\r
-\r
- if (me.min === me.max) {\r
- if (me.min !== 0 && me.min !== null) {\r
- me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);\r
- me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);\r
- } else {\r
- me.min = 1;\r
- me.max = 10;\r
- }\r
- }\r
- },\r
- buildTicks: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
-\r
- // Reset the ticks array. Later on, we will draw a grid line at these positions\r
- // The array simply contains the numerical value of the spots where ticks will be\r
- var ticks = me.ticks = [];\r
-\r
- // Figure out what the max number of ticks we can support it is based on the size of\r
- // the axis area. For now, we say that the minimum tick spacing in pixels must be 50\r
- // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\r
- // the graph\r
-\r
- var tickVal = getValueOrDefault(tickOpts.min, Math.pow(10, Math.floor(helpers.log10(me.min))));\r
-\r
- while (tickVal < me.max) {\r
- ticks.push(tickVal);\r
-\r
- var exp = Math.floor(helpers.log10(tickVal));\r
- var significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;\r
-\r
- if (significand === 10) {\r
- significand = 1;\r
- ++exp;\r
- }\r
-\r
- tickVal = significand * Math.pow(10, exp);\r
- }\r
-\r
- var lastTick = getValueOrDefault(tickOpts.max, tickVal);\r
- ticks.push(lastTick);\r
-\r
- if (!me.isHorizontal()) {\r
- // We are in a vertical orientation. The top value is the highest. So reverse the array\r
- ticks.reverse();\r
- }\r
-\r
- // At this point, we need to update our max and min given the tick values since we have expanded the\r
- // range of the scale\r
- me.max = helpers.max(ticks);\r
- me.min = helpers.min(ticks);\r
-\r
- if (tickOpts.reverse) {\r
- ticks.reverse();\r
-\r
- me.start = me.max;\r
- me.end = me.min;\r
- } else {\r
- me.start = me.min;\r
- me.end = me.max;\r
- }\r
- },\r
- convertTicksToLabels: function() {\r
- this.tickValues = this.ticks.slice();\r
-\r
- Chart.Scale.prototype.convertTicksToLabels.call(this);\r
- },\r
- // Get the correct tooltip label\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.tickValues[index], null, null, includeOffset);\r
- },\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- var me = this;\r
- var innerDimension;\r
- var pixel;\r
-\r
- var start = me.start;\r
- var newVal = +me.getRightValue(value);\r
- var range = helpers.log10(me.end) - helpers.log10(start);\r
- var paddingTop = me.paddingTop;\r
- var paddingBottom = me.paddingBottom;\r
- var paddingLeft = me.paddingLeft;\r
-\r
- if (me.isHorizontal()) {\r
-\r
- if (newVal === 0) {\r
- pixel = me.left + paddingLeft;\r
- } else {\r
- innerDimension = me.width - (paddingLeft + me.paddingRight);\r
- pixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\r
- pixel += paddingLeft;\r
- }\r
- } else {\r
- // Bottom - top since pixels increase downard on a screen\r
- if (newVal === 0) {\r
- pixel = me.top + paddingTop;\r
- } else {\r
- innerDimension = me.height - (paddingTop + paddingBottom);\r
- pixel = (me.bottom - paddingBottom) - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\r
- }\r
- }\r
-\r
- return pixel;\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var offset;\r
- var range = helpers.log10(me.end) - helpers.log10(me.start);\r
- var value;\r
- var innerDimension;\r
-\r
- if (me.isHorizontal()) {\r
- innerDimension = me.width - (me.paddingLeft + me.paddingRight);\r
- value = me.start * Math.pow(10, (pixel - me.left - me.paddingLeft) * range / innerDimension);\r
- } else {\r
- innerDimension = me.height - (me.paddingTop + me.paddingBottom);\r
- value = Math.pow(10, (me.bottom - me.paddingBottom - pixel) * range / innerDimension) / me.start;\r
- }\r
-\r
- return value;\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);\r
-\r
-};
-},{}],42:[function(require,module,exports){
-"use strict";\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var globalDefaults = Chart.defaults.global;\r
-\r
- var defaultConfig = {\r
- display: true,\r
-\r
- //Boolean - Whether to animate scaling the chart from the centre\r
- animate: true,\r
- lineArc: false,\r
- position: "chartArea",\r
-\r
- angleLines: {\r
- display: true,\r
- color: "rgba(0, 0, 0, 0.1)",\r
- lineWidth: 1\r
- },\r
-\r
- // label settings\r
- ticks: {\r
- //Boolean - Show a backdrop to the scale label\r
- showLabelBackdrop: true,\r
-\r
- //String - The colour of the label backdrop\r
- backdropColor: "rgba(255,255,255,0.75)",\r
-\r
- //Number - The backdrop padding above & below the label in pixels\r
- backdropPaddingY: 2,\r
-\r
- //Number - The backdrop padding to the side of the label in pixels\r
- backdropPaddingX: 2\r
- },\r
-\r
- pointLabels: {\r
- //Number - Point label font size in pixels\r
- fontSize: 10,\r
-\r
- //Function - Used to convert point labels\r
- callback: function(label) {\r
- return label;\r
- }\r
- }\r
- };\r
-\r
- var LinearRadialScale = Chart.LinearScaleBase.extend({\r
- getValueCount: function() {\r
- return this.chart.data.labels.length;\r
- },\r
- setDimensions: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var tickOpts = opts.ticks;\r
- // Set the unconstrained dimension before label rotation\r
- me.width = me.maxWidth;\r
- me.height = me.maxHeight;\r
- me.xCenter = Math.round(me.width / 2);\r
- me.yCenter = Math.round(me.height / 2);\r
-\r
- var minSize = helpers.min([me.height, me.width]);\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);\r
- },\r
- determineDataLimits: function() {\r
- var me = this;\r
- var chart = me.chart;\r
- me.min = null;\r
- me.max = null;\r
-\r
-\r
- helpers.each(chart.data.datasets, function(dataset, datasetIndex) {\r
- if (chart.isDatasetVisible(datasetIndex)) {\r
- var meta = chart.getDatasetMeta(datasetIndex);\r
-\r
- helpers.each(dataset.data, function(rawValue, index) {\r
- var value = +me.getRightValue(rawValue);\r
- if (isNaN(value) || meta.data[index].hidden) {\r
- return;\r
- }\r
-\r
- if (me.min === null) {\r
- me.min = value;\r
- } else if (value < me.min) {\r
- me.min = value;\r
- }\r
-\r
- if (me.max === null) {\r
- me.max = value;\r
- } else if (value > me.max) {\r
- me.max = value;\r
- }\r
- });\r
- }\r
- });\r
-\r
- // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\r
- me.handleTickRangeOptions();\r
- },\r
- getTickLimit: function() {\r
- var tickOpts = this.options.ticks;\r
- var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);\r
-\r
- // Point labels\r
- me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);\r
- },\r
- getLabelForIndex: function(index, datasetIndex) {\r
- return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\r
- },\r
- fit: function() {\r
- /*\r
- * Right, this is really confusing and there is a lot of maths going on here\r
- * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\r
- *\r
- * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\r
- *\r
- * Solution:\r
- *\r
- * We assume the radius of the polygon is half the size of the canvas at first\r
- * at each index we check if the text overlaps.\r
- *\r
- * Where it does, we store that angle and that index.\r
- *\r
- * After finding the largest index and angle we calculate how much we need to remove\r
- * from the shape radius to move the point inwards by that x.\r
- *\r
- * We average the left and right distances to get the maximum shape radius that can fit in the box\r
- * along with labels.\r
- *\r
- * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\r
- * on each side, removing that from the size, halving it and adding the left x protrusion width.\r
- *\r
- * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\r
- * and position it in the most space efficient manner\r
- *\r
- * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\r
- */\r
-\r
- var pointLabels = this.options.pointLabels;\r
- var pointLabelFontSize = helpers.getValueOrDefault(pointLabels.fontSize, globalDefaults.defaultFontSize);\r
- var pointLabeFontStyle = helpers.getValueOrDefault(pointLabels.fontStyle, globalDefaults.defaultFontStyle);\r
- var pointLabeFontFamily = helpers.getValueOrDefault(pointLabels.fontFamily, globalDefaults.defaultFontFamily);\r
- var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);\r
-\r
- // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\r
- // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\r
- var largestPossibleRadius = helpers.min([(this.height / 2 - pointLabelFontSize - 5), this.width / 2]),\r
- pointPosition,\r
- i,\r
- textWidth,\r
- halfTextWidth,\r
- furthestRight = this.width,\r
- furthestRightIndex,\r
- furthestRightAngle,\r
- furthestLeft = 0,\r
- furthestLeftIndex,\r
- furthestLeftAngle,\r
- xProtrusionLeft,\r
- xProtrusionRight,\r
- radiusReductionRight,\r
- radiusReductionLeft,\r
- maxWidthRadius;\r
- this.ctx.font = pointLabeFont;\r
-\r
- for (i = 0; i < this.getValueCount(); i++) {\r
- // 5px to space the text slightly out - similar to what we do in the draw function.\r
- pointPosition = this.getPointPosition(i, largestPossibleRadius);\r
- textWidth = this.ctx.measureText(this.pointLabels[i] ? this.pointLabels[i] : '').width + 5;\r
- if (i === 0 || i === this.getValueCount() / 2) {\r
- // If we're at index zero, or exactly the middle, we're at exactly the top/bottom\r
- // of the radar chart, so text will be aligned centrally, so we'll half it and compare\r
- // w/left and right text sizes\r
- halfTextWidth = textWidth / 2;\r
- if (pointPosition.x + halfTextWidth > furthestRight) {\r
- furthestRight = pointPosition.x + halfTextWidth;\r
- furthestRightIndex = i;\r
- }\r
- if (pointPosition.x - halfTextWidth < furthestLeft) {\r
- furthestLeft = pointPosition.x - halfTextWidth;\r
- furthestLeftIndex = i;\r
- }\r
- } else if (i < this.getValueCount() / 2) {\r
- // Less than half the values means we'll left align the text\r
- if (pointPosition.x + textWidth > furthestRight) {\r
- furthestRight = pointPosition.x + textWidth;\r
- furthestRightIndex = i;\r
- }\r
- } else if (i > this.getValueCount() / 2) {\r
- // More than half the values means we'll right align the text\r
- if (pointPosition.x - textWidth < furthestLeft) {\r
- furthestLeft = pointPosition.x - textWidth;\r
- furthestLeftIndex = i;\r
- }\r
- }\r
- }\r
-\r
- xProtrusionLeft = furthestLeft;\r
- xProtrusionRight = Math.ceil(furthestRight - this.width);\r
-\r
- furthestRightAngle = this.getIndexAngle(furthestRightIndex);\r
- furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);\r
-\r
- radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI / 2);\r
- radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI / 2);\r
-\r
- // Ensure we actually need to reduce the size of the chart\r
- radiusReductionRight = (helpers.isNumber(radiusReductionRight)) ? radiusReductionRight : 0;\r
- radiusReductionLeft = (helpers.isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;\r
-\r
- this.drawingArea = Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2);\r
- this.setCenterPoint(radiusReductionLeft, radiusReductionRight);\r
- },\r
- setCenterPoint: function(leftMovement, rightMovement) {\r
- var me = this;\r
- var maxRight = me.width - rightMovement - me.drawingArea,\r
- maxLeft = leftMovement + me.drawingArea;\r
-\r
- me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);\r
- // Always vertically in the centre as the text height doesn't change\r
- me.yCenter = Math.round((me.height / 2) + me.top);\r
- },\r
-\r
- getIndexAngle: function(index) {\r
- var angleMultiplier = (Math.PI * 2) / this.getValueCount();\r
- // Start from the top instead of right, so remove a quarter of the circle\r
-\r
- return index * angleMultiplier - (Math.PI / 2);\r
- },\r
- getDistanceFromCenterForValue: function(value) {\r
- var me = this;\r
-\r
- if (value === null) {\r
- return 0; // null always in center\r
- }\r
-\r
- // Take into account half font size + the yPadding of the top value\r
- var scalingFactor = me.drawingArea / (me.max - me.min);\r
- if (me.options.reverse) {\r
- return (me.max - value) * scalingFactor;\r
- } else {\r
- return (value - me.min) * scalingFactor;\r
- }\r
- },\r
- getPointPosition: function(index, distanceFromCenter) {\r
- var me = this;\r
- var thisAngle = me.getIndexAngle(index);\r
- return {\r
- x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,\r
- y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter\r
- };\r
- },\r
- getPointPositionForValue: function(index, value) {\r
- return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\r
- },\r
-\r
- getBasePosition: function() {\r
- var me = this;\r
- var min = me.min;\r
- var max = me.max;\r
-\r
- return me.getPointPositionForValue(0,\r
- me.beginAtZero? 0:\r
- min < 0 && max < 0? max :\r
- min > 0 && max > 0? min :\r
- 0);\r
- },\r
-\r
- draw: function() {\r
- var me = this;\r
- var opts = me.options;\r
- var gridLineOpts = opts.gridLines;\r
- var tickOpts = opts.ticks;\r
- var angleLineOpts = opts.angleLines;\r
- var pointLabelOpts = opts.pointLabels;\r
- var getValueOrDefault = helpers.getValueOrDefault;\r
-\r
- if (opts.display) {\r
- var ctx = me.ctx;\r
-\r
- // Tick Font\r
- var tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\r
- var tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
-\r
- helpers.each(me.ticks, function(label, index) {\r
- // Don't draw a centre value (if it is minimum)\r
- if (index > 0 || opts.reverse) {\r
- var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\r
- var yHeight = me.yCenter - yCenterOffset;\r
-\r
- // Draw circular lines around the scale\r
- if (gridLineOpts.display && index !== 0) {\r
- ctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);\r
- ctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);\r
-\r
- if (opts.lineArc) {\r
- // Draw circular arcs between the points\r
- ctx.beginPath();\r
- ctx.arc(me.xCenter, me.yCenter, yCenterOffset, 0, Math.PI * 2);\r
- ctx.closePath();\r
- ctx.stroke();\r
- } else {\r
- // Draw straight lines connecting each index\r
- ctx.beginPath();\r
- for (var i = 0; i < me.getValueCount(); i++) {\r
- var pointPosition = me.getPointPosition(i, yCenterOffset);\r
- if (i === 0) {\r
- ctx.moveTo(pointPosition.x, pointPosition.y);\r
- } else {\r
- ctx.lineTo(pointPosition.x, pointPosition.y);\r
- }\r
- }\r
- ctx.closePath();\r
- ctx.stroke();\r
- }\r
- }\r
-\r
- if (tickOpts.display) {\r
- var tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);\r
- ctx.font = tickLabelFont;\r
-\r
- if (tickOpts.showLabelBackdrop) {\r
- var labelWidth = ctx.measureText(label).width;\r
- ctx.fillStyle = tickOpts.backdropColor;\r
- ctx.fillRect(\r
- me.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,\r
- yHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,\r
- labelWidth + tickOpts.backdropPaddingX * 2,\r
- tickFontSize + tickOpts.backdropPaddingY * 2\r
- );\r
- }\r
-\r
- ctx.textAlign = 'center';\r
- ctx.textBaseline = "middle";\r
- ctx.fillStyle = tickFontColor;\r
- ctx.fillText(label, me.xCenter, yHeight);\r
- }\r
- }\r
- });\r
-\r
- if (!opts.lineArc) {\r
- ctx.lineWidth = angleLineOpts.lineWidth;\r
- ctx.strokeStyle = angleLineOpts.color;\r
-\r
- var outerDistance = me.getDistanceFromCenterForValue(opts.reverse ? me.min : me.max);\r
-\r
- // Point Label Font\r
- var pointLabelFontSize = getValueOrDefault(pointLabelOpts.fontSize, globalDefaults.defaultFontSize);\r
- var pointLabeFontStyle = getValueOrDefault(pointLabelOpts.fontStyle, globalDefaults.defaultFontStyle);\r
- var pointLabeFontFamily = getValueOrDefault(pointLabelOpts.fontFamily, globalDefaults.defaultFontFamily);\r
- var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);\r
-\r
- for (var i = me.getValueCount() - 1; i >= 0; i--) {\r
- if (angleLineOpts.display) {\r
- var outerPosition = me.getPointPosition(i, outerDistance);\r
- ctx.beginPath();\r
- ctx.moveTo(me.xCenter, me.yCenter);\r
- ctx.lineTo(outerPosition.x, outerPosition.y);\r
- ctx.stroke();\r
- ctx.closePath();\r
- }\r
- // Extra 3px out for some label spacing\r
- var pointLabelPosition = me.getPointPosition(i, outerDistance + 5);\r
-\r
- // Keep this in loop since we may support array properties here\r
- var pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);\r
- ctx.font = pointLabeFont;\r
- ctx.fillStyle = pointLabelFontColor;\r
-\r
- var pointLabels = me.pointLabels,\r
- labelsCount = pointLabels.length,\r
- halfLabelsCount = pointLabels.length / 2,\r
- quarterLabelsCount = halfLabelsCount / 2,\r
- upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),\r
- exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);\r
- if (i === 0) {\r
- ctx.textAlign = 'center';\r
- } else if (i === halfLabelsCount) {\r
- ctx.textAlign = 'center';\r
- } else if (i < halfLabelsCount) {\r
- ctx.textAlign = 'left';\r
- } else {\r
- ctx.textAlign = 'right';\r
- }\r
-\r
- // Set the correct text baseline based on outer positioning\r
- if (exactQuarter) {\r
- ctx.textBaseline = 'middle';\r
- } else if (upperHalf) {\r
- ctx.textBaseline = 'bottom';\r
- } else {\r
- ctx.textBaseline = 'top';\r
- }\r
-\r
- ctx.fillText(pointLabels[i] ? pointLabels[i] : '', pointLabelPosition.x, pointLabelPosition.y);\r
- }\r
- }\r
- }\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("radialLinear", LinearRadialScale, defaultConfig);\r
-\r
-};\r
-
-},{}],43:[function(require,module,exports){
-/*global window: false */\r
-"use strict";\r
-\r
-var moment = require(1);\r
-moment = typeof(moment) === 'function' ? moment : window.moment;\r
-\r
-module.exports = function(Chart) {\r
-\r
- var helpers = Chart.helpers;\r
- var time = {\r
- units: [{\r
- name: 'millisecond',\r
- steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]\r
- }, {\r
- name: 'second',\r
- steps: [1, 2, 5, 10, 30]\r
- }, {\r
- name: 'minute',\r
- steps: [1, 2, 5, 10, 30]\r
- }, {\r
- name: 'hour',\r
- steps: [1, 2, 3, 6, 12]\r
- }, {\r
- name: 'day',\r
- steps: [1, 2, 5]\r
- }, {\r
- name: 'week',\r
- maxStep: 4\r
- }, {\r
- name: 'month',\r
- maxStep: 3\r
- }, {\r
- name: 'quarter',\r
- maxStep: 4\r
- }, {\r
- name: 'year',\r
- maxStep: false\r
- }]\r
- };\r
-\r
- var defaultConfig = {\r
- position: "bottom",\r
-\r
- time: {\r
- parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment\r
- format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/\r
- unit: false, // false == automatic or override with week, month, year, etc.\r
- round: false, // none, or override with week, month, year, etc.\r
- displayFormat: false, // DEPRECATED\r
- isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/\r
-\r
- // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/\r
- displayFormats: {\r
- 'millisecond': 'h:mm:ss.SSS a', // 11:20:01.123 AM,\r
- 'second': 'h:mm:ss a', // 11:20:01 AM\r
- 'minute': 'h:mm:ss a', // 11:20:01 AM\r
- 'hour': 'MMM D, hA', // Sept 4, 5PM\r
- 'day': 'll', // Sep 4 2015\r
- 'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?\r
- 'month': 'MMM YYYY', // Sept 2015\r
- 'quarter': '[Q]Q - YYYY', // Q3\r
- 'year': 'YYYY' // 2015\r
- }\r
- },\r
- ticks: {\r
- autoSkip: false\r
- }\r
- };\r
-\r
- var TimeScale = Chart.Scale.extend({\r
- initialize: function() {\r
- if (!moment) {\r
- throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');\r
- }\r
-\r
- Chart.Scale.prototype.initialize.call(this);\r
- },\r
- getLabelMoment: function(datasetIndex, index) {\r
- return this.labelMoments[datasetIndex][index];\r
- },\r
- getMomentStartOf: function(tick) {\r
- var me = this;\r
- if (me.options.time.unit === 'week' && me.options.time.isoWeekday !== false) {\r
- return tick.clone().startOf('isoWeek').isoWeekday(me.options.time.isoWeekday);\r
- } else {\r
- return tick.clone().startOf(me.tickUnit);\r
- }\r
- },\r
- determineDataLimits: function() {\r
- var me = this;\r
- me.labelMoments = [];\r
-\r
- // Only parse these once. If the dataset does not have data as x,y pairs, we will use\r
- // these\r
- var scaleLabelMoments = [];\r
- if (me.chart.data.labels && me.chart.data.labels.length > 0) {\r
- helpers.each(me.chart.data.labels, function(label, index) {\r
- var labelMoment = me.parseTime(label);\r
-\r
- if (labelMoment.isValid()) {\r
- if (me.options.time.round) {\r
- labelMoment.startOf(me.options.time.round);\r
- }\r
- scaleLabelMoments.push(labelMoment);\r
- }\r
- }, me);\r
-\r
- me.firstTick = moment.min.call(me, scaleLabelMoments);\r
- me.lastTick = moment.max.call(me, scaleLabelMoments);\r
- } else {\r
- me.firstTick = null;\r
- me.lastTick = null;\r
- }\r
-\r
- helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {\r
- var momentsForDataset = [];\r
- var datasetVisible = me.chart.isDatasetVisible(datasetIndex);\r
-\r
- if (typeof dataset.data[0] === 'object' && dataset.data[0] !== null) {\r
- helpers.each(dataset.data, function(value, index) {\r
- var labelMoment = me.parseTime(me.getRightValue(value));\r
-\r
- if (labelMoment.isValid()) {\r
- if (me.options.time.round) {\r
- labelMoment.startOf(me.options.time.round);\r
- }\r
- momentsForDataset.push(labelMoment);\r
-\r
- if (datasetVisible) {\r
- // May have gone outside the scale ranges, make sure we keep the first and last ticks updated\r
- me.firstTick = me.firstTick !== null ? moment.min(me.firstTick, labelMoment) : labelMoment;\r
- me.lastTick = me.lastTick !== null ? moment.max(me.lastTick, labelMoment) : labelMoment;\r
- }\r
- }\r
- }, me);\r
- } else {\r
- // We have no labels. Use the ones from the scale\r
- momentsForDataset = scaleLabelMoments;\r
- }\r
-\r
- me.labelMoments.push(momentsForDataset);\r
- }, me);\r
-\r
- // Set these after we've done all the data\r
- if (me.options.time.min) {\r
- me.firstTick = me.parseTime(me.options.time.min);\r
- }\r
-\r
- if (me.options.time.max) {\r
- me.lastTick = me.parseTime(me.options.time.max);\r
- }\r
-\r
- // We will modify these, so clone for later\r
- me.firstTick = (me.firstTick || moment()).clone();\r
- me.lastTick = (me.lastTick || moment()).clone();\r
- },\r
- buildTicks: function(index) {\r
- var me = this;\r
-\r
- me.ctx.save();\r
- var tickFontSize = helpers.getValueOrDefault(me.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);\r
- var tickFontStyle = helpers.getValueOrDefault(me.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);\r
- var tickFontFamily = helpers.getValueOrDefault(me.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);\r
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\r
- me.ctx.font = tickLabelFont;\r
-\r
- me.ticks = [];\r
- me.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step\r
- me.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc)\r
-\r
- // Set unit override if applicable\r
- if (me.options.time.unit) {\r
- me.tickUnit = me.options.time.unit || 'day';\r
- me.displayFormat = me.options.time.displayFormats[me.tickUnit];\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);\r
- me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, 1);\r
- } else {\r
- // Determine the smallest needed unit of the time\r
- var innerWidth = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);\r
-\r
- // Crude approximation of what the label length might be\r
- var tempFirstLabel = me.tickFormatFunction(me.firstTick, 0, []);\r
- var tickLabelWidth = me.ctx.measureText(tempFirstLabel).width;\r
- var cosRotation = Math.cos(helpers.toRadians(me.options.ticks.maxRotation));\r
- var sinRotation = Math.sin(helpers.toRadians(me.options.ticks.maxRotation));\r
- tickLabelWidth = (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);\r
- var labelCapacity = innerWidth / (tickLabelWidth);\r
-\r
- // Start as small as possible\r
- me.tickUnit = 'millisecond';\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);\r
- me.displayFormat = me.options.time.displayFormats[me.tickUnit];\r
-\r
- var unitDefinitionIndex = 0;\r
- var unitDefinition = time.units[unitDefinitionIndex];\r
-\r
- // While we aren't ideal and we don't have units left\r
- while (unitDefinitionIndex < time.units.length) {\r
- // Can we scale this unit. If `false` we can scale infinitely\r
- me.unitScale = 1;\r
-\r
- if (helpers.isArray(unitDefinition.steps) && Math.ceil(me.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) {\r
- // Use one of the prefedined steps\r
- for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {\r
- if (unitDefinition.steps[idx] >= Math.ceil(me.scaleSizeInUnits / labelCapacity)) {\r
- me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, unitDefinition.steps[idx]);\r
- break;\r
- }\r
- }\r
-\r
- break;\r
- } else if ((unitDefinition.maxStep === false) || (Math.ceil(me.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep)) {\r
- // We have a max step. Scale this unit\r
- me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, Math.ceil(me.scaleSizeInUnits / labelCapacity));\r
- break;\r
- } else {\r
- // Move to the next unit up\r
- ++unitDefinitionIndex;\r
- unitDefinition = time.units[unitDefinitionIndex];\r
-\r
- me.tickUnit = unitDefinition.name;\r
- var leadingUnitBuffer = me.firstTick.diff(me.getMomentStartOf(me.firstTick), me.tickUnit, true);\r
- var trailingUnitBuffer = me.getMomentStartOf(me.lastTick.clone().add(1, me.tickUnit)).diff(me.lastTick, me.tickUnit, true);\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true) + leadingUnitBuffer + trailingUnitBuffer;\r
- me.displayFormat = me.options.time.displayFormats[unitDefinition.name];\r
- }\r
- }\r
- }\r
-\r
- var roundedStart;\r
-\r
- // Only round the first tick if we have no hard minimum\r
- if (!me.options.time.min) {\r
- me.firstTick = me.getMomentStartOf(me.firstTick);\r
- roundedStart = me.firstTick;\r
- } else {\r
- roundedStart = me.getMomentStartOf(me.firstTick);\r
- }\r
-\r
- // Only round the last tick if we have no hard maximum\r
- if (!me.options.time.max) {\r
- var roundedEnd = me.getMomentStartOf(me.lastTick);\r
- if (roundedEnd.diff(me.lastTick, me.tickUnit, true) !== 0) {\r
- // Do not use end of because we need me to be in the next time unit\r
- me.lastTick = me.getMomentStartOf(me.lastTick.add(1, me.tickUnit));\r
- }\r
- }\r
-\r
- me.smallestLabelSeparation = me.width;\r
-\r
- helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {\r
- for (var i = 1; i < me.labelMoments[datasetIndex].length; i++) {\r
- me.smallestLabelSeparation = Math.min(me.smallestLabelSeparation, me.labelMoments[datasetIndex][i].diff(me.labelMoments[datasetIndex][i - 1], me.tickUnit, true));\r
- }\r
- }, me);\r
-\r
- // Tick displayFormat override\r
- if (me.options.time.displayFormat) {\r
- me.displayFormat = me.options.time.displayFormat;\r
- }\r
-\r
- // first tick. will have been rounded correctly if options.time.min is not specified\r
- me.ticks.push(me.firstTick.clone());\r
-\r
- // For every unit in between the first and last moment, create a moment and add it to the ticks tick\r
- for (var i = 1; i <= me.scaleSizeInUnits; ++i) {\r
- var newTick = roundedStart.clone().add(i, me.tickUnit);\r
-\r
- // Are we greater than the max time\r
- if (me.options.time.max && newTick.diff(me.lastTick, me.tickUnit, true) >= 0) {\r
- break;\r
- }\r
-\r
- if (i % me.unitScale === 0) {\r
- me.ticks.push(newTick);\r
- }\r
- }\r
-\r
- // Always show the right tick\r
- var diff = me.ticks[me.ticks.length - 1].diff(me.lastTick, me.tickUnit);\r
- if (diff !== 0 || me.scaleSizeInUnits === 0) {\r
- // this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart\r
- // but the last tick was not rounded.\r
- if (me.options.time.max) {\r
- me.ticks.push(me.lastTick.clone());\r
- me.scaleSizeInUnits = me.lastTick.diff(me.ticks[0], me.tickUnit, true);\r
- } else {\r
- me.ticks.push(me.lastTick.clone());\r
- me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);\r
- }\r
- }\r
-\r
- me.ctx.restore();\r
- },\r
- // Get tooltip label\r
- getLabelForIndex: function(index, datasetIndex) {\r
- var me = this;\r
- var label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';\r
-\r
- if (typeof me.chart.data.datasets[datasetIndex].data[0] === 'object') {\r
- label = me.getRightValue(me.chart.data.datasets[datasetIndex].data[index]);\r
- }\r
-\r
- // Format nicely\r
- if (me.options.time.tooltipFormat) {\r
- label = me.parseTime(label).format(me.options.time.tooltipFormat);\r
- }\r
-\r
- return label;\r
- },\r
- // Function to format an individual tick mark\r
- tickFormatFunction: function tickFormatFunction(tick, index, ticks) {\r
- var formattedTick = tick.format(this.displayFormat);\r
- var tickOpts = this.options.ticks;\r
- var callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);\r
-\r
- if (callback) {\r
- return callback(formattedTick, index, ticks);\r
- } else {\r
- return formattedTick;\r
- }\r
- },\r
- convertTicksToLabels: function() {\r
- var me = this;\r
- me.tickMoments = me.ticks;\r
- me.ticks = me.ticks.map(me.tickFormatFunction, me);\r
- },\r
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {\r
- var me = this;\r
- var labelMoment = value && value.isValid && value.isValid() ? value : me.getLabelMoment(datasetIndex, index);\r
-\r
- if (labelMoment) {\r
- var offset = labelMoment.diff(me.firstTick, me.tickUnit, true);\r
-\r
- var decimal = offset / me.scaleSizeInUnits;\r
-\r
- if (me.isHorizontal()) {\r
- var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\r
- var valueWidth = innerWidth / Math.max(me.ticks.length - 1, 1);\r
- var valueOffset = (innerWidth * decimal) + me.paddingLeft;\r
-\r
- return me.left + Math.round(valueOffset);\r
- } else {\r
- var innerHeight = me.height - (me.paddingTop + me.paddingBottom);\r
- var valueHeight = innerHeight / Math.max(me.ticks.length - 1, 1);\r
- var heightOffset = (innerHeight * decimal) + me.paddingTop;\r
-\r
- return me.top + Math.round(heightOffset);\r
- }\r
- }\r
- },\r
- getPixelForTick: function(index, includeOffset) {\r
- return this.getPixelForValue(this.tickMoments[index], null, null, includeOffset);\r
- },\r
- getValueForPixel: function(pixel) {\r
- var me = this;\r
- var innerDimension = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);\r
- var offset = (pixel - (me.isHorizontal() ? me.left + me.paddingLeft : me.top + me.paddingTop)) / innerDimension;\r
- offset *= me.scaleSizeInUnits;\r
- return me.firstTick.clone().add(moment.duration(offset, me.tickUnit).asSeconds(), 'seconds');\r
- },\r
- parseTime: function(label) {\r
- var me = this;\r
- if (typeof me.options.time.parser === 'string') {\r
- return moment(label, me.options.time.parser);\r
- }\r
- if (typeof me.options.time.parser === 'function') {\r
- return me.options.time.parser(label);\r
- }\r
- // Date objects\r
- if (typeof label.getMonth === 'function' || typeof label === 'number') {\r
- return moment(label);\r
- }\r
- // Moment support\r
- if (label.isValid && label.isValid()) {\r
- return label;\r
- }\r
- // Custom parsing (return an instance of moment)\r
- if (typeof me.options.time.format !== 'string' && me.options.time.format.call) {\r
- console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale");\r
- return me.options.time.format(label);\r
- }\r
- // Moment format parsing\r
- return moment(label, me.options.time.format);\r
- }\r
- });\r
- Chart.scaleService.registerScaleType("time", TimeScale, defaultConfig);\r
-\r
-};\r
-
-},{"1":1}]},{},[7])(7)
-});
\ No newline at end of file
+++ /dev/null
-/*!
- * Chart.js
- * http://chartjs.org/
- * Version: 2.1.6
- *
- * Copyright 2016 Nick Downie
- * Released under the MIT license
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
- */
-!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){return function t(e,a,i){function n(r,l){if(!a[r]){if(!e[r]){var s="function"==typeof require&&require;if(!l&&s)return s(r,!0);if(o)return o(r,!0);var d=new Error("Cannot find module '"+r+"'");throw d.code="MODULE_NOT_FOUND",d}var u=a[r]={exports:{}};e[r][0].call(u.exports,function(t){var a=e[r][1][t];return n(a?a:t)},u,u.exports,t,e,a,i)}return a[r].exports}for(var o="function"==typeof require&&require,r=0;r<i.length;r++)n(i[r]);return n}({1:[function(t,e,a){},{}],2:[function(t,e,a){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,a=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,n=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,o=/(\w+)/,r=[0,0,0],l=1,s=t.match(e);if(s){s=s[1];for(var d=0;d<r.length;d++)r[d]=parseInt(s[d]+s[d],16)}else if(s=t.match(a)){s=s[1];for(var d=0;d<r.length;d++)r[d]=parseInt(s.slice(2*d,2*d+2),16)}else if(s=t.match(i)){for(var d=0;d<r.length;d++)r[d]=parseInt(s[d+1]);l=parseFloat(s[4])}else if(s=t.match(n)){for(var d=0;d<r.length;d++)r[d]=Math.round(2.55*parseFloat(s[d+1]));l=parseFloat(s[4])}else if(s=t.match(o)){if("transparent"==s[1])return[0,0,0,0];if(r=y[s[1]],!r)return}for(var d=0;d<r.length;d++)r[d]=v(r[d],0,255);return l=l||0==l?v(l,0,1):1,r[3]=l,r}}function n(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=v(parseInt(a[1]),0,360),o=v(parseFloat(a[2]),0,100),r=v(parseFloat(a[3]),0,100),l=v(isNaN(i)?1:i,0,1);return[n,o,r,l]}}}function o(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=v(parseInt(a[1]),0,360),o=v(parseFloat(a[2]),0,100),r=v(parseFloat(a[3]),0,100),l=v(isNaN(i)?1:i,0,1);return[n,o,r,l]}}}function r(t){var e=i(t);return e&&e.slice(0,3)}function l(t){var e=n(t);return e&&e.slice(0,3)}function s(t){var e=i(t);return e?e[3]:(e=n(t))?e[3]:(e=o(t))?e[3]:void 0}function d(t){return"#"+x(t[0])+x(t[1])+x(t[2])}function u(t,e){return 1>e||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(1>e||t[3]&&t[3]<1)return f(t,e);var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgb("+a+"%, "+i+"%, "+n+"%)"}function f(t,e){var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgba("+a+"%, "+i+"%, "+n+"%, "+(e||t[3]||1)+")"}function g(t,e){return 1>e||t[3]&&t[3]<1?p(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function b(t){return k[t.slice(0,3)]}function v(t,e,a){return Math.min(Math.max(e,t),a)}function x(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y=t(6);e.exports={getRgba:i,getHsla:n,getRgb:r,getHsl:l,getHwb:o,getAlpha:s,hexString:d,rgbString:u,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:p,hwbString:m,keyword:b};var k={};for(var S in y)k[y[S]]=S},{6:6}],3:[function(t,e,a){var i=t(5),n=t(2),o=function(t){if(t instanceof o)return t;if(!(this instanceof o))return new o(t);this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;if("string"==typeof t)if(e=n.getRgba(t))this.setValues("rgb",e);else if(e=n.getHsla(t))this.setValues("hsl",e);else{if(!(e=n.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}else if("object"==typeof t)if(e=t,void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}};o.prototype={rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=0>t?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return n.hexString(this.values.rgb)},rgbString:function(){return n.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return n.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return n.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return n.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return n.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return n.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return n.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],a=0;a<t.length;a++){var i=t[a]/255;e[a]=.03928>=i?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),a=t.luminosity();return e>a?(e+.05)/(a+.05):(a+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return 128>e},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;3>e;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,a=(e[0]+t)%360;return e[0]=0>a?360+a:a,this.setValues("hsl",e),this},mix:function(t,e){var a=this,i=t,n=void 0===e?.5:e,o=2*n-1,r=a.alpha()-i.alpha(),l=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,s=1-l;return this.rgb(l*a.red()+s*i.red(),l*a.green()+s*i.green(),l*a.blue()+s*i.blue()).alpha(a.alpha()*n+i.alpha()*(1-n))},toJSON:function(){return this.rgb()},clone:function(){var t,e,a=new o,i=this.values,n=a.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?n[r]=t.slice(0):"[object Number]"===e?n[r]=t:console.error("unexpected color value:",t));return a}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,a={},i=0;i<t.length;i++)a[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(a.a=e.alpha),a},o.prototype.setValues=function(t,e){var a,n=this.values,o=this.spaces,r=this.maxes,l=1;if("alpha"===t)l=e;else if(e.length)n[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(a=0;a<t.length;a++)n[t][a]=e[t.charAt(a)];l=e.a}else if(void 0!==e[o[t][0]]){var s=o[t];for(a=0;a<t.length;a++)n[t][a]=e[s[a]];l=e.alpha}if(n.alpha=Math.max(0,Math.min(1,void 0===l?n.alpha:l)),"alpha"===t)return!1;var d;for(a=0;a<t.length;a++)d=Math.max(0,Math.min(r[t][a],n[t][a])),n[t][a]=Math.round(d);for(var u in o)u!==t&&(n[u]=i[t][u](n[t]));return!0},o.prototype.setSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a),this)},o.prototype.setChannel=function(t,e,a){var i=this.values[t];return void 0===a?i[e]:a===i[e]?this:(i[e]=a,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,a){function i(t){var e,a,i,n=t[0]/255,o=t[1]/255,r=t[2]/255,l=Math.min(n,o,r),s=Math.max(n,o,r),d=s-l;return s==l?e=0:n==s?e=(o-r)/d:o==s?e=2+(r-n)/d:r==s&&(e=4+(n-o)/d),e=Math.min(60*e,360),0>e&&(e+=360),i=(l+s)/2,a=s==l?0:.5>=i?d/(s+l):d/(2-s-l),[e,100*a,100*i]}function n(t){var e,a,i,n=t[0],o=t[1],r=t[2],l=Math.min(n,o,r),s=Math.max(n,o,r),d=s-l;return a=0==s?0:d/s*1e3/10,s==l?e=0:n==s?e=(o-r)/d:o==s?e=2+(r-n)/d:r==s&&(e=4+(n-o)/d),e=Math.min(60*e,360),0>e&&(e+=360),i=s/255*1e3/10,[e,a,i]}function o(t){var e=t[0],a=t[1],n=t[2],o=i(t)[0],r=1/255*Math.min(e,Math.min(a,n)),n=1-1/255*Math.max(e,Math.max(a,n));return[o,100*r,100*n]}function l(t){var e,a,i,n,o=t[0]/255,r=t[1]/255,l=t[2]/255;return n=Math.min(1-o,1-r,1-l),e=(1-o-n)/(1-n)||0,a=(1-r-n)/(1-n)||0,i=(1-l-n)/(1-n)||0,[100*e,100*a,100*i,100*n]}function s(t){return Q[JSON.stringify(t)]}function d(t){var e=t[0]/255,a=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var n=.4124*e+.3576*a+.1805*i,o=.2126*e+.7152*a+.0722*i,r=.0193*e+.1192*a+.9505*i;return[100*n,100*o,100*r]}function u(t){var e,a,i,n=d(t),o=n[0],r=n[1],l=n[2];return o/=95.047,r/=100,l/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,l=l>.008856?Math.pow(l,1/3):7.787*l+16/116,e=116*r-16,a=500*(o-r),i=200*(r-l),[e,a,i]}function c(t){return W(u(t))}function h(t){var e,a,i,n,o,r=t[0]/360,l=t[1]/100,s=t[2]/100;if(0==l)return o=255*s,[o,o,o];a=.5>s?s*(1+l):s+l-s*l,e=2*s-a,n=[0,0,0];for(var d=0;3>d;d++)i=r+1/3*-(d-1),0>i&&i++,i>1&&i--,o=1>6*i?e+6*(a-e)*i:1>2*i?a:2>3*i?e+(a-e)*(2/3-i)*6:e,n[d]=255*o;return n}function f(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,n*=1>=o?o:2-o,a=(o+n)/2,e=2*n/(o+n),[i,100*e,100*a])}function p(t){return o(h(t))}function m(t){return l(h(t))}function v(t){return s(h(t))}function x(t){var e=t[0]/60,a=t[1]/100,i=t[2]/100,n=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-a),l=255*i*(1-a*o),s=255*i*(1-a*(1-o)),i=255*i;switch(n){case 0:return[i,s,r];case 1:return[l,i,r];case 2:return[r,i,s];case 3:return[r,l,i];case 4:return[s,r,i];case 5:return[i,r,l]}}function y(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return a=(2-n)*o,e=n*o,e/=1>=a?a:2-a,e=e||0,a/=2,[i,100*e,100*a]}function k(t){return o(x(t))}function S(t){return l(x(t))}function w(t){return s(x(t))}function C(t){var e,a,i,n,o=t[0]/360,l=t[1]/100,s=t[2]/100,d=l+s;switch(d>1&&(l/=d,s/=d),e=Math.floor(6*o),a=1-s,i=6*o-e,0!=(1&e)&&(i=1-i),n=l+i*(a-l),e){default:case 6:case 0:r=a,g=n,b=l;break;case 1:r=n,g=a,b=l;break;case 2:r=l,g=a,b=n;break;case 3:r=l,g=n,b=a;break;case 4:r=n,g=l,b=a;break;case 5:r=a,g=l,b=n}return[255*r,255*g,255*b]}function M(t){return i(C(t))}function D(t){return n(C(t))}function A(t){return l(C(t))}function I(t){return s(C(t))}function F(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100,l=t[3]/100;return e=1-Math.min(1,n*(1-l)+l),a=1-Math.min(1,o*(1-l)+l),i=1-Math.min(1,r*(1-l)+l),[255*e,255*a,255*i]}function T(t){return i(F(t))}function P(t){return n(F(t))}function _(t){return o(F(t))}function R(t){return s(F(t))}function V(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*n+-1.5372*o+r*-.4986,a=n*-.9689+1.8758*o+.0415*r,i=.0557*n+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e=12.92*e,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a=12.92*a,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i=12.92*i,e=Math.min(Math.max(0,e),1),a=Math.min(Math.max(0,a),1),i=Math.min(Math.max(0,i),1),[255*e,255*a,255*i]}function O(t){var e,a,i,n=t[0],o=t[1],r=t[2];return n/=95.047,o/=100,r/=108.883,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*o-16,a=500*(n-o),i=200*(o-r),[e,a,i]}function L(t){return W(O(t))}function B(t){var e,a,i,n,o=t[0],r=t[1],l=t[2];return 8>=o?(a=100*o/903.3,n=7.787*(a/100)+16/116):(a=100*Math.pow((o+16)/116,3),n=Math.pow(a/100,1/3)),e=.008856>=e/95.047?e=95.047*(r/500+n-16/116)/7.787:95.047*Math.pow(r/500+n,3),i=.008859>=i/108.883?i=108.883*(n-l/200-16/116)/7.787:108.883*Math.pow(n-l/200,3),[e,a,i]}function W(t){var e,a,i,n=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),a=360*e/2/Math.PI,0>a&&(a+=360),i=Math.sqrt(o*o+r*r),[n,i,a]}function z(t){return V(B(t))}function H(t){var e,a,i,n=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),a=o*Math.sin(i),[n,e,a]}function N(t){return B(H(t))}function E(t){return z(H(t))}function U(t){return G[t]}function q(t){return i(U(t))}function j(t){return n(U(t))}function Y(t){return o(U(t))}function J(t){return l(U(t))}function X(t){return u(U(t))}function Z(t){return d(U(t))}e.exports={rgb2hsl:i,rgb2hsv:n,rgb2hwb:o,rgb2cmyk:l,rgb2keyword:s,rgb2xyz:d,rgb2lab:u,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:S,hsv2keyword:w,hwb2rgb:C,hwb2hsl:M,hwb2hsv:D,hwb2cmyk:A,hwb2keyword:I,cmyk2rgb:F,cmyk2hsl:T,cmyk2hsv:P,cmyk2hwb:_,cmyk2keyword:R,keyword2rgb:U,keyword2hsl:q,keyword2hsv:j,keyword2hwb:Y,keyword2cmyk:J,keyword2lab:X,keyword2xyz:Z,xyz2rgb:V,xyz2lab:O,xyz2lch:L,lab2xyz:B,lab2rgb:z,lab2lch:W,lch2lab:H,lch2xyz:N,lch2rgb:E};var G={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Q={};for(var $ in G)Q[JSON.stringify(G[$])]=$},{}],5:[function(t,e,a){var i=t(4),n=function(){return new d};for(var o in i){n[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),l=r[1],s=r[2];n[l]=n[l]||{},n[l][s]=n[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var a=i[t](e);if("string"==typeof a||void 0===a)return a;for(var n=0;n<a.length;n++)a[n]=Math.round(a[n]);return a}}(o)}var d=function(){this.convs={}};d.prototype.routeSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a))},d.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},d.prototype.getValues=function(t){var e=this.convs[t];if(!e){var a=this.space,i=this.convs[a];e=n[a][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){d.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=n},{4:4}],6:[function(t,e,a){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],7:[function(t,e,a){var i=t(26)();t(25)(i),t(24)(i),t(21)(i),t(22)(i),t(23)(i),t(27)(i),t(31)(i),t(29)(i),t(30)(i),t(32)(i),t(28)(i),t(33)(i),t(34)(i),t(35)(i),t(36)(i),t(37)(i),t(40)(i),t(38)(i),t(39)(i),t(41)(i),t(42)(i),t(43)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i),window.Chart=e.exports=i},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,8:8,9:9}],8:[function(t,e,a){"use strict";e.exports=function(t){t.Bar=function(e,a){return a.type="bar",new t(e,a)}}},{}],9:[function(t,e,a){"use strict";e.exports=function(t){t.Bubble=function(e,a){return a.type="bubble",new t(e,a)}}},{}],10:[function(t,e,a){"use strict";e.exports=function(t){t.Doughnut=function(e,a){return a.type="doughnut",new t(e,a)}}},{}],11:[function(t,e,a){"use strict";e.exports=function(t){t.Line=function(e,a){return a.type="line",new t(e,a)}}},{}],12:[function(t,e,a){"use strict";e.exports=function(t){t.PolarArea=function(e,a){return a.type="polarArea",new t(e,a)}}},{}],13:[function(t,e,a){"use strict";e.exports=function(t){t.Radar=function(e,a){return a.options=t.helpers.configMerge({aspectRatio:1},a.options),a.type="radar",new t(e,a)}}},{}],14:[function(t,e,a){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(t,e){return""},label:function(t,e){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,a){return a.type="scatter",new t(e,a)}}},{}],15:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(e,a){t.DatasetController.prototype.initialize.call(this,e,a),this.getMeta().bar=!0},getBarCount:function(){var t=this,a=0;return e.each(t.chart.data.datasets,function(e,i){var n=t.chart.getDatasetMeta(i);n.bar&&t.chart.isDatasetVisible(i)&&++a},t),a},update:function(t){var a=this;e.each(a.getMeta().data,function(e,i){a.updateElement(e,i,t)},a)},updateElement:function(t,a,i){var n=this,o=n.getMeta(),r=n.getScaleForId(o.xAxisID),l=n.getScaleForId(o.yAxisID),s=l.getBasePixel(),d=n.chart.options.elements.rectangle,u=t.custom||{},c=n.getDataset();e.extend(t,{_xScale:r,_yScale:l,_datasetIndex:n.index,_index:a,_model:{x:n.calculateBarX(a,n.index),y:i?s:n.calculateBarY(a,n.index),label:n.chart.data.labels[a],datasetLabel:c.label,base:i?s:n.calculateBarBase(n.index,a),width:n.calculateBarWidth(a),backgroundColor:u.backgroundColor?u.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,a,d.backgroundColor),borderSkipped:u.borderSkipped?u.borderSkipped:d.borderSkipped,borderColor:u.borderColor?u.borderColor:e.getValueAtIndexOrDefault(c.borderColor,a,d.borderColor),borderWidth:u.borderWidth?u.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,a,d.borderWidth)}}),t.pivot()},calculateBarBase:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=0;if(n.options.stacked){var r=a.chart,l=r.data.datasets,s=l[t].data[e];if(0>s)for(var d=0;t>d;d++){var u=l[d],c=r.getDatasetMeta(d);c.bar&&c.yAxisID===n.id&&r.isDatasetVisible(d)&&(o+=u.data[e]<0?u.data[e]:0)}else for(var h=0;t>h;h++){var f=l[h],g=r.getDatasetMeta(h);g.bar&&g.yAxisID===n.id&&r.isDatasetVisible(h)&&(o+=f.data[e]>0?f.data[e]:0)}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(t){var e,a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=a.getBarCount();e="category"===n.options.type?n.getPixelForTick(t+1)-n.getPixelForTick(t):n.width/n.ticks.length;var r=e*n.options.categoryPercentage,l=(e-e*n.options.categoryPercentage)/2,s=r/o;if(n.ticks.length!==a.chart.data.labels.length){var d=n.ticks.length/a.chart.data.labels.length;s*=d}var u=s*n.options.barPercentage,c=s-s*n.options.barPercentage;return{datasetCount:o,tickWidth:e,categoryWidth:r,categorySpacing:l,fullBarWidth:s,barWidth:u,barSpacing:c}},calculateBarWidth:function(t){var e=this.getScaleForId(this.getMeta().xAxisID),a=this.getRuler(t);return e.options.stacked?a.categoryWidth:a.barWidth},getBarIndex:function(t){var e,a,i=0;for(a=0;t>a;++a)e=this.chart.getDatasetMeta(a),e.bar&&this.chart.isDatasetVisible(a)&&++i;return i},calculateBarX:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=a.getBarIndex(e),r=a.getRuler(t),l=n.getPixelForValue(null,t,e,a.chart.isCombo);return l-=a.chart.isCombo?r.tickWidth/2:0,n.options.stacked?l+r.categoryWidth/2+r.categorySpacing:l+r.barWidth/2+r.categorySpacing+r.barWidth*o+r.barSpacing/2+r.barSpacing*o},calculateBarY:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=a.getDataset().data[t];if(n.options.stacked){for(var r=0,l=0,s=0;e>s;s++){var d=a.chart.data.datasets[s],u=a.chart.getDatasetMeta(s);u.bar&&u.yAxisID===n.id&&a.chart.isDatasetVisible(s)&&(d.data[t]<0?l+=d.data[t]||0:r+=d.data[t]||0)}return 0>o?n.getPixelForValue(l+o):n.getPixelForValue(r+o)}return n.getPixelForValue(o)},draw:function(t){var a=this,i=t||1;e.each(a.getMeta().data,function(t,e){var n=a.getDataset().data[e];null===n||void 0===n||isNaN(n)||t.transition(i).draw()},a)},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.hoverBackgroundColor,i,e.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor?n.hoverBorderColor:e.getValueAtIndexOrDefault(a.hoverBorderColor,i,e.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:e.getValueAtIndexOrDefault(a.hoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model,r=this.chart.options.elements.rectangle;o.backgroundColor=n.backgroundColor?n.backgroundColor:e.getValueAtIndexOrDefault(a.backgroundColor,i,r.backgroundColor),o.borderColor=n.borderColor?n.borderColor:e.getValueAtIndexOrDefault(a.borderColor,i,r.borderColor),o.borderWidth=n.borderWidth?n.borderWidth:e.getValueAtIndexOrDefault(a.borderWidth,i,r.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var a="";return t.length>0&&(t[0].yLabel?a=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(a=e.labels[t[0].index])),a},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({updateElement:function(t,a,i,n){var o=this,r=o.getMeta(),l=o.getScaleForId(r.xAxisID),s=o.getScaleForId(r.yAxisID),d=l.getBasePixel(),u=t.custom||{},c=o.getDataset(),h=o.chart.options.elements.rectangle;e.extend(t,{_xScale:l,_yScale:s,_datasetIndex:o.index,_index:a,_model:{x:i?d:o.calculateBarX(a,o.index),y:o.calculateBarY(a,o.index),label:o.chart.data.labels[a],datasetLabel:c.label,base:i?d:o.calculateBarBase(o.index,a),height:o.calculateBarHeight(a),backgroundColor:u.backgroundColor?u.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,a,h.backgroundColor),borderSkipped:u.borderSkipped?u.borderSkipped:h.borderSkipped,borderColor:u.borderColor?u.borderColor:e.getValueAtIndexOrDefault(c.borderColor,a,h.borderColor),borderWidth:u.borderWidth?u.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,a,h.borderWidth)},draw:function(){function t(t){return s[(u+t)%4]}var e=this._chart.ctx,a=this._view,i=a.height/2,n=a.y-i,o=a.y+i,r=a.base-(a.base-a.x),l=a.borderWidth/2;a.borderWidth&&(n+=l,o-=l,r+=l),e.beginPath(),e.fillStyle=a.backgroundColor,e.strokeStyle=a.borderColor,e.lineWidth=a.borderWidth;var s=[[a.base,o],[a.base,n],[r,n],[r,o]],d=["bottom","left","top","right"],u=d.indexOf(a.borderSkipped,0);-1===u&&(u=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),a.borderWidth&&e.stroke()},inRange:function(t,e){var a=this._view,i=!1;return a&&(i=a.x<a.base?e>=a.y-a.height/2&&e<=a.y+a.height/2&&t>=a.x&&t<=a.base:e>=a.y-a.height/2&&e<=a.y+a.height/2&&t>=a.base&&t<=a.x),i}}),t.pivot()},calculateBarBase:function(t,e){
-var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=0;if(n.options.stacked){var r=a.chart.data.datasets[t].data[e];if(0>r)for(var l=0;t>l;l++){var s=a.chart.data.datasets[l],d=a.chart.getDatasetMeta(l);d.bar&&d.xAxisID===n.id&&a.chart.isDatasetVisible(l)&&(o+=s.data[e]<0?s.data[e]:0)}else for(var u=0;t>u;u++){var c=a.chart.data.datasets[u],h=a.chart.getDatasetMeta(u);h.bar&&h.xAxisID===n.id&&a.chart.isDatasetVisible(u)&&(o+=c.data[e]>0?c.data[e]:0)}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(t){var e,a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=a.getBarCount();e="category"===n.options.type?n.getPixelForTick(t+1)-n.getPixelForTick(t):n.width/n.ticks.length;var r=e*n.options.categoryPercentage,l=(e-e*n.options.categoryPercentage)/2,s=r/o;if(n.ticks.length!==a.chart.data.labels.length){var d=n.ticks.length/a.chart.data.labels.length;s*=d}var u=s*n.options.barPercentage,c=s-s*n.options.barPercentage;return{datasetCount:o,tickHeight:e,categoryHeight:r,categorySpacing:l,fullBarHeight:s,barHeight:u,barSpacing:c}},calculateBarHeight:function(t){var e=this,a=e.getScaleForId(e.getMeta().yAxisID),i=e.getRuler(t);return a.options.stacked?i.categoryHeight:i.barHeight},calculateBarX:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=a.getDataset().data[t];if(n.options.stacked){for(var r=0,l=0,s=0;e>s;s++){var d=a.chart.data.datasets[s],u=a.chart.getDatasetMeta(s);u.bar&&u.xAxisID===n.id&&a.chart.isDatasetVisible(s)&&(d.data[t]<0?l+=d.data[t]||0:r+=d.data[t]||0)}return 0>o?n.getPixelForValue(l+o):n.getPixelForValue(r+o)}return n.getPixelForValue(o)},calculateBarY:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=a.getBarIndex(e),r=a.getRuler(t),l=n.getPixelForValue(null,t,e,a.chart.isCombo);return l-=a.chart.isCombo?r.tickHeight/2:0,n.options.stacked?l+r.categoryHeight/2+r.categorySpacing:l+r.barHeight/2+r.categorySpacing+r.barHeight*o+r.barSpacing/2+r.barSpacing*o}})}},{}],16:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(t,e){return""},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return a+": ("+i.x+", "+i.y+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var a=this,i=a.getMeta(),n=i.data;e.each(n,function(e,i){a.updateElement(e,i,t)})},updateElement:function(a,i,n){var o=this,r=o.getMeta(),l=o.getScaleForId(r.xAxisID),s=o.getScaleForId(r.yAxisID),d=a.custom||{},u=o.getDataset(),c=u.data[i],h=o.chart.options.elements.point,f=o.index;e.extend(a,{_xScale:l,_yScale:s,_datasetIndex:f,_index:i,_model:{x:n?l.getPixelForDecimal(.5):l.getPixelForValue(c,i,f,o.chart.isCombo),y:n?s.getBasePixel():s.getPixelForValue(c,i,f),radius:n?0:d.radius?d.radius:o.getRadius(c),hitRadius:d.hitRadius?d.hitRadius:e.getValueAtIndexOrDefault(u.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(o,a,h);var g=a._model;g.skip=d.skip?d.skip:isNaN(g.x)||isNaN(g.y),a.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(a){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,a);var n=i.chart.data.datasets[a._datasetIndex],o=a._index,r=a.custom||{},l=a._model;l.radius=r.hoverRadius?r.hoverRadius:e.getValueAtIndexOrDefault(n.hoverRadius,o,i.chart.options.elements.point.hoverRadius)+i.getRadius(n.data[o])},removeHoverStyle:function(e){var a=this;t.DatasetController.prototype.removeHoverStyle.call(a,e,a.chart.options.elements.point);var i=a.chart.data.datasets[e._datasetIndex].data[e._index],n=e.custom||{},o=e._model;o.radius=n.radius?n.radius:a.getRadius(i)}})}},{}],17:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults;a.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),n[o]&&e.push(n[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],l=o.data[n],s=l.custom||{},d=e.getValueAtIndexOrDefault,u=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:d(r.backgroundColor,n,u.backgroundColor),h=s.borderColor?s.borderColor:d(r.borderColor,n,u.borderColor),f=s.borderWidth?s.borderWidth:d(r.borderWidth,n,u.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;i>a;++a)n=r.getDatasetMeta(a),n.data[o].hidden=!n.data[o].hidden;r.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+e.datasets[t.datasetIndex].data[t.index]}}}},a.pie=e.clone(a.doughnut),e.extend(a.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,a=0;t>a;++a)this.chart.isDatasetVisible(a)&&++e;return e},update:function(t){var a=this,i=a.chart,n=i.chartArea,o=i.options,r=o.elements.arc,l=n.right-n.left-r.borderWidth,s=n.bottom-n.top-r.borderWidth,d=Math.min(l,s),u={x:0,y:0},c=a.getMeta(),h=o.cutoutPercentage,f=o.circumference;if(f<2*Math.PI){var g=o.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},b={x:Math.cos(p),y:Math.sin(p)},v=0>=g&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,x=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,y=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,w={x:y?-1:Math.min(m.x*(m.x<0?1:S),b.x*(b.x<0?1:S)),y:k?-1:Math.min(m.y*(m.y<0?1:S),b.y*(b.y<0?1:S))},C={x:v?1:Math.max(m.x*(m.x>0?1:S),b.x*(b.x>0?1:S)),y:x?1:Math.max(m.y*(m.y>0?1:S),b.y*(b.y>0?1:S))},M={width:.5*(C.x-w.x),height:.5*(C.y-w.y)};d=Math.min(l/M.width,s/M.height),u={x:(C.x+w.x)*-.5,y:(C.y+w.y)*-.5}}i.outerRadius=Math.max(d/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=u.x*i.outerRadius,i.offsetY=u.y*i.outerRadius,c.total=a.calculateTotal(),a.outerRadius=i.outerRadius-i.radiusLength*a.getRingIndex(a.index),a.innerRadius=a.outerRadius-i.radiusLength,e.each(c.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){var n=this,o=n.chart,r=o.chartArea,l=o.options,s=l.animation,d=(l.elements.arc,(r.left+r.right)/2),u=(r.top+r.bottom)/2,c=l.rotation,h=l.rotation,f=n.getDataset(),g=i&&s.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[a])*(l.circumference/(2*Math.PI)),p=i&&s.animateScale?0:n.innerRadius,m=i&&s.animateScale?0:n.outerRadius,b=(t.custom||{},e.getValueAtIndexOrDefault);e.extend(t,{_datasetIndex:n.index,_index:a,_model:{x:d+o.offsetX,y:u+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:b(f.label,a,o.data.labels[a])}});var v=t._model;this.removeHoverStyle(t),i&&s.animateRotate||(0===a?v.startAngle=l.rotation:v.startAngle=n.getMeta().data[a-1]._model.endAngle,v.endAngle=v.startAngle+v.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,a=this.getDataset(),i=this.getMeta(),n=0;return e.each(i.data,function(e,i){t=a.data[i],isNaN(t)||e.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0}})}},{}],18:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return a.getValueOrDefault(t.showLine,e.showLines)}var a=t.helpers;t.defaults.line={showLines:!0,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,addElementAndReset:function(a){var i=this,n=i.chart.options,o=i.getMeta();t.DatasetController.prototype.addElementAndReset.call(i,a),e(i.getDataset(),n)&&0!==o.dataset._model.tension&&i.updateBezierControlPoints()},update:function(t){var i,n,o,r=this,l=r.getMeta(),s=l.dataset,d=l.data||[],u=r.chart.options,c=u.elements.line,h=r.getScaleForId(l.yAxisID),f=r.getDataset(),g=e(f,u);for(g&&(o=s.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),s._scale=h,s._datasetIndex=r.index,s._children=d,s._model={spanGaps:f.spanGaps?f.spanGaps:!1,tension:o.tension?o.tension:a.getValueOrDefault(f.lineTension,c.tension),backgroundColor:o.backgroundColor?o.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:f.borderWidth||c.borderWidth,borderColor:o.borderColor?o.borderColor:f.borderColor||c.borderColor,borderCapStyle:o.borderCapStyle?o.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:o.borderDash?o.borderDash:f.borderDash||c.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:o.fill?o.fill:void 0!==f.fill?f.fill:c.fill,scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},s.pivot()),i=0,n=d.length;n>i;++i)r.updateElement(d[i],i,t);for(g&&0!==s._model.tension&&r.updateBezierControlPoints(),i=0,n=d.length;n>i;++i)d[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,n=this.getDataset(),o=t.custom||{};return o.backgroundColor?i=o.backgroundColor:n.pointBackgroundColor?i=a.getValueAtIndexOrDefault(n.pointBackgroundColor,e,i):n.backgroundColor&&(i=n.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,n=this.getDataset(),o=t.custom||{};return o.borderColor?i=o.borderColor:n.pointBorderColor?i=a.getValueAtIndexOrDefault(n.pointBorderColor,e,i):n.borderColor&&(i=n.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,n=this.getDataset(),o=t.custom||{};return o.borderWidth?i=o.borderWidth:n.pointBorderWidth?i=a.getValueAtIndexOrDefault(n.pointBorderWidth,e,i):n.borderWidth&&(i=n.borderWidth),i},updateElement:function(t,e,i){var n,o,r=this,l=r.getMeta(),s=t.custom||{},d=r.getDataset(),u=r.index,c=d.data[e],h=r.getScaleForId(l.yAxisID),f=r.getScaleForId(l.xAxisID),g=r.chart.options.elements.point;void 0!==d.radius&&void 0===d.pointRadius&&(d.pointRadius=d.radius),void 0!==d.hitRadius&&void 0===d.pointHitRadius&&(d.pointHitRadius=d.hitRadius),n=f.getPixelForValue(c,e,u,r.chart.isCombo),o=i?h.getBasePixel():r.calculatePointY(c,e,u,r.chart.isCombo),t._xScale=f,t._yScale=h,t._datasetIndex=u,t._index=e,t._model={x:n,y:o,skip:s.skip||isNaN(n)||isNaN(o),radius:s.radius||a.getValueAtIndexOrDefault(d.pointRadius,e,g.radius),pointStyle:s.pointStyle||a.getValueAtIndexOrDefault(d.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:l.dataset._model?l.dataset._model.tension:0,hitRadius:s.hitRadius||a.getValueAtIndexOrDefault(d.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,a,i){var n,o,r,l=this,s=l.chart,d=l.getMeta(),u=l.getScaleForId(d.yAxisID),c=0,h=0;if(u.options.stacked){for(n=0;a>n;n++)o=s.data.datasets[n],r=s.getDatasetMeta(n),"line"===r.type&&s.isDatasetVisible(n)&&(o.data[e]<0?h+=o.data[e]||0:c+=o.data[e]||0);return 0>t?u.getPixelForValue(h+t):u.getPixelForValue(c+t)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,i,n,o,r=this.getMeta(),l=(this.chart.chartArea,r.data||[]);for(t=0,e=l.length;e>t;++t)i=l[t],n=i._model,o=a.splineCurve(a.previousItem(l,t)._model,n,a.nextItem(l,t)._model,r.dataset._model.tension),n.controlPointPreviousX=o.previous.x,n.controlPointPreviousY=o.previous.y,n.controlPointNextX=o.next.x,n.controlPointNextY=o.next.y},draw:function(t){var a,i,n=this,o=n.getMeta(),r=o.data||[],l=t||1;for(a=0,i=r.length;i>a;++a)r[a].transition(l);for(e(n.getDataset(),n.chart.options)&&o.dataset.transition(l).draw(),a=0,i=r.length;i>a;++a)r[a].draw()},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.radius=n.hoverRadius||a.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),o.backgroundColor=n.hoverBackgroundColor||a.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,a.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor||a.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,a.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth||a.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=o.radius||a.getValueAtIndexOrDefault(i.pointRadius,n,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,n),r.borderColor=e.getPointBorderColor(t,n),r.borderWidth=e.getPointBorderWidth(t,n)}})}},{}],19:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0},animation:{animateRotate:!0,animateScale:!0},aspectRatio:1,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'">'),n[o]&&e.push(n[o]),e.push("</span></li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],l=o.data[n],s=l.custom||{},d=e.getValueAtIndexOrDefault,u=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:d(r.backgroundColor,n,u.backgroundColor),h=s.borderColor?s.borderColor:d(r.borderColor,n,u.borderColor),f=s.borderWidth?s.borderWidth:d(r.borderWidth,n,u.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;i>a;++a)n=r.getDatasetMeta(a),n.data[o].hidden=!n.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var a=this,i=a.chart,n=i.chartArea,o=a.getMeta(),r=i.options,l=r.elements.arc,s=Math.min(n.right-n.left,n.bottom-n.top);i.outerRadius=Math.max((s-l.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),a.outerRadius=i.outerRadius-i.radiusLength*a.index,a.innerRadius=a.outerRadius-i.radiusLength,o.count=a.countVisibleElements(),e.each(o.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){for(var n=this,o=n.chart,r=o.chartArea,l=n.getDataset(),s=o.options,d=s.animation,u=(s.elements.arc,t.custom||{},o.scale),c=e.getValueAtIndexOrDefault,h=o.data.labels,f=n.calculateCircumference(l.data[a]),g=(r.left+r.right)/2,p=(r.top+r.bottom)/2,m=0,b=n.getMeta(),v=0;a>v;++v)isNaN(l.data[v])||b.data[v].hidden||++m;var x=-.5*Math.PI,y=t.hidden?0:u.getDistanceFromCenterForValue(l.data[a]),k=x+f*m,S=k+(t.hidden?0:f),w=d.animateScale?0:u.getDistanceFromCenterForValue(l.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:u,_model:{x:g,y:p,innerRadius:0,outerRadius:i?w:y,startAngle:i&&d.animateRotate?x:k,endAngle:i&&d.animateRotate?x:S,label:c(h,a,h[a])}}),n.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),a=this.getMeta(),i=0;return e.each(a.data,function(e,a){isNaN(t.data[a])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,addElementAndReset:function(e){t.DatasetController.prototype.addElementAndReset.call(this,e),this.updateBezierControlPoints()},update:function(t){var a=this,i=a.getMeta(),n=i.dataset,o=i.data,r=n.custom||{},l=a.getDataset(),s=a.chart.options.elements.line,d=a.chart.scale;void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),e.extend(i.dataset,{_datasetIndex:a.index,_children:o,_loop:!0,_model:{tension:r.tension?r.tension:e.getValueOrDefault(l.lineTension,s.tension),backgroundColor:r.backgroundColor?r.backgroundColor:l.backgroundColor||s.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:l.borderWidth||s.borderWidth,borderColor:r.borderColor?r.borderColor:l.borderColor||s.borderColor,fill:r.fill?r.fill:void 0!==l.fill?l.fill:s.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:l.borderCapStyle||s.borderCapStyle,borderDash:r.borderDash?r.borderDash:l.borderDash||s.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:l.borderDashOffset||s.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:l.borderJoinStyle||s.borderJoinStyle,scaleTop:d.top,scaleBottom:d.bottom,scaleZero:d.getBasePosition()}}),i.dataset.pivot(),e.each(o,function(e,i){a.updateElement(e,i,t)},a),a.updateBezierControlPoints()},updateElement:function(t,a,i){var n=this,o=t.custom||{},r=n.getDataset(),l=n.chart.scale,s=n.chart.options.elements.point,d=l.getPointPositionForValue(a,r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:l,_model:{x:i?l.xCenter:d.x,y:i?l.yCenter:d.y,tension:o.tension?o.tension:e.getValueOrDefault(r.tension,n.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,a,s.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,a,s.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,a,s.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,a,s.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,a,s.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.hitRadius,a,s.hitRadius)}}),t._model.skip=o.skip?o.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,a=this.getMeta();e.each(a.data,function(i,n){var o=i._model,r=e.splineCurve(e.previousItem(a.data,n,!0)._model,o,e.nextItem(a.data,n,!0)._model,o.tension);o.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),o.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),o.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),o.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var a=this.getMeta(),i=t||1;e.each(a.data,function(t,e){t.transition(i)}),a.dataset.transition(i).draw(),e.each(a.data,function(t){t.draw()})},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(a.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.pointHoverBackgroundColor,n,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(a.pointHoverBorderColor,n,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(a.pointHoverBorderWidth,n,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(a.radius,n,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(a.pointBackgroundColor,n,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(a.pointBorderColor,n,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(a.pointBorderWidth,n,r.borderWidth)}})}},{}],21:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,a,i){var n=this;i||(t.animating=!0);for(var o=0;o<n.animations.length;++o)if(n.animations[o].chartInstance===t)return void(n.animations[o].animationObject=e);n.animations.push({chartInstance:t,animationObject:e}),1===n.animations.length&&n.requestAnimationFrame()},cancelAnimation:function(t){var a=e.findIndex(this.animations,function(e){return e.chartInstance===t});-1!==a&&(this.animations.splice(a,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),a=0;t.dropFrames>1&&(a=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;i<t.animations.length;)null===t.animations[i].animationObject.currentStep&&(t.animations[i].animationObject.currentStep=0),t.animations[i].animationObject.currentStep+=1+a,t.animations[i].animationObject.currentStep>t.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var n=Date.now(),o=(n-e)/t.frameDuration;t.dropFrames+=o,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.types={},t.instances={},t.controllers={},t.Controller=function(a){return this.chart=a,this.config=a.config,this.options=this.config.options=e.configMerge(t.defaults.global,t.defaults[this.config.type],this.config.options||{}),this.id=e.uid(),Object.defineProperty(this,"data",{get:function(){return this.config.data}}),t.instances[this.id]=this,this.options.responsive&&this.resize(!0),this.initialize(),this},e.extend(t.Controller.prototype,{initialize:function(){var e=this;return t.plugins.notify("beforeInit",[e]),e.bindEvents(),e.ensureScalesHaveIDs(),e.buildOrUpdateControllers(),e.buildScales(),e.updateLayout(),e.resetElements(),e.initToolTip(),e.update(),t.plugins.notify("afterInit",[e]),e},clear:function(){return e.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(a){var i=this,n=i.chart,o=n.canvas,r=e.getMaximumWidth(o),l=n.aspectRatio,s=i.options.maintainAspectRatio&&isNaN(l)===!1&&isFinite(l)&&0!==l?r/l:e.getMaximumHeight(o),d=n.width!==r||n.height!==s;if(!d)return i;o.width=n.width=r,o.height=n.height=s,e.retinaScale(n);var u={width:r,height:s};return t.plugins.notify("resize",[i,u]),i.options.onResize&&i.options.onResize(i,u),a||(i.stop(),i.update(i.options.responsiveAnimationDuration)),i},ensureScalesHaveIDs:function(){var t=this.options,a=t.scales||{},i=t.scale;e.each(a.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),e.each(a.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildScales:function(){var a=this,i=a.options,n=a.scales={},o=[];i.scales&&(o=o.concat((i.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(i.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),i.scale&&o.push({options:i.scale,dtype:"radialLinear",isDefault:!0}),e.each(o,function(i,o){var r=i.options,l=e.getValueOrDefault(r.type,i.dtype),s=t.scaleService.getScaleConstructor(l);if(s){var d=new s({id:r.id,options:r,ctx:a.chart.ctx,chart:a});n[d.id]=d,i.isDefault&&(a.scale=d)}}),t.scaleService.addScalesToLayout(this)},updateLayout:function(){t.layoutService.update(this,this.chart.width,this.chart.height)},buildOrUpdateControllers:function(){var a=this,i=[],n=[];if(e.each(a.data.datasets,function(e,o){var r=a.getDatasetMeta(o);r.type||(r.type=e.type||a.config.type),i.push(r.type),r.controller?r.controller.updateIndex(o):(r.controller=new t.controllers[r.type](a,o),n.push(r.controller))},a),i.length>1)for(var o=1;o<i.length;o++)if(i[o]!==i[o-1]){a.isCombo=!0;break}return n},resetElements:function(){var t=this;e.each(t.data.datasets,function(e,a){t.getDatasetMeta(a).controller.reset()},t)},update:function(a,i){var n=this;t.plugins.notify("beforeUpdate",[n]),n.tooltip._data=n.data;var o=n.buildOrUpdateControllers();e.each(n.data.datasets,function(t,e){n.getDatasetMeta(e).controller.buildOrUpdateElements()},n),t.layoutService.update(n,n.chart.width,n.chart.height),t.plugins.notify("afterScaleUpdate",[n]),e.each(o,function(t){t.reset()}),n.updateDatasets(),t.plugins.notify("afterUpdate",[n]),n.render(a,i)},updateDatasets:function(){var e,a,i=this;if(t.plugins.notify("beforeDatasetsUpdate",[i])){for(e=0,a=i.data.datasets.length;a>e;++e)i.getDatasetMeta(e).controller.update();t.plugins.notify("afterDatasetsUpdate",[i])}},render:function(a,i){var n=this;t.plugins.notify("beforeRender",[n]);var o=n.options.animation;if(o&&("undefined"!=typeof a&&0!==a||"undefined"==typeof a&&0!==o.duration)){var r=new t.Animation;r.numSteps=(a||o.duration)/16.66,r.easing=o.easing,r.render=function(t,a){var i=e.easingEffects[a.easing],n=a.currentStep/a.numSteps,o=i(n);t.draw(o,n,a.currentStep)},r.onAnimationProgress=o.onProgress,r.onAnimationComplete=o.onComplete,t.animationService.addAnimation(n,r,a,i)}else n.draw(),o&&o.onComplete&&o.onComplete.call&&o.onComplete.call(n);return n},draw:function(a){var i=this,n=a||1;i.clear(),t.plugins.notify("beforeDraw",[i,n]),e.each(i.boxes,function(t){t.draw(i.chartArea)},i),i.scale&&i.scale.draw(),t.plugins.notify("beforeDatasetsDraw",[i,n]),e.each(i.data.datasets,function(t,e){i.isDatasetVisible(e)&&i.getDatasetMeta(e).controller.draw(a)},i,!0),t.plugins.notify("afterDatasetsDraw",[i,n]),i.tooltip.transition(n).draw(),t.plugins.notify("afterDraw",[i,n])},getElementAtEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[];return e.each(a.data.datasets,function(t,o){if(a.isDatasetVisible(o)){var r=a.getDatasetMeta(o);e.each(r.data,function(t,e){return t.inRange(i.x,i.y)?(n.push(t),n):void 0})}}),n},getElementsAtEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[],o=function(){if(a.data.datasets)for(var t=0;t<a.data.datasets.length;t++){var e=a.getDatasetMeta(t);if(a.isDatasetVisible(t))for(var n=0;n<e.data.length;n++)if(e.data[n].inRange(i.x,i.y))return e.data[n]}}.call(a);return o?(e.each(a.data.datasets,function(t,e){if(a.isDatasetVisible(e)){var i=a.getDatasetMeta(e);n.push(i.data[o._index])}},a),n):n},getElementsAtEventForMode:function(t,e){var a=this;switch(e){case"single":return a.getElementAtEvent(t);case"label":return a.getElementsAtEvent(t);case"dataset":return a.getDatasetAtEvent(t);default:return t}},getDatasetAtEvent:function(t){var e=this.getElementAtEvent(t);return e.length>0&&(e=this.getDatasetMeta(e[0]._datasetIndex).data),e},getDatasetMeta:function(t){var e=this,a=e.data.datasets[t];a._meta||(a._meta={});var i=a._meta[e.id];return i||(i=a._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,a=this.data.datasets.length;a>e;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var a=this;a.stop(),a.clear(),e.unbindEvents(a,a.events),e.removeResizeListener(a.chart.canvas.parentNode);var i=a.chart.canvas;i.width=a.chart.width,i.height=a.chart.height,void 0!==a.chart.originalDevicePixelRatio&&a.chart.ctx.scale(1/a.chart.originalDevicePixelRatio,1/a.chart.originalDevicePixelRatio),i.style.width=a.chart.originalCanvasStyleWidth,i.style.height=a.chart.originalCanvasStyleHeight,t.plugins.notify("destroy",[a]),delete t.instances[a.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e.chart,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this;e.bindEvents(t,t.options.events,function(e){t.eventHandler(e)})},updateHoverStyle:function(t,e,a){var i,n,o,r=a?"setHoverStyle":"removeHoverStyle";switch(e){case"single":t=[t[0]];break;case"label":case"dataset":break;default:return}for(n=0,o=t.length;o>n;++n)i=t[n],i&&this.getDatasetMeta(i._datasetIndex).controller[r](i)},eventHandler:function(t){var a=this,i=a.tooltip,n=a.options||{},o=n.hover,r=n.tooltips;return a.lastActive=a.lastActive||[],a.lastTooltipActive=a.lastTooltipActive||[],"mouseout"===t.type?(a.active=[],a.tooltipActive=[]):(a.active=a.getElementsAtEventForMode(t,o.mode),a.tooltipActive=a.getElementsAtEventForMode(t,r.mode)),o.onHover&&o.onHover.call(a,a.active),("mouseup"===t.type||"click"===t.type)&&(n.onClick&&n.onClick.call(a,t,a.active),a.legend&&a.legend.handleEvent&&a.legend.handleEvent(t)),a.lastActive.length&&a.updateHoverStyle(a.lastActive,o.mode,!1),a.active.length&&o.mode&&a.updateHoverStyle(a.active,o.mode,!0),(r.enabled||r.custom)&&(i.initialize(),i._active=a.tooltipActive,i.update(!0)),i.pivot(),a.animating||e.arrayEquals(a.active,a.lastActive)&&e.arrayEquals(a.tooltipActive,a.lastTooltipActive)||(a.stop(),(r.enabled||r.custom)&&i.update(!0),a.render(o.animationDuration,!0)),a.lastActive=a.active,a.lastTooltipActive=a.tooltipActive,a}})}},{}],23:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.DatasetController=function(t,e){this.initialize.call(this,t,e)},e.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var a=this;a.chart=t,a.index=e,a.linkScales(),a.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),a=t.getDataset();null===e.xAxisID&&(e.xAxisID=a.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=a.yAxisID||t.chart.options.scales.yAxes[0].id);
-},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,a=e.dataElementType;return a&&new a({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,a=this,i=a.getMeta(),n=a.getDataset().data||[],o=i.data;for(t=0,e=n.length;e>t;++t)o[t]=o[t]||a.createMetaData(i,t);i.dataset=i.dataset||a.createMetaDataset()},addElementAndReset:function(t){var e=this,a=e.createMetaData(t);e.getMeta().data.splice(t,0,a),e.updateElement(a,t,!0)},buildOrUpdateElements:function(){var t=this.getMeta(),e=t.data,a=this.getDataset().data.length,i=e.length;if(i>a)e.splice(a,i-a);else if(a>i)for(var n=i;a>n;++n)this.addElementAndReset(n)},update:a,draw:function(t){var a=t||1;e.each(this.getMeta().data,function(t,e){t.transition(a).draw()})},removeHoverStyle:function(t,a){var i=this.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=e.getValueAtIndexOrDefault,l=(e.color,t._model);l.backgroundColor=o.backgroundColor?o.backgroundColor:r(i.backgroundColor,n,a.backgroundColor),l.borderColor=o.borderColor?o.borderColor:r(i.borderColor,n,a.borderColor),l.borderWidth=o.borderWidth?o.borderWidth:r(i.borderWidth,n,a.borderWidth)},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=e.getValueAtIndexOrDefault,r=(e.color,e.getHoverColor),l=t._model;l.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:o(a.hoverBackgroundColor,i,r(l.backgroundColor)),l.borderColor=n.hoverBorderColor?n.hoverBorderColor:o(a.hoverBorderColor,i,r(l.borderColor)),l.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:o(a.hoverBorderWidth,i,l.borderWidth)}}),t.DatasetController.extend=e.inherits}},{}],24:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=e.clone(t._model)),t._start=e.clone(t._view),t},transition:function(t){var a=this;return a._view||(a._view=e.clone(a._model)),1===t?(a._view=a._model,a._start=null,a):(a._start||a.pivot(),e.each(a._model,function(i,n){if("_"===n[0]);else if(a._view.hasOwnProperty(n))if(i===a._view[n]);else if("string"==typeof i)try{var o=e.color(a._model[n]).mix(e.color(a._start[n]),t);a._view[n]=o.rgbString()}catch(r){a._view[n]=i}else if("number"==typeof i){var l=void 0!==a._start[n]&&isNaN(a._start[n])===!1?a._start[n]:0;a._view[n]=(a._model[n]-l)*t+l}else a._view[n]=i;else"number"!=typeof i||isNaN(a._view[n])?a._view[n]=i:a._view[n]=i*t},a),a)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],25:[function(t,e,a){"use strict";var i=t(3);e.exports=function(t){function e(t,e,a){var i;return"string"==typeof t?(i=parseInt(t,10),-1!=t.indexOf("%")&&(i=i/100*e.parentNode[a])):i=t,i}function a(t){return void 0!==t&&null!==t&&"none"!==t}function n(t,i,n){var o=document.defaultView,r=t.parentNode,l=o.getComputedStyle(t)[i],s=o.getComputedStyle(r)[i],d=a(l),u=a(s),c=Number.POSITIVE_INFINITY;return d||u?Math.min(d?e(l,t,n):c,u?e(s,r,n):c):"none"}var o=t.helpers={};o.each=function(t,e,a,i){var n,r;if(o.isArray(t))if(r=t.length,i)for(n=r-1;n>=0;n--)e.call(a,t[n],n);else for(n=0;r>n;n++)e.call(a,t[n],n);else if("object"==typeof t){var l=Object.keys(t);for(r=l.length,n=0;r>n;n++)e.call(a,t[l[n]],l[n])}},o.clone=function(t){var e={};return o.each(t,function(t,a){o.isArray(t)?e[a]=t.slice(0):"object"==typeof t&&null!==t?e[a]=o.clone(t):e[a]=t}),e},o.extend=function(t){for(var e=function(e,a){t[a]=e},a=1,i=arguments.length;i>a;a++)o.each(arguments[a],e);return t},o.configMerge=function(e){var a=o.clone(e);return o.each(Array.prototype.slice.call(arguments,1),function(e){o.each(e,function(e,i){if("scales"===i)a[i]=o.scaleMerge(a.hasOwnProperty(i)?a[i]:{},e);else if("scale"===i)a[i]=o.configMerge(a.hasOwnProperty(i)?a[i]:{},t.scaleService.getScaleDefaults(e.type),e);else if(a.hasOwnProperty(i)&&o.isArray(a[i])&&o.isArray(e)){var n=a[i];o.each(e,function(t,e){e<n.length?"object"==typeof n[e]&&null!==n[e]&&"object"==typeof t&&null!==t?n[e]=o.configMerge(n[e],t):n[e]=t:n.push(t)})}else a.hasOwnProperty(i)&&"object"==typeof a[i]&&null!==a[i]&&"object"==typeof e?a[i]=o.configMerge(a[i],e):a[i]=e})}),a},o.scaleMerge=function(e,a){var i=o.clone(e);return o.each(a,function(e,a){"xAxes"===a||"yAxes"===a?i.hasOwnProperty(a)?o.each(e,function(e,n){var r=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear"),l=t.scaleService.getScaleDefaults(r);n>=i[a].length||!i[a][n].type?i[a].push(o.configMerge(l,e)):e.type&&e.type!==i[a][n].type?i[a][n]=o.configMerge(i[a][n],l,e):i[a][n]=o.configMerge(i[a][n],e)}):(i[a]=[],o.each(e,function(e){var n=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear");i[a].push(o.configMerge(t.scaleService.getScaleDefaults(n),e))})):i.hasOwnProperty(a)&&"object"==typeof i[a]&&null!==i[a]&&"object"==typeof e?i[a]=o.configMerge(i[a],e):i[a]=e}),i},o.getValueAtIndexOrDefault=function(t,e,a){return void 0===t||null===t?a:o.isArray(t)?e<t.length?t[e]:a:t},o.getValueOrDefault=function(t,e){return void 0===t?e:t},o.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var a=0,i=t.length;i>a;++a)if(t[a]===e)return a;return-1},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var a=[];return o.each(t,function(t){e(t)&&a.push(t)}),a},o.findIndex=Array.prototype.findIndex?function(t,e,a){return t.findIndex(e,a)}:function(t,e,a){a=void 0===a?t:a;for(var i=0,n=t.length;n>i;++i)if(e.call(a,t[i],i,t))return i;return-1},o.findNextWhere=function(t,e,a){(void 0===a||null===a)&&(a=-1);for(var i=a+1;i<t.length;i++){var n=t[i];if(e(n))return n}},o.findPreviousWhere=function(t,e,a){(void 0===a||null===a)&&(a=t.length);for(var i=a-1;i>=0;i--){var n=t[i];if(e(n))return n}},o.inherits=function(t){var e=this,a=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=a};return i.prototype=e.prototype,a.prototype=new i,a.extend=o.inherits,t&&o.extend(a.prototype,t),a.__super__=e.prototype,a},o.noop=function(){},o.uid=function(){var t=0;return function(){return t++}}(),o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,a){return Math.abs(t-e)<a},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var a=e.x-t.x,i=e.y-t.y,n=Math.sqrt(a*a+i*i),o=Math.atan2(i,a);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:n}},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,a,i){var n=t.skip?e:t,o=e,r=a.skip?e:a,l=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),s=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),d=l/(l+s),u=s/(l+s);d=isNaN(d)?0:d,u=isNaN(u)?0:u;var c=i*d,h=i*u;return{previous:{x:o.x-c*(r.x-n.x),y:o.y-c*(r.y-n.y)},next:{x:o.x+h*(r.x-n.x),y:o.y+h*(r.y-n.y)}}},o.nextItem=function(t,e,a){return a?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,a){return a?0>=e?t[t.length-1]:t[e-1]:0>=e?t[0]:t[e-1]},o.niceNum=function(t,e){var a,i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return a=e?1.5>n?1:3>n?2:7>n?5:10:1>=n?1:2>=n?2:5>=n?5:10,a*Math.pow(10,i)};var r=o.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)))},easeOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/a)+1)},easeInOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:2===(t/=.5)?1:(a||(a=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),1>t?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-r.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*r.easeInBounce(2*t):.5*r.easeOutBounce(2*t-1)+.5}};o.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),o.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),o.getRelativePosition=function(t,e){var a,i,n=t.originalEvent||t,r=t.currentTarget||t.srcElement,l=r.getBoundingClientRect(),s=n.touches;s&&s.length>0?(a=s[0].clientX,i=s[0].clientY):(a=n.clientX,i=n.clientY);var d=parseFloat(o.getStyle(r,"padding-left")),u=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=l.right-l.left-d-c,g=l.bottom-l.top-u-h;return a=Math.round((a-l.left-d)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-l.top-u)/g*r.height/e.currentDevicePixelRatio),{x:a,y:i}},o.addEvent=function(t,e,a){t.addEventListener?t.addEventListener(e,a):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a},o.removeEvent=function(t,e,a){t.removeEventListener?t.removeEventListener(e,a,!1):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=o.noop},o.bindEvents=function(t,e,a){var i=t.events=t.events||{};o.each(e,function(e){i[e]=function(){a.apply(t,arguments)},o.addEvent(t.chart.canvas,e,i[e])})},o.unbindEvents=function(t,e){var a=t.chart.canvas;o.each(e,function(t,e){o.removeEvent(a,e,t)})},o.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-left"))+parseInt(o.getStyle(e,"padding-right")),i=e.clientWidth-a,n=o.getConstraintWidth(t);return isNaN(n)?i:Math.min(i,n)},o.getMaximumHeight=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-top"))+parseInt(o.getStyle(e,"padding-bottom")),i=e.clientHeight-a,n=o.getConstraintHeight(t);return isNaN(n)?i:Math.min(i,n)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t){var e=t.ctx,a=t.canvas,i=a.width,n=a.height,o=t.currentDevicePixelRatio=window.devicePixelRatio||1;1!==o&&(a.height=n*o,a.width=i*o,e.scale(o,o),t.originalDevicePixelRatio=t.originalDevicePixelRatio||o),a.style.width=i+"px",a.style.height=n+"px"},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,a){return e+" "+t+"px "+a},o.longestText=function(t,e,a,i){i=i||{};var n=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(n=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var l=0;o.each(a,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?l=o.measureText(t,n,r,l,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(l=o.measureText(t,n,r,l,e))})});var s=r.length/2;if(s>a.length){for(var d=0;s>d;d++)delete n[r[d]];r.splice(0,s)}return l},o.measureText=function(t,e,a,i,n){var o=e[n];return o||(o=e[n]=t.measureText(n).width,a.push(n)),o>i&&(i=o),i},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.drawRoundedRectangle=function(t,e,a,i,n,o){t.beginPath(),t.moveTo(e+o,a),t.lineTo(e+i-o,a),t.quadraticCurveTo(e+i,a,e+i,a+o),t.lineTo(e+i,a+n-o),t.quadraticCurveTo(e+i,a+n,e+i-o,a+n),t.lineTo(e+o,a+n),t.quadraticCurveTo(e,a+n,e,a+n-o),t.lineTo(e,a+o),t.quadraticCurveTo(e,a,e+o,a),t.closePath()},o.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.log("Color.js not found!"),e)},o.addResizeListener=function(t,e){var a=document.createElement("iframe"),i="chartjs-hidden-iframe";a.classlist?a.classlist.add(i):a.setAttribute("class",i);var n=a.style;n.width="100%",n.display="block",n.border=0,n.height=0,n.margin=0,n.position="absolute",n.left=0,n.right=0,n.top=0,n.bottom=0,t.insertBefore(a,t.firstChild),(a.contentWindow||a).onresize=function(){e&&e()}},o.removeResizeListener=function(t){var e=t.querySelector(".chartjs-hidden-iframe");e&&e.parentNode.removeChild(e)},o.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},o.arrayEquals=function(t,e){var a,i,n,r;if(!t||!e||t.length!=e.length)return!1;for(a=0,i=t.length;i>a;++a)if(n=t[a],r=e[a],n instanceof Array&&r instanceof Array){if(!o.arrayEquals(n,r))return!1}else if(n!=r)return!1;return!0},o.callCallback=function(t,e,a){t&&"function"==typeof t.call&&t.apply(a,e)},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{3:3}],26:[function(t,e,a){"use strict";e.exports=function(){var t=function(e,a){var i=this,n=t.helpers;return i.config=a,e.length&&e[0].getContext&&(e=e[0]),e.getContext&&(e=e.getContext("2d")),i.ctx=e,i.canvas=e.canvas,e.canvas.style.display=e.canvas.style.display||"block",i.width=e.canvas.width||parseInt(n.getStyle(e.canvas,"width"),10)||n.getMaximumWidth(e.canvas),i.height=e.canvas.height||parseInt(n.getStyle(e.canvas,"height"),10)||n.getMaximumHeight(e.canvas),i.aspectRatio=i.width/i.height,(isNaN(i.aspectRatio)||isFinite(i.aspectRatio)===!1)&&(i.aspectRatio=void 0!==a.aspectRatio?a.aspectRatio:2),i.originalCanvasStyleWidth=e.canvas.style.width,i.originalCanvasStyleHeight=e.canvas.style.height,n.retinaScale(i),a&&(i.controller=new t.Controller(i)),n.addResizeListener(e.canvas.parentNode,function(){i.controller&&i.controller.config.options.responsive&&i.controller.resize()}),i.controller?i.controller:i};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"single",animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var a=0;a<t.data.datasets.length;a++)e.push('<li><span style="background-color:'+t.data.datasets[a].backgroundColor+'"></span>'),t.data.datasets[a].label&&e.push(t.data.datasets[a].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],27:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,a,i){function n(t){var e,a=t.isHorizontal();a?(e=t.update(t.options.fullWidth?p:k,y),S-=e.height):(e=t.update(x,v),k-=e.width),w.push({horizontal:a,minSize:e,box:t})}function o(t){var a=e.findNextWhere(w,function(e){return e.box===t});if(a)if(t.isHorizontal()){var i={left:C,right:M,top:0,bottom:0};t.update(t.options.fullWidth?p:k,m/2,i)}else t.update(a.minSize.width,S)}function r(t){var a=e.findNextWhere(w,function(e){return e.box===t}),i={left:0,right:0,top:D,bottom:A};a&&t.update(a.minSize.width,S,i)}function l(t){t.isHorizontal()?(t.left=t.options.fullWidth?s:C,t.right=t.options.fullWidth?a-s:C+k,t.top=P,t.bottom=P+t.height,P=t.bottom):(t.left=T,t.right=T+t.width,t.top=D,t.bottom=D+S,T=t.right)}if(t){var s=0,d=0,u=e.where(t.boxes,function(t){return"left"===t.options.position}),c=e.where(t.boxes,function(t){return"right"===t.options.position}),h=e.where(t.boxes,function(t){return"top"===t.options.position}),f=e.where(t.boxes,function(t){return"bottom"===t.options.position}),g=e.where(t.boxes,function(t){return"chartArea"===t.options.position});h.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),f.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var p=a-2*s,m=i-2*d,b=p/2,v=m/2,x=(a-b)/(u.length+c.length),y=(i-v)/(h.length+f.length),k=p,S=m,w=[];e.each(u.concat(c,h,f),n);var C=s,M=s,D=d,A=d;e.each(u.concat(c),o),e.each(u,function(t){C+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h.concat(f),o),e.each(h,function(t){D+=t.height}),e.each(f,function(t){A+=t.height}),e.each(u.concat(c),r),C=s,M=s,D=d,A=d,e.each(u,function(t){C+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h,function(t){D+=t.height}),e.each(f,function(t){A+=t.height});var I=i-D-A,F=a-C-M;(F!==k||I!==S)&&(e.each(u,function(t){t.height=I}),e.each(c,function(t){t.height=I}),e.each(h,function(t){t.options.fullWidth||(t.width=F)}),e.each(f,function(t){t.options.fullWidth||(t.width=F)}),S=I,k=F);var T=s,P=d;e.each(u.concat(h),l),T+=k,P+=S,e.each(c,l),e.each(f,l),t.chartArea={left:C,top:D,right:C+k,bottom:D+S},e.each(g,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(k,S)})}}}}},{}],28:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var a=e.datasetIndex,i=this.chart,n=i.getDatasetMeta(a);n.hidden=null===n.hidden?!i.data.datasets[a].hidden:null,i.update()},labels:{boxWidth:40,padding:10,generateLabels:function(t){var a=t.data;return e.isArray(a.datasets)?a.datasets.map(function(a,i){return{text:a.label,fillStyle:e.isArray(a.backgroundColor)?a.backgroundColor[0]:a.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,datasetIndex:i}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){e.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:a,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:a,beforeSetDimensions:a,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:a,beforeBuildLabels:a,buildLabels:function(){var t=this;t.legendItems=t.options.labels.generateLabels.call(t,t.chart),t.options.reverse&&t.legendItems.reverse()},afterBuildLabels:a,beforeFit:a,fit:function(){var a=this,i=a.options,n=i.labels,o=i.display,r=a.ctx,l=t.defaults.global,s=e.getValueOrDefault,d=s(n.fontSize,l.defaultFontSize),u=s(n.fontStyle,l.defaultFontStyle),c=s(n.fontFamily,l.defaultFontFamily),h=e.fontString(d,u,c),f=a.legendHitBoxes=[],g=a.minSize,p=a.isHorizontal();if(p?(g.width=a.maxWidth,g.height=o?10:0):(g.width=o?10:0,g.height=a.maxHeight),o)if(r.font=h,p){var m=a.lineWidths=[0],b=a.legendItems.length?d+n.padding:0;r.textAlign="left",r.textBaseline="top",e.each(a.legendItems,function(t,e){var i=n.boxWidth+d/2+r.measureText(t.text).width;m[m.length-1]+i+n.padding>=a.width&&(b+=d+n.padding,m[m.length]=a.left),f[e]={left:0,top:0,width:i,height:d},m[m.length-1]+=i+n.padding}),g.height+=b}else{var v=n.padding,x=a.columnWidths=[],y=n.padding,k=0,S=0,w=d+v;e.each(a.legendItems,function(t,e){var a=n.boxWidth+d/2+r.measureText(t.text).width;S+w>g.height&&(y+=k+n.padding,x.push(k),k=0,S=0),k=Math.max(k,a),S+=w,f[e]={left:0,top:0,width:a,height:d}}),y+=k,x.push(k),g.width+=y}a.width=g.width,a.height=g.height},afterFit:a,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var a=this,i=a.options,n=i.labels,o=t.defaults.global,r=o.elements.line,l=a.width,s=(a.height,a.lineWidths);if(i.display){var d,u=a.ctx,c=e.getValueOrDefault,h=c(n.fontColor,o.defaultFontColor),f=c(n.fontSize,o.defaultFontSize),g=c(n.fontStyle,o.defaultFontStyle),p=c(n.fontFamily,o.defaultFontFamily),m=e.fontString(f,g,p);u.textAlign="left",u.textBaseline="top",u.lineWidth=.5,u.strokeStyle=h,u.fillStyle=h,u.font=m;var b=n.boxWidth,v=a.legendHitBoxes,x=function(t,e,a){u.save(),u.fillStyle=c(a.fillStyle,o.defaultColor),u.lineCap=c(a.lineCap,r.borderCapStyle),u.lineDashOffset=c(a.lineDashOffset,r.borderDashOffset),u.lineJoin=c(a.lineJoin,r.borderJoinStyle),u.lineWidth=c(a.lineWidth,r.borderWidth),u.strokeStyle=c(a.strokeStyle,o.defaultColor),u.setLineDash&&u.setLineDash(c(a.lineDash,r.borderDash)),u.strokeRect(t,e,b,f),u.fillRect(t,e,b,f),u.restore()},y=function(t,e,a,i){u.fillText(a.text,b+f/2+t,e),a.hidden&&(u.beginPath(),u.lineWidth=2,u.moveTo(b+f/2+t,e+f/2),u.lineTo(b+f/2+t+i,e+f/2),u.stroke())},k=a.isHorizontal();d=k?{x:a.left+(l-s[0])/2,y:a.top+n.padding,line:0}:{x:a.left+n.padding,y:a.top,line:0};var S=f+n.padding;e.each(a.legendItems,function(t,e){var i=u.measureText(t.text).width,o=b+f/2+i,r=d.x,c=d.y;k?r+o>=l&&(c=d.y+=f+n.padding,d.line++,r=d.x=a.left+(l-s[d.line])/2):c+S>a.bottom&&(r=d.x=r+a.columnWidths[d.line]+n.padding,c=d.y=a.top,d.line++),x(r,c,t),v[e].left=r,v[e].top=c,y(r,c,t,i),k?d.x+=o+n.padding:d.y+=S})}},handleEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart.chart),n=i.x,o=i.y,r=a.options;if(n>=a.left&&n<=a.right&&o>=a.top&&o<=a.bottom)for(var l=a.legendHitBoxes,s=0;s<l.length;++s){var d=l[s];if(n>=d.left&&n<=d.left+d.width&&o>=d.top&&o<=d.top+d.height){r.onClick&&r.onClick.call(a,t,a.legendItems[s]);break}}}}),t.plugins.register({beforeInit:function(e){var a=e.options,i=a.legend;i&&(e.legend=new t.Legend({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.legend))}})}},{}],29:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers.noop;t.plugins={_plugins:[],register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)})},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var a=e.indexOf(t);-1!==a&&e.splice(a,1)})},clear:function(){this._plugins=[]},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e){var a,i,n=this._plugins,o=n.length;for(a=0;o>a;++a)if(i=n[a],"function"==typeof i[t]&&i[t].apply(i,e||[])===!1)return!1;return!0}},t.PluginBase=t.Element.extend({beforeInit:e,afterInit:e,beforeUpdate:e,afterUpdate:e,beforeDraw:e,afterDraw:e,destroy:e}),t.pluginService=t.plugins}},{}],30:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:10,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:function(t){return e.isArray(t)?t:""+t}}},t.Scale=t.Element.extend({beforeUpdate:function(){e.callCallback(this.options.beforeUpdate,[this])},update:function(t,a,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=a,n.margins=e.extend({left:0,right:0,top:0,bottom:0},i),n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeDataLimits(),n.determineDataLimits(),n.afterDataLimits(),n.beforeBuildTicks(),n.buildTicks(),n.afterBuildTicks(),n.beforeTickToLabelConversion(),n.convertTicksToLabels(),n.afterTickToLabelConversion(),n.beforeCalculateTickRotation(),n.calculateTickRotation(),n.afterCalculateTickRotation(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:function(){e.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){e.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){e.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){e.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:e.noop,afterDataLimits:function(){e.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){e.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:e.noop,afterBuildTicks:function(){e.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){e.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this;t.ticks=t.ticks.map(function(e,a,i){return t.options.ticks.userCallback?t.options.ticks.userCallback(e,a,i):t.options.ticks.callback(e,a,i)},t)},afterTickToLabelConversion:function(){e.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){e.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var a=this,i=a.ctx,n=t.defaults.global,o=a.options.ticks,r=e.getValueOrDefault(o.fontSize,n.defaultFontSize),l=e.getValueOrDefault(o.fontStyle,n.defaultFontStyle),s=e.getValueOrDefault(o.fontFamily,n.defaultFontFamily),d=e.fontString(r,l,s);i.font=d;var u,c=i.measureText(a.ticks[0]).width,h=i.measureText(a.ticks[a.ticks.length-1]).width;if(a.labelRotation=o.minRotation||0,a.paddingRight=0,a.paddingLeft=0,a.options.display&&a.isHorizontal()){a.paddingRight=h/2+3,a.paddingLeft=c/2+3,a.longestTextCache||(a.longestTextCache={});for(var f,g,p=e.longestText(i,d,a.ticks,a.longestTextCache),m=p,b=a.getPixelForTick(1)-a.getPixelForTick(0)-6;m>b&&a.labelRotation<o.maxRotation;){if(f=Math.cos(e.toRadians(a.labelRotation)),g=Math.sin(e.toRadians(a.labelRotation)),u=f*c,u+r/2>a.yLabelWidth&&(a.paddingLeft=u+r/2),a.paddingRight=r/2,g*p>a.maxHeight){a.labelRotation--;break}a.labelRotation++,m=f*p}}a.margins&&(a.paddingLeft=Math.max(a.paddingLeft-a.margins.left,0),a.paddingRight=Math.max(a.paddingRight-a.margins.right,0))},afterCalculateTickRotation:function(){e.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){e.callCallback(this.options.beforeFit,[this])},fit:function(){var a=this,i=a.minSize={width:0,height:0},n=a.options,o=t.defaults.global,r=n.ticks,l=n.scaleLabel,s=n.display,d=a.isHorizontal(),u=e.getValueOrDefault(r.fontSize,o.defaultFontSize),c=e.getValueOrDefault(r.fontStyle,o.defaultFontStyle),h=e.getValueOrDefault(r.fontFamily,o.defaultFontFamily),f=e.fontString(u,c,h),g=e.getValueOrDefault(l.fontSize,o.defaultFontSize),p=e.getValueOrDefault(l.fontStyle,o.defaultFontStyle),m=e.getValueOrDefault(l.fontFamily,o.defaultFontFamily),b=(e.fontString(g,p,m),n.gridLines.tickMarkLength);if(d?i.width=a.isFullWidth()?a.maxWidth-a.margins.left-a.margins.right:a.maxWidth:i.width=s?b:0,d?i.height=s?b:0:i.height=a.maxHeight,l.display&&s&&(d?i.height+=1.5*g:i.width+=1.5*g),r.display&&s){a.longestTextCache||(a.longestTextCache={});var v=e.longestText(a.ctx,f,a.ticks,a.longestTextCache),x=e.numberOfLabelLines(a.ticks),y=.5*u;if(d){a.longestLabelWidth=v;var k=Math.sin(e.toRadians(a.labelRotation))*a.longestLabelWidth+u*x+y*x;i.height=Math.min(a.maxHeight,i.height+k),a.ctx.font=f;var S=a.ctx.measureText(a.ticks[0]).width,w=a.ctx.measureText(a.ticks[a.ticks.length-1]).width,C=Math.cos(e.toRadians(a.labelRotation)),M=Math.sin(e.toRadians(a.labelRotation));a.paddingLeft=0!==a.labelRotation?C*S+3:S/2+3,a.paddingRight=0!==a.labelRotation?M*(u/2)+3:w/2+3}else{var D=a.maxWidth-i.width,A=r.mirror;A?v=0:v+=a.options.ticks.padding,D>v?i.width+=v:i.width=a.maxWidth,a.paddingTop=u/2,a.paddingBottom=u/2}}a.margins&&(a.paddingLeft=Math.max(a.paddingLeft-a.margins.left,0),a.paddingTop=Math.max(a.paddingTop-a.margins.top,0),a.paddingRight=Math.max(a.paddingRight-a.margins.right,0),a.paddingBottom=Math.max(a.paddingBottom-a.margins.bottom,0)),a.width=i.width,a.height=i.height},afterFit:function(){e.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function a(t){return null===t||"undefined"==typeof t?NaN:"number"==typeof t&&isNaN(t)?NaN:"object"==typeof t?t instanceof Date||t.isValid?t:a(this.isHorizontal()?t.x:t.y):t},getLabelForIndex:e.noop,getPixelForValue:e.noop,getValueForPixel:e.noop,getPixelForTick:function(t,e){var a=this;if(a.isHorizontal()){var i=a.width-(a.paddingLeft+a.paddingRight),n=i/Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),o=n*t+a.paddingLeft;e&&(o+=n/2);var r=a.left+Math.round(o);return r+=a.isFullWidth()?a.margins.left:0}var l=a.height-(a.paddingTop+a.paddingBottom);return a.top+t*(l/(a.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var a=e.width-(e.paddingLeft+e.paddingRight),i=a*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){var t=this,e=t.min,a=t.max;return t.getPixelForValue(t.beginAtZero?0:0>e&&0>a?a:e>0&&a>0?e:0)},draw:function(a){var i=this,n=i.options;if(n.display){
-var o,r,l=i.ctx,s=t.defaults.global,d=n.ticks,u=n.gridLines,c=n.scaleLabel,h=0!==i.labelRotation,f=d.autoSkip,g=i.isHorizontal();d.maxTicksLimit&&(r=d.maxTicksLimit);var p=e.getValueOrDefault(d.fontColor,s.defaultFontColor),m=e.getValueOrDefault(d.fontSize,s.defaultFontSize),b=e.getValueOrDefault(d.fontStyle,s.defaultFontStyle),v=e.getValueOrDefault(d.fontFamily,s.defaultFontFamily),x=e.fontString(m,b,v),y=u.tickMarkLength,k=e.getValueOrDefault(c.fontColor,s.defaultFontColor),S=e.getValueOrDefault(c.fontSize,s.defaultFontSize),w=e.getValueOrDefault(c.fontStyle,s.defaultFontStyle),C=e.getValueOrDefault(c.fontFamily,s.defaultFontFamily),M=e.fontString(S,w,C),D=e.toRadians(i.labelRotation),A=Math.cos(D),I=(Math.sin(D),i.longestLabelWidth*A);l.fillStyle=p;var F=[];if(g){if(o=!1,h&&(I/=2),(I+d.autoSkipPadding)*i.ticks.length>i.width-(i.paddingLeft+i.paddingRight)&&(o=1+Math.floor((I+d.autoSkipPadding)*i.ticks.length/(i.width-(i.paddingLeft+i.paddingRight)))),r&&i.ticks.length>r)for(;!o||i.ticks.length/(o||1)>r;)o||(o=1),o+=1;f||(o=!1)}var T="right"===n.position?i.left:i.right-y,P="right"===n.position?i.left+y:i.right,_="bottom"===n.position?i.top:i.bottom-y,R="bottom"===n.position?i.top+y:i.bottom;if(e.each(i.ticks,function(t,r){if(void 0!==t&&null!==t){var l=i.ticks.length===r+1,s=o>1&&r%o>0||r%o===0&&r+o>=i.ticks.length;if((!s||l)&&void 0!==t&&null!==t){var c,f;r===("undefined"!=typeof i.zeroLineIndex?i.zeroLineIndex:0)?(c=u.zeroLineWidth,f=u.zeroLineColor):(c=e.getValueAtIndexOrDefault(u.lineWidth,r),f=e.getValueAtIndexOrDefault(u.color,r));var p,m,b,v,x,k,S,w,C,M,A,I="middle";if(g){h||(I="top"===n.position?"bottom":"top"),A=h?"right":"center";var V=i.getPixelForTick(r)+e.aliasPixel(c);C=i.getPixelForTick(r,u.offsetGridLines)+d.labelOffset,M=h?i.top+12:"top"===n.position?i.bottom-y:i.top+y,p=b=x=S=V,m=_,v=R,k=a.top,w=a.bottom}else{"left"===n.position?d.mirror?(C=i.right+d.padding,A="left"):(C=i.right-d.padding,A="right"):d.mirror?(C=i.left-d.padding,A="right"):(C=i.left+d.padding,A="left");var O=i.getPixelForTick(r);O+=e.aliasPixel(c),M=i.getPixelForTick(r,u.offsetGridLines),p=T,b=P,x=a.left,S=a.right,m=v=k=w=O}F.push({tx1:p,ty1:m,tx2:b,ty2:v,x1:x,y1:k,x2:S,y2:w,labelX:C,labelY:M,glWidth:c,glColor:f,rotation:-1*D,label:t,textBaseline:I,textAlign:A})}}}),e.each(F,function(t){if(u.display&&(l.lineWidth=t.glWidth,l.strokeStyle=t.glColor,l.beginPath(),u.drawTicks&&(l.moveTo(t.tx1,t.ty1),l.lineTo(t.tx2,t.ty2)),u.drawOnChartArea&&(l.moveTo(t.x1,t.y1),l.lineTo(t.x2,t.y2)),l.stroke()),d.display){l.save(),l.translate(t.labelX,t.labelY),l.rotate(t.rotation),l.font=x,l.textBaseline=t.textBaseline,l.textAlign=t.textAlign;var a=t.label;if(e.isArray(a))for(var i=0,n=0;i<a.length;++i)l.fillText(""+a[i],0,n),n+=1.5*m;else l.fillText(a,0,0);l.restore()}}),c.display){var V,O,L=0;if(g)V=i.left+(i.right-i.left)/2,O="bottom"===n.position?i.bottom-S/2:i.top+S/2;else{var B="left"===n.position;V=B?i.left+S/2:i.right-S/2,O=i.top+(i.bottom-i.top)/2,L=B?-.5*Math.PI:.5*Math.PI}l.save(),l.translate(V,O),l.rotate(L),l.textAlign="center",l.textBaseline="middle",l.fillStyle=k,l.font=M,l.fillText(c.labelString,0,0),l.restore()}if(u.drawBorder){l.lineWidth=e.getValueAtIndexOrDefault(u.lineWidth,0),l.strokeStyle=e.getValueAtIndexOrDefault(u.color,0);var W=i.left,z=i.right,H=i.top,N=i.bottom,E=e.aliasPixel(l.lineWidth);g?(H=N="top"===n.position?i.bottom:i.top,H+=E,N+=E):(W=z="left"===n.position?i.right:i.left,W+=E,z+=E),l.beginPath(),l.moveTo(W,H),l.lineTo(z,N),l.stroke()}}}})}},{}],31:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,a,i){this.constructors[t]=a,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(a){return this.defaults.hasOwnProperty(a)?e.scaleMerge(t.defaults.scale,this.defaults[a]):{}},updateScaleDefaults:function(t,a){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],a))},addScalesToLayout:function(a){e.each(a.scales,function(e){t.layoutService.addBox(a,e)})}}}},{}],32:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var a=e.noop;t.Title=t.Element.extend({initialize:function(a){var i=this;e.extend(i,a),i.options=e.configMerge(t.defaults.global.title,a.options),i.legendHitBoxes=[]},beforeUpdate:function(){var a=this.chart.options;a&&a.title&&(this.options=e.configMerge(t.defaults.global.title,a.title))},update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:a,beforeSetDimensions:a,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:a,beforeBuildLabels:a,buildLabels:a,afterBuildLabels:a,beforeFit:a,fit:function(){var a=this,i=(a.ctx,e.getValueOrDefault),n=a.options,o=t.defaults.global,r=n.display,l=i(n.fontSize,o.defaultFontSize),s=a.minSize;a.isHorizontal()?(s.width=a.maxWidth,s.height=r?l+2*n.padding:0):(s.width=r?l+2*n.padding:0,s.height=a.maxHeight),a.width=s.width,a.height=s.height},afterFit:a,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var a=this,i=a.ctx,n=e.getValueOrDefault,o=a.options,r=t.defaults.global;if(o.display){var l,s,d=n(o.fontSize,r.defaultFontSize),u=n(o.fontStyle,r.defaultFontStyle),c=n(o.fontFamily,r.defaultFontFamily),h=e.fontString(d,u,c),f=0,g=a.top,p=a.left,m=a.bottom,b=a.right;i.fillStyle=n(o.fontColor,r.defaultFontColor),i.font=h,a.isHorizontal()?(l=p+(b-p)/2,s=g+(m-g)/2):(l="left"===o.position?p+d/2:b-d/2,s=g+(m-g)/2,f=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(l,s),i.rotate(f),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0),i.restore()}}}),t.plugins.register({beforeInit:function(e){var a=e.options,i=a.title;i&&(e.titleBlock=new t.Title({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.titleBlock))}})}},{}],33:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return e&&(n.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function a(t){if(!t.length)return!1;var e,a,i=[],n=[];for(e=0,a=t.length;a>e;++e){var o=t[e];if(o&&o.hasValue()){var r=o.tooltipPosition();i.push(r.x),n.push(r.y)}}var l=0,s=0;for(e=0,a-i.length;a>e;++e)l+=i[e],s+=n[e];return{x:Math.round(l/i.length),y:Math.round(s/i.length)}}function i(t){var e=t._xScale,a=t._yScale||t._scale,i=t._index,n=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,n):"",yLabel:a?a.getLabelForIndex(i,n):"",index:i,datasetIndex:n}}var n=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"single",backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,yAlign:"center",xAlign:"center",caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",callbacks:{beforeTitle:n.noop,title:function(t,e){var a="",i=e.labels,n=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?a=o.xLabel:n>0&&o.index<n&&(a=i[o.index])}return a},afterTitle:n.noop,beforeBody:n.noop,beforeLabel:n.noop,label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.yLabel},labelColor:function(t,e){var a=e.getDatasetMeta(t.datasetIndex),i=a.data[t.index],n=i._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},afterLabel:n.noop,afterBody:n.noop,beforeFooter:n.noop,footer:n.noop,afterFooter:n.noop}},t.Tooltip=t.Element.extend({initialize:function(){var e=this,a=t.defaults.global,i=e._options,o=n.getValueOrDefault;n.extend(e,{_model:{xPadding:i.xPadding,yPadding:i.yPadding,xAlign:i.yAlign,yAlign:i.xAlign,bodyFontColor:i.bodyFontColor,_bodyFontFamily:o(i.bodyFontFamily,a.defaultFontFamily),_bodyFontStyle:o(i.bodyFontStyle,a.defaultFontStyle),_bodyAlign:i.bodyAlign,bodyFontSize:o(i.bodyFontSize,a.defaultFontSize),bodySpacing:i.bodySpacing,titleFontColor:i.titleFontColor,_titleFontFamily:o(i.titleFontFamily,a.defaultFontFamily),_titleFontStyle:o(i.titleFontStyle,a.defaultFontStyle),titleFontSize:o(i.titleFontSize,a.defaultFontSize),_titleAlign:i.titleAlign,titleSpacing:i.titleSpacing,titleMarginBottom:i.titleMarginBottom,footerFontColor:i.footerFontColor,_footerFontFamily:o(i.footerFontFamily,a.defaultFontFamily),_footerFontStyle:o(i.footerFontStyle,a.defaultFontStyle),footerFontSize:o(i.footerFontSize,a.defaultFontSize),_footerAlign:i.footerAlign,footerSpacing:i.footerSpacing,footerMarginTop:i.footerMarginTop,caretSize:i.caretSize,cornerRadius:i.cornerRadius,backgroundColor:i.backgroundColor,opacity:0,legendColorBackground:i.multiKeyBackground}})},getTitle:function(){var t=this,a=t._options,i=a.callbacks,n=i.beforeTitle.apply(t,arguments),o=i.title.apply(t,arguments),r=i.afterTitle.apply(t,arguments),l=[];return l=e(l,n),l=e(l,o),l=e(l,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return n.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,a){var i=this,o=i._options.callbacks,r=[];return n.each(t,function(t){var n={before:[],lines:[],after:[]};e(n.before,o.beforeLabel.call(i,t,a)),e(n.lines,o.label.call(i,t,a)),e(n.after,o.afterLabel.call(i,t,a)),r.push(n)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return n.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,a=t._options.callbacks,i=a.beforeFooter.apply(t,arguments),n=a.footer.apply(t,arguments),o=a.afterFooter.apply(t,arguments),r=[];return r=e(r,i),r=e(r,n),r=e(r,o)},update:function(t){var e,o,r=this,l=r._options,s=r._model,d=r._active,u=r._data,c=r._chartInstance;if(d.length){s.opacity=1;var h=[],f=a(d),g=[];for(e=0,o=d.length;o>e;++e)g.push(i(d[e]));l.itemSort&&(g=g.sort(l.itemSort)),d.length>1&&n.each(g,function(t){h.push(l.callbacks.labelColor.call(r,t,c))}),n.extend(s,{title:r.getTitle(g,u),beforeBody:r.getBeforeBody(g,u),body:r.getBody(g,u),afterBody:r.getAfterBody(g,u),footer:r.getFooter(g,u),x:Math.round(f.x),y:Math.round(f.y),caretPadding:n.getValueOrDefault(f.padding,2),labelColors:h});var p=r.getTooltipSize(s);r.determineAlignment(p),n.extend(s,r.getBackgroundPoint(s,p))}else r._model.opacity=0;return t&&l.custom&&l.custom.call(r,s),r},getTooltipSize:function(t){var e=this._chart.ctx,a={height:2*t.yPadding,width:0},i=t.body,o=i.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);o+=t.beforeBody.length+t.afterBody.length;var r=t.title.length,l=t.footer.length,s=t.titleFontSize,d=t.bodyFontSize,u=t.footerFontSize;a.height+=r*s,a.height+=(r-1)*t.titleSpacing,a.height+=r?t.titleMarginBottom:0,a.height+=o*d,a.height+=o?(o-1)*t.bodySpacing:0,a.height+=l?t.footerMarginTop:0,a.height+=l*u,a.height+=l?(l-1)*t.footerSpacing:0;var c=0,h=function(t){a.width=Math.max(a.width,e.measureText(t).width+c)};return e.font=n.fontString(s,t._titleFontStyle,t._titleFontFamily),n.each(t.title,h),e.font=n.fontString(d,t._bodyFontStyle,t._bodyFontFamily),n.each(t.beforeBody.concat(t.afterBody),h),c=i.length>1?d+2:0,n.each(i,function(t){n.each(t.before,h),n.each(t.lines,h),n.each(t.after,h)}),c=0,e.font=n.fontString(u,t._footerFontStyle,t._footerFontFamily),n.each(t.footer,h),a.width+=2*t.xPadding,a},determineAlignment:function(t){var e=this,a=e._model,i=e._chart,n=e._chartInstance.chartArea;a.y<t.height?a.yAlign="top":a.y>i.height-t.height&&(a.yAlign="bottom");var o,r,l,s,d,u=(n.left+n.right)/2,c=(n.top+n.bottom)/2;"center"===a.yAlign?(o=function(t){return u>=t},r=function(t){return t>u}):(o=function(e){return e<=t.width/2},r=function(e){return e>=i.width-t.width/2}),l=function(e){return e+t.width>i.width},s=function(e){return e-t.width<0},d=function(t){return c>=t?"top":"bottom"},o(a.x)?(a.xAlign="left",l(a.x)&&(a.xAlign="center",a.yAlign=d(a.y))):r(a.x)&&(a.xAlign="right",s(a.x)&&(a.xAlign="center",a.yAlign=d(a.y)))},getBackgroundPoint:function(t,e){var a={x:t.x,y:t.y},i=t.caretSize,n=t.caretPadding,o=t.cornerRadius,r=t.xAlign,l=t.yAlign,s=i+n,d=o+n;return"right"===r?a.x-=e.width:"center"===r&&(a.x-=e.width/2),"top"===l?a.y+=s:"bottom"===l?a.y-=e.height+s:a.y-=e.height/2,"center"===l?"left"===r?a.x+=s:"right"===r&&(a.x-=s):"left"===r?a.x-=d:"right"===r&&(a.x+=d),a},drawCaret:function(t,e,a,i){var o,r,l,s,d,u,c=this._view,h=this._chart.ctx,f=c.caretSize,g=c.cornerRadius,p=c.xAlign,m=c.yAlign,b=t.x,v=t.y,x=e.width,y=e.height;"center"===m?("left"===p?(o=b,r=o-f,l=o):(o=b+x,r=o+f,l=o),d=v+y/2,s=d-f,u=d+f):("left"===p?(o=b+g,r=o+f,l=r+f):"right"===p?(o=b+x-g,r=o-f,l=r-f):(r=b+x/2,o=r-f,l=r+f),"top"===m?(s=v,d=s-f,u=s):(s=v+y,d=s+f,u=s));var k=n.color(c.backgroundColor);h.fillStyle=k.alpha(a*k.alpha()).rgbString(),h.beginPath(),h.moveTo(o,s),h.lineTo(r,d),h.lineTo(l,u),h.closePath(),h.fill()},drawTitle:function(t,e,a,i){var o=e.title;if(o.length){a.textAlign=e._titleAlign,a.textBaseline="top";var r=e.titleFontSize,l=e.titleSpacing,s=n.color(e.titleFontColor);a.fillStyle=s.alpha(i*s.alpha()).rgbString(),a.font=n.fontString(r,e._titleFontStyle,e._titleFontFamily);var d,u;for(d=0,u=o.length;u>d;++d)a.fillText(o[d],t.x,t.y),t.y+=r+l,d+1===o.length&&(t.y+=e.titleMarginBottom-l)}},drawBody:function(t,e,a,i){var o=e.bodyFontSize,r=e.bodySpacing,l=e.body;a.textAlign=e._bodyAlign,a.textBaseline="top";var s=n.color(e.bodyFontColor),d=s.alpha(i*s.alpha()).rgbString();a.fillStyle=d,a.font=n.fontString(o,e._bodyFontStyle,e._bodyFontFamily);var u=0,c=function(e){a.fillText(e,t.x+u,t.y),t.y+=o+r};n.each(e.beforeBody,c);var h=l.length>1;u=h?o+2:0,n.each(l,function(r,l){n.each(r.before,c),n.each(r.lines,function(r){h&&(a.fillStyle=n.color(e.legendColorBackground).alpha(i).rgbaString(),a.fillRect(t.x,t.y,o,o),a.strokeStyle=n.color(e.labelColors[l].borderColor).alpha(i).rgbaString(),a.strokeRect(t.x,t.y,o,o),a.fillStyle=n.color(e.labelColors[l].backgroundColor).alpha(i).rgbaString(),a.fillRect(t.x+1,t.y+1,o-2,o-2),a.fillStyle=d),c(r)}),n.each(r.after,c)}),u=0,n.each(e.afterBody,c),t.y-=r},drawFooter:function(t,e,a,i){var o=e.footer;if(o.length){t.y+=e.footerMarginTop,a.textAlign=e._footerAlign,a.textBaseline="top";var r=n.color(e.footerFontColor);a.fillStyle=r.alpha(i*r.alpha()).rgbString(),a.font=n.fontString(e.footerFontSize,e._footerFontStyle,e._footerFontFamily),n.each(o,function(i){a.fillText(i,t.x,t.y),t.y+=e.footerFontSize+e.footerSpacing})}},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var a=this.getTooltipSize(e),i={x:e.x,y:e.y},o=Math.abs(e.opacity<.001)?0:e.opacity;if(this._options.enabled){var r=n.color(e.backgroundColor);t.fillStyle=r.alpha(o*r.alpha()).rgbString(),n.drawRoundedRectangle(t,i.x,i.y,a.width,a.height,e.cornerRadius),t.fill(),this.drawCaret(i,a,o,e.caretPadding),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,o),this.drawBody(i,e,t,o),this.drawFooter(i,e,t,o)}}}})}},{}],34:[function(t,e,a){"use strict";e.exports=function(t,e){var a=t.helpers,i=t.defaults.global;i.elements.arc={backgroundColor:i.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2):!1},inRange:function(t,e){var i=this._view;if(i){for(var n=a.getAngleFromPoint(i,{x:t,y:e}),o=n.angle,r=n.distance,l=i.startAngle,s=i.endAngle;l>s;)s+=2*Math.PI;for(;o>s;)o-=2*Math.PI;for(;l>o;)o+=2*Math.PI;var d=o>=l&&s>=o,u=r>=i.innerRadius&&r<=i.outerRadius;return d&&u}return!1},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,a=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},draw:function(){var t=this._chart.ctx,e=this._view,a=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,a,i),t.arc(e.x,e.y,e.innerRadius,i,a,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],35:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:a.defaultColor,borderWidth:3,borderColor:a.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",fill:!0},t.elements.Line=t.Element.extend({lineToNextPoint:function(t,e,a,i,n){var o=this,r=o._chart.ctx,l=o._view?o._view.spanGaps:!1;e._view.skip&&!l?i.call(o,t,e,a):t._view.skip&&!l?n.call(o,t,e,a):0===e._view.tension?r.lineTo(e._view.x,e._view.y):r.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,e._view.controlPointPreviousX,e._view.controlPointPreviousY,e._view.x,e._view.y)},draw:function(){function t(t){r._view.skip||l._view.skip?t&&o.lineTo(i._view.scaleZero.x,i._view.scaleZero.y):o.bezierCurveTo(l._view.controlPointNextX,l._view.controlPointNextY,r._view.controlPointPreviousX,r._view.controlPointPreviousY,r._view.x,r._view.y)}var i=this,n=i._view,o=i._chart.ctx,r=i._children[0],l=i._children[i._children.length-1];o.save(),i._children.length>0&&n.fill&&(o.beginPath(),e.each(i._children,function(t,a){var r=e.previousItem(i._children,a),l=e.nextItem(i._children,a);0===a?(i._loop?o.moveTo(n.scaleZero.x,n.scaleZero.y):o.moveTo(t._view.x,n.scaleZero),t._view.skip?i._loop||o.moveTo(l._view.x,i._view.scaleZero):o.lineTo(t._view.x,t._view.y)):i.lineToNextPoint(r,t,l,function(t,e,a){i._loop?o.lineTo(i._view.scaleZero.x,i._view.scaleZero.y):(o.lineTo(t._view.x,i._view.scaleZero),o.moveTo(a._view.x,i._view.scaleZero))},function(t,e){o.lineTo(e._view.x,e._view.y)})},i),i._loop?t(!0):(o.lineTo(i._children[i._children.length-1]._view.x,n.scaleZero),o.lineTo(i._children[0]._view.x,n.scaleZero)),o.fillStyle=n.backgroundColor||a.defaultColor,o.closePath(),o.fill());var s=a.elements.line;o.lineCap=n.borderCapStyle||s.borderCapStyle,o.setLineDash&&o.setLineDash(n.borderDash||s.borderDash),o.lineDashOffset=n.borderDashOffset||s.borderDashOffset,o.lineJoin=n.borderJoinStyle||s.borderJoinStyle,o.lineWidth=n.borderWidth||s.borderWidth,o.strokeStyle=n.borderColor||a.defaultColor,o.beginPath(),e.each(i._children,function(t,a){var n=e.previousItem(i._children,a),r=e.nextItem(i._children,a);0===a?o.moveTo(t._view.x,t._view.y):i.lineToNextPoint(n,t,r,function(t,e,a){o.moveTo(a._view.x,a._view.y)},function(t,e){o.moveTo(e._view.x,e._view.y)})},i),i._loop&&i._children.length>0&&t(),o.stroke(),o.restore()}})}},{}],36:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global,i=a.defaultColor;a.elements.point={radius:3,pointStyle:"circle",backgroundColor:i,borderWidth:1,borderColor:i,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var a=this._view;return a?Math.pow(t-a.x,2)+Math.pow(e-a.y,2)<Math.pow(a.hitRadius+a.radius,2):!1},inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2):!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(){var t,n,o,r,l,s,d=this._view,u=this._chart.ctx,c=d.pointStyle,h=d.radius,f=d.x,g=d.y;if(!d.skip){if("object"==typeof c&&(t=c.toString(),"[object HTMLImageElement]"===t||"[object HTMLCanvasElement]"===t))return void u.drawImage(c,f-c.width/2,g-c.height/2);if(!(isNaN(h)||0>=h)){switch(u.strokeStyle=d.borderColor||i,u.lineWidth=e.getValueOrDefault(d.borderWidth,a.elements.point.borderWidth),u.fillStyle=d.backgroundColor||i,c){default:u.beginPath(),u.arc(f,g,h,0,2*Math.PI),u.closePath(),u.fill();break;case"triangle":u.beginPath(),n=3*h/Math.sqrt(3),l=n*Math.sqrt(3)/2,u.moveTo(f-n/2,g+l/3),u.lineTo(f+n/2,g+l/3),u.lineTo(f,g-2*l/3),u.closePath(),u.fill();break;case"rect":s=1/Math.SQRT2*h,u.fillRect(f-s,g-s,2*s,2*s),u.strokeRect(f-s,g-s,2*s,2*s);break;case"rectRot":s=1/Math.SQRT2*h,u.beginPath(),u.moveTo(f-s,g),u.lineTo(f,g+s),u.lineTo(f+s,g),u.lineTo(f,g-s),u.closePath(),u.fill();break;case"cross":u.beginPath(),u.moveTo(f,g+h),u.lineTo(f,g-h),u.moveTo(f-h,g),u.lineTo(f+h,g),u.closePath();break;case"crossRot":u.beginPath(),o=Math.cos(Math.PI/4)*h,r=Math.sin(Math.PI/4)*h,u.moveTo(f-o,g-r),u.lineTo(f+o,g+r),u.moveTo(f-o,g+r),u.lineTo(f+o,g-r),u.closePath();break;case"star":u.beginPath(),u.moveTo(f,g+h),u.lineTo(f,g-h),u.moveTo(f-h,g),u.lineTo(f+h,g),o=Math.cos(Math.PI/4)*h,r=Math.sin(Math.PI/4)*h,u.moveTo(f-o,g-r),u.lineTo(f+o,g+r),u.moveTo(f-o,g+r),u.lineTo(f+o,g-r),u.closePath();break;case"line":u.beginPath(),u.moveTo(f-h,g),u.lineTo(f+h,g),u.closePath();break;case"dash":u.beginPath(),u.moveTo(f,g),u.lineTo(f+h,g),u.closePath()}u.stroke()}}}})}},{}],37:[function(t,e,a){"use strict";e.exports=function(t){var e=(t.helpers,t.defaults.global);e.elements.rectangle={backgroundColor:e.defaultColor,borderWidth:0,borderColor:e.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return s[(u+t)%4]}var e=this._chart.ctx,a=this._view,i=a.width/2,n=a.x-i,o=a.x+i,r=a.base-(a.base-a.y),l=a.borderWidth/2;a.borderWidth&&(n+=l,o-=l,r+=l),e.beginPath(),e.fillStyle=a.backgroundColor,e.strokeStyle=a.borderColor,e.lineWidth=a.borderWidth;var s=[[n,a.base],[n,r],[o,r],[o,a.base]],d=["bottom","left","top","right"],u=d.indexOf(a.borderSkipped,0);-1===u&&(u=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),a.borderWidth&&e.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var a=this._view;return a?a.y<a.base?t>=a.x-a.width/2&&t<=a.x+a.width/2&&e>=a.y&&e<=a.base:t>=a.x-a.width/2&&t<=a.x+a.width/2&&e>=a.base&&e<=a.y:!1},inLabelRange:function(t){var e=this._view;return e?t>=e.x-e.width/2&&t<=e.x+e.width/2:!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],38:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"bottom"},i=t.Scale.extend({determineDataLimits:function(){var t=this;t.minIndex=0,t.maxIndex=t.chart.data.labels.length-1;var a;void 0!==t.options.ticks.min&&(a=e.indexOf(t.chart.data.labels,t.options.ticks.min),t.minIndex=-1!==a?a:t.minIndex),void 0!==t.options.ticks.max&&(a=e.indexOf(t.chart.data.labels,t.options.ticks.max),t.maxIndex=-1!==a?a:t.maxIndex),t.min=t.chart.data.labels[t.minIndex],t.max=t.chart.data.labels[t.maxIndex]},buildTicks:function(t){var e=this;e.ticks=0===e.minIndex&&e.maxIndex===e.chart.data.labels.length-1?e.chart.data.labels:e.chart.data.labels.slice(e.minIndex,e.maxIndex+1)},getLabelForIndex:function(t,e){return this.ticks[t]},getPixelForValue:function(t,e,a,i){var n=this,o=Math.max(n.maxIndex+1-n.minIndex-(n.options.gridLines.offsetGridLines?0:1),1);if(n.isHorizontal()){var r=n.width-(n.paddingLeft+n.paddingRight),l=r/o,s=l*(e-n.minIndex)+n.paddingLeft;return n.options.gridLines.offsetGridLines&&i&&(s+=l/2),n.left+Math.round(s)}var d=n.height-(n.paddingTop+n.paddingBottom),u=d/o,c=u*(e-n.minIndex)+n.paddingTop;return n.options.gridLines.offsetGridLines&&i&&(c+=u/2),n.top+Math.round(c)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,a=this,i=Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),n=a.isHorizontal(),o=n?a.width-(a.paddingLeft+a.paddingRight):a.height-(a.paddingTop+a.paddingBottom),r=o/i;return a.options.gridLines.offsetGridLines&&(t-=r/2),t-=n?a.paddingLeft:a.paddingTop,e=0>=t?0:Math.round(t/r)}});t.scaleService.registerScaleType("category",i,a)}},{}],39:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:function(t,a,i){var n=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(n)>1&&t!==Math.floor(t)&&(n=t-Math.floor(t));var o=e.log10(Math.abs(n)),r="";if(0!==t){var l=-1*Math.floor(o);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r}}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return l?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=(i.ticks,a.chart),o=n.data,r=o.datasets,l=a.isHorizontal();if(a.min=null,a.max=null,i.stacked){var s={},d=!1,u=!1;e.each(r,function(o,r){var l=n.getDatasetMeta(r);void 0===s[l.type]&&(s[l.type]={positiveValues:[],negativeValues:[]});var c=s[l.type].positiveValues,h=s[l.type].negativeValues;n.isDatasetVisible(r)&&t(l)&&e.each(o.data,function(t,e){var n=+a.getRightValue(t);isNaN(n)||l.data[e].hidden||(c[e]=c[e]||0,h[e]=h[e]||0,i.relativePoints?c[e]=100:0>n?(u=!0,h[e]+=n):(d=!0,c[e]+=n))})}),e.each(s,function(t){var i=t.positiveValues.concat(t.negativeValues),n=e.min(i),o=e.max(i);a.min=null===a.min?n:Math.min(a.min,n),a.max=null===a.max?o:Math.max(a.max,o)})}else e.each(r,function(i,o){var r=n.getDatasetMeta(o);n.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var a,i=this,n=i.options.ticks;if(i.isHorizontal())a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.width/50));else{var o=e.getValueOrDefault(n.fontSize,t.defaults.global.defaultFontSize);a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}return a},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t,e,a,i){var n,o,r=this,l=r.paddingLeft,s=r.paddingBottom,d=r.start,u=+r.getRightValue(t),c=r.end-d;return r.isHorizontal()?(o=r.width-(l+r.paddingRight),n=r.left+o/c*(u-d),Math.round(n+l)):(o=r.height-(r.paddingTop+s),n=r.bottom-s-o/c*(u-d),Math.round(n))},getValueForPixel:function(t){var e=this,a=e.isHorizontal(),i=e.paddingLeft,n=e.paddingBottom,o=a?e.width-(i+e.paddingRight):e.height-(e.paddingTop+n),r=(a?t-e.left-i:e.bottom-n-t)/o;return e.start+(e.end-e.start)*r},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticksAsNumbers[t],null,null,e)}});t.scaleService.registerScaleType("linear",i,a)}},{}],40:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,a=t.options,i=a.ticks;if(i.beginAtZero){var n=e.sign(t.min),o=e.sign(t.max);0>n&&0>o?t.max=0:n>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:a,handleDirectionalChanges:a,buildTicks:function(){var t=this,a=t.options,i=a.ticks,n=e.getValueOrDefault,o=(t.isHorizontal(),t.ticks=[]),r=t.getTickLimit();r=Math.max(2,r);var l,s=i.fixedStepSize&&i.fixedStepSize>0||i.stepSize&&i.stepSize>0;if(s)l=n(i.fixedStepSize,i.stepSize);else{var d=e.niceNum(t.max-t.min,!1);l=e.niceNum(d/(r-1),!0)}var u=Math.floor(t.min/l)*l,c=Math.ceil(t.max/l)*l,h=(c-u)/l;h=e.almostEquals(h,Math.round(h),l/1e3)?Math.round(h):Math.ceil(h),o.push(void 0!==i.min?i.min:u);for(var f=1;h>f;++f)o.push(u+f*l);o.push(void 0!==i.max?i.max:c),t.handleDirectionalChanges(),t.max=e.max(o),t.min=e.min(o),i.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],41:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:function(t,a,i){var n=t/Math.pow(10,Math.floor(e.log10(t)));return 1===n||2===n||5===n||0===a||a===i.length-1?t.toExponential():""}}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return d?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=i.ticks,o=a.chart,r=o.data,l=r.datasets,s=e.getValueOrDefault,d=a.isHorizontal();if(a.min=null,a.max=null,i.stacked){var u={};e.each(l,function(n,r){var l=o.getDatasetMeta(r);o.isDatasetVisible(r)&&t(l)&&(void 0===u[l.type]&&(u[l.type]=[]),e.each(n.data,function(t,e){var n=u[l.type],o=+a.getRightValue(t);isNaN(o)||l.data[e].hidden||(n[e]=n[e]||0,i.relativePoints?n[e]=100:n[e]+=o)}))}),e.each(u,function(t){var i=e.min(t),n=e.max(t);a.min=null===a.min?i:Math.min(a.min,i),a.max=null===a.max?n:Math.max(a.max,n)})}else e.each(l,function(i,n){var r=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i))})});a.min=s(n.min,a.min),a.max=s(n.max,a.max),a.min===a.max&&(0!==a.min&&null!==a.min?(a.min=Math.pow(10,Math.floor(e.log10(a.min))-1),a.max=Math.pow(10,Math.floor(e.log10(a.max))+1)):(a.min=1,a.max=10))},buildTicks:function(){for(var t=this,a=t.options,i=a.ticks,n=e.getValueOrDefault,o=t.ticks=[],r=n(i.min,Math.pow(10,Math.floor(e.log10(t.min))));r<t.max;){o.push(r);var l=Math.floor(e.log10(r)),s=Math.floor(r/Math.pow(10,l))+1;10===s&&(s=1,++l),r=s*Math.pow(10,l)}var d=n(i.max,r);o.push(d),t.isHorizontal()||o.reverse(),t.max=e.max(o),t.min=e.min(o),i.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t,e){return this.getPixelForValue(this.tickValues[t],null,null,e)},getPixelForValue:function(t,a,i,n){var o,r,l=this,s=l.start,d=+l.getRightValue(t),u=e.log10(l.end)-e.log10(s),c=l.paddingTop,h=l.paddingBottom,f=l.paddingLeft;return l.isHorizontal()?0===d?r=l.left+f:(o=l.width-(f+l.paddingRight),r=l.left+o/u*(e.log10(d)-e.log10(s)),r+=f):0===d?r=l.top+c:(o=l.height-(c+h),r=l.bottom-h-o/u*(e.log10(d)-e.log10(s))),r},getValueForPixel:function(t){var a,i,n=this,o=e.log10(n.end)-e.log10(n.start);return n.isHorizontal()?(i=n.width-(n.paddingLeft+n.paddingRight),a=n.start*Math.pow(10,(t-n.left-n.paddingLeft)*o/i)):(i=n.height-(n.paddingTop+n.paddingBottom),a=Math.pow(10,(n.bottom-n.paddingBottom-t)*o/i)/n.start),a}});t.scaleService.registerScaleType("logarithmic",i,a)}},{}],42:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global,i={display:!0,animate:!0,lineArc:!1,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2},pointLabels:{fontSize:10,callback:function(t){return t}}},n=t.LinearScaleBase.extend({getValueCount:function(){return this.chart.data.labels.length},setDimensions:function(){var t=this,i=t.options,n=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var o=e.min([t.height,t.width]),r=e.getValueOrDefault(n.fontSize,a.defaultFontSize);t.drawingArea=i.display?o/2-(r/2+n.backdropPaddingY):o/2},determineDataLimits:function(){var t=this,a=t.chart;t.min=null,t.max=null,e.each(a.data.datasets,function(i,n){if(a.isDatasetVisible(n)){var o=a.getDatasetMeta(n);e.each(i.data,function(e,a){var i=+t.getRightValue(e);isNaN(i)||o.data[a].hidden||(null===t.min?t.min=i:i<t.min&&(t.min=i),null===t.max?t.max=i:i>t.max&&(t.max=i))})}}),t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=e.getValueOrDefault(t.fontSize,a.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){
-var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,i,n,o,r,l,s,d,u,c,h,f,g=this.options.pointLabels,p=e.getValueOrDefault(g.fontSize,a.defaultFontSize),m=e.getValueOrDefault(g.fontStyle,a.defaultFontStyle),b=e.getValueOrDefault(g.fontFamily,a.defaultFontFamily),v=e.fontString(p,m,b),x=e.min([this.height/2-p-5,this.width/2]),y=this.width,k=0;for(this.ctx.font=v,i=0;i<this.getValueCount();i++)t=this.getPointPosition(i,x),n=this.ctx.measureText(this.pointLabels[i]?this.pointLabels[i]:"").width+5,0===i||i===this.getValueCount()/2?(o=n/2,t.x+o>y&&(y=t.x+o,r=i),t.x-o<k&&(k=t.x-o,s=i)):i<this.getValueCount()/2?t.x+n>y&&(y=t.x+n,r=i):i>this.getValueCount()/2&&t.x-n<k&&(k=t.x-n,s=i);u=k,c=Math.ceil(y-this.width),l=this.getIndexAngle(r),d=this.getIndexAngle(s),h=c/Math.sin(l+Math.PI/2),f=u/Math.sin(d+Math.PI/2),h=e.isNumber(h)?h:0,f=e.isNumber(f)?f:0,this.drawingArea=Math.round(x-(f+h)/2),this.setCenterPoint(f,h)},setCenterPoint:function(t,e){var a=this,i=a.width-e-a.drawingArea,n=t+a.drawingArea;a.xCenter=Math.round((n+i)/2+a.left),a.yCenter=Math.round(a.height/2+a.top)},getIndexAngle:function(t){var e=2*Math.PI/this.getValueCount();return t*e-Math.PI/2},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var a=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*a:(t-e.min)*a},getPointPosition:function(t,e){var a=this,i=a.getIndexAngle(t);return{x:Math.round(Math.cos(i)*e)+a.xCenter,y:Math.round(Math.sin(i)*e)+a.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,a=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:0>e&&0>a?a:e>0&&a>0?e:0)},draw:function(){var t=this,i=t.options,n=i.gridLines,o=i.ticks,r=i.angleLines,l=i.pointLabels,s=e.getValueOrDefault;if(i.display){var d=t.ctx,u=s(o.fontSize,a.defaultFontSize),c=s(o.fontStyle,a.defaultFontStyle),h=s(o.fontFamily,a.defaultFontFamily),f=e.fontString(u,c,h);if(e.each(t.ticks,function(r,l){if(l>0||i.reverse){var c=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),h=t.yCenter-c;if(n.display&&0!==l)if(d.strokeStyle=e.getValueAtIndexOrDefault(n.color,l-1),d.lineWidth=e.getValueAtIndexOrDefault(n.lineWidth,l-1),i.lineArc)d.beginPath(),d.arc(t.xCenter,t.yCenter,c,0,2*Math.PI),d.closePath(),d.stroke();else{d.beginPath();for(var g=0;g<t.getValueCount();g++){var p=t.getPointPosition(g,c);0===g?d.moveTo(p.x,p.y):d.lineTo(p.x,p.y)}d.closePath(),d.stroke()}if(o.display){var m=s(o.fontColor,a.defaultFontColor);if(d.font=f,o.showLabelBackdrop){var b=d.measureText(r).width;d.fillStyle=o.backdropColor,d.fillRect(t.xCenter-b/2-o.backdropPaddingX,h-u/2-o.backdropPaddingY,b+2*o.backdropPaddingX,u+2*o.backdropPaddingY)}d.textAlign="center",d.textBaseline="middle",d.fillStyle=m,d.fillText(r,t.xCenter,h)}}}),!i.lineArc){d.lineWidth=r.lineWidth,d.strokeStyle=r.color;for(var g=t.getDistanceFromCenterForValue(i.reverse?t.min:t.max),p=s(l.fontSize,a.defaultFontSize),m=s(l.fontStyle,a.defaultFontStyle),b=s(l.fontFamily,a.defaultFontFamily),v=e.fontString(p,m,b),x=t.getValueCount()-1;x>=0;x--){if(r.display){var y=t.getPointPosition(x,g);d.beginPath(),d.moveTo(t.xCenter,t.yCenter),d.lineTo(y.x,y.y),d.stroke(),d.closePath()}var k=t.getPointPosition(x,g+5),S=s(l.fontColor,a.defaultFontColor);d.font=v,d.fillStyle=S;var w=t.pointLabels,C=w.length,M=w.length/2,D=M/2,A=D>x||x>C-D,I=x===D||x===C-D;0===x?d.textAlign="center":x===M?d.textAlign="center":M>x?d.textAlign="left":d.textAlign="right",I?d.textBaseline="middle":A?d.textBaseline="bottom":d.textBaseline="top",d.fillText(w[x]?w[x]:"",k.x,k.y)}}}}});t.scaleService.registerScaleType("radialLinear",n,i)}},{}],43:[function(t,e,a){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,a={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},n={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},o=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return this.labelMoments[t][e]},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e,i){var n=t.parseTime(e);n.isValid()&&(t.options.time.round&&n.startOf(t.options.time.round),a.push(n))},t),t.firstTick=i.min.call(t,a),t.lastTick=i.max.call(t,a)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(n,o){var r=[],l=t.chart.isDatasetVisible(o);"object"==typeof n.data[0]&&null!==n.data[0]?e.each(n.data,function(e,a){var n=t.parseTime(t.getRightValue(e));n.isValid()&&(t.options.time.round&&n.startOf(t.options.time.round),r.push(n),l&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,n):n,t.lastTick=null!==t.lastTick?i.max(t.lastTick,n):n))},t):r=a,t.labelMoments.push(r)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildTicks:function(i){var n=this;n.ctx.save();var o=e.getValueOrDefault(n.options.ticks.fontSize,t.defaults.global.defaultFontSize),r=e.getValueOrDefault(n.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),l=e.getValueOrDefault(n.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),s=e.fontString(o,r,l);if(n.ctx.font=s,n.ticks=[],n.unitScale=1,n.scaleSizeInUnits=0,n.options.time.unit)n.tickUnit=n.options.time.unit||"day",n.displayFormat=n.options.time.displayFormats[n.tickUnit],n.scaleSizeInUnits=n.lastTick.diff(n.firstTick,n.tickUnit,!0),n.unitScale=e.getValueOrDefault(n.options.time.unitStepSize,1);else{var d=n.isHorizontal()?n.width-(n.paddingLeft+n.paddingRight):n.height-(n.paddingTop+n.paddingBottom),u=n.tickFormatFunction(n.firstTick,0,[]),c=n.ctx.measureText(u).width,h=Math.cos(e.toRadians(n.options.ticks.maxRotation)),f=Math.sin(e.toRadians(n.options.ticks.maxRotation));c=c*h+o*f;var g=d/c;n.tickUnit="millisecond",n.scaleSizeInUnits=n.lastTick.diff(n.firstTick,n.tickUnit,!0),n.displayFormat=n.options.time.displayFormats[n.tickUnit];for(var p=0,m=a.units[p];p<a.units.length;){if(n.unitScale=1,e.isArray(m.steps)&&Math.ceil(n.scaleSizeInUnits/g)<e.max(m.steps)){for(var b=0;b<m.steps.length;++b)if(m.steps[b]>=Math.ceil(n.scaleSizeInUnits/g)){n.unitScale=e.getValueOrDefault(n.options.time.unitStepSize,m.steps[b]);break}break}if(m.maxStep===!1||Math.ceil(n.scaleSizeInUnits/g)<m.maxStep){n.unitScale=e.getValueOrDefault(n.options.time.unitStepSize,Math.ceil(n.scaleSizeInUnits/g));break}++p,m=a.units[p],n.tickUnit=m.name;var v=n.firstTick.diff(n.getMomentStartOf(n.firstTick),n.tickUnit,!0),x=n.getMomentStartOf(n.lastTick.clone().add(1,n.tickUnit)).diff(n.lastTick,n.tickUnit,!0);n.scaleSizeInUnits=n.lastTick.diff(n.firstTick,n.tickUnit,!0)+v+x,n.displayFormat=n.options.time.displayFormats[m.name]}}var y;if(n.options.time.min?y=n.getMomentStartOf(n.firstTick):(n.firstTick=n.getMomentStartOf(n.firstTick),y=n.firstTick),!n.options.time.max){var k=n.getMomentStartOf(n.lastTick);0!==k.diff(n.lastTick,n.tickUnit,!0)&&(n.lastTick=n.getMomentStartOf(n.lastTick.add(1,n.tickUnit)))}n.smallestLabelSeparation=n.width,e.each(n.chart.data.datasets,function(t,e){for(var a=1;a<n.labelMoments[e].length;a++)n.smallestLabelSeparation=Math.min(n.smallestLabelSeparation,n.labelMoments[e][a].diff(n.labelMoments[e][a-1],n.tickUnit,!0))},n),n.options.time.displayFormat&&(n.displayFormat=n.options.time.displayFormat),n.ticks.push(n.firstTick.clone());for(var S=1;S<=n.scaleSizeInUnits;++S){var w=y.clone().add(S,n.tickUnit);if(n.options.time.max&&w.diff(n.lastTick,n.tickUnit,!0)>=0)break;S%n.unitScale===0&&n.ticks.push(w)}var C=n.ticks[n.ticks.length-1].diff(n.lastTick,n.tickUnit);(0!==C||0===n.scaleSizeInUnits)&&(n.options.time.max?(n.ticks.push(n.lastTick.clone()),n.scaleSizeInUnits=n.lastTick.diff(n.ticks[0],n.tickUnit,!0)):(n.ticks.push(n.lastTick.clone()),n.scaleSizeInUnits=n.lastTick.diff(n.firstTick,n.tickUnit,!0))),n.ctx.restore()},getLabelForIndex:function(t,e){var a=this,i=a.chart.data.labels&&t<a.chart.data.labels.length?a.chart.data.labels[t]:"";return"object"==typeof a.chart.data.datasets[e].data[0]&&(i=a.getRightValue(a.chart.data.datasets[e].data[t])),a.options.time.tooltipFormat&&(i=a.parseTime(i).format(a.options.time.tooltipFormat)),i},tickFormatFunction:function(t,a,i){var n=t.format(this.displayFormat),o=this.options.ticks,r=e.getValueOrDefault(o.callback,o.userCallback);return r?r(n,a,i):n},convertTicksToLabels:function(){var t=this;t.tickMoments=t.ticks,t.ticks=t.ticks.map(t.tickFormatFunction,t)},getPixelForValue:function(t,e,a,i){var n=this,o=t&&t.isValid&&t.isValid()?t:n.getLabelMoment(a,e);if(o){var r=o.diff(n.firstTick,n.tickUnit,!0),l=r/n.scaleSizeInUnits;if(n.isHorizontal()){var s=n.width-(n.paddingLeft+n.paddingRight),d=(s/Math.max(n.ticks.length-1,1),s*l+n.paddingLeft);return n.left+Math.round(d)}var u=n.height-(n.paddingTop+n.paddingBottom),c=(u/Math.max(n.ticks.length-1,1),u*l+n.paddingTop);return n.top+Math.round(c)}},getPixelForTick:function(t,e){return this.getPixelForValue(this.tickMoments[t],null,null,e)},getValueForPixel:function(t){var e=this,a=e.isHorizontal()?e.width-(e.paddingLeft+e.paddingRight):e.height-(e.paddingTop+e.paddingBottom),n=(t-(e.isHorizontal()?e.left+e.paddingLeft:e.top+e.paddingTop))/a;return n*=e.scaleSizeInUnits,e.firstTick.clone().add(i.duration(n,e.tickUnit).asSeconds(),"seconds")},parseTime:function(t){var e=this;return"string"==typeof e.options.time.parser?i(t,e.options.time.parser):"function"==typeof e.options.time.parser?e.options.time.parser(t):"function"==typeof t.getMonth||"number"==typeof t?i(t):t.isValid&&t.isValid()?t:"string"!=typeof e.options.time.format&&e.options.time.format.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"),e.options.time.format(t)):i(t,e.options.time.format)}});t.scaleService.registerScaleType("time",o,n)}},{1:1}]},{},[7])(7)});
\ No newline at end of file