diff --git a/.gitignore b/.gitignore
index f7bbf70..c8cfd69 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@
 web/gui/src/main/webapp/node_modules/
 web/gui/src/main/webapp/tests/coverage
 web/gui/src/main/webapp/dist/
+web/gui/src/main/webapp/vendor/
 
 npm-debug.log
 sonar-project.properties
diff --git a/tools/gui/gulp-tasks/bower/index.js b/tools/gui/gulp-tasks/bower/index.js
new file mode 100644
index 0000000..c6b89e2
--- /dev/null
+++ b/tools/gui/gulp-tasks/bower/index.js
@@ -0,0 +1,15 @@
+import gulp from 'gulp';
+import bower from 'gulp-bower';
+
+const bowerTask = () => {
+    return bower({
+        directory: 'vendor',
+        cwd: '../../web/gui/src/main/webapp',
+    });
+};
+
+const tasks = () => {
+    gulp.task('bower', () => bowerTask());
+};
+
+export default tasks();
\ No newline at end of file
diff --git a/tools/gui/gulp-tasks/index.js b/tools/gui/gulp-tasks/index.js
index 1a926f6..0aee89a 100644
--- a/tools/gui/gulp-tasks/index.js
+++ b/tools/gui/gulp-tasks/index.js
@@ -1,7 +1,6 @@
 export { default as BundleJS } from './bundles/bundle-js';
 export { default as BundleCSS } from './bundles/bundle-css';
-
-// TODO: These are commented out because of npm issues with BUCK.
 export { default as Lint } from './lint';
 export { default as DevServer } from './dev-server';
-export { default as Tests } from './unit-tests';
\ No newline at end of file
+export { default as Tests } from './unit-tests';
+export { default as bowerDeps } from './bower';
\ No newline at end of file
diff --git a/tools/gui/gulp-tasks/lint/index.js b/tools/gui/gulp-tasks/lint/index.js
index 1aeb444..f864c6b 100644
--- a/tools/gui/gulp-tasks/lint/index.js
+++ b/tools/gui/gulp-tasks/lint/index.js
@@ -7,8 +7,6 @@
     '../../web/gui/src/main/webapp/app/**/*.js'
 ];
 
-console.log(eslint().version);
-
 function isFixed(file) {
     // Has ESLint fixed the file contents?
     return file.eslint != null && file.eslint.fixed;
diff --git a/tools/gui/gulpfile.babel.js b/tools/gui/gulpfile.babel.js
index 2705872..24327e0 100644
--- a/tools/gui/gulpfile.babel.js
+++ b/tools/gui/gulpfile.babel.js
@@ -1,10 +1,6 @@
 import gulp from 'gulp';
 import * as Tasks from './gulp-tasks/';
 
-gulp.task('build', ['bundle-css', 'bundle-js']);
-gulp.task('tests', ['test']);
-
-gulp.task('default', []);
-
-// TODO: Uncomment once npm and buck issues are resolved.
-// gulp.task('default', ['bundle-js', 'serve', 'watch-js']);
\ No newline at end of file
+gulp.task('build', ['bower', 'bundle-css', 'bundle-js']);
+gulp.task('tests', ['bower', 'test']);
+gulp.task('default', ['bundle-js', 'serve', 'watch-js']);
\ No newline at end of file
diff --git a/tools/gui/package.json b/tools/gui/package.json
index 25e418b..1b3f4d7 100644
--- a/tools/gui/package.json
+++ b/tools/gui/package.json
@@ -18,6 +18,7 @@
     "eslint": "^4.4.1",
     "eslint-config-google": "^0.9.1",
     "gulp": "^3.9.1",
+    "gulp-bower": "0.0.13",
     "gulp-concat": "^2.6.1",
     "gulp-eslint": "^4.0.0",
     "gulp-if": "^2.0.2",
diff --git a/web/gui/src/main/webapp/bower.json b/web/gui/src/main/webapp/bower.json
new file mode 100644
index 0000000..440dd58
--- /dev/null
+++ b/web/gui/src/main/webapp/bower.json
@@ -0,0 +1,30 @@
+{
+  "name": "onos-gui",
+  "description": "The GUI interface for ONOS",
+  "main": "index.html",
+  "directory": "./vendor",
+  "authors": [
+    "ON.Lab"
+  ],
+  "license": "Apache 2.0",
+  "homepage": "",
+  "private": true,
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "lodash": "https://raw.githubusercontent.com/lodash/lodash/4.17.4/dist/lodash.min.js",
+    "angular": "1.3.5",
+    "angular-chart.js": "1.0.0",
+    "angular-cookies": "1.3.5",
+    "angular-mocks": "https://code.angularjs.org/1.3.5/angular-mocks.js",
+    "angular-route": "1.3.5",
+    "Chart.js": "2.6.0",
+    "d3": "3.5.16",
+    "topojson": "1.6.18"
+  }
+}
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index 1ab04dd..a6f6f35 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -30,16 +30,14 @@
     <title>ONOS</title>
 
     <!-- Third party library code included here -->
-    <script src="tp/angular.js"></script>
-    <script src="tp/angular-route.js"></script>
-    <script src="tp/angular-cookies.js"></script>
-
-    <script src="tp/d3.js"></script>
-    <script src="tp/topojson.v1.min.js"></script>
-
-    <script src="tp/Chart.min.js"></script>
-    <script src="tp/angular-chart.min.js"></script>
-    <script src="tp/lodash.min.js"></script>
+    <script src="vendor/angular/angular.min.js"></script>
+    <script src="vendor/angular-route/angular-route.min.js"></script>
+    <script src="vendor/angular-cookies/angular-cookies.min.js"></script>
+    <script src="vendor/d3/d3.min.js"></script>
+    <script src="vendor/topojson/topojson.js"></script>
+    <script src="vendor/Chart.js/dist/Chart.min.js"></script>
+    <script src="vendor/angular-chart.js/dist/angular-chart.min.js"></script>
+    <script src="vendor/lodash/index.js"></script>
 
     <!-- {INJECTED-USER-START} -->
     <!-- {INJECTED-USER-END} -->
diff --git a/web/gui/src/main/webapp/tests/karma.ci.js b/web/gui/src/main/webapp/tests/karma.ci.js
index fddf81a..d7f7d18 100644
--- a/web/gui/src/main/webapp/tests/karma.ci.js
+++ b/web/gui/src/main/webapp/tests/karma.ci.js
@@ -16,13 +16,15 @@
     // list of files / patterns to load in the browser
     files: [
         // library code...
-        '../tp/angular.js',
-        '../tp/angular-mocks.js',
-        '../tp/angular-route.js',
-        '../tp/angular-cookies.js',
-        '../tp/d3.js',
-        '../tp/topojson.v1.min.js',
-        '../tp/lodash.min.js',
+        '../vendor/angular/angular.min.js',
+        '../vendor/angular-mocks/index.js',
+        '../vendor/angular-route/angular-route.min.js',
+        '../vendor/angular-cookies/angular-cookies.min.js',
+        '../vendor/d3/d3.min.js',
+        '../vendor/topojson/topojson.js',
+        '../vendor/Chart.js/dist/Chart.min.js',
+        '../vendor/angular-chart.js/dist/angular-chart.min.js',
+        '../vendor/lodash/index.js',
 
         // production code...
         // make sure modules are defined first...
diff --git a/web/gui/src/main/webapp/tests/karma.conf.js b/web/gui/src/main/webapp/tests/karma.conf.js
index ba08e18..bc4c942 100644
--- a/web/gui/src/main/webapp/tests/karma.conf.js
+++ b/web/gui/src/main/webapp/tests/karma.conf.js
@@ -16,13 +16,15 @@
     // list of files / patterns to load in the browser
     files: [
         // library code...
-        '../tp/angular.js',
-        '../tp/angular-mocks.js',
-        '../tp/angular-route.js',
-        '../tp/angular-cookies.js',
-        '../tp/d3.js',
-        '../tp/topojson.v1.min.js',
-        '../tp/lodash.min.js',
+        '../vendor/angular/angular.min.js',
+        '../vendor/angular-mocks/index.js',
+        '../vendor/angular-route/angular-route.min.js',
+        '../vendor/angular-cookies/angular-cookies.min.js',
+        '../vendor/d3/d3.min.js',
+        '../vendor/topojson/topojson.js',
+        '../vendor/Chart.js/dist/Chart.min.js',
+        '../vendor/angular-chart.js/dist/angular-chart.min.js',
+        '../vendor/lodash/index.js',
 
         // production code...
         // make sure modules are defined first...
diff --git a/web/gui/src/main/webapp/tests/package-lock.json b/web/gui/src/main/webapp/tests/package-lock.json
index 5303aaa..b5f7f3c 100644
--- a/web/gui/src/main/webapp/tests/package-lock.json
+++ b/web/gui/src/main/webapp/tests/package-lock.json
@@ -3,6 +3,12 @@
   "version": "1.0.0",
   "lockfileVersion": 1,
   "dependencies": {
+    "bower": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.0.tgz",
+      "integrity": "sha1-Vdvr7wrZFVOC2enT5JfBNyNFtEo=",
+      "dev": true
+    },
     "jasmine-core": {
       "version": "2.6.4",
       "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.6.4.tgz",
diff --git a/web/gui/src/main/webapp/tests/package.json b/web/gui/src/main/webapp/tests/package.json
index 4d298bb..59b8102 100644
--- a/web/gui/src/main/webapp/tests/package.json
+++ b/web/gui/src/main/webapp/tests/package.json
@@ -4,8 +4,9 @@
   "description": "Tests for the ONOS GUI",
   "main": "karma.conf.js",
   "scripts": {
-    "test:dev": "karma start",
-    "test": "karma start karma.ci.js"
+    "install:deps": "./node_modules/bower/bin/bower install ../bower.json --config.directory=../vendor",
+    "test:dev": "npm run install:deps && karma start",
+    "test": "npm run install:deps && karma start karma.ci.js"
   },
   "author": "ON.Lab",
   "license": "Apache-2.0",
@@ -14,6 +15,7 @@
     "url": "opennetworkinglab/onos"
   },
   "devDependencies": {
+    "bower": "^1.8.0",
     "jasmine-core": "^2.4.1",
     "karma": "^0.13.22",
     "karma-babel-preprocessor": "^6.0.1",
diff --git a/web/gui/src/main/webapp/tp/AngularJS.LICENSE b/web/gui/src/main/webapp/tp/AngularJS.LICENSE
deleted file mode 100644
index 8d06275..0000000
--- a/web/gui/src/main/webapp/tp/AngularJS.LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-AngularJS uses the MIT License, as follows...
------------------------------------------------------------------------------
-
-The MIT License
-
-Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/web/gui/src/main/webapp/tp/Chart.LICENSE b/web/gui/src/main/webapp/tp/Chart.LICENSE
deleted file mode 100644
index 36d5cf0..0000000
--- a/web/gui/src/main/webapp/tp/Chart.LICENSE
+++ /dev/null
@@ -1,7 +0,0 @@
-Copyright (c) 2013-2016 Nick Downie
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/web/gui/src/main/webapp/tp/Chart.js b/web/gui/src/main/webapp/tp/Chart.js
deleted file mode 100644
index 24ffad0..0000000
--- a/web/gui/src/main/webapp/tp/Chart.js
+++ /dev/null
@@ -1,12757 +0,0 @@
-/*!
- * Chart.js
- * http://chartjs.org/
- * Version: 2.6.0
- *
- * Copyright 2017 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 */
-    var colorNames = require(6);
-
-    module.exports = {
-        getRgba: getRgba,
-        getHsla: getHsla,
-        getRgb: getRgb,
-        getHsl: getHsl,
-        getHwb: getHwb,
-        getAlpha: getAlpha,
-
-        hexString: hexString,
-        rgbString: rgbString,
-        rgbaString: rgbaString,
-        percentString: percentString,
-        percentaString: percentaString,
-        hslString: hslString,
-        hslaString: hslaString,
-        hwbString: hwbString,
-        keyword: keyword
-    }
-
-    function getRgba(string) {
-        if (!string) {
-            return;
-        }
-        var abbr =  /^#([a-fA-F0-9]{3})$/,
-            hex =  /^#([a-fA-F0-9]{6})$/,
-            rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,
-            per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,
-            keyword = /(\w+)/;
-
-        var rgb = [0, 0, 0],
-            a = 1,
-            match = string.match(abbr);
-        if (match) {
-            match = match[1];
-            for (var i = 0; i < rgb.length; i++) {
-                rgb[i] = parseInt(match[i] + match[i], 16);
-            }
-        }
-        else if (match = string.match(hex)) {
-            match = match[1];
-            for (var i = 0; i < rgb.length; i++) {
-                rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);
-            }
-        }
-        else if (match = string.match(rgba)) {
-            for (var i = 0; i < rgb.length; i++) {
-                rgb[i] = parseInt(match[i + 1]);
-            }
-            a = parseFloat(match[4]);
-        }
-        else if (match = string.match(per)) {
-            for (var i = 0; i < rgb.length; i++) {
-                rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);
-            }
-            a = parseFloat(match[4]);
-        }
-        else if (match = string.match(keyword)) {
-            if (match[1] == "transparent") {
-                return [0, 0, 0, 0];
-            }
-            rgb = colorNames[match[1]];
-            if (!rgb) {
-                return;
-            }
-        }
-
-        for (var i = 0; i < rgb.length; i++) {
-            rgb[i] = scale(rgb[i], 0, 255);
-        }
-        if (!a && a != 0) {
-            a = 1;
-        }
-        else {
-            a = scale(a, 0, 1);
-        }
-        rgb[3] = a;
-        return rgb;
-    }
-
-    function getHsla(string) {
-        if (!string) {
-            return;
-        }
-        var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
-        var match = string.match(hsl);
-        if (match) {
-            var alpha = parseFloat(match[4]);
-            var h = scale(parseInt(match[1]), 0, 360),
-                s = scale(parseFloat(match[2]), 0, 100),
-                l = scale(parseFloat(match[3]), 0, 100),
-                a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
-            return [h, s, l, a];
-        }
-    }
-
-    function getHwb(string) {
-        if (!string) {
-            return;
-        }
-        var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
-        var match = string.match(hwb);
-        if (match) {
-            var alpha = parseFloat(match[4]);
-            var h = scale(parseInt(match[1]), 0, 360),
-                w = scale(parseFloat(match[2]), 0, 100),
-                b = scale(parseFloat(match[3]), 0, 100),
-                a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
-            return [h, w, b, a];
-        }
-    }
-
-    function getRgb(string) {
-        var rgba = getRgba(string);
-        return rgba && rgba.slice(0, 3);
-    }
-
-    function getHsl(string) {
-        var hsla = getHsla(string);
-        return hsla && hsla.slice(0, 3);
-    }
-
-    function getAlpha(string) {
-        var vals = getRgba(string);
-        if (vals) {
-            return vals[3];
-        }
-        else if (vals = getHsla(string)) {
-            return vals[3];
-        }
-        else if (vals = getHwb(string)) {
-            return vals[3];
-        }
-    }
-
-// generators
-    function hexString(rgb) {
-        return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])
-            + hexDouble(rgb[2]);
-    }
-
-    function rgbString(rgba, alpha) {
-        if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
-            return rgbaString(rgba, alpha);
-        }
-        return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";
-    }
-
-    function rgbaString(rgba, alpha) {
-        if (alpha === undefined) {
-            alpha = (rgba[3] !== undefined ? rgba[3] : 1);
-        }
-        return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]
-            + ", " + alpha + ")";
-    }
-
-    function percentString(rgba, alpha) {
-        if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
-            return percentaString(rgba, alpha);
-        }
-        var r = Math.round(rgba[0]/255 * 100),
-            g = Math.round(rgba[1]/255 * 100),
-            b = Math.round(rgba[2]/255 * 100);
-
-        return "rgb(" + r + "%, " + g + "%, " + b + "%)";
-    }
-
-    function percentaString(rgba, alpha) {
-        var r = Math.round(rgba[0]/255 * 100),
-            g = Math.round(rgba[1]/255 * 100),
-            b = Math.round(rgba[2]/255 * 100);
-        return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";
-    }
-
-    function hslString(hsla, alpha) {
-        if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {
-            return hslaString(hsla, alpha);
-        }
-        return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";
-    }
-
-    function hslaString(hsla, alpha) {
-        if (alpha === undefined) {
-            alpha = (hsla[3] !== undefined ? hsla[3] : 1);
-        }
-        return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "
-            + alpha + ")";
-    }
-
-// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
-// (hwb have alpha optional & 1 is default value)
-    function hwbString(hwb, alpha) {
-        if (alpha === undefined) {
-            alpha = (hwb[3] !== undefined ? hwb[3] : 1);
-        }
-        return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"
-            + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";
-    }
-
-    function keyword(rgb) {
-        return reverseNames[rgb.slice(0, 3)];
-    }
-
-// helpers
-    function scale(num, min, max) {
-        return Math.min(Math.max(min, num), max);
-    }
-
-    function hexDouble(num) {
-        var str = num.toString(16).toUpperCase();
-        return (str.length < 2) ? "0" + str : str;
-    }
-
-
-//create a list of reverse color names
-    var reverseNames = {};
-    for (var name in colorNames) {
-        reverseNames[colorNames[name]] = name;
-    }
-
-},{"6":6}],3:[function(require,module,exports){
-    /* MIT license */
-    var convert = require(5);
-    var string = require(2);
-
-    var Color = function (obj) {
-        if (obj instanceof Color) {
-            return obj;
-        }
-        if (!(this instanceof Color)) {
-            return new Color(obj);
-        }
-
-        this.valid = false;
-        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
-        };
-
-        // parse Color() argument
-        var vals;
-        if (typeof obj === 'string') {
-            vals = string.getRgba(obj);
-            if (vals) {
-                this.setValues('rgb', vals);
-            } else if (vals = string.getHsla(obj)) {
-                this.setValues('hsl', vals);
-            } else if (vals = string.getHwb(obj)) {
-                this.setValues('hwb', vals);
-            }
-        } else if (typeof obj === 'object') {
-            vals = obj;
-            if (vals.r !== undefined || vals.red !== undefined) {
-                this.setValues('rgb', vals);
-            } else if (vals.l !== undefined || vals.lightness !== undefined) {
-                this.setValues('hsl', vals);
-            } else if (vals.v !== undefined || vals.value !== undefined) {
-                this.setValues('hsv', vals);
-            } else if (vals.w !== undefined || vals.whiteness !== undefined) {
-                this.setValues('hwb', vals);
-            } else if (vals.c !== undefined || vals.cyan !== undefined) {
-                this.setValues('cmyk', vals);
-            }
-        }
-    };
-
-    Color.prototype = {
-        isValid: function () {
-            return this.valid;
-        },
-        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 values = this.values;
-            if (values.alpha !== 1) {
-                return values.hwb.concat([values.alpha]);
-            }
-            return values.hwb;
-        },
-        cmykArray: function () {
-            return this.values.cmyk;
-        },
-        rgbaArray: function () {
-            var values = this.values;
-            return values.rgb.concat([values.alpha]);
-        },
-        hslaArray: function () {
-            var values = this.values;
-            return values.hsl.concat([values.alpha]);
-        },
-        alpha: function (val) {
-            if (val === undefined) {
-                return this.values.alpha;
-            }
-            this.setValues('alpha', val);
-            return this;
-        },
-
-        red: function (val) {
-            return this.setChannel('rgb', 0, val);
-        },
-        green: function (val) {
-            return this.setChannel('rgb', 1, val);
-        },
-        blue: function (val) {
-            return this.setChannel('rgb', 2, val);
-        },
-        hue: function (val) {
-            if (val) {
-                val %= 360;
-                val = val < 0 ? 360 + val : val;
-            }
-            return this.setChannel('hsl', 0, val);
-        },
-        saturation: function (val) {
-            return this.setChannel('hsl', 1, val);
-        },
-        lightness: function (val) {
-            return this.setChannel('hsl', 2, val);
-        },
-        saturationv: function (val) {
-            return this.setChannel('hsv', 1, val);
-        },
-        whiteness: function (val) {
-            return this.setChannel('hwb', 1, val);
-        },
-        blackness: function (val) {
-            return this.setChannel('hwb', 2, val);
-        },
-        value: function (val) {
-            return this.setChannel('hsv', 2, val);
-        },
-        cyan: function (val) {
-            return this.setChannel('cmyk', 0, val);
-        },
-        magenta: function (val) {
-            return this.setChannel('cmyk', 1, val);
-        },
-        yellow: function (val) {
-            return this.setChannel('cmyk', 2, val);
-        },
-        black: function (val) {
-            return this.setChannel('cmyk', 3, val);
-        },
-
-        hexString: function () {
-            return string.hexString(this.values.rgb);
-        },
-        rgbString: function () {
-            return string.rgbString(this.values.rgb, this.values.alpha);
-        },
-        rgbaString: function () {
-            return string.rgbaString(this.values.rgb, this.values.alpha);
-        },
-        percentString: function () {
-            return string.percentString(this.values.rgb, this.values.alpha);
-        },
-        hslString: function () {
-            return string.hslString(this.values.hsl, this.values.alpha);
-        },
-        hslaString: function () {
-            return string.hslaString(this.values.hsl, this.values.alpha);
-        },
-        hwbString: function () {
-            return string.hwbString(this.values.hwb, this.values.alpha);
-        },
-        keyword: function () {
-            return string.keyword(this.values.rgb, this.values.alpha);
-        },
-
-        rgbNumber: function () {
-            var rgb = this.values.rgb;
-            return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
-        },
-
-        luminosity: function () {
-            // http://www.w3.org/TR/WCAG20/#relativeluminancedef
-            var rgb = this.values.rgb;
-            var lum = [];
-            for (var i = 0; i < rgb.length; i++) {
-                var chan = rgb[i] / 255;
-                lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);
-            }
-            return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
-        },
-
-        contrast: function (color2) {
-            // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
-            var lum1 = this.luminosity();
-            var lum2 = color2.luminosity();
-            if (lum1 > lum2) {
-                return (lum1 + 0.05) / (lum2 + 0.05);
-            }
-            return (lum2 + 0.05) / (lum1 + 0.05);
-        },
-
-        level: function (color2) {
-            var contrastRatio = this.contrast(color2);
-            if (contrastRatio >= 7.1) {
-                return 'AAA';
-            }
-
-            return (contrastRatio >= 4.5) ? 'AA' : '';
-        },
-
-        dark: function () {
-            // YIQ equation from http://24ways.org/2010/calculating-color-contrast
-            var rgb = this.values.rgb;
-            var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
-            return yiq < 128;
-        },
-
-        light: function () {
-            return !this.dark();
-        },
-
-        negate: function () {
-            var rgb = [];
-            for (var i = 0; i < 3; i++) {
-                rgb[i] = 255 - this.values.rgb[i];
-            }
-            this.setValues('rgb', rgb);
-            return this;
-        },
-
-        lighten: function (ratio) {
-            var hsl = this.values.hsl;
-            hsl[2] += hsl[2] * ratio;
-            this.setValues('hsl', hsl);
-            return this;
-        },
-
-        darken: function (ratio) {
-            var hsl = this.values.hsl;
-            hsl[2] -= hsl[2] * ratio;
-            this.setValues('hsl', hsl);
-            return this;
-        },
-
-        saturate: function (ratio) {
-            var hsl = this.values.hsl;
-            hsl[1] += hsl[1] * ratio;
-            this.setValues('hsl', hsl);
-            return this;
-        },
-
-        desaturate: function (ratio) {
-            var hsl = this.values.hsl;
-            hsl[1] -= hsl[1] * ratio;
-            this.setValues('hsl', hsl);
-            return this;
-        },
-
-        whiten: function (ratio) {
-            var hwb = this.values.hwb;
-            hwb[1] += hwb[1] * ratio;
-            this.setValues('hwb', hwb);
-            return this;
-        },
-
-        blacken: function (ratio) {
-            var hwb = this.values.hwb;
-            hwb[2] += hwb[2] * ratio;
-            this.setValues('hwb', hwb);
-            return this;
-        },
-
-        greyscale: function () {
-            var rgb = this.values.rgb;
-            // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
-            var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
-            this.setValues('rgb', [val, val, val]);
-            return this;
-        },
-
-        clearer: function (ratio) {
-            var alpha = this.values.alpha;
-            this.setValues('alpha', alpha - (alpha * ratio));
-            return this;
-        },
-
-        opaquer: function (ratio) {
-            var alpha = this.values.alpha;
-            this.setValues('alpha', alpha + (alpha * ratio));
-            return this;
-        },
-
-        rotate: function (degrees) {
-            var hsl = this.values.hsl;
-            var hue = (hsl[0] + degrees) % 360;
-            hsl[0] = hue < 0 ? 360 + hue : hue;
-            this.setValues('hsl', hsl);
-            return this;
-        },
-
-        /**
-         * Ported from sass implementation in C
-         * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
-         */
-        mix: function (mixinColor, weight) {
-            var color1 = this;
-            var color2 = mixinColor;
-            var p = weight === undefined ? 0.5 : weight;
-
-            var w = 2 * p - 1;
-            var a = color1.alpha() - color2.alpha();
-
-            var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
-            var w2 = 1 - w1;
-
-            return this
-                .rgb(
-                    w1 * color1.red() + w2 * color2.red(),
-                    w1 * color1.green() + w2 * color2.green(),
-                    w1 * color1.blue() + w2 * color2.blue()
-                )
-                .alpha(color1.alpha() * p + color2.alpha() * (1 - p));
-        },
-
-        toJSON: function () {
-            return this.rgb();
-        },
-
-        clone: function () {
-            // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
-            // making the final build way to big to embed in Chart.js. So let's do it manually,
-            // assuming that values to clone are 1 dimension arrays containing only numbers,
-            // except 'alpha' which is a number.
-            var result = new Color();
-            var source = this.values;
-            var target = result.values;
-            var value, type;
-
-            for (var prop in source) {
-                if (source.hasOwnProperty(prop)) {
-                    value = source[prop];
-                    type = ({}).toString.call(value);
-                    if (type === '[object Array]') {
-                        target[prop] = value.slice(0);
-                    } else if (type === '[object Number]') {
-                        target[prop] = value;
-                    } else {
-                        console.error('unexpected color value:', value);
-                    }
-                }
-            }
-
-            return result;
-        }
-    };
-
-    Color.prototype.spaces = {
-        rgb: ['red', 'green', 'blue'],
-        hsl: ['hue', 'saturation', 'lightness'],
-        hsv: ['hue', 'saturation', 'value'],
-        hwb: ['hue', 'whiteness', 'blackness'],
-        cmyk: ['cyan', 'magenta', 'yellow', 'black']
-    };
-
-    Color.prototype.maxes = {
-        rgb: [255, 255, 255],
-        hsl: [360, 100, 100],
-        hsv: [360, 100, 100],
-        hwb: [360, 100, 100],
-        cmyk: [100, 100, 100, 100]
-    };
-
-    Color.prototype.getValues = function (space) {
-        var values = this.values;
-        var vals = {};
-
-        for (var i = 0; i < space.length; i++) {
-            vals[space.charAt(i)] = values[space][i];
-        }
-
-        if (values.alpha !== 1) {
-            vals.a = values.alpha;
-        }
-
-        // {r: 255, g: 255, b: 255, a: 0.4}
-        return vals;
-    };
-
-    Color.prototype.setValues = function (space, vals) {
-        var values = this.values;
-        var spaces = this.spaces;
-        var maxes = this.maxes;
-        var alpha = 1;
-        var i;
-
-        this.valid = true;
-
-        if (space === 'alpha') {
-            alpha = vals;
-        } else if (vals.length) {
-            // [10, 10, 10]
-            values[space] = vals.slice(0, space.length);
-            alpha = vals[space.length];
-        } else if (vals[space.charAt(0)] !== undefined) {
-            // {r: 10, g: 10, b: 10}
-            for (i = 0; i < space.length; i++) {
-                values[space][i] = vals[space.charAt(i)];
-            }
-
-            alpha = vals.a;
-        } else if (vals[spaces[space][0]] !== undefined) {
-            // {red: 10, green: 10, blue: 10}
-            var chans = spaces[space];
-
-            for (i = 0; i < space.length; i++) {
-                values[space][i] = vals[chans[i]];
-            }
-
-            alpha = vals.alpha;
-        }
-
-        values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
-
-        if (space === 'alpha') {
-            return false;
-        }
-
-        var capped;
-
-        // cap values of the space prior converting all values
-        for (i = 0; i < space.length; i++) {
-            capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
-            values[space][i] = Math.round(capped);
-        }
-
-        // convert to all the other color spaces
-        for (var sname in spaces) {
-            if (sname !== space) {
-                values[sname] = convert[space][sname](values[space]);
-            }
-        }
-
-        return true;
-    };
-
-    Color.prototype.setSpace = function (space, args) {
-        var vals = args[0];
-
-        if (vals === undefined) {
-            // color.rgb()
-            return this.getValues(space);
-        }
-
-        // color.rgb(10, 10, 10)
-        if (typeof vals === 'number') {
-            vals = Array.prototype.slice.call(args);
-        }
-
-        this.setValues(space, vals);
-        return this;
-    };
-
-    Color.prototype.setChannel = function (space, index, val) {
-        var svalues = this.values[space];
-        if (val === undefined) {
-            // color.red()
-            return svalues[index];
-        } else if (val === svalues[index]) {
-            // color.red(color.red())
-            return this;
-        }
-
-        // color.red(100)
-        svalues[index] = val;
-        this.setValues(space, svalues);
-
-        return this;
-    };
-
-    if (typeof window !== 'undefined') {
-        window.Color = Color;
-    }
-
-    module.exports = Color;
-
-},{"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 = {
-        "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(require,module,exports){
-    /**
-     * @namespace Chart
-     */
-    var Chart = require(28)();
-
-    require(26)(Chart);
-    require(40)(Chart);
-    require(22)(Chart);
-    require(25)(Chart);
-    require(30)(Chart);
-    require(21)(Chart);
-    require(23)(Chart);
-    require(24)(Chart);
-    require(29)(Chart);
-    require(32)(Chart);
-    require(33)(Chart);
-    require(31)(Chart);
-    require(27)(Chart);
-    require(34)(Chart);
-
-    require(35)(Chart);
-    require(36)(Chart);
-    require(37)(Chart);
-    require(38)(Chart);
-
-    require(46)(Chart);
-    require(44)(Chart);
-    require(45)(Chart);
-    require(47)(Chart);
-    require(48)(Chart);
-    require(49)(Chart);
-
-// Controllers must be loaded after elements
-// See Chart.core.datasetController.dataElementType
-    require(15)(Chart);
-    require(16)(Chart);
-    require(17)(Chart);
-    require(18)(Chart);
-    require(19)(Chart);
-    require(20)(Chart);
-
-    require(8)(Chart);
-    require(9)(Chart);
-    require(10)(Chart);
-    require(11)(Chart);
-    require(12)(Chart);
-    require(13)(Chart);
-    require(14)(Chart);
-
-// Loading built-it plugins
-    var plugins = [];
-
-    plugins.push(
-        require(41)(Chart),
-        require(42)(Chart),
-        require(43)(Chart)
-    );
-
-    Chart.plugins.register(plugins);
-
-    module.exports = Chart;
-    if (typeof window !== 'undefined') {
-        window.Chart = Chart;
-    }
-
-},{"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,"40":40,"41":41,"42":42,"43":43,"44":44,"45":45,"46":46,"47":47,"48":48,"49":49,"8":8,"9":9}],8:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        Chart.Bar = function(context, config) {
-            config.type = 'bar';
-
-            return new Chart(context, config);
-        };
-
-    };
-
-},{}],9:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        Chart.Bubble = function(context, config) {
-            config.type = 'bubble';
-            return new Chart(context, config);
-        };
-
-    };
-
-},{}],10:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        Chart.Doughnut = function(context, config) {
-            config.type = 'doughnut';
-
-            return new Chart(context, config);
-        };
-
-    };
-
-},{}],11:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        Chart.Line = function(context, config) {
-            config.type = 'line';
-
-            return new Chart(context, config);
-        };
-
-    };
-
-},{}],12:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        Chart.PolarArea = function(context, config) {
-            config.type = 'polarArea';
-
-            return new Chart(context, config);
-        };
-
-    };
-
-},{}],13:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        Chart.Radar = function(context, config) {
-            config.type = 'radar';
-
-            return new Chart(context, config);
-        };
-
-    };
-
-},{}],14:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var defaultConfig = {
-            hover: {
-                mode: 'single'
-            },
-
-            scales: {
-                xAxes: [{
-                    type: 'linear', // scatter should not use a category axis
-                    position: 'bottom',
-                    id: 'x-axis-1' // need an ID so datasets can reference the scale
-                }],
-                yAxes: [{
-                    type: 'linear',
-                    position: 'left',
-                    id: 'y-axis-1'
-                }]
-            },
-
-            tooltips: {
-                callbacks: {
-                    title: function() {
-                        // Title doesn't make sense for scatter since we format the data as a point
-                        return '';
-                    },
-                    label: function(tooltipItem) {
-                        return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';
-                    }
-                }
-            }
-        };
-
-        // Register the default config for this type
-        Chart.defaults.scatter = defaultConfig;
-
-        // Scatter charts use line controllers
-        Chart.controllers.scatter = Chart.controllers.line;
-
-        Chart.Scatter = function(context, config) {
-            config.type = 'scatter';
-            return new Chart(context, config);
-        };
-
-    };
-
-},{}],15:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.bar = {
-            hover: {
-                mode: 'label'
-            },
-
-            scales: {
-                xAxes: [{
-                    type: 'category',
-
-                    // Specific to Bar Controller
-                    categoryPercentage: 0.8,
-                    barPercentage: 0.9,
-
-                    // grid line settings
-                    gridLines: {
-                        offsetGridLines: true
-                    }
-                }],
-                yAxes: [{
-                    type: 'linear'
-                }]
-            }
-        };
-
-        Chart.controllers.bar = Chart.DatasetController.extend({
-
-            dataElementType: Chart.elements.Rectangle,
-
-            initialize: function() {
-                var me = this;
-                var meta;
-
-                Chart.DatasetController.prototype.initialize.apply(me, arguments);
-
-                meta = me.getMeta();
-                meta.stack = me.getDataset().stack;
-                meta.bar = true;
-            },
-
-            update: function(reset) {
-                var me = this;
-                var elements = me.getMeta().data;
-                var i, ilen;
-
-                me._ruler = me.getRuler();
-
-                for (i = 0, ilen = elements.length; i < ilen; ++i) {
-                    me.updateElement(elements[i], i, reset);
-                }
-            },
-
-            updateElement: function(rectangle, index, reset) {
-                var me = this;
-                var chart = me.chart;
-                var meta = me.getMeta();
-                var dataset = me.getDataset();
-                var custom = rectangle.custom || {};
-                var rectangleOptions = chart.options.elements.rectangle;
-
-                rectangle._xScale = me.getScaleForId(meta.xAxisID);
-                rectangle._yScale = me.getScaleForId(meta.yAxisID);
-                rectangle._datasetIndex = me.index;
-                rectangle._index = index;
-
-                rectangle._model = {
-                    datasetLabel: dataset.label,
-                    label: chart.data.labels[index],
-                    borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,
-                    backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),
-                    borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),
-                    borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)
-                };
-
-                me.updateElementGeometry(rectangle, index, reset);
-
-                rectangle.pivot();
-            },
-
-            /**
-             * @private
-             */
-            updateElementGeometry: function(rectangle, index, reset) {
-                var me = this;
-                var model = rectangle._model;
-                var vscale = me.getValueScale();
-                var base = vscale.getBasePixel();
-                var horizontal = vscale.isHorizontal();
-                var ruler = me._ruler || me.getRuler();
-                var vpixels = me.calculateBarValuePixels(me.index, index);
-                var ipixels = me.calculateBarIndexPixels(me.index, index, ruler);
-
-                model.horizontal = horizontal;
-                model.base = reset? base : vpixels.base;
-                model.x = horizontal? reset? base : vpixels.head : ipixels.center;
-                model.y = horizontal? ipixels.center : reset? base : vpixels.head;
-                model.height = horizontal? ipixels.size : undefined;
-                model.width = horizontal? undefined : ipixels.size;
-            },
-
-            /**
-             * @private
-             */
-            getValueScaleId: function() {
-                return this.getMeta().yAxisID;
-            },
-
-            /**
-             * @private
-             */
-            getIndexScaleId: function() {
-                return this.getMeta().xAxisID;
-            },
-
-            /**
-             * @private
-             */
-            getValueScale: function() {
-                return this.getScaleForId(this.getValueScaleId());
-            },
-
-            /**
-             * @private
-             */
-            getIndexScale: function() {
-                return this.getScaleForId(this.getIndexScaleId());
-            },
-
-            /**
-             * Returns the effective number of stacks based on groups and bar visibility.
-             * @private
-             */
-            getStackCount: function(last) {
-                var me = this;
-                var chart = me.chart;
-                var scale = me.getIndexScale();
-                var stacked = scale.options.stacked;
-                var ilen = last === undefined? chart.data.datasets.length : last + 1;
-                var stacks = [];
-                var i, meta;
-
-                for (i = 0; i < ilen; ++i) {
-                    meta = chart.getDatasetMeta(i);
-                    if (meta.bar && chart.isDatasetVisible(i) &&
-                        (stacked === false ||
-                        (stacked === true && stacks.indexOf(meta.stack) === -1) ||
-                        (stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {
-                        stacks.push(meta.stack);
-                    }
-                }
-
-                return stacks.length;
-            },
-
-            /**
-             * Returns the stack index for the given dataset based on groups and bar visibility.
-             * @private
-             */
-            getStackIndex: function(datasetIndex) {
-                return this.getStackCount(datasetIndex) - 1;
-            },
-
-            /**
-             * @private
-             */
-            getRuler: function() {
-                var me = this;
-                var scale = me.getIndexScale();
-                var options = scale.options;
-                var stackCount = me.getStackCount();
-                var fullSize = scale.isHorizontal()? scale.width : scale.height;
-                var tickSize = fullSize / scale.ticks.length;
-                var categorySize = tickSize * options.categoryPercentage;
-                var fullBarSize = categorySize / stackCount;
-                var barSize = fullBarSize * options.barPercentage;
-
-                barSize = Math.min(
-                    helpers.getValueOrDefault(options.barThickness, barSize),
-                    helpers.getValueOrDefault(options.maxBarThickness, Infinity));
-
-                return {
-                    stackCount: stackCount,
-                    tickSize: tickSize,
-                    categorySize: categorySize,
-                    categorySpacing: tickSize - categorySize,
-                    fullBarSize: fullBarSize,
-                    barSize: barSize,
-                    barSpacing: fullBarSize - barSize,
-                    scale: scale
-                };
-            },
-
-            /**
-             * Note: pixel values are not clamped to the scale area.
-             * @private
-             */
-            calculateBarValuePixels: function(datasetIndex, index) {
-                var me = this;
-                var chart = me.chart;
-                var meta = me.getMeta();
-                var scale = me.getValueScale();
-                var datasets = chart.data.datasets;
-                var value = Number(datasets[datasetIndex].data[index]);
-                var stacked = scale.options.stacked;
-                var stack = meta.stack;
-                var start = 0;
-                var i, imeta, ivalue, base, head, size;
-
-                if (stacked || (stacked === undefined && stack !== undefined)) {
-                    for (i = 0; i < datasetIndex; ++i) {
-                        imeta = chart.getDatasetMeta(i);
-
-                        if (imeta.bar &&
-                            imeta.stack === stack &&
-                            imeta.controller.getValueScaleId() === scale.id &&
-                            chart.isDatasetVisible(i)) {
-
-                            ivalue = Number(datasets[i].data[index]);
-                            if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {
-                                start += ivalue;
-                            }
-                        }
-                    }
-                }
-
-                base = scale.getPixelForValue(start);
-                head = scale.getPixelForValue(start + value);
-                size = (head - base) / 2;
-
-                return {
-                    size: size,
-                    base: base,
-                    head: head,
-                    center: head + size / 2
-                };
-            },
-
-            /**
-             * @private
-             */
-            calculateBarIndexPixels: function(datasetIndex, index, ruler) {
-                var me = this;
-                var scale = ruler.scale;
-                var isCombo = me.chart.isCombo;
-                var stackIndex = me.getStackIndex(datasetIndex);
-                var base = scale.getPixelForValue(null, index, datasetIndex, isCombo);
-                var size = ruler.barSize;
-
-                base -= isCombo? ruler.tickSize / 2 : 0;
-                base += ruler.fullBarSize * stackIndex;
-                base += ruler.categorySpacing / 2;
-                base += ruler.barSpacing / 2;
-
-                return {
-                    size: size,
-                    base: base,
-                    head: base + size,
-                    center: base + size / 2
-                };
-            },
-
-            draw: function() {
-                var me = this;
-                var chart = me.chart;
-                var elements = me.getMeta().data;
-                var dataset = me.getDataset();
-                var ilen = elements.length;
-                var i = 0;
-                var d;
-
-                helpers.canvas.clipArea(chart.ctx, chart.chartArea);
-
-                for (; i<ilen; ++i) {
-                    d = dataset.data[i];
-                    if (d !== null && d !== undefined && !isNaN(d)) {
-                        elements[i].draw();
-                    }
-                }
-
-                helpers.canvas.unclipArea(chart.ctx);
-            },
-
-            setHoverStyle: function(rectangle) {
-                var dataset = this.chart.data.datasets[rectangle._datasetIndex];
-                var index = rectangle._index;
-                var custom = rectangle.custom || {};
-                var model = rectangle._model;
-
-                model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
-                model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));
-                model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
-            },
-
-            removeHoverStyle: function(rectangle) {
-                var dataset = this.chart.data.datasets[rectangle._datasetIndex];
-                var index = rectangle._index;
-                var custom = rectangle.custom || {};
-                var model = rectangle._model;
-                var rectangleElementOptions = this.chart.options.elements.rectangle;
-
-                model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);
-                model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);
-                model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);
-            }
-        });
-
-
-        // including horizontalBar in the bar file, instead of a file of its own
-        // it extends bar (like pie extends doughnut)
-        Chart.defaults.horizontalBar = {
-            hover: {
-                mode: 'label'
-            },
-
-            scales: {
-                xAxes: [{
-                    type: 'linear',
-                    position: 'bottom'
-                }],
-                yAxes: [{
-                    position: 'left',
-                    type: 'category',
-
-                    // Specific to Horizontal Bar Controller
-                    categoryPercentage: 0.8,
-                    barPercentage: 0.9,
-
-                    // grid line settings
-                    gridLines: {
-                        offsetGridLines: true
-                    }
-                }]
-            },
-            elements: {
-                rectangle: {
-                    borderSkipped: 'left'
-                }
-            },
-            tooltips: {
-                callbacks: {
-                    title: function(tooltipItems, data) {
-                        // Pick first xLabel for now
-                        var title = '';
-
-                        if (tooltipItems.length > 0) {
-                            if (tooltipItems[0].yLabel) {
-                                title = tooltipItems[0].yLabel;
-                            } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {
-                                title = data.labels[tooltipItems[0].index];
-                            }
-                        }
-
-                        return title;
-                    },
-                    label: function(tooltipItem, data) {
-                        var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
-                        return datasetLabel + ': ' + tooltipItem.xLabel;
-                    }
-                }
-            }
-        };
-
-        Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
-            /**
-             * @private
-             */
-            getValueScaleId: function() {
-                return this.getMeta().xAxisID;
-            },
-
-            /**
-             * @private
-             */
-            getIndexScaleId: function() {
-                return this.getMeta().yAxisID;
-            }
-        });
-    };
-
-},{}],16:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.bubble = {
-            hover: {
-                mode: 'single'
-            },
-
-            scales: {
-                xAxes: [{
-                    type: 'linear', // bubble should probably use a linear scale by default
-                    position: 'bottom',
-                    id: 'x-axis-0' // need an ID so datasets can reference the scale
-                }],
-                yAxes: [{
-                    type: 'linear',
-                    position: 'left',
-                    id: 'y-axis-0'
-                }]
-            },
-
-            tooltips: {
-                callbacks: {
-                    title: function() {
-                        // Title doesn't make sense for scatter since we format the data as a point
-                        return '';
-                    },
-                    label: function(tooltipItem, data) {
-                        var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
-                        var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
-                        return datasetLabel + ': (' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ', ' + dataPoint.r + ')';
-                    }
-                }
-            }
-        };
-
-        Chart.controllers.bubble = Chart.DatasetController.extend({
-
-            dataElementType: Chart.elements.Point,
-
-            update: function(reset) {
-                var me = this;
-                var meta = me.getMeta();
-                var points = meta.data;
-
-                // Update Points
-                helpers.each(points, function(point, index) {
-                    me.updateElement(point, index, reset);
-                });
-            },
-
-            updateElement: function(point, index, reset) {
-                var me = this;
-                var meta = me.getMeta();
-                var xScale = me.getScaleForId(meta.xAxisID);
-                var yScale = me.getScaleForId(meta.yAxisID);
-
-                var custom = point.custom || {};
-                var dataset = me.getDataset();
-                var data = dataset.data[index];
-                var pointElementOptions = me.chart.options.elements.point;
-                var dsIndex = me.index;
-
-                helpers.extend(point, {
-                    // Utility
-                    _xScale: xScale,
-                    _yScale: yScale,
-                    _datasetIndex: dsIndex,
-                    _index: index,
-
-                    // Desired view properties
-                    _model: {
-                        x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),
-                        y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),
-                        // Appearance
-                        radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),
-
-                        // Tooltip
-                        hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)
-                    }
-                });
-
-                // Trick to reset the styles of the point
-                Chart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);
-
-                var model = point._model;
-                model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));
-
-                point.pivot();
-            },
-
-            getRadius: function(value) {
-                return value.r || this.chart.options.elements.point.radius;
-            },
-
-            setHoverStyle: function(point) {
-                var me = this;
-                Chart.DatasetController.prototype.setHoverStyle.call(me, point);
-
-                // Radius
-                var dataset = me.chart.data.datasets[point._datasetIndex];
-                var index = point._index;
-                var custom = point.custom || {};
-                var model = point._model;
-                model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);
-            },
-
-            removeHoverStyle: function(point) {
-                var me = this;
-                Chart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);
-
-                var dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];
-                var custom = point.custom || {};
-                var model = point._model;
-
-                model.radius = custom.radius ? custom.radius : me.getRadius(dataVal);
-            }
-        });
-    };
-
-},{}],17:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers,
-            defaults = Chart.defaults;
-
-        defaults.doughnut = {
-            animation: {
-                // Boolean - Whether we animate the rotation of the Doughnut
-                animateRotate: true,
-                // Boolean - Whether we animate scaling the Doughnut from the centre
-                animateScale: false
-            },
-            aspectRatio: 1,
-            hover: {
-                mode: 'single'
-            },
-            legendCallback: function(chart) {
-                var text = [];
-                text.push('<ul class="' + chart.id + '-legend">');
-
-                var data = chart.data;
-                var datasets = data.datasets;
-                var labels = data.labels;
-
-                if (datasets.length) {
-                    for (var i = 0; i < datasets[0].data.length; ++i) {
-                        text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
-                        if (labels[i]) {
-                            text.push(labels[i]);
-                        }
-                        text.push('</li>');
-                    }
-                }
-
-                text.push('</ul>');
-                return text.join('');
-            },
-            legend: {
-                labels: {
-                    generateLabels: function(chart) {
-                        var data = chart.data;
-                        if (data.labels.length && data.datasets.length) {
-                            return data.labels.map(function(label, i) {
-                                var meta = chart.getDatasetMeta(0);
-                                var ds = data.datasets[0];
-                                var arc = meta.data[i];
-                                var custom = arc && arc.custom || {};
-                                var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-                                var arcOpts = chart.options.elements.arc;
-                                var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
-                                var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
-                                var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
-
-                                return {
-                                    text: label,
-                                    fillStyle: fill,
-                                    strokeStyle: stroke,
-                                    lineWidth: bw,
-                                    hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
-
-                                    // Extra data used for toggling the correct item
-                                    index: i
-                                };
-                            });
-                        }
-                        return [];
-                    }
-                },
-
-                onClick: function(e, legendItem) {
-                    var index = legendItem.index;
-                    var chart = this.chart;
-                    var i, ilen, meta;
-
-                    for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
-                        meta = chart.getDatasetMeta(i);
-                        // toggle visibility of index if exists
-                        if (meta.data[index]) {
-                            meta.data[index].hidden = !meta.data[index].hidden;
-                        }
-                    }
-
-                    chart.update();
-                }
-            },
-
-            // The percentage of the chart that we cut out of the middle.
-            cutoutPercentage: 50,
-
-            // The rotation of the chart, where the first data arc begins.
-            rotation: Math.PI * -0.5,
-
-            // The total circumference of the chart.
-            circumference: Math.PI * 2.0,
-
-            // Need to override these to give a nice default
-            tooltips: {
-                callbacks: {
-                    title: function() {
-                        return '';
-                    },
-                    label: function(tooltipItem, data) {
-                        var dataLabel = data.labels[tooltipItem.index];
-                        var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
-
-                        if (helpers.isArray(dataLabel)) {
-                            // show value on first line of multiline label
-                            // need to clone because we are changing the value
-                            dataLabel = dataLabel.slice();
-                            dataLabel[0] += value;
-                        } else {
-                            dataLabel += value;
-                        }
-
-                        return dataLabel;
-                    }
-                }
-            }
-        };
-
-        defaults.pie = helpers.clone(defaults.doughnut);
-        helpers.extend(defaults.pie, {
-            cutoutPercentage: 0
-        });
-
-
-        Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
-
-            dataElementType: Chart.elements.Arc,
-
-            linkScales: helpers.noop,
-
-            // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
-            getRingIndex: function(datasetIndex) {
-                var ringIndex = 0;
-
-                for (var j = 0; j < datasetIndex; ++j) {
-                    if (this.chart.isDatasetVisible(j)) {
-                        ++ringIndex;
-                    }
-                }
-
-                return ringIndex;
-            },
-
-            update: function(reset) {
-                var me = this;
-                var chart = me.chart,
-                    chartArea = chart.chartArea,
-                    opts = chart.options,
-                    arcOpts = opts.elements.arc,
-                    availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,
-                    availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,
-                    minSize = Math.min(availableWidth, availableHeight),
-                    offset = {
-                        x: 0,
-                        y: 0
-                    },
-                    meta = me.getMeta(),
-                    cutoutPercentage = opts.cutoutPercentage,
-                    circumference = opts.circumference;
-
-                // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
-                if (circumference < Math.PI * 2.0) {
-                    var startAngle = opts.rotation % (Math.PI * 2.0);
-                    startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);
-                    var endAngle = startAngle + circumference;
-                    var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};
-                    var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};
-                    var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);
-                    var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);
-                    var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);
-                    var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);
-                    var cutout = cutoutPercentage / 100.0;
-                    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))};
-                    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))};
-                    var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};
-                    minSize = Math.min(availableWidth / size.width, availableHeight / size.height);
-                    offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
-                }
-
-                chart.borderWidth = me.getMaxBorderWidth(meta.data);
-                chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
-                chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
-                chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
-                chart.offsetX = offset.x * chart.outerRadius;
-                chart.offsetY = offset.y * chart.outerRadius;
-
-                meta.total = me.calculateTotal();
-
-                me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
-                me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
-
-                helpers.each(meta.data, function(arc, index) {
-                    me.updateElement(arc, index, reset);
-                });
-            },
-
-            updateElement: function(arc, index, reset) {
-                var me = this;
-                var chart = me.chart,
-                    chartArea = chart.chartArea,
-                    opts = chart.options,
-                    animationOpts = opts.animation,
-                    centerX = (chartArea.left + chartArea.right) / 2,
-                    centerY = (chartArea.top + chartArea.bottom) / 2,
-                    startAngle = opts.rotation, // non reset case handled later
-                    endAngle = opts.rotation, // non reset case handled later
-                    dataset = me.getDataset(),
-                    circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),
-                    innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,
-                    outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,
-                    valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-
-                helpers.extend(arc, {
-                    // Utility
-                    _datasetIndex: me.index,
-                    _index: index,
-
-                    // Desired view properties
-                    _model: {
-                        x: centerX + chart.offsetX,
-                        y: centerY + chart.offsetY,
-                        startAngle: startAngle,
-                        endAngle: endAngle,
-                        circumference: circumference,
-                        outerRadius: outerRadius,
-                        innerRadius: innerRadius,
-                        label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
-                    }
-                });
-
-                var model = arc._model;
-                // Resets the visual styles
-                this.removeHoverStyle(arc);
-
-                // Set correct angles if not resetting
-                if (!reset || !animationOpts.animateRotate) {
-                    if (index === 0) {
-                        model.startAngle = opts.rotation;
-                    } else {
-                        model.startAngle = me.getMeta().data[index - 1]._model.endAngle;
-                    }
-
-                    model.endAngle = model.startAngle + model.circumference;
-                }
-
-                arc.pivot();
-            },
-
-            removeHoverStyle: function(arc) {
-                Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
-            },
-
-            calculateTotal: function() {
-                var dataset = this.getDataset();
-                var meta = this.getMeta();
-                var total = 0;
-                var value;
-
-                helpers.each(meta.data, function(element, index) {
-                    value = dataset.data[index];
-                    if (!isNaN(value) && !element.hidden) {
-                        total += Math.abs(value);
-                    }
-                });
-
-                /* if (total === 0) {
-                 total = NaN;
-                 }*/
-
-                return total;
-            },
-
-            calculateCircumference: function(value) {
-                var total = this.getMeta().total;
-                if (total > 0 && !isNaN(value)) {
-                    return (Math.PI * 2.0) * (value / total);
-                }
-                return 0;
-            },
-
-            // gets the max border or hover width to properly scale pie charts
-            getMaxBorderWidth: function(elements) {
-                var max = 0,
-                    index = this.index,
-                    length = elements.length,
-                    borderWidth,
-                    hoverWidth;
-
-                for (var i = 0; i < length; i++) {
-                    borderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;
-                    hoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
-
-                    max = borderWidth > max ? borderWidth : max;
-                    max = hoverWidth > max ? hoverWidth : max;
-                }
-                return max;
-            }
-        });
-    };
-
-},{}],18:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.line = {
-            showLines: true,
-            spanGaps: false,
-
-            hover: {
-                mode: 'label'
-            },
-
-            scales: {
-                xAxes: [{
-                    type: 'category',
-                    id: 'x-axis-0'
-                }],
-                yAxes: [{
-                    type: 'linear',
-                    id: 'y-axis-0'
-                }]
-            }
-        };
-
-        function lineEnabled(dataset, options) {
-            return helpers.getValueOrDefault(dataset.showLine, options.showLines);
-        }
-
-        Chart.controllers.line = Chart.DatasetController.extend({
-
-            datasetElementType: Chart.elements.Line,
-
-            dataElementType: Chart.elements.Point,
-
-            update: function(reset) {
-                var me = this;
-                var meta = me.getMeta();
-                var line = meta.dataset;
-                var points = meta.data || [];
-                var options = me.chart.options;
-                var lineElementOptions = options.elements.line;
-                var scale = me.getScaleForId(meta.yAxisID);
-                var i, ilen, custom;
-                var dataset = me.getDataset();
-                var showLine = lineEnabled(dataset, options);
-
-                // Update Line
-                if (showLine) {
-                    custom = line.custom || {};
-
-                    // Compatibility: If the properties are defined with only the old name, use those values
-                    if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
-                        dataset.lineTension = dataset.tension;
-                    }
-
-                    // Utility
-                    line._scale = scale;
-                    line._datasetIndex = me.index;
-                    // Data
-                    line._children = points;
-                    // Model
-                    line._model = {
-                        // Appearance
-                        // The default behavior of lines is to break at null values, according
-                        // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
-                        // This option gives lines the ability to span gaps
-                        spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
-                        tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
-                        backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
-                        borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
-                        borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
-                        borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
-                        borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
-                        borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
-                        borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
-                        fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
-                        steppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
-                        cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.getValueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),
-                    };
-
-                    line.pivot();
-                }
-
-                // Update Points
-                for (i=0, ilen=points.length; i<ilen; ++i) {
-                    me.updateElement(points[i], i, reset);
-                }
-
-                if (showLine && line._model.tension !== 0) {
-                    me.updateBezierControlPoints();
-                }
-
-                // Now pivot the point for animation
-                for (i=0, ilen=points.length; i<ilen; ++i) {
-                    points[i].pivot();
-                }
-            },
-
-            getPointBackgroundColor: function(point, index) {
-                var backgroundColor = this.chart.options.elements.point.backgroundColor;
-                var dataset = this.getDataset();
-                var custom = point.custom || {};
-
-                if (custom.backgroundColor) {
-                    backgroundColor = custom.backgroundColor;
-                } else if (dataset.pointBackgroundColor) {
-                    backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
-                } else if (dataset.backgroundColor) {
-                    backgroundColor = dataset.backgroundColor;
-                }
-
-                return backgroundColor;
-            },
-
-            getPointBorderColor: function(point, index) {
-                var borderColor = this.chart.options.elements.point.borderColor;
-                var dataset = this.getDataset();
-                var custom = point.custom || {};
-
-                if (custom.borderColor) {
-                    borderColor = custom.borderColor;
-                } else if (dataset.pointBorderColor) {
-                    borderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);
-                } else if (dataset.borderColor) {
-                    borderColor = dataset.borderColor;
-                }
-
-                return borderColor;
-            },
-
-            getPointBorderWidth: function(point, index) {
-                var borderWidth = this.chart.options.elements.point.borderWidth;
-                var dataset = this.getDataset();
-                var custom = point.custom || {};
-
-                if (!isNaN(custom.borderWidth)) {
-                    borderWidth = custom.borderWidth;
-                } else if (!isNaN(dataset.pointBorderWidth)) {
-                    borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
-                } else if (!isNaN(dataset.borderWidth)) {
-                    borderWidth = dataset.borderWidth;
-                }
-
-                return borderWidth;
-            },
-
-            updateElement: function(point, index, reset) {
-                var me = this;
-                var meta = me.getMeta();
-                var custom = point.custom || {};
-                var dataset = me.getDataset();
-                var datasetIndex = me.index;
-                var value = dataset.data[index];
-                var yScale = me.getScaleForId(meta.yAxisID);
-                var xScale = me.getScaleForId(meta.xAxisID);
-                var pointOptions = me.chart.options.elements.point;
-                var x, y;
-                var labels = me.chart.data.labels || [];
-                var includeOffset = (labels.length === 1 || dataset.data.length === 1) || me.chart.isCombo;
-
-                // Compatibility: If the properties are defined with only the old name, use those values
-                if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
-                    dataset.pointRadius = dataset.radius;
-                }
-                if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
-                    dataset.pointHitRadius = dataset.hitRadius;
-                }
-
-                x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);
-                y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
-
-                // Utility
-                point._xScale = xScale;
-                point._yScale = yScale;
-                point._datasetIndex = datasetIndex;
-                point._index = index;
-
-                // Desired view properties
-                point._model = {
-                    x: x,
-                    y: y,
-                    skip: custom.skip || isNaN(x) || isNaN(y),
-                    // Appearance
-                    radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
-                    pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
-                    backgroundColor: me.getPointBackgroundColor(point, index),
-                    borderColor: me.getPointBorderColor(point, index),
-                    borderWidth: me.getPointBorderWidth(point, index),
-                    tension: meta.dataset._model ? meta.dataset._model.tension : 0,
-                    steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
-                    // Tooltip
-                    hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
-                };
-            },
-
-            calculatePointY: function(value, index, datasetIndex) {
-                var me = this;
-                var chart = me.chart;
-                var meta = me.getMeta();
-                var yScale = me.getScaleForId(meta.yAxisID);
-                var sumPos = 0;
-                var sumNeg = 0;
-                var i, ds, dsMeta;
-
-                if (yScale.options.stacked) {
-                    for (i = 0; i < datasetIndex; i++) {
-                        ds = chart.data.datasets[i];
-                        dsMeta = chart.getDatasetMeta(i);
-                        if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
-                            var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
-                            if (stackedRightValue < 0) {
-                                sumNeg += stackedRightValue || 0;
-                            } else {
-                                sumPos += stackedRightValue || 0;
-                            }
-                        }
-                    }
-
-                    var rightValue = Number(yScale.getRightValue(value));
-                    if (rightValue < 0) {
-                        return yScale.getPixelForValue(sumNeg + rightValue);
-                    }
-                    return yScale.getPixelForValue(sumPos + rightValue);
-                }
-
-                return yScale.getPixelForValue(value);
-            },
-
-            updateBezierControlPoints: function() {
-                var me = this;
-                var meta = me.getMeta();
-                var area = me.chart.chartArea;
-                var points = (meta.data || []);
-                var i, ilen, point, model, controlPoints;
-
-                // Only consider points that are drawn in case the spanGaps option is used
-                if (meta.dataset._model.spanGaps) {
-                    points = points.filter(function(pt) {
-                        return !pt._model.skip;
-                    });
-                }
-
-                function capControlPoint(pt, min, max) {
-                    return Math.max(Math.min(pt, max), min);
-                }
-
-                if (meta.dataset._model.cubicInterpolationMode === 'monotone') {
-                    helpers.splineCurveMonotone(points);
-                } else {
-                    for (i = 0, ilen = points.length; i < ilen; ++i) {
-                        point = points[i];
-                        model = point._model;
-                        controlPoints = helpers.splineCurve(
-                            helpers.previousItem(points, i)._model,
-                            model,
-                            helpers.nextItem(points, i)._model,
-                            meta.dataset._model.tension
-                        );
-                        model.controlPointPreviousX = controlPoints.previous.x;
-                        model.controlPointPreviousY = controlPoints.previous.y;
-                        model.controlPointNextX = controlPoints.next.x;
-                        model.controlPointNextY = controlPoints.next.y;
-                    }
-                }
-
-                if (me.chart.options.elements.line.capBezierPoints) {
-                    for (i = 0, ilen = points.length; i < ilen; ++i) {
-                        model = points[i]._model;
-                        model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);
-                        model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);
-                        model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);
-                        model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);
-                    }
-                }
-            },
-
-            draw: function() {
-                var me = this;
-                var chart = me.chart;
-                var meta = me.getMeta();
-                var points = meta.data || [];
-                var area = chart.chartArea;
-                var ilen = points.length;
-                var i = 0;
-
-                Chart.canvasHelpers.clipArea(chart.ctx, area);
-
-                if (lineEnabled(me.getDataset(), chart.options)) {
-                    meta.dataset.draw();
-                }
-
-                Chart.canvasHelpers.unclipArea(chart.ctx);
-
-                // Draw the points
-                for (; i<ilen; ++i) {
-                    points[i].draw(area);
-                }
-            },
-
-            setHoverStyle: function(point) {
-                // Point
-                var dataset = this.chart.data.datasets[point._datasetIndex];
-                var index = point._index;
-                var custom = point.custom || {};
-                var model = point._model;
-
-                model.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
-                model.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
-                model.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
-                model.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
-            },
-
-            removeHoverStyle: function(point) {
-                var me = this;
-                var dataset = me.chart.data.datasets[point._datasetIndex];
-                var index = point._index;
-                var custom = point.custom || {};
-                var model = point._model;
-
-                // Compatibility: If the properties are defined with only the old name, use those values
-                if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
-                    dataset.pointRadius = dataset.radius;
-                }
-
-                model.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
-                model.backgroundColor = me.getPointBackgroundColor(point, index);
-                model.borderColor = me.getPointBorderColor(point, index);
-                model.borderWidth = me.getPointBorderWidth(point, index);
-            }
-        });
-    };
-
-},{}],19:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.polarArea = {
-
-            scale: {
-                type: 'radialLinear',
-                angleLines: {
-                    display: false
-                },
-                gridLines: {
-                    circular: true
-                },
-                pointLabels: {
-                    display: false
-                },
-                ticks: {
-                    beginAtZero: true
-                }
-            },
-
-            // Boolean - Whether to animate the rotation of the chart
-            animation: {
-                animateRotate: true,
-                animateScale: true
-            },
-
-            startAngle: -0.5 * Math.PI,
-            aspectRatio: 1,
-            legendCallback: function(chart) {
-                var text = [];
-                text.push('<ul class="' + chart.id + '-legend">');
-
-                var data = chart.data;
-                var datasets = data.datasets;
-                var labels = data.labels;
-
-                if (datasets.length) {
-                    for (var i = 0; i < datasets[0].data.length; ++i) {
-                        text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
-                        if (labels[i]) {
-                            text.push(labels[i]);
-                        }
-                        text.push('</li>');
-                    }
-                }
-
-                text.push('</ul>');
-                return text.join('');
-            },
-            legend: {
-                labels: {
-                    generateLabels: function(chart) {
-                        var data = chart.data;
-                        if (data.labels.length && data.datasets.length) {
-                            return data.labels.map(function(label, i) {
-                                var meta = chart.getDatasetMeta(0);
-                                var ds = data.datasets[0];
-                                var arc = meta.data[i];
-                                var custom = arc.custom || {};
-                                var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-                                var arcOpts = chart.options.elements.arc;
-                                var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
-                                var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
-                                var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
-
-                                return {
-                                    text: label,
-                                    fillStyle: fill,
-                                    strokeStyle: stroke,
-                                    lineWidth: bw,
-                                    hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
-
-                                    // Extra data used for toggling the correct item
-                                    index: i
-                                };
-                            });
-                        }
-                        return [];
-                    }
-                },
-
-                onClick: function(e, legendItem) {
-                    var index = legendItem.index;
-                    var chart = this.chart;
-                    var i, ilen, meta;
-
-                    for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
-                        meta = chart.getDatasetMeta(i);
-                        meta.data[index].hidden = !meta.data[index].hidden;
-                    }
-
-                    chart.update();
-                }
-            },
-
-            // Need to override these to give a nice default
-            tooltips: {
-                callbacks: {
-                    title: function() {
-                        return '';
-                    },
-                    label: function(tooltipItem, data) {
-                        return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;
-                    }
-                }
-            }
-        };
-
-        Chart.controllers.polarArea = Chart.DatasetController.extend({
-
-            dataElementType: Chart.elements.Arc,
-
-            linkScales: helpers.noop,
-
-            update: function(reset) {
-                var me = this;
-                var chart = me.chart;
-                var chartArea = chart.chartArea;
-                var meta = me.getMeta();
-                var opts = chart.options;
-                var arcOpts = opts.elements.arc;
-                var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
-                chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
-                chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
-                chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
-
-                me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
-                me.innerRadius = me.outerRadius - chart.radiusLength;
-
-                meta.count = me.countVisibleElements();
-
-                helpers.each(meta.data, function(arc, index) {
-                    me.updateElement(arc, index, reset);
-                });
-            },
-
-            updateElement: function(arc, index, reset) {
-                var me = this;
-                var chart = me.chart;
-                var dataset = me.getDataset();
-                var opts = chart.options;
-                var animationOpts = opts.animation;
-                var scale = chart.scale;
-                var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-                var labels = chart.data.labels;
-
-                var circumference = me.calculateCircumference(dataset.data[index]);
-                var centerX = scale.xCenter;
-                var centerY = scale.yCenter;
-
-                // If there is NaN data before us, we need to calculate the starting angle correctly.
-                // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
-                var visibleCount = 0;
-                var meta = me.getMeta();
-                for (var i = 0; i < index; ++i) {
-                    if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {
-                        ++visibleCount;
-                    }
-                }
-
-                // var negHalfPI = -0.5 * Math.PI;
-                var datasetStartAngle = opts.startAngle;
-                var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
-                var startAngle = datasetStartAngle + (circumference * visibleCount);
-                var endAngle = startAngle + (arc.hidden ? 0 : circumference);
-
-                var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
-
-                helpers.extend(arc, {
-                    // Utility
-                    _datasetIndex: me.index,
-                    _index: index,
-                    _scale: scale,
-
-                    // Desired view properties
-                    _model: {
-                        x: centerX,
-                        y: centerY,
-                        innerRadius: 0,
-                        outerRadius: reset ? resetRadius : distance,
-                        startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
-                        endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
-                        label: getValueAtIndexOrDefault(labels, index, labels[index])
-                    }
-                });
-
-                // Apply border and fill style
-                me.removeHoverStyle(arc);
-
-                arc.pivot();
-            },
-
-            removeHoverStyle: function(arc) {
-                Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
-            },
-
-            countVisibleElements: function() {
-                var dataset = this.getDataset();
-                var meta = this.getMeta();
-                var count = 0;
-
-                helpers.each(meta.data, function(element, index) {
-                    if (!isNaN(dataset.data[index]) && !element.hidden) {
-                        count++;
-                    }
-                });
-
-                return count;
-            },
-
-            calculateCircumference: function(value) {
-                var count = this.getMeta().count;
-                if (count > 0 && !isNaN(value)) {
-                    return (2 * Math.PI) / count;
-                }
-                return 0;
-            }
-        });
-    };
-
-},{}],20:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.radar = {
-            aspectRatio: 1,
-            scale: {
-                type: 'radialLinear'
-            },
-            elements: {
-                line: {
-                    tension: 0 // no bezier in radar
-                }
-            }
-        };
-
-        Chart.controllers.radar = Chart.DatasetController.extend({
-
-            datasetElementType: Chart.elements.Line,
-
-            dataElementType: Chart.elements.Point,
-
-            linkScales: helpers.noop,
-
-            update: function(reset) {
-                var me = this;
-                var meta = me.getMeta();
-                var line = meta.dataset;
-                var points = meta.data;
-                var custom = line.custom || {};
-                var dataset = me.getDataset();
-                var lineElementOptions = me.chart.options.elements.line;
-                var scale = me.chart.scale;
-
-                // Compatibility: If the properties are defined with only the old name, use those values
-                if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
-                    dataset.lineTension = dataset.tension;
-                }
-
-                helpers.extend(meta.dataset, {
-                    // Utility
-                    _datasetIndex: me.index,
-                    _scale: scale,
-                    // Data
-                    _children: points,
-                    _loop: true,
-                    // Model
-                    _model: {
-                        // Appearance
-                        tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
-                        backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
-                        borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
-                        borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
-                        fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
-                        borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
-                        borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
-                        borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
-                        borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
-                    }
-                });
-
-                meta.dataset.pivot();
-
-                // Update Points
-                helpers.each(points, function(point, index) {
-                    me.updateElement(point, index, reset);
-                }, me);
-
-                // Update bezier control points
-                me.updateBezierControlPoints();
-            },
-            updateElement: function(point, index, reset) {
-                var me = this;
-                var custom = point.custom || {};
-                var dataset = me.getDataset();
-                var scale = me.chart.scale;
-                var pointElementOptions = me.chart.options.elements.point;
-                var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
-
-                // Compatibility: If the properties are defined with only the old name, use those values
-                if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
-                    dataset.pointRadius = dataset.radius;
-                }
-                if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
-                    dataset.pointHitRadius = dataset.hitRadius;
-                }
-
-                helpers.extend(point, {
-                    // Utility
-                    _datasetIndex: me.index,
-                    _index: index,
-                    _scale: scale,
-
-                    // Desired view properties
-                    _model: {
-                        x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
-                        y: reset ? scale.yCenter : pointPosition.y,
-
-                        // Appearance
-                        tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),
-                        radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),
-                        backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),
-                        borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),
-                        borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),
-                        pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),
-
-                        // Tooltip
-                        hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)
-                    }
-                });
-
-                point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
-            },
-            updateBezierControlPoints: function() {
-                var chartArea = this.chart.chartArea;
-                var meta = this.getMeta();
-
-                helpers.each(meta.data, function(point, index) {
-                    var model = point._model;
-                    var controlPoints = helpers.splineCurve(
-                        helpers.previousItem(meta.data, index, true)._model,
-                        model,
-                        helpers.nextItem(meta.data, index, true)._model,
-                        model.tension
-                    );
-
-                    // Prevent the bezier going outside of the bounds of the graph
-                    model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);
-                    model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);
-
-                    model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);
-                    model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);
-
-                    // Now pivot the point for animation
-                    point.pivot();
-                });
-            },
-
-            setHoverStyle: function(point) {
-                // Point
-                var dataset = this.chart.data.datasets[point._datasetIndex];
-                var custom = point.custom || {};
-                var index = point._index;
-                var model = point._model;
-
-                model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
-                model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
-                model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
-                model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
-            },
-
-            removeHoverStyle: function(point) {
-                var dataset = this.chart.data.datasets[point._datasetIndex];
-                var custom = point.custom || {};
-                var index = point._index;
-                var model = point._model;
-                var pointElementOptions = this.chart.options.elements.point;
-
-                model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);
-                model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);
-                model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);
-                model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);
-            }
-        });
-    };
-
-},{}],21:[function(require,module,exports){
-    /* global window: false */
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.global.animation = {
-            duration: 1000,
-            easing: 'easeOutQuart',
-            onProgress: helpers.noop,
-            onComplete: helpers.noop
-        };
-
-        Chart.Animation = Chart.Element.extend({
-            chart: null, // the animation associated chart instance
-            currentStep: 0, // the current animation step
-            numSteps: 60, // default number of steps
-            easing: '', // the easing to use for this animation
-            render: null, // render function used by the animation service
-
-            onAnimationProgress: null, // user specified callback to fire on each step of the animation
-            onAnimationComplete: null, // user specified callback to fire when the animation finishes
-        });
-
-        Chart.animationService = {
-            frameDuration: 17,
-            animations: [],
-            dropFrames: 0,
-            request: null,
-
-            /**
-             * @param {Chart} chart - The chart to animate.
-             * @param {Chart.Animation} animation - The animation that we will animate.
-             * @param {Number} duration - The animation duration in ms.
-             * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions
-             */
-            addAnimation: function(chart, animation, duration, lazy) {
-                var animations = this.animations;
-                var i, ilen;
-
-                animation.chart = chart;
-
-                if (!lazy) {
-                    chart.animating = true;
-                }
-
-                for (i=0, ilen=animations.length; i < ilen; ++i) {
-                    if (animations[i].chart === chart) {
-                        animations[i] = animation;
-                        return;
-                    }
-                }
-
-                animations.push(animation);
-
-                // If there are no animations queued, manually kickstart a digest, for lack of a better word
-                if (animations.length === 1) {
-                    this.requestAnimationFrame();
-                }
-            },
-
-            cancelAnimation: function(chart) {
-                var index = helpers.findIndex(this.animations, function(animation) {
-                    return animation.chart === chart;
-                });
-
-                if (index !== -1) {
-                    this.animations.splice(index, 1);
-                    chart.animating = false;
-                }
-            },
-
-            requestAnimationFrame: function() {
-                var me = this;
-                if (me.request === null) {
-                    // Skip animation frame requests until the active one is executed.
-                    // This can happen when processing mouse events, e.g. 'mousemove'
-                    // and 'mouseout' events will trigger multiple renders.
-                    me.request = helpers.requestAnimFrame.call(window, function() {
-                        me.request = null;
-                        me.startDigest();
-                    });
-                }
-            },
-
-            /**
-             * @private
-             */
-            startDigest: function() {
-                var me = this;
-                var startTime = Date.now();
-                var framesToDrop = 0;
-
-                if (me.dropFrames > 1) {
-                    framesToDrop = Math.floor(me.dropFrames);
-                    me.dropFrames = me.dropFrames % 1;
-                }
-
-                me.advance(1 + framesToDrop);
-
-                var endTime = Date.now();
-
-                me.dropFrames += (endTime - startTime) / me.frameDuration;
-
-                // Do we have more stuff to animate?
-                if (me.animations.length > 0) {
-                    me.requestAnimationFrame();
-                }
-            },
-
-            /**
-             * @private
-             */
-            advance: function(count) {
-                var animations = this.animations;
-                var animation, chart;
-                var i = 0;
-
-                while (i < animations.length) {
-                    animation = animations[i];
-                    chart = animation.chart;
-
-                    animation.currentStep = (animation.currentStep || 0) + count;
-                    animation.currentStep = Math.min(animation.currentStep, animation.numSteps);
-
-                    helpers.callback(animation.render, [chart, animation], chart);
-                    helpers.callback(animation.onAnimationProgress, [animation], chart);
-
-                    if (animation.currentStep >= animation.numSteps) {
-                        helpers.callback(animation.onAnimationComplete, [animation], chart);
-                        chart.animating = false;
-                        animations.splice(i, 1);
-                    } else {
-                        ++i;
-                    }
-                }
-            }
-        };
-
-        /**
-         * Provided for backward compatibility, use Chart.Animation instead
-         * @prop Chart.Animation#animationObject
-         * @deprecated since version 2.6.0
-         * @todo remove at version 3
-         */
-        Object.defineProperty(Chart.Animation.prototype, 'animationObject', {
-            get: function() {
-                return this;
-            }
-        });
-
-        /**
-         * Provided for backward compatibility, use Chart.Animation#chart instead
-         * @prop Chart.Animation#chartInstance
-         * @deprecated since version 2.6.0
-         * @todo remove at version 3
-         */
-        Object.defineProperty(Chart.Animation.prototype, 'chartInstance', {
-            get: function() {
-                return this.chart;
-            },
-            set: function(value) {
-                this.chart = value;
-            }
-        });
-
-    };
-
-},{}],22:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-        // Global Chart canvas helpers object for drawing items to canvas
-        var helpers = Chart.canvasHelpers = {};
-
-        helpers.drawPoint = function(ctx, pointStyle, radius, x, y) {
-            var type, edgeLength, xOffset, yOffset, height, size;
-
-            if (typeof pointStyle === 'object') {
-                type = pointStyle.toString();
-                if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
-                    ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2, pointStyle.width, pointStyle.height);
-                    return;
-                }
-            }
-
-            if (isNaN(radius) || radius <= 0) {
-                return;
-            }
-
-            switch (pointStyle) {
-                // Default includes circle
-                default:
-                    ctx.beginPath();
-                    ctx.arc(x, y, radius, 0, Math.PI * 2);
-                    ctx.closePath();
-                    ctx.fill();
-                    break;
-                case 'triangle':
-                    ctx.beginPath();
-                    edgeLength = 3 * radius / Math.sqrt(3);
-                    height = edgeLength * Math.sqrt(3) / 2;
-                    ctx.moveTo(x - edgeLength / 2, y + height / 3);
-                    ctx.lineTo(x + edgeLength / 2, y + height / 3);
-                    ctx.lineTo(x, y - 2 * height / 3);
-                    ctx.closePath();
-                    ctx.fill();
-                    break;
-                case 'rect':
-                    size = 1 / Math.SQRT2 * radius;
-                    ctx.beginPath();
-                    ctx.fillRect(x - size, y - size, 2 * size, 2 * size);
-                    ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
-                    break;
-                case 'rectRounded':
-                    var offset = radius / Math.SQRT2;
-                    var leftX = x - offset;
-                    var topY = y - offset;
-                    var sideSize = Math.SQRT2 * radius;
-                    Chart.helpers.drawRoundedRectangle(ctx, leftX, topY, sideSize, sideSize, radius / 2);
-                    ctx.fill();
-                    break;
-                case 'rectRot':
-                    size = 1 / Math.SQRT2 * radius;
-                    ctx.beginPath();
-                    ctx.moveTo(x - size, y);
-                    ctx.lineTo(x, y + size);
-                    ctx.lineTo(x + size, y);
-                    ctx.lineTo(x, y - size);
-                    ctx.closePath();
-                    ctx.fill();
-                    break;
-                case 'cross':
-                    ctx.beginPath();
-                    ctx.moveTo(x, y + radius);
-                    ctx.lineTo(x, y - radius);
-                    ctx.moveTo(x - radius, y);
-                    ctx.lineTo(x + radius, y);
-                    ctx.closePath();
-                    break;
-                case 'crossRot':
-                    ctx.beginPath();
-                    xOffset = Math.cos(Math.PI / 4) * radius;
-                    yOffset = Math.sin(Math.PI / 4) * radius;
-                    ctx.moveTo(x - xOffset, y - yOffset);
-                    ctx.lineTo(x + xOffset, y + yOffset);
-                    ctx.moveTo(x - xOffset, y + yOffset);
-                    ctx.lineTo(x + xOffset, y - yOffset);
-                    ctx.closePath();
-                    break;
-                case 'star':
-                    ctx.beginPath();
-                    ctx.moveTo(x, y + radius);
-                    ctx.lineTo(x, y - radius);
-                    ctx.moveTo(x - radius, y);
-                    ctx.lineTo(x + radius, y);
-                    xOffset = Math.cos(Math.PI / 4) * radius;
-                    yOffset = Math.sin(Math.PI / 4) * radius;
-                    ctx.moveTo(x - xOffset, y - yOffset);
-                    ctx.lineTo(x + xOffset, y + yOffset);
-                    ctx.moveTo(x - xOffset, y + yOffset);
-                    ctx.lineTo(x + xOffset, y - yOffset);
-                    ctx.closePath();
-                    break;
-                case 'line':
-                    ctx.beginPath();
-                    ctx.moveTo(x - radius, y);
-                    ctx.lineTo(x + radius, y);
-                    ctx.closePath();
-                    break;
-                case 'dash':
-                    ctx.beginPath();
-                    ctx.moveTo(x, y);
-                    ctx.lineTo(x + radius, y);
-                    ctx.closePath();
-                    break;
-            }
-
-            ctx.stroke();
-        };
-
-        helpers.clipArea = function(ctx, clipArea) {
-            ctx.save();
-            ctx.beginPath();
-            ctx.rect(clipArea.left, clipArea.top, clipArea.right - clipArea.left, clipArea.bottom - clipArea.top);
-            ctx.clip();
-        };
-
-        helpers.unclipArea = function(ctx) {
-            ctx.restore();
-        };
-
-        helpers.lineTo = function(ctx, previous, target, flip) {
-            if (target.steppedLine) {
-                if (target.steppedLine === 'after') {
-                    ctx.lineTo(previous.x, target.y);
-                } else {
-                    ctx.lineTo(target.x, previous.y);
-                }
-                ctx.lineTo(target.x, target.y);
-                return;
-            }
-
-            if (!target.tension) {
-                ctx.lineTo(target.x, target.y);
-                return;
-            }
-
-            ctx.bezierCurveTo(
-                flip? previous.controlPointPreviousX : previous.controlPointNextX,
-                flip? previous.controlPointPreviousY : previous.controlPointNextY,
-                flip? target.controlPointNextX : target.controlPointPreviousX,
-                flip? target.controlPointNextY : target.controlPointPreviousY,
-                target.x,
-                target.y);
-        };
-
-        Chart.helpers.canvas = helpers;
-    };
-
-},{}],23:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-        var plugins = Chart.plugins;
-        var platform = Chart.platform;
-
-        // Create a dictionary of chart types, to allow for extension of existing types
-        Chart.types = {};
-
-        // Store a reference to each instance - allowing us to globally resize chart instances on window resize.
-        // Destroy method on the chart will remove the instance of the chart from this reference.
-        Chart.instances = {};
-
-        // Controllers available for dataset visualization eg. bar, line, slice, etc.
-        Chart.controllers = {};
-
-        /**
-         * Initializes the given config with global and chart default values.
-         */
-        function initConfig(config) {
-            config = config || {};
-
-            // Do NOT use configMerge() for the data object because this method merges arrays
-            // and so would change references to labels and datasets, preventing data updates.
-            var data = config.data = config.data || {};
-            data.datasets = data.datasets || [];
-            data.labels = data.labels || [];
-
-            config.options = helpers.configMerge(
-                Chart.defaults.global,
-                Chart.defaults[config.type],
-                config.options || {});
-
-            return config;
-        }
-
-        /**
-         * Updates the config of the chart
-         * @param chart {Chart} chart to update the options for
-         */
-        function updateConfig(chart) {
-            var newOptions = chart.options;
-
-            // Update Scale(s) with options
-            if (newOptions.scale) {
-                chart.scale.options = newOptions.scale;
-            } else if (newOptions.scales) {
-                newOptions.scales.xAxes.concat(newOptions.scales.yAxes).forEach(function(scaleOptions) {
-                    chart.scales[scaleOptions.id].options = scaleOptions;
-                });
-            }
-
-            // Tooltip
-            chart.tooltip._options = newOptions.tooltips;
-        }
-
-        function positionIsHorizontal(position) {
-            return position === 'top' || position === 'bottom';
-        }
-
-        helpers.extend(Chart.prototype, /** @lends Chart */ {
-            /**
-             * @private
-             */
-            construct: function(item, config) {
-                var me = this;
-
-                config = initConfig(config);
-
-                var context = platform.acquireContext(item, config);
-                var canvas = context && context.canvas;
-                var height = canvas && canvas.height;
-                var width = canvas && canvas.width;
-
-                me.id = helpers.uid();
-                me.ctx = context;
-                me.canvas = canvas;
-                me.config = config;
-                me.width = width;
-                me.height = height;
-                me.aspectRatio = height? width / height : null;
-                me.options = config.options;
-                me._bufferedRender = false;
-
-                /**
-                 * Provided for backward compatibility, Chart and Chart.Controller have been merged,
-                 * the "instance" still need to be defined since it might be called from plugins.
-                 * @prop Chart#chart
-                 * @deprecated since version 2.6.0
-                 * @todo remove at version 3
-                 * @private
-                 */
-                me.chart = me;
-                me.controller = me;  // chart.chart.controller #inception
-
-                // Add the chart instance to the global namespace
-                Chart.instances[me.id] = me;
-
-                // Define alias to the config data: `chart.data === chart.config.data`
-                Object.defineProperty(me, 'data', {
-                    get: function() {
-                        return me.config.data;
-                    },
-                    set: function(value) {
-                        me.config.data = value;
-                    }
-                });
-
-                if (!context || !canvas) {
-                    // The given item is not a compatible context2d element, let's return before finalizing
-                    // the chart initialization but after setting basic chart / controller properties that
-                    // can help to figure out that the chart is not valid (e.g chart.canvas !== null);
-                    // https://github.com/chartjs/Chart.js/issues/2807
-                    console.error("Failed to create chart: can't acquire context from the given item");
-                    return;
-                }
-
-                me.initialize();
-                me.update();
-            },
-
-            /**
-             * @private
-             */
-            initialize: function() {
-                var me = this;
-
-                // Before init plugin notification
-                plugins.notify(me, 'beforeInit');
-
-                helpers.retinaScale(me);
-
-                me.bindEvents();
-
-                if (me.options.responsive) {
-                    // Initial resize before chart draws (must be silent to preserve initial animations).
-                    me.resize(true);
-                }
-
-                // Make sure scales have IDs and are built before we build any controllers.
-                me.ensureScalesHaveIDs();
-                me.buildScales();
-                me.initToolTip();
-
-                // After init plugin notification
-                plugins.notify(me, 'afterInit');
-
-                return me;
-            },
-
-            clear: function() {
-                helpers.clear(this);
-                return this;
-            },
-
-            stop: function() {
-                // Stops any current animation loop occurring
-                Chart.animationService.cancelAnimation(this);
-                return this;
-            },
-
-            resize: function(silent) {
-                var me = this;
-                var options = me.options;
-                var canvas = me.canvas;
-                var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
-
-                // the canvas render width and height will be casted to integers so make sure that
-                // the canvas display style uses the same integer values to avoid blurring effect.
-                var newWidth = Math.floor(helpers.getMaximumWidth(canvas));
-                var newHeight = Math.floor(aspectRatio? newWidth / aspectRatio : helpers.getMaximumHeight(canvas));
-
-                if (me.width === newWidth && me.height === newHeight) {
-                    return;
-                }
-
-                canvas.width = me.width = newWidth;
-                canvas.height = me.height = newHeight;
-                canvas.style.width = newWidth + 'px';
-                canvas.style.height = newHeight + 'px';
-
-                helpers.retinaScale(me);
-
-                if (!silent) {
-                    // Notify any plugins about the resize
-                    var newSize = {width: newWidth, height: newHeight};
-                    plugins.notify(me, 'resize', [newSize]);
-
-                    // Notify of resize
-                    if (me.options.onResize) {
-                        me.options.onResize(me, newSize);
-                    }
-
-                    me.stop();
-                    me.update(me.options.responsiveAnimationDuration);
-                }
-            },
-
-            ensureScalesHaveIDs: function() {
-                var options = this.options;
-                var scalesOptions = options.scales || {};
-                var scaleOptions = options.scale;
-
-                helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
-                    xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
-                });
-
-                helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
-                    yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
-                });
-
-                if (scaleOptions) {
-                    scaleOptions.id = scaleOptions.id || 'scale';
-                }
-            },
-
-            /**
-             * Builds a map of scale ID to scale object for future lookup.
-             */
-            buildScales: function() {
-                var me = this;
-                var options = me.options;
-                var scales = me.scales = {};
-                var items = [];
-
-                if (options.scales) {
-                    items = items.concat(
-                        (options.scales.xAxes || []).map(function(xAxisOptions) {
-                            return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};
-                        }),
-                        (options.scales.yAxes || []).map(function(yAxisOptions) {
-                            return {options: yAxisOptions, dtype: 'linear', dposition: 'left'};
-                        })
-                    );
-                }
-
-                if (options.scale) {
-                    items.push({
-                        options: options.scale,
-                        dtype: 'radialLinear',
-                        isDefault: true,
-                        dposition: 'chartArea'
-                    });
-                }
-
-                helpers.each(items, function(item) {
-                    var scaleOptions = item.options;
-                    var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);
-                    var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
-                    if (!scaleClass) {
-                        return;
-                    }
-
-                    if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
-                        scaleOptions.position = item.dposition;
-                    }
-
-                    var scale = new scaleClass({
-                        id: scaleOptions.id,
-                        options: scaleOptions,
-                        ctx: me.ctx,
-                        chart: me
-                    });
-
-                    scales[scale.id] = scale;
-
-                    // TODO(SB): I think we should be able to remove this custom case (options.scale)
-                    // and consider it as a regular scale part of the "scales"" map only! This would
-                    // make the logic easier and remove some useless? custom code.
-                    if (item.isDefault) {
-                        me.scale = scale;
-                    }
-                });
-
-                Chart.scaleService.addScalesToLayout(this);
-            },
-
-            buildOrUpdateControllers: function() {
-                var me = this;
-                var types = [];
-                var newControllers = [];
-
-                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-                    var meta = me.getDatasetMeta(datasetIndex);
-                    if (!meta.type) {
-                        meta.type = dataset.type || me.config.type;
-                    }
-
-                    types.push(meta.type);
-
-                    if (meta.controller) {
-                        meta.controller.updateIndex(datasetIndex);
-                    } else {
-                        var ControllerClass = Chart.controllers[meta.type];
-                        if (ControllerClass === undefined) {
-                            throw new Error('"' + meta.type + '" is not a chart type.');
-                        }
-
-                        meta.controller = new ControllerClass(me, datasetIndex);
-                        newControllers.push(meta.controller);
-                    }
-                }, me);
-
-                if (types.length > 1) {
-                    for (var i = 1; i < types.length; i++) {
-                        if (types[i] !== types[i - 1]) {
-                            me.isCombo = true;
-                            break;
-                        }
-                    }
-                }
-
-                return newControllers;
-            },
-
-            /**
-             * Reset the elements of all datasets
-             * @private
-             */
-            resetElements: function() {
-                var me = this;
-                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-                    me.getDatasetMeta(datasetIndex).controller.reset();
-                }, me);
-            },
-
-            /**
-             * Resets the chart back to it's state before the initial animation
-             */
-            reset: function() {
-                this.resetElements();
-                this.tooltip.initialize();
-            },
-
-            update: function(animationDuration, lazy) {
-                var me = this;
-
-                updateConfig(me);
-
-                if (plugins.notify(me, 'beforeUpdate') === false) {
-                    return;
-                }
-
-                // In case the entire data object changed
-                me.tooltip._data = me.data;
-
-                // Make sure dataset controllers are updated and new controllers are reset
-                var newControllers = me.buildOrUpdateControllers();
-
-                // Make sure all dataset controllers have correct meta data counts
-                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-                    me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
-                }, me);
-
-                me.updateLayout();
-
-                // Can only reset the new controllers after the scales have been updated
-                helpers.each(newControllers, function(controller) {
-                    controller.reset();
-                });
-
-                me.updateDatasets();
-
-                // Do this before render so that any plugins that need final scale updates can use it
-                plugins.notify(me, 'afterUpdate');
-
-                if (me._bufferedRender) {
-                    me._bufferedRequest = {
-                        lazy: lazy,
-                        duration: animationDuration
-                    };
-                } else {
-                    me.render(animationDuration, lazy);
-                }
-            },
-
-            /**
-             * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`
-             * hook, in which case, plugins will not be called on `afterLayout`.
-             * @private
-             */
-            updateLayout: function() {
-                var me = this;
-
-                if (plugins.notify(me, 'beforeLayout') === false) {
-                    return;
-                }
-
-                Chart.layoutService.update(this, this.width, this.height);
-
-                /**
-                 * Provided for backward compatibility, use `afterLayout` instead.
-                 * @method IPlugin#afterScaleUpdate
-                 * @deprecated since version 2.5.0
-                 * @todo remove at version 3
-                 * @private
-                 */
-                plugins.notify(me, 'afterScaleUpdate');
-                plugins.notify(me, 'afterLayout');
-            },
-
-            /**
-             * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`
-             * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.
-             * @private
-             */
-            updateDatasets: function() {
-                var me = this;
-
-                if (plugins.notify(me, 'beforeDatasetsUpdate') === false) {
-                    return;
-                }
-
-                for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
-                    me.updateDataset(i);
-                }
-
-                plugins.notify(me, 'afterDatasetsUpdate');
-            },
-
-            /**
-             * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`
-             * hook, in which case, plugins will not be called on `afterDatasetUpdate`.
-             * @private
-             */
-            updateDataset: function(index) {
-                var me = this;
-                var meta = me.getDatasetMeta(index);
-                var args = {
-                    meta: meta,
-                    index: index
-                };
-
-                if (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {
-                    return;
-                }
-
-                meta.controller.update();
-
-                plugins.notify(me, 'afterDatasetUpdate', [args]);
-            },
-
-            render: function(duration, lazy) {
-                var me = this;
-
-                if (plugins.notify(me, 'beforeRender') === false) {
-                    return;
-                }
-
-                var animationOptions = me.options.animation;
-                var onComplete = function(animation) {
-                    plugins.notify(me, 'afterRender');
-                    helpers.callback(animationOptions && animationOptions.onComplete, [animation], me);
-                };
-
-                if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {
-                    var animation = new Chart.Animation({
-                        numSteps: (duration || animationOptions.duration) / 16.66, // 60 fps
-                        easing: animationOptions.easing,
-
-                        render: function(chart, animationObject) {
-                            var easingFunction = helpers.easingEffects[animationObject.easing];
-                            var currentStep = animationObject.currentStep;
-                            var stepDecimal = currentStep / animationObject.numSteps;
-
-                            chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);
-                        },
-
-                        onAnimationProgress: animationOptions.onProgress,
-                        onAnimationComplete: onComplete
-                    });
-
-                    Chart.animationService.addAnimation(me, animation, duration, lazy);
-                } else {
-                    me.draw();
-
-                    // See https://github.com/chartjs/Chart.js/issues/3781
-                    onComplete(new Chart.Animation({numSteps: 0, chart: me}));
-                }
-
-                return me;
-            },
-
-            draw: function(easingValue) {
-                var me = this;
-
-                me.clear();
-
-                if (easingValue === undefined || easingValue === null) {
-                    easingValue = 1;
-                }
-
-                me.transition(easingValue);
-
-                if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {
-                    return;
-                }
-
-                // Draw all the scales
-                helpers.each(me.boxes, function(box) {
-                    box.draw(me.chartArea);
-                }, me);
-
-                if (me.scale) {
-                    me.scale.draw();
-                }
-
-                me.drawDatasets(easingValue);
-
-                // Finally draw the tooltip
-                me.tooltip.draw();
-
-                plugins.notify(me, 'afterDraw', [easingValue]);
-            },
-
-            /**
-             * @private
-             */
-            transition: function(easingValue) {
-                var me = this;
-
-                for (var i=0, ilen=(me.data.datasets || []).length; i<ilen; ++i) {
-                    if (me.isDatasetVisible(i)) {
-                        me.getDatasetMeta(i).controller.transition(easingValue);
-                    }
-                }
-
-                me.tooltip.transition(easingValue);
-            },
-
-            /**
-             * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`
-             * hook, in which case, plugins will not be called on `afterDatasetsDraw`.
-             * @private
-             */
-            drawDatasets: function(easingValue) {
-                var me = this;
-
-                if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
-                    return;
-                }
-
-                // Draw datasets reversed to support proper line stacking
-                for (var i=(me.data.datasets || []).length - 1; i >= 0; --i) {
-                    if (me.isDatasetVisible(i)) {
-                        me.drawDataset(i, easingValue);
-                    }
-                }
-
-                plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
-            },
-
-            /**
-             * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`
-             * hook, in which case, plugins will not be called on `afterDatasetDraw`.
-             * @private
-             */
-            drawDataset: function(index, easingValue) {
-                var me = this;
-                var meta = me.getDatasetMeta(index);
-                var args = {
-                    meta: meta,
-                    index: index,
-                    easingValue: easingValue
-                };
-
-                if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {
-                    return;
-                }
-
-                meta.controller.draw(easingValue);
-
-                plugins.notify(me, 'afterDatasetDraw', [args]);
-            },
-
-            // Get the single element that was clicked on
-            // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
-            getElementAtEvent: function(e) {
-                return Chart.Interaction.modes.single(this, e);
-            },
-
-            getElementsAtEvent: function(e) {
-                return Chart.Interaction.modes.label(this, e, {intersect: true});
-            },
-
-            getElementsAtXAxis: function(e) {
-                return Chart.Interaction.modes['x-axis'](this, e, {intersect: true});
-            },
-
-            getElementsAtEventForMode: function(e, mode, options) {
-                var method = Chart.Interaction.modes[mode];
-                if (typeof method === 'function') {
-                    return method(this, e, options);
-                }
-
-                return [];
-            },
-
-            getDatasetAtEvent: function(e) {
-                return Chart.Interaction.modes.dataset(this, e, {intersect: true});
-            },
-
-            getDatasetMeta: function(datasetIndex) {
-                var me = this;
-                var dataset = me.data.datasets[datasetIndex];
-                if (!dataset._meta) {
-                    dataset._meta = {};
-                }
-
-                var meta = dataset._meta[me.id];
-                if (!meta) {
-                    meta = dataset._meta[me.id] = {
-                        type: null,
-                        data: [],
-                        dataset: null,
-                        controller: null,
-                        hidden: null,			// See isDatasetVisible() comment
-                        xAxisID: null,
-                        yAxisID: null
-                    };
-                }
-
-                return meta;
-            },
-
-            getVisibleDatasetCount: function() {
-                var count = 0;
-                for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {
-                    if (this.isDatasetVisible(i)) {
-                        count++;
-                    }
-                }
-                return count;
-            },
-
-            isDatasetVisible: function(datasetIndex) {
-                var meta = this.getDatasetMeta(datasetIndex);
-
-                // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,
-                // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.
-                return typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
-            },
-
-            generateLegend: function() {
-                return this.options.legendCallback(this);
-            },
-
-            destroy: function() {
-                var me = this;
-                var canvas = me.canvas;
-                var meta, i, ilen;
-
-                me.stop();
-
-                // dataset controllers need to cleanup associated data
-                for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
-                    meta = me.getDatasetMeta(i);
-                    if (meta.controller) {
-                        meta.controller.destroy();
-                        meta.controller = null;
-                    }
-                }
-
-                if (canvas) {
-                    me.unbindEvents();
-                    helpers.clear(me);
-                    platform.releaseContext(me.ctx);
-                    me.canvas = null;
-                    me.ctx = null;
-                }
-
-                plugins.notify(me, 'destroy');
-
-                delete Chart.instances[me.id];
-            },
-
-            toBase64Image: function() {
-                return this.canvas.toDataURL.apply(this.canvas, arguments);
-            },
-
-            initToolTip: function() {
-                var me = this;
-                me.tooltip = new Chart.Tooltip({
-                    _chart: me,
-                    _chartInstance: me,            // deprecated, backward compatibility
-                    _data: me.data,
-                    _options: me.options.tooltips
-                }, me);
-                me.tooltip.initialize();
-            },
-
-            /**
-             * @private
-             */
-            bindEvents: function() {
-                var me = this;
-                var listeners = me._listeners = {};
-                var listener = function() {
-                    me.eventHandler.apply(me, arguments);
-                };
-
-                helpers.each(me.options.events, function(type) {
-                    platform.addEventListener(me, type, listener);
-                    listeners[type] = listener;
-                });
-
-                // Responsiveness is currently based on the use of an iframe, however this method causes
-                // performance issues and could be troublesome when used with ad blockers. So make sure
-                // that the user is still able to create a chart without iframe when responsive is false.
-                // See https://github.com/chartjs/Chart.js/issues/2210
-                if (me.options.responsive) {
-                    listener = function() {
-                        me.resize();
-                    };
-
-                    platform.addEventListener(me, 'resize', listener);
-                    listeners.resize = listener;
-                }
-            },
-
-            /**
-             * @private
-             */
-            unbindEvents: function() {
-                var me = this;
-                var listeners = me._listeners;
-                if (!listeners) {
-                    return;
-                }
-
-                delete me._listeners;
-                helpers.each(listeners, function(listener, type) {
-                    platform.removeEventListener(me, type, listener);
-                });
-            },
-
-            updateHoverStyle: function(elements, mode, enabled) {
-                var method = enabled? 'setHoverStyle' : 'removeHoverStyle';
-                var element, i, ilen;
-
-                for (i=0, ilen=elements.length; i<ilen; ++i) {
-                    element = elements[i];
-                    if (element) {
-                        this.getDatasetMeta(element._datasetIndex).controller[method](element);
-                    }
-                }
-            },
-
-            /**
-             * @private
-             */
-            eventHandler: function(e) {
-                var me = this;
-                var tooltip = me.tooltip;
-
-                if (plugins.notify(me, 'beforeEvent', [e]) === false) {
-                    return;
-                }
-
-                // Buffer any update calls so that renders do not occur
-                me._bufferedRender = true;
-                me._bufferedRequest = null;
-
-                var changed = me.handleEvent(e);
-                changed |= tooltip && tooltip.handleEvent(e);
-
-                plugins.notify(me, 'afterEvent', [e]);
-
-                var bufferedRequest = me._bufferedRequest;
-                if (bufferedRequest) {
-                    // If we have an update that was triggered, we need to do a normal render
-                    me.render(bufferedRequest.duration, bufferedRequest.lazy);
-                } else if (changed && !me.animating) {
-                    // If entering, leaving, or changing elements, animate the change via pivot
-                    me.stop();
-
-                    // We only need to render at this point. Updating will cause scales to be
-                    // recomputed generating flicker & using more memory than necessary.
-                    me.render(me.options.hover.animationDuration, true);
-                }
-
-                me._bufferedRender = false;
-                me._bufferedRequest = null;
-
-                return me;
-            },
-
-            /**
-             * Handle an event
-             * @private
-             * @param {IEvent} event the event to handle
-             * @return {Boolean} true if the chart needs to re-render
-             */
-            handleEvent: function(e) {
-                var me = this;
-                var options = me.options || {};
-                var hoverOptions = options.hover;
-                var changed = false;
-
-                me.lastActive = me.lastActive || [];
-
-                // Find Active Elements for hover and tooltips
-                if (e.type === 'mouseout') {
-                    me.active = [];
-                } else {
-                    me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
-                }
-
-                // On Hover hook
-                if (hoverOptions.onHover) {
-                    // Need to call with native event here to not break backwards compatibility
-                    hoverOptions.onHover.call(me, e.native, me.active);
-                }
-
-                if (e.type === 'mouseup' || e.type === 'click') {
-                    if (options.onClick) {
-                        // Use e.native here for backwards compatibility
-                        options.onClick.call(me, e.native, me.active);
-                    }
-                }
-
-                // Remove styling for last active (even if it may still be active)
-                if (me.lastActive.length) {
-                    me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
-                }
-
-                // Built in hover styling
-                if (me.active.length && hoverOptions.mode) {
-                    me.updateHoverStyle(me.active, hoverOptions.mode, true);
-                }
-
-                changed = !helpers.arrayEquals(me.active, me.lastActive);
-
-                // Remember Last Actives
-                me.lastActive = me.active;
-
-                return changed;
-            }
-        });
-
-        /**
-         * Provided for backward compatibility, use Chart instead.
-         * @class Chart.Controller
-         * @deprecated since version 2.6.0
-         * @todo remove at version 3
-         * @private
-         */
-        Chart.Controller = Chart;
-    };
-
-},{}],24:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
-
-        /**
-         * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
-         * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
-         * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
-         */
-        function listenArrayEvents(array, listener) {
-            if (array._chartjs) {
-                array._chartjs.listeners.push(listener);
-                return;
-            }
-
-            Object.defineProperty(array, '_chartjs', {
-                configurable: true,
-                enumerable: false,
-                value: {
-                    listeners: [listener]
-                }
-            });
-
-            arrayEvents.forEach(function(key) {
-                var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
-                var base = array[key];
-
-                Object.defineProperty(array, key, {
-                    configurable: true,
-                    enumerable: false,
-                    value: function() {
-                        var args = Array.prototype.slice.call(arguments);
-                        var res = base.apply(this, args);
-
-                        helpers.each(array._chartjs.listeners, function(object) {
-                            if (typeof object[method] === 'function') {
-                                object[method].apply(object, args);
-                            }
-                        });
-
-                        return res;
-                    }
-                });
-            });
-        }
-
-        /**
-         * Removes the given array event listener and cleanup extra attached properties (such as
-         * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
-         */
-        function unlistenArrayEvents(array, listener) {
-            var stub = array._chartjs;
-            if (!stub) {
-                return;
-            }
-
-            var listeners = stub.listeners;
-            var index = listeners.indexOf(listener);
-            if (index !== -1) {
-                listeners.splice(index, 1);
-            }
-
-            if (listeners.length > 0) {
-                return;
-            }
-
-            arrayEvents.forEach(function(key) {
-                delete array[key];
-            });
-
-            delete array._chartjs;
-        }
-
-        // Base class for all dataset controllers (line, bar, etc)
-        Chart.DatasetController = function(chart, datasetIndex) {
-            this.initialize(chart, datasetIndex);
-        };
-
-        helpers.extend(Chart.DatasetController.prototype, {
-
-            /**
-             * Element type used to generate a meta dataset (e.g. Chart.element.Line).
-             * @type {Chart.core.element}
-             */
-            datasetElementType: null,
-
-            /**
-             * Element type used to generate a meta data (e.g. Chart.element.Point).
-             * @type {Chart.core.element}
-             */
-            dataElementType: null,
-
-            initialize: function(chart, datasetIndex) {
-                var me = this;
-                me.chart = chart;
-                me.index = datasetIndex;
-                me.linkScales();
-                me.addElements();
-            },
-
-            updateIndex: function(datasetIndex) {
-                this.index = datasetIndex;
-            },
-
-            linkScales: function() {
-                var me = this;
-                var meta = me.getMeta();
-                var dataset = me.getDataset();
-
-                if (meta.xAxisID === null) {
-                    meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
-                }
-                if (meta.yAxisID === null) {
-                    meta.yAxisID = dataset.yAxisID || me.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(scaleID) {
-                return this.chart.scales[scaleID];
-            },
-
-            reset: function() {
-                this.update(true);
-            },
-
-            /**
-             * @private
-             */
-            destroy: function() {
-                if (this._data) {
-                    unlistenArrayEvents(this._data, this);
-                }
-            },
-
-            createMetaDataset: function() {
-                var me = this;
-                var type = me.datasetElementType;
-                return type && new type({
-                        _chart: me.chart,
-                        _datasetIndex: me.index
-                    });
-            },
-
-            createMetaData: function(index) {
-                var me = this;
-                var type = me.dataElementType;
-                return type && new type({
-                        _chart: me.chart,
-                        _datasetIndex: me.index,
-                        _index: index
-                    });
-            },
-
-            addElements: function() {
-                var me = this;
-                var meta = me.getMeta();
-                var data = me.getDataset().data || [];
-                var metaData = meta.data;
-                var i, ilen;
-
-                for (i=0, ilen=data.length; i<ilen; ++i) {
-                    metaData[i] = metaData[i] || me.createMetaData(i);
-                }
-
-                meta.dataset = meta.dataset || me.createMetaDataset();
-            },
-
-            addElementAndReset: function(index) {
-                var element = this.createMetaData(index);
-                this.getMeta().data.splice(index, 0, element);
-                this.updateElement(element, index, true);
-            },
-
-            buildOrUpdateElements: function() {
-                var me = this;
-                var dataset = me.getDataset();
-                var data = dataset.data || (dataset.data = []);
-
-                // In order to correctly handle data addition/deletion animation (an thus simulate
-                // real-time charts), we need to monitor these data modifications and synchronize
-                // the internal meta data accordingly.
-                if (me._data !== data) {
-                    if (me._data) {
-                        // This case happens when the user replaced the data array instance.
-                        unlistenArrayEvents(me._data, me);
-                    }
-
-                    listenArrayEvents(data, me);
-                    me._data = data;
-                }
-
-                // Re-sync meta data in case the user replaced the data array or if we missed
-                // any updates and so make sure that we handle number of datapoints changing.
-                me.resyncElements();
-            },
-
-            update: helpers.noop,
-
-            transition: function(easingValue) {
-                var meta = this.getMeta();
-                var elements = meta.data || [];
-                var ilen = elements.length;
-                var i = 0;
-
-                for (; i<ilen; ++i) {
-                    elements[i].transition(easingValue);
-                }
-
-                if (meta.dataset) {
-                    meta.dataset.transition(easingValue);
-                }
-            },
-
-            draw: function() {
-                var meta = this.getMeta();
-                var elements = meta.data || [];
-                var ilen = elements.length;
-                var i = 0;
-
-                if (meta.dataset) {
-                    meta.dataset.draw();
-                }
-
-                for (; i<ilen; ++i) {
-                    elements[i].draw();
-                }
-            },
-
-            removeHoverStyle: function(element, elementOpts) {
-                var dataset = this.chart.data.datasets[element._datasetIndex],
-                    index = element._index,
-                    custom = element.custom || {},
-                    valueOrDefault = helpers.getValueAtIndexOrDefault,
-                    model = element._model;
-
-                model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
-                model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
-                model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
-            },
-
-            setHoverStyle: function(element) {
-                var dataset = this.chart.data.datasets[element._datasetIndex],
-                    index = element._index,
-                    custom = element.custom || {},
-                    valueOrDefault = helpers.getValueAtIndexOrDefault,
-                    getHoverColor = helpers.getHoverColor,
-                    model = element._model;
-
-                model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
-                model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
-                model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
-            },
-
-            /**
-             * @private
-             */
-            resyncElements: function() {
-                var me = this;
-                var meta = me.getMeta();
-                var data = me.getDataset().data;
-                var numMeta = meta.data.length;
-                var numData = data.length;
-
-                if (numData < numMeta) {
-                    meta.data.splice(numData, numMeta - numData);
-                } else if (numData > numMeta) {
-                    me.insertElements(numMeta, numData - numMeta);
-                }
-            },
-
-            /**
-             * @private
-             */
-            insertElements: function(start, count) {
-                for (var i=0; i<count; ++i) {
-                    this.addElementAndReset(start + i);
-                }
-            },
-
-            /**
-             * @private
-             */
-            onDataPush: function() {
-                this.insertElements(this.getDataset().data.length-1, arguments.length);
-            },
-
-            /**
-             * @private
-             */
-            onDataPop: function() {
-                this.getMeta().data.pop();
-            },
-
-            /**
-             * @private
-             */
-            onDataShift: function() {
-                this.getMeta().data.shift();
-            },
-
-            /**
-             * @private
-             */
-            onDataSplice: function(start, count) {
-                this.getMeta().data.splice(start, count);
-                this.insertElements(start, arguments.length - 2);
-            },
-
-            /**
-             * @private
-             */
-            onDataUnshift: function() {
-                this.insertElements(0, arguments.length);
-            }
-        });
-
-        Chart.DatasetController.extend = helpers.inherits;
-    };
-
-},{}],25:[function(require,module,exports){
-    'use strict';
-
-    var color = require(3);
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        function interpolate(start, view, model, ease) {
-            var keys = Object.keys(model);
-            var i, ilen, key, actual, origin, target, type, c0, c1;
-
-            for (i=0, ilen=keys.length; i<ilen; ++i) {
-                key = keys[i];
-
-                target = model[key];
-
-                // if a value is added to the model after pivot() has been called, the view
-                // doesn't contain it, so let's initialize the view to the target value.
-                if (!view.hasOwnProperty(key)) {
-                    view[key] = target;
-                }
-
-                actual = view[key];
-
-                if (actual === target || key[0] === '_') {
-                    continue;
-                }
-
-                if (!start.hasOwnProperty(key)) {
-                    start[key] = actual;
-                }
-
-                origin = start[key];
-
-                type = typeof(target);
-
-                if (type === typeof(origin)) {
-                    if (type === 'string') {
-                        c0 = color(origin);
-                        if (c0.valid) {
-                            c1 = color(target);
-                            if (c1.valid) {
-                                view[key] = c1.mix(c0, ease).rgbString();
-                                continue;
-                            }
-                        }
-                    } else if (type === 'number' && isFinite(origin) && isFinite(target)) {
-                        view[key] = origin + (target - origin) * ease;
-                        continue;
-                    }
-                }
-
-                view[key] = target;
-            }
-        }
-
-        Chart.elements = {};
-
-        Chart.Element = function(configuration) {
-            helpers.extend(this, configuration);
-            this.initialize.apply(this, arguments);
-        };
-
-        helpers.extend(Chart.Element.prototype, {
-
-            initialize: function() {
-                this.hidden = false;
-            },
-
-            pivot: function() {
-                var me = this;
-                if (!me._view) {
-                    me._view = helpers.clone(me._model);
-                }
-                me._start = {};
-                return me;
-            },
-
-            transition: function(ease) {
-                var me = this;
-                var model = me._model;
-                var start = me._start;
-                var view = me._view;
-
-                // No animation -> No Transition
-                if (!model || ease === 1) {
-                    me._view = model;
-                    me._start = null;
-                    return me;
-                }
-
-                if (!view) {
-                    view = me._view = {};
-                }
-
-                if (!start) {
-                    start = me._start = {};
-                }
-
-                interpolate(start, view, model, ease);
-
-                return me;
-            },
-
-            tooltipPosition: function() {
-                return {
-                    x: this._model.x,
-                    y: this._model.y
-                };
-            },
-
-            hasValue: function() {
-                return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
-            }
-        });
-
-        Chart.Element.extend = helpers.inherits;
-    };
-
-},{"3":3}],26:[function(require,module,exports){
-    /* global window: false */
-    /* global document: false */
-    'use strict';
-
-    var color = require(3);
-
-    module.exports = function(Chart) {
-        // Global Chart helpers object for utility methods and classes
-        var helpers = Chart.helpers = {};
-
-        // -- Basic js utility methods
-        helpers.each = function(loopable, callback, self, reverse) {
-            // Check to see if null or undefined firstly.
-            var i, len;
-            if (helpers.isArray(loopable)) {
-                len = loopable.length;
-                if (reverse) {
-                    for (i = len - 1; i >= 0; i--) {
-                        callback.call(self, loopable[i], i);
-                    }
-                } else {
-                    for (i = 0; i < len; i++) {
-                        callback.call(self, loopable[i], i);
-                    }
-                }
-            } else if (typeof loopable === 'object') {
-                var keys = Object.keys(loopable);
-                len = keys.length;
-                for (i = 0; i < len; i++) {
-                    callback.call(self, loopable[keys[i]], keys[i]);
-                }
-            }
-        };
-        helpers.clone = function(obj) {
-            var objClone = {};
-            helpers.each(obj, function(value, key) {
-                if (helpers.isArray(value)) {
-                    objClone[key] = value.slice(0);
-                } else if (typeof value === 'object' && value !== null) {
-                    objClone[key] = helpers.clone(value);
-                } else {
-                    objClone[key] = value;
-                }
-            });
-            return objClone;
-        };
-        helpers.extend = function(base) {
-            var setFn = function(value, key) {
-                base[key] = value;
-            };
-            for (var i = 1, ilen = arguments.length; i < ilen; i++) {
-                helpers.each(arguments[i], setFn);
-            }
-            return base;
-        };
-        // Need a special merge function to chart configs since they are now grouped
-        helpers.configMerge = function(_base) {
-            var base = helpers.clone(_base);
-            helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {
-                helpers.each(extension, function(value, key) {
-                    var baseHasProperty = base.hasOwnProperty(key);
-                    var baseVal = baseHasProperty ? base[key] : {};
-
-                    if (key === 'scales') {
-                        // Scale config merging is complex. Add our own function here for that
-                        base[key] = helpers.scaleMerge(baseVal, value);
-                    } else if (key === 'scale') {
-                        // Used in polar area & radar charts since there is only one scale
-                        base[key] = helpers.configMerge(baseVal, Chart.scaleService.getScaleDefaults(value.type), value);
-                    } else if (baseHasProperty
-                        && typeof baseVal === 'object'
-                        && !helpers.isArray(baseVal)
-                        && baseVal !== null
-                        && typeof value === 'object'
-                        && !helpers.isArray(value)) {
-                        // If we are overwriting an object with an object, do a merge of the properties.
-                        base[key] = helpers.configMerge(baseVal, value);
-                    } else {
-                        // can just overwrite the value in this case
-                        base[key] = value;
-                    }
-                });
-            });
-
-            return base;
-        };
-        helpers.scaleMerge = function(_base, extension) {
-            var base = helpers.clone(_base);
-
-            helpers.each(extension, function(value, key) {
-                if (key === 'xAxes' || key === 'yAxes') {
-                    // These properties are arrays of items
-                    if (base.hasOwnProperty(key)) {
-                        helpers.each(value, function(valueObj, index) {
-                            var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
-                            var axisDefaults = Chart.scaleService.getScaleDefaults(axisType);
-                            if (index >= base[key].length || !base[key][index].type) {
-                                base[key].push(helpers.configMerge(axisDefaults, valueObj));
-                            } else if (valueObj.type && valueObj.type !== base[key][index].type) {
-                                // Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults
-                                base[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);
-                            } else {
-                                // Type is the same
-                                base[key][index] = helpers.configMerge(base[key][index], valueObj);
-                            }
-                        });
-                    } else {
-                        base[key] = [];
-                        helpers.each(value, function(valueObj) {
-                            var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
-                            base[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));
-                        });
-                    }
-                } else if (base.hasOwnProperty(key) && typeof base[key] === 'object' && base[key] !== null && typeof value === 'object') {
-                    // If we are overwriting an object with an object, do a merge of the properties.
-                    base[key] = helpers.configMerge(base[key], value);
-
-                } else {
-                    // can just overwrite the value in this case
-                    base[key] = value;
-                }
-            });
-
-            return base;
-        };
-        helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {
-            if (value === undefined || value === null) {
-                return defaultValue;
-            }
-
-            if (helpers.isArray(value)) {
-                return index < value.length ? value[index] : defaultValue;
-            }
-
-            return value;
-        };
-        helpers.getValueOrDefault = function(value, defaultValue) {
-            return value === undefined ? defaultValue : value;
-        };
-        helpers.indexOf = Array.prototype.indexOf?
-            function(array, item) {
-                return array.indexOf(item);
-            }:
-            function(array, item) {
-                for (var i = 0, ilen = array.length; i < ilen; ++i) {
-                    if (array[i] === item) {
-                        return i;
-                    }
-                }
-                return -1;
-            };
-        helpers.where = function(collection, filterCallback) {
-            if (helpers.isArray(collection) && Array.prototype.filter) {
-                return collection.filter(filterCallback);
-            }
-            var filtered = [];
-
-            helpers.each(collection, function(item) {
-                if (filterCallback(item)) {
-                    filtered.push(item);
-                }
-            });
-
-            return filtered;
-        };
-        helpers.findIndex = Array.prototype.findIndex?
-            function(array, callback, scope) {
-                return array.findIndex(callback, scope);
-            } :
-            function(array, callback, scope) {
-                scope = scope === undefined? array : scope;
-                for (var i = 0, ilen = array.length; i < ilen; ++i) {
-                    if (callback.call(scope, array[i], i, array)) {
-                        return i;
-                    }
-                }
-                return -1;
-            };
-        helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
-            // Default to start of the array
-            if (startIndex === undefined || startIndex === null) {
-                startIndex = -1;
-            }
-            for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
-                var currentItem = arrayToSearch[i];
-                if (filterCallback(currentItem)) {
-                    return currentItem;
-                }
-            }
-        };
-        helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
-            // Default to end of the array
-            if (startIndex === undefined || startIndex === null) {
-                startIndex = arrayToSearch.length;
-            }
-            for (var i = startIndex - 1; i >= 0; i--) {
-                var currentItem = arrayToSearch[i];
-                if (filterCallback(currentItem)) {
-                    return currentItem;
-                }
-            }
-        };
-        helpers.inherits = function(extensions) {
-            // Basic javascript inheritance based on the model created in Backbone.js
-            var me = this;
-            var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {
-                return me.apply(this, arguments);
-            };
-
-            var Surrogate = function() {
-                this.constructor = ChartElement;
-            };
-            Surrogate.prototype = me.prototype;
-            ChartElement.prototype = new Surrogate();
-
-            ChartElement.extend = helpers.inherits;
-
-            if (extensions) {
-                helpers.extend(ChartElement.prototype, extensions);
-            }
-
-            ChartElement.__super__ = me.prototype;
-
-            return ChartElement;
-        };
-        helpers.noop = function() {};
-        helpers.uid = (function() {
-            var id = 0;
-            return function() {
-                return id++;
-            };
-        }());
-        // -- Math methods
-        helpers.isNumber = function(n) {
-            return !isNaN(parseFloat(n)) && isFinite(n);
-        };
-        helpers.almostEquals = function(x, y, epsilon) {
-            return Math.abs(x - y) < epsilon;
-        };
-        helpers.almostWhole = function(x, epsilon) {
-            var rounded = Math.round(x);
-            return (((rounded - epsilon) < x) && ((rounded + epsilon) > x));
-        };
-        helpers.max = function(array) {
-            return array.reduce(function(max, value) {
-                if (!isNaN(value)) {
-                    return Math.max(max, value);
-                }
-                return max;
-            }, Number.NEGATIVE_INFINITY);
-        };
-        helpers.min = function(array) {
-            return array.reduce(function(min, value) {
-                if (!isNaN(value)) {
-                    return Math.min(min, value);
-                }
-                return min;
-            }, Number.POSITIVE_INFINITY);
-        };
-        helpers.sign = Math.sign?
-            function(x) {
-                return Math.sign(x);
-            } :
-            function(x) {
-                x = +x; // convert to a number
-                if (x === 0 || isNaN(x)) {
-                    return x;
-                }
-                return x > 0 ? 1 : -1;
-            };
-        helpers.log10 = Math.log10?
-            function(x) {
-                return Math.log10(x);
-            } :
-            function(x) {
-                return Math.log(x) / Math.LN10;
-            };
-        helpers.toRadians = function(degrees) {
-            return degrees * (Math.PI / 180);
-        };
-        helpers.toDegrees = function(radians) {
-            return radians * (180 / Math.PI);
-        };
-        // Gets the angle from vertical upright to the point about a centre.
-        helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
-            var distanceFromXCenter = anglePoint.x - centrePoint.x,
-                distanceFromYCenter = anglePoint.y - centrePoint.y,
-                radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
-
-            var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
-
-            if (angle < (-0.5 * Math.PI)) {
-                angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
-            }
-
-            return {
-                angle: angle,
-                distance: radialDistanceFromCenter
-            };
-        };
-        helpers.distanceBetweenPoints = function(pt1, pt2) {
-            return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
-        };
-        helpers.aliasPixel = function(pixelWidth) {
-            return (pixelWidth % 2 === 0) ? 0 : 0.5;
-        };
-        helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
-            // Props to Rob Spencer at scaled innovation for his post on splining between points
-            // http://scaledinnovation.com/analytics/splines/aboutSplines.html
-
-            // This function must also respect "skipped" points
-
-            var previous = firstPoint.skip ? middlePoint : firstPoint,
-                current = middlePoint,
-                next = afterPoint.skip ? middlePoint : afterPoint;
-
-            var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
-            var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
-
-            var s01 = d01 / (d01 + d12);
-            var s12 = d12 / (d01 + d12);
-
-            // If all points are the same, s01 & s02 will be inf
-            s01 = isNaN(s01) ? 0 : s01;
-            s12 = isNaN(s12) ? 0 : s12;
-
-            var fa = t * s01; // scaling factor for triangle Ta
-            var fb = t * s12;
-
-            return {
-                previous: {
-                    x: current.x - fa * (next.x - previous.x),
-                    y: current.y - fa * (next.y - previous.y)
-                },
-                next: {
-                    x: current.x + fb * (next.x - previous.x),
-                    y: current.y + fb * (next.y - previous.y)
-                }
-            };
-        };
-        helpers.EPSILON = Number.EPSILON || 1e-14;
-        helpers.splineCurveMonotone = function(points) {
-            // This function calculates Bézier control points in a similar way than |splineCurve|,
-            // but preserves monotonicity of the provided data and ensures no local extremums are added
-            // between the dataset discrete points due to the interpolation.
-            // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
-
-            var pointsWithTangents = (points || []).map(function(point) {
-                return {
-                    model: point._model,
-                    deltaK: 0,
-                    mK: 0
-                };
-            });
-
-            // Calculate slopes (deltaK) and initialize tangents (mK)
-            var pointsLen = pointsWithTangents.length;
-            var i, pointBefore, pointCurrent, pointAfter;
-            for (i = 0; i < pointsLen; ++i) {
-                pointCurrent = pointsWithTangents[i];
-                if (pointCurrent.model.skip) {
-                    continue;
-                }
-
-                pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
-                pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
-                if (pointAfter && !pointAfter.model.skip) {
-                    var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);
-
-                    // In the case of two points that appear at the same x pixel, slopeDeltaX is 0
-                    pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;
-                }
-
-                if (!pointBefore || pointBefore.model.skip) {
-                    pointCurrent.mK = pointCurrent.deltaK;
-                } else if (!pointAfter || pointAfter.model.skip) {
-                    pointCurrent.mK = pointBefore.deltaK;
-                } else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {
-                    pointCurrent.mK = 0;
-                } else {
-                    pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;
-                }
-            }
-
-            // Adjust tangents to ensure monotonic properties
-            var alphaK, betaK, tauK, squaredMagnitude;
-            for (i = 0; i < pointsLen - 1; ++i) {
-                pointCurrent = pointsWithTangents[i];
-                pointAfter = pointsWithTangents[i + 1];
-                if (pointCurrent.model.skip || pointAfter.model.skip) {
-                    continue;
-                }
-
-                if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {
-                    pointCurrent.mK = pointAfter.mK = 0;
-                    continue;
-                }
-
-                alphaK = pointCurrent.mK / pointCurrent.deltaK;
-                betaK = pointAfter.mK / pointCurrent.deltaK;
-                squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
-                if (squaredMagnitude <= 9) {
-                    continue;
-                }
-
-                tauK = 3 / Math.sqrt(squaredMagnitude);
-                pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;
-                pointAfter.mK = betaK * tauK * pointCurrent.deltaK;
-            }
-
-            // Compute control points
-            var deltaX;
-            for (i = 0; i < pointsLen; ++i) {
-                pointCurrent = pointsWithTangents[i];
-                if (pointCurrent.model.skip) {
-                    continue;
-                }
-
-                pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
-                pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
-                if (pointBefore && !pointBefore.model.skip) {
-                    deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;
-                    pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;
-                    pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;
-                }
-                if (pointAfter && !pointAfter.model.skip) {
-                    deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;
-                    pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;
-                    pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;
-                }
-            }
-        };
-        helpers.nextItem = function(collection, index, loop) {
-            if (loop) {
-                return index >= collection.length - 1 ? collection[0] : collection[index + 1];
-            }
-            return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];
-        };
-        helpers.previousItem = function(collection, index, loop) {
-            if (loop) {
-                return index <= 0 ? collection[collection.length - 1] : collection[index - 1];
-            }
-            return index <= 0 ? collection[0] : collection[index - 1];
-        };
-        // Implementation of the nice number algorithm used in determining where axis labels will go
-        helpers.niceNum = function(range, round) {
-            var exponent = Math.floor(helpers.log10(range));
-            var fraction = range / Math.pow(10, exponent);
-            var niceFraction;
-
-            if (round) {
-                if (fraction < 1.5) {
-                    niceFraction = 1;
-                } else if (fraction < 3) {
-                    niceFraction = 2;
-                } else if (fraction < 7) {
-                    niceFraction = 5;
-                } else {
-                    niceFraction = 10;
-                }
-            } else if (fraction <= 1.0) {
-                niceFraction = 1;
-            } else if (fraction <= 2) {
-                niceFraction = 2;
-            } else if (fraction <= 5) {
-                niceFraction = 5;
-            } else {
-                niceFraction = 10;
-            }
-
-            return niceFraction * Math.pow(10, exponent);
-        };
-        // Easing functions adapted from Robert Penner's easing equations
-        // http://www.robertpenner.com/easing/
-        var easingEffects = helpers.easingEffects = {
-            linear: function(t) {
-                return t;
-            },
-            easeInQuad: function(t) {
-                return t * t;
-            },
-            easeOutQuad: function(t) {
-                return -1 * t * (t - 2);
-            },
-            easeInOutQuad: function(t) {
-                if ((t /= 1 / 2) < 1) {
-                    return 1 / 2 * t * t;
-                }
-                return -1 / 2 * ((--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) {
-                if ((t /= 1 / 2) < 1) {
-                    return 1 / 2 * t * t * t;
-                }
-                return 1 / 2 * ((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) {
-                if ((t /= 1 / 2) < 1) {
-                    return 1 / 2 * t * t * t * t;
-                }
-                return -1 / 2 * ((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) {
-                if ((t /= 1 / 2) < 1) {
-                    return 1 / 2 * t * t * t * t * t;
-                }
-                return 1 / 2 * ((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 -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
-            },
-            easeInExpo: function(t) {
-                return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
-            },
-            easeOutExpo: function(t) {
-                return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
-            },
-            easeInOutExpo: function(t) {
-                if (t === 0) {
-                    return 0;
-                }
-                if (t === 1) {
-                    return 1;
-                }
-                if ((t /= 1 / 2) < 1) {
-                    return 1 / 2 * Math.pow(2, 10 * (t - 1));
-                }
-                return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
-            },
-            easeInCirc: function(t) {
-                if (t >= 1) {
-                    return t;
-                }
-                return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
-            },
-            easeOutCirc: function(t) {
-                return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
-            },
-            easeInOutCirc: function(t) {
-                if ((t /= 1 / 2) < 1) {
-                    return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
-                }
-                return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
-            },
-            easeInElastic: function(t) {
-                var s = 1.70158;
-                var p = 0;
-                var a = 1;
-                if (t === 0) {
-                    return 0;
-                }
-                if ((t /= 1) === 1) {
-                    return 1;
-                }
-                if (!p) {
-                    p = 1 * 0.3;
-                }
-                if (a < Math.abs(1)) {
-                    a = 1;
-                    s = p / 4;
-                } else {
-                    s = p / (2 * Math.PI) * Math.asin(1 / a);
-                }
-                return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
-            },
-            easeOutElastic: function(t) {
-                var s = 1.70158;
-                var p = 0;
-                var a = 1;
-                if (t === 0) {
-                    return 0;
-                }
-                if ((t /= 1) === 1) {
-                    return 1;
-                }
-                if (!p) {
-                    p = 1 * 0.3;
-                }
-                if (a < Math.abs(1)) {
-                    a = 1;
-                    s = p / 4;
-                } else {
-                    s = p / (2 * Math.PI) * Math.asin(1 / a);
-                }
-                return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
-            },
-            easeInOutElastic: function(t) {
-                var s = 1.70158;
-                var p = 0;
-                var a = 1;
-                if (t === 0) {
-                    return 0;
-                }
-                if ((t /= 1 / 2) === 2) {
-                    return 1;
-                }
-                if (!p) {
-                    p = 1 * (0.3 * 1.5);
-                }
-                if (a < Math.abs(1)) {
-                    a = 1;
-                    s = p / 4;
-                } else {
-                    s = p / (2 * Math.PI) * Math.asin(1 / a);
-                }
-                if (t < 1) {
-                    return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
-                }
-                return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
-            },
-            easeInBack: function(t) {
-                var s = 1.70158;
-                return 1 * (t /= 1) * t * ((s + 1) * t - s);
-            },
-            easeOutBack: function(t) {
-                var s = 1.70158;
-                return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
-            },
-            easeInOutBack: function(t) {
-                var s = 1.70158;
-                if ((t /= 1 / 2) < 1) {
-                    return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
-                }
-                return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
-            },
-            easeInBounce: function(t) {
-                return 1 - easingEffects.easeOutBounce(1 - t);
-            },
-            easeOutBounce: function(t) {
-                if ((t /= 1) < (1 / 2.75)) {
-                    return 1 * (7.5625 * t * t);
-                } else if (t < (2 / 2.75)) {
-                    return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
-                } else if (t < (2.5 / 2.75)) {
-                    return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
-                }
-                return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
-            },
-            easeInOutBounce: function(t) {
-                if (t < 1 / 2) {
-                    return easingEffects.easeInBounce(t * 2) * 0.5;
-                }
-                return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
-            }
-        };
-        // Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
-        helpers.requestAnimFrame = (function() {
-            if (typeof window === 'undefined') {
-                return function(callback) {
-                    callback();
-                };
-            }
-            return window.requestAnimationFrame ||
-                window.webkitRequestAnimationFrame ||
-                window.mozRequestAnimationFrame ||
-                window.oRequestAnimationFrame ||
-                window.msRequestAnimationFrame ||
-                function(callback) {
-                    return window.setTimeout(callback, 1000 / 60);
-                };
-        }());
-        // -- DOM methods
-        helpers.getRelativePosition = function(evt, chart) {
-            var mouseX, mouseY;
-            var e = evt.originalEvent || evt,
-                canvas = evt.currentTarget || evt.srcElement,
-                boundingRect = canvas.getBoundingClientRect();
-
-            var touches = e.touches;
-            if (touches && touches.length > 0) {
-                mouseX = touches[0].clientX;
-                mouseY = touches[0].clientY;
-
-            } else {
-                mouseX = e.clientX;
-                mouseY = e.clientY;
-            }
-
-            // Scale mouse coordinates into canvas coordinates
-            // by following the pattern laid out by 'jerryj' in the comments of
-            // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
-            var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));
-            var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));
-            var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));
-            var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));
-            var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;
-            var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;
-
-            // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
-            // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
-            mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);
-            mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);
-
-            return {
-                x: mouseX,
-                y: mouseY
-            };
-
-        };
-        helpers.addEvent = function(node, eventType, method) {
-            if (node.addEventListener) {
-                node.addEventListener(eventType, method);
-            } else if (node.attachEvent) {
-                node.attachEvent('on' + eventType, method);
-            } else {
-                node['on' + eventType] = method;
-            }
-        };
-        helpers.removeEvent = function(node, eventType, handler) {
-            if (node.removeEventListener) {
-                node.removeEventListener(eventType, handler, false);
-            } else if (node.detachEvent) {
-                node.detachEvent('on' + eventType, handler);
-            } else {
-                node['on' + eventType] = helpers.noop;
-            }
-        };
-
-        // Private helper function to convert max-width/max-height values that may be percentages into a number
-        function parseMaxStyle(styleValue, node, parentProperty) {
-            var valueInPixels;
-            if (typeof(styleValue) === 'string') {
-                valueInPixels = parseInt(styleValue, 10);
-
-                if (styleValue.indexOf('%') !== -1) {
-                    // percentage * size in dimension
-                    valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
-                }
-            } else {
-                valueInPixels = styleValue;
-            }
-
-            return valueInPixels;
-        }
-
-        /**
-         * Returns if the given value contains an effective constraint.
-         * @private
-         */
-        function isConstrainedValue(value) {
-            return value !== undefined && value !== null && value !== 'none';
-        }
-
-        // Private helper to get a constraint dimension
-        // @param domNode : the node to check the constraint on
-        // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)
-        // @param percentageProperty : property of parent to use when calculating width as a percentage
-        // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser
-        function getConstraintDimension(domNode, maxStyle, percentageProperty) {
-            var view = document.defaultView;
-            var parentNode = domNode.parentNode;
-            var constrainedNode = view.getComputedStyle(domNode)[maxStyle];
-            var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];
-            var hasCNode = isConstrainedValue(constrainedNode);
-            var hasCContainer = isConstrainedValue(constrainedContainer);
-            var infinity = Number.POSITIVE_INFINITY;
-
-            if (hasCNode || hasCContainer) {
-                return Math.min(
-                    hasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,
-                    hasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);
-            }
-
-            return 'none';
-        }
-        // returns Number or undefined if no constraint
-        helpers.getConstraintWidth = function(domNode) {
-            return getConstraintDimension(domNode, 'max-width', 'clientWidth');
-        };
-        // returns Number or undefined if no constraint
-        helpers.getConstraintHeight = function(domNode) {
-            return getConstraintDimension(domNode, 'max-height', 'clientHeight');
-        };
-        helpers.getMaximumWidth = function(domNode) {
-            var container = domNode.parentNode;
-            var paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);
-            var paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);
-            var w = container.clientWidth - paddingLeft - paddingRight;
-            var cw = helpers.getConstraintWidth(domNode);
-            return isNaN(cw)? w : Math.min(w, cw);
-        };
-        helpers.getMaximumHeight = function(domNode) {
-            var container = domNode.parentNode;
-            var paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);
-            var paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);
-            var h = container.clientHeight - paddingTop - paddingBottom;
-            var ch = helpers.getConstraintHeight(domNode);
-            return isNaN(ch)? h : Math.min(h, ch);
-        };
-        helpers.getStyle = function(el, property) {
-            return el.currentStyle ?
-                el.currentStyle[property] :
-                document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
-        };
-        helpers.retinaScale = function(chart) {
-            var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
-            if (pixelRatio === 1) {
-                return;
-            }
-
-            var canvas = chart.canvas;
-            var height = chart.height;
-            var width = chart.width;
-
-            canvas.height = height * pixelRatio;
-            canvas.width = width * pixelRatio;
-            chart.ctx.scale(pixelRatio, pixelRatio);
-
-            // If no style has been set on the canvas, the render size is used as display size,
-            // making the chart visually bigger, so let's enforce it to the "correct" values.
-            // See https://github.com/chartjs/Chart.js/issues/3575
-            canvas.style.height = height + 'px';
-            canvas.style.width = width + 'px';
-        };
-        // -- Canvas methods
-        helpers.clear = function(chart) {
-            chart.ctx.clearRect(0, 0, chart.width, chart.height);
-        };
-        helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
-            return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
-        };
-        helpers.longestText = function(ctx, font, arrayOfThings, cache) {
-            cache = cache || {};
-            var data = cache.data = cache.data || {};
-            var gc = cache.garbageCollect = cache.garbageCollect || [];
-
-            if (cache.font !== font) {
-                data = cache.data = {};
-                gc = cache.garbageCollect = [];
-                cache.font = font;
-            }
-
-            ctx.font = font;
-            var longest = 0;
-            helpers.each(arrayOfThings, function(thing) {
-                // Undefined strings and arrays should not be measured
-                if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {
-                    longest = helpers.measureText(ctx, data, gc, longest, thing);
-                } else if (helpers.isArray(thing)) {
-                    // if it is an array lets measure each element
-                    // to do maybe simplify this function a bit so we can do this more recursively?
-                    helpers.each(thing, function(nestedThing) {
-                        // Undefined strings and arrays should not be measured
-                        if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {
-                            longest = helpers.measureText(ctx, data, gc, longest, nestedThing);
-                        }
-                    });
-                }
-            });
-
-            var gcLen = gc.length / 2;
-            if (gcLen > arrayOfThings.length) {
-                for (var i = 0; i < gcLen; i++) {
-                    delete data[gc[i]];
-                }
-                gc.splice(0, gcLen);
-            }
-            return longest;
-        };
-        helpers.measureText = function(ctx, data, gc, longest, string) {
-            var textWidth = data[string];
-            if (!textWidth) {
-                textWidth = data[string] = ctx.measureText(string).width;
-                gc.push(string);
-            }
-            if (textWidth > longest) {
-                longest = textWidth;
-            }
-            return longest;
-        };
-        helpers.numberOfLabelLines = function(arrayOfThings) {
-            var numberOfLines = 1;
-            helpers.each(arrayOfThings, function(thing) {
-                if (helpers.isArray(thing)) {
-                    if (thing.length > numberOfLines) {
-                        numberOfLines = thing.length;
-                    }
-                }
-            });
-            return numberOfLines;
-        };
-        helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {
-            ctx.beginPath();
-            ctx.moveTo(x + radius, y);
-            ctx.lineTo(x + width - radius, y);
-            ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
-            ctx.lineTo(x + width, y + height - radius);
-            ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
-            ctx.lineTo(x + radius, y + height);
-            ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
-            ctx.lineTo(x, y + radius);
-            ctx.quadraticCurveTo(x, y, x + radius, y);
-            ctx.closePath();
-        };
-
-        helpers.color = !color?
-            function(value) {
-                console.error('Color.js not found!');
-                return value;
-            } :
-            function(value) {
-                /* global CanvasGradient */
-                if (value instanceof CanvasGradient) {
-                    value = Chart.defaults.global.defaultColor;
-                }
-
-                return color(value);
-            };
-
-        helpers.isArray = Array.isArray?
-            function(obj) {
-                return Array.isArray(obj);
-            } :
-            function(obj) {
-                return Object.prototype.toString.call(obj) === '[object Array]';
-            };
-        // ! @see http://stackoverflow.com/a/14853974
-        helpers.arrayEquals = function(a0, a1) {
-            var i, ilen, v0, v1;
-
-            if (!a0 || !a1 || a0.length !== a1.length) {
-                return false;
-            }
-
-            for (i = 0, ilen=a0.length; i < ilen; ++i) {
-                v0 = a0[i];
-                v1 = a1[i];
-
-                if (v0 instanceof Array && v1 instanceof Array) {
-                    if (!helpers.arrayEquals(v0, v1)) {
-                        return false;
-                    }
-                } else if (v0 !== v1) {
-                    // NOTE: two different object instances will never be equal: {x:20} != {x:20}
-                    return false;
-                }
-            }
-
-            return true;
-        };
-        helpers.callback = function(fn, args, thisArg) {
-            if (fn && typeof fn.call === 'function') {
-                fn.apply(thisArg, args);
-            }
-        };
-        helpers.getHoverColor = function(colorValue) {
-            /* global CanvasPattern */
-            return (colorValue instanceof CanvasPattern) ?
-                colorValue :
-                helpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();
-        };
-
-        /**
-         * Provided for backward compatibility, use Chart.helpers#callback instead.
-         * @function Chart.helpers#callCallback
-         * @deprecated since version 2.6.0
-         * @todo remove at version 3
-         */
-        helpers.callCallback = helpers.callback;
-    };
-
-},{"3":3}],27:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-        var helpers = Chart.helpers;
-
-        /**
-         * Helper function to get relative position for an event
-         * @param {Event|IEvent} event - The event to get the position for
-         * @param {Chart} chart - The chart
-         * @returns {Point} the event position
-         */
-        function getRelativePosition(e, chart) {
-            if (e.native) {
-                return {
-                    x: e.x,
-                    y: e.y
-                };
-            }
-
-            return helpers.getRelativePosition(e, chart);
-        }
-
-        /**
-         * Helper function to traverse all of the visible elements in the chart
-         * @param chart {chart} the chart
-         * @param handler {Function} the callback to execute for each visible item
-         */
-        function parseVisibleItems(chart, handler) {
-            var datasets = chart.data.datasets;
-            var meta, i, j, ilen, jlen;
-
-            for (i = 0, ilen = datasets.length; i < ilen; ++i) {
-                if (!chart.isDatasetVisible(i)) {
-                    continue;
-                }
-
-                meta = chart.getDatasetMeta(i);
-                for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
-                    var element = meta.data[j];
-                    if (!element._view.skip) {
-                        handler(element);
-                    }
-                }
-            }
-        }
-
-        /**
-         * Helper function to get the items that intersect the event position
-         * @param items {ChartElement[]} elements to filter
-         * @param position {Point} the point to be nearest to
-         * @return {ChartElement[]} the nearest items
-         */
-        function getIntersectItems(chart, position) {
-            var elements = [];
-
-            parseVisibleItems(chart, function(element) {
-                if (element.inRange(position.x, position.y)) {
-                    elements.push(element);
-                }
-            });
-
-            return elements;
-        }
-
-        /**
-         * Helper function to get the items nearest to the event position considering all visible items in teh chart
-         * @param chart {Chart} the chart to look at elements from
-         * @param position {Point} the point to be nearest to
-         * @param intersect {Boolean} if true, only consider items that intersect the position
-         * @param distanceMetric {Function} Optional function to provide the distance between
-         * @return {ChartElement[]} the nearest items
-         */
-        function getNearestItems(chart, position, intersect, distanceMetric) {
-            var minDistance = Number.POSITIVE_INFINITY;
-            var nearestItems = [];
-
-            if (!distanceMetric) {
-                distanceMetric = helpers.distanceBetweenPoints;
-            }
-
-            parseVisibleItems(chart, function(element) {
-                if (intersect && !element.inRange(position.x, position.y)) {
-                    return;
-                }
-
-                var center = element.getCenterPoint();
-                var distance = distanceMetric(position, center);
-
-                if (distance < minDistance) {
-                    nearestItems = [element];
-                    minDistance = distance;
-                } else if (distance === minDistance) {
-                    // Can have multiple items at the same distance in which case we sort by size
-                    nearestItems.push(element);
-                }
-            });
-
-            return nearestItems;
-        }
-
-        function indexMode(chart, e, options) {
-            var position = getRelativePosition(e, chart);
-            var distanceMetric = function(pt1, pt2) {
-                return Math.abs(pt1.x - pt2.x);
-            };
-            var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
-            var elements = [];
-
-            if (!items.length) {
-                return [];
-            }
-
-            chart.data.datasets.forEach(function(dataset, datasetIndex) {
-                if (chart.isDatasetVisible(datasetIndex)) {
-                    var meta = chart.getDatasetMeta(datasetIndex),
-                        element = meta.data[items[0]._index];
-
-                    // don't count items that are skipped (null data)
-                    if (element && !element._view.skip) {
-                        elements.push(element);
-                    }
-                }
-            });
-
-            return elements;
-        }
-
-        /**
-         * @interface IInteractionOptions
-         */
-        /**
-         * If true, only consider items that intersect the point
-         * @name IInterfaceOptions#boolean
-         * @type Boolean
-         */
-
-        /**
-         * Contains interaction related functions
-         * @namespace Chart.Interaction
-         */
-        Chart.Interaction = {
-            // Helper function for different modes
-            modes: {
-                single: function(chart, e) {
-                    var position = getRelativePosition(e, chart);
-                    var elements = [];
-
-                    parseVisibleItems(chart, function(element) {
-                        if (element.inRange(position.x, position.y)) {
-                            elements.push(element);
-                            return elements;
-                        }
-                    });
-
-                    return elements.slice(0, 1);
-                },
-
-                /**
-                 * @function Chart.Interaction.modes.label
-                 * @deprecated since version 2.4.0
-                 * @todo remove at version 3
-                 * @private
-                 */
-                label: indexMode,
-
-                /**
-                 * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something
-                 * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item
-                 * @function Chart.Interaction.modes.index
-                 * @since v2.4.0
-                 * @param chart {chart} the chart we are returning items from
-                 * @param e {Event} the event we are find things at
-                 * @param options {IInteractionOptions} options to use during interaction
-                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
-                 */
-                index: indexMode,
-
-                /**
-                 * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something
-                 * If the options.intersect is false, we find the nearest item and return the items in that dataset
-                 * @function Chart.Interaction.modes.dataset
-                 * @param chart {chart} the chart we are returning items from
-                 * @param e {Event} the event we are find things at
-                 * @param options {IInteractionOptions} options to use during interaction
-                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
-                 */
-                dataset: function(chart, e, options) {
-                    var position = getRelativePosition(e, chart);
-                    var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false);
-
-                    if (items.length > 0) {
-                        items = chart.getDatasetMeta(items[0]._datasetIndex).data;
-                    }
-
-                    return items;
-                },
-
-                /**
-                 * @function Chart.Interaction.modes.x-axis
-                 * @deprecated since version 2.4.0. Use index mode and intersect == true
-                 * @todo remove at version 3
-                 * @private
-                 */
-                'x-axis': function(chart, e) {
-                    return indexMode(chart, e, true);
-                },
-
-                /**
-                 * Point mode returns all elements that hit test based on the event position
-                 * of the event
-                 * @function Chart.Interaction.modes.intersect
-                 * @param chart {chart} the chart we are returning items from
-                 * @param e {Event} the event we are find things at
-                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
-                 */
-                point: function(chart, e) {
-                    var position = getRelativePosition(e, chart);
-                    return getIntersectItems(chart, position);
-                },
-
-                /**
-                 * nearest mode returns the element closest to the point
-                 * @function Chart.Interaction.modes.intersect
-                 * @param chart {chart} the chart we are returning items from
-                 * @param e {Event} the event we are find things at
-                 * @param options {IInteractionOptions} options to use
-                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
-                 */
-                nearest: function(chart, e, options) {
-                    var position = getRelativePosition(e, chart);
-                    var nearestItems = getNearestItems(chart, position, options.intersect);
-
-                    // We have multiple items at the same distance from the event. Now sort by smallest
-                    if (nearestItems.length > 1) {
-                        nearestItems.sort(function(a, b) {
-                            var sizeA = a.getArea();
-                            var sizeB = b.getArea();
-                            var ret = sizeA - sizeB;
-
-                            if (ret === 0) {
-                                // if equal sort by dataset index
-                                ret = a._datasetIndex - b._datasetIndex;
-                            }
-
-                            return ret;
-                        });
-                    }
-
-                    // Return only 1 item
-                    return nearestItems.slice(0, 1);
-                },
-
-                /**
-                 * x mode returns the elements that hit-test at the current x coordinate
-                 * @function Chart.Interaction.modes.x
-                 * @param chart {chart} the chart we are returning items from
-                 * @param e {Event} the event we are find things at
-                 * @param options {IInteractionOptions} options to use
-                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
-                 */
-                x: function(chart, e, options) {
-                    var position = getRelativePosition(e, chart);
-                    var items = [];
-                    var intersectsItem = false;
-
-                    parseVisibleItems(chart, function(element) {
-                        if (element.inXRange(position.x)) {
-                            items.push(element);
-                        }
-
-                        if (element.inRange(position.x, position.y)) {
-                            intersectsItem = true;
-                        }
-                    });
-
-                    // If we want to trigger on an intersect and we don't have any items
-                    // that intersect the position, return nothing
-                    if (options.intersect && !intersectsItem) {
-                        items = [];
-                    }
-                    return items;
-                },
-
-                /**
-                 * y mode returns the elements that hit-test at the current y coordinate
-                 * @function Chart.Interaction.modes.y
-                 * @param chart {chart} the chart we are returning items from
-                 * @param e {Event} the event we are find things at
-                 * @param options {IInteractionOptions} options to use
-                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
-                 */
-                y: function(chart, e, options) {
-                    var position = getRelativePosition(e, chart);
-                    var items = [];
-                    var intersectsItem = false;
-
-                    parseVisibleItems(chart, function(element) {
-                        if (element.inYRange(position.y)) {
-                            items.push(element);
-                        }
-
-                        if (element.inRange(position.x, position.y)) {
-                            intersectsItem = true;
-                        }
-                    });
-
-                    // If we want to trigger on an intersect and we don't have any items
-                    // that intersect the position, return nothing
-                    if (options.intersect && !intersectsItem) {
-                        items = [];
-                    }
-                    return items;
-                }
-            }
-        };
-    };
-
-},{}],28:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function() {
-
-        // Occupy the global variable of Chart, and create a simple base class
-        var Chart = function(item, config) {
-            this.construct(item, config);
-            return this;
-        };
-
-        // Globally expose the defaults to allow for user updating/changing
-        Chart.defaults = {
-            global: {
-                responsive: true,
-                responsiveAnimationDuration: 0,
-                maintainAspectRatio: true,
-                events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
-                hover: {
-                    onHover: null,
-                    mode: 'nearest',
-                    intersect: true,
-                    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: true,
-
-                // Element defaults defined in element extensions
-                elements: {},
-
-                // Legend callback string
-                legendCallback: function(chart) {
-                    var text = [];
-                    text.push('<ul class="' + chart.id + '-legend">');
-                    for (var i = 0; i < chart.data.datasets.length; i++) {
-                        text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>');
-                        if (chart.data.datasets[i].label) {
-                            text.push(chart.data.datasets[i].label);
-                        }
-                        text.push('</li>');
-                    }
-                    text.push('</ul>');
-
-                    return text.join('');
-                }
-            }
-        };
-
-        Chart.Chart = Chart;
-
-        return Chart;
-    };
-
-},{}],29:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        function filterByPosition(array, position) {
-            return helpers.where(array, function(v) {
-                return v.position === position;
-            });
-        }
-
-        function sortByWeight(array, reverse) {
-            array.forEach(function(v, i) {
-                v._tmpIndex_ = i;
-                return v;
-            });
-            array.sort(function(a, b) {
-                var v0 = reverse ? b : a;
-                var v1 = reverse ? a : b;
-                return v0.weight === v1.weight ?
-                    v0._tmpIndex_ - v1._tmpIndex_ :
-                    v0.weight - v1.weight;
-            });
-            array.forEach(function(v) {
-                delete v._tmpIndex_;
-            });
-        }
-
-        /**
-         * @interface ILayoutItem
-         * @prop {String} position - The position of the item in the chart layout. Possible values are
-         * 'left', 'top', 'right', 'bottom', and 'chartArea'
-         * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area
-         * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down
-         * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)
-         * @prop {Function} update - Takes two parameters: width and height. Returns size of item
-         * @prop {Function} getPadding -  Returns an object with padding on the edges
-         * @prop {Number} width - Width of item. Must be valid after update()
-         * @prop {Number} height - Height of item. Must be valid after update()
-         * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update
-         * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update
-         * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update
-         * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update
-         */
-
-        // The layout service is very self explanatory.  It's responsible for the layout within a chart.
-        // Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
-        // It is this service's responsibility of carrying out that layout.
-        Chart.layoutService = {
-            defaults: {},
-
-            /**
-             * Register a box to a chart.
-             * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
-             * @param {Chart} chart - the chart to use
-             * @param {ILayoutItem} item - the item to add to be layed out
-             */
-            addBox: function(chart, item) {
-                if (!chart.boxes) {
-                    chart.boxes = [];
-                }
-
-                // initialize item with default values
-                item.fullWidth = item.fullWidth || false;
-                item.position = item.position || 'top';
-                item.weight = item.weight || 0;
-
-                chart.boxes.push(item);
-            },
-
-            /**
-             * Remove a layoutItem from a chart
-             * @param {Chart} chart - the chart to remove the box from
-             * @param {Object} layoutItem - the item to remove from the layout
-             */
-            removeBox: function(chart, layoutItem) {
-                var index = chart.boxes? chart.boxes.indexOf(layoutItem) : -1;
-                if (index !== -1) {
-                    chart.boxes.splice(index, 1);
-                }
-            },
-
-            /**
-             * Sets (or updates) options on the given `item`.
-             * @param {Chart} chart - the chart in which the item lives (or will be added to)
-             * @param {Object} item - the item to configure with the given options
-             * @param {Object} options - the new item options.
-             */
-            configure: function(chart, item, options) {
-                var props = ['fullWidth', 'position', 'weight'];
-                var ilen = props.length;
-                var i = 0;
-                var prop;
-
-                for (; i<ilen; ++i) {
-                    prop = props[i];
-                    if (options.hasOwnProperty(prop)) {
-                        item[prop] = options[prop];
-                    }
-                }
-            },
-
-            /**
-             * Fits boxes of the given chart into the given size by having each box measure itself
-             * then running a fitting algorithm
-             * @param {Chart} chart - the chart
-             * @param {Number} width - the width to fit into
-             * @param {Number} height - the height to fit into
-             */
-            update: function(chart, width, height) {
-                if (!chart) {
-                    return;
-                }
-
-                var layoutOptions = chart.options.layout;
-                var padding = layoutOptions ? layoutOptions.padding : null;
-
-                var leftPadding = 0;
-                var rightPadding = 0;
-                var topPadding = 0;
-                var bottomPadding = 0;
-
-                if (!isNaN(padding)) {
-                    // options.layout.padding is a number. assign to all
-                    leftPadding = padding;
-                    rightPadding = padding;
-                    topPadding = padding;
-                    bottomPadding = padding;
-                } else {
-                    leftPadding = padding.left || 0;
-                    rightPadding = padding.right || 0;
-                    topPadding = padding.top || 0;
-                    bottomPadding = padding.bottom || 0;
-                }
-
-                var leftBoxes = filterByPosition(chart.boxes, 'left');
-                var rightBoxes = filterByPosition(chart.boxes, 'right');
-                var topBoxes = filterByPosition(chart.boxes, 'top');
-                var bottomBoxes = filterByPosition(chart.boxes, 'bottom');
-                var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');
-
-                // Sort boxes by weight. A higher weight is further away from the chart area
-                sortByWeight(leftBoxes, true);
-                sortByWeight(rightBoxes, false);
-                sortByWeight(topBoxes, true);
-                sortByWeight(bottomBoxes, false);
-
-                // Essentially we now have any number of boxes on each of the 4 sides.
-                // Our canvas looks like the following.
-                // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
-                // B1 is the bottom axis
-                // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
-                // These locations are single-box locations only, when trying to register a chartArea location that is already taken,
-                // an error will be thrown.
-                //
-                // |----------------------------------------------------|
-                // |                  T1 (Full Width)                   |
-                // |----------------------------------------------------|
-                // |    |    |                 T2                  |    |
-                // |    |----|-------------------------------------|----|
-                // |    |    | C1 |                           | C2 |    |
-                // |    |    |----|                           |----|    |
-                // |    |    |                                     |    |
-                // | L1 | L2 |           ChartArea (C0)            | R1 |
-                // |    |    |                                     |    |
-                // |    |    |----|                           |----|    |
-                // |    |    | C3 |                           | C4 |    |
-                // |    |----|-------------------------------------|----|
-                // |    |    |                 B1                  |    |
-                // |----------------------------------------------------|
-                // |                  B2 (Full Width)                   |
-                // |----------------------------------------------------|
-                //
-                // What we do to find the best sizing, we do the following
-                // 1. Determine the minimum size of the chart area.
-                // 2. Split the remaining width equally between each vertical axis
-                // 3. Split the remaining height equally between each horizontal axis
-                // 4. Give each layout the maximum size it can be. The layout will return it's minimum size
-                // 5. Adjust the sizes of each axis based on it's minimum reported size.
-                // 6. Refit each axis
-                // 7. Position each axis in the final location
-                // 8. Tell the chart the final location of the chart area
-                // 9. Tell any axes that overlay the chart area the positions of the chart area
-
-                // Step 1
-                var chartWidth = width - leftPadding - rightPadding;
-                var chartHeight = height - topPadding - bottomPadding;
-                var chartAreaWidth = chartWidth / 2; // min 50%
-                var chartAreaHeight = chartHeight / 2; // min 50%
-
-                // Step 2
-                var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
-
-                // Step 3
-                var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
-
-                // Step 4
-                var maxChartAreaWidth = chartWidth;
-                var maxChartAreaHeight = chartHeight;
-                var minBoxSizes = [];
-
-                function getMinimumBoxSize(box) {
-                    var minSize;
-                    var isHorizontal = box.isHorizontal();
-
-                    if (isHorizontal) {
-                        minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
-                        maxChartAreaHeight -= minSize.height;
-                    } else {
-                        minSize = box.update(verticalBoxWidth, chartAreaHeight);
-                        maxChartAreaWidth -= minSize.width;
-                    }
-
-                    minBoxSizes.push({
-                        horizontal: isHorizontal,
-                        minSize: minSize,
-                        box: box,
-                    });
-                }
-
-                helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
-
-                // If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)
-                var maxHorizontalLeftPadding = 0;
-                var maxHorizontalRightPadding = 0;
-                var maxVerticalTopPadding = 0;
-                var maxVerticalBottomPadding = 0;
-
-                helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {
-                    if (horizontalBox.getPadding) {
-                        var boxPadding = horizontalBox.getPadding();
-                        maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);
-                        maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);
-                    }
-                });
-
-                helpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {
-                    if (verticalBox.getPadding) {
-                        var boxPadding = verticalBox.getPadding();
-                        maxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);
-                        maxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);
-                    }
-                });
-
-                // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
-                // be if the axes are drawn at their minimum sizes.
-                // Steps 5 & 6
-                var totalLeftBoxesWidth = leftPadding;
-                var totalRightBoxesWidth = rightPadding;
-                var totalTopBoxesHeight = topPadding;
-                var totalBottomBoxesHeight = bottomPadding;
-
-                // Function to fit a box
-                function fitBox(box) {
-                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
-                        return minBox.box === box;
-                    });
-
-                    if (minBoxSize) {
-                        if (box.isHorizontal()) {
-                            var scaleMargin = {
-                                left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
-                                right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
-                                top: 0,
-                                bottom: 0
-                            };
-
-                            // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
-                            // on the margin. Sometimes they need to increase in size slightly
-                            box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
-                        } else {
-                            box.update(minBoxSize.minSize.width, maxChartAreaHeight);
-                        }
-                    }
-                }
-
-                // Update, and calculate the left and right margins for the horizontal boxes
-                helpers.each(leftBoxes.concat(rightBoxes), fitBox);
-
-                helpers.each(leftBoxes, function(box) {
-                    totalLeftBoxesWidth += box.width;
-                });
-
-                helpers.each(rightBoxes, function(box) {
-                    totalRightBoxesWidth += box.width;
-                });
-
-                // Set the Left and Right margins for the horizontal boxes
-                helpers.each(topBoxes.concat(bottomBoxes), fitBox);
-
-                // Figure out how much margin is on the top and bottom of the vertical boxes
-                helpers.each(topBoxes, function(box) {
-                    totalTopBoxesHeight += box.height;
-                });
-
-                helpers.each(bottomBoxes, function(box) {
-                    totalBottomBoxesHeight += box.height;
-                });
-
-                function finalFitVerticalBox(box) {
-                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
-                        return minSize.box === box;
-                    });
-
-                    var scaleMargin = {
-                        left: 0,
-                        right: 0,
-                        top: totalTopBoxesHeight,
-                        bottom: totalBottomBoxesHeight
-                    };
-
-                    if (minBoxSize) {
-                        box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
-                    }
-                }
-
-                // Let the left layout know the final margin
-                helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
-
-                // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
-                totalLeftBoxesWidth = leftPadding;
-                totalRightBoxesWidth = rightPadding;
-                totalTopBoxesHeight = topPadding;
-                totalBottomBoxesHeight = bottomPadding;
-
-                helpers.each(leftBoxes, function(box) {
-                    totalLeftBoxesWidth += box.width;
-                });
-
-                helpers.each(rightBoxes, function(box) {
-                    totalRightBoxesWidth += box.width;
-                });
-
-                helpers.each(topBoxes, function(box) {
-                    totalTopBoxesHeight += box.height;
-                });
-                helpers.each(bottomBoxes, function(box) {
-                    totalBottomBoxesHeight += box.height;
-                });
-
-                // We may be adding some padding to account for rotated x axis labels
-                var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);
-                totalLeftBoxesWidth += leftPaddingAddition;
-                totalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);
-
-                var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);
-                totalTopBoxesHeight += topPaddingAddition;
-                totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);
-
-                // Figure out if our chart area changed. This would occur if the dataset layout label rotation
-                // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
-                // without calling `fit` again
-                var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
-                var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
-
-                if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
-                    helpers.each(leftBoxes, function(box) {
-                        box.height = newMaxChartAreaHeight;
-                    });
-
-                    helpers.each(rightBoxes, function(box) {
-                        box.height = newMaxChartAreaHeight;
-                    });
-
-                    helpers.each(topBoxes, function(box) {
-                        if (!box.fullWidth) {
-                            box.width = newMaxChartAreaWidth;
-                        }
-                    });
-
-                    helpers.each(bottomBoxes, function(box) {
-                        if (!box.fullWidth) {
-                            box.width = newMaxChartAreaWidth;
-                        }
-                    });
-
-                    maxChartAreaHeight = newMaxChartAreaHeight;
-                    maxChartAreaWidth = newMaxChartAreaWidth;
-                }
-
-                // Step 7 - Position the boxes
-                var left = leftPadding + leftPaddingAddition;
-                var top = topPadding + topPaddingAddition;
-
-                function placeBox(box) {
-                    if (box.isHorizontal()) {
-                        box.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;
-                        box.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;
-                        box.top = top;
-                        box.bottom = top + box.height;
-
-                        // Move to next point
-                        top = box.bottom;
-
-                    } else {
-
-                        box.left = left;
-                        box.right = left + box.width;
-                        box.top = totalTopBoxesHeight;
-                        box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
-
-                        // Move to next point
-                        left = box.right;
-                    }
-                }
-
-                helpers.each(leftBoxes.concat(topBoxes), placeBox);
-
-                // Account for chart width and height
-                left += maxChartAreaWidth;
-                top += maxChartAreaHeight;
-
-                helpers.each(rightBoxes, placeBox);
-                helpers.each(bottomBoxes, placeBox);
-
-                // Step 8
-                chart.chartArea = {
-                    left: totalLeftBoxesWidth,
-                    top: totalTopBoxesHeight,
-                    right: totalLeftBoxesWidth + maxChartAreaWidth,
-                    bottom: totalTopBoxesHeight + maxChartAreaHeight
-                };
-
-                // Step 9
-                helpers.each(chartAreaBoxes, function(box) {
-                    box.left = chart.chartArea.left;
-                    box.top = chart.chartArea.top;
-                    box.right = chart.chartArea.right;
-                    box.bottom = chart.chartArea.bottom;
-
-                    box.update(maxChartAreaWidth, maxChartAreaHeight);
-                });
-            }
-        };
-    };
-
-},{}],30:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.global.plugins = {};
-
-        /**
-         * The plugin service singleton
-         * @namespace Chart.plugins
-         * @since 2.1.0
-         */
-        Chart.plugins = {
-            /**
-             * Globally registered plugins.
-             * @private
-             */
-            _plugins: [],
-
-            /**
-             * This identifier is used to invalidate the descriptors cache attached to each chart
-             * when a global plugin is registered or unregistered. In this case, the cache ID is
-             * incremented and descriptors are regenerated during following API calls.
-             * @private
-             */
-            _cacheId: 0,
-
-            /**
-             * Registers the given plugin(s) if not already registered.
-             * @param {Array|Object} plugins plugin instance(s).
-             */
-            register: function(plugins) {
-                var p = this._plugins;
-                ([]).concat(plugins).forEach(function(plugin) {
-                    if (p.indexOf(plugin) === -1) {
-                        p.push(plugin);
-                    }
-                });
-
-                this._cacheId++;
-            },
-
-            /**
-             * Unregisters the given plugin(s) only if registered.
-             * @param {Array|Object} plugins plugin instance(s).
-             */
-            unregister: function(plugins) {
-                var p = this._plugins;
-                ([]).concat(plugins).forEach(function(plugin) {
-                    var idx = p.indexOf(plugin);
-                    if (idx !== -1) {
-                        p.splice(idx, 1);
-                    }
-                });
-
-                this._cacheId++;
-            },
-
-            /**
-             * Remove all registered plugins.
-             * @since 2.1.5
-             */
-            clear: function() {
-                this._plugins = [];
-                this._cacheId++;
-            },
-
-            /**
-             * Returns the number of registered plugins?
-             * @returns {Number}
-             * @since 2.1.5
-             */
-            count: function() {
-                return this._plugins.length;
-            },
-
-            /**
-             * Returns all registered plugin instances.
-             * @returns {Array} array of plugin objects.
-             * @since 2.1.5
-             */
-            getAll: function() {
-                return this._plugins;
-            },
-
-            /**
-             * Calls enabled plugins for `chart` on the specified hook and with the given args.
-             * This method immediately returns as soon as a plugin explicitly returns false. The
-             * returned value can be used, for instance, to interrupt the current action.
-             * @param {Object} chart - The chart instance for which plugins should be called.
-             * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').
-             * @param {Array} [args] - Extra arguments to apply to the hook call.
-             * @returns {Boolean} false if any of the plugins return false, else returns true.
-             */
-            notify: function(chart, hook, args) {
-                var descriptors = this.descriptors(chart);
-                var ilen = descriptors.length;
-                var i, descriptor, plugin, params, method;
-
-                for (i=0; i<ilen; ++i) {
-                    descriptor = descriptors[i];
-                    plugin = descriptor.plugin;
-                    method = plugin[hook];
-                    if (typeof method === 'function') {
-                        params = [chart].concat(args || []);
-                        params.push(descriptor.options);
-                        if (method.apply(plugin, params) === false) {
-                            return false;
-                        }
-                    }
-                }
-
-                return true;
-            },
-
-            /**
-             * Returns descriptors of enabled plugins for the given chart.
-             * @returns {Array} [{ plugin, options }]
-             * @private
-             */
-            descriptors: function(chart) {
-                var cache = chart._plugins || (chart._plugins = {});
-                if (cache.id === this._cacheId) {
-                    return cache.descriptors;
-                }
-
-                var plugins = [];
-                var descriptors = [];
-                var config = (chart && chart.config) || {};
-                var defaults = Chart.defaults.global.plugins;
-                var options = (config.options && config.options.plugins) || {};
-
-                this._plugins.concat(config.plugins || []).forEach(function(plugin) {
-                    var idx = plugins.indexOf(plugin);
-                    if (idx !== -1) {
-                        return;
-                    }
-
-                    var id = plugin.id;
-                    var opts = options[id];
-                    if (opts === false) {
-                        return;
-                    }
-
-                    if (opts === true) {
-                        opts = helpers.clone(defaults[id]);
-                    }
-
-                    plugins.push(plugin);
-                    descriptors.push({
-                        plugin: plugin,
-                        options: opts || {}
-                    });
-                });
-
-                cache.descriptors = descriptors;
-                cache.id = this._cacheId;
-                return descriptors;
-            }
-        };
-
-        /**
-         * Plugin extension hooks.
-         * @interface IPlugin
-         * @since 2.1.0
-         */
-        /**
-         * @method IPlugin#beforeInit
-         * @desc Called before initializing `chart`.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#afterInit
-         * @desc Called after `chart` has been initialized and before the first update.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeUpdate
-         * @desc Called before updating `chart`. If any plugin returns `false`, the update
-         * is cancelled (and thus subsequent render(s)) until another `update` is triggered.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} `false` to cancel the chart update.
-         */
-        /**
-         * @method IPlugin#afterUpdate
-         * @desc Called after `chart` has been updated and before rendering. Note that this
-         * hook will not be called if the chart update has been previously cancelled.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeDatasetsUpdate
-         * @desc Called before updating the `chart` datasets. If any plugin returns `false`,
-         * the datasets update is cancelled until another `update` is triggered.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} false to cancel the datasets update.
-         * @since version 2.1.5
-         */
-        /**
-         * @method IPlugin#afterDatasetsUpdate
-         * @desc Called after the `chart` datasets have been updated. Note that this hook
-         * will not be called if the datasets update has been previously cancelled.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         * @since version 2.1.5
-         */
-        /**
-         * @method IPlugin#beforeDatasetUpdate
-         * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin
-         * returns `false`, the datasets update is cancelled until another `update` is triggered.
-         * @param {Chart} chart - The chart instance.
-         * @param {Object} args - The call arguments.
-         * @param {Object} args.index - The dataset index.
-         * @param {Number} args.meta - The dataset metadata.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} `false` to cancel the chart datasets drawing.
-         */
-        /**
-         * @method IPlugin#afterDatasetUpdate
-         * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note
-         * that this hook will not be called if the datasets update has been previously cancelled.
-         * @param {Chart} chart - The chart instance.
-         * @param {Object} args - The call arguments.
-         * @param {Object} args.index - The dataset index.
-         * @param {Number} args.meta - The dataset metadata.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeLayout
-         * @desc Called before laying out `chart`. If any plugin returns `false`,
-         * the layout update is cancelled until another `update` is triggered.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} `false` to cancel the chart layout.
-         */
-        /**
-         * @method IPlugin#afterLayout
-         * @desc Called after the `chart` has been layed out. Note that this hook will not
-         * be called if the layout update has been previously cancelled.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeRender
-         * @desc Called before rendering `chart`. If any plugin returns `false`,
-         * the rendering is cancelled until another `render` is triggered.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} `false` to cancel the chart rendering.
-         */
-        /**
-         * @method IPlugin#afterRender
-         * @desc Called after the `chart` has been fully rendered (and animation completed). Note
-         * that this hook will not be called if the rendering has been previously cancelled.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeDraw
-         * @desc Called before drawing `chart` at every animation frame specified by the given
-         * easing value. If any plugin returns `false`, the frame drawing is cancelled until
-         * another `render` is triggered.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} `false` to cancel the chart drawing.
-         */
-        /**
-         * @method IPlugin#afterDraw
-         * @desc Called after the `chart` has been drawn for the specific easing value. Note
-         * that this hook will not be called if the drawing has been previously cancelled.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeDatasetsDraw
-         * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,
-         * the datasets drawing is cancelled until another `render` is triggered.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} `false` to cancel the chart datasets drawing.
-         */
-        /**
-         * @method IPlugin#afterDatasetsDraw
-         * @desc Called after the `chart` datasets have been drawn. Note that this hook
-         * will not be called if the datasets drawing has been previously cancelled.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeDatasetDraw
-         * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets
-         * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing
-         * is cancelled until another `render` is triggered.
-         * @param {Chart} chart - The chart instance.
-         * @param {Object} args - The call arguments.
-         * @param {Object} args.index - The dataset index.
-         * @param {Number} args.meta - The dataset metadata.
-         * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
-         * @param {Object} options - The plugin options.
-         * @returns {Boolean} `false` to cancel the chart datasets drawing.
-         */
-        /**
-         * @method IPlugin#afterDatasetDraw
-         * @desc Called after the `chart` datasets at the given `args.index` have been drawn
-         * (datasets are drawn in the reverse order). Note that this hook will not be called
-         * if the datasets drawing has been previously cancelled.
-         * @param {Chart} chart - The chart instance.
-         * @param {Object} args - The call arguments.
-         * @param {Object} args.index - The dataset index.
-         * @param {Number} args.meta - The dataset metadata.
-         * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#beforeEvent
-         * @desc Called before processing the specified `event`. If any plugin returns `false`,
-         * the event will be discarded.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {IEvent} event - The event object.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#afterEvent
-         * @desc Called after the `event` has been consumed. Note that this hook
-         * will not be called if the `event` has been previously discarded.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {IEvent} event - The event object.
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#resize
-         * @desc Called after the chart as been resized.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Number} size - The new canvas display size (eq. canvas.style width & height).
-         * @param {Object} options - The plugin options.
-         */
-        /**
-         * @method IPlugin#destroy
-         * @desc Called after the chart as been destroyed.
-         * @param {Chart.Controller} chart - The chart instance.
-         * @param {Object} options - The plugin options.
-         */
-
-        /**
-         * Provided for backward compatibility, use Chart.plugins instead
-         * @namespace Chart.pluginService
-         * @deprecated since version 2.1.5
-         * @todo remove at version 3
-         * @private
-         */
-        Chart.pluginService = Chart.plugins;
-
-        /**
-         * Provided for backward compatibility, inheriting from Chart.PlugingBase has no
-         * effect, instead simply create/register plugins via plain JavaScript objects.
-         * @interface Chart.PluginBase
-         * @deprecated since version 2.5.0
-         * @todo remove at version 3
-         * @private
-         */
-        Chart.PluginBase = Chart.Element.extend({});
-    };
-
-},{}],31:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.defaults.scale = {
-            display: true,
-            position: 'left',
-
-            // grid line settings
-            gridLines: {
-                display: true,
-                color: 'rgba(0, 0, 0, 0.1)',
-                lineWidth: 1,
-                drawBorder: true,
-                drawOnChartArea: true,
-                drawTicks: true,
-                tickMarkLength: 10,
-                zeroLineWidth: 1,
-                zeroLineColor: 'rgba(0,0,0,0.25)',
-                zeroLineBorderDash: [],
-                zeroLineBorderDashOffset: 0.0,
-                offsetGridLines: false,
-                borderDash: [],
-                borderDashOffset: 0.0
-            },
-
-            // scale label
-            scaleLabel: {
-                // actual label
-                labelString: '',
-
-                // display property
-                display: false
-            },
-
-            // label settings
-            ticks: {
-                beginAtZero: false,
-                minRotation: 0,
-                maxRotation: 50,
-                mirror: false,
-                padding: 0,
-                reverse: false,
-                display: true,
-                autoSkip: true,
-                autoSkipPadding: 0,
-                labelOffset: 0,
-                // We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
-                callback: Chart.Ticks.formatters.values
-            }
-        };
-
-        function computeTextSize(context, tick, font) {
-            return helpers.isArray(tick) ?
-                helpers.longestText(context, font, tick) :
-                context.measureText(tick).width;
-        }
-
-        function parseFontOptions(options) {
-            var getValueOrDefault = helpers.getValueOrDefault;
-            var globalDefaults = Chart.defaults.global;
-            var size = getValueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
-            var style = getValueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);
-            var family = getValueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);
-
-            return {
-                size: size,
-                style: style,
-                family: family,
-                font: helpers.fontString(size, style, family)
-            };
-        }
-
-        Chart.Scale = Chart.Element.extend({
-            /**
-             * Get the padding needed for the scale
-             * @method getPadding
-             * @private
-             * @returns {Padding} the necessary padding
-             */
-            getPadding: function() {
-                var me = this;
-                return {
-                    left: me.paddingLeft || 0,
-                    top: me.paddingTop || 0,
-                    right: me.paddingRight || 0,
-                    bottom: me.paddingBottom || 0
-                };
-            },
-
-            // These methods are ordered by lifecyle. Utilities then follow.
-            // Any function defined here is inherited by all scale types.
-            // Any function can be extended by the scale type
-
-            beforeUpdate: function() {
-                helpers.callback(this.options.beforeUpdate, [this]);
-            },
-            update: function(maxWidth, maxHeight, margins) {
-                var me = this;
-
-                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-                me.beforeUpdate();
-
-                // Absorb the master measurements
-                me.maxWidth = maxWidth;
-                me.maxHeight = maxHeight;
-                me.margins = helpers.extend({
-                    left: 0,
-                    right: 0,
-                    top: 0,
-                    bottom: 0
-                }, margins);
-                me.longestTextCache = me.longestTextCache || {};
-
-                // Dimensions
-                me.beforeSetDimensions();
-                me.setDimensions();
-                me.afterSetDimensions();
-
-                // Data min/max
-                me.beforeDataLimits();
-                me.determineDataLimits();
-                me.afterDataLimits();
-
-                // Ticks
-                me.beforeBuildTicks();
-                me.buildTicks();
-                me.afterBuildTicks();
-
-                me.beforeTickToLabelConversion();
-                me.convertTicksToLabels();
-                me.afterTickToLabelConversion();
-
-                // Tick Rotation
-                me.beforeCalculateTickRotation();
-                me.calculateTickRotation();
-                me.afterCalculateTickRotation();
-                // Fit
-                me.beforeFit();
-                me.fit();
-                me.afterFit();
-                //
-                me.afterUpdate();
-
-                return me.minSize;
-
-            },
-            afterUpdate: function() {
-                helpers.callback(this.options.afterUpdate, [this]);
-            },
-
-            //
-
-            beforeSetDimensions: function() {
-                helpers.callback(this.options.beforeSetDimensions, [this]);
-            },
-            setDimensions: function() {
-                var me = this;
-                // Set the unconstrained dimension before label rotation
-                if (me.isHorizontal()) {
-                    // Reset position before calculating rotation
-                    me.width = me.maxWidth;
-                    me.left = 0;
-                    me.right = me.width;
-                } else {
-                    me.height = me.maxHeight;
-
-                    // Reset position before calculating rotation
-                    me.top = 0;
-                    me.bottom = me.height;
-                }
-
-                // Reset padding
-                me.paddingLeft = 0;
-                me.paddingTop = 0;
-                me.paddingRight = 0;
-                me.paddingBottom = 0;
-            },
-            afterSetDimensions: function() {
-                helpers.callback(this.options.afterSetDimensions, [this]);
-            },
-
-            // Data limits
-            beforeDataLimits: function() {
-                helpers.callback(this.options.beforeDataLimits, [this]);
-            },
-            determineDataLimits: helpers.noop,
-            afterDataLimits: function() {
-                helpers.callback(this.options.afterDataLimits, [this]);
-            },
-
-            //
-            beforeBuildTicks: function() {
-                helpers.callback(this.options.beforeBuildTicks, [this]);
-            },
-            buildTicks: helpers.noop,
-            afterBuildTicks: function() {
-                helpers.callback(this.options.afterBuildTicks, [this]);
-            },
-
-            beforeTickToLabelConversion: function() {
-                helpers.callback(this.options.beforeTickToLabelConversion, [this]);
-            },
-            convertTicksToLabels: function() {
-                var me = this;
-                // Convert ticks to strings
-                var tickOpts = me.options.ticks;
-                me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback);
-            },
-            afterTickToLabelConversion: function() {
-                helpers.callback(this.options.afterTickToLabelConversion, [this]);
-            },
-
-            //
-
-            beforeCalculateTickRotation: function() {
-                helpers.callback(this.options.beforeCalculateTickRotation, [this]);
-            },
-            calculateTickRotation: function() {
-                var me = this;
-                var context = me.ctx;
-                var tickOpts = me.options.ticks;
-
-                // Get the width of each grid by calculating the difference
-                // between x offsets between 0 and 1.
-                var tickFont = parseFontOptions(tickOpts);
-                context.font = tickFont.font;
-
-                var labelRotation = tickOpts.minRotation || 0;
-
-                if (me.options.display && me.isHorizontal()) {
-                    var originalLabelWidth = helpers.longestText(context, tickFont.font, me.ticks, me.longestTextCache);
-                    var labelWidth = originalLabelWidth;
-                    var cosRotation;
-                    var sinRotation;
-
-                    // Allow 3 pixels x2 padding either side for label readability
-                    var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
-
-                    // Max label rotation can be set or default to 90 - also act as a loop counter
-                    while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {
-                        var angleRadians = helpers.toRadians(labelRotation);
-                        cosRotation = Math.cos(angleRadians);
-                        sinRotation = Math.sin(angleRadians);
-
-                        if (sinRotation * originalLabelWidth > me.maxHeight) {
-                            // go back one step
-                            labelRotation--;
-                            break;
-                        }
-
-                        labelRotation++;
-                        labelWidth = cosRotation * originalLabelWidth;
-                    }
-                }
-
-                me.labelRotation = labelRotation;
-            },
-            afterCalculateTickRotation: function() {
-                helpers.callback(this.options.afterCalculateTickRotation, [this]);
-            },
-
-            //
-
-            beforeFit: function() {
-                helpers.callback(this.options.beforeFit, [this]);
-            },
-            fit: function() {
-                var me = this;
-                // Reset
-                var minSize = me.minSize = {
-                    width: 0,
-                    height: 0
-                };
-
-                var opts = me.options;
-                var tickOpts = opts.ticks;
-                var scaleLabelOpts = opts.scaleLabel;
-                var gridLineOpts = opts.gridLines;
-                var display = opts.display;
-                var isHorizontal = me.isHorizontal();
-
-                var tickFont = parseFontOptions(tickOpts);
-                var scaleLabelFontSize = parseFontOptions(scaleLabelOpts).size * 1.5;
-                var tickMarkLength = opts.gridLines.tickMarkLength;
-
-                // Width
-                if (isHorizontal) {
-                    // subtract the margins to line up with the chartArea if we are a full width scale
-                    minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;
-                } else {
-                    minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
-                }
-
-                // height
-                if (isHorizontal) {
-                    minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
-                } else {
-                    minSize.height = me.maxHeight; // fill all the height
-                }
-
-                // Are we showing a title for the scale?
-                if (scaleLabelOpts.display && display) {
-                    if (isHorizontal) {
-                        minSize.height += scaleLabelFontSize;
-                    } else {
-                        minSize.width += scaleLabelFontSize;
-                    }
-                }
-
-                // Don't bother fitting the ticks if we are not showing them
-                if (tickOpts.display && display) {
-                    var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, me.ticks, me.longestTextCache);
-                    var tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);
-                    var lineSpace = tickFont.size * 0.5;
-
-                    if (isHorizontal) {
-                        // A horizontal axis is more constrained by the height.
-                        me.longestLabelWidth = largestTextWidth;
-
-                        var angleRadians = helpers.toRadians(me.labelRotation);
-                        var cosRotation = Math.cos(angleRadians);
-                        var sinRotation = Math.sin(angleRadians);
-
-                        // TODO - improve this calculation
-                        var labelHeight = (sinRotation * largestTextWidth)
-                            + (tickFont.size * tallestLabelHeightInLines)
-                            + (lineSpace * tallestLabelHeightInLines);
-
-                        minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);
-                        me.ctx.font = tickFont.font;
-
-                        var firstTick = me.ticks[0];
-                        var firstLabelWidth = computeTextSize(me.ctx, firstTick, tickFont.font);
-
-                        var lastTick = me.ticks[me.ticks.length - 1];
-                        var lastLabelWidth = computeTextSize(me.ctx, lastTick, tickFont.font);
-
-                        // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated
-                        // by the font height
-                        if (me.labelRotation !== 0) {
-                            me.paddingLeft = opts.position === 'bottom'? (cosRotation * firstLabelWidth) + 3: (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges
-                            me.paddingRight = opts.position === 'bottom'? (cosRotation * lineSpace) + 3: (cosRotation * lastLabelWidth) + 3;
-                        } else {
-                            me.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
-                            me.paddingRight = lastLabelWidth / 2 + 3;
-                        }
-                    } else {
-                        // A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first
-                        // Account for padding
-
-                        if (tickOpts.mirror) {
-                            largestTextWidth = 0;
-                        } else {
-                            largestTextWidth += me.options.ticks.padding;
-                        }
-                        minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);
-                        me.paddingTop = tickFont.size / 2;
-                        me.paddingBottom = tickFont.size / 2;
-                    }
-                }
-
-                me.handleMargins();
-
-                me.width = minSize.width;
-                me.height = minSize.height;
-            },
-
-            /**
-             * Handle margins and padding interactions
-             * @private
-             */
-            handleMargins: function() {
-                var me = this;
-                if (me.margins) {
-                    me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
-                    me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);
-                    me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
-                    me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);
-                }
-            },
-
-            afterFit: function() {
-                helpers.callback(this.options.afterFit, [this]);
-            },
-
-            // Shared Methods
-            isHorizontal: function() {
-                return this.options.position === 'top' || this.options.position === 'bottom';
-            },
-            isFullWidth: function() {
-                return (this.options.fullWidth);
-            },
-
-            // 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
-            getRightValue: function(rawValue) {
-                // Null and undefined values first
-                if (rawValue === null || typeof(rawValue) === 'undefined') {
-                    return NaN;
-                }
-                // isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values
-                if (typeof(rawValue) === 'number' && !isFinite(rawValue)) {
-                    return NaN;
-                }
-                // If it is in fact an object, dive in one more level
-                if (typeof(rawValue) === 'object') {
-                    if ((rawValue instanceof Date) || (rawValue.isValid)) {
-                        return rawValue;
-                    }
-                    return this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
-                }
-
-                // Value is good, return it
-                return rawValue;
-            },
-
-            // Used to get the value to display in the tooltip for the data at the given index
-            // function getLabelForIndex(index, datasetIndex)
-            getLabelForIndex: helpers.noop,
-
-            // Used to get data value locations.  Value can either be an index or a numerical value
-            getPixelForValue: helpers.noop,
-
-            // Used to get the data value from a given pixel. This is the inverse of getPixelForValue
-            getValueForPixel: helpers.noop,
-
-            // Used for tick location, should
-            getPixelForTick: function(index, includeOffset) {
-                var me = this;
-                if (me.isHorizontal()) {
-                    var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-                    var tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
-                    var pixel = (tickWidth * index) + me.paddingLeft;
-
-                    if (includeOffset) {
-                        pixel += tickWidth / 2;
-                    }
-
-                    var finalVal = me.left + Math.round(pixel);
-                    finalVal += me.isFullWidth() ? me.margins.left : 0;
-                    return finalVal;
-                }
-                var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
-                return me.top + (index * (innerHeight / (me.ticks.length - 1)));
-            },
-
-            // Utility for getting the pixel location of a percentage of scale
-            getPixelForDecimal: function(decimal /* , includeOffset*/) {
-                var me = this;
-                if (me.isHorizontal()) {
-                    var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-                    var valueOffset = (innerWidth * decimal) + me.paddingLeft;
-
-                    var finalVal = me.left + Math.round(valueOffset);
-                    finalVal += me.isFullWidth() ? me.margins.left : 0;
-                    return finalVal;
-                }
-                return me.top + (decimal * me.height);
-            },
-
-            getBasePixel: function() {
-                return this.getPixelForValue(this.getBaseValue());
-            },
-
-            getBaseValue: function() {
-                var me = this;
-                var min = me.min;
-                var max = me.max;
-
-                return me.beginAtZero ? 0:
-                    min < 0 && max < 0? max :
-                        min > 0 && max > 0? min :
-                            0;
-            },
-
-            // Actually draw the scale on the canvas
-            // @param {rectangle} chartArea : the area of the chart to draw full grid lines on
-            draw: function(chartArea) {
-                var me = this;
-                var options = me.options;
-                if (!options.display) {
-                    return;
-                }
-
-                var context = me.ctx;
-                var globalDefaults = Chart.defaults.global;
-                var optionTicks = options.ticks;
-                var gridLines = options.gridLines;
-                var scaleLabel = options.scaleLabel;
-
-                var isRotated = me.labelRotation !== 0;
-                var skipRatio;
-                var useAutoskipper = optionTicks.autoSkip;
-                var isHorizontal = me.isHorizontal();
-
-                // figure out the maximum number of gridlines to show
-                var maxTicks;
-                if (optionTicks.maxTicksLimit) {
-                    maxTicks = optionTicks.maxTicksLimit;
-                }
-
-                var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
-                var tickFont = parseFontOptions(optionTicks);
-
-                var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;
-
-                var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
-                var scaleLabelFont = parseFontOptions(scaleLabel);
-
-                var labelRotationRadians = helpers.toRadians(me.labelRotation);
-                var cosRotation = Math.cos(labelRotationRadians);
-                var longestRotatedLabel = me.longestLabelWidth * cosRotation;
-
-                // Make sure we draw text in the correct color and font
-                context.fillStyle = tickFontColor;
-
-                var itemsToDraw = [];
-
-                if (isHorizontal) {
-                    skipRatio = false;
-
-                    if ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {
-                        skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));
-                    }
-
-                    // if they defined a max number of optionTicks,
-                    // increase skipRatio until that number is met
-                    if (maxTicks && me.ticks.length > maxTicks) {
-                        while (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {
-                            if (!skipRatio) {
-                                skipRatio = 1;
-                            }
-                            skipRatio += 1;
-                        }
-                    }
-
-                    if (!useAutoskipper) {
-                        skipRatio = false;
-                    }
-                }
-
-
-                var xTickStart = options.position === 'right' ? me.left : me.right - tl;
-                var xTickEnd = options.position === 'right' ? me.left + tl : me.right;
-                var yTickStart = options.position === 'bottom' ? me.top : me.bottom - tl;
-                var yTickEnd = options.position === 'bottom' ? me.top + tl : me.bottom;
-
-                helpers.each(me.ticks, function(label, index) {
-                    // If the callback returned a null or undefined value, do not draw this line
-                    if (label === undefined || label === null) {
-                        return;
-                    }
-
-                    var isLastTick = me.ticks.length === index + 1;
-
-                    // Since we always show the last tick,we need may need to hide the last shown one before
-                    var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);
-                    if (shouldSkip && !isLastTick || (label === undefined || label === null)) {
-                        return;
-                    }
-
-                    var lineWidth, lineColor, borderDash, borderDashOffset;
-                    if (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {
-                        // Draw the first index specially
-                        lineWidth = gridLines.zeroLineWidth;
-                        lineColor = gridLines.zeroLineColor;
-                        borderDash = gridLines.zeroLineBorderDash;
-                        borderDashOffset = gridLines.zeroLineBorderDashOffset;
-                    } else {
-                        lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);
-                        lineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);
-                        borderDash = helpers.getValueOrDefault(gridLines.borderDash, globalDefaults.borderDash);
-                        borderDashOffset = helpers.getValueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);
-                    }
-
-                    // Common properties
-                    var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
-                    var textAlign = 'middle';
-                    var textBaseline = 'middle';
-
-                    if (isHorizontal) {
-
-                        if (options.position === 'bottom') {
-                            // bottom
-                            textBaseline = !isRotated? 'top':'middle';
-                            textAlign = !isRotated? 'center': 'right';
-                            labelY = me.top + tl;
-                        } else {
-                            // top
-                            textBaseline = !isRotated? 'bottom':'middle';
-                            textAlign = !isRotated? 'center': 'left';
-                            labelY = me.bottom - tl;
-                        }
-
-                        var xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines
-                        labelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)
-
-                        tx1 = tx2 = x1 = x2 = xLineValue;
-                        ty1 = yTickStart;
-                        ty2 = yTickEnd;
-                        y1 = chartArea.top;
-                        y2 = chartArea.bottom;
-                    } else {
-                        var isLeft = options.position === 'left';
-                        var tickPadding = optionTicks.padding;
-                        var labelXOffset;
-
-                        if (optionTicks.mirror) {
-                            textAlign = isLeft ? 'left' : 'right';
-                            labelXOffset = tickPadding;
-                        } else {
-                            textAlign = isLeft ? 'right' : 'left';
-                            labelXOffset = tl + tickPadding;
-                        }
-
-                        labelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;
-
-                        var yLineValue = me.getPixelForTick(index); // xvalues for grid lines
-                        yLineValue += helpers.aliasPixel(lineWidth);
-                        labelY = me.getPixelForTick(index, gridLines.offsetGridLines);
-
-                        tx1 = xTickStart;
-                        tx2 = xTickEnd;
-                        x1 = chartArea.left;
-                        x2 = chartArea.right;
-                        ty1 = ty2 = y1 = y2 = yLineValue;
-                    }
-
-                    itemsToDraw.push({
-                        tx1: tx1,
-                        ty1: ty1,
-                        tx2: tx2,
-                        ty2: ty2,
-                        x1: x1,
-                        y1: y1,
-                        x2: x2,
-                        y2: y2,
-                        labelX: labelX,
-                        labelY: labelY,
-                        glWidth: lineWidth,
-                        glColor: lineColor,
-                        glBorderDash: borderDash,
-                        glBorderDashOffset: borderDashOffset,
-                        rotation: -1 * labelRotationRadians,
-                        label: label,
-                        textBaseline: textBaseline,
-                        textAlign: textAlign
-                    });
-                });
-
-                // Draw all of the tick labels, tick marks, and grid lines at the correct places
-                helpers.each(itemsToDraw, function(itemToDraw) {
-                    if (gridLines.display) {
-                        context.save();
-                        context.lineWidth = itemToDraw.glWidth;
-                        context.strokeStyle = itemToDraw.glColor;
-                        if (context.setLineDash) {
-                            context.setLineDash(itemToDraw.glBorderDash);
-                            context.lineDashOffset = itemToDraw.glBorderDashOffset;
-                        }
-
-                        context.beginPath();
-
-                        if (gridLines.drawTicks) {
-                            context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
-                            context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
-                        }
-
-                        if (gridLines.drawOnChartArea) {
-                            context.moveTo(itemToDraw.x1, itemToDraw.y1);
-                            context.lineTo(itemToDraw.x2, itemToDraw.y2);
-                        }
-
-                        context.stroke();
-                        context.restore();
-                    }
-
-                    if (optionTicks.display) {
-                        context.save();
-                        context.translate(itemToDraw.labelX, itemToDraw.labelY);
-                        context.rotate(itemToDraw.rotation);
-                        context.font = tickFont.font;
-                        context.textBaseline = itemToDraw.textBaseline;
-                        context.textAlign = itemToDraw.textAlign;
-
-                        var label = itemToDraw.label;
-                        if (helpers.isArray(label)) {
-                            for (var i = 0, y = 0; i < label.length; ++i) {
-                                // We just make sure the multiline element is a string here..
-                                context.fillText('' + label[i], 0, y);
-                                // apply same lineSpacing as calculated @ L#320
-                                y += (tickFont.size * 1.5);
-                            }
-                        } else {
-                            context.fillText(label, 0, 0);
-                        }
-                        context.restore();
-                    }
-                });
-
-                if (scaleLabel.display) {
-                    // Draw the scale label
-                    var scaleLabelX;
-                    var scaleLabelY;
-                    var rotation = 0;
-
-                    if (isHorizontal) {
-                        scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
-                        scaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFont.size / 2) : me.top + (scaleLabelFont.size / 2);
-                    } else {
-                        var isLeft = options.position === 'left';
-                        scaleLabelX = isLeft ? me.left + (scaleLabelFont.size / 2) : me.right - (scaleLabelFont.size / 2);
-                        scaleLabelY = me.top + ((me.bottom - me.top) / 2);
-                        rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
-                    }
-
-                    context.save();
-                    context.translate(scaleLabelX, scaleLabelY);
-                    context.rotate(rotation);
-                    context.textAlign = 'center';
-                    context.textBaseline = 'middle';
-                    context.fillStyle = scaleLabelFontColor; // render in correct colour
-                    context.font = scaleLabelFont.font;
-                    context.fillText(scaleLabel.labelString, 0, 0);
-                    context.restore();
-                }
-
-                if (gridLines.drawBorder) {
-                    // Draw the line at the edge of the axis
-                    context.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);
-                    context.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);
-                    var x1 = me.left,
-                        x2 = me.right,
-                        y1 = me.top,
-                        y2 = me.bottom;
-
-                    var aliasPixel = helpers.aliasPixel(context.lineWidth);
-                    if (isHorizontal) {
-                        y1 = y2 = options.position === 'top' ? me.bottom : me.top;
-                        y1 += aliasPixel;
-                        y2 += aliasPixel;
-                    } else {
-                        x1 = x2 = options.position === 'left' ? me.right : me.left;
-                        x1 += aliasPixel;
-                        x2 += aliasPixel;
-                    }
-
-                    context.beginPath();
-                    context.moveTo(x1, y1);
-                    context.lineTo(x2, y2);
-                    context.stroke();
-                }
-            }
-        });
-    };
-
-},{}],32:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        Chart.scaleService = {
-            // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
-            // use the new chart options to grab the correct scale
-            constructors: {},
-            // Use a registration function so that we can move to an ES6 map when we no longer need to support
-            // old browsers
-
-            // Scale config defaults
-            defaults: {},
-            registerScaleType: function(type, scaleConstructor, defaults) {
-                this.constructors[type] = scaleConstructor;
-                this.defaults[type] = helpers.clone(defaults);
-            },
-            getScaleConstructor: function(type) {
-                return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
-            },
-            getScaleDefaults: function(type) {
-                // Return the scale defaults merged with the global settings so that we always use the latest ones
-                return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};
-            },
-            updateScaleDefaults: function(type, additions) {
-                var defaults = this.defaults;
-                if (defaults.hasOwnProperty(type)) {
-                    defaults[type] = helpers.extend(defaults[type], additions);
-                }
-            },
-            addScalesToLayout: function(chart) {
-                // Adds each scale to the chart.boxes array to be sized accordingly
-                helpers.each(chart.scales, function(scale) {
-                    // Set ILayoutItem parameters for backwards compatibility
-                    scale.fullWidth = scale.options.fullWidth;
-                    scale.position = scale.options.position;
-                    scale.weight = scale.options.weight;
-                    Chart.layoutService.addBox(chart, scale);
-                });
-            }
-        };
-    };
-
-},{}],33:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        /**
-         * Namespace to hold static tick generation functions
-         * @namespace Chart.Ticks
-         */
-        Chart.Ticks = {
-            /**
-             * Namespace to hold generators for different types of ticks
-             * @namespace Chart.Ticks.generators
-             */
-            generators: {
-                /**
-                 * Interface for the options provided to the numeric tick generator
-                 * @interface INumericTickGenerationOptions
-                 */
-                /**
-                 * The maximum number of ticks to display
-                 * @name INumericTickGenerationOptions#maxTicks
-                 * @type Number
-                 */
-                /**
-                 * The distance between each tick.
-                 * @name INumericTickGenerationOptions#stepSize
-                 * @type Number
-                 * @optional
-                 */
-                /**
-                 * Forced minimum for the ticks. If not specified, the minimum of the data range is used to calculate the tick minimum
-                 * @name INumericTickGenerationOptions#min
-                 * @type Number
-                 * @optional
-                 */
-                /**
-                 * The maximum value of the ticks. If not specified, the maximum of the data range is used to calculate the tick maximum
-                 * @name INumericTickGenerationOptions#max
-                 * @type Number
-                 * @optional
-                 */
-
-                /**
-                 * Generate a set of linear ticks
-                 * @method Chart.Ticks.generators.linear
-                 * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks
-                 * @param dataRange {IRange} the range of the data
-                 * @returns {Array<Number>} array of tick values
-                 */
-                linear: function(generationOptions, dataRange) {
-                    var ticks = [];
-                    // To get a "nice" value for the tick spacing, we will use the appropriately named
-                    // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
-                    // for details.
-
-                    var spacing;
-                    if (generationOptions.stepSize && generationOptions.stepSize > 0) {
-                        spacing = generationOptions.stepSize;
-                    } else {
-                        var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);
-                        spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);
-                    }
-                    var niceMin = Math.floor(dataRange.min / spacing) * spacing;
-                    var niceMax = Math.ceil(dataRange.max / spacing) * spacing;
-
-                    // If min, max and stepSize is set and they make an evenly spaced scale use it.
-                    if (generationOptions.min && generationOptions.max && generationOptions.stepSize) {
-                        // If very close to our whole number, use it.
-                        if (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {
-                            niceMin = generationOptions.min;
-                            niceMax = generationOptions.max;
-                        }
-                    }
-
-                    var numSpaces = (niceMax - niceMin) / spacing;
-                    // If very close to our rounded value, use it.
-                    if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
-                        numSpaces = Math.round(numSpaces);
-                    } else {
-                        numSpaces = Math.ceil(numSpaces);
-                    }
-
-                    // Put the values into the ticks array
-                    ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);
-                    for (var j = 1; j < numSpaces; ++j) {
-                        ticks.push(niceMin + (j * spacing));
-                    }
-                    ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);
-
-                    return ticks;
-                },
-
-                /**
-                 * Generate a set of logarithmic ticks
-                 * @method Chart.Ticks.generators.logarithmic
-                 * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks
-                 * @param dataRange {IRange} the range of the data
-                 * @returns {Array<Number>} array of tick values
-                 */
-                logarithmic: function(generationOptions, dataRange) {
-                    var ticks = [];
-                    var getValueOrDefault = helpers.getValueOrDefault;
-
-                    // Figure out what the max number of ticks we can support it is based on the size of
-                    // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
-                    // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
-                    // the graph
-                    var tickVal = getValueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));
-
-                    var endExp = Math.floor(helpers.log10(dataRange.max));
-                    var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
-                    var exp;
-                    var significand;
-
-                    if (tickVal === 0) {
-                        exp = Math.floor(helpers.log10(dataRange.minNotZero));
-                        significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
-
-                        ticks.push(tickVal);
-                        tickVal = significand * Math.pow(10, exp);
-                    } else {
-                        exp = Math.floor(helpers.log10(tickVal));
-                        significand = Math.floor(tickVal / Math.pow(10, exp));
-                    }
-
-                    do {
-                        ticks.push(tickVal);
-
-                        ++significand;
-                        if (significand === 10) {
-                            significand = 1;
-                            ++exp;
-                        }
-
-                        tickVal = significand * Math.pow(10, exp);
-                    } while (exp < endExp || (exp === endExp && significand < endSignificand));
-
-                    var lastTick = getValueOrDefault(generationOptions.max, tickVal);
-                    ticks.push(lastTick);
-
-                    return ticks;
-                }
-            },
-
-            /**
-             * Namespace to hold formatters for different types of ticks
-             * @namespace Chart.Ticks.formatters
-             */
-            formatters: {
-                /**
-                 * Formatter for value labels
-                 * @method Chart.Ticks.formatters.values
-                 * @param value the value to display
-                 * @return {String|Array} the label to display
-                 */
-                values: function(value) {
-                    return helpers.isArray(value) ? value : '' + value;
-                },
-
-                /**
-                 * Formatter for linear numeric ticks
-                 * @method Chart.Ticks.formatters.linear
-                 * @param tickValue {Number} the value to be formatted
-                 * @param index {Number} the position of the tickValue parameter in the ticks array
-                 * @param ticks {Array<Number>} the list of ticks being converted
-                 * @return {String} string representation of the tickValue parameter
-                 */
-                linear: function(tickValue, index, ticks) {
-                    // If we have lots of ticks, don't use the ones
-                    var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
-
-                    // If we have a number like 2.5 as the delta, figure out how many decimal places we need
-                    if (Math.abs(delta) > 1) {
-                        if (tickValue !== Math.floor(tickValue)) {
-                            // not an integer
-                            delta = tickValue - Math.floor(tickValue);
-                        }
-                    }
-
-                    var logDelta = helpers.log10(Math.abs(delta));
-                    var tickString = '';
-
-                    if (tickValue !== 0) {
-                        var numDecimal = -1 * Math.floor(logDelta);
-                        numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
-                        tickString = tickValue.toFixed(numDecimal);
-                    } else {
-                        tickString = '0'; // never show decimal places for 0
-                    }
-
-                    return tickString;
-                },
-
-                logarithmic: function(tickValue, index, ticks) {
-                    var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
-
-                    if (tickValue === 0) {
-                        return '0';
-                    } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {
-                        return tickValue.toExponential();
-                    }
-                    return '';
-                }
-            }
-        };
-    };
-
-},{}],34:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        /**
-         * Helper method to merge the opacity into a color
-         */
-        function mergeOpacity(colorString, opacity) {
-            var color = helpers.color(colorString);
-            return color.alpha(opacity * color.alpha()).rgbaString();
-        }
-
-        Chart.defaults.global.tooltips = {
-            enabled: true,
-            custom: null,
-            mode: 'nearest',
-            position: 'average',
-            intersect: true,
-            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,
-            caretPadding: 2,
-            caretSize: 5,
-            cornerRadius: 6,
-            multiKeyBackground: '#fff',
-            displayColors: true,
-            borderColor: 'rgba(0,0,0,0)',
-            borderWidth: 0,
-            callbacks: {
-                // Args are: (tooltipItems, data)
-                beforeTitle: helpers.noop,
-                title: function(tooltipItems, data) {
-                    // Pick first xLabel for now
-                    var title = '';
-                    var labels = data.labels;
-                    var labelCount = labels ? labels.length : 0;
-
-                    if (tooltipItems.length > 0) {
-                        var item = tooltipItems[0];
-
-                        if (item.xLabel) {
-                            title = item.xLabel;
-                        } else if (labelCount > 0 && item.index < labelCount) {
-                            title = labels[item.index];
-                        }
-                    }
-
-                    return title;
-                },
-                afterTitle: helpers.noop,
-
-                // Args are: (tooltipItems, data)
-                beforeBody: helpers.noop,
-
-                // Args are: (tooltipItem, data)
-                beforeLabel: helpers.noop,
-                label: function(tooltipItem, data) {
-                    var label = data.datasets[tooltipItem.datasetIndex].label || '';
-
-                    if (label) {
-                        label += ': ';
-                    }
-                    label += tooltipItem.yLabel;
-                    return label;
-                },
-                labelColor: function(tooltipItem, chart) {
-                    var meta = chart.getDatasetMeta(tooltipItem.datasetIndex);
-                    var activeElement = meta.data[tooltipItem.index];
-                    var view = activeElement._view;
-                    return {
-                        borderColor: view.borderColor,
-                        backgroundColor: view.backgroundColor
-                    };
-                },
-                afterLabel: helpers.noop,
-
-                // Args are: (tooltipItems, data)
-                afterBody: helpers.noop,
-
-                // Args are: (tooltipItems, data)
-                beforeFooter: helpers.noop,
-                footer: helpers.noop,
-                afterFooter: helpers.noop
-            }
-        };
-
-        // Helper to push or concat based on if the 2nd parameter is an array or not
-        function pushOrConcat(base, toPush) {
-            if (toPush) {
-                if (helpers.isArray(toPush)) {
-                    // base = base.concat(toPush);
-                    Array.prototype.push.apply(base, toPush);
-                } else {
-                    base.push(toPush);
-                }
-            }
-
-            return base;
-        }
-
-        // Private helper to create a tooltip item model
-        // @param element : the chart element (point, arc, bar) to create the tooltip item for
-        // @return : new tooltip item
-        function createTooltipItem(element) {
-            var xScale = element._xScale;
-            var yScale = element._yScale || element._scale; // handle radar || polarArea charts
-            var index = element._index,
-                datasetIndex = element._datasetIndex;
-
-            return {
-                xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
-                yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
-                index: index,
-                datasetIndex: datasetIndex,
-                x: element._model.x,
-                y: element._model.y
-            };
-        }
-
-        /**
-         * Helper to get the reset model for the tooltip
-         * @param tooltipOpts {Object} the tooltip options
-         */
-        function getBaseModel(tooltipOpts) {
-            var globalDefaults = Chart.defaults.global;
-            var getValueOrDefault = helpers.getValueOrDefault;
-
-            return {
-                // Positioning
-                xPadding: tooltipOpts.xPadding,
-                yPadding: tooltipOpts.yPadding,
-                xAlign: tooltipOpts.xAlign,
-                yAlign: tooltipOpts.yAlign,
-
-                // Body
-                bodyFontColor: tooltipOpts.bodyFontColor,
-                _bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
-                _bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
-                _bodyAlign: tooltipOpts.bodyAlign,
-                bodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
-                bodySpacing: tooltipOpts.bodySpacing,
-
-                // Title
-                titleFontColor: tooltipOpts.titleFontColor,
-                _titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
-                _titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
-                titleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
-                _titleAlign: tooltipOpts.titleAlign,
-                titleSpacing: tooltipOpts.titleSpacing,
-                titleMarginBottom: tooltipOpts.titleMarginBottom,
-
-                // Footer
-                footerFontColor: tooltipOpts.footerFontColor,
-                _footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
-                _footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
-                footerFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
-                _footerAlign: tooltipOpts.footerAlign,
-                footerSpacing: tooltipOpts.footerSpacing,
-                footerMarginTop: tooltipOpts.footerMarginTop,
-
-                // Appearance
-                caretSize: tooltipOpts.caretSize,
-                cornerRadius: tooltipOpts.cornerRadius,
-                backgroundColor: tooltipOpts.backgroundColor,
-                opacity: 0,
-                legendColorBackground: tooltipOpts.multiKeyBackground,
-                displayColors: tooltipOpts.displayColors,
-                borderColor: tooltipOpts.borderColor,
-                borderWidth: tooltipOpts.borderWidth
-            };
-        }
-
-        /**
-         * Get the size of the tooltip
-         */
-        function getTooltipSize(tooltip, model) {
-            var ctx = tooltip._chart.ctx;
-
-            var height = model.yPadding * 2; // Tooltip Padding
-            var width = 0;
-
-            // Count of all lines in the body
-            var body = model.body;
-            var combinedBodyLength = body.reduce(function(count, bodyItem) {
-                return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
-            }, 0);
-            combinedBodyLength += model.beforeBody.length + model.afterBody.length;
-
-            var titleLineCount = model.title.length;
-            var footerLineCount = model.footer.length;
-            var titleFontSize = model.titleFontSize,
-                bodyFontSize = model.bodyFontSize,
-                footerFontSize = model.footerFontSize;
-
-            height += titleLineCount * titleFontSize; // Title Lines
-            height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing
-            height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin
-            height += combinedBodyLength * bodyFontSize; // Body Lines
-            height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing
-            height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin
-            height += footerLineCount * (footerFontSize); // Footer Lines
-            height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing
-
-            // Title width
-            var widthPadding = 0;
-            var maxLineWidth = function(line) {
-                width = Math.max(width, ctx.measureText(line).width + widthPadding);
-            };
-
-            ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
-            helpers.each(model.title, maxLineWidth);
-
-            // Body width
-            ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
-            helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);
-
-            // Body lines may include some extra width due to the color box
-            widthPadding = model.displayColors ? (bodyFontSize + 2) : 0;
-            helpers.each(body, function(bodyItem) {
-                helpers.each(bodyItem.before, maxLineWidth);
-                helpers.each(bodyItem.lines, maxLineWidth);
-                helpers.each(bodyItem.after, maxLineWidth);
-            });
-
-            // Reset back to 0
-            widthPadding = 0;
-
-            // Footer width
-            ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
-            helpers.each(model.footer, maxLineWidth);
-
-            // Add padding
-            width += 2 * model.xPadding;
-
-            return {
-                width: width,
-                height: height
-            };
-        }
-
-        /**
-         * Helper to get the alignment of a tooltip given the size
-         */
-        function determineAlignment(tooltip, size) {
-            var model = tooltip._model;
-            var chart = tooltip._chart;
-            var chartArea = tooltip._chart.chartArea;
-            var xAlign = 'center';
-            var yAlign = 'center';
-
-            if (model.y < size.height) {
-                yAlign = 'top';
-            } else if (model.y > (chart.height - size.height)) {
-                yAlign = 'bottom';
-            }
-
-            var lf, rf; // functions to determine left, right alignment
-            var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
-            var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
-            var midX = (chartArea.left + chartArea.right) / 2;
-            var midY = (chartArea.top + chartArea.bottom) / 2;
-
-            if (yAlign === 'center') {
-                lf = function(x) {
-                    return x <= midX;
-                };
-                rf = function(x) {
-                    return x > midX;
-                };
-            } else {
-                lf = function(x) {
-                    return x <= (size.width / 2);
-                };
-                rf = function(x) {
-                    return x >= (chart.width - (size.width / 2));
-                };
-            }
-
-            olf = function(x) {
-                return x + size.width > chart.width;
-            };
-            orf = function(x) {
-                return x - size.width < 0;
-            };
-            yf = function(y) {
-                return y <= midY ? 'top' : 'bottom';
-            };
-
-            if (lf(model.x)) {
-                xAlign = 'left';
-
-                // Is tooltip too wide and goes over the right side of the chart.?
-                if (olf(model.x)) {
-                    xAlign = 'center';
-                    yAlign = yf(model.y);
-                }
-            } else if (rf(model.x)) {
-                xAlign = 'right';
-
-                // Is tooltip too wide and goes outside left edge of canvas?
-                if (orf(model.x)) {
-                    xAlign = 'center';
-                    yAlign = yf(model.y);
-                }
-            }
-
-            var opts = tooltip._options;
-            return {
-                xAlign: opts.xAlign ? opts.xAlign : xAlign,
-                yAlign: opts.yAlign ? opts.yAlign : yAlign
-            };
-        }
-
-        /**
-         * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment
-         */
-        function getBackgroundPoint(vm, size, alignment) {
-            // Background Position
-            var x = vm.x;
-            var y = vm.y;
-
-            var caretSize = vm.caretSize,
-                caretPadding = vm.caretPadding,
-                cornerRadius = vm.cornerRadius,
-                xAlign = alignment.xAlign,
-                yAlign = alignment.yAlign,
-                paddingAndSize = caretSize + caretPadding,
-                radiusAndPadding = cornerRadius + caretPadding;
-
-            if (xAlign === 'right') {
-                x -= size.width;
-            } else if (xAlign === 'center') {
-                x -= (size.width / 2);
-            }
-
-            if (yAlign === 'top') {
-                y += paddingAndSize;
-            } else if (yAlign === 'bottom') {
-                y -= size.height + paddingAndSize;
-            } else {
-                y -= (size.height / 2);
-            }
-
-            if (yAlign === 'center') {
-                if (xAlign === 'left') {
-                    x += paddingAndSize;
-                } else if (xAlign === 'right') {
-                    x -= paddingAndSize;
-                }
-            } else if (xAlign === 'left') {
-                x -= radiusAndPadding;
-            } else if (xAlign === 'right') {
-                x += radiusAndPadding;
-            }
-
-            return {
-                x: x,
-                y: y
-            };
-        }
-
-        Chart.Tooltip = Chart.Element.extend({
-            initialize: function() {
-                this._model = getBaseModel(this._options);
-            },
-
-            // Get the title
-            // Args are: (tooltipItem, data)
-            getTitle: function() {
-                var me = this;
-                var opts = me._options;
-                var callbacks = opts.callbacks;
-
-                var beforeTitle = callbacks.beforeTitle.apply(me, arguments),
-                    title = callbacks.title.apply(me, arguments),
-                    afterTitle = callbacks.afterTitle.apply(me, arguments);
-
-                var lines = [];
-                lines = pushOrConcat(lines, beforeTitle);
-                lines = pushOrConcat(lines, title);
-                lines = pushOrConcat(lines, afterTitle);
-
-                return lines;
-            },
-
-            // Args are: (tooltipItem, data)
-            getBeforeBody: function() {
-                var lines = this._options.callbacks.beforeBody.apply(this, arguments);
-                return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
-            },
-
-            // Args are: (tooltipItem, data)
-            getBody: function(tooltipItems, data) {
-                var me = this;
-                var callbacks = me._options.callbacks;
-                var bodyItems = [];
-
-                helpers.each(tooltipItems, function(tooltipItem) {
-                    var bodyItem = {
-                        before: [],
-                        lines: [],
-                        after: []
-                    };
-                    pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));
-                    pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));
-                    pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));
-
-                    bodyItems.push(bodyItem);
-                });
-
-                return bodyItems;
-            },
-
-            // Args are: (tooltipItem, data)
-            getAfterBody: function() {
-                var lines = this._options.callbacks.afterBody.apply(this, arguments);
-                return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
-            },
-
-            // Get the footer and beforeFooter and afterFooter lines
-            // Args are: (tooltipItem, data)
-            getFooter: function() {
-                var me = this;
-                var callbacks = me._options.callbacks;
-
-                var beforeFooter = callbacks.beforeFooter.apply(me, arguments);
-                var footer = callbacks.footer.apply(me, arguments);
-                var afterFooter = callbacks.afterFooter.apply(me, arguments);
-
-                var lines = [];
-                lines = pushOrConcat(lines, beforeFooter);
-                lines = pushOrConcat(lines, footer);
-                lines = pushOrConcat(lines, afterFooter);
-
-                return lines;
-            },
-
-            update: function(changed) {
-                var me = this;
-                var opts = me._options;
-
-                // Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition
-                // that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time
-                // which breaks any animations.
-                var existingModel = me._model;
-                var model = me._model = getBaseModel(opts);
-                var active = me._active;
-
-                var data = me._data;
-
-                // In the case where active.length === 0 we need to keep these at existing values for good animations
-                var alignment = {
-                    xAlign: existingModel.xAlign,
-                    yAlign: existingModel.yAlign
-                };
-                var backgroundPoint = {
-                    x: existingModel.x,
-                    y: existingModel.y
-                };
-                var tooltipSize = {
-                    width: existingModel.width,
-                    height: existingModel.height
-                };
-                var tooltipPosition = {
-                    x: existingModel.caretX,
-                    y: existingModel.caretY
-                };
-
-                var i, len;
-
-                if (active.length) {
-                    model.opacity = 1;
-
-                    var labelColors = [];
-                    tooltipPosition = Chart.Tooltip.positioners[opts.position](active, me._eventPosition);
-
-                    var tooltipItems = [];
-                    for (i = 0, len = active.length; i < len; ++i) {
-                        tooltipItems.push(createTooltipItem(active[i]));
-                    }
-
-                    // If the user provided a filter function, use it to modify the tooltip items
-                    if (opts.filter) {
-                        tooltipItems = tooltipItems.filter(function(a) {
-                            return opts.filter(a, data);
-                        });
-                    }
-
-                    // If the user provided a sorting function, use it to modify the tooltip items
-                    if (opts.itemSort) {
-                        tooltipItems = tooltipItems.sort(function(a, b) {
-                            return opts.itemSort(a, b, data);
-                        });
-                    }
-
-                    // Determine colors for boxes
-                    helpers.each(tooltipItems, function(tooltipItem) {
-                        labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));
-                    });
-
-                    // Build the Text Lines
-                    model.title = me.getTitle(tooltipItems, data);
-                    model.beforeBody = me.getBeforeBody(tooltipItems, data);
-                    model.body = me.getBody(tooltipItems, data);
-                    model.afterBody = me.getAfterBody(tooltipItems, data);
-                    model.footer = me.getFooter(tooltipItems, data);
-
-                    // Initial positioning and colors
-                    model.x = Math.round(tooltipPosition.x);
-                    model.y = Math.round(tooltipPosition.y);
-                    model.caretPadding = opts.caretPadding;
-                    model.labelColors = labelColors;
-
-                    // data points
-                    model.dataPoints = tooltipItems;
-
-                    // We need to determine alignment of the tooltip
-                    tooltipSize = getTooltipSize(this, model);
-                    alignment = determineAlignment(this, tooltipSize);
-                    // Final Size and Position
-                    backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment);
-                } else {
-                    model.opacity = 0;
-                }
-
-                model.xAlign = alignment.xAlign;
-                model.yAlign = alignment.yAlign;
-                model.x = backgroundPoint.x;
-                model.y = backgroundPoint.y;
-                model.width = tooltipSize.width;
-                model.height = tooltipSize.height;
-
-                // Point where the caret on the tooltip points to
-                model.caretX = tooltipPosition.x;
-                model.caretY = tooltipPosition.y;
-
-                me._model = model;
-
-                if (changed && opts.custom) {
-                    opts.custom.call(me, model);
-                }
-
-                return me;
-            },
-            drawCaret: function(tooltipPoint, size) {
-                var ctx = this._chart.ctx;
-                var vm = this._view;
-                var caretPosition = this.getCaretPosition(tooltipPoint, size, vm);
-
-                ctx.lineTo(caretPosition.x1, caretPosition.y1);
-                ctx.lineTo(caretPosition.x2, caretPosition.y2);
-                ctx.lineTo(caretPosition.x3, caretPosition.y3);
-            },
-            getCaretPosition: function(tooltipPoint, size, vm) {
-                var x1, x2, x3;
-                var y1, y2, y3;
-                var caretSize = vm.caretSize;
-                var cornerRadius = vm.cornerRadius;
-                var xAlign = vm.xAlign,
-                    yAlign = vm.yAlign;
-                var ptX = tooltipPoint.x,
-                    ptY = tooltipPoint.y;
-                var width = size.width,
-                    height = size.height;
-
-                if (yAlign === 'center') {
-                    y2 = ptY + (height / 2);
-
-                    if (xAlign === 'left') {
-                        x1 = ptX;
-                        x2 = x1 - caretSize;
-                        x3 = x1;
-
-                        y1 = y2 + caretSize;
-                        y3 = y2 - caretSize;
-                    } else {
-                        x1 = ptX + width;
-                        x2 = x1 + caretSize;
-                        x3 = x1;
-
-                        y1 = y2 - caretSize;
-                        y3 = y2 + caretSize;
-                    }
-                } else {
-                    if (xAlign === 'left') {
-                        x2 = ptX + cornerRadius + (caretSize);
-                        x1 = x2 - caretSize;
-                        x3 = x2 + caretSize;
-                    } else if (xAlign === 'right') {
-                        x2 = ptX + width - cornerRadius - caretSize;
-                        x1 = x2 - caretSize;
-                        x3 = x2 + caretSize;
-                    } else {
-                        x2 = ptX + (width / 2);
-                        x1 = x2 - caretSize;
-                        x3 = x2 + caretSize;
-                    }
-                    if (yAlign === 'top') {
-                        y1 = ptY;
-                        y2 = y1 - caretSize;
-                        y3 = y1;
-                    } else {
-                        y1 = ptY + height;
-                        y2 = y1 + caretSize;
-                        y3 = y1;
-                        // invert drawing order
-                        var tmp = x3;
-                        x3 = x1;
-                        x1 = tmp;
-                    }
-                }
-                return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};
-            },
-            drawTitle: function(pt, vm, ctx, opacity) {
-                var title = vm.title;
-
-                if (title.length) {
-                    ctx.textAlign = vm._titleAlign;
-                    ctx.textBaseline = 'top';
-
-                    var titleFontSize = vm.titleFontSize,
-                        titleSpacing = vm.titleSpacing;
-
-                    ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
-                    ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
-
-                    var i, len;
-                    for (i = 0, len = title.length; i < len; ++i) {
-                        ctx.fillText(title[i], pt.x, pt.y);
-                        pt.y += titleFontSize + titleSpacing; // Line Height and spacing
-
-                        if (i + 1 === title.length) {
-                            pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing
-                        }
-                    }
-                }
-            },
-            drawBody: function(pt, vm, ctx, opacity) {
-                var bodyFontSize = vm.bodyFontSize;
-                var bodySpacing = vm.bodySpacing;
-                var body = vm.body;
-
-                ctx.textAlign = vm._bodyAlign;
-                ctx.textBaseline = 'top';
-
-                var textColor = mergeOpacity(vm.bodyFontColor, opacity);
-                ctx.fillStyle = textColor;
-                ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
-
-                // Before Body
-                var xLinePadding = 0;
-                var fillLineOfText = function(line) {
-                    ctx.fillText(line, pt.x + xLinePadding, pt.y);
-                    pt.y += bodyFontSize + bodySpacing;
-                };
-
-                // Before body lines
-                helpers.each(vm.beforeBody, fillLineOfText);
-
-                var drawColorBoxes = vm.displayColors;
-                xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
-
-                // Draw body lines now
-                helpers.each(body, function(bodyItem, i) {
-                    helpers.each(bodyItem.before, fillLineOfText);
-
-                    helpers.each(bodyItem.lines, function(line) {
-                        // Draw Legend-like boxes if needed
-                        if (drawColorBoxes) {
-                            // Fill a white rect so that colours merge nicely if the opacity is < 1
-                            ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
-                            ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
-
-                            // Border
-                            ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
-                            ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
-
-                            // Inner square
-                            ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
-                            ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
-
-                            ctx.fillStyle = textColor;
-                        }
-
-                        fillLineOfText(line);
-                    });
-
-                    helpers.each(bodyItem.after, fillLineOfText);
-                });
-
-                // Reset back to 0 for after body
-                xLinePadding = 0;
-
-                // After body lines
-                helpers.each(vm.afterBody, fillLineOfText);
-                pt.y -= bodySpacing; // Remove last body spacing
-            },
-            drawFooter: function(pt, vm, ctx, opacity) {
-                var footer = vm.footer;
-
-                if (footer.length) {
-                    pt.y += vm.footerMarginTop;
-
-                    ctx.textAlign = vm._footerAlign;
-                    ctx.textBaseline = 'top';
-
-                    ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
-                    ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
-
-                    helpers.each(footer, function(line) {
-                        ctx.fillText(line, pt.x, pt.y);
-                        pt.y += vm.footerFontSize + vm.footerSpacing;
-                    });
-                }
-            },
-            drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
-                ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
-                ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);
-                ctx.lineWidth = vm.borderWidth;
-                var xAlign = vm.xAlign;
-                var yAlign = vm.yAlign;
-                var x = pt.x;
-                var y = pt.y;
-                var width = tooltipSize.width;
-                var height = tooltipSize.height;
-                var radius = vm.cornerRadius;
-
-                ctx.beginPath();
-                ctx.moveTo(x + radius, y);
-                if (yAlign === 'top') {
-                    this.drawCaret(pt, tooltipSize);
-                }
-                ctx.lineTo(x + width - radius, y);
-                ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
-                if (yAlign === 'center' && xAlign === 'right') {
-                    this.drawCaret(pt, tooltipSize);
-                }
-                ctx.lineTo(x + width, y + height - radius);
-                ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
-                if (yAlign === 'bottom') {
-                    this.drawCaret(pt, tooltipSize);
-                }
-                ctx.lineTo(x + radius, y + height);
-                ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
-                if (yAlign === 'center' && xAlign === 'left') {
-                    this.drawCaret(pt, tooltipSize);
-                }
-                ctx.lineTo(x, y + radius);
-                ctx.quadraticCurveTo(x, y, x + radius, y);
-                ctx.closePath();
-
-                ctx.fill();
-
-                if (vm.borderWidth > 0) {
-                    ctx.stroke();
-                }
-            },
-            draw: function() {
-                var ctx = this._chart.ctx;
-                var vm = this._view;
-
-                if (vm.opacity === 0) {
-                    return;
-                }
-
-                var tooltipSize = {
-                    width: vm.width,
-                    height: vm.height
-                };
-                var pt = {
-                    x: vm.x,
-                    y: vm.y
-                };
-
-                // IE11/Edge does not like very small opacities, so snap to 0
-                var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
-
-                // Truthy/falsey value for empty tooltip
-                var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
-
-                if (this._options.enabled && hasTooltipContent) {
-                    // Draw Background
-                    this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
-
-                    // Draw Title, Body, and Footer
-                    pt.x += vm.xPadding;
-                    pt.y += vm.yPadding;
-
-                    // Titles
-                    this.drawTitle(pt, vm, ctx, opacity);
-
-                    // Body
-                    this.drawBody(pt, vm, ctx, opacity);
-
-                    // Footer
-                    this.drawFooter(pt, vm, ctx, opacity);
-                }
-            },
-
-            /**
-             * Handle an event
-             * @private
-             * @param {IEvent} event - The event to handle
-             * @returns {Boolean} true if the tooltip changed
-             */
-            handleEvent: function(e) {
-                var me = this;
-                var options = me._options;
-                var changed = false;
-
-                me._lastActive = me._lastActive || [];
-
-                // Find Active Elements for tooltips
-                if (e.type === 'mouseout') {
-                    me._active = [];
-                } else {
-                    me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
-                }
-
-                // Remember Last Actives
-                changed = !helpers.arrayEquals(me._active, me._lastActive);
-
-                // If tooltip didn't change, do not handle the target event
-                if (!changed) {
-                    return false;
-                }
-
-                me._lastActive = me._active;
-
-                if (options.enabled || options.custom) {
-                    me._eventPosition = {
-                        x: e.x,
-                        y: e.y
-                    };
-
-                    var model = me._model;
-                    me.update(true);
-                    me.pivot();
-
-                    // See if our tooltip position changed
-                    changed |= (model.x !== me._model.x) || (model.y !== me._model.y);
-                }
-
-                return changed;
-            }
-        });
-
-        /**
-         * @namespace Chart.Tooltip.positioners
-         */
-        Chart.Tooltip.positioners = {
-            /**
-             * Average mode places the tooltip at the average position of the elements shown
-             * @function Chart.Tooltip.positioners.average
-             * @param elements {ChartElement[]} the elements being displayed in the tooltip
-             * @returns {Point} tooltip position
-             */
-            average: function(elements) {
-                if (!elements.length) {
-                    return false;
-                }
-
-                var i, len;
-                var x = 0;
-                var y = 0;
-                var count = 0;
-
-                for (i = 0, len = elements.length; i < len; ++i) {
-                    var el = elements[i];
-                    if (el && el.hasValue()) {
-                        var pos = el.tooltipPosition();
-                        x += pos.x;
-                        y += pos.y;
-                        ++count;
-                    }
-                }
-
-                return {
-                    x: Math.round(x / count),
-                    y: Math.round(y / count)
-                };
-            },
-
-            /**
-             * Gets the tooltip position nearest of the item nearest to the event position
-             * @function Chart.Tooltip.positioners.nearest
-             * @param elements {Chart.Element[]} the tooltip elements
-             * @param eventPosition {Point} the position of the event in canvas coordinates
-             * @returns {Point} the tooltip position
-             */
-            nearest: function(elements, eventPosition) {
-                var x = eventPosition.x;
-                var y = eventPosition.y;
-
-                var nearestElement;
-                var minDistance = Number.POSITIVE_INFINITY;
-                var i, len;
-                for (i = 0, len = elements.length; i < len; ++i) {
-                    var el = elements[i];
-                    if (el && el.hasValue()) {
-                        var center = el.getCenterPoint();
-                        var d = helpers.distanceBetweenPoints(eventPosition, center);
-
-                        if (d < minDistance) {
-                            minDistance = d;
-                            nearestElement = el;
-                        }
-                    }
-                }
-
-                if (nearestElement) {
-                    var tp = nearestElement.tooltipPosition();
-                    x = tp.x;
-                    y = tp.y;
-                }
-
-                return {
-                    x: x,
-                    y: y
-                };
-            }
-        };
-    };
-
-},{}],35:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers,
-            globalOpts = Chart.defaults.global;
-
-        globalOpts.elements.arc = {
-            backgroundColor: globalOpts.defaultColor,
-            borderColor: '#fff',
-            borderWidth: 2
-        };
-
-        Chart.elements.Arc = Chart.Element.extend({
-            inLabelRange: function(mouseX) {
-                var vm = this._view;
-
-                if (vm) {
-                    return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
-                }
-                return false;
-            },
-            inRange: function(chartX, chartY) {
-                var vm = this._view;
-
-                if (vm) {
-                    var pointRelativePosition = helpers.getAngleFromPoint(vm, {
-                            x: chartX,
-                            y: chartY
-                        }),
-                        angle = pointRelativePosition.angle,
-                        distance = pointRelativePosition.distance;
-
-                    // Sanitise angle range
-                    var startAngle = vm.startAngle;
-                    var endAngle = vm.endAngle;
-                    while (endAngle < startAngle) {
-                        endAngle += 2.0 * Math.PI;
-                    }
-                    while (angle > endAngle) {
-                        angle -= 2.0 * Math.PI;
-                    }
-                    while (angle < startAngle) {
-                        angle += 2.0 * Math.PI;
-                    }
-
-                    // Check if within the range of the open/close angle
-                    var betweenAngles = (angle >= startAngle && angle <= endAngle),
-                        withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);
-
-                    return (betweenAngles && withinRadius);
-                }
-                return false;
-            },
-            getCenterPoint: function() {
-                var vm = this._view;
-                var halfAngle = (vm.startAngle + vm.endAngle) / 2;
-                var halfRadius = (vm.innerRadius + vm.outerRadius) / 2;
-                return {
-                    x: vm.x + Math.cos(halfAngle) * halfRadius,
-                    y: vm.y + Math.sin(halfAngle) * halfRadius
-                };
-            },
-            getArea: function() {
-                var vm = this._view;
-                return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));
-            },
-            tooltipPosition: function() {
-                var vm = this._view;
-
-                var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),
-                    rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
-                return {
-                    x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
-                    y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
-                };
-            },
-            draw: function() {
-
-                var ctx = this._chart.ctx,
-                    vm = this._view,
-                    sA = vm.startAngle,
-                    eA = vm.endAngle;
-
-                ctx.beginPath();
-
-                ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
-                ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
-
-                ctx.closePath();
-                ctx.strokeStyle = vm.borderColor;
-                ctx.lineWidth = vm.borderWidth;
-
-                ctx.fillStyle = vm.backgroundColor;
-
-                ctx.fill();
-                ctx.lineJoin = 'bevel';
-
-                if (vm.borderWidth) {
-                    ctx.stroke();
-                }
-            }
-        });
-    };
-
-},{}],36:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-        var globalDefaults = Chart.defaults.global;
-
-        Chart.defaults.global.elements.line = {
-            tension: 0.4,
-            backgroundColor: globalDefaults.defaultColor,
-            borderWidth: 3,
-            borderColor: globalDefaults.defaultColor,
-            borderCapStyle: 'butt',
-            borderDash: [],
-            borderDashOffset: 0.0,
-            borderJoinStyle: 'miter',
-            capBezierPoints: true,
-            fill: true, // do we fill in the area between the line and its base axis
-        };
-
-        Chart.elements.Line = Chart.Element.extend({
-            draw: function() {
-                var me = this;
-                var vm = me._view;
-                var ctx = me._chart.ctx;
-                var spanGaps = vm.spanGaps;
-                var points = me._children.slice(); // clone array
-                var globalOptionLineElements = globalDefaults.elements.line;
-                var lastDrawnIndex = -1;
-                var index, current, previous, currentVM;
-
-                // If we are looping, adding the first point again
-                if (me._loop && points.length) {
-                    points.push(points[0]);
-                }
-
-                ctx.save();
-
-                // Stroke Line Options
-                ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
-
-                // IE 9 and 10 do not support line dash
-                if (ctx.setLineDash) {
-                    ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
-                }
-
-                ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
-                ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
-                ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
-                ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
-
-                // Stroke Line
-                ctx.beginPath();
-                lastDrawnIndex = -1;
-
-                for (index = 0; index < points.length; ++index) {
-                    current = points[index];
-                    previous = helpers.previousItem(points, index);
-                    currentVM = current._view;
-
-                    // First point moves to it's starting position no matter what
-                    if (index === 0) {
-                        if (!currentVM.skip) {
-                            ctx.moveTo(currentVM.x, currentVM.y);
-                            lastDrawnIndex = index;
-                        }
-                    } else {
-                        previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
-
-                        if (!currentVM.skip) {
-                            if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
-                                // There was a gap and this is the first point after the gap
-                                ctx.moveTo(currentVM.x, currentVM.y);
-                            } else {
-                                // Line to next point
-                                helpers.canvas.lineTo(ctx, previous._view, current._view);
-                            }
-                            lastDrawnIndex = index;
-                        }
-                    }
-                }
-
-                ctx.stroke();
-                ctx.restore();
-            }
-        });
-    };
-
-},{}],37:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers,
-            globalOpts = Chart.defaults.global,
-            defaultColor = globalOpts.defaultColor;
-
-        globalOpts.elements.point = {
-            radius: 3,
-            pointStyle: 'circle',
-            backgroundColor: defaultColor,
-            borderWidth: 1,
-            borderColor: defaultColor,
-            // Hover
-            hitRadius: 1,
-            hoverRadius: 4,
-            hoverBorderWidth: 1
-        };
-
-        function xRange(mouseX) {
-            var vm = this._view;
-            return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
-        }
-
-        function yRange(mouseY) {
-            var vm = this._view;
-            return vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
-        }
-
-        Chart.elements.Point = Chart.Element.extend({
-            inRange: function(mouseX, mouseY) {
-                var vm = this._view;
-                return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
-            },
-
-            inLabelRange: xRange,
-            inXRange: xRange,
-            inYRange: yRange,
-
-            getCenterPoint: function() {
-                var vm = this._view;
-                return {
-                    x: vm.x,
-                    y: vm.y
-                };
-            },
-            getArea: function() {
-                return Math.PI * Math.pow(this._view.radius, 2);
-            },
-            tooltipPosition: function() {
-                var vm = this._view;
-                return {
-                    x: vm.x,
-                    y: vm.y,
-                    padding: vm.radius + vm.borderWidth
-                };
-            },
-            draw: function(chartArea) {
-                var vm = this._view;
-                var model = this._model;
-                var ctx = this._chart.ctx;
-                var pointStyle = vm.pointStyle;
-                var radius = vm.radius;
-                var x = vm.x;
-                var y = vm.y;
-                var color = Chart.helpers.color;
-                var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)
-                var ratio = 0;
-
-                if (vm.skip) {
-                    return;
-                }
-
-                ctx.strokeStyle = vm.borderColor || defaultColor;
-                ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);
-                ctx.fillStyle = vm.backgroundColor || defaultColor;
-
-                // Cliping for Points.
-                // going out from inner charArea?
-                if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right*errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom*errMargin < model.y))) {
-                    // Point fade out
-                    if (model.x < chartArea.left) {
-                        ratio = (x - model.x) / (chartArea.left - model.x);
-                    } else if (chartArea.right*errMargin < model.x) {
-                        ratio = (model.x - x) / (model.x - chartArea.right);
-                    } else if (model.y < chartArea.top) {
-                        ratio = (y - model.y) / (chartArea.top - model.y);
-                    } else if (chartArea.bottom*errMargin < model.y) {
-                        ratio = (model.y - y) / (model.y - chartArea.bottom);
-                    }
-                    ratio = Math.round(ratio*100) / 100;
-                    ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();
-                    ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();
-                }
-
-                Chart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);
-            }
-        });
-    };
-
-},{}],38:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var globalOpts = Chart.defaults.global;
-
-        globalOpts.elements.rectangle = {
-            backgroundColor: globalOpts.defaultColor,
-            borderWidth: 0,
-            borderColor: globalOpts.defaultColor,
-            borderSkipped: 'bottom'
-        };
-
-        function isVertical(bar) {
-            return bar._view.width !== undefined;
-        }
-
-        /**
-         * Helper function to get the bounds of the bar regardless of the orientation
-         * @private
-         * @param bar {Chart.Element.Rectangle} the bar
-         * @return {Bounds} bounds of the bar
-         */
-        function getBarBounds(bar) {
-            var vm = bar._view;
-            var x1, x2, y1, y2;
-
-            if (isVertical(bar)) {
-                // vertical
-                var halfWidth = vm.width / 2;
-                x1 = vm.x - halfWidth;
-                x2 = vm.x + halfWidth;
-                y1 = Math.min(vm.y, vm.base);
-                y2 = Math.max(vm.y, vm.base);
-            } else {
-                // horizontal bar
-                var halfHeight = vm.height / 2;
-                x1 = Math.min(vm.x, vm.base);
-                x2 = Math.max(vm.x, vm.base);
-                y1 = vm.y - halfHeight;
-                y2 = vm.y + halfHeight;
-            }
-
-            return {
-                left: x1,
-                top: y1,
-                right: x2,
-                bottom: y2
-            };
-        }
-
-        Chart.elements.Rectangle = Chart.Element.extend({
-            draw: function() {
-                var ctx = this._chart.ctx;
-                var vm = this._view;
-                var left, right, top, bottom, signX, signY, borderSkipped;
-                var borderWidth = vm.borderWidth;
-
-                if (!vm.horizontal) {
-                    // bar
-                    left = vm.x - vm.width / 2;
-                    right = vm.x + vm.width / 2;
-                    top = vm.y;
-                    bottom = vm.base;
-                    signX = 1;
-                    signY = bottom > top? 1: -1;
-                    borderSkipped = vm.borderSkipped || 'bottom';
-                } else {
-                    // horizontal bar
-                    left = vm.base;
-                    right = vm.x;
-                    top = vm.y - vm.height / 2;
-                    bottom = vm.y + vm.height / 2;
-                    signX = right > left? 1: -1;
-                    signY = 1;
-                    borderSkipped = vm.borderSkipped || 'left';
-                }
-
-                // Canvas doesn't allow us to stroke inside the width so we can
-                // adjust the sizes to fit if we're setting a stroke on the line
-                if (borderWidth) {
-                    // borderWidth shold be less than bar width and bar height.
-                    var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
-                    borderWidth = borderWidth > barSize? barSize: borderWidth;
-                    var halfStroke = borderWidth / 2;
-                    // Adjust borderWidth when bar top position is near vm.base(zero).
-                    var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);
-                    var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);
-                    var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);
-                    var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);
-                    // not become a vertical line?
-                    if (borderLeft !== borderRight) {
-                        top = borderTop;
-                        bottom = borderBottom;
-                    }
-                    // not become a horizontal line?
-                    if (borderTop !== borderBottom) {
-                        left = borderLeft;
-                        right = borderRight;
-                    }
-                }
-
-                ctx.beginPath();
-                ctx.fillStyle = vm.backgroundColor;
-                ctx.strokeStyle = vm.borderColor;
-                ctx.lineWidth = borderWidth;
-
-                // Corner points, from bottom-left to bottom-right clockwise
-                // | 1 2 |
-                // | 0 3 |
-                var corners = [
-                    [left, bottom],
-                    [left, top],
-                    [right, top],
-                    [right, bottom]
-                ];
-
-                // Find first (starting) corner with fallback to 'bottom'
-                var borders = ['bottom', 'left', 'top', 'right'];
-                var startCorner = borders.indexOf(borderSkipped, 0);
-                if (startCorner === -1) {
-                    startCorner = 0;
-                }
-
-                function cornerAt(index) {
-                    return corners[(startCorner + index) % 4];
-                }
-
-                // Draw rectangle from 'startCorner'
-                var corner = cornerAt(0);
-                ctx.moveTo(corner[0], corner[1]);
-
-                for (var i = 1; i < 4; i++) {
-                    corner = cornerAt(i);
-                    ctx.lineTo(corner[0], corner[1]);
-                }
-
-                ctx.fill();
-                if (borderWidth) {
-                    ctx.stroke();
-                }
-            },
-            height: function() {
-                var vm = this._view;
-                return vm.base - vm.y;
-            },
-            inRange: function(mouseX, mouseY) {
-                var inRange = false;
-
-                if (this._view) {
-                    var bounds = getBarBounds(this);
-                    inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;
-                }
-
-                return inRange;
-            },
-            inLabelRange: function(mouseX, mouseY) {
-                var me = this;
-                if (!me._view) {
-                    return false;
-                }
-
-                var inRange = false;
-                var bounds = getBarBounds(me);
-
-                if (isVertical(me)) {
-                    inRange = mouseX >= bounds.left && mouseX <= bounds.right;
-                } else {
-                    inRange = mouseY >= bounds.top && mouseY <= bounds.bottom;
-                }
-
-                return inRange;
-            },
-            inXRange: function(mouseX) {
-                var bounds = getBarBounds(this);
-                return mouseX >= bounds.left && mouseX <= bounds.right;
-            },
-            inYRange: function(mouseY) {
-                var bounds = getBarBounds(this);
-                return mouseY >= bounds.top && mouseY <= bounds.bottom;
-            },
-            getCenterPoint: function() {
-                var vm = this._view;
-                var x, y;
-                if (isVertical(this)) {
-                    x = vm.x;
-                    y = (vm.y + vm.base) / 2;
-                } else {
-                    x = (vm.x + vm.base) / 2;
-                    y = vm.y;
-                }
-
-                return {x: x, y: y};
-            },
-            getArea: function() {
-                var vm = this._view;
-                return vm.width * Math.abs(vm.y - vm.base);
-            },
-            tooltipPosition: function() {
-                var vm = this._view;
-                return {
-                    x: vm.x,
-                    y: vm.y
-                };
-            }
-        });
-
-    };
-
-},{}],39:[function(require,module,exports){
-    'use strict';
-
-// Chart.Platform implementation for targeting a web browser
-    module.exports = function(Chart) {
-        var helpers = Chart.helpers;
-
-        // DOM event types -> Chart.js event types.
-        // Note: only events with different types are mapped.
-        // https://developer.mozilla.org/en-US/docs/Web/Events
-        var eventTypeMap = {
-            // Touch events
-            touchstart: 'mousedown',
-            touchmove: 'mousemove',
-            touchend: 'mouseup',
-
-            // Pointer events
-            pointerenter: 'mouseenter',
-            pointerdown: 'mousedown',
-            pointermove: 'mousemove',
-            pointerup: 'mouseup',
-            pointerleave: 'mouseout',
-            pointerout: 'mouseout'
-        };
-
-        /**
-         * The "used" size is the final value of a dimension property after all calculations have
-         * been performed. This method uses the computed style of `element` but returns undefined
-         * if the computed style is not expressed in pixels. That can happen in some cases where
-         * `element` has a size relative to its parent and this last one is not yet displayed,
-         * for example because of `display: none` on a parent node.
-         * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
-         * @returns {Number} Size in pixels or undefined if unknown.
-         */
-        function readUsedSize(element, property) {
-            var value = helpers.getStyle(element, property);
-            var matches = value && value.match(/^(\d+)(\.\d+)?px$/);
-            return matches? Number(matches[1]) : undefined;
-        }
-
-        /**
-         * Initializes the canvas style and render size without modifying the canvas display size,
-         * since responsiveness is handled by the controller.resize() method. The config is used
-         * to determine the aspect ratio to apply in case no explicit height has been specified.
-         */
-        function initCanvas(canvas, config) {
-            var style = canvas.style;
-
-            // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it
-            // returns null or '' if no explicit value has been set to the canvas attribute.
-            var renderHeight = canvas.getAttribute('height');
-            var renderWidth = canvas.getAttribute('width');
-
-            // Chart.js modifies some canvas values that we want to restore on destroy
-            canvas._chartjs = {
-                initial: {
-                    height: renderHeight,
-                    width: renderWidth,
-                    style: {
-                        display: style.display,
-                        height: style.height,
-                        width: style.width
-                    }
-                }
-            };
-
-            // Force canvas to display as block to avoid extra space caused by inline
-            // elements, which would interfere with the responsive resize process.
-            // https://github.com/chartjs/Chart.js/issues/2538
-            style.display = style.display || 'block';
-
-            if (renderWidth === null || renderWidth === '') {
-                var displayWidth = readUsedSize(canvas, 'width');
-                if (displayWidth !== undefined) {
-                    canvas.width = displayWidth;
-                }
-            }
-
-            if (renderHeight === null || renderHeight === '') {
-                if (canvas.style.height === '') {
-                    // If no explicit render height and style height, let's apply the aspect ratio,
-                    // which one can be specified by the user but also by charts as default option
-                    // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.
-                    canvas.height = canvas.width / (config.options.aspectRatio || 2);
-                } else {
-                    var displayHeight = readUsedSize(canvas, 'height');
-                    if (displayWidth !== undefined) {
-                        canvas.height = displayHeight;
-                    }
-                }
-            }
-
-            return canvas;
-        }
-
-        function createEvent(type, chart, x, y, nativeEvent) {
-            return {
-                type: type,
-                chart: chart,
-                native: nativeEvent || null,
-                x: x !== undefined? x : null,
-                y: y !== undefined? y : null,
-            };
-        }
-
-        function fromNativeEvent(event, chart) {
-            var type = eventTypeMap[event.type] || event.type;
-            var pos = helpers.getRelativePosition(event, chart);
-            return createEvent(type, chart, pos.x, pos.y, event);
-        }
-
-        function createResizer(handler) {
-            var iframe = document.createElement('iframe');
-            iframe.className = 'chartjs-hidden-iframe';
-            iframe.style.cssText =
-                'display:block;'+
-                'overflow:hidden;'+
-                'border:0;'+
-                'margin:0;'+
-                'top:0;'+
-                'left:0;'+
-                'bottom:0;'+
-                'right:0;'+
-                'height:100%;'+
-                'width:100%;'+
-                'position:absolute;'+
-                'pointer-events:none;'+
-                'z-index:-1;';
-
-            // Prevent the iframe to gain focus on tab.
-            // https://github.com/chartjs/Chart.js/issues/3090
-            iframe.tabIndex = -1;
-
-            // If the iframe is re-attached to the DOM, the resize listener is removed because the
-            // content is reloaded, so make sure to install the handler after the iframe is loaded.
-            // https://github.com/chartjs/Chart.js/issues/3521
-            helpers.addEvent(iframe, 'load', function() {
-                helpers.addEvent(iframe.contentWindow || iframe, 'resize', handler);
-
-                // The iframe size might have changed while loading, which can also
-                // happen if the size has been changed while detached from the DOM.
-                handler();
-            });
-
-            return iframe;
-        }
-
-        function addResizeListener(node, listener, chart) {
-            var stub = node._chartjs = {
-                ticking: false
-            };
-
-            // Throttle the callback notification until the next animation frame.
-            var notify = function() {
-                if (!stub.ticking) {
-                    stub.ticking = true;
-                    helpers.requestAnimFrame.call(window, function() {
-                        if (stub.resizer) {
-                            stub.ticking = false;
-                            return listener(createEvent('resize', chart));
-                        }
-                    });
-                }
-            };
-
-            // Let's keep track of this added iframe and thus avoid DOM query when removing it.
-            stub.resizer = createResizer(notify);
-
-            node.insertBefore(stub.resizer, node.firstChild);
-        }
-
-        function removeResizeListener(node) {
-            if (!node || !node._chartjs) {
-                return;
-            }
-
-            var resizer = node._chartjs.resizer;
-            if (resizer) {
-                resizer.parentNode.removeChild(resizer);
-                node._chartjs.resizer = null;
-            }
-
-            delete node._chartjs;
-        }
-
-        return {
-            acquireContext: function(item, config) {
-                if (typeof item === 'string') {
-                    item = document.getElementById(item);
-                } else if (item.length) {
-                    // Support for array based queries (such as jQuery)
-                    item = item[0];
-                }
-
-                if (item && item.canvas) {
-                    // Support for any object associated to a canvas (including a context2d)
-                    item = item.canvas;
-                }
-
-                // To prevent canvas fingerprinting, some add-ons undefine the getContext
-                // method, for example: https://github.com/kkapsner/CanvasBlocker
-                // https://github.com/chartjs/Chart.js/issues/2807
-                var context = item && item.getContext && item.getContext('2d');
-
-                // `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is
-                // inside an iframe or when running in a protected environment. We could guess the
-                // types from their toString() value but let's keep things flexible and assume it's
-                // a sufficient condition if the item has a context2D which has item as `canvas`.
-                // https://github.com/chartjs/Chart.js/issues/3887
-                // https://github.com/chartjs/Chart.js/issues/4102
-                // https://github.com/chartjs/Chart.js/issues/4152
-                if (context && context.canvas === item) {
-                    initCanvas(item, config);
-                    return context;
-                }
-
-                return null;
-            },
-
-            releaseContext: function(context) {
-                var canvas = context.canvas;
-                if (!canvas._chartjs) {
-                    return;
-                }
-
-                var initial = canvas._chartjs.initial;
-                ['height', 'width'].forEach(function(prop) {
-                    var value = initial[prop];
-                    if (value === undefined || value === null) {
-                        canvas.removeAttribute(prop);
-                    } else {
-                        canvas.setAttribute(prop, value);
-                    }
-                });
-
-                helpers.each(initial.style || {}, function(value, key) {
-                    canvas.style[key] = value;
-                });
-
-                // The canvas render size might have been changed (and thus the state stack discarded),
-                // we can't use save() and restore() to restore the initial state. So make sure that at
-                // least the canvas context is reset to the default state by setting the canvas width.
-                // https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html
-                canvas.width = canvas.width;
-
-                delete canvas._chartjs;
-            },
-
-            addEventListener: function(chart, type, listener) {
-                var canvas = chart.canvas;
-                if (type === 'resize') {
-                    // Note: the resize event is not supported on all browsers.
-                    addResizeListener(canvas.parentNode, listener, chart);
-                    return;
-                }
-
-                var stub = listener._chartjs || (listener._chartjs = {});
-                var proxies = stub.proxies || (stub.proxies = {});
-                var proxy = proxies[chart.id + '_' + type] = function(event) {
-                    listener(fromNativeEvent(event, chart));
-                };
-
-                helpers.addEvent(canvas, type, proxy);
-            },
-
-            removeEventListener: function(chart, type, listener) {
-                var canvas = chart.canvas;
-                if (type === 'resize') {
-                    // Note: the resize event is not supported on all browsers.
-                    removeResizeListener(canvas.parentNode, listener);
-                    return;
-                }
-
-                var stub = listener._chartjs || {};
-                var proxies = stub.proxies || {};
-                var proxy = proxies[chart.id + '_' + type];
-                if (!proxy) {
-                    return;
-                }
-
-                helpers.removeEvent(canvas, type, proxy);
-            }
-        };
-    };
-
-},{}],40:[function(require,module,exports){
-    'use strict';
-
-// By default, select the browser (DOM) platform.
-// @TODO Make possible to select another platform at build time.
-    var implementation = require(39);
-
-    module.exports = function(Chart) {
-        /**
-         * @namespace Chart.platform
-         * @see https://chartjs.gitbooks.io/proposals/content/Platform.html
-         * @since 2.4.0
-         */
-        Chart.platform = {
-            /**
-             * Called at chart construction time, returns a context2d instance implementing
-             * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.
-             * @param {*} item - The native item from which to acquire context (platform specific)
-             * @param {Object} options - The chart options
-             * @returns {CanvasRenderingContext2D} context2d instance
-             */
-            acquireContext: function() {},
-
-            /**
-             * Called at chart destruction time, releases any resources associated to the context
-             * previously returned by the acquireContext() method.
-             * @param {CanvasRenderingContext2D} context - The context2d instance
-             * @returns {Boolean} true if the method succeeded, else false
-             */
-            releaseContext: function() {},
-
-            /**
-             * Registers the specified listener on the given chart.
-             * @param {Chart} chart - Chart from which to listen for event
-             * @param {String} type - The ({@link IEvent}) type to listen for
-             * @param {Function} listener - Receives a notification (an object that implements
-             * the {@link IEvent} interface) when an event of the specified type occurs.
-             */
-            addEventListener: function() {},
-
-            /**
-             * Removes the specified listener previously registered with addEventListener.
-             * @param {Chart} chart -Chart from which to remove the listener
-             * @param {String} type - The ({@link IEvent}) type to remove
-             * @param {Function} listener - The listener function to remove from the event target.
-             */
-            removeEventListener: function() {}
-        };
-
-        /**
-         * @interface IPlatform
-         * Allows abstracting platform dependencies away from the chart
-         * @borrows Chart.platform.acquireContext as acquireContext
-         * @borrows Chart.platform.releaseContext as releaseContext
-         * @borrows Chart.platform.addEventListener as addEventListener
-         * @borrows Chart.platform.removeEventListener as removeEventListener
-         */
-
-        /**
-         * @interface IEvent
-         * @prop {String} type - The event type name, possible values are:
-         * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',
-         * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'
-         * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')
-         * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)
-         * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)
-         */
-
-        Chart.helpers.extend(Chart.platform, implementation(Chart));
-    };
-
-},{"39":39}],41:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-        /**
-         * Plugin based on discussion from the following Chart.js issues:
-         * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569
-         * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897
-         */
-        Chart.defaults.global.plugins.filler = {
-            propagate: true
-        };
-
-        var defaults = Chart.defaults;
-        var helpers = Chart.helpers;
-        var mappers = {
-            dataset: function(source) {
-                var index = source.fill;
-                var chart = source.chart;
-                var meta = chart.getDatasetMeta(index);
-                var visible = meta && chart.isDatasetVisible(index);
-                var points = (visible && meta.dataset._children) || [];
-
-                return !points.length? null : function(point, i) {
-                    return points[i]._view || null;
-                };
-            },
-
-            boundary: function(source) {
-                var boundary = source.boundary;
-                var x = boundary? boundary.x : null;
-                var y = boundary? boundary.y : null;
-
-                return function(point) {
-                    return {
-                        x: x === null? point.x : x,
-                        y: y === null? point.y : y,
-                    };
-                };
-            }
-        };
-
-        // @todo if (fill[0] === '#')
-        function decodeFill(el, index, count) {
-            var model = el._model || {};
-            var fill = model.fill;
-            var target;
-
-            if (fill === undefined) {
-                fill = !!model.backgroundColor;
-            }
-
-            if (fill === false || fill === null) {
-                return false;
-            }
-
-            if (fill === true) {
-                return 'origin';
-            }
-
-            target = parseFloat(fill, 10);
-            if (isFinite(target) && Math.floor(target) === target) {
-                if (fill[0] === '-' || fill[0] === '+') {
-                    target = index + target;
-                }
-
-                if (target === index || target < 0 || target >= count) {
-                    return false;
-                }
-
-                return target;
-            }
-
-            switch (fill) {
-                // compatibility
-                case 'bottom':
-                    return 'start';
-                case 'top':
-                    return 'end';
-                case 'zero':
-                    return 'origin';
-                // supported boundaries
-                case 'origin':
-                case 'start':
-                case 'end':
-                    return fill;
-                // invalid fill values
-                default:
-                    return false;
-            }
-        }
-
-        function computeBoundary(source) {
-            var model = source.el._model || {};
-            var scale = source.el._scale || {};
-            var fill = source.fill;
-            var target = null;
-            var horizontal;
-
-            if (isFinite(fill)) {
-                return null;
-            }
-
-            // Backward compatibility: until v3, we still need to support boundary values set on
-            // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and
-            // controllers might still use it (e.g. the Smith chart).
-
-            if (fill === 'start') {
-                target = model.scaleBottom === undefined? scale.bottom : model.scaleBottom;
-            } else if (fill === 'end') {
-                target = model.scaleTop === undefined? scale.top : model.scaleTop;
-            } else if (model.scaleZero !== undefined) {
-                target = model.scaleZero;
-            } else if (scale.getBasePosition) {
-                target = scale.getBasePosition();
-            } else if (scale.getBasePixel) {
-                target = scale.getBasePixel();
-            }
-
-            if (target !== undefined && target !== null) {
-                if (target.x !== undefined && target.y !== undefined) {
-                    return target;
-                }
-
-                if (typeof target === 'number' && isFinite(target)) {
-                    horizontal = scale.isHorizontal();
-                    return {
-                        x: horizontal? target : null,
-                        y: horizontal? null : target
-                    };
-                }
-            }
-
-            return null;
-        }
-
-        function resolveTarget(sources, index, propagate) {
-            var source = sources[index];
-            var fill = source.fill;
-            var visited = [index];
-            var target;
-
-            if (!propagate) {
-                return fill;
-            }
-
-            while (fill !== false && visited.indexOf(fill) === -1) {
-                if (!isFinite(fill)) {
-                    return fill;
-                }
-
-                target = sources[fill];
-                if (!target) {
-                    return false;
-                }
-
-                if (target.visible) {
-                    return fill;
-                }
-
-                visited.push(fill);
-                fill = target.fill;
-            }
-
-            return false;
-        }
-
-        function createMapper(source) {
-            var fill = source.fill;
-            var type = 'dataset';
-
-            if (fill === false) {
-                return null;
-            }
-
-            if (!isFinite(fill)) {
-                type = 'boundary';
-            }
-
-            return mappers[type](source);
-        }
-
-        function isDrawable(point) {
-            return point && !point.skip;
-        }
-
-        function drawArea(ctx, curve0, curve1, len0, len1) {
-            var i;
-
-            if (!len0 || !len1) {
-                return;
-            }
-
-            // building first area curve (normal)
-            ctx.moveTo(curve0[0].x, curve0[0].y);
-            for (i=1; i<len0; ++i) {
-                helpers.canvas.lineTo(ctx, curve0[i-1], curve0[i]);
-            }
-
-            // joining the two area curves
-            ctx.lineTo(curve1[len1-1].x, curve1[len1-1].y);
-
-            // building opposite area curve (reverse)
-            for (i=len1-1; i>0; --i) {
-                helpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true);
-            }
-        }
-
-        function doFill(ctx, points, mapper, view, color, loop) {
-            var count = points.length;
-            var span = view.spanGaps;
-            var curve0 = [];
-            var curve1 = [];
-            var len0 = 0;
-            var len1 = 0;
-            var i, ilen, index, p0, p1, d0, d1;
-
-            ctx.beginPath();
-
-            for (i = 0, ilen = (count + !!loop); i < ilen; ++i) {
-                index = i%count;
-                p0 = points[index]._view;
-                p1 = mapper(p0, index, view);
-                d0 = isDrawable(p0);
-                d1 = isDrawable(p1);
-
-                if (d0 && d1) {
-                    len0 = curve0.push(p0);
-                    len1 = curve1.push(p1);
-                } else if (len0 && len1) {
-                    if (!span) {
-                        drawArea(ctx, curve0, curve1, len0, len1);
-                        len0 = len1 = 0;
-                        curve0 = [];
-                        curve1 = [];
-                    } else {
-                        if (d0) {
-                            curve0.push(p0);
-                        }
-                        if (d1) {
-                            curve1.push(p1);
-                        }
-                    }
-                }
-            }
-
-            drawArea(ctx, curve0, curve1, len0, len1);
-
-            ctx.closePath();
-            ctx.fillStyle = color;
-            ctx.fill();
-        }
-
-        return {
-            id: 'filler',
-
-            afterDatasetsUpdate: function(chart, options) {
-                var count = (chart.data.datasets || []).length;
-                var propagate = options.propagate;
-                var sources = [];
-                var meta, i, el, source;
-
-                for (i = 0; i < count; ++i) {
-                    meta = chart.getDatasetMeta(i);
-                    el = meta.dataset;
-                    source = null;
-
-                    if (el && el._model && el instanceof Chart.elements.Line) {
-                        source = {
-                            visible: chart.isDatasetVisible(i),
-                            fill: decodeFill(el, i, count),
-                            chart: chart,
-                            el: el
-                        };
-                    }
-
-                    meta.$filler = source;
-                    sources.push(source);
-                }
-
-                for (i=0; i<count; ++i) {
-                    source = sources[i];
-                    if (!source) {
-                        continue;
-                    }
-
-                    source.fill = resolveTarget(sources, i, propagate);
-                    source.boundary = computeBoundary(source);
-                    source.mapper = createMapper(source);
-                }
-            },
-
-            beforeDatasetDraw: function(chart, args) {
-                var meta = args.meta.$filler;
-                if (!meta) {
-                    return;
-                }
-
-                var el = meta.el;
-                var view = el._view;
-                var points = el._children || [];
-                var mapper = meta.mapper;
-                var color = view.backgroundColor || defaults.global.defaultColor;
-
-                if (mapper && color && points.length) {
-                    doFill(chart.ctx, points, mapper, view, color, el._loop);
-                }
-            }
-        };
-    };
-
-},{}],42:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-        var layout = Chart.layoutService;
-        var noop = helpers.noop;
-
-        Chart.defaults.global.legend = {
-            display: true,
-            position: 'top',
-            fullWidth: true,
-            reverse: false,
-            weight: 1000,
-
-            // a callback that will handle
-            onClick: function(e, legendItem) {
-                var index = legendItem.datasetIndex;
-                var ci = this.chart;
-                var meta = ci.getDatasetMeta(index);
-
-                // See controller.isDatasetVisible comment
-                meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
-
-                // We hid a dataset ... rerender the chart
-                ci.update();
-            },
-
-            onHover: null,
-
-            labels: {
-                boxWidth: 40,
-                padding: 10,
-                // Generates labels shown in the legend
-                // Valid properties to return:
-                // text : text to display
-                // fillStyle : fill of coloured box
-                // strokeStyle: stroke of coloured box
-                // hidden : if this legend item refers to a hidden item
-                // lineCap : cap style for line
-                // lineDash
-                // lineDashOffset :
-                // lineJoin :
-                // lineWidth :
-                generateLabels: function(chart) {
-                    var data = chart.data;
-                    return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
-                        return {
-                            text: dataset.label,
-                            fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),
-                            hidden: !chart.isDatasetVisible(i),
-                            lineCap: dataset.borderCapStyle,
-                            lineDash: dataset.borderDash,
-                            lineDashOffset: dataset.borderDashOffset,
-                            lineJoin: dataset.borderJoinStyle,
-                            lineWidth: dataset.borderWidth,
-                            strokeStyle: dataset.borderColor,
-                            pointStyle: dataset.pointStyle,
-
-                            // Below is extra data used for toggling the datasets
-                            datasetIndex: i
-                        };
-                    }, this) : [];
-                }
-            }
-        };
-
-        /**
-         * Helper function to get the box width based on the usePointStyle option
-         * @param labelopts {Object} the label options on the legend
-         * @param fontSize {Number} the label font size
-         * @return {Number} width of the color box area
-         */
-        function getBoxWidth(labelOpts, fontSize) {
-            return labelOpts.usePointStyle ?
-                fontSize * Math.SQRT2 :
-                labelOpts.boxWidth;
-        }
-
-        Chart.Legend = Chart.Element.extend({
-
-            initialize: function(config) {
-                helpers.extend(this, config);
-
-                // Contains hit boxes for each dataset (in dataset order)
-                this.legendHitBoxes = [];
-
-                // Are we in doughnut mode which has a different data type
-                this.doughnutMode = false;
-            },
-
-            // These methods are ordered by lifecycle. Utilities then follow.
-            // Any function defined here is inherited by all legend types.
-            // Any function can be extended by the legend type
-
-            beforeUpdate: noop,
-            update: function(maxWidth, maxHeight, margins) {
-                var me = this;
-
-                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-                me.beforeUpdate();
-
-                // Absorb the master measurements
-                me.maxWidth = maxWidth;
-                me.maxHeight = maxHeight;
-                me.margins = margins;
-
-                // Dimensions
-                me.beforeSetDimensions();
-                me.setDimensions();
-                me.afterSetDimensions();
-                // Labels
-                me.beforeBuildLabels();
-                me.buildLabels();
-                me.afterBuildLabels();
-
-                // Fit
-                me.beforeFit();
-                me.fit();
-                me.afterFit();
-                //
-                me.afterUpdate();
-
-                return me.minSize;
-            },
-            afterUpdate: noop,
-
-            //
-
-            beforeSetDimensions: noop,
-            setDimensions: function() {
-                var me = this;
-                // Set the unconstrained dimension before label rotation
-                if (me.isHorizontal()) {
-                    // Reset position before calculating rotation
-                    me.width = me.maxWidth;
-                    me.left = 0;
-                    me.right = me.width;
-                } else {
-                    me.height = me.maxHeight;
-
-                    // Reset position before calculating rotation
-                    me.top = 0;
-                    me.bottom = me.height;
-                }
-
-                // Reset padding
-                me.paddingLeft = 0;
-                me.paddingTop = 0;
-                me.paddingRight = 0;
-                me.paddingBottom = 0;
-
-                // Reset minSize
-                me.minSize = {
-                    width: 0,
-                    height: 0
-                };
-            },
-            afterSetDimensions: noop,
-
-            //
-
-            beforeBuildLabels: noop,
-            buildLabels: function() {
-                var me = this;
-                var labelOpts = me.options.labels;
-                var legendItems = labelOpts.generateLabels.call(me, me.chart);
-
-                if (labelOpts.filter) {
-                    legendItems = legendItems.filter(function(item) {
-                        return labelOpts.filter(item, me.chart.data);
-                    });
-                }
-
-                if (me.options.reverse) {
-                    legendItems.reverse();
-                }
-
-                me.legendItems = legendItems;
-            },
-            afterBuildLabels: noop,
-
-            //
-
-            beforeFit: noop,
-            fit: function() {
-                var me = this;
-                var opts = me.options;
-                var labelOpts = opts.labels;
-                var display = opts.display;
-
-                var ctx = me.ctx;
-
-                var globalDefault = Chart.defaults.global,
-                    itemOrDefault = helpers.getValueOrDefault,
-                    fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),
-                    fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),
-                    fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),
-                    labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
-
-                // Reset hit boxes
-                var hitboxes = me.legendHitBoxes = [];
-
-                var minSize = me.minSize;
-                var isHorizontal = me.isHorizontal();
-
-                if (isHorizontal) {
-                    minSize.width = me.maxWidth; // fill all the width
-                    minSize.height = display ? 10 : 0;
-                } else {
-                    minSize.width = display ? 10 : 0;
-                    minSize.height = me.maxHeight; // fill all the height
-                }
-
-                // Increase sizes here
-                if (display) {
-                    ctx.font = labelFont;
-
-                    if (isHorizontal) {
-                        // Labels
-
-                        // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
-                        var lineWidths = me.lineWidths = [0];
-                        var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;
-
-                        ctx.textAlign = 'left';
-                        ctx.textBaseline = 'top';
-
-                        helpers.each(me.legendItems, function(legendItem, i) {
-                            var boxWidth = getBoxWidth(labelOpts, fontSize);
-                            var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
-
-                            if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
-                                totalHeight += fontSize + (labelOpts.padding);
-                                lineWidths[lineWidths.length] = me.left;
-                            }
-
-                            // Store the hitbox width and height here. Final position will be updated in `draw`
-                            hitboxes[i] = {
-                                left: 0,
-                                top: 0,
-                                width: width,
-                                height: fontSize
-                            };
-
-                            lineWidths[lineWidths.length - 1] += width + labelOpts.padding;
-                        });
-
-                        minSize.height += totalHeight;
-
-                    } else {
-                        var vPadding = labelOpts.padding;
-                        var columnWidths = me.columnWidths = [];
-                        var totalWidth = labelOpts.padding;
-                        var currentColWidth = 0;
-                        var currentColHeight = 0;
-                        var itemHeight = fontSize + vPadding;
-
-                        helpers.each(me.legendItems, function(legendItem, i) {
-                            var boxWidth = getBoxWidth(labelOpts, fontSize);
-                            var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
-
-                            // If too tall, go to new column
-                            if (currentColHeight + itemHeight > minSize.height) {
-                                totalWidth += currentColWidth + labelOpts.padding;
-                                columnWidths.push(currentColWidth); // previous column width
-
-                                currentColWidth = 0;
-                                currentColHeight = 0;
-                            }
-
-                            // Get max width
-                            currentColWidth = Math.max(currentColWidth, itemWidth);
-                            currentColHeight += itemHeight;
-
-                            // Store the hitbox width and height here. Final position will be updated in `draw`
-                            hitboxes[i] = {
-                                left: 0,
-                                top: 0,
-                                width: itemWidth,
-                                height: fontSize
-                            };
-                        });
-
-                        totalWidth += currentColWidth;
-                        columnWidths.push(currentColWidth);
-                        minSize.width += totalWidth;
-                    }
-                }
-
-                me.width = minSize.width;
-                me.height = minSize.height;
-            },
-            afterFit: noop,
-
-            // Shared Methods
-            isHorizontal: function() {
-                return this.options.position === 'top' || this.options.position === 'bottom';
-            },
-
-            // Actually draw the legend on the canvas
-            draw: function() {
-                var me = this;
-                var opts = me.options;
-                var labelOpts = opts.labels;
-                var globalDefault = Chart.defaults.global,
-                    lineDefault = globalDefault.elements.line,
-                    legendWidth = me.width,
-                    lineWidths = me.lineWidths;
-
-                if (opts.display) {
-                    var ctx = me.ctx,
-                        cursor,
-                        itemOrDefault = helpers.getValueOrDefault,
-                        fontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),
-                        fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),
-                        fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),
-                        fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),
-                        labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
-
-                    // Canvas setup
-                    ctx.textAlign = 'left';
-                    ctx.textBaseline = 'top';
-                    ctx.lineWidth = 0.5;
-                    ctx.strokeStyle = fontColor; // for strikethrough effect
-                    ctx.fillStyle = fontColor; // render in correct colour
-                    ctx.font = labelFont;
-
-                    var boxWidth = getBoxWidth(labelOpts, fontSize),
-                        hitboxes = me.legendHitBoxes;
-
-                    // current position
-                    var drawLegendBox = function(x, y, legendItem) {
-                        if (isNaN(boxWidth) || boxWidth <= 0) {
-                            return;
-                        }
-
-                        // Set the ctx for the box
-                        ctx.save();
-
-                        ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
-                        ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
-                        ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
-                        ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
-                        ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
-                        ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
-                        var isLineWidthZero = (itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);
-
-                        if (ctx.setLineDash) {
-                            // IE 9 and 10 do not support line dash
-                            ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
-                        }
-
-                        if (opts.labels && opts.labels.usePointStyle) {
-                            // Recalculate x and y for drawPoint() because its expecting
-                            // x and y to be center of figure (instead of top left)
-                            var radius = fontSize * Math.SQRT2 / 2;
-                            var offSet = radius / Math.SQRT2;
-                            var centerX = x + offSet;
-                            var centerY = y + offSet;
-
-                            // Draw pointStyle as legend symbol
-                            Chart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
-                        } else {
-                            // Draw box as legend symbol
-                            if (!isLineWidthZero) {
-                                ctx.strokeRect(x, y, boxWidth, fontSize);
-                            }
-                            ctx.fillRect(x, y, boxWidth, fontSize);
-                        }
-
-                        ctx.restore();
-                    };
-                    var fillText = function(x, y, legendItem, textWidth) {
-                        ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);
-
-                        if (legendItem.hidden) {
-                            // Strikethrough the text if hidden
-                            ctx.beginPath();
-                            ctx.lineWidth = 2;
-                            ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));
-                            ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));
-                            ctx.stroke();
-                        }
-                    };
-
-                    // Horizontal
-                    var isHorizontal = me.isHorizontal();
-                    if (isHorizontal) {
-                        cursor = {
-                            x: me.left + ((legendWidth - lineWidths[0]) / 2),
-                            y: me.top + labelOpts.padding,
-                            line: 0
-                        };
-                    } else {
-                        cursor = {
-                            x: me.left + labelOpts.padding,
-                            y: me.top + labelOpts.padding,
-                            line: 0
-                        };
-                    }
-
-                    var itemHeight = fontSize + labelOpts.padding;
-                    helpers.each(me.legendItems, function(legendItem, i) {
-                        var textWidth = ctx.measureText(legendItem.text).width,
-                            width = boxWidth + (fontSize / 2) + textWidth,
-                            x = cursor.x,
-                            y = cursor.y;
-
-                        if (isHorizontal) {
-                            if (x + width >= legendWidth) {
-                                y = cursor.y += itemHeight;
-                                cursor.line++;
-                                x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
-                            }
-                        } else if (y + itemHeight > me.bottom) {
-                            x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
-                            y = cursor.y = me.top + labelOpts.padding;
-                            cursor.line++;
-                        }
-
-                        drawLegendBox(x, y, legendItem);
-
-                        hitboxes[i].left = x;
-                        hitboxes[i].top = y;
-
-                        // Fill the actual label
-                        fillText(x, y, legendItem, textWidth);
-
-                        if (isHorizontal) {
-                            cursor.x += width + (labelOpts.padding);
-                        } else {
-                            cursor.y += itemHeight;
-                        }
-
-                    });
-                }
-            },
-
-            /**
-             * Handle an event
-             * @private
-             * @param {IEvent} event - The event to handle
-             * @return {Boolean} true if a change occured
-             */
-            handleEvent: function(e) {
-                var me = this;
-                var opts = me.options;
-                var type = e.type === 'mouseup' ? 'click' : e.type;
-                var changed = false;
-
-                if (type === 'mousemove') {
-                    if (!opts.onHover) {
-                        return;
-                    }
-                } else if (type === 'click') {
-                    if (!opts.onClick) {
-                        return;
-                    }
-                } else {
-                    return;
-                }
-
-                // Chart event already has relative position in it
-                var x = e.x,
-                    y = e.y;
-
-                if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {
-                    // See if we are touching one of the dataset boxes
-                    var lh = me.legendHitBoxes;
-                    for (var i = 0; i < lh.length; ++i) {
-                        var hitBox = lh[i];
-
-                        if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
-                            // Touching an element
-                            if (type === 'click') {
-                                // use e.native for backwards compatibility
-                                opts.onClick.call(me, e.native, me.legendItems[i]);
-                                changed = true;
-                                break;
-                            } else if (type === 'mousemove') {
-                                // use e.native for backwards compatibility
-                                opts.onHover.call(me, e.native, me.legendItems[i]);
-                                changed = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                return changed;
-            }
-        });
-
-        function createNewLegendAndAttach(chart, legendOpts) {
-            var legend = new Chart.Legend({
-                ctx: chart.ctx,
-                options: legendOpts,
-                chart: chart
-            });
-
-            layout.configure(chart, legend, legendOpts);
-            layout.addBox(chart, legend);
-            chart.legend = legend;
-        }
-
-        return {
-            id: 'legend',
-
-            beforeInit: function(chart) {
-                var legendOpts = chart.options.legend;
-
-                if (legendOpts) {
-                    createNewLegendAndAttach(chart, legendOpts);
-                }
-            },
-
-            beforeUpdate: function(chart) {
-                var legendOpts = chart.options.legend;
-                var legend = chart.legend;
-
-                if (legendOpts) {
-                    legendOpts = helpers.configMerge(Chart.defaults.global.legend, legendOpts);
-
-                    if (legend) {
-                        layout.configure(chart, legend, legendOpts);
-                        legend.options = legendOpts;
-                    } else {
-                        createNewLegendAndAttach(chart, legendOpts);
-                    }
-                } else if (legend) {
-                    layout.removeBox(chart, legend);
-                    delete chart.legend;
-                }
-            },
-
-            afterEvent: function(chart, e) {
-                var legend = chart.legend;
-                if (legend) {
-                    legend.handleEvent(e);
-                }
-            }
-        };
-    };
-
-},{}],43:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-        var layout = Chart.layoutService;
-        var noop = helpers.noop;
-
-        Chart.defaults.global.title = {
-            display: false,
-            position: 'top',
-            fullWidth: true,
-            weight: 2000,        // by default greater than legend (1000) to be above
-            fontStyle: 'bold',
-            padding: 10,
-
-            // actual title
-            text: ''
-        };
-
-        Chart.Title = Chart.Element.extend({
-            initialize: function(config) {
-                var me = this;
-                helpers.extend(me, config);
-
-                // Contains hit boxes for each dataset (in dataset order)
-                me.legendHitBoxes = [];
-            },
-
-            // These methods are ordered by lifecycle. Utilities then follow.
-
-            beforeUpdate: noop,
-            update: function(maxWidth, maxHeight, margins) {
-                var me = this;
-
-                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-                me.beforeUpdate();
-
-                // Absorb the master measurements
-                me.maxWidth = maxWidth;
-                me.maxHeight = maxHeight;
-                me.margins = margins;
-
-                // Dimensions
-                me.beforeSetDimensions();
-                me.setDimensions();
-                me.afterSetDimensions();
-                // Labels
-                me.beforeBuildLabels();
-                me.buildLabels();
-                me.afterBuildLabels();
-
-                // Fit
-                me.beforeFit();
-                me.fit();
-                me.afterFit();
-                //
-                me.afterUpdate();
-
-                return me.minSize;
-
-            },
-            afterUpdate: noop,
-
-            //
-
-            beforeSetDimensions: noop,
-            setDimensions: function() {
-                var me = this;
-                // Set the unconstrained dimension before label rotation
-                if (me.isHorizontal()) {
-                    // Reset position before calculating rotation
-                    me.width = me.maxWidth;
-                    me.left = 0;
-                    me.right = me.width;
-                } else {
-                    me.height = me.maxHeight;
-
-                    // Reset position before calculating rotation
-                    me.top = 0;
-                    me.bottom = me.height;
-                }
-
-                // Reset padding
-                me.paddingLeft = 0;
-                me.paddingTop = 0;
-                me.paddingRight = 0;
-                me.paddingBottom = 0;
-
-                // Reset minSize
-                me.minSize = {
-                    width: 0,
-                    height: 0
-                };
-            },
-            afterSetDimensions: noop,
-
-            //
-
-            beforeBuildLabels: noop,
-            buildLabels: noop,
-            afterBuildLabels: noop,
-
-            //
-
-            beforeFit: noop,
-            fit: function() {
-                var me = this,
-                    valueOrDefault = helpers.getValueOrDefault,
-                    opts = me.options,
-                    globalDefaults = Chart.defaults.global,
-                    display = opts.display,
-                    fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
-                    minSize = me.minSize;
-
-                if (me.isHorizontal()) {
-                    minSize.width = me.maxWidth; // fill all the width
-                    minSize.height = display ? fontSize + (opts.padding * 2) : 0;
-                } else {
-                    minSize.width = display ? fontSize + (opts.padding * 2) : 0;
-                    minSize.height = me.maxHeight; // fill all the height
-                }
-
-                me.width = minSize.width;
-                me.height = minSize.height;
-
-            },
-            afterFit: noop,
-
-            // Shared Methods
-            isHorizontal: function() {
-                var pos = this.options.position;
-                return pos === 'top' || pos === 'bottom';
-            },
-
-            // Actually draw the title block on the canvas
-            draw: function() {
-                var me = this,
-                    ctx = me.ctx,
-                    valueOrDefault = helpers.getValueOrDefault,
-                    opts = me.options,
-                    globalDefaults = Chart.defaults.global;
-
-                if (opts.display) {
-                    var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
-                        fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),
-                        fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),
-                        titleFont = helpers.fontString(fontSize, fontStyle, fontFamily),
-                        rotation = 0,
-                        titleX,
-                        titleY,
-                        top = me.top,
-                        left = me.left,
-                        bottom = me.bottom,
-                        right = me.right,
-                        maxWidth;
-
-                    ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
-                    ctx.font = titleFont;
-
-                    // Horizontal
-                    if (me.isHorizontal()) {
-                        titleX = left + ((right - left) / 2); // midpoint of the width
-                        titleY = top + ((bottom - top) / 2); // midpoint of the height
-                        maxWidth = right - left;
-                    } else {
-                        titleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);
-                        titleY = top + ((bottom - top) / 2);
-                        maxWidth = bottom - top;
-                        rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
-                    }
-
-                    ctx.save();
-                    ctx.translate(titleX, titleY);
-                    ctx.rotate(rotation);
-                    ctx.textAlign = 'center';
-                    ctx.textBaseline = 'middle';
-                    ctx.fillText(opts.text, 0, 0, maxWidth);
-                    ctx.restore();
-                }
-            }
-        });
-
-        function createNewTitleBlockAndAttach(chart, titleOpts) {
-            var title = new Chart.Title({
-                ctx: chart.ctx,
-                options: titleOpts,
-                chart: chart
-            });
-
-            layout.configure(chart, title, titleOpts);
-            layout.addBox(chart, title);
-            chart.titleBlock = title;
-        }
-
-        return {
-            id: 'title',
-
-            beforeInit: function(chart) {
-                var titleOpts = chart.options.title;
-
-                if (titleOpts) {
-                    createNewTitleBlockAndAttach(chart, titleOpts);
-                }
-            },
-
-            beforeUpdate: function(chart) {
-                var titleOpts = chart.options.title;
-                var titleBlock = chart.titleBlock;
-
-                if (titleOpts) {
-                    titleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);
-
-                    if (titleBlock) {
-                        layout.configure(chart, titleBlock, titleOpts);
-                        titleBlock.options = titleOpts;
-                    } else {
-                        createNewTitleBlockAndAttach(chart, titleOpts);
-                    }
-                } else if (titleBlock) {
-                    Chart.layoutService.removeBox(chart, titleBlock);
-                    delete chart.titleBlock;
-                }
-            }
-        };
-    };
-
-},{}],44:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-        // Default config for a category scale
-        var defaultConfig = {
-            position: 'bottom'
-        };
-
-        var DatasetScale = Chart.Scale.extend({
-            /**
-             * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those
-             * else fall back to data.labels
-             * @private
-             */
-            getLabels: function() {
-                var data = this.chart.data;
-                return (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
-            },
-
-            determineDataLimits: function() {
-                var me = this;
-                var labels = me.getLabels();
-                me.minIndex = 0;
-                me.maxIndex = labels.length - 1;
-                var findIndex;
-
-                if (me.options.ticks.min !== undefined) {
-                    // user specified min value
-                    findIndex = helpers.indexOf(labels, me.options.ticks.min);
-                    me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
-                }
-
-                if (me.options.ticks.max !== undefined) {
-                    // user specified max value
-                    findIndex = helpers.indexOf(labels, me.options.ticks.max);
-                    me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
-                }
-
-                me.min = labels[me.minIndex];
-                me.max = labels[me.maxIndex];
-            },
-
-            buildTicks: function() {
-                var me = this;
-                var labels = me.getLabels();
-                // If we are viewing some subset of labels, slice the original array
-                me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
-            },
-
-            getLabelForIndex: function(index, datasetIndex) {
-                var me = this;
-                var data = me.chart.data;
-                var isHorizontal = me.isHorizontal();
-
-                if (data.yLabels && !isHorizontal) {
-                    return me.getRightValue(data.datasets[datasetIndex].data[index]);
-                }
-                return me.ticks[index - me.minIndex];
-            },
-
-            // Used to get data value locations.  Value can either be an index or a numerical value
-            getPixelForValue: function(value, index, datasetIndex, includeOffset) {
-                var me = this;
-                // 1 is added because we need the length but we have the indexes
-                var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
-
-                // If value is a data object, then index is the index in the data array,
-                // not the index of the scale. We need to change that.
-                var valueCategory;
-                if (value !== undefined && value !== null) {
-                    valueCategory = me.isHorizontal() ? value.x : value.y;
-                }
-                if (valueCategory !== undefined || (value !== undefined && isNaN(index))) {
-                    var labels = me.getLabels();
-                    value = valueCategory || value;
-                    var idx = labels.indexOf(value);
-                    index = idx !== -1 ? idx : index;
-                }
-
-                if (me.isHorizontal()) {
-                    var valueWidth = me.width / offsetAmt;
-                    var widthOffset = (valueWidth * (index - me.minIndex));
-
-                    if (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {
-                        widthOffset += (valueWidth / 2);
-                    }
-
-                    return me.left + Math.round(widthOffset);
-                }
-                var valueHeight = me.height / offsetAmt;
-                var heightOffset = (valueHeight * (index - me.minIndex));
-
-                if (me.options.gridLines.offsetGridLines && includeOffset) {
-                    heightOffset += (valueHeight / 2);
-                }
-
-                return me.top + Math.round(heightOffset);
-            },
-            getPixelForTick: function(index, includeOffset) {
-                return this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);
-            },
-            getValueForPixel: function(pixel) {
-                var me = this;
-                var value;
-                var offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
-                var horz = me.isHorizontal();
-                var valueDimension = (horz ? me.width : me.height) / offsetAmt;
-
-                pixel -= horz ? me.left : me.top;
-
-                if (me.options.gridLines.offsetGridLines) {
-                    pixel -= (valueDimension / 2);
-                }
-
-                if (pixel <= 0) {
-                    value = 0;
-                } else {
-                    value = Math.round(pixel / valueDimension);
-                }
-
-                return value;
-            },
-            getBasePixel: function() {
-                return this.bottom;
-            }
-        });
-
-        Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);
-
-    };
-
-},{}],45:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        var defaultConfig = {
-            position: 'left',
-            ticks: {
-                callback: Chart.Ticks.formatters.linear
-            }
-        };
-
-        var LinearScale = Chart.LinearScaleBase.extend({
-
-            determineDataLimits: function() {
-                var me = this;
-                var opts = me.options;
-                var chart = me.chart;
-                var data = chart.data;
-                var datasets = data.datasets;
-                var isHorizontal = me.isHorizontal();
-                var DEFAULT_MIN = 0;
-                var DEFAULT_MAX = 1;
-
-                function IDMatches(meta) {
-                    return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
-                }
-
-                // First Calculate the range
-                me.min = null;
-                me.max = null;
-
-                var hasStacks = opts.stacked;
-                if (hasStacks === undefined) {
-                    helpers.each(datasets, function(dataset, datasetIndex) {
-                        if (hasStacks) {
-                            return;
-                        }
-
-                        var meta = chart.getDatasetMeta(datasetIndex);
-                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
-                            meta.stack !== undefined) {
-                            hasStacks = true;
-                        }
-                    });
-                }
-
-                if (opts.stacked || hasStacks) {
-                    var valuesPerStack = {};
-
-                    helpers.each(datasets, function(dataset, datasetIndex) {
-                        var meta = chart.getDatasetMeta(datasetIndex);
-                        var key = [
-                            meta.type,
-                            // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
-                            ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
-                            meta.stack
-                        ].join('.');
-
-                        if (valuesPerStack[key] === undefined) {
-                            valuesPerStack[key] = {
-                                positiveValues: [],
-                                negativeValues: []
-                            };
-                        }
-
-                        // Store these per type
-                        var positiveValues = valuesPerStack[key].positiveValues;
-                        var negativeValues = valuesPerStack[key].negativeValues;
-
-                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-                            helpers.each(dataset.data, function(rawValue, index) {
-                                var value = +me.getRightValue(rawValue);
-                                if (isNaN(value) || meta.data[index].hidden) {
-                                    return;
-                                }
-
-                                positiveValues[index] = positiveValues[index] || 0;
-                                negativeValues[index] = negativeValues[index] || 0;
-
-                                if (opts.relativePoints) {
-                                    positiveValues[index] = 100;
-                                } else if (value < 0) {
-                                    negativeValues[index] += value;
-                                } else {
-                                    positiveValues[index] += value;
-                                }
-                            });
-                        }
-                    });
-
-                    helpers.each(valuesPerStack, function(valuesForType) {
-                        var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
-                        var minVal = helpers.min(values);
-                        var maxVal = helpers.max(values);
-                        me.min = me.min === null ? minVal : Math.min(me.min, minVal);
-                        me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
-                    });
-
-                } else {
-                    helpers.each(datasets, function(dataset, datasetIndex) {
-                        var meta = chart.getDatasetMeta(datasetIndex);
-                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-                            helpers.each(dataset.data, function(rawValue, index) {
-                                var value = +me.getRightValue(rawValue);
-                                if (isNaN(value) || meta.data[index].hidden) {
-                                    return;
-                                }
-
-                                if (me.min === null) {
-                                    me.min = value;
-                                } else if (value < me.min) {
-                                    me.min = value;
-                                }
-
-                                if (me.max === null) {
-                                    me.max = value;
-                                } else if (value > me.max) {
-                                    me.max = value;
-                                }
-                            });
-                        }
-                    });
-                }
-
-                me.min = isFinite(me.min) ? me.min : DEFAULT_MIN;
-                me.max = isFinite(me.max) ? me.max : DEFAULT_MAX;
-
-                // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
-                this.handleTickRangeOptions();
-            },
-            getTickLimit: function() {
-                var maxTicks;
-                var me = this;
-                var tickOpts = me.options.ticks;
-
-                if (me.isHorizontal()) {
-                    maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));
-                } else {
-                    // The factor of 2 used to scale the font size has been experimentally determined.
-                    var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);
-                    maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));
-                }
-
-                return maxTicks;
-            },
-            // Called after the ticks are built. We need
-            handleDirectionalChanges: function() {
-                if (!this.isHorizontal()) {
-                    // We are in a vertical orientation. The top value is the highest. So reverse the array
-                    this.ticks.reverse();
-                }
-            },
-            getLabelForIndex: function(index, datasetIndex) {
-                return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
-            },
-            // Utils
-            getPixelForValue: function(value) {
-                // This must be called after fit has been run so that
-                // this.left, this.top, this.right, and this.bottom have been defined
-                var me = this;
-                var start = me.start;
-
-                var rightValue = +me.getRightValue(value);
-                var pixel;
-                var range = me.end - start;
-
-                if (me.isHorizontal()) {
-                    pixel = me.left + (me.width / range * (rightValue - start));
-                    return Math.round(pixel);
-                }
-
-                pixel = me.bottom - (me.height / range * (rightValue - start));
-                return Math.round(pixel);
-            },
-            getValueForPixel: function(pixel) {
-                var me = this;
-                var isHorizontal = me.isHorizontal();
-                var innerDimension = isHorizontal ? me.width : me.height;
-                var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;
-                return me.start + ((me.end - me.start) * offset);
-            },
-            getPixelForTick: function(index) {
-                return this.getPixelForValue(this.ticksAsNumbers[index]);
-            }
-        });
-        Chart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);
-
-    };
-
-},{}],46:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers,
-            noop = helpers.noop;
-
-        Chart.LinearScaleBase = Chart.Scale.extend({
-            handleTickRangeOptions: function() {
-                var me = this;
-                var opts = me.options;
-                var tickOpts = opts.ticks;
-
-                // If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
-                // do nothing since that would make the chart weird. If the user really wants a weird chart
-                // axis, they can manually override it
-                if (tickOpts.beginAtZero) {
-                    var minSign = helpers.sign(me.min);
-                    var maxSign = helpers.sign(me.max);
-
-                    if (minSign < 0 && maxSign < 0) {
-                        // move the top up to 0
-                        me.max = 0;
-                    } else if (minSign > 0 && maxSign > 0) {
-                        // move the bottom down to 0
-                        me.min = 0;
-                    }
-                }
-
-                if (tickOpts.min !== undefined) {
-                    me.min = tickOpts.min;
-                } else if (tickOpts.suggestedMin !== undefined) {
-                    if (me.min === null) {
-                        me.min = tickOpts.suggestedMin;
-                    } else {
-                        me.min = Math.min(me.min, tickOpts.suggestedMin);
-                    }
-                }
-
-                if (tickOpts.max !== undefined) {
-                    me.max = tickOpts.max;
-                } else if (tickOpts.suggestedMax !== undefined) {
-                    if (me.max === null) {
-                        me.max = tickOpts.suggestedMax;
-                    } else {
-                        me.max = Math.max(me.max, tickOpts.suggestedMax);
-                    }
-                }
-
-                if (me.min === me.max) {
-                    me.max++;
-
-                    if (!tickOpts.beginAtZero) {
-                        me.min--;
-                    }
-                }
-            },
-            getTickLimit: noop,
-            handleDirectionalChanges: noop,
-
-            buildTicks: function() {
-                var me = this;
-                var opts = me.options;
-                var tickOpts = opts.ticks;
-
-                // Figure out what the max number of ticks we can support it is based on the size of
-                // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
-                // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
-                // the graph. Make sure we always have at least 2 ticks
-                var maxTicks = me.getTickLimit();
-                maxTicks = Math.max(2, maxTicks);
-
-                var numericGeneratorOptions = {
-                    maxTicks: maxTicks,
-                    min: tickOpts.min,
-                    max: tickOpts.max,
-                    stepSize: helpers.getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)
-                };
-                var ticks = me.ticks = Chart.Ticks.generators.linear(numericGeneratorOptions, me);
-
-                me.handleDirectionalChanges();
-
-                // At this point, we need to update our max and min given the tick values since we have expanded the
-                // range of the scale
-                me.max = helpers.max(ticks);
-                me.min = helpers.min(ticks);
-
-                if (tickOpts.reverse) {
-                    ticks.reverse();
-
-                    me.start = me.max;
-                    me.end = me.min;
-                } else {
-                    me.start = me.min;
-                    me.end = me.max;
-                }
-            },
-            convertTicksToLabels: function() {
-                var me = this;
-                me.ticksAsNumbers = me.ticks.slice();
-                me.zeroLineIndex = me.ticks.indexOf(0);
-
-                Chart.Scale.prototype.convertTicksToLabels.call(me);
-            }
-        });
-    };
-
-},{}],47:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-
-        var defaultConfig = {
-            position: 'left',
-
-            // label settings
-            ticks: {
-                callback: Chart.Ticks.formatters.logarithmic
-            }
-        };
-
-        var LogarithmicScale = Chart.Scale.extend({
-            determineDataLimits: function() {
-                var me = this;
-                var opts = me.options;
-                var tickOpts = opts.ticks;
-                var chart = me.chart;
-                var data = chart.data;
-                var datasets = data.datasets;
-                var getValueOrDefault = helpers.getValueOrDefault;
-                var isHorizontal = me.isHorizontal();
-                function IDMatches(meta) {
-                    return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
-                }
-
-                // Calculate Range
-                me.min = null;
-                me.max = null;
-                me.minNotZero = null;
-
-                var hasStacks = opts.stacked;
-                if (hasStacks === undefined) {
-                    helpers.each(datasets, function(dataset, datasetIndex) {
-                        if (hasStacks) {
-                            return;
-                        }
-
-                        var meta = chart.getDatasetMeta(datasetIndex);
-                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
-                            meta.stack !== undefined) {
-                            hasStacks = true;
-                        }
-                    });
-                }
-
-                if (opts.stacked || hasStacks) {
-                    var valuesPerStack = {};
-
-                    helpers.each(datasets, function(dataset, datasetIndex) {
-                        var meta = chart.getDatasetMeta(datasetIndex);
-                        var key = [
-                            meta.type,
-                            // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
-                            ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
-                            meta.stack
-                        ].join('.');
-
-                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-                            if (valuesPerStack[key] === undefined) {
-                                valuesPerStack[key] = [];
-                            }
-
-                            helpers.each(dataset.data, function(rawValue, index) {
-                                var values = valuesPerStack[key];
-                                var value = +me.getRightValue(rawValue);
-                                if (isNaN(value) || meta.data[index].hidden) {
-                                    return;
-                                }
-
-                                values[index] = values[index] || 0;
-
-                                if (opts.relativePoints) {
-                                    values[index] = 100;
-                                } else {
-                                    // Don't need to split positive and negative since the log scale can't handle a 0 crossing
-                                    values[index] += value;
-                                }
-                            });
-                        }
-                    });
-
-                    helpers.each(valuesPerStack, function(valuesForType) {
-                        var minVal = helpers.min(valuesForType);
-                        var maxVal = helpers.max(valuesForType);
-                        me.min = me.min === null ? minVal : Math.min(me.min, minVal);
-                        me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
-                    });
-
-                } else {
-                    helpers.each(datasets, function(dataset, datasetIndex) {
-                        var meta = chart.getDatasetMeta(datasetIndex);
-                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-                            helpers.each(dataset.data, function(rawValue, index) {
-                                var value = +me.getRightValue(rawValue);
-                                if (isNaN(value) || meta.data[index].hidden) {
-                                    return;
-                                }
-
-                                if (me.min === null) {
-                                    me.min = value;
-                                } else if (value < me.min) {
-                                    me.min = value;
-                                }
-
-                                if (me.max === null) {
-                                    me.max = value;
-                                } else if (value > me.max) {
-                                    me.max = value;
-                                }
-
-                                if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {
-                                    me.minNotZero = value;
-                                }
-                            });
-                        }
-                    });
-                }
-
-                me.min = getValueOrDefault(tickOpts.min, me.min);
-                me.max = getValueOrDefault(tickOpts.max, me.max);
-
-                if (me.min === me.max) {
-                    if (me.min !== 0 && me.min !== null) {
-                        me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);
-                        me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);
-                    } else {
-                        me.min = 1;
-                        me.max = 10;
-                    }
-                }
-            },
-            buildTicks: function() {
-                var me = this;
-                var opts = me.options;
-                var tickOpts = opts.ticks;
-
-                var generationOptions = {
-                    min: tickOpts.min,
-                    max: tickOpts.max
-                };
-                var ticks = me.ticks = Chart.Ticks.generators.logarithmic(generationOptions, me);
-
-                if (!me.isHorizontal()) {
-                    // We are in a vertical orientation. The top value is the highest. So reverse the array
-                    ticks.reverse();
-                }
-
-                // At this point, we need to update our max and min given the tick values since we have expanded the
-                // range of the scale
-                me.max = helpers.max(ticks);
-                me.min = helpers.min(ticks);
-
-                if (tickOpts.reverse) {
-                    ticks.reverse();
-
-                    me.start = me.max;
-                    me.end = me.min;
-                } else {
-                    me.start = me.min;
-                    me.end = me.max;
-                }
-            },
-            convertTicksToLabels: function() {
-                this.tickValues = this.ticks.slice();
-
-                Chart.Scale.prototype.convertTicksToLabels.call(this);
-            },
-            // Get the correct tooltip label
-            getLabelForIndex: function(index, datasetIndex) {
-                return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
-            },
-            getPixelForTick: function(index) {
-                return this.getPixelForValue(this.tickValues[index]);
-            },
-            getPixelForValue: function(value) {
-                var me = this;
-                var innerDimension;
-                var pixel;
-
-                var start = me.start;
-                var newVal = +me.getRightValue(value);
-                var range;
-                var opts = me.options;
-                var tickOpts = opts.ticks;
-
-                if (me.isHorizontal()) {
-                    range = helpers.log10(me.end) - helpers.log10(start); // todo: if start === 0
-                    if (newVal === 0) {
-                        pixel = me.left;
-                    } else {
-                        innerDimension = me.width;
-                        pixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
-                    }
-                } else {
-                    // Bottom - top since pixels increase downward on a screen
-                    innerDimension = me.height;
-                    if (start === 0 && !tickOpts.reverse) {
-                        range = helpers.log10(me.end) - helpers.log10(me.minNotZero);
-                        if (newVal === start) {
-                            pixel = me.bottom;
-                        } else if (newVal === me.minNotZero) {
-                            pixel = me.bottom - innerDimension * 0.02;
-                        } else {
-                            pixel = me.bottom - innerDimension * 0.02 - (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));
-                        }
-                    } else if (me.end === 0 && tickOpts.reverse) {
-                        range = helpers.log10(me.start) - helpers.log10(me.minNotZero);
-                        if (newVal === me.end) {
-                            pixel = me.top;
-                        } else if (newVal === me.minNotZero) {
-                            pixel = me.top + innerDimension * 0.02;
-                        } else {
-                            pixel = me.top + innerDimension * 0.02 + (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));
-                        }
-                    } else if (newVal === 0) {
-                        pixel = tickOpts.reverse ? me.top : me.bottom;
-                    } else {
-                        range = helpers.log10(me.end) - helpers.log10(start);
-                        innerDimension = me.height;
-                        pixel = me.bottom - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
-                    }
-                }
-                return pixel;
-            },
-            getValueForPixel: function(pixel) {
-                var me = this;
-                var range = helpers.log10(me.end) - helpers.log10(me.start);
-                var value, innerDimension;
-
-                if (me.isHorizontal()) {
-                    innerDimension = me.width;
-                    value = me.start * Math.pow(10, (pixel - me.left) * range / innerDimension);
-                } else {  // todo: if start === 0
-                    innerDimension = me.height;
-                    value = Math.pow(10, (me.bottom - pixel) * range / innerDimension) / me.start;
-                }
-                return value;
-            }
-        });
-        Chart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);
-
-    };
-
-},{}],48:[function(require,module,exports){
-    'use strict';
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-        var globalDefaults = Chart.defaults.global;
-
-        var defaultConfig = {
-            display: true,
-
-            // Boolean - Whether to animate scaling the chart from the centre
-            animate: true,
-            position: 'chartArea',
-
-            angleLines: {
-                display: true,
-                color: 'rgba(0, 0, 0, 0.1)',
-                lineWidth: 1
-            },
-
-            gridLines: {
-                circular: false
-            },
-
-            // label settings
-            ticks: {
-                // Boolean - Show a backdrop to the scale label
-                showLabelBackdrop: true,
-
-                // String - The colour of the label backdrop
-                backdropColor: 'rgba(255,255,255,0.75)',
-
-                // Number - The backdrop padding above & below the label in pixels
-                backdropPaddingY: 2,
-
-                // Number - The backdrop padding to the side of the label in pixels
-                backdropPaddingX: 2,
-
-                callback: Chart.Ticks.formatters.linear
-            },
-
-            pointLabels: {
-                // Boolean - if true, show point labels
-                display: true,
-
-                // Number - Point label font size in pixels
-                fontSize: 10,
-
-                // Function - Used to convert point labels
-                callback: function(label) {
-                    return label;
-                }
-            }
-        };
-
-        function getValueCount(scale) {
-            var opts = scale.options;
-            return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;
-        }
-
-        function getPointLabelFontOptions(scale) {
-            var pointLabelOptions = scale.options.pointLabels;
-            var fontSize = helpers.getValueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);
-            var fontStyle = helpers.getValueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);
-            var fontFamily = helpers.getValueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);
-            var font = helpers.fontString(fontSize, fontStyle, fontFamily);
-
-            return {
-                size: fontSize,
-                style: fontStyle,
-                family: fontFamily,
-                font: font
-            };
-        }
-
-        function measureLabelSize(ctx, fontSize, label) {
-            if (helpers.isArray(label)) {
-                return {
-                    w: helpers.longestText(ctx, ctx.font, label),
-                    h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)
-                };
-            }
-
-            return {
-                w: ctx.measureText(label).width,
-                h: fontSize
-            };
-        }
-
-        function determineLimits(angle, pos, size, min, max) {
-            if (angle === min || angle === max) {
-                return {
-                    start: pos - (size / 2),
-                    end: pos + (size / 2)
-                };
-            } else if (angle < min || angle > max) {
-                return {
-                    start: pos - size - 5,
-                    end: pos
-                };
-            }
-
-            return {
-                start: pos,
-                end: pos + size + 5
-            };
-        }
-
-        /**
-         * Helper function to fit a radial linear scale with point labels
-         */
-        function fitWithPointLabels(scale) {
-            /*
-             * Right, this is really confusing and there is a lot of maths going on here
-             * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
-             *
-             * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
-             *
-             * Solution:
-             *
-             * We assume the radius of the polygon is half the size of the canvas at first
-             * at each index we check if the text overlaps.
-             *
-             * Where it does, we store that angle and that index.
-             *
-             * After finding the largest index and angle we calculate how much we need to remove
-             * from the shape radius to move the point inwards by that x.
-             *
-             * We average the left and right distances to get the maximum shape radius that can fit in the box
-             * along with labels.
-             *
-             * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
-             * on each side, removing that from the size, halving it and adding the left x protrusion width.
-             *
-             * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
-             * and position it in the most space efficient manner
-             *
-             * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
-             */
-
-            var plFont = getPointLabelFontOptions(scale);
-
-            // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
-            // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
-            var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
-            var furthestLimits = {
-                r: scale.width,
-                l: 0,
-                t: scale.height,
-                b: 0
-            };
-            var furthestAngles = {};
-            var i;
-            var textSize;
-            var pointPosition;
-
-            scale.ctx.font = plFont.font;
-            scale._pointLabelSizes = [];
-
-            var valueCount = getValueCount(scale);
-            for (i = 0; i < valueCount; i++) {
-                pointPosition = scale.getPointPosition(i, largestPossibleRadius);
-                textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');
-                scale._pointLabelSizes[i] = textSize;
-
-                // Add quarter circle to make degree 0 mean top of circle
-                var angleRadians = scale.getIndexAngle(i);
-                var angle = helpers.toDegrees(angleRadians) % 360;
-                var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
-                var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
-
-                if (hLimits.start < furthestLimits.l) {
-                    furthestLimits.l = hLimits.start;
-                    furthestAngles.l = angleRadians;
-                }
-
-                if (hLimits.end > furthestLimits.r) {
-                    furthestLimits.r = hLimits.end;
-                    furthestAngles.r = angleRadians;
-                }
-
-                if (vLimits.start < furthestLimits.t) {
-                    furthestLimits.t = vLimits.start;
-                    furthestAngles.t = angleRadians;
-                }
-
-                if (vLimits.end > furthestLimits.b) {
-                    furthestLimits.b = vLimits.end;
-                    furthestAngles.b = angleRadians;
-                }
-            }
-
-            scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);
-        }
-
-        /**
-         * Helper function to fit a radial linear scale with no point labels
-         */
-        function fit(scale) {
-            var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
-            scale.drawingArea = Math.round(largestPossibleRadius);
-            scale.setCenterPoint(0, 0, 0, 0);
-        }
-
-        function getTextAlignForAngle(angle) {
-            if (angle === 0 || angle === 180) {
-                return 'center';
-            } else if (angle < 180) {
-                return 'left';
-            }
-
-            return 'right';
-        }
-
-        function fillText(ctx, text, position, fontSize) {
-            if (helpers.isArray(text)) {
-                var y = position.y;
-                var spacing = 1.5 * fontSize;
-
-                for (var i = 0; i < text.length; ++i) {
-                    ctx.fillText(text[i], position.x, y);
-                    y+= spacing;
-                }
-            } else {
-                ctx.fillText(text, position.x, position.y);
-            }
-        }
-
-        function adjustPointPositionForLabelHeight(angle, textSize, position) {
-            if (angle === 90 || angle === 270) {
-                position.y -= (textSize.h / 2);
-            } else if (angle > 270 || angle < 90) {
-                position.y -= textSize.h;
-            }
-        }
-
-        function drawPointLabels(scale) {
-            var ctx = scale.ctx;
-            var getValueOrDefault = helpers.getValueOrDefault;
-            var opts = scale.options;
-            var angleLineOpts = opts.angleLines;
-            var pointLabelOpts = opts.pointLabels;
-
-            ctx.lineWidth = angleLineOpts.lineWidth;
-            ctx.strokeStyle = angleLineOpts.color;
-
-            var outerDistance = scale.getDistanceFromCenterForValue(opts.reverse ? scale.min : scale.max);
-
-            // Point Label Font
-            var plFont = getPointLabelFontOptions(scale);
-
-            ctx.textBaseline = 'top';
-
-            for (var i = getValueCount(scale) - 1; i >= 0; i--) {
-                if (angleLineOpts.display) {
-                    var outerPosition = scale.getPointPosition(i, outerDistance);
-                    ctx.beginPath();
-                    ctx.moveTo(scale.xCenter, scale.yCenter);
-                    ctx.lineTo(outerPosition.x, outerPosition.y);
-                    ctx.stroke();
-                    ctx.closePath();
-                }
-
-                if (pointLabelOpts.display) {
-                    // Extra 3px out for some label spacing
-                    var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
-
-                    // Keep this in loop since we may support array properties here
-                    var pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);
-                    ctx.font = plFont.font;
-                    ctx.fillStyle = pointLabelFontColor;
-
-                    var angleRadians = scale.getIndexAngle(i);
-                    var angle = helpers.toDegrees(angleRadians);
-                    ctx.textAlign = getTextAlignForAngle(angle);
-                    adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);
-                    fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);
-                }
-            }
-        }
-
-        function drawRadiusLine(scale, gridLineOpts, radius, index) {
-            var ctx = scale.ctx;
-            ctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);
-            ctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
-
-            if (scale.options.gridLines.circular) {
-                // Draw circular arcs between the points
-                ctx.beginPath();
-                ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);
-                ctx.closePath();
-                ctx.stroke();
-            } else {
-                // Draw straight lines connecting each index
-                var valueCount = getValueCount(scale);
-
-                if (valueCount === 0) {
-                    return;
-                }
-
-                ctx.beginPath();
-                var pointPosition = scale.getPointPosition(0, radius);
-                ctx.moveTo(pointPosition.x, pointPosition.y);
-
-                for (var i = 1; i < valueCount; i++) {
-                    pointPosition = scale.getPointPosition(i, radius);
-                    ctx.lineTo(pointPosition.x, pointPosition.y);
-                }
-
-                ctx.closePath();
-                ctx.stroke();
-            }
-        }
-
-        function numberOrZero(param) {
-            return helpers.isNumber(param) ? param : 0;
-        }
-
-        var LinearRadialScale = Chart.LinearScaleBase.extend({
-            setDimensions: function() {
-                var me = this;
-                var opts = me.options;
-                var tickOpts = opts.ticks;
-                // Set the unconstrained dimension before label rotation
-                me.width = me.maxWidth;
-                me.height = me.maxHeight;
-                me.xCenter = Math.round(me.width / 2);
-                me.yCenter = Math.round(me.height / 2);
-
-                var minSize = helpers.min([me.height, me.width]);
-                var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-                me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);
-            },
-            determineDataLimits: function() {
-                var me = this;
-                var chart = me.chart;
-                var min = Number.POSITIVE_INFINITY;
-                var max = Number.NEGATIVE_INFINITY;
-
-                helpers.each(chart.data.datasets, function(dataset, datasetIndex) {
-                    if (chart.isDatasetVisible(datasetIndex)) {
-                        var meta = chart.getDatasetMeta(datasetIndex);
-
-                        helpers.each(dataset.data, function(rawValue, index) {
-                            var value = +me.getRightValue(rawValue);
-                            if (isNaN(value) || meta.data[index].hidden) {
-                                return;
-                            }
-
-                            min = Math.min(value, min);
-                            max = Math.max(value, max);
-                        });
-                    }
-                });
-
-                me.min = (min === Number.POSITIVE_INFINITY ? 0 : min);
-                me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);
-
-                // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
-                me.handleTickRangeOptions();
-            },
-            getTickLimit: function() {
-                var tickOpts = this.options.ticks;
-                var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-                return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));
-            },
-            convertTicksToLabels: function() {
-                var me = this;
-                Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);
-
-                // Point labels
-                me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);
-            },
-            getLabelForIndex: function(index, datasetIndex) {
-                return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
-            },
-            fit: function() {
-                if (this.options.pointLabels.display) {
-                    fitWithPointLabels(this);
-                } else {
-                    fit(this);
-                }
-            },
-            /**
-             * Set radius reductions and determine new radius and center point
-             * @private
-             */
-            setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {
-                var me = this;
-                var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
-                var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);
-                var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
-                var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);
-
-                radiusReductionLeft = numberOrZero(radiusReductionLeft);
-                radiusReductionRight = numberOrZero(radiusReductionRight);
-                radiusReductionTop = numberOrZero(radiusReductionTop);
-                radiusReductionBottom = numberOrZero(radiusReductionBottom);
-
-                me.drawingArea = Math.min(
-                    Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),
-                    Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));
-                me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);
-            },
-            setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {
-                var me = this;
-                var maxRight = me.width - rightMovement - me.drawingArea,
-                    maxLeft = leftMovement + me.drawingArea,
-                    maxTop = topMovement + me.drawingArea,
-                    maxBottom = me.height - bottomMovement - me.drawingArea;
-
-                me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);
-                me.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);
-            },
-
-            getIndexAngle: function(index) {
-                var angleMultiplier = (Math.PI * 2) / getValueCount(this);
-                var startAngle = this.chart.options && this.chart.options.startAngle ?
-                    this.chart.options.startAngle :
-                    0;
-
-                var startAngleRadians = startAngle * Math.PI * 2 / 360;
-
-                // Start from the top instead of right, so remove a quarter of the circle
-                return index * angleMultiplier + startAngleRadians;
-            },
-            getDistanceFromCenterForValue: function(value) {
-                var me = this;
-
-                if (value === null) {
-                    return 0; // null always in center
-                }
-
-                // Take into account half font size + the yPadding of the top value
-                var scalingFactor = me.drawingArea / (me.max - me.min);
-                if (me.options.reverse) {
-                    return (me.max - value) * scalingFactor;
-                }
-                return (value - me.min) * scalingFactor;
-            },
-            getPointPosition: function(index, distanceFromCenter) {
-                var me = this;
-                var thisAngle = me.getIndexAngle(index) - (Math.PI / 2);
-                return {
-                    x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,
-                    y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter
-                };
-            },
-            getPointPositionForValue: function(index, value) {
-                return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
-            },
-
-            getBasePosition: function() {
-                var me = this;
-                var min = me.min;
-                var max = me.max;
-
-                return me.getPointPositionForValue(0,
-                    me.beginAtZero? 0:
-                        min < 0 && max < 0? max :
-                            min > 0 && max > 0? min :
-                                0);
-            },
-
-            draw: function() {
-                var me = this;
-                var opts = me.options;
-                var gridLineOpts = opts.gridLines;
-                var tickOpts = opts.ticks;
-                var getValueOrDefault = helpers.getValueOrDefault;
-
-                if (opts.display) {
-                    var ctx = me.ctx;
-
-                    // Tick Font
-                    var tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-                    var tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
-                    var tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
-                    var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-
-                    helpers.each(me.ticks, function(label, index) {
-                        // Don't draw a centre value (if it is minimum)
-                        if (index > 0 || opts.reverse) {
-                            var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
-                            var yHeight = me.yCenter - yCenterOffset;
-
-                            // Draw circular lines around the scale
-                            if (gridLineOpts.display && index !== 0) {
-                                drawRadiusLine(me, gridLineOpts, yCenterOffset, index);
-                            }
-
-                            if (tickOpts.display) {
-                                var tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);
-                                ctx.font = tickLabelFont;
-
-                                if (tickOpts.showLabelBackdrop) {
-                                    var labelWidth = ctx.measureText(label).width;
-                                    ctx.fillStyle = tickOpts.backdropColor;
-                                    ctx.fillRect(
-                                        me.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,
-                                        yHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,
-                                        labelWidth + tickOpts.backdropPaddingX * 2,
-                                        tickFontSize + tickOpts.backdropPaddingY * 2
-                                    );
-                                }
-
-                                ctx.textAlign = 'center';
-                                ctx.textBaseline = 'middle';
-                                ctx.fillStyle = tickFontColor;
-                                ctx.fillText(label, me.xCenter, yHeight);
-                            }
-                        }
-                    });
-
-                    if (opts.angleLines.display || opts.pointLabels.display) {
-                        drawPointLabels(me);
-                    }
-                }
-            }
-        });
-        Chart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);
-
-    };
-
-},{}],49:[function(require,module,exports){
-    /* global window: false */
-    'use strict';
-
-    var moment = require(1);
-    moment = typeof(moment) === 'function' ? moment : window.moment;
-
-    module.exports = function(Chart) {
-
-        var helpers = Chart.helpers;
-        var interval = {
-            millisecond: {
-                size: 1,
-                steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
-            },
-            second: {
-                size: 1000,
-                steps: [1, 2, 5, 10, 30]
-            },
-            minute: {
-                size: 60000,
-                steps: [1, 2, 5, 10, 30]
-            },
-            hour: {
-                size: 3600000,
-                steps: [1, 2, 3, 6, 12]
-            },
-            day: {
-                size: 86400000,
-                steps: [1, 2, 5]
-            },
-            week: {
-                size: 604800000,
-                maxStep: 4
-            },
-            month: {
-                size: 2.628e9,
-                maxStep: 3
-            },
-            quarter: {
-                size: 7.884e9,
-                maxStep: 4
-            },
-            year: {
-                size: 3.154e10,
-                maxStep: false
-            }
-        };
-
-        var defaultConfig = {
-            position: 'bottom',
-
-            time: {
-                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
-                format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
-                unit: false, // false == automatic or override with week, month, year, etc.
-                round: false, // none, or override with week, month, year, etc.
-                displayFormat: false, // DEPRECATED
-                isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/
-                minUnit: 'millisecond',
-
-                // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
-                displayFormats: {
-                    millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,
-                    second: 'h:mm:ss a', // 11:20:01 AM
-                    minute: 'h:mm:ss a', // 11:20:01 AM
-                    hour: 'MMM D, hA', // Sept 4, 5PM
-                    day: 'll', // Sep 4 2015
-                    week: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
-                    month: 'MMM YYYY', // Sept 2015
-                    quarter: '[Q]Q - YYYY', // Q3
-                    year: 'YYYY' // 2015
-                },
-            },
-            ticks: {
-                autoSkip: false
-            }
-        };
-
-        /**
-         * Helper function to parse time to a moment object
-         * @param axis {TimeAxis} the time axis
-         * @param label {Date|string|number|Moment} The thing to parse
-         * @return {Moment} parsed time
-         */
-        function parseTime(axis, label) {
-            var timeOpts = axis.options.time;
-            if (typeof timeOpts.parser === 'string') {
-                return moment(label, timeOpts.parser);
-            }
-            if (typeof timeOpts.parser === 'function') {
-                return timeOpts.parser(label);
-            }
-            if (typeof label.getMonth === 'function' || typeof label === 'number') {
-                // Date objects
-                return moment(label);
-            }
-            if (label.isValid && label.isValid()) {
-                // Moment support
-                return label;
-            }
-            var format = timeOpts.format;
-            if (typeof format !== 'string' && format.call) {
-                // Custom parsing (return an instance of moment)
-                console.warn('options.time.format is deprecated and replaced by options.time.parser.');
-                return format(label);
-            }
-            // Moment format parsing
-            return moment(label, format);
-        }
-
-        /**
-         * Figure out which is the best unit for the scale
-         * @param minUnit {String} minimum unit to use
-         * @param min {Number} scale minimum
-         * @param max {Number} scale maximum
-         * @return {String} the unit to use
-         */
-        function determineUnit(minUnit, min, max, maxTicks) {
-            var units = Object.keys(interval);
-            var unit;
-            var numUnits = units.length;
-
-            for (var i = units.indexOf(minUnit); i < numUnits; i++) {
-                unit = units[i];
-                var unitDetails = interval[unit];
-                var steps = (unitDetails.steps && unitDetails.steps[unitDetails.steps.length - 1]) || unitDetails.maxStep;
-                if (steps === undefined || Math.ceil((max - min) / (steps * unitDetails.size)) <= maxTicks) {
-                    break;
-                }
-            }
-
-            return unit;
-        }
-
-        /**
-         * Determines how we scale the unit
-         * @param min {Number} the scale minimum
-         * @param max {Number} the scale maximum
-         * @param unit {String} the unit determined by the {@see determineUnit} method
-         * @return {Number} the axis step size as a multiple of unit
-         */
-        function determineStepSize(min, max, unit, maxTicks) {
-            // Using our unit, figoure out what we need to scale as
-            var unitDefinition = interval[unit];
-            var unitSizeInMilliSeconds = unitDefinition.size;
-            var sizeInUnits = Math.ceil((max - min) / unitSizeInMilliSeconds);
-            var multiplier = 1;
-            var range = max - min;
-
-            if (unitDefinition.steps) {
-                // Have an array of steps
-                var numSteps = unitDefinition.steps.length;
-                for (var i = 0; i < numSteps && sizeInUnits > maxTicks; i++) {
-                    multiplier = unitDefinition.steps[i];
-                    sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
-                }
-            } else {
-                while (sizeInUnits > maxTicks && maxTicks > 0) {
-                    ++multiplier;
-                    sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
-                }
-            }
-
-            return multiplier;
-        }
-
-        /**
-         * Helper for generating axis labels.
-         * @param options {ITimeGeneratorOptions} the options for generation
-         * @param dataRange {IRange} the data range
-         * @param niceRange {IRange} the pretty range to display
-         * @return {Number[]} ticks
-         */
-        function generateTicks(options, dataRange, niceRange) {
-            var ticks = [];
-            if (options.maxTicks) {
-                var stepSize = options.stepSize;
-                ticks.push(options.min !== undefined ? options.min : niceRange.min);
-                var cur = moment(niceRange.min);
-                while (cur.add(stepSize, options.unit).valueOf() < niceRange.max) {
-                    ticks.push(cur.valueOf());
-                }
-                var realMax = options.max || niceRange.max;
-                if (ticks[ticks.length - 1] !== realMax) {
-                    ticks.push(realMax);
-                }
-            }
-            return ticks;
-        }
-
-        /**
-         * @function Chart.Ticks.generators.time
-         * @param options {ITimeGeneratorOptions} the options for generation
-         * @param dataRange {IRange} the data range
-         * @return {Number[]} ticks
-         */
-        Chart.Ticks.generators.time = function(options, dataRange) {
-            var niceMin;
-            var niceMax;
-            var isoWeekday = options.isoWeekday;
-            if (options.unit === 'week' && isoWeekday !== false) {
-                niceMin = moment(dataRange.min).startOf('isoWeek').isoWeekday(isoWeekday).valueOf();
-                niceMax = moment(dataRange.max).startOf('isoWeek').isoWeekday(isoWeekday);
-                if (dataRange.max - niceMax > 0) {
-                    niceMax.add(1, 'week');
-                }
-                niceMax = niceMax.valueOf();
-            } else {
-                niceMin = moment(dataRange.min).startOf(options.unit).valueOf();
-                niceMax = moment(dataRange.max).startOf(options.unit);
-                if (dataRange.max - niceMax > 0) {
-                    niceMax.add(1, options.unit);
-                }
-                niceMax = niceMax.valueOf();
-            }
-            return generateTicks(options, dataRange, {
-                min: niceMin,
-                max: niceMax
-            });
-        };
-
-        var TimeScale = Chart.Scale.extend({
-            initialize: function() {
-                if (!moment) {
-                    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');
-                }
-
-                Chart.Scale.prototype.initialize.call(this);
-            },
-            determineDataLimits: function() {
-                var me = this;
-                var timeOpts = me.options.time;
-
-                // We store the data range as unix millisecond timestamps so dataMin and dataMax will always be integers.
-                var dataMin = Number.MAX_SAFE_INTEGER;
-                var dataMax = Number.MIN_SAFE_INTEGER;
-
-                var chartData = me.chart.data;
-                var parsedData = {
-                    labels: [],
-                    datasets: []
-                };
-
-                var timestamp;
-
-                helpers.each(chartData.labels, function(label, labelIndex) {
-                    var labelMoment = parseTime(me, label);
-
-                    if (labelMoment.isValid()) {
-                        // We need to round the time
-                        if (timeOpts.round) {
-                            labelMoment.startOf(timeOpts.round);
-                        }
-
-                        timestamp = labelMoment.valueOf();
-                        dataMin = Math.min(timestamp, dataMin);
-                        dataMax = Math.max(timestamp, dataMax);
-
-                        // Store this value for later
-                        parsedData.labels[labelIndex] = timestamp;
-                    }
-                });
-
-                helpers.each(chartData.datasets, function(dataset, datasetIndex) {
-                    var timestamps = [];
-
-                    if (typeof dataset.data[0] === 'object' && dataset.data[0] !== null && me.chart.isDatasetVisible(datasetIndex)) {
-                        // We have potential point data, so we need to parse this
-                        helpers.each(dataset.data, function(value, dataIndex) {
-                            var dataMoment = parseTime(me, me.getRightValue(value));
-
-                            if (dataMoment.isValid()) {
-                                if (timeOpts.round) {
-                                    dataMoment.startOf(timeOpts.round);
-                                }
-
-                                timestamp = dataMoment.valueOf();
-                                dataMin = Math.min(timestamp, dataMin);
-                                dataMax = Math.max(timestamp, dataMax);
-                                timestamps[dataIndex] = timestamp;
-                            }
-                        });
-                    } else {
-                        // We have no x coordinates, so use the ones from the labels
-                        timestamps = parsedData.labels.slice();
-                    }
-
-                    parsedData.datasets[datasetIndex] = timestamps;
-                });
-
-                me.dataMin = dataMin;
-                me.dataMax = dataMax;
-                me._parsedData = parsedData;
-            },
-            buildTicks: function() {
-                var me = this;
-                var timeOpts = me.options.time;
-
-                var minTimestamp;
-                var maxTimestamp;
-                var dataMin = me.dataMin;
-                var dataMax = me.dataMax;
-
-                if (timeOpts.min) {
-                    var minMoment = parseTime(me, timeOpts.min);
-                    if (timeOpts.round) {
-                        minMoment.round(timeOpts.round);
-                    }
-                    minTimestamp = minMoment.valueOf();
-                }
-
-                if (timeOpts.max) {
-                    maxTimestamp = parseTime(me, timeOpts.max).valueOf();
-                }
-
-                var maxTicks = me.getLabelCapacity(minTimestamp || dataMin);
-                var unit = timeOpts.unit || determineUnit(timeOpts.minUnit, minTimestamp || dataMin, maxTimestamp || dataMax, maxTicks);
-                me.displayFormat = timeOpts.displayFormats[unit];
-
-                var stepSize = timeOpts.stepSize || determineStepSize(minTimestamp || dataMin, maxTimestamp || dataMax, unit, maxTicks);
-                me.ticks = Chart.Ticks.generators.time({
-                    maxTicks: maxTicks,
-                    min: minTimestamp,
-                    max: maxTimestamp,
-                    stepSize: stepSize,
-                    unit: unit,
-                    isoWeekday: timeOpts.isoWeekday
-                }, {
-                    min: dataMin,
-                    max: dataMax
-                });
-
-                // At this point, we need to update our max and min given the tick values since we have expanded the
-                // range of the scale
-                me.max = helpers.max(me.ticks);
-                me.min = helpers.min(me.ticks);
-            },
-            // Get tooltip label
-            getLabelForIndex: function(index, datasetIndex) {
-                var me = this;
-                var label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';
-                var value = me.chart.data.datasets[datasetIndex].data[index];
-
-                if (value !== null && typeof value === 'object') {
-                    label = me.getRightValue(value);
-                }
-
-                // Format nicely
-                if (me.options.time.tooltipFormat) {
-                    label = parseTime(me, label).format(me.options.time.tooltipFormat);
-                }
-
-                return label;
-            },
-            // Function to format an individual tick mark
-            tickFormatFunction: function(tick, index, ticks) {
-                var formattedTick = tick.format(this.displayFormat);
-                var tickOpts = this.options.ticks;
-                var callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);
-
-                if (callback) {
-                    return callback(formattedTick, index, ticks);
-                }
-                return formattedTick;
-            },
-            convertTicksToLabels: function() {
-                var me = this;
-                me.ticksAsTimestamps = me.ticks;
-                me.ticks = me.ticks.map(function(tick) {
-                    return moment(tick);
-                }).map(me.tickFormatFunction, me);
-            },
-            getPixelForOffset: function(offset) {
-                var me = this;
-                var epochWidth = me.max - me.min;
-                var decimal = epochWidth ? (offset - me.min) / epochWidth : 0;
-
-                if (me.isHorizontal()) {
-                    var valueOffset = (me.width * decimal);
-                    return me.left + Math.round(valueOffset);
-                }
-
-                var heightOffset = (me.height * decimal);
-                return me.top + Math.round(heightOffset);
-            },
-            getPixelForValue: function(value, index, datasetIndex) {
-                var me = this;
-                var offset = null;
-                if (index !== undefined && datasetIndex !== undefined) {
-                    offset = me._parsedData.datasets[datasetIndex][index];
-                }
-
-                if (offset === null) {
-                    if (!value || !value.isValid) {
-                        // not already a moment object
-                        value = parseTime(me, me.getRightValue(value));
-                    }
-
-                    if (value && value.isValid && value.isValid()) {
-                        offset = value.valueOf();
-                    }
-                }
-
-                if (offset !== null) {
-                    return me.getPixelForOffset(offset);
-                }
-            },
-            getPixelForTick: function(index) {
-                return this.getPixelForOffset(this.ticksAsTimestamps[index]);
-            },
-            getValueForPixel: function(pixel) {
-                var me = this;
-                var innerDimension = me.isHorizontal() ? me.width : me.height;
-                var offset = (pixel - (me.isHorizontal() ? me.left : me.top)) / innerDimension;
-                return moment(me.min + (offset * (me.max - me.min)));
-            },
-            // Crude approximation of what the label width might be
-            getLabelWidth: function(label) {
-                var me = this;
-                var ticks = me.options.ticks;
-
-                var tickLabelWidth = me.ctx.measureText(label).width;
-                var cosRotation = Math.cos(helpers.toRadians(ticks.maxRotation));
-                var sinRotation = Math.sin(helpers.toRadians(ticks.maxRotation));
-                var tickFontSize = helpers.getValueOrDefault(ticks.fontSize, Chart.defaults.global.defaultFontSize);
-                return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
-            },
-            getLabelCapacity: function(exampleTime) {
-                var me = this;
-
-                me.displayFormat = me.options.time.displayFormats.millisecond;	// Pick the longest format for guestimation
-                var exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, []);
-                var tickLabelWidth = me.getLabelWidth(exampleLabel);
-
-                var innerWidth = me.isHorizontal() ? me.width : me.height;
-                var labelCapacity = innerWidth / tickLabelWidth;
-                return labelCapacity;
-            }
-        });
-        Chart.scaleService.registerScaleType('time', TimeScale, defaultConfig);
-
-    };
-
-},{"1":1}]},{},[7])(7)
-});
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/tp/Chart.min.js b/web/gui/src/main/webapp/tp/Chart.min.js
deleted file mode 100644
index cf50797..0000000
--- a/web/gui/src/main/webapp/tp/Chart.min.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/*!
- * Chart.js
- * http://chartjs.org/
- * Version: 2.6.0
- *
- * Copyright 2017 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,n,i){function a(r,l){if(!n[r]){if(!e[r]){var s="function"==typeof require&&require;if(!l&&s)return s(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[r]={exports:{}};e[r][0].call(d.exports,function(t){var n=e[r][1][t];return a(n?n:t)},d,d.exports,t,e,n,i)}return n[r].exports}for(var o="function"==typeof require&&require,r=0;r<i.length;r++)a(i[r]);return a}({1:[function(t,e,n){},{}],2:[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*)?\)$/,o=/(\w+)/,r=[0,0,0],l=1,s=t.match(e);if(s){s=s[1];for(var u=0;u<r.length;u++)r[u]=parseInt(s[u]+s[u],16)}else if(s=t.match(n)){s=s[1];for(var u=0;u<r.length;u++)r[u]=parseInt(s.slice(2*u,2*u+2),16)}else if(s=t.match(i)){for(var u=0;u<r.length;u++)r[u]=parseInt(s[u+1]);l=parseFloat(s[4])}else if(s=t.match(a)){for(var u=0;u<r.length;u++)r[u]=Math.round(2.55*parseFloat(s[u+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 u=0;u<r.length;u++)r[u]=b(r[u],0,255);return l=l||0==l?b(l,0,1):1,r[3]=l,r}}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),o=b(parseFloat(n[2]),0,100),r=b(parseFloat(n[3]),0,100),l=b(isNaN(i)?1:i,0,1);return[a,o,r,l]}}}function o(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),o=b(parseFloat(n[2]),0,100),r=b(parseFloat(n[3]),0,100),l=b(isNaN(i)?1:i,0,1);return[a,o,r,l]}}}function r(t){var e=i(t);return e&&e.slice(0,3)}function l(t){var e=a(t);return e&&e.slice(0,3)}function s(t){var e=i(t);return e?e[3]:(e=a(t))?e[3]:(e=o(t))?e[3]:void 0}function u(t){return"#"+x(t[0])+x(t[1])+x(t[2])}function d(t,e){return e<1||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(e<1||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 e<1||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 x(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y=t(6);e.exports={getRgba:i,getHsla:a,getRgb:r,getHsl:l,getHwb:o,getAlpha:s,hexString:u,rgbString:d,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:p,hwbString:m,keyword:v};var k={};for(var w in y)k[y[w]]=w},{6:6}],3:[function(t,e,n){var i=t(5),a=t(2),o=function(t){if(t instanceof o)return t;if(!(this instanceof o))return new o(t);this.valid=!1,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;"string"==typeof t?(e=a.getRgba(t),e?this.setValues("rgb",e):(e=a.getHsla(t))?this.setValues("hsl",e):(e=a.getHwb(t))&&this.setValues("hwb",e)):"object"==typeof t&&(e=t,void 0!==e.r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e))};o.prototype={isValid:function(){return this.valid},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=t<0?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]=i<=.03928?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 e<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;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]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=this,i=t,a=void 0===e?.5:e,o=2*a-1,r=n.alpha()-i.alpha(),l=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,s=1-l;return this.rgb(l*n.red()+s*i.red(),l*n.green()+s*i.green(),l*n.blue()+s*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new o,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},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,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},o.prototype.setValues=function(t,e){var n,a=this.values,o=this.spaces,r=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)a[t]=e.slice(0,t.length),l=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)];l=e.a}else if(void 0!==e[o[t][0]]){var s=o[t];for(n=0;n<t.length;n++)a[t][n]=e[s[n]];l=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===l?a.alpha:l)),"alpha"===t)return!1;var u;for(n=0;n<t.length;n++)u=Math.max(0,Math.min(r[t][n],a[t][n])),a[t][n]=Math.round(u);for(var d in o)d!==t&&(a[d]=i[t][d](a[t]));return!0},o.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)},o.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=o),e.exports=o},{2:2,5:5}],4:[function(t,e,n){function i(t){var e,n,i,a=t[0]/255,o=t[1]/255,r=t[2]/255,l=Math.min(a,o,r),s=Math.max(a,o,r),u=s-l;return s==l?e=0:a==s?e=(o-r)/u:o==s?e=2+(r-a)/u:r==s&&(e=4+(a-o)/u),e=Math.min(60*e,360),e<0&&(e+=360),i=(l+s)/2,n=s==l?0:i<=.5?u/(s+l):u/(2-s-l),[e,100*n,100*i]}function a(t){var e,n,i,a=t[0],o=t[1],r=t[2],l=Math.min(a,o,r),s=Math.max(a,o,r),u=s-l;return n=0==s?0:u/s*1e3/10,s==l?e=0:a==s?e=(o-r)/u:o==s?e=2+(r-a)/u:r==s&&(e=4+(a-o)/u),e=Math.min(60*e,360),e<0&&(e+=360),i=s/255*1e3/10,[e,n,i]}function o(t){var e=t[0],n=t[1],a=t[2],o=i(t)[0],r=1/255*Math.min(e,Math.min(n,a)),a=1-1/255*Math.max(e,Math.max(n,a));return[o,100*r,100*a]}function l(t){var e,n,i,a,o=t[0]/255,r=t[1]/255,l=t[2]/255;return a=Math.min(1-o,1-r,1-l),e=(1-o-a)/(1-a)||0,n=(1-r-a)/(1-a)||0,i=(1-l-a)/(1-a)||0,[100*e,100*n,100*i,100*a]}function s(t){return Z[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,o=.2126*e+.7152*n+.0722*i,r=.0193*e+.1192*n+.9505*i;return[100*a,100*o,100*r]}function d(t){var e,n,i,a=u(t),o=a[0],r=a[1],l=a[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,n=500*(o-r),i=200*(r-l),[e,n,i]}function c(t){return B(d(t))}function h(t){var e,n,i,a,o,r=t[0]/360,l=t[1]/100,s=t[2]/100;if(0==l)return o=255*s,[o,o,o];n=s<.5?s*(1+l):s+l-s*l,e=2*s-n,a=[0,0,0];for(var u=0;u<3;u++)i=r+1/3*-(u-1),i<0&&i++,i>1&&i--,o=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*o;return a}function f(t){var e,n,i=t[0],a=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,a*=o<=1?o:2-o,n=(o+a)/2,e=2*a/(o+a),[i,100*e,100*n])}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,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-n),l=255*i*(1-n*o),s=255*i*(1-n*(1-o)),i=255*i;switch(a){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,n,i=t[0],a=t[1]/100,o=t[2]/100;return n=(2-a)*o,e=a*o,e/=n<=1?n:2-n,e=e||0,n/=2,[i,100*e,100*n]}function k(t){return o(x(t))}function w(t){return l(x(t))}function M(t){return s(x(t))}function S(t){var e,n,i,a,o=t[0]/360,l=t[1]/100,s=t[2]/100,u=l+s;switch(u>1&&(l/=u,s/=u),e=Math.floor(6*o),n=1-s,i=6*o-e,0!=(1&e)&&(i=1-i),a=l+i*(n-l),e){default:case 6:case 0:r=n,g=a,b=l;break;case 1:r=a,g=n,b=l;break;case 2:r=l,g=n,b=a;break;case 3:r=l,g=a,b=n;break;case 4:r=a,g=l,b=n;break;case 5:r=n,g=l,b=a}return[255*r,255*g,255*b]}function C(t){return i(S(t))}function D(t){return a(S(t))}function I(t){return l(S(t))}function A(t){return s(S(t))}function P(t){var e,n,i,a=t[0]/100,o=t[1]/100,r=t[2]/100,l=t[3]/100;return e=1-Math.min(1,a*(1-l)+l),n=1-Math.min(1,o*(1-l)+l),i=1-Math.min(1,r*(1-l)+l),[255*e,255*n,255*i]}function _(t){return i(P(t))}function T(t){return a(P(t))}function F(t){return o(P(t))}function R(t){return s(P(t))}function L(t){var e,n,i,a=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*a+o*-1.5372+r*-.4986,n=a*-.9689+1.8758*o+.0415*r,i=.0557*a+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,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 V(t){var e,n,i,a=t[0],o=t[1],r=t[2];return a/=95.047,o/=100,r/=108.883,a=a>.008856?Math.pow(a,1/3):7.787*a+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,n=500*(a-o),i=200*(o-r),[e,n,i]}function O(t){return B(V(t))}function z(t){var e,n,i,a,o=t[0],r=t[1],l=t[2];return o<=8?(n=100*o/903.3,a=7.787*(n/100)+16/116):(n=100*Math.pow((o+16)/116,3),a=Math.pow(n/100,1/3)),e=e/95.047<=.008856?e=95.047*(r/500+a-16/116)/7.787:95.047*Math.pow(r/500+a,3),i=i/108.883<=.008859?i=108.883*(a-l/200-16/116)/7.787:108.883*Math.pow(a-l/200,3),[e,n,i]}function B(t){var e,n,i,a=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),n=360*e/2/Math.PI,n<0&&(n+=360),i=Math.sqrt(o*o+r*r),[a,i,n]}function W(t){return L(z(t))}function N(t){var e,n,i,a=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),n=o*Math.sin(i),[a,e,n]}function E(t){return z(N(t))}function H(t){return W(N(t))}function q(t){return J[t]}function j(t){return i(q(t))}function Y(t){return a(q(t))}function U(t){return o(q(t))}function X(t){return l(q(t))}function K(t){return d(q(t))}function G(t){return u(q(t))}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:l,rgb2keyword:s,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:w,hsv2keyword:M,hwb2rgb:S,hwb2hsl:C,hwb2hsv:D,hwb2cmyk:I,hwb2keyword:A,cmyk2rgb:P,cmyk2hsl:_,cmyk2hsv:T,cmyk2hwb:F,cmyk2keyword:R,keyword2rgb:q,keyword2hsl:j,keyword2hsv:Y,keyword2hwb:U,keyword2cmyk:X,keyword2lab:K,keyword2xyz:G,xyz2rgb:L,xyz2lab:V,xyz2lch:O,lab2xyz:z,lab2rgb:W,lab2lch:B,lch2lab:N,lch2xyz:E,lch2rgb:H};var J={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]},Z={};for(var Q in J)Z[JSON.stringify(J[Q])]=Q},{}],5:[function(t,e,n){var i=t(4),a=function(){return new u};for(var o in i){a[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];a[l]=a[l]||{},a[l][s]=a[o]=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}}(o)}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},{4:4}],6:[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]}},{}],7:[function(t,e,n){var i=t(28)();t(26)(i),t(40)(i),t(22)(i),t(25)(i),t(30)(i),t(21)(i),t(23)(i),t(24)(i),t(29)(i),t(32)(i),t(33)(i),t(31)(i),t(27)(i),t(34)(i),t(35)(i),t(36)(i),t(37)(i),t(38)(i),t(46)(i),t(44)(i),t(45)(i),t(47)(i),t(48)(i),t(49)(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);var a=[];a.push(t(41)(i),t(42)(i),t(43)(i)),i.plugins.register(a),e.exports=i,"undefined"!=typeof window&&(window.Chart=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,40:40,41:41,42:42,43:43,44:44,45:45,46:46,47:47,48:48,49:49,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.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(){return""},label:function(t){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(){var e,n=this;t.DatasetController.prototype.initialize.apply(n,arguments),e=n.getMeta(),e.stack=n.getDataset().stack,e.bar=!0},update:function(t){var e,n,i=this,a=i.getMeta().data;for(i._ruler=i.getRuler(),e=0,n=a.length;e<n;++e)i.updateElement(a[e],e,t)},updateElement:function(t,n,i){var a=this,o=a.chart,r=a.getMeta(),l=a.getDataset(),s=t.custom||{},u=o.options.elements.rectangle;t._xScale=a.getScaleForId(r.xAxisID),t._yScale=a.getScaleForId(r.yAxisID),t._datasetIndex=a.index,t._index=n,t._model={datasetLabel:l.label,label:o.data.labels[n],borderSkipped:s.borderSkipped?s.borderSkipped:u.borderSkipped,backgroundColor:s.backgroundColor?s.backgroundColor:e.getValueAtIndexOrDefault(l.backgroundColor,n,u.backgroundColor),borderColor:s.borderColor?s.borderColor:e.getValueAtIndexOrDefault(l.borderColor,n,u.borderColor),borderWidth:s.borderWidth?s.borderWidth:e.getValueAtIndexOrDefault(l.borderWidth,n,u.borderWidth)},a.updateElementGeometry(t,n,i),t.pivot()},updateElementGeometry:function(t,e,n){var i=this,a=t._model,o=i.getValueScale(),r=o.getBasePixel(),l=o.isHorizontal(),s=i._ruler||i.getRuler(),u=i.calculateBarValuePixels(i.index,e),d=i.calculateBarIndexPixels(i.index,e,s);a.horizontal=l,a.base=n?r:u.base,a.x=l?n?r:u.head:d.center,a.y=l?d.center:n?r:u.head,a.height=l?d.size:void 0,a.width=l?void 0:d.size},getValueScaleId:function(){return this.getMeta().yAxisID},getIndexScaleId:function(){return this.getMeta().xAxisID},getValueScale:function(){return this.getScaleForId(this.getValueScaleId())},getIndexScale:function(){return this.getScaleForId(this.getIndexScaleId())},getStackCount:function(t){var e,n,i=this,a=i.chart,o=i.getIndexScale(),r=o.options.stacked,l=void 0===t?a.data.datasets.length:t+1,s=[];for(e=0;e<l;++e)n=a.getDatasetMeta(e),n.bar&&a.isDatasetVisible(e)&&(r===!1||r===!0&&s.indexOf(n.stack)===-1||void 0===r&&(void 0===n.stack||s.indexOf(n.stack)===-1))&&s.push(n.stack);return s.length},getStackIndex:function(t){return this.getStackCount(t)-1},getRuler:function(){var t=this,n=t.getIndexScale(),i=n.options,a=t.getStackCount(),o=n.isHorizontal()?n.width:n.height,r=o/n.ticks.length,l=r*i.categoryPercentage,s=l/a,u=s*i.barPercentage;return u=Math.min(e.getValueOrDefault(i.barThickness,u),e.getValueOrDefault(i.maxBarThickness,1/0)),{stackCount:a,tickSize:r,categorySize:l,categorySpacing:r-l,fullBarSize:s,barSize:u,barSpacing:s-u,scale:n}},calculateBarValuePixels:function(t,e){var n,i,a,o,r,l,s=this,u=s.chart,d=s.getMeta(),c=s.getValueScale(),h=u.data.datasets,f=Number(h[t].data[e]),g=c.options.stacked,p=d.stack,m=0;if(g||void 0===g&&void 0!==p)for(n=0;n<t;++n)i=u.getDatasetMeta(n),i.bar&&i.stack===p&&i.controller.getValueScaleId()===c.id&&u.isDatasetVisible(n)&&(a=Number(h[n].data[e]),(f<0&&a<0||f>=0&&a>0)&&(m+=a));return o=c.getPixelForValue(m),r=c.getPixelForValue(m+f),l=(r-o)/2,{size:l,base:o,head:r,center:r+l/2}},calculateBarIndexPixels:function(t,e,n){var i=this,a=n.scale,o=i.chart.isCombo,r=i.getStackIndex(t),l=a.getPixelForValue(null,e,t,o),s=n.barSize;return l-=o?n.tickSize/2:0,l+=n.fullBarSize*r,l+=n.categorySpacing/2,l+=n.barSpacing/2,{size:s,base:l,head:l+s,center:l+s/2}},draw:function(){var t,n=this,i=n.chart,a=n.getMeta().data,o=n.getDataset(),r=a.length,l=0;for(e.canvas.clipArea(i.ctx,i.chartArea);l<r;++l)t=o.data[l],null===t||void 0===t||isNaN(t)||a[l].draw();e.canvas.unclipArea(i.ctx)},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model;o.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.hoverBackgroundColor,i,e.getHoverColor(o.backgroundColor)),o.borderColor=a.hoverBorderColor?a.hoverBorderColor:e.getValueAtIndexOrDefault(n.hoverBorderColor,i,e.getHoverColor(o.borderColor)),o.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:e.getValueAtIndexOrDefault(n.hoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model,r=this.chart.options.elements.rectangle;o.backgroundColor=a.backgroundColor?a.backgroundColor:e.getValueAtIndexOrDefault(n.backgroundColor,i,r.backgroundColor),o.borderColor=a.borderColor?a.borderColor:e.getValueAtIndexOrDefault(n.borderColor,i,r.borderColor),o.borderWidth=a.borderWidth?a.borderWidth:e.getValueAtIndexOrDefault(n.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 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({getValueScaleId:function(){return this.getMeta().xAxisID},getIndexScaleId:function(){return this.getMeta().yAxisID}})}},{}],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(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+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 o=this,r=o.getMeta(),l=o.getScaleForId(r.xAxisID),s=o.getScaleForId(r.yAxisID),u=n.custom||{},d=o.getDataset(),c=d.data[i],h=o.chart.options.elements.point,f=o.index;e.extend(n,{_xScale:l,_yScale:s,_datasetIndex:f,_index:i,_model:{x:a?l.getPixelForDecimal(.5):l.getPixelForValue("object"==typeof c?c:NaN,i,f,o.chart.isCombo),y:a?s.getBasePixel():s.getPixelForValue(c,i,f),radius:a?0:u.radius?u.radius:o.getRadius(c),hitRadius:u.hitRadius?u.hitRadius:e.getValueAtIndexOrDefault(d.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(o,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],o=n._index,r=n.custom||{},l=n._model;
-    l.radius=r.hoverRadius?r.hoverRadius:e.getValueAtIndexOrDefault(a.hoverRadius,o,i.chart.options.elements.point.hoverRadius)+i.getRadius(a.data[o])},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||{},o=e._model;o.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 o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),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 o=t.getDatasetMeta(0),r=n.datasets[0],l=o.data[a],s=l&&l.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:u(r.backgroundColor,a,d.backgroundColor),h=s.borderColor?s.borderColor:u(r.borderColor,a,d.borderColor),f=s.borderWidth?s.borderWidth:u(r.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[a])||o.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,o=e.index,r=this.chart;for(n=0,i=(r.data.datasets||[]).length;n<i;++n)a=r.getDatasetMeta(n),a.data[o]&&(a.data[o].hidden=!a.data[o].hidden);r.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,n){var i=n.labels[t.index],a=": "+n.datasets[t.datasetIndex].data[t.index];return e.isArray(i)?(i=i.slice(),i[0]+=a):i+=a,i}}}},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;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var n=this,i=n.chart,a=i.chartArea,o=i.options,r=o.elements.arc,l=a.right-a.left-r.borderWidth,s=a.bottom-a.top-r.borderWidth,u=Math.min(l,s),d={x:0,y:0},c=n.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)},v={x:Math.cos(p),y:Math.sin(p)},b=g<=0&&0<=p||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,w=h/100,M={x:y?-1:Math.min(m.x*(m.x<0?1:w),v.x*(v.x<0?1:w)),y:k?-1:Math.min(m.y*(m.y<0?1:w),v.y*(v.y<0?1:w))},S={x:b?1:Math.max(m.x*(m.x>0?1:w),v.x*(v.x>0?1:w)),y:x?1:Math.max(m.y*(m.y>0?1:w),v.y*(v.y>0?1:w))},C={width:.5*(S.x-M.x),height:.5*(S.y-M.y)};u=Math.min(l/C.width,s/C.height),d={x:(S.x+M.x)*-.5,y:(S.y+M.y)*-.5}}i.borderWidth=n.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,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=Math.max(n.outerRadius-i.radiusLength,0),e.each(c.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){var a=this,o=a.chart,r=o.chartArea,l=o.options,s=l.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=l.rotation,h=l.rotation,f=a.getDataset(),g=i&&s.animateRotate?0:t.hidden?0:a.calculateCircumference(f.data[n])*(l.circumference/(2*Math.PI)),p=i&&s.animateScale?0:a.innerRadius,m=i&&s.animateScale?0:a.outerRadius,v=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:a.index,_index:n,_model:{x:u+o.offsetX,y:d+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,n,o.data.labels[n])}});var b=t._model;this.removeHoverStyle(t),i&&s.animateRotate||(0===n?b.startAngle=l.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},getMaxBorderWidth:function(t){for(var e,n,i=0,a=this.index,o=t.length,r=0;r<o;r++)e=t[r]._model?t[r]._model.borderWidth:0,n=t[r]._chart?t[r]._chart.config.data.datasets[a].hoverBorderWidth:0,i=e>i?e:i,i=n>i?n:i;return i}})}},{}],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,spanGaps:!1,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,update:function(t){var i,a,o,r=this,l=r.getMeta(),s=l.dataset,u=l.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(l.yAxisID),f=r.getDataset(),g=e(f,d);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=u,s._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:o.tension?o.tension:n.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,steppedLine:o.steppedLine?o.steppedLine:n.getValueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:o.cubicInterpolationMode?o.cubicInterpolationMode:n.getValueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},s.pivot()),i=0,a=u.length;i<a;++i)r.updateElement(u[i],i,t);for(g&&0!==s._model.tension&&r.updateBezierControlPoints(),i=0,a=u.length;i<a;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,a=this.getDataset(),o=t.custom||{};return o.backgroundColor?i=o.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(),o=t.custom||{};return o.borderColor?i=o.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(),o=t.custom||{};return isNaN(o.borderWidth)?isNaN(a.pointBorderWidth)?isNaN(a.borderWidth)||(i=a.borderWidth):i=n.getValueAtIndexOrDefault(a.pointBorderWidth,e,i):i=o.borderWidth,i},updateElement:function(t,e,i){var a,o,r=this,l=r.getMeta(),s=t.custom||{},u=r.getDataset(),d=r.index,c=u.data[e],h=r.getScaleForId(l.yAxisID),f=r.getScaleForId(l.xAxisID),g=r.chart.options.elements.point,p=r.chart.data.labels||[],m=1===p.length||1===u.data.length||r.chart.isCombo;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("object"==typeof c?c:NaN,e,d,m),o=i?h.getBasePixel():r.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:a,y:o,skip:s.skip||isNaN(a)||isNaN(o),radius:s.radius||n.getValueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:s.pointStyle||n.getValueAtIndexOrDefault(u.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,steppedLine:!!l.dataset._model&&l.dataset._model.steppedLine,hitRadius:s.hitRadius||n.getValueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,n){var i,a,o,r=this,l=r.chart,s=r.getMeta(),u=r.getScaleForId(s.yAxisID),d=0,c=0;if(u.options.stacked){for(i=0;i<n;i++)if(a=l.data.datasets[i],o=l.getDatasetMeta(i),"line"===o.type&&o.yAxisID===u.id&&l.isDatasetVisible(i)){var h=Number(u.getRightValue(a.data[e]));h<0?c+=h||0:d+=h||0}var f=Number(u.getRightValue(t));return f<0?u.getPixelForValue(c+f):u.getPixelForValue(d+f)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,n){return Math.max(Math.min(t,n),e)}var e,i,a,o,r,l=this,s=l.getMeta(),u=l.chart.chartArea,d=s.data||[];if(s.dataset._model.spanGaps&&(d=d.filter(function(t){return!t._model.skip})),"monotone"===s.dataset._model.cubicInterpolationMode)n.splineCurveMonotone(d);else for(e=0,i=d.length;e<i;++e)a=d[e],o=a._model,r=n.splineCurve(n.previousItem(d,e)._model,o,n.nextItem(d,e)._model,s.dataset._model.tension),o.controlPointPreviousX=r.previous.x,o.controlPointPreviousY=r.previous.y,o.controlPointNextX=r.next.x,o.controlPointNextY=r.next.y;if(l.chart.options.elements.line.capBezierPoints)for(e=0,i=d.length;e<i;++e)o=d[e]._model,o.controlPointPreviousX=t(o.controlPointPreviousX,u.left,u.right),o.controlPointPreviousY=t(o.controlPointPreviousY,u.top,u.bottom),o.controlPointNextX=t(o.controlPointNextX,u.left,u.right),o.controlPointNextY=t(o.controlPointNextY,u.top,u.bottom)},draw:function(){var n=this,i=n.chart,a=n.getMeta(),o=a.data||[],r=i.chartArea,l=o.length,s=0;for(t.canvasHelpers.clipArea(i.ctx,r),e(n.getDataset(),i.options)&&a.dataset.draw(),t.canvasHelpers.unclipArea(i.ctx);s<l;++s)o[s].draw(r)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model;o.radius=a.hoverRadius||n.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),o.backgroundColor=a.hoverBackgroundColor||n.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,n.getHoverColor(o.backgroundColor)),o.borderColor=a.hoverBorderColor||n.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,n.getHoverColor(o.borderColor)),o.borderWidth=a.hoverBorderWidth||n.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],a=t._index,o=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=o.radius||n.getValueAtIndexOrDefault(i.pointRadius,a,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,a),r.borderColor=e.getPointBorderColor(t,a),r.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",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,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 o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),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 o=t.getDatasetMeta(0),r=n.datasets[0],l=o.data[a],s=l.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:u(r.backgroundColor,a,d.backgroundColor),h=s.borderColor?s.borderColor:u(r.borderColor,a,d.borderColor),f=s.borderWidth?s.borderWidth:u(r.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[a])||o.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,o=e.index,r=this.chart;for(n=0,i=(r.data.datasets||[]).length;n<i;++n)a=r.getDatasetMeta(n),a.data[o].hidden=!a.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 n=this,i=n.chart,a=i.chartArea,o=n.getMeta(),r=i.options,l=r.elements.arc,s=Math.min(a.right-a.left,a.bottom-a.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(),n.outerRadius=i.outerRadius-i.radiusLength*n.index,n.innerRadius=n.outerRadius-i.radiusLength,o.count=n.countVisibleElements(),e.each(o.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){for(var a=this,o=a.chart,r=a.getDataset(),l=o.options,s=l.animation,u=o.scale,d=e.getValueAtIndexOrDefault,c=o.data.labels,h=a.calculateCircumference(r.data[n]),f=u.xCenter,g=u.yCenter,p=0,m=a.getMeta(),v=0;v<n;++v)isNaN(r.data[v])||m.data[v].hidden||++p;var b=l.startAngle,x=t.hidden?0:u.getDistanceFromCenterForValue(r.data[n]),y=b+h*p,k=y+(t.hidden?0:h),w=s.animateScale?0:u.getDistanceFromCenterForValue(r.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:u,_model:{x:f,y:g,innerRadius:0,outerRadius:i?w:x,startAngle:i&&s.animateRotate?b:y,endAngle:i&&s.animateRotate?b:k,label:d(c,n,c[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={aspectRatio:1,scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,update:function(t){var n=this,i=n.getMeta(),a=i.dataset,o=i.data,r=a.custom||{},l=n.getDataset(),s=n.chart.options.elements.line,u=n.chart.scale;void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),e.extend(i.dataset,{_datasetIndex:n.index,_scale:u,_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}}),i.dataset.pivot(),e.each(o,function(e,i){n.updateElement(e,i,t)},n),n.updateBezierControlPoints()},updateElement:function(t,n,i){var a=this,o=t.custom||{},r=a.getDataset(),l=a.chart.scale,s=a.chart.options.elements.point,u=l.getPointPositionForValue(n,r.data[n]);void 0!==r.radius&&void 0===r.pointRadius&&(r.pointRadius=r.radius),void 0!==r.hitRadius&&void 0===r.pointHitRadius&&(r.pointHitRadius=r.hitRadius),e.extend(t,{_datasetIndex:a.index,_index:n,_scale:l,_model:{x:i?l.xCenter:u.x,y:i?l.yCenter:u.y,tension:o.tension?o.tension:e.getValueOrDefault(r.lineTension,a.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,n,s.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,n,s.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,n,s.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,n,s.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,n,s.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.pointHitRadius,n,s.hitRadius)}}),t._model.skip=o.skip?o.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 o=i._model,r=e.splineCurve(e.previousItem(n.data,a,!0)._model,o,e.nextItem(n.data,a,!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()})},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(n.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.pointHoverBackgroundColor,a,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(n.pointHoverBorderColor,a,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(n.pointHoverBorderWidth,a,o.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(n.pointRadius,a,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(n.pointBackgroundColor,a,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(n.pointBorderColor,a,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(n.pointBorderWidth,a,r.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({chart:null,currentStep:0,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,o,r=this.animations;for(e.chart=t,i||(t.animating=!0),a=0,o=r.length;a<o;++a)if(r[a].chart===t)return void(r[a]=e);r.push(e),1===r.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var n=e.findIndex(this.animations,function(e){return e.chart===t});n!==-1&&(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),t.advance(1+n);var i=Date.now();t.dropFrames+=(i-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var n,i,a=this.animations,o=0;o<a.length;)n=a[o],i=n.chart,n.currentStep=(n.currentStep||0)+t,n.currentStep=Math.min(n.currentStep,n.numSteps),e.callback(n.render,[i,n],i),e.callback(n.onAnimationProgress,[n],i),n.currentStep>=n.numSteps?(e.callback(n.onAnimationComplete,[n],i),i.animating=!1,a.splice(o,1)):++o}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{}],22:[function(t,e,n){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(e,n,i,a,o){var r,l,s,u,d,c;if("object"==typeof n&&(r=n.toString(),"[object HTMLImageElement]"===r||"[object HTMLCanvasElement]"===r))return void e.drawImage(n,a-n.width/2,o-n.height/2,n.width,n.height);if(!(isNaN(i)||i<=0)){switch(n){default:e.beginPath(),e.arc(a,o,i,0,2*Math.PI),e.closePath(),e.fill();break;case"triangle":e.beginPath(),l=3*i/Math.sqrt(3),d=l*Math.sqrt(3)/2,e.moveTo(a-l/2,o+d/3),e.lineTo(a+l/2,o+d/3),e.lineTo(a,o-2*d/3),e.closePath(),e.fill();break;case"rect":c=1/Math.SQRT2*i,e.beginPath(),e.fillRect(a-c,o-c,2*c,2*c),e.strokeRect(a-c,o-c,2*c,2*c);break;case"rectRounded":var h=i/Math.SQRT2,f=a-h,g=o-h,p=Math.SQRT2*i;t.helpers.drawRoundedRectangle(e,f,g,p,p,i/2),e.fill();break;case"rectRot":c=1/Math.SQRT2*i,e.beginPath(),e.moveTo(a-c,o),e.lineTo(a,o+c),e.lineTo(a+c,o),e.lineTo(a,o-c),e.closePath(),e.fill();break;case"cross":e.beginPath(),e.moveTo(a,o+i),e.lineTo(a,o-i),e.moveTo(a-i,o),e.lineTo(a+i,o),e.closePath();break;case"crossRot":e.beginPath(),s=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(a-s,o-u),e.lineTo(a+s,o+u),e.moveTo(a-s,o+u),e.lineTo(a+s,o-u),e.closePath();break;case"star":e.beginPath(),e.moveTo(a,o+i),e.lineTo(a,o-i),e.moveTo(a-i,o),e.lineTo(a+i,o),s=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(a-s,o-u),e.lineTo(a+s,o+u),e.moveTo(a-s,o+u),e.lineTo(a+s,o-u),e.closePath();break;case"line":e.beginPath(),e.moveTo(a-i,o),e.lineTo(a+i,o),e.closePath();break;case"dash":e.beginPath(),e.moveTo(a,o),e.lineTo(a+i,o),e.closePath()}e.stroke()}},e.clipArea=function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},e.unclipArea=function(t){t.restore()},e.lineTo=function(t,e,n,i){return n.steppedLine?("after"===n.steppedLine?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y),void t.lineTo(n.x,n.y)):n.tension?void t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):void t.lineTo(n.x,n.y)},t.helpers.canvas=e}},{}],23:[function(t,e,n){"use strict";e.exports=function(t){function e(e){e=e||{};var n=e.data=e.data||{};return n.datasets=n.datasets||[],n.labels=n.labels||[],e.options=a.configMerge(t.defaults.global,t.defaults[e.type],e.options||{}),e}function n(t){var e=t.options;e.scale?t.scale.options=e.scale:e.scales&&e.scales.xAxes.concat(e.scales.yAxes).forEach(function(e){t.scales[e.id].options=e}),t.tooltip._options=e.tooltips}function i(t){return"top"===t||"bottom"===t}var a=t.helpers,o=t.plugins,r=t.platform;t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(n,i){var o=this;i=e(i);var l=r.acquireContext(n,i),s=l&&l.canvas,u=s&&s.height,d=s&&s.width;return o.id=a.uid(),o.ctx=l,o.canvas=s,o.config=i,o.width=d,o.height=u,o.aspectRatio=u?d/u:null,o.options=i.options,o._bufferedRender=!1,o.chart=o,o.controller=o,t.instances[o.id]=o,Object.defineProperty(o,"data",{get:function(){return o.config.data},set:function(t){o.config.data=t}}),l&&s?(o.initialize(),void o.update()):void console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return o.notify(t,"beforeInit"),a.retinaScale(t),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildScales(),t.initToolTip(),o.notify(t,"afterInit"),t},clear:function(){return a.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,r=n.maintainAspectRatio&&e.aspectRatio||null,l=Math.floor(a.getMaximumWidth(i)),s=Math.floor(r?l/r:a.getMaximumHeight(i));if((e.width!==l||e.height!==s)&&(i.width=e.width=l,i.height=e.height=s,i.style.width=l+"px",i.style.height=s+"px",a.retinaScale(e),!t)){var u={width:l,height:s};o.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),n&&(n.id=n.id||"scale")},buildScales:function(){var e=this,n=e.options,o=e.scales={},r=[];n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,l=a.getValueOrDefault(r.type,n.dtype),s=t.scaleService.getScaleConstructor(l);if(s){i(r.position)!==i(n.dposition)&&(r.position=n.dposition);var u=new s({id:r.id,options:r,ctx:e.ctx,chart:e});o[u.id]=u,n.isDefault&&(e.scale=u)}}),t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,n=[],i=[];if(a.each(e.data.datasets,function(a,o){var r=e.getDatasetMeta(o);if(r.type||(r.type=a.type||e.config.type),n.push(r.type),r.controller)r.controller.updateIndex(o);else{var l=t.controllers[r.type];if(void 0===l)throw new Error('"'+r.type+'" is not a chart type.');r.controller=new l(e,o),i.push(r.controller)}},e),n.length>1)for(var o=1;o<n.length;o++)if(n[o]!==n[o-1]){e.isCombo=!0;break}return i},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t,e){var i=this;if(n(i),o.notify(i,"beforeUpdate")!==!1){i.tooltip._data=i.data;var r=i.buildOrUpdateControllers();a.each(i.data.datasets,function(t,e){i.getDatasetMeta(e).controller.buildOrUpdateElements()},i),i.updateLayout(),a.each(r,function(t){t.reset()}),i.updateDatasets(),o.notify(i,"afterUpdate"),i._bufferedRender?i._bufferedRequest={lazy:e,duration:t}:i.render(t,e)}},updateLayout:function(){var e=this;o.notify(e,"beforeLayout")!==!1&&(t.layoutService.update(this,this.width,this.height),o.notify(e,"afterScaleUpdate"),o.notify(e,"afterLayout"))},updateDatasets:function(){var t=this;if(o.notify(t,"beforeDatasetsUpdate")!==!1){for(var e=0,n=t.data.datasets.length;e<n;++e)t.updateDataset(e);o.notify(t,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this,n=e.getDatasetMeta(t),i={meta:n,index:t};o.notify(e,"beforeDatasetUpdate",[i])!==!1&&(n.controller.update(),o.notify(e,"afterDatasetUpdate",[i]))},render:function(e,n){var i=this;if(o.notify(i,"beforeRender")!==!1){var r=i.options.animation,l=function(t){o.notify(i,"afterRender"),a.callback(r&&r.onComplete,[t],i)};if(r&&("undefined"!=typeof e&&0!==e||"undefined"==typeof e&&0!==r.duration)){var s=new t.Animation({numSteps:(e||r.duration)/16.66,easing:r.easing,render:function(t,e){var n=a.easingEffects[e.easing],i=e.currentStep,o=i/e.numSteps;t.draw(n(o),o,i)},onAnimationProgress:r.onProgress,onAnimationComplete:l});t.animationService.addAnimation(i,s,e,n)}else i.draw(),l(new t.Animation({numSteps:0,chart:i}));return i}},draw:function(t){var e=this;e.clear(),void 0!==t&&null!==t||(t=1),e.transition(t),o.notify(e,"beforeDraw",[t])!==!1&&(a.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e.tooltip.draw(),o.notify(e,"afterDraw",[t]))},transition:function(t){for(var e=this,n=0,i=(e.data.datasets||[]).length;n<i;++n)e.isDatasetVisible(n)&&e.getDatasetMeta(n).controller.transition(t);e.tooltip.transition(t)},drawDatasets:function(t){var e=this;if(o.notify(e,"beforeDatasetsDraw",[t])!==!1){for(var n=(e.data.datasets||[]).length-1;n>=0;--n)e.isDatasetVisible(n)&&e.drawDataset(n,t);o.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n=this,i=n.getDatasetMeta(t),a={meta:i,index:t,easingValue:e};o.notify(n,"beforeDatasetDraw",[a])!==!1&&(i.controller.draw(e),o.notify(n,"afterDatasetDraw",[a]))},getElementAtEvent:function(e){return t.Interaction.modes.single(this,e)},getElementsAtEvent:function(e){return t.Interaction.modes.label(this,e,{intersect:!0})},getElementsAtXAxis:function(e){return t.Interaction.modes["x-axis"](this,e,{intersect:!0})},getElementsAtEventForMode:function(e,n,i){var a=t.Interaction.modes[n];return"function"==typeof a?a(this,e,i):[]},getDatasetAtEvent:function(e){return t.Interaction.modes.dataset(this,e,{intersect:!0})},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;e<n;++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 e,n,i,l=this,s=l.canvas;for(l.stop(),n=0,i=l.data.datasets.length;n<i;++n)e=l.getDatasetMeta(n),e.controller&&(e.controller.destroy(),e.controller=null);s&&(l.unbindEvents(),a.clear(l),r.releaseContext(l.ctx),l.canvas=null,l.ctx=null),o.notify(l,"destroy"),delete t.instances[l.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e),e.tooltip.initialize()},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};a.each(t.options.events,function(i){r.addEventListener(t,i,n),e[i]=n}),t.options.responsive&&(n=function(){t.resize()},r.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,a.each(e,function(e,n){r.removeEventListener(t,n,e)}))},updateHoverStyle:function(t,e,n){var i,a,o,r=n?"setHoverStyle":"removeHoverStyle";for(a=0,o=t.length;a<o;++a)i=t[a],i&&this.getDatasetMeta(i._datasetIndex).controller[r](i)},eventHandler:function(t){var e=this,n=e.tooltip;if(o.notify(e,"beforeEvent",[t])!==!1){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);i|=n&&n.handleEvent(t),o.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a.duration,a.lazy):i&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e=this,n=e.options||{},i=n.hover,o=!1;return e.lastActive=e.lastActive||[],"mouseout"===t.type?e.active=[]:e.active=e.getElementsAtEventForMode(t,i.mode,i),i.onHover&&i.onHover.call(e,t.native,e.active),"mouseup"!==t.type&&"click"!==t.type||n.onClick&&n.onClick.call(e,t.native,e.active),e.lastActive.length&&e.updateHoverStyle(e.lastActive,i.mode,!1),e.active.length&&i.mode&&e.updateHoverStyle(e.active,i.mode,!0),o=!a.arrayEquals(e.active,e.lastActive),e.lastActive=e.active,o}}),t.Controller=t}},{}],24:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t._chartjs?void t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),void a.forEach(function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),o=a.apply(this,e);return i.each(t._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),o}})}))}function n(t,e){var n=t._chartjs;if(n){var i=n.listeners,o=i.indexOf(e);
-    o!==-1&&i.splice(o,1),i.length>0||(a.forEach(function(e){delete t[e]}),delete t._chartjs)}}var i=t.helpers,a=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.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)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],o=i.data;for(t=0,e=a.length;t<e;++t)o[t]=o[t]||n.createMetaData(t);i.dataset=i.dataset||n.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t=this,i=t.getDataset(),a=i.data||(i.data=[]);t._data!==a&&(t._data&&n(t._data,t),e(a,t),t._data=a),t.resyncElements()},update:i.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,a=0;a<i;++a)n[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],n=e.length,i=0;for(t.dataset&&t.dataset.draw();i<n;++i)e[i].draw()},removeHoverStyle:function(t,e){var n=this.chart.data.datasets[t._datasetIndex],a=t._index,o=t.custom||{},r=i.getValueAtIndexOrDefault,l=t._model;l.backgroundColor=o.backgroundColor?o.backgroundColor:r(n.backgroundColor,a,e.backgroundColor),l.borderColor=o.borderColor?o.borderColor:r(n.borderColor,a,e.borderColor),l.borderWidth=o.borderWidth?o.borderWidth:r(n.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},o=i.getValueAtIndexOrDefault,r=i.getHoverColor,l=t._model;l.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:o(e.hoverBackgroundColor,n,r(l.backgroundColor)),l.borderColor=a.hoverBorderColor?a.hoverBorderColor:o(e.hoverBorderColor,n,r(l.borderColor)),l.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:o(e.hoverBorderWidth,n,l.borderWidth)},resyncElements:function(){var t=this,e=t.getMeta(),n=t.getDataset().data,i=e.data.length,a=n.length;a<i?e.data.splice(a,i-a):a>i&&t.insertElements(i,a-i)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=i.inherits}},{}],25:[function(t,e,n){"use strict";var i=t(3);e.exports=function(t){function e(t,e,n,a){var o,r,l,s,u,d,c,h,f,g=Object.keys(n);for(o=0,r=g.length;o<r;++o)if(l=g[o],d=n[l],e.hasOwnProperty(l)||(e[l]=d),s=e[l],s!==d&&"_"!==l[0]){if(t.hasOwnProperty(l)||(t[l]=s),u=t[l],c=typeof d,c===typeof u)if("string"===c){if(h=i(u),h.valid&&(f=i(d),f.valid)){e[l]=f.mix(h,a).rgbString();continue}}else if("number"===c&&isFinite(u)&&isFinite(d)){e[l]=u+(d-u)*a;continue}e[l]=d}}var n=t.helpers;t.elements={},t.Element=function(t){n.extend(this,t),this.initialize.apply(this,arguments)},n.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=n.clone(t._model)),t._start={},t},transition:function(t){var n=this,i=n._model,a=n._start,o=n._view;return i&&1!==t?(o||(o=n._view={}),a||(a=n._start={}),e(a,o,i,t),n):(n._view=i,n._start=null,n)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return n.isNumber(this._model.x)&&n.isNumber(this._model.y)}}),t.Element.extend=n.inherits}},{3:3}],26:[function(t,e,n){"use strict";var i=t(3);e.exports=function(t){function e(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),t.indexOf("%")!==-1&&(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 o=document.defaultView,r=t.parentNode,l=o.getComputedStyle(t)[i],s=o.getComputedStyle(r)[i],u=n(l),d=n(s),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(l,t,a):c,d?e(s,r,a):c):"none"}var o=t.helpers={};o.each=function(t,e,n,i){var a,r;if(o.isArray(t))if(r=t.length,i)for(a=r-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;a<r;a++)e.call(n,t[a],a);else if("object"==typeof t){var l=Object.keys(t);for(r=l.length,a=0;a<r;a++)e.call(n,t[l[a]],l[a])}},o.clone=function(t){var e={};return o.each(t,function(t,n){o.isArray(t)?e[n]=t.slice(0):"object"==typeof t&&null!==t?e[n]=o.clone(t):e[n]=t}),e},o.extend=function(t){for(var e=function(e,n){t[n]=e},n=1,i=arguments.length;n<i;n++)o.each(arguments[n],e);return t},o.configMerge=function(e){var n=o.clone(e);return o.each(Array.prototype.slice.call(arguments,1),function(e){o.each(e,function(e,i){var a=n.hasOwnProperty(i),r=a?n[i]:{};"scales"===i?n[i]=o.scaleMerge(r,e):"scale"===i?n[i]=o.configMerge(r,t.scaleService.getScaleDefaults(e.type),e):!a||"object"!=typeof r||o.isArray(r)||null===r||"object"!=typeof e||o.isArray(e)?n[i]=e:n[i]=o.configMerge(r,e)})}),n},o.scaleMerge=function(e,n){var i=o.clone(e);return o.each(n,function(e,n){"xAxes"===n||"yAxes"===n?i.hasOwnProperty(n)?o.each(e,function(e,a){var r=o.getValueOrDefault(e.type,"xAxes"===n?"category":"linear"),l=t.scaleService.getScaleDefaults(r);a>=i[n].length||!i[n][a].type?i[n].push(o.configMerge(l,e)):e.type&&e.type!==i[n][a].type?i[n][a]=o.configMerge(i[n][a],l,e):i[n][a]=o.configMerge(i[n][a],e)}):(i[n]=[],o.each(e,function(e){var a=o.getValueOrDefault(e.type,"xAxes"===n?"category":"linear");i[n].push(o.configMerge(t.scaleService.getScaleDefaults(a),e))})):i.hasOwnProperty(n)&&"object"==typeof i[n]&&null!==i[n]&&"object"==typeof e?i[n]=o.configMerge(i[n],e):i[n]=e}),i},o.getValueAtIndexOrDefault=function(t,e,n){return void 0===t||null===t?n:o.isArray(t)?e<t.length?t[e]:n: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 n=0,i=t.length;n<i;++n)if(t[n]===e)return n;return-1},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return o.each(t,function(t){e(t)&&n.push(t)}),n},o.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;i<a;++i)if(e.call(n,t[i],i,t))return i;return-1},o.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}},o.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}},o.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=o.inherits,t&&o.extend(n.prototype,t),n.__super__=e.prototype,n},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,n){return Math.abs(t-e)<n},o.almostWhole=function(t,e){var n=Math.round(t);return n-e<t&&n+e>t},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 n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),o=Math.atan2(i,n);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:a}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,n,i){var a=t.skip?e:t,o=e,r=n.skip?e:n,l=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),s=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=l/(l+s),d=s/(l+s);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:o.x-c*(r.x-a.x),y:o.y-c*(r.y-a.y)},next:{x:o.x+h*(r.x-a.x),y:o.y+h*(r.y-a.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,n,i,a,r=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),l=r.length;for(e=0;e<l;++e)if(i=r[e],!i.model.skip){if(n=e>0?r[e-1]:null,a=e<l-1?r[e+1]:null,a&&!a.model.skip){var s=a.model.x-i.model.x;i.deltaK=0!==s?(a.model.y-i.model.y)/s:0}!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2}var u,d,c,h;for(e=0;e<l-1;++e)i=r[e],a=r[e+1],i.model.skip||a.model.skip||(o.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(u=i.mK/i.deltaK,d=a.mK/i.deltaK,h=Math.pow(u,2)+Math.pow(d,2),h<=9||(c=3/Math.sqrt(h),i.mK=u*c*i.deltaK,a.mK=d*c*i.deltaK)));var f;for(e=0;e<l;++e)i=r[e],i.model.skip||(n=e>0?r[e-1]:null,a=e<l-1?r[e+1]:null,n&&!n.model.skip&&(f=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-f,i.model.controlPointPreviousY=i.model.y-f*i.mK),a&&!a.model.skip&&(f=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+f,i.model.controlPointNextY=i.model.y+f*i.mK))},o.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]},o.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var n,i=Math.floor(o.log10(t)),a=t/Math.pow(10,i);return n=e?a<1.5?1:a<3?2:a<7?5:10:a<=1?1:a<=2?2:a<=5?5:10,n*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:-.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:-.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-.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?-.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),t<1?-.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-r.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):t<2/2.75?1*(7.5625*(t-=1.5/2.75)*t+.75):t<2.5/2.75?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return t<.5?.5*r.easeInBounce(2*t):.5*r.easeOutBounce(2*t-1)+.5}};o.requestAnimFrame=function(){return"undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),o.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.currentTarget||t.srcElement,l=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=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-u-c,g=l.bottom-l.top-d-h;return n=Math.round((n-l.left-u)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-l.top-d)/g*r.height/e.currentDevicePixelRatio),{x:n,y:i}},o.addEvent=function(t,e,n){t.addEventListener?t.addEventListener(e,n):t.attachEvent?t.attachEvent("on"+e,n):t["on"+e]=n},o.removeEvent=function(t,e,n){t.removeEventListener?t.removeEventListener(e,n,!1):t.detachEvent?t.detachEvent("on"+e,n):t["on"+e]=o.noop},o.getConstraintWidth=function(t){return a(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return a(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,n=parseInt(o.getStyle(e,"padding-left"),10),i=parseInt(o.getStyle(e,"padding-right"),10),a=e.clientWidth-n-i,r=o.getConstraintWidth(t);return isNaN(r)?a:Math.min(a,r)},o.getMaximumHeight=function(t){var e=t.parentNode,n=parseInt(o.getStyle(e,"padding-top"),10),i=parseInt(o.getStyle(e,"padding-bottom"),10),a=e.clientHeight-n-i,r=o.getConstraintHeight(t);return isNaN(r)?a:Math.min(a,r)},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.currentDevicePixelRatio=window.devicePixelRatio||1;if(1!==e){var n=t.canvas,i=t.height,a=t.width;n.height=i*e,n.width=a*e,t.ctx.scale(e,e),n.style.height=i+"px",n.style.width=a+"px"}},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,n){return e+" "+t+"px "+n},o.longestText=function(t,e,n,i){i=i||{};var a=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var l=0;o.each(n,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?l=o.measureText(t,a,r,l,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(l=o.measureText(t,a,r,l,e))})});var s=r.length/2;if(s>n.length){for(var u=0;u<s;u++)delete a[r[u]];r.splice(0,s)}return l},o.measureText=function(t,e,n,i,a){var o=e[a];return o||(o=e[a]=t.measureText(a).width,n.push(a)),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,n,i,a,o){t.beginPath(),t.moveTo(e+o,n),t.lineTo(e+i-o,n),t.quadraticCurveTo(e+i,n,e+i,n+o),t.lineTo(e+i,n+a-o),t.quadraticCurveTo(e+i,n+a,e+i-o,n+a),t.lineTo(e+o,n+a),t.quadraticCurveTo(e,n+a,e,n+a-o),t.lineTo(e,n+o),t.quadraticCurveTo(e,n,e+o,n),t.closePath()},o.color=i?function(e){return e instanceof CanvasGradient&&(e=t.defaults.global.defaultColor),i(e)}:function(t){return console.error("Color.js not found!"),t},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 n,i,a,r;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;n<i;++n)if(a=t[n],r=e[n],a instanceof Array&&r instanceof Array){if(!o.arrayEquals(a,r))return!1}else if(a!==r)return!1;return!0},o.callback=function(t,e,n){t&&"function"==typeof t.call&&t.apply(n,e)},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()},o.callCallback=o.callback}},{3:3}],27:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t.native?{x:t.x,y:t.y}:r.getRelativePosition(t,e)}function n(t,e){var n,i,a,o,r,l=t.data.datasets;for(i=0,o=l.length;i<o;++i)if(t.isDatasetVisible(i))for(n=t.getDatasetMeta(i),a=0,r=n.data.length;a<r;++a){var s=n.data[a];s._view.skip||e(s)}}function i(t,e){var i=[];return n(t,function(t){t.inRange(e.x,e.y)&&i.push(t)}),i}function a(t,e,i,a){var o=Number.POSITIVE_INFINITY,l=[];return a||(a=r.distanceBetweenPoints),n(t,function(t){if(!i||t.inRange(e.x,e.y)){var n=t.getCenterPoint(),r=a(e,n);r<o?(l=[t],o=r):r===o&&l.push(t)}}),l}function o(t,n,o){var r=e(n,t),l=function(t,e){return Math.abs(t.x-e.x)},s=o.intersect?i(t,r):a(t,r,!1,l),u=[];return s.length?(t.data.datasets.forEach(function(e,n){if(t.isDatasetVisible(n)){var i=t.getDatasetMeta(n),a=i.data[s[0]._index];a&&!a._view.skip&&u.push(a)}}),u):[]}var r=t.helpers;t.Interaction={modes:{single:function(t,i){var a=e(i,t),o=[];return n(t,function(t){if(t.inRange(a.x,a.y))return o.push(t),o}),o.slice(0,1)},label:o,index:o,dataset:function(t,n,o){var r=e(n,t),l=o.intersect?i(t,r):a(t,r,!1);return l.length>0&&(l=t.getDatasetMeta(l[0]._datasetIndex).data),l},"x-axis":function(t,e){return o(t,e,!0)},point:function(t,n){var a=e(n,t);return i(t,a)},nearest:function(t,n,i){var o=e(n,t),r=a(t,o,i.intersect);return r.length>1&&r.sort(function(t,e){var n=t.getArea(),i=e.getArea(),a=n-i;return 0===a&&(a=t._datasetIndex-e._datasetIndex),a}),r.slice(0,1)},x:function(t,i,a){var o=e(i,t),r=[],l=!1;return n(t,function(t){t.inXRange(o.x)&&r.push(t),t.inRange(o.x,o.y)&&(l=!0)}),a.intersect&&!l&&(r=[]),r},y:function(t,i,a){var o=e(i,t),r=[],l=!1;return n(t,function(t){t.inYRange(o.y)&&r.push(t),t.inRange(o.x,o.y)&&(l=!0)}),a.intersect&&!l&&(r=[]),r}}}}},{}],28:[function(t,e,n){"use strict";e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,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}},{}],29:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return i.where(t,function(t){return t.position===e})}function n(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i._tmpIndex_-a._tmpIndex_:i.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}var i=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;n!==-1&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],o=a.length,r=0;r<o;++r)i=a[r],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(t,a,o){function r(t){var e,n=t.isHorizontal();n?(e=t.update(t.fullWidth?k:I,D),A-=e.height):(e=t.update(C,S),I-=e.width),P.push({horizontal:n,minSize:e,box:t})}function l(t){var e=i.findNextWhere(P,function(e){return e.box===t});if(e)if(t.isHorizontal()){var n={left:Math.max(L,_),right:Math.max(V,T),top:0,bottom:0};t.update(t.fullWidth?k:I,w/2,n)}else t.update(e.minSize.width,A)}function s(t){var e=i.findNextWhere(P,function(e){return e.box===t}),n={left:0,right:0,top:O,bottom:z};e&&t.update(e.minSize.width,A,n)}function u(t){t.isHorizontal()?(t.left=t.fullWidth?h:L,t.right=t.fullWidth?a-f:L+I,t.top=q,t.bottom=q+t.height,q=t.bottom):(t.left=H,t.right=H+t.width,t.top=O,t.bottom=O+A,H=t.right)}if(t){var d=t.options.layout,c=d?d.padding:null,h=0,f=0,g=0,p=0;isNaN(c)?(h=c.left||0,f=c.right||0,g=c.top||0,p=c.bottom||0):(h=c,f=c,g=c,p=c);var m=e(t.boxes,"left"),v=e(t.boxes,"right"),b=e(t.boxes,"top"),x=e(t.boxes,"bottom"),y=e(t.boxes,"chartArea");n(m,!0),n(v,!1),n(b,!0),n(x,!1);var k=a-h-f,w=o-g-p,M=k/2,S=w/2,C=(a-M)/(m.length+v.length),D=(o-S)/(b.length+x.length),I=k,A=w,P=[];i.each(m.concat(v,b,x),r);var _=0,T=0,F=0,R=0;i.each(b.concat(x),function(t){if(t.getPadding){var e=t.getPadding();_=Math.max(_,e.left),T=Math.max(T,e.right)}}),i.each(m.concat(v),function(t){if(t.getPadding){var e=t.getPadding();F=Math.max(F,e.top),R=Math.max(R,e.bottom)}});var L=h,V=f,O=g,z=p;i.each(m.concat(v),l),i.each(m,function(t){L+=t.width}),i.each(v,function(t){V+=t.width}),i.each(b.concat(x),l),i.each(b,function(t){O+=t.height}),i.each(x,function(t){z+=t.height}),i.each(m.concat(v),s),L=h,V=f,O=g,z=p,i.each(m,function(t){L+=t.width}),i.each(v,function(t){V+=t.width}),i.each(b,function(t){O+=t.height}),i.each(x,function(t){z+=t.height});var B=Math.max(_-L,0);L+=B,V+=Math.max(T-V,0);var W=Math.max(F-O,0);O+=W,z+=Math.max(R-z,0);var N=o-O-z,E=a-L-V;E===I&&N===A||(i.each(m,function(t){t.height=N}),i.each(v,function(t){t.height=N}),i.each(b,function(t){t.fullWidth||(t.width=E)}),i.each(x,function(t){t.fullWidth||(t.width=E)}),A=N,I=E);var H=h+B,q=g+W;i.each(m.concat(b),u),H+=I,q+=A,i.each(v,u),i.each(x,u),t.chartArea={left:L,top:O,right:L+I,bottom:O+A},i.each(y,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(I,A)})}}}}},{}],30:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.plugins={},t.plugins={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){e.indexOf(t)===-1&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var n=e.indexOf(t);n!==-1&&e.splice(n,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,n){var i,a,o,r,l,s=this.descriptors(t),u=s.length;for(i=0;i<u;++i)if(a=s[i],o=a.plugin,l=o[e],"function"==typeof l&&(r=[t].concat(n||[]),r.push(a.options),l.apply(o,r)===!1))return!1;return!0},descriptors:function(n){var i=n._plugins||(n._plugins={});if(i.id===this._cacheId)return i.descriptors;var a=[],o=[],r=n&&n.config||{},l=t.defaults.global.plugins,s=r.options&&r.options.plugins||{};return this._plugins.concat(r.plugins||[]).forEach(function(t){var n=a.indexOf(t);if(n===-1){var i=t.id,r=s[i];r!==!1&&(r===!0&&(r=e.clone(l[i])),a.push(t),o.push({plugin:t,options:r||{}}))}}),i.descriptors=o,i.id=this._cacheId,o}},t.pluginService=t.plugins,t.PluginBase=t.Element.extend({})}},{}],31:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e,n){return i.isArray(e)?i.longestText(t,n,e):t.measureText(e).width}function n(e){var n=i.getValueOrDefault,a=t.defaults.global,o=n(e.fontSize,a.defaultFontSize),r=n(e.fontStyle,a.defaultFontStyle),l=n(e.fontFamily,a.defaultFontFamily);return{size:o,style:r,family:l,font:i.fontString(o,r,l)}}var i=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)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:t.Ticks.formatters.values}},t.Scale=t.Element.extend({getPadding:function(){var t=this;return{left:t.paddingLeft||0,top:t.paddingTop||0,right:t.paddingRight||0,bottom:t.paddingBottom||0}},beforeUpdate:function(){i.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var a=this;return a.beforeUpdate(),a.maxWidth=t,a.maxHeight=e,a.margins=i.extend({left:0,right:0,top:0,bottom:0},n),a.longestTextCache=a.longestTextCache||{},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(){i.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){i.callback(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(){i.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){i.callback(this.options.beforeDataLimits,[this])},determineDataLimits:i.noop,afterDataLimits:function(){i.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){i.callback(this.options.beforeBuildTicks,[this])},buildTicks:i.noop,afterBuildTicks:function(){i.callback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){i.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback)},afterTickToLabelConversion:function(){i.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){i.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,a=t.options.ticks,o=n(a);e.font=o.font;var r=a.minRotation||0;if(t.options.display&&t.isHorizontal())for(var l,s,u=i.longestText(e,o.font,t.ticks,t.longestTextCache),d=u,c=t.getPixelForTick(1)-t.getPixelForTick(0)-6;d>c&&r<a.maxRotation;){var h=i.toRadians(r);if(l=Math.cos(h),s=Math.sin(h),s*u>t.maxHeight){r--;break}r++,d=l*u}t.labelRotation=r},afterCalculateTickRotation:function(){i.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){i.callback(this.options.beforeFit,[this])},fit:function(){var t=this,a=t.minSize={width:0,height:0},o=t.options,r=o.ticks,l=o.scaleLabel,s=o.gridLines,u=o.display,d=t.isHorizontal(),c=n(r),h=1.5*n(l).size,f=o.gridLines.tickMarkLength;if(d?a.width=t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:a.width=u&&s.drawTicks?f:0,d?a.height=u&&s.drawTicks?f:0:a.height=t.maxHeight,l.display&&u&&(d?a.height+=h:a.width+=h),r.display&&u){var g=i.longestText(t.ctx,c.font,t.ticks,t.longestTextCache),p=i.numberOfLabelLines(t.ticks),m=.5*c.size;if(d){t.longestLabelWidth=g;var v=i.toRadians(t.labelRotation),b=Math.cos(v),x=Math.sin(v),y=x*g+c.size*p+m*p;a.height=Math.min(t.maxHeight,a.height+y),t.ctx.font=c.font;var k=t.ticks[0],w=e(t.ctx,k,c.font),M=t.ticks[t.ticks.length-1],S=e(t.ctx,M,c.font);0!==t.labelRotation?(t.paddingLeft="bottom"===o.position?b*w+3:b*m+3,t.paddingRight="bottom"===o.position?b*m+3:b*S+3):(t.paddingLeft=w/2+3,t.paddingRight=S/2+3)}else r.mirror?g=0:g+=t.options.ticks.padding,a.width=Math.min(t.maxWidth,a.width+g),t.paddingTop=c.size/2,t.paddingBottom=c.size/2}t.handleMargins(),t.width=a.width,t.height=a.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){i.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"!=typeof t||isFinite(t)?"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t:NaN},getLabelForIndex:i.noop,getPixelForValue:i.noop,getValueForPixel:i.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),o=a*t+n.paddingLeft;e&&(o+=a/2);var r=n.left+Math.round(o);return r+=n.isFullWidth()?n.margins.left:0}var l=n.height-(n.paddingTop+n.paddingBottom);return n.top+t*(l/(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(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,n=t.max;return t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0},draw:function(e){var a=this,o=a.options;if(o.display){var r,l,s=a.ctx,u=t.defaults.global,d=o.ticks,c=o.gridLines,h=o.scaleLabel,f=0!==a.labelRotation,g=d.autoSkip,p=a.isHorizontal();d.maxTicksLimit&&(l=d.maxTicksLimit);var m=i.getValueOrDefault(d.fontColor,u.defaultFontColor),v=n(d),b=c.drawTicks?c.tickMarkLength:0,x=i.getValueOrDefault(h.fontColor,u.defaultFontColor),y=n(h),k=i.toRadians(a.labelRotation),w=Math.cos(k),M=a.longestLabelWidth*w;s.fillStyle=m;var S=[];if(p){if(r=!1,(M+d.autoSkipPadding)*a.ticks.length>a.width-(a.paddingLeft+a.paddingRight)&&(r=1+Math.floor((M+d.autoSkipPadding)*a.ticks.length/(a.width-(a.paddingLeft+a.paddingRight)))),l&&a.ticks.length>l)for(;!r||a.ticks.length/(r||1)>l;)r||(r=1),r+=1;g||(r=!1)}var C="right"===o.position?a.left:a.right-b,D="right"===o.position?a.left+b:a.right,I="bottom"===o.position?a.top:a.bottom-b,A="bottom"===o.position?a.top+b:a.bottom;if(i.each(a.ticks,function(t,n){if(void 0!==t&&null!==t){var l=a.ticks.length===n+1,s=r>1&&n%r>0||n%r===0&&n+r>=a.ticks.length;if((!s||l)&&void 0!==t&&null!==t){var h,g,m,v;n===("undefined"!=typeof a.zeroLineIndex?a.zeroLineIndex:0)?(h=c.zeroLineWidth,g=c.zeroLineColor,m=c.zeroLineBorderDash,v=c.zeroLineBorderDashOffset):(h=i.getValueAtIndexOrDefault(c.lineWidth,n),g=i.getValueAtIndexOrDefault(c.color,n),m=i.getValueOrDefault(c.borderDash,u.borderDash),v=i.getValueOrDefault(c.borderDashOffset,u.borderDashOffset));var x,y,w,M,P,_,T,F,R,L,V="middle",O="middle";if(p){"bottom"===o.position?(O=f?"middle":"top",V=f?"right":"center",L=a.top+b):(O=f?"middle":"bottom",V=f?"left":"center",L=a.bottom-b);var z=a.getPixelForTick(n)+i.aliasPixel(h);R=a.getPixelForTick(n,c.offsetGridLines)+d.labelOffset,x=w=P=T=z,y=I,M=A,_=e.top,F=e.bottom}else{var B,W="left"===o.position,N=d.padding;d.mirror?(V=W?"left":"right",B=N):(V=W?"right":"left",
-        B=b+N),R=W?a.right-B:a.left+B;var E=a.getPixelForTick(n);E+=i.aliasPixel(h),L=a.getPixelForTick(n,c.offsetGridLines),x=C,w=D,P=e.left,T=e.right,y=M=_=F=E}S.push({tx1:x,ty1:y,tx2:w,ty2:M,x1:P,y1:_,x2:T,y2:F,labelX:R,labelY:L,glWidth:h,glColor:g,glBorderDash:m,glBorderDashOffset:v,rotation:-1*k,label:t,textBaseline:O,textAlign:V})}}}),i.each(S,function(t){if(c.display&&(s.save(),s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.setLineDash&&(s.setLineDash(t.glBorderDash),s.lineDashOffset=t.glBorderDashOffset),s.beginPath(),c.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),c.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke(),s.restore()),d.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=v.font,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var e=t.label;if(i.isArray(e))for(var n=0,a=0;n<e.length;++n)s.fillText(""+e[n],0,a),a+=1.5*v.size;else s.fillText(e,0,0);s.restore()}}),h.display){var P,_,T=0;if(p)P=a.left+(a.right-a.left)/2,_="bottom"===o.position?a.bottom-y.size/2:a.top+y.size/2;else{var F="left"===o.position;P=F?a.left+y.size/2:a.right-y.size/2,_=a.top+(a.bottom-a.top)/2,T=F?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(P,_),s.rotate(T),s.textAlign="center",s.textBaseline="middle",s.fillStyle=x,s.font=y.font,s.fillText(h.labelString,0,0),s.restore()}if(c.drawBorder){s.lineWidth=i.getValueAtIndexOrDefault(c.lineWidth,0),s.strokeStyle=i.getValueAtIndexOrDefault(c.color,0);var R=a.left,L=a.right,V=a.top,O=a.bottom,z=i.aliasPixel(s.lineWidth);p?(V=O="top"===o.position?a.bottom:a.top,V+=z,O+=z):(R=L="left"===o.position?a.right:a.left,R+=z,L+=z),s.beginPath(),s.moveTo(R,V),s.lineTo(L,O),s.stroke()}}}})}},{}],32:[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){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,t.layoutService.addBox(n,e)})}}}},{}],33:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.Ticks={generators:{linear:function(t,n){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var o=e.niceNum(n.max-n.min,!1);i=e.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(n.min/i)*i,l=Math.ceil(n.max/i)*i;t.min&&t.max&&t.stepSize&&e.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,l=t.max);var s=(l-r)/i;s=e.almostEquals(s,Math.round(s),i/1e3)?Math.round(s):Math.ceil(s),a.push(void 0!==t.min?t.min:r);for(var u=1;u<s;++u)a.push(r+u*i);return a.push(void 0!==t.max?t.max:l),a},logarithmic:function(t,n){var i,a,o=[],r=e.getValueOrDefault,l=r(t.min,Math.pow(10,Math.floor(e.log10(n.min)))),s=Math.floor(e.log10(n.max)),u=Math.ceil(n.max/Math.pow(10,s));0===l?(i=Math.floor(e.log10(n.minNotZero)),a=Math.floor(n.minNotZero/Math.pow(10,i)),o.push(l),l=a*Math.pow(10,i)):(i=Math.floor(e.log10(l)),a=Math.floor(l/Math.pow(10,i)));do o.push(l),++a,10===a&&(a=1,++i),l=a*Math.pow(10,i);while(i<s||i===s&&a<u);var d=r(t.max,l);return o.push(d),o}},formatters:{values:function(t){return e.isArray(t)?t:""+t},linear: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 o=e.log10(Math.abs(a)),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},logarithmic:function(t,n,i){var a=t/Math.pow(10,Math.floor(e.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===n||n===i.length-1?t.toExponential():""}}}}},{}],34:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=s.color(t);return n.alpha(e*n.alpha()).rgbaString()}function n(t,e){return e&&(s.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}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,x:t._model.x,y:t._model.y}}function a(e){var n=t.defaults.global,i=s.getValueOrDefault;return{xPadding:e.xPadding,yPadding:e.yPadding,xAlign:e.xAlign,yAlign:e.yAlign,bodyFontColor:e.bodyFontColor,_bodyFontFamily:i(e.bodyFontFamily,n.defaultFontFamily),_bodyFontStyle:i(e.bodyFontStyle,n.defaultFontStyle),_bodyAlign:e.bodyAlign,bodyFontSize:i(e.bodyFontSize,n.defaultFontSize),bodySpacing:e.bodySpacing,titleFontColor:e.titleFontColor,_titleFontFamily:i(e.titleFontFamily,n.defaultFontFamily),_titleFontStyle:i(e.titleFontStyle,n.defaultFontStyle),titleFontSize:i(e.titleFontSize,n.defaultFontSize),_titleAlign:e.titleAlign,titleSpacing:e.titleSpacing,titleMarginBottom:e.titleMarginBottom,footerFontColor:e.footerFontColor,_footerFontFamily:i(e.footerFontFamily,n.defaultFontFamily),_footerFontStyle:i(e.footerFontStyle,n.defaultFontStyle),footerFontSize:i(e.footerFontSize,n.defaultFontSize),_footerAlign:e.footerAlign,footerSpacing:e.footerSpacing,footerMarginTop:e.footerMarginTop,caretSize:e.caretSize,cornerRadius:e.cornerRadius,backgroundColor:e.backgroundColor,opacity:0,legendColorBackground:e.multiKeyBackground,displayColors:e.displayColors,borderColor:e.borderColor,borderWidth:e.borderWidth}}function o(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,o=e.body,r=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);r+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=l*d,i+=l?(l-1)*e.titleSpacing:0,i+=l?e.titleMarginBottom:0,i+=r*c,i+=r?(r-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,n.measureText(t).width+f)};return n.font=s.fontString(d,e._titleFontStyle,e._titleFontFamily),s.each(e.title,g),n.font=s.fontString(c,e._bodyFontStyle,e._bodyFontFamily),s.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,s.each(o,function(t){s.each(t.before,g),s.each(t.lines,g),s.each(t.after,g)}),f=0,n.font=s.fontString(h,e._footerFontStyle,e._footerFontFamily),s.each(e.footer,g),a+=2*e.xPadding,{width:a,height:i}}function r(t,e){var n=t._model,i=t._chart,a=t._chart.chartArea,o="center",r="center";n.y<e.height?r="top":n.y>i.height-e.height&&(r="bottom");var l,s,u,d,c,h=(a.left+a.right)/2,f=(a.top+a.bottom)/2;"center"===r?(l=function(t){return t<=h},s=function(t){return t>h}):(l=function(t){return t<=e.width/2},s=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return t<=f?"top":"bottom"},l(n.x)?(o="left",u(n.x)&&(o="center",r=c(n.y))):s(n.x)&&(o="right",d(n.x)&&(o="center",r=c(n.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:o,yAlign:g.yAlign?g.yAlign:r}}function l(t,e,n){var i=t.x,a=t.y,o=t.caretSize,r=t.caretPadding,l=t.cornerRadius,s=n.xAlign,u=n.yAlign,d=o+r,c=l+r;return"right"===s?i-=e.width:"center"===s&&(i-=e.width/2),"top"===u?a+=d:a-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===s?i+=d:"right"===s&&(i-=d):"left"===s?i-=c:"right"===s&&(i+=c),{x:i,y:a}}var s=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,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,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:s.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?n=o.xLabel:a>0&&o.index<a&&(n=i[o.index])}return n},afterTitle:s.noop,beforeBody:s.noop,beforeLabel:s.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),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:s.noop,afterBody:s.noop,beforeFooter:s.noop,footer:s.noop,afterFooter:s.noop}},t.Tooltip=t.Element.extend({initialize:function(){this._model=a(this._options)},getTitle:function(){var t=this,e=t._options,i=e.callbacks,a=i.beforeTitle.apply(t,arguments),o=i.title.apply(t,arguments),r=i.afterTitle.apply(t,arguments),l=[];return l=n(l,a),l=n(l,o),l=n(l,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return s.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var i=this,a=i._options.callbacks,o=[];return s.each(t,function(t){var r={before:[],lines:[],after:[]};n(r.before,a.beforeLabel.call(i,t,e)),n(r.lines,a.label.call(i,t,e)),n(r.after,a.afterLabel.call(i,t,e)),o.push(r)}),o},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return s.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,e=t._options.callbacks,i=e.beforeFooter.apply(t,arguments),a=e.footer.apply(t,arguments),o=e.afterFooter.apply(t,arguments),r=[];return r=n(r,i),r=n(r,a),r=n(r,o)},update:function(e){var n,u,d=this,c=d._options,h=d._model,f=d._model=a(c),g=d._active,p=d._data,m={xAlign:h.xAlign,yAlign:h.yAlign},v={x:h.x,y:h.y},b={width:h.width,height:h.height},x={x:h.caretX,y:h.caretY};if(g.length){f.opacity=1;var y=[];x=t.Tooltip.positioners[c.position](g,d._eventPosition);var k=[];for(n=0,u=g.length;n<u;++n)k.push(i(g[n]));c.filter&&(k=k.filter(function(t){return c.filter(t,p)})),c.itemSort&&(k=k.sort(function(t,e){return c.itemSort(t,e,p)})),s.each(k,function(t){y.push(c.callbacks.labelColor.call(d,t,d._chart))}),f.title=d.getTitle(k,p),f.beforeBody=d.getBeforeBody(k,p),f.body=d.getBody(k,p),f.afterBody=d.getAfterBody(k,p),f.footer=d.getFooter(k,p),f.x=Math.round(x.x),f.y=Math.round(x.y),f.caretPadding=c.caretPadding,f.labelColors=y,f.dataPoints=k,b=o(this,f),m=r(this,b),v=l(f,b,m)}else f.opacity=0;return f.xAlign=m.xAlign,f.yAlign=m.yAlign,f.x=v.x,f.y=v.y,f.width=b.width,f.height=b.height,f.caretX=x.x,f.caretY=x.y,d._model=f,e&&c.custom&&c.custom.call(d,f),d},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,o,r,l,s,u=n.caretSize,d=n.cornerRadius,c=n.xAlign,h=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===h)l=g+m/2,"left"===c?(i=f,a=i-u,o=i,r=l+u,s=l-u):(i=f+p,a=i+u,o=i,r=l-u,s=l+u);else if("left"===c?(a=f+d+u,i=a-u,o=a+u):"right"===c?(a=f+p-d-u,i=a-u,o=a+u):(a=f+p/2,i=a-u,o=a+u),"top"===h)r=g,l=r-u,s=r;else{r=g+m,l=r+u,s=r;var v=o;o=i,i=v}return{x1:i,x2:a,x3:o,y1:r,y2:l,y3:s}},drawTitle:function(t,n,i,a){var o=n.title;if(o.length){i.textAlign=n._titleAlign,i.textBaseline="top";var r=n.titleFontSize,l=n.titleSpacing;i.fillStyle=e(n.titleFontColor,a),i.font=s.fontString(r,n._titleFontStyle,n._titleFontFamily);var u,d;for(u=0,d=o.length;u<d;++u)i.fillText(o[u],t.x,t.y),t.y+=r+l,u+1===o.length&&(t.y+=n.titleMarginBottom-l)}},drawBody:function(t,n,i,a){var o=n.bodyFontSize,r=n.bodySpacing,l=n.body;i.textAlign=n._bodyAlign,i.textBaseline="top";var u=e(n.bodyFontColor,a);i.fillStyle=u,i.font=s.fontString(o,n._bodyFontStyle,n._bodyFontFamily);var d=0,c=function(e){i.fillText(e,t.x+d,t.y),t.y+=o+r};s.each(n.beforeBody,c);var h=n.displayColors;d=h?o+2:0,s.each(l,function(r,l){s.each(r.before,c),s.each(r.lines,function(r){h&&(i.fillStyle=e(n.legendColorBackground,a),i.fillRect(t.x,t.y,o,o),i.strokeStyle=e(n.labelColors[l].borderColor,a),i.strokeRect(t.x,t.y,o,o),i.fillStyle=e(n.labelColors[l].backgroundColor,a),i.fillRect(t.x+1,t.y+1,o-2,o-2),i.fillStyle=u),c(r)}),s.each(r.after,c)}),d=0,s.each(n.afterBody,c),t.y-=r},drawFooter:function(t,n,i,a){var o=n.footer;o.length&&(t.y+=n.footerMarginTop,i.textAlign=n._footerAlign,i.textBaseline="top",i.fillStyle=e(n.footerFontColor,a),i.font=s.fontString(n.footerFontSize,n._footerFontStyle,n._footerFontFamily),s.each(o,function(e){i.fillText(e,t.x,t.y),t.y+=n.footerFontSize+n.footerSpacing}))},drawBackground:function(t,n,i,a,o){i.fillStyle=e(n.backgroundColor,o),i.strokeStyle=e(n.borderColor,o),i.lineWidth=n.borderWidth;var r=n.xAlign,l=n.yAlign,s=t.x,u=t.y,d=a.width,c=a.height,h=n.cornerRadius;i.beginPath(),i.moveTo(s+h,u),"top"===l&&this.drawCaret(t,a),i.lineTo(s+d-h,u),i.quadraticCurveTo(s+d,u,s+d,u+h),"center"===l&&"right"===r&&this.drawCaret(t,a),i.lineTo(s+d,u+c-h),i.quadraticCurveTo(s+d,u+c,s+d-h,u+c),"bottom"===l&&this.drawCaret(t,a),i.lineTo(s+h,u+c),i.quadraticCurveTo(s,u+c,s,u+c-h),"center"===l&&"left"===r&&this.drawCaret(t,a),i.lineTo(s,u+h),i.quadraticCurveTo(s,u,s+h,u),i.closePath(),i.fill(),n.borderWidth>0&&i.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,o=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&o&&(this.drawBackground(i,e,t,n,a),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,a),this.drawBody(i,e,t,a),this.drawFooter(i,e,t,a))}},handleEvent:function(t){var e=this,n=e._options,i=!1;if(e._lastActive=e._lastActive||[],"mouseout"===t.type?e._active=[]:e._active=e._chart.getElementsAtEventForMode(t,n.mode,n),i=!s.arrayEquals(e._active,e._lastActive),!i)return!1;if(e._lastActive=e._active,n.enabled||n.custom){e._eventPosition={x:t.x,y:t.y};var a=e._model;e.update(!0),e.pivot(),i|=a.x!==e._model.x||a.y!==e._model.y}return i}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,o=0;for(e=0,n=t.length;e<n;++e){var r=t[e];if(r&&r.hasValue()){var l=r.tooltipPosition();i+=l.x,a+=l.y,++o}}return{x:Math.round(i/o),y:Math.round(a/o)}},nearest:function(t,e){var n,i,a,o=e.x,r=e.y,l=Number.POSITIVE_INFINITY;for(i=0,a=t.length;i<a;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=s.distanceBetweenPoints(e,d);c<l&&(l=c,n=u)}}if(n){var h=n.tooltipPosition();o=h.x,r=h.y}return{x:o,y:r}}}}},{}],35:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;n.elements.arc={backgroundColor:n.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)},inRange:function(t,n){var i=this._view;if(i){for(var a=e.getAngleFromPoint(i,{x:t,y:n}),o=a.angle,r=a.distance,l=i.startAngle,s=i.endAngle;s<l;)s+=2*Math.PI;for(;o>s;)o-=2*Math.PI;for(;o<l;)o+=2*Math.PI;var u=o>=l&&o<=s,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},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()}})}},{}],36:[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",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){var t,i,a,o,r=this,l=r._view,s=r._chart.ctx,u=l.spanGaps,d=r._children.slice(),c=n.elements.line,h=-1;for(r._loop&&d.length&&d.push(d[0]),s.save(),s.lineCap=l.borderCapStyle||c.borderCapStyle,s.setLineDash&&s.setLineDash(l.borderDash||c.borderDash),s.lineDashOffset=l.borderDashOffset||c.borderDashOffset,s.lineJoin=l.borderJoinStyle||c.borderJoinStyle,s.lineWidth=l.borderWidth||c.borderWidth,s.strokeStyle=l.borderColor||n.defaultColor,s.beginPath(),h=-1,t=0;t<d.length;++t)i=d[t],a=e.previousItem(d,t),o=i._view,0===t?o.skip||(s.moveTo(o.x,o.y),h=t):(a=h===-1?a:d[h],o.skip||(h!==t-1&&!u||h===-1?s.moveTo(o.x,o.y):e.canvas.lineTo(s,a._view,i._view),h=t));s.stroke(),s.restore()}})}},{}],37:[function(t,e,n){"use strict";e.exports=function(t){function e(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2)}function n(t){var e=this._view;return!!e&&Math.pow(t-e.y,2)<Math.pow(e.radius+e.hitRadius,2)}var i=t.helpers,a=t.defaults.global,o=a.defaultColor;a.elements.point={radius:3,pointStyle:"circle",backgroundColor:o,borderWidth:1,borderColor:o,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)},inLabelRange:e,inXRange:e,inYRange:n,getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(e){var n=this._view,r=this._model,l=this._chart.ctx,s=n.pointStyle,u=n.radius,d=n.x,c=n.y,h=t.helpers.color,f=1.01,g=0;n.skip||(l.strokeStyle=n.borderColor||o,l.lineWidth=i.getValueOrDefault(n.borderWidth,a.elements.point.borderWidth),l.fillStyle=n.backgroundColor||o,void 0!==e&&(r.x<e.left||e.right*f<r.x||r.y<e.top||e.bottom*f<r.y)&&(r.x<e.left?g=(d-r.x)/(e.left-r.x):e.right*f<r.x?g=(r.x-d)/(r.x-e.right):r.y<e.top?g=(c-r.y)/(e.top-r.y):e.bottom*f<r.y&&(g=(r.y-c)/(r.y-e.bottom)),g=Math.round(100*g)/100,l.strokeStyle=h(l.strokeStyle).alpha(g).rgbString(),l.fillStyle=h(l.fillStyle).alpha(g).rgbString()),t.canvasHelpers.drawPoint(l,s,u,d,c))}})}},{}],38:[function(t,e,n){"use strict";e.exports=function(t){function e(t){return void 0!==t._view.width}function n(t){var n,i,a,o,r=t._view;if(e(t)){var l=r.width/2;n=r.x-l,i=r.x+l,a=Math.min(r.y,r.base),o=Math.max(r.y,r.base)}else{var s=r.height/2;n=Math.min(r.x,r.base),i=Math.max(r.x,r.base),a=r.y-s,o=r.y+s}return{left:n,top:a,right:i,bottom:o}}var i=t.defaults.global;i.elements.rectangle={backgroundColor:i.defaultColor,borderWidth:0,borderColor:i.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return v[(x+t)%4]}var e,n,i,a,o,r,l,s=this._chart.ctx,u=this._view,d=u.borderWidth;if(u.horizontal?(e=u.base,n=u.x,i=u.y-u.height/2,a=u.y+u.height/2,o=n>e?1:-1,r=1,l=u.borderSkipped||"left"):(e=u.x-u.width/2,n=u.x+u.width/2,i=u.y,a=u.base,o=1,r=a>i?1:-1,l=u.borderSkipped||"bottom"),d){var c=Math.min(Math.abs(e-n),Math.abs(i-a));d=d>c?c:d;var h=d/2,f=e+("left"!==l?h*o:0),g=n+("right"!==l?-h*o:0),p=i+("top"!==l?h*r:0),m=a+("bottom"!==l?-h*r:0);f!==g&&(i=p,a=m),p!==m&&(e=f,n=g)}s.beginPath(),s.fillStyle=u.backgroundColor,s.strokeStyle=u.borderColor,s.lineWidth=d;var v=[[e,a],[e,i],[n,i],[n,a]],b=["bottom","left","top","right"],x=b.indexOf(l,0);x===-1&&(x=0);var y=t(0);s.moveTo(y[0],y[1]);for(var k=1;k<4;k++)y=t(k),s.lineTo(y[0],y[1]);s.fill(),d&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var a=n(this);i=t>=a.left&&t<=a.right&&e>=a.top&&e<=a.bottom}return i},inLabelRange:function(t,i){var a=this;if(!a._view)return!1;var o=!1,r=n(a);return o=e(a)?t>=r.left&&t<=r.right:i>=r.top&&i<=r.bottom},inXRange:function(t){var e=n(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=n(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,n,i=this._view;return e(this)?(t=i.x,n=(i.y+i.base)/2):(t=(i.x+i.base)/2,n=i.y),{x:t,y:n}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],39:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=s.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}function n(t,n){var i=t.style,a=t.getAttribute("height"),o=t.getAttribute("width");if(t._chartjs={initial:{height:a,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=e(t,"width");void 0!==r&&(t.width=r)}if(null===a||""===a)if(""===t.style.height)t.height=t.width/(n.options.aspectRatio||2);else{var l=e(t,"height");void 0!==r&&(t.height=l)}return t}function i(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function a(t,e){var n=u[t.type]||t.type,a=s.getRelativePosition(t,e);return i(n,e,a.x,a.y,t)}function o(t){var e=document.createElement("iframe");return e.className="chartjs-hidden-iframe",e.style.cssText="display:block;overflow:hidden;border:0;margin:0;top:0;left:0;bottom:0;right:0;height:100%;width:100%;position:absolute;pointer-events:none;z-index:-1;",e.tabIndex=-1,s.addEvent(e,"load",function(){s.addEvent(e.contentWindow||e,"resize",t),t()}),e}function r(t,e,n){var a=t._chartjs={ticking:!1},r=function(){a.ticking||(a.ticking=!0,s.requestAnimFrame.call(window,function(){if(a.resizer)return a.ticking=!1,e(i("resize",n))}))};a.resizer=o(r),t.insertBefore(a.resizer,t.firstChild)}function l(t){if(t&&t._chartjs){var e=t._chartjs.resizer;e&&(e.parentNode.removeChild(e),t._chartjs.resizer=null),delete t._chartjs}}var s=t.helpers,u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};return{acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(n(t,e),i):null},releaseContext:function(t){var e=t.canvas;if(e._chartjs){var n=e._chartjs.initial;["height","width"].forEach(function(t){var i=n[t];void 0===i||null===i?e.removeAttribute(t):e.setAttribute(t,i)}),s.each(n.style||{},function(t,n){e.style[n]=t}),e.width=e.width,delete e._chartjs}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"===e)return void r(i.parentNode,n,t);var o=n._chartjs||(n._chartjs={}),l=o.proxies||(o.proxies={}),u=l[t.id+"_"+e]=function(e){n(a(e,t))};s.addEvent(i,e,u)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"===e)return void l(i.parentNode,n);var a=n._chartjs||{},o=a.proxies||{},r=o[t.id+"_"+e];r&&s.removeEvent(i,e,r)}}}},{}],40:[function(t,e,n){"use strict";var i=t(39);e.exports=function(t){t.platform={acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},t.helpers.extend(t.platform,i(t))}},{39:39}],41:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e,n){var i,a=t._model||{},o=a.fill;if(void 0===o&&(o=!!a.backgroundColor),o===!1||null===o)return!1;if(o===!0)return"origin";if(i=parseFloat(o,10),isFinite(i)&&Math.floor(i)===i)return"-"!==o[0]&&"+"!==o[0]||(i=e+i),!(i===e||i<0||i>=n)&&i;switch(o){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return o;default:return!1}}function n(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,o=null;if(isFinite(a))return null;if("start"===a?o=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?o=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?o=n.scaleZero:i.getBasePosition?o=i.getBasePosition():i.getBasePixel&&(o=i.getBasePixel()),void 0!==o&&null!==o){if(void 0!==o.x&&void 0!==o.y)return o;if("number"==typeof o&&isFinite(o))return e=i.isHorizontal(),{x:e?o:null,y:e?null:o}}return null}function i(t,e,n){var i,a=t[e],o=a.fill,r=[e];if(!n)return o;for(;o!==!1&&r.indexOf(o)===-1;){if(!isFinite(o))return o;if(i=t[o],!i)return!1;if(i.visible)return o;r.push(o),o=i.fill}return!1}function a(t){var e=t.fill,n="dataset";return e===!1?null:(isFinite(e)||(n="boundary"),d[n](t))}function o(t){return t&&!t.skip}function r(t,e,n,i,a){var o;if(i&&a){for(t.moveTo(e[0].x,e[0].y),o=1;o<i;++o)u.canvas.lineTo(t,e[o-1],e[o]);for(t.lineTo(n[a-1].x,n[a-1].y),o=a-1;o>0;--o)u.canvas.lineTo(t,n[o],n[o-1],!0)}}function l(t,e,n,i,a,l){var s,u,d,c,h,f,g,p=e.length,m=i.spanGaps,v=[],b=[],x=0,y=0;for(t.beginPath(),s=0,u=p+!!l;s<u;++s)d=s%p,c=e[d]._view,h=n(c,d,i),f=o(c),g=o(h),f&&g?(x=v.push(c),y=b.push(h)):x&&y&&(m?(f&&v.push(c),g&&b.push(h)):(r(t,v,b,x,y),x=y=0,v=[],b=[]));r(t,v,b,x,y),t.closePath(),t.fillStyle=a,t.fill()}t.defaults.global.plugins.filler={propagate:!0};var s=t.defaults,u=t.helpers,d={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e),o=a&&i.dataset._children||[];return o.length?function(t,e){return o[e]._view||null}:null},boundary:function(t){var e=t.boundary,n=e?e.x:null,i=e?e.y:null;return function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};return{id:"filler",afterDatasetsUpdate:function(o,r){var l,s,u,d,c=(o.data.datasets||[]).length,h=r.propagate,f=[];for(s=0;s<c;++s)l=o.getDatasetMeta(s),u=l.dataset,d=null,u&&u._model&&u instanceof t.elements.Line&&(d={visible:o.isDatasetVisible(s),fill:e(u,s,c),chart:o,el:u}),l.$filler=d,f.push(d);for(s=0;s<c;++s)d=f[s],d&&(d.fill=i(f,s,h),d.boundary=n(d),d.mapper=a(d))},beforeDatasetDraw:function(t,e){var n=e.meta.$filler;if(n){var i=n.el,a=i._view,o=i._children||[],r=n.mapper,u=a.backgroundColor||s.global.defaultColor;r&&u&&o.length&&l(t.ctx,o,r,a,u,i._loop)}}}}},{}],42:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}function n(e,n){var i=new t.Legend({ctx:e.ctx,options:n,chart:e});a.configure(e,i,n),a.addBox(e,i),e.legend=i}var i=t.helpers,a=t.layoutService,o=i.noop;return t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,weight:1e3,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()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return i.isArray(e.datasets)?e.datasets.map(function(e,n){return{text:e.label,fillStyle:i.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(n),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:n}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){i.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:o,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:o,beforeSetDimensions:o,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:o,beforeBuildLabels:o,buildLabels:function(){var t=this,e=t.options.labels,n=e.generateLabels.call(t,t.chart);e.filter&&(n=n.filter(function(n){return e.filter(n,t.chart.data)})),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:o,beforeFit:o,fit:function(){var n=this,a=n.options,o=a.labels,r=a.display,l=n.ctx,s=t.defaults.global,u=i.getValueOrDefault,d=u(o.fontSize,s.defaultFontSize),c=u(o.fontStyle,s.defaultFontStyle),h=u(o.fontFamily,s.defaultFontFamily),f=i.fontString(d,c,h),g=n.legendHitBoxes=[],p=n.minSize,m=n.isHorizontal();if(m?(p.width=n.maxWidth,p.height=r?10:0):(p.width=r?10:0,p.height=n.maxHeight),r)if(l.font=f,m){var v=n.lineWidths=[0],b=n.legendItems.length?d+o.padding:0;l.textAlign="left",l.textBaseline="top",i.each(n.legendItems,function(t,i){var a=e(o,d),r=a+d/2+l.measureText(t.text).width;v[v.length-1]+r+o.padding>=n.width&&(b+=d+o.padding,v[v.length]=n.left),g[i]={left:0,top:0,width:r,height:d},v[v.length-1]+=r+o.padding}),p.height+=b}else{var x=o.padding,y=n.columnWidths=[],k=o.padding,w=0,M=0,S=d+x;i.each(n.legendItems,function(t,n){var i=e(o,d),a=i+d/2+l.measureText(t.text).width;M+S>p.height&&(k+=w+o.padding,y.push(w),w=0,M=0),w=Math.max(w,a),M+=S,g[n]={left:0,top:0,width:a,height:d}}),k+=w,y.push(w),p.width+=k}n.width=p.width,n.height=p.height},afterFit:o,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var n=this,a=n.options,o=a.labels,r=t.defaults.global,l=r.elements.line,s=n.width,u=n.lineWidths;if(a.display){var d,c=n.ctx,h=i.getValueOrDefault,f=h(o.fontColor,r.defaultFontColor),g=h(o.fontSize,r.defaultFontSize),p=h(o.fontStyle,r.defaultFontStyle),m=h(o.fontFamily,r.defaultFontFamily),v=i.fontString(g,p,m);c.textAlign="left",c.textBaseline="top",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=e(o,g),x=n.legendHitBoxes,y=function(e,n,i){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(i.fillStyle,r.defaultColor),c.lineCap=h(i.lineCap,l.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,l.borderDashOffset),c.lineJoin=h(i.lineJoin,l.borderJoinStyle),c.lineWidth=h(i.lineWidth,l.borderWidth),c.strokeStyle=h(i.strokeStyle,r.defaultColor);var o=0===h(i.lineWidth,l.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,l.borderDash)),a.labels&&a.labels.usePointStyle){var s=g*Math.SQRT2/2,u=s/Math.SQRT2,d=e+u,f=n+u;t.canvasHelpers.drawPoint(c,i.pointStyle,s,d,f)}else o||c.strokeRect(e,n,b,g),c.fillRect(e,n,b,g);c.restore()}},k=function(t,e,n,i){c.fillText(n.text,b+g/2+t,e),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(b+g/2+t,e+g/2),c.lineTo(b+g/2+t+i,e+g/2),c.stroke())},w=n.isHorizontal();d=w?{x:n.left+(s-u[0])/2,y:n.top+o.padding,line:0}:{x:n.left+o.padding,y:n.top+o.padding,line:0};var M=g+o.padding;i.each(n.legendItems,function(t,e){var i=c.measureText(t.text).width,a=b+g/2+i,r=d.x,l=d.y;w?r+a>=s&&(l=d.y+=M,d.line++,r=d.x=n.left+(s-u[d.line])/2):l+M>n.bottom&&(r=d.x=r+n.columnWidths[d.line]+o.padding,l=d.y=n.top+o.padding,d.line++),y(r,l,t),x[e].left=r,x[e].top=l,k(r,l,t,i),w?d.x+=a+o.padding:d.y+=M})}},handleEvent:function(t){var e=this,n=e.options,i="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===i){if(!n.onHover)return}else{if("click"!==i)return;if(!n.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var l=e.legendHitBoxes,s=0;s<l.length;++s){var u=l[s];if(o>=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===i){n.onClick.call(e,t.native,e.legendItems[s]),a=!0;break}if("mousemove"===i){n.onHover.call(e,t.native,e.legendItems[s]),a=!0;break}}}return a}}),{id:"legend",beforeInit:function(t){var e=t.options.legend;e&&n(t,e)},beforeUpdate:function(e){var o=e.options.legend,r=e.legend;o?(o=i.configMerge(t.defaults.global.legend,o),r?(a.configure(e,r,o),r.options=o):n(e,o)):r&&(a.removeBox(e,r),delete e.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}}}},{}],43:[function(t,e,n){"use strict";e.exports=function(t){function e(e,n){var a=new t.Title({ctx:e.ctx,options:n,chart:e});i.configure(e,a,n),i.addBox(e,a),e.titleBlock=a}var n=t.helpers,i=t.layoutService,a=n.noop;return t.defaults.global.title={display:!1,position:"top",fullWidth:!0,weight:2e3,fontStyle:"bold",padding:10,text:""},t.Title=t.Element.extend({initialize:function(t){var e=this;n.extend(e,t),e.legendHitBoxes=[];
-},beforeUpdate:a,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: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 e=this,i=n.getValueOrDefault,a=e.options,o=t.defaults.global,r=a.display,l=i(a.fontSize,o.defaultFontSize),s=e.minSize;e.isHorizontal()?(s.width=e.maxWidth,s.height=r?l+2*a.padding:0):(s.width=r?l+2*a.padding:0,s.height=e.maxHeight),e.width=s.width,e.height=s.height},afterFit:a,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var e=this,i=e.ctx,a=n.getValueOrDefault,o=e.options,r=t.defaults.global;if(o.display){var l,s,u,d=a(o.fontSize,r.defaultFontSize),c=a(o.fontStyle,r.defaultFontStyle),h=a(o.fontFamily,r.defaultFontFamily),f=n.fontString(d,c,h),g=0,p=e.top,m=e.left,v=e.bottom,b=e.right;i.fillStyle=a(o.fontColor,r.defaultFontColor),i.font=f,e.isHorizontal()?(l=m+(b-m)/2,s=p+(v-p)/2,u=b-m):(l="left"===o.position?m+d/2:b-d/2,s=p+(v-p)/2,u=v-p,g=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(l,s),i.rotate(g),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0,u),i.restore()}}}),{id:"title",beforeInit:function(t){var n=t.options.title;n&&e(t,n)},beforeUpdate:function(a){var o=a.options.title,r=a.titleBlock;o?(o=n.configMerge(t.defaults.global.title,o),r?(i.configure(a,r,o),r.options=o):e(a,o)):r&&(t.layoutService.removeBox(a,r),delete a.titleBlock)}}}},{}],44:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,n=t.getLabels();t.minIndex=0,t.maxIndex=n.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(n,t.options.ticks.min),t.minIndex=i!==-1?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(n,t.options.ticks.max),t.maxIndex=i!==-1?i:t.maxIndex),t.min=n[t.minIndex],t.max=n[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.isHorizontal();return i.yLabels&&!a?n.getRightValue(i.datasets[e].data[t]):n.ticks[t-n.minIndex]},getPixelForValue:function(t,e,n,i){var a,o=this,r=Math.max(o.maxIndex+1-o.minIndex-(o.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t&&null!==t&&(a=o.isHorizontal()?t.x:t.y),void 0!==a||void 0!==t&&isNaN(e)){var l=o.getLabels();t=a||t;var s=l.indexOf(t);e=s!==-1?s:e}if(o.isHorizontal()){var u=o.width/r,d=u*(e-o.minIndex);return(o.options.gridLines.offsetGridLines&&i||o.maxIndex===o.minIndex&&i)&&(d+=u/2),o.left+Math.round(d)}var c=o.height/r,h=c*(e-o.minIndex);return o.options.gridLines.offsetGridLines&&i&&(h+=c/2),o.top+Math.round(h)},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(),o=(a?n.width:n.height)/i;return t-=a?n.left:n.top,n.options.gridLines.offsetGridLines&&(t-=o/2),e=t<=0?0:Math.round(t/o)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,n)}},{}],45:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return l?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=n.chart,o=a.data,r=o.datasets,l=n.isHorizontal(),s=0,u=1;n.min=null,n.max=null;var d=i.stacked;if(void 0===d&&e.each(r,function(e,n){if(!d){var i=a.getDatasetMeta(n);a.isDatasetVisible(n)&&t(i)&&void 0!==i.stack&&(d=!0)}}),i.stacked||d){var c={};e.each(r,function(o,r){var l=a.getDatasetMeta(r),s=[l.type,void 0===i.stacked&&void 0===l.stack?r:"",l.stack].join(".");void 0===c[s]&&(c[s]={positiveValues:[],negativeValues:[]});var u=c[s].positiveValues,d=c[s].negativeValues;a.isDatasetVisible(r)&&t(l)&&e.each(o.data,function(t,e){var a=+n.getRightValue(t);isNaN(a)||l.data[e].hidden||(u[e]=u[e]||0,d[e]=d[e]||0,i.relativePoints?u[e]=100:a<0?d[e]+=a:u[e]+=a)})}),e.each(c,function(t){var i=t.positiveValues.concat(t.negativeValues),a=e.min(i),o=e.max(i);n.min=null===n.min?a:Math.min(n.min,a),n.max=null===n.max?o:Math.max(n.max,o)})}else e.each(r,function(i,o){var r=a.getDatasetMeta(o);a.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||r.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=isFinite(n.min)?n.min:s,n.max=isFinite(n.max)?n.max:u,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 o=e.getValueOrDefault(a.fontSize,t.defaults.global.defaultFontSize);n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}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){var e,n=this,i=n.start,a=+n.getRightValue(t),o=n.end-i;return n.isHorizontal()?(e=n.left+n.width/o*(a-i),Math.round(e)):(e=n.bottom-n.height/o*(a-i),Math.round(e))},getValueForPixel:function(t){var e=this,n=e.isHorizontal(),i=n?e.width:e.height,a=(n?t-e.left:e.bottom-t)/i;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,n)}},{}],46:[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),o=e.sign(t.max);a<0&&o<0?t.max=0:a>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(null===t.min?t.min=i.suggestedMin:t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(null===t.max?t.max=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 n=this,i=n.options,a=i.ticks,o=n.getTickLimit();o=Math.max(2,o);var r={maxTicks:o,min:a.min,max:a.max,stepSize:e.getValueOrDefault(a.fixedStepSize,a.stepSize)},l=n.ticks=t.Ticks.generators.linear(r,n);n.handleDirectionalChanges(),n.max=e.max(l),n.min=e.min(l),a.reverse?(l.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],47:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.logarithmic}},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,o=n.chart,r=o.data,l=r.datasets,s=e.getValueOrDefault,u=n.isHorizontal();n.min=null,n.max=null,n.minNotZero=null;var d=i.stacked;if(void 0===d&&e.each(l,function(e,n){if(!d){var i=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(i)&&void 0!==i.stack&&(d=!0)}}),i.stacked||d){var c={};e.each(l,function(a,r){var l=o.getDatasetMeta(r),s=[l.type,void 0===i.stacked&&void 0===l.stack?r:"",l.stack].join(".");o.isDatasetVisible(r)&&t(l)&&(void 0===c[s]&&(c[s]=[]),e.each(a.data,function(t,e){var a=c[s],o=+n.getRightValue(t);isNaN(o)||l.data[e].hidden||(a[e]=a[e]||0,i.relativePoints?a[e]=100:a[e]+=o)}))}),e.each(c,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(l,function(i,a){var r=o.getDatasetMeta(a);o.isDatasetVisible(a)&&t(r)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||r.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),0!==i&&(null===n.minNotZero||i<n.minNotZero)&&(n.minNotZero=i))})});n.min=s(a.min,n.min),n.max=s(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(){var n=this,i=n.options,a=i.ticks,o={min:a.min,max:a.max},r=n.ticks=t.Ticks.generators.logarithmic(o,n);n.isHorizontal()||r.reverse(),n.max=e.max(r),n.min=e.min(r),a.reverse?(r.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.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){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var n,i,a,o=this,r=o.start,l=+o.getRightValue(t),s=o.options,u=s.ticks;return o.isHorizontal()?(a=e.log10(o.end)-e.log10(r),0===l?i=o.left:(n=o.width,i=o.left+n/a*(e.log10(l)-e.log10(r)))):(n=o.height,0!==r||u.reverse?0===o.end&&u.reverse?(a=e.log10(o.start)-e.log10(o.minNotZero),i=l===o.end?o.top:l===o.minNotZero?o.top+.02*n:o.top+.02*n+.98*n/a*(e.log10(l)-e.log10(o.minNotZero))):0===l?i=u.reverse?o.top:o.bottom:(a=e.log10(o.end)-e.log10(r),n=o.height,i=o.bottom-n/a*(e.log10(l)-e.log10(r))):(a=e.log10(o.end)-e.log10(o.minNotZero),i=l===r?o.bottom:l===o.minNotZero?o.bottom-.02*n:o.bottom-.02*n-.98*n/a*(e.log10(l)-e.log10(o.minNotZero)))),i},getValueForPixel:function(t){var n,i,a=this,o=e.log10(a.end)-e.log10(a.start);return a.isHorizontal()?(i=a.width,n=a.start*Math.pow(10,(t-a.left)*o/i)):(i=a.height,n=Math.pow(10,(a.bottom-t)*o/i)/a.start),n}});t.scaleService.registerScaleType("logarithmic",i,n)}},{}],48:[function(t,e,n){"use strict";e.exports=function(t){function e(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function n(t){var e=t.options.pointLabels,n=f.getValueOrDefault(e.fontSize,g.defaultFontSize),i=f.getValueOrDefault(e.fontStyle,g.defaultFontStyle),a=f.getValueOrDefault(e.fontFamily,g.defaultFontFamily),o=f.fontString(n,i,a);return{size:n,style:i,family:a,font:o}}function i(t,e,n){return f.isArray(n)?{w:f.longestText(t,t.font,n),h:n.length*e+1.5*(n.length-1)*e}:{w:t.measureText(n).width,h:e}}function a(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:t<i||t>a?{start:e-n-5,end:e}:{start:e,end:e+n+5}}function o(t){var o,r,l,s=n(t),u=Math.min(t.height/2,t.width/2),d={r:t.width,l:0,t:t.height,b:0},c={};t.ctx.font=s.font,t._pointLabelSizes=[];var h=e(t);for(o=0;o<h;o++){l=t.getPointPosition(o,u),r=i(t.ctx,s.size,t.pointLabels[o]||""),t._pointLabelSizes[o]=r;var g=t.getIndexAngle(o),p=f.toDegrees(g)%360,m=a(p,l.x,r.w,0,180),v=a(p,l.y,r.h,90,270);m.start<d.l&&(d.l=m.start,c.l=g),m.end>d.r&&(d.r=m.end,c.r=g),v.start<d.t&&(d.t=v.start,c.t=g),v.end>d.b&&(d.b=v.end,c.b=g)}t.setReductions(u,d,c)}function r(t){var e=Math.min(t.height/2,t.width/2);t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0)}function l(t){return 0===t||180===t?"center":t<180?"left":"right"}function s(t,e,n,i){if(f.isArray(e))for(var a=n.y,o=1.5*i,r=0;r<e.length;++r)t.fillText(e[r],n.x,a),a+=o;else t.fillText(e,n.x,n.y)}function u(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function d(t){var i=t.ctx,a=f.getValueOrDefault,o=t.options,r=o.angleLines,d=o.pointLabels;i.lineWidth=r.lineWidth,i.strokeStyle=r.color;var c=t.getDistanceFromCenterForValue(o.reverse?t.min:t.max),h=n(t);i.textBaseline="top";for(var p=e(t)-1;p>=0;p--){if(r.display){var m=t.getPointPosition(p,c);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(m.x,m.y),i.stroke(),i.closePath()}if(d.display){var v=t.getPointPosition(p,c+5),b=a(d.fontColor,g.defaultFontColor);i.font=h.font,i.fillStyle=b;var x=t.getIndexAngle(p),y=f.toDegrees(x);i.textAlign=l(y),u(y,t._pointLabelSizes[p],v),s(i,t.pointLabels[p]||"",v,h.size)}}}function c(t,n,i,a){var o=t.ctx;if(o.strokeStyle=f.getValueAtIndexOrDefault(n.color,a-1),o.lineWidth=f.getValueAtIndexOrDefault(n.lineWidth,a-1),t.options.gridLines.circular)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var r=e(t);if(0===r)return;o.beginPath();var l=t.getPointPosition(0,i);o.moveTo(l.x,l.y);for(var s=1;s<r;s++)l=t.getPointPosition(s,i),o.lineTo(l.x,l.y);o.closePath(),o.stroke()}}function h(t){return f.isNumber(t)?t:0}var f=t.helpers,g=t.defaults.global,p={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:t.Ticks.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}},m=t.LinearScaleBase.extend({setDimensions:function(){var t=this,e=t.options,n=e.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var i=f.min([t.height,t.width]),a=f.getValueOrDefault(n.fontSize,g.defaultFontSize);t.drawingArea=e.display?i/2-(a/2+n.backdropPaddingY):i/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;f.each(e.data.datasets,function(a,o){if(e.isDatasetVisible(o)){var r=e.getDatasetMeta(o);f.each(a.data,function(e,a){var o=+t.getRightValue(e);isNaN(o)||r.data[a].hidden||(n=Math.min(o,n),i=Math.max(o,i))})}}),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,e=f.getValueOrDefault(t.fontSize,g.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*e)))},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(){this.options.pointLabels.display?o(this):r(this)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),o=Math.max(e.r-i.width,0)/Math.sin(n.r),r=-e.t/Math.cos(n.t),l=-Math.max(e.b-i.height,0)/Math.cos(n.b);a=h(a),o=h(o),r=h(r),l=h(l),i.drawingArea=Math.min(Math.round(t-(a+o)/2),Math.round(t-(r+l)/2)),i.setCenterPoint(a,o,r,l)},setCenterPoint:function(t,e,n,i){var a=this,o=a.width-e-a.drawingArea,r=t+a.drawingArea,l=n+a.drawingArea,s=a.height-i-a.drawingArea;a.xCenter=Math.round((r+o)/2+a.left),a.yCenter=Math.round((l+s)/2+a.top)},getIndexAngle:function(t){var n=2*Math.PI/e(this),i=this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0,a=i*Math.PI*2/360;return t*n+a},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)-Math.PI/2;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:e<0&&n<0?n:e>0&&n>0?e:0)},draw:function(){var t=this,e=t.options,n=e.gridLines,i=e.ticks,a=f.getValueOrDefault;if(e.display){var o=t.ctx,r=a(i.fontSize,g.defaultFontSize),l=a(i.fontStyle,g.defaultFontStyle),s=a(i.fontFamily,g.defaultFontFamily),u=f.fontString(r,l,s);f.each(t.ticks,function(l,s){if(s>0||e.reverse){var d=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]),h=t.yCenter-d;if(n.display&&0!==s&&c(t,n,d,s),i.display){var f=a(i.fontColor,g.defaultFontColor);if(o.font=u,i.showLabelBackdrop){var p=o.measureText(l).width;o.fillStyle=i.backdropColor,o.fillRect(t.xCenter-p/2-i.backdropPaddingX,h-r/2-i.backdropPaddingY,p+2*i.backdropPaddingX,r+2*i.backdropPaddingY)}o.textAlign="center",o.textBaseline="middle",o.fillStyle=f,o.fillText(l,t.xCenter,h)}}}),(e.angleLines.display||e.pointLabels.display)&&d(t)}}});t.scaleService.registerScaleType("radialLinear",m,p)}},{}],49:[function(t,e,n){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){function e(t,e){var n=t.options.time;if("string"==typeof n.parser)return i(e,n.parser);if("function"==typeof n.parser)return n.parser(e);if("function"==typeof e.getMonth||"number"==typeof e)return i(e);if(e.isValid&&e.isValid())return e;var a=n.format;return"string"!=typeof a&&a.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser."),a(e)):i(e,a)}function n(t,e,n,i){for(var a,o=Object.keys(l),r=o.length,s=o.indexOf(t);s<r;s++){a=o[s];var u=l[a],d=u.steps&&u.steps[u.steps.length-1]||u.maxStep;if(void 0===d||Math.ceil((n-e)/(d*u.size))<=i)break}return a}function a(t,e,n,i){var a=l[n],o=a.size,r=Math.ceil((e-t)/o),s=1,u=e-t;if(a.steps)for(var d=a.steps.length,c=0;c<d&&r>i;c++)s=a.steps[c],r=Math.ceil(u/(o*s));else for(;r>i&&i>0;)++s,r=Math.ceil(u/(o*s));return s}function o(t,e,n){var a=[];if(t.maxTicks){var o=t.stepSize;a.push(void 0!==t.min?t.min:n.min);for(var r=i(n.min);r.add(o,t.unit).valueOf()<n.max;)a.push(r.valueOf());var l=t.max||n.max;a[a.length-1]!==l&&a.push(l)}return a}var r=t.helpers,l={millisecond:{size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{size:1e3,steps:[1,2,5,10,30]},minute:{size:6e4,steps:[1,2,5,10,30]},hour:{size:36e5,steps:[1,2,3,6,12]},day:{size:864e5,steps:[1,2,5]},week:{size:6048e5,maxStep:4},month:{size:2628e6,maxStep:3},quarter:{size:7884e6,maxStep:4},year:{size:3154e7,maxStep:!1}},s={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",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}};t.Ticks.generators.time=function(t,e){var n,a,r=t.isoWeekday;return"week"===t.unit&&r!==!1?(n=i(e.min).startOf("isoWeek").isoWeekday(r).valueOf(),a=i(e.max).startOf("isoWeek").isoWeekday(r),e.max-a>0&&a.add(1,"week"),a=a.valueOf()):(n=i(e.min).startOf(t.unit).valueOf(),a=i(e.max).startOf(t.unit),e.max-a>0&&a.add(1,t.unit),a=a.valueOf()),o(t,e,{min:n,max:a})};var u=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)},determineDataLimits:function(){var t,n=this,i=n.options.time,a=Number.MAX_SAFE_INTEGER,o=Number.MIN_SAFE_INTEGER,l=n.chart.data,s={labels:[],datasets:[]};r.each(l.labels,function(r,l){var u=e(n,r);u.isValid()&&(i.round&&u.startOf(i.round),t=u.valueOf(),a=Math.min(t,a),o=Math.max(t,o),s.labels[l]=t)}),r.each(l.datasets,function(l,u){var d=[];"object"==typeof l.data[0]&&null!==l.data[0]&&n.chart.isDatasetVisible(u)?r.each(l.data,function(r,l){var s=e(n,n.getRightValue(r));s.isValid()&&(i.round&&s.startOf(i.round),t=s.valueOf(),a=Math.min(t,a),o=Math.max(t,o),d[l]=t)}):d=s.labels.slice(),s.datasets[u]=d}),n.dataMin=a,n.dataMax=o,n._parsedData=s},buildTicks:function(){var i,o,l=this,s=l.options.time,u=l.dataMin,d=l.dataMax;if(s.min){var c=e(l,s.min);s.round&&c.round(s.round),i=c.valueOf()}s.max&&(o=e(l,s.max).valueOf());var h=l.getLabelCapacity(i||u),f=s.unit||n(s.minUnit,i||u,o||d,h);l.displayFormat=s.displayFormats[f];var g=s.stepSize||a(i||u,o||d,f,h);l.ticks=t.Ticks.generators.time({maxTicks:h,min:i,max:o,stepSize:g,unit:f,isoWeekday:s.isoWeekday},{min:u,max:d}),l.max=r.max(l.ticks),l.min=r.min(l.ticks)},getLabelForIndex:function(t,n){var i=this,a=i.chart.data.labels&&t<i.chart.data.labels.length?i.chart.data.labels[t]:"",o=i.chart.data.datasets[n].data[t];return null!==o&&"object"==typeof o&&(a=i.getRightValue(o)),i.options.time.tooltipFormat&&(a=e(i,a).format(i.options.time.tooltipFormat)),a},tickFormatFunction:function(t,e,n){var i=t.format(this.displayFormat),a=this.options.ticks,o=r.getValueOrDefault(a.callback,a.userCallback);return o?o(i,e,n):i},convertTicksToLabels:function(){var t=this;t.ticksAsTimestamps=t.ticks,t.ticks=t.ticks.map(function(t){return i(t)}).map(t.tickFormatFunction,t)},getPixelForOffset:function(t){var e=this,n=e.max-e.min,i=n?(t-e.min)/n:0;if(e.isHorizontal()){var a=e.width*i;return e.left+Math.round(a)}var o=e.height*i;return e.top+Math.round(o)},getPixelForValue:function(t,n,i){var a=this,o=null;if(void 0!==n&&void 0!==i&&(o=a._parsedData.datasets[i][n]),null===o&&(t&&t.isValid||(t=e(a,a.getRightValue(t))),t&&t.isValid&&t.isValid()&&(o=t.valueOf())),null!==o)return a.getPixelForOffset(o)},getPixelForTick:function(t){return this.getPixelForOffset(this.ticksAsTimestamps[t])},getValueForPixel:function(t){var e=this,n=e.isHorizontal()?e.width:e.height,a=(t-(e.isHorizontal()?e.left:e.top))/n;return i(e.min+a*(e.max-e.min))},getLabelWidth:function(e){var n=this,i=n.options.ticks,a=n.ctx.measureText(e).width,o=Math.cos(r.toRadians(i.maxRotation)),l=Math.sin(r.toRadians(i.maxRotation)),s=r.getValueOrDefault(i.fontSize,t.defaults.global.defaultFontSize);return a*o+s*l},getLabelCapacity:function(t){var e=this;e.displayFormat=e.options.time.displayFormats.millisecond;var n=e.tickFormatFunction(i(t),0,[]),a=e.getLabelWidth(n),o=e.isHorizontal()?e.width:e.height,r=o/a;return r}});t.scaleService.registerScaleType("time",u,s)}},{1:1}]},{},[7])(7)});
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/tp/D3.LICENSE b/web/gui/src/main/webapp/tp/D3.LICENSE
deleted file mode 100644
index 83013469..0000000
--- a/web/gui/src/main/webapp/tp/D3.LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 2010-2014, Michael Bostock
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-* The name Michael Bostock may not be used to endorse or promote products
-  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/web/gui/src/main/webapp/tp/README.txt b/web/gui/src/main/webapp/tp/README.txt
deleted file mode 100644
index c4e0e80..0000000
--- a/web/gui/src/main/webapp/tp/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-# Third Party libraries
diff --git a/web/gui/src/main/webapp/tp/angular-chart.LICENSE b/web/gui/src/main/webapp/tp/angular-chart.LICENSE
deleted file mode 100644
index f3bd714..0000000
--- a/web/gui/src/main/webapp/tp/angular-chart.LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) Jerome Touffe-Blin ("Author")
-All rights reserved.
-
-The BSD License
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/tp/angular-chart.js b/web/gui/src/main/webapp/tp/angular-chart.js
deleted file mode 100755
index 26ac9fe..0000000
--- a/web/gui/src/main/webapp/tp/angular-chart.js
+++ /dev/null
@@ -1,374 +0,0 @@
-/*!
- * angular-chart.js - An angular.js wrapper for Chart.js
- * http://jtblin.github.io/angular-chart.js/
- * Version: 1.0.0
- *
- * Copyright 2016 Jerome Touffe-Blin
- * Released under the BSD-2-Clause license
- * https://github.com/jtblin/angular-chart.js/blob/master/LICENSE
- */
-(function (factory) {
-  'use strict';
-  if (typeof exports === 'object') {
-    // Node/CommonJS
-    module.exports = factory(
-      typeof angular !== 'undefined' ? angular : require('angular'),
-      typeof Chart !== 'undefined' ? Chart : require('chart.js'));
-  }  else if (typeof define === 'function' && define.amd) {
-    // AMD. Register as an anonymous module.
-    define(['angular', 'chart'], factory);
-  } else {
-    // Browser globals
-    if (typeof angular === 'undefined' || typeof Chart === 'undefined')
-      throw new Error('Chart.js library needs to included, see http://jtblin.github.io/angular-chart.js/');
-    factory(angular, Chart);
-  }
-}(function (angular, Chart) {
-  'use strict';
-
-  Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>';
-  Chart.defaults.global.tooltips.mode = 'label';
-  Chart.defaults.global.elements.line.borderWidth = 2;
-  Chart.defaults.global.elements.rectangle.borderWidth = 2;
-  Chart.defaults.global.legend.display = false;
-  Chart.defaults.global.colors = [
-    '#97BBCD', // blue
-    '#DCDCDC', // light grey
-    '#F7464A', // red
-    '#46BFBD', // green
-    '#FDB45C', // yellow
-    '#949FB1', // grey
-    '#4D5360'  // dark grey
-  ];
-
-  var useExcanvas = typeof window.G_vmlCanvasManager === 'object' &&
-    window.G_vmlCanvasManager !== null &&
-    typeof window.G_vmlCanvasManager.initElement === 'function';
-
-  if (useExcanvas) Chart.defaults.global.animation = false;
-
-  return angular.module('chart.js', [])
-    .provider('ChartJs', ChartJsProvider)
-    .factory('ChartJsFactory', ['ChartJs', '$timeout', ChartJsFactory])
-    .directive('chartBase', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory(); }])
-    .directive('chartLine', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('line'); }])
-    .directive('chartBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bar'); }])
-    .directive('chartHorizontalBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('horizontalBar'); }])
-    .directive('chartRadar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('radar'); }])
-    .directive('chartDoughnut', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('doughnut'); }])
-    .directive('chartPie', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('pie'); }])
-    .directive('chartPolarArea', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('polarArea'); }])
-    .directive('chartBubble', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bubble'); }])
-    .name;
-
-  /**
-   * Wrapper for chart.js
-   * Allows configuring chart js using the provider
-   *
-   * angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) {
-   *   ChartJsProvider.setOptions({ responsive: false });
-   *   ChartJsProvider.setOptions('Line', { responsive: true });
-   * })))
-   */
-  function ChartJsProvider () {
-    var options = { responsive: true };
-    var ChartJs = {
-      Chart: Chart,
-      getOptions: function (type) {
-        var typeOptions = type && options[type] || {};
-        return angular.extend({}, options, typeOptions);
-      }
-    };
-
-    /**
-     * Allow to set global options during configuration
-     */
-    this.setOptions = function (type, customOptions) {
-      // If no type was specified set option for the global object
-      if (! customOptions) {
-        customOptions = type;
-        options = angular.extend(options, customOptions);
-        return;
-      }
-      // Set options for the specific chart
-      options[type] = angular.extend(options[type] || {}, customOptions);
-    };
-
-    this.$get = function () {
-      return ChartJs;
-    };
-  }
-
-  function ChartJsFactory (ChartJs, $timeout) {
-    return function chart (type) {
-      return {
-        restrict: 'CA',
-        scope: {
-          chartGetColor: '=?',
-          chartType: '=',
-          chartData: '=?',
-          chartLabels: '=?',
-          chartOptions: '=?',
-          chartSeries: '=?',
-          chartColors: '=?',
-          chartClick: '=?',
-          chartHover: '=?',
-          chartDatasetOverride: '=?'
-        },
-        link: function (scope, elem/*, attrs */) {
-          if (useExcanvas) window.G_vmlCanvasManager.initElement(elem[0]);
-
-          // Order of setting "watch" matter
-          scope.$watch('chartData', watchData, true);
-          scope.$watch('chartSeries', watchOther, true);
-          scope.$watch('chartLabels', watchOther, true);
-          scope.$watch('chartOptions', watchOther, true);
-          scope.$watch('chartColors', watchOther, true);
-          scope.$watch('chartDatasetOverride', watchOther, true);
-          scope.$watch('chartType', watchType, false);
-
-          scope.$on('$destroy', function () {
-            destroyChart(scope);
-          });
-
-          scope.$on('$resize', function () {
-            if (scope.chart) scope.chart.resize();
-          });
-
-          function watchData (newVal, oldVal) {
-            if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) {
-              destroyChart(scope);
-              return;
-            }
-            var chartType = type || scope.chartType;
-            if (! chartType) return;
-
-            if (scope.chart && canUpdateChart(newVal, oldVal))
-              return updateChart(newVal, scope);
-
-            createChart(chartType, scope, elem);
-          }
-
-          function watchOther (newVal, oldVal) {
-            if (isEmpty(newVal)) return;
-            if (angular.equals(newVal, oldVal)) return;
-            var chartType = type || scope.chartType;
-            if (! chartType) return;
-
-            // chart.update() doesn't work for series and labels
-            // so we have to re-create the chart entirely
-            createChart(chartType, scope, elem);
-          }
-
-          function watchType (newVal, oldVal) {
-            if (isEmpty(newVal)) return;
-            if (angular.equals(newVal, oldVal)) return;
-            createChart(newVal, scope, elem);
-          }
-        }
-      };
-    };
-
-    function createChart (type, scope, elem) {
-      var options = getChartOptions(type, scope);
-      if (! hasData(scope) || ! canDisplay(type, scope, elem, options)) return;
-
-      var cvs = elem[0];
-      var ctx = cvs.getContext('2d');
-
-      scope.chartGetColor = getChartColorFn(scope);
-      var data = getChartData(type, scope);
-
-      // Destroy old chart if it exists to avoid ghost charts issue
-      // https://github.com/jtblin/angular-chart.js/issues/187
-      destroyChart(scope);
-
-      scope.chart = new ChartJs.Chart(ctx, {
-        type: type,
-        data: data,
-        options: options
-      });
-      scope.$emit('chart-create', scope.chart);
-      bindEvents(cvs, scope);
-    }
-
-    function canUpdateChart (newVal, oldVal) {
-      if (newVal && oldVal && newVal.length && oldVal.length) {
-        return Array.isArray(newVal[0]) ?
-        newVal.length === oldVal.length && newVal.every(function (element, index) {
-          return element.length === oldVal[index].length; }) :
-          oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false;
-      }
-      return false;
-    }
-
-    function sum (carry, val) {
-      return carry + val;
-    }
-
-    function getEventHandler (scope, action, triggerOnlyOnChange) {
-      var lastState = null;
-      return function (evt) {
-        var atEvent = scope.chart.getElementsAtEvent || scope.chart.getPointsAtEvent;
-        if (atEvent) {
-          var activePoints = atEvent.call(scope.chart, evt);
-          if (triggerOnlyOnChange === false || angular.equals(lastState, activePoints) === false) {
-            lastState = activePoints;
-            scope[action](activePoints, evt);
-          }
-        }
-      };
-    }
-
-    function getColors (type, scope) {
-      var colors = angular.copy(scope.chartColors ||
-        ChartJs.getOptions(type).chartColors ||
-        Chart.defaults.global.colors
-      );
-      var notEnoughColors = colors.length < scope.chartData.length;
-      while (colors.length < scope.chartData.length) {
-        colors.push(scope.chartGetColor());
-      }
-      // mutate colors in this case as we don't want
-      // the colors to change on each refresh
-      if (notEnoughColors) scope.chartColors = colors;
-      return colors.map(convertColor);
-    }
-
-    function convertColor (color) {
-      if (typeof color === 'object' && color !== null) return color;
-      if (typeof color === 'string' && color[0] === '#') return getColor(hexToRgb(color.substr(1)));
-      return getRandomColor();
-    }
-
-    function getRandomColor () {
-      var color = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)];
-      return getColor(color);
-    }
-
-    function getColor (color) {
-      return {
-        backgroundColor: rgba(color, 0.2),
-        pointBackgroundColor: rgba(color, 1),
-        pointHoverBackgroundColor: rgba(color, 0.8),
-        borderColor: rgba(color, 1),
-        pointBorderColor: '#fff',
-        pointHoverBorderColor: rgba(color, 1)
-      };
-    }
-
-    function getRandomInt (min, max) {
-      return Math.floor(Math.random() * (max - min + 1)) + min;
-    }
-
-    function rgba (color, alpha) {
-      // rgba not supported by IE8
-      return useExcanvas ? 'rgb(' + color.join(',') + ')' : 'rgba(' + color.concat(alpha).join(',') + ')';
-    }
-
-    // Credit: http://stackoverflow.com/a/11508164/1190235
-    function hexToRgb (hex) {
-      var bigint = parseInt(hex, 16),
-        r = (bigint >> 16) & 255,
-        g = (bigint >> 8) & 255,
-        b = bigint & 255;
-
-      return [r, g, b];
-    }
-
-    function hasData (scope) {
-      return scope.chartData && scope.chartData.length;
-    }
-
-    function getChartColorFn (scope) {
-      return typeof scope.chartGetColor === 'function' ? scope.chartGetColor : getRandomColor;
-    }
-
-    function getChartData (type, scope) {
-      var colors = getColors(type, scope);
-      return Array.isArray(scope.chartData[0]) ?
-        getDataSets(scope.chartLabels, scope.chartData, scope.chartSeries || [], colors, scope.chartDatasetOverride) :
-        getData(scope.chartLabels, scope.chartData, colors, scope.chartDatasetOverride);
-    }
-
-    function getDataSets (labels, data, series, colors, datasetOverride) {
-      return {
-        labels: labels,
-        datasets: data.map(function (item, i) {
-          var dataset = angular.extend({}, colors[i], {
-            label: series[i],
-            data: item
-          });
-          if (datasetOverride && datasetOverride.length >= i) {
-            angular.merge(dataset, datasetOverride[i]);
-          }
-          return dataset;
-        })
-      };
-    }
-
-    function getData (labels, data, colors, datasetOverride) {
-      var dataset = {
-        labels: labels,
-        datasets: [{
-          data: data,
-          backgroundColor: colors.map(function (color) {
-            return color.pointBackgroundColor;
-          }),
-          hoverBackgroundColor: colors.map(function (color) {
-            return color.backgroundColor;
-          })
-        }]
-      };
-      if (datasetOverride) {
-        angular.merge(dataset.datasets[0], datasetOverride);
-      }
-      return dataset;
-    }
-
-    function getChartOptions (type, scope) {
-      return angular.extend({}, ChartJs.getOptions(type), scope.chartOptions);
-    }
-
-    function bindEvents (cvs, scope) {
-      cvs.onclick = scope.chartClick ? getEventHandler(scope, 'chartClick', false) : angular.noop;
-      cvs.onmousemove = scope.chartHover ? getEventHandler(scope, 'chartHover', true) : angular.noop;
-    }
-
-    function updateChart (values, scope) {
-      if (Array.isArray(scope.chartData[0])) {
-        scope.chart.data.datasets.forEach(function (dataset, i) {
-          dataset.data = values[i];
-        });
-      } else {
-        scope.chart.data.datasets[0].data = values;
-      }
-
-      scope.chart.update();
-      scope.$emit('chart-update', scope.chart);
-    }
-
-    function isEmpty (value) {
-      return ! value ||
-        (Array.isArray(value) && ! value.length) ||
-        (typeof value === 'object' && ! Object.keys(value).length);
-    }
-
-    function canDisplay (type, scope, elem, options) {
-      // TODO: check parent?
-      if (options.responsive && elem[0].clientHeight === 0) {
-        $timeout(function () {
-          createChart(type, scope, elem);
-        }, 50, false);
-        return false;
-      }
-      return true;
-    }
-
-    function destroyChart(scope) {
-      if(! scope.chart) return;
-      scope.chart.destroy();
-      scope.$emit('chart-destroy', scope.chart);
-    }
-  }
-}));
diff --git a/web/gui/src/main/webapp/tp/angular-chart.min.js b/web/gui/src/main/webapp/tp/angular-chart.min.js
deleted file mode 100755
index 644c32c..0000000
--- a/web/gui/src/main/webapp/tp/angular-chart.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/*!
- * angular-chart.js - An angular.js wrapper for Chart.js
- * http://jtblin.github.io/angular-chart.js/
- * Version: 1.0.0
- *
- * Copyright 2016 Jerome Touffe-Blin
- * Released under the BSD-2-Clause license
- * https://github.com/jtblin/angular-chart.js/blob/master/LICENSE
- */
-!function(t){"use strict";if("object"==typeof exports)module.exports=t("undefined"!=typeof angular?angular:require("angular"),"undefined"!=typeof Chart?Chart:require("chart.js"));else if("function"==typeof define&&define.amd)define(["angular","chart"],t);else{if("undefined"==typeof angular||"undefined"==typeof Chart)throw new Error("Chart.js library needs to included, see http://jtblin.github.io/angular-chart.js/");t(angular,Chart)}}(function(t,r){"use strict";function a(){var a={responsive:!0},e={Chart:r,getOptions:function(r){var e=r&&a[r]||{};return t.extend({},a,e)}};this.setOptions=function(r,e){return e?void(a[r]=t.extend(a[r]||{},e)):(e=r,void(a=t.extend(a,e)))},this.$get=function(){return e}}function e(a,e){function o(t,r,e){var n=w(t,r);if(p(r)&&$(t,r,e,n)){var o=e[0],c=o.getContext("2d");r.chartGetColor=C(r);var i=y(t,r);F(r),r.chart=new a.Chart(c,{type:t,data:i,options:n}),r.$emit("chart-create",r.chart),D(o,r)}}function c(t,r){return t&&r&&t.length&&r.length?Array.isArray(t[0])?t.length===r.length&&t.every(function(t,a){return t.length===r[a].length}):r.reduce(i,0)>0?t.length===r.length:!1:!1}function i(t,r){return t+r}function u(r,a,e){var n=null;return function(o){var c=r.chart.getElementsAtEvent||r.chart.getPointsAtEvent;if(c){var i=c.call(r.chart,o);e!==!1&&t.equals(n,i)!==!1||(n=i,r[a](i,o))}}}function h(e,n){for(var o=t.copy(n.chartColors||a.getOptions(e).chartColors||r.defaults.global.colors),c=o.length<n.chartData.length;o.length<n.chartData.length;)o.push(n.chartGetColor());return c&&(n.chartColors=o),o.map(l)}function l(t){return"object"==typeof t&&null!==t?t:"string"==typeof t&&"#"===t[0]?f(v(t.substr(1))):s()}function s(){var t=[d(0,255),d(0,255),d(0,255)];return f(t)}function f(t){return{backgroundColor:g(t,.2),pointBackgroundColor:g(t,1),pointHoverBackgroundColor:g(t,.8),borderColor:g(t,1),pointBorderColor:"#fff",pointHoverBorderColor:g(t,1)}}function d(t,r){return Math.floor(Math.random()*(r-t+1))+t}function g(t,r){return n?"rgb("+t.join(",")+")":"rgba("+t.concat(r).join(",")+")"}function v(t){var r=parseInt(t,16),a=r>>16&255,e=r>>8&255,n=255&r;return[a,e,n]}function p(t){return t.chartData&&t.chartData.length}function C(t){return"function"==typeof t.chartGetColor?t.chartGetColor:s}function y(t,r){var a=h(t,r);return Array.isArray(r.chartData[0])?b(r.chartLabels,r.chartData,r.chartSeries||[],a,r.chartDatasetOverride):m(r.chartLabels,r.chartData,a,r.chartDatasetOverride)}function b(r,a,e,n,o){return{labels:r,datasets:a.map(function(r,a){var c=t.extend({},n[a],{label:e[a],data:r});return o&&o.length>=a&&t.merge(c,o[a]),c})}}function m(r,a,e,n){var o={labels:r,datasets:[{data:a,backgroundColor:e.map(function(t){return t.pointBackgroundColor}),hoverBackgroundColor:e.map(function(t){return t.backgroundColor})}]};return n&&t.merge(o.datasets[0],n),o}function w(r,e){return t.extend({},a.getOptions(r),e.chartOptions)}function D(r,a){r.onclick=a.chartClick?u(a,"chartClick",!1):t.noop,r.onmousemove=a.chartHover?u(a,"chartHover",!0):t.noop}function B(t,r){Array.isArray(r.chartData[0])?r.chart.data.datasets.forEach(function(r,a){r.data=t[a]}):r.chart.data.datasets[0].data=t,r.chart.update(),r.$emit("chart-update",r.chart)}function A(t){return!t||Array.isArray(t)&&!t.length||"object"==typeof t&&!Object.keys(t).length}function $(t,r,a,n){return n.responsive&&0===a[0].clientHeight?(e(function(){o(t,r,a)},50,!1),!1):!0}function F(t){t.chart&&(t.chart.destroy(),t.$emit("chart-destroy",t.chart))}return function(r){return{restrict:"CA",scope:{chartGetColor:"=?",chartType:"=",chartData:"=?",chartLabels:"=?",chartOptions:"=?",chartSeries:"=?",chartColors:"=?",chartClick:"=?",chartHover:"=?",chartDatasetOverride:"=?"},link:function(a,e){function i(t,n){if(!t||!t.length||Array.isArray(t[0])&&!t[0].length)return void F(a);var i=r||a.chartType;if(i)return a.chart&&c(t,n)?B(t,a):void o(i,a,e)}function u(n,c){if(!A(n)&&!t.equals(n,c)){var i=r||a.chartType;i&&o(i,a,e)}}function h(r,n){A(r)||t.equals(r,n)||o(r,a,e)}n&&window.G_vmlCanvasManager.initElement(e[0]),a.$watch("chartData",i,!0),a.$watch("chartSeries",u,!0),a.$watch("chartLabels",u,!0),a.$watch("chartOptions",u,!0),a.$watch("chartColors",u,!0),a.$watch("chartDatasetOverride",u,!0),a.$watch("chartType",h,!1),a.$on("$destroy",function(){F(a)}),a.$on("$resize",function(){a.chart&&a.chart.resize()})}}}}r.defaults.global.multiTooltipTemplate="<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>",r.defaults.global.tooltips.mode="label",r.defaults.global.elements.line.borderWidth=2,r.defaults.global.elements.rectangle.borderWidth=2,r.defaults.global.legend.display=!1,r.defaults.global.colors=["#97BBCD","#DCDCDC","#F7464A","#46BFBD","#FDB45C","#949FB1","#4D5360"];var n="object"==typeof window.G_vmlCanvasManager&&null!==window.G_vmlCanvasManager&&"function"==typeof window.G_vmlCanvasManager.initElement;return n&&(r.defaults.global.animation=!1),t.module("chart.js",[]).provider("ChartJs",a).factory("ChartJsFactory",["ChartJs","$timeout",e]).directive("chartBase",["ChartJsFactory",function(t){return new t}]).directive("chartLine",["ChartJsFactory",function(t){return new t("line")}]).directive("chartBar",["ChartJsFactory",function(t){return new t("bar")}]).directive("chartHorizontalBar",["ChartJsFactory",function(t){return new t("horizontalBar")}]).directive("chartRadar",["ChartJsFactory",function(t){return new t("radar")}]).directive("chartDoughnut",["ChartJsFactory",function(t){return new t("doughnut")}]).directive("chartPie",["ChartJsFactory",function(t){return new t("pie")}]).directive("chartPolarArea",["ChartJsFactory",function(t){return new t("polarArea")}]).directive("chartBubble",["ChartJsFactory",function(t){return new t("bubble")}]).name});
-//# sourceMappingURL=angular-chart.min.js.map
diff --git a/web/gui/src/main/webapp/tp/angular-chart.min.js.map b/web/gui/src/main/webapp/tp/angular-chart.min.js.map
deleted file mode 100755
index cfe9a96..0000000
--- a/web/gui/src/main/webapp/tp/angular-chart.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["angular-chart.js"],"names":["factory","exports","module","angular","require","Chart","define","amd","Error","ChartJsProvider","options","responsive","ChartJs","getOptions","type","typeOptions","extend","this","setOptions","customOptions","$get","ChartJsFactory","$timeout","createChart","scope","elem","getChartOptions","hasData","canDisplay","cvs","ctx","getContext","chartGetColor","getChartColorFn","data","getChartData","destroyChart","chart","$emit","bindEvents","canUpdateChart","newVal","oldVal","length","Array","isArray","every","element","index","reduce","sum","carry","val","getEventHandler","action","triggerOnlyOnChange","lastState","evt","atEvent","getElementsAtEvent","getPointsAtEvent","activePoints","call","equals","getColors","colors","copy","chartColors","defaults","global","notEnoughColors","chartData","push","map","convertColor","color","getColor","hexToRgb","substr","getRandomColor","getRandomInt","backgroundColor","rgba","pointBackgroundColor","pointHoverBackgroundColor","borderColor","pointBorderColor","pointHoverBorderColor","min","max","Math","floor","random","alpha","useExcanvas","join","concat","hex","bigint","parseInt","r","g","b","getDataSets","chartLabels","chartSeries","chartDatasetOverride","getData","labels","series","datasetOverride","datasets","item","i","dataset","label","merge","hoverBackgroundColor","chartOptions","onclick","chartClick","noop","onmousemove","chartHover","updateChart","values","forEach","update","isEmpty","value","Object","keys","clientHeight","destroy","restrict","chartType","link","watchData","watchOther","watchType","window","G_vmlCanvasManager","initElement","$watch","$on","resize","multiTooltipTemplate","tooltips","mode","elements","line","borderWidth","rectangle","legend","display","animation","provider","directive","name"],"mappings":";;;;;;;;;CAAA,SAAAA,GACA,YACA,IAAA,gBAAAC,SAEAC,OAAAD,QAAAD,EACA,mBAAAG,SAAAA,QAAAC,QAAA,WACA,mBAAAC,OAAAA,MAAAD,QAAA,iBACA,IAAA,kBAAAE,SAAAA,OAAAC,IAEAD,QAAA,UAAA,SAAAN,OACA,CAEA,GAAA,mBAAAG,UAAA,mBAAAE,OACA,KAAA,IAAAG,OAAA,oFACAR,GAAAG,QAAAE,SAEA,SAAAF,EAAAE,GACA,YA8CA,SAAAI,KACA,GAAAC,IAAAC,YAAA,GACAC,GACAP,MAAAA,EACAQ,WAAA,SAAAC,GACA,GAAAC,GAAAD,GAAAJ,EAAAI,MACA,OAAAX,GAAAa,UAAAN,EAAAK,IAOAE,MAAAC,WAAA,SAAAJ,EAAAK,GAEA,MAAAA,QAMAT,EAAAI,GAAAX,EAAAa,OAAAN,EAAAI,OAAAK,KALAA,EAAAL,OACAJ,EAAAP,EAAAa,OAAAN,EAAAS,MAOAF,KAAAG,KAAA,WACA,MAAAR,IAIA,QAAAS,GAAAT,EAAAU,GAsEA,QAAAC,GAAAT,EAAAU,EAAAC,GACA,GAAAf,GAAAgB,EAAAZ,EAAAU,EACA,IAAAG,EAAAH,IAAAI,EAAAd,EAAAU,EAAAC,EAAAf,GAAA,CAEA,GAAAmB,GAAAJ,EAAA,GACAK,EAAAD,EAAAE,WAAA,KAEAP,GAAAQ,cAAAC,EAAAT,EACA,IAAAU,GAAAC,EAAArB,EAAAU,EAIAY,GAAAZ,GAEAA,EAAAa,MAAA,GAAAzB,GAAAP,MAAAyB,GACAhB,KAAAA,EACAoB,KAAAA,EACAxB,QAAAA,IAEAc,EAAAc,MAAA,eAAAd,EAAAa,OACAE,EAAAV,EAAAL,IAGA,QAAAgB,GAAAC,EAAAC,GACA,MAAAD,IAAAC,GAAAD,EAAAE,QAAAD,EAAAC,OACAC,MAAAC,QAAAJ,EAAA,IACAA,EAAAE,SAAAD,EAAAC,QAAAF,EAAAK,MAAA,SAAAC,EAAAC,GACA,MAAAD,GAAAJ,SAAAD,EAAAM,GAAAL,SACAD,EAAAO,OAAAC,EAAA,GAAA,EAAAT,EAAAE,SAAAD,EAAAC,QAAA,GAEA,EAGA,QAAAO,GAAAC,EAAAC,GACA,MAAAD,GAAAC,EAGA,QAAAC,GAAA7B,EAAA8B,EAAAC,GACA,GAAAC,GAAA,IACA,OAAA,UAAAC,GACA,GAAAC,GAAAlC,EAAAa,MAAAsB,oBAAAnC,EAAAa,MAAAuB,gBACA,IAAAF,EAAA,CACA,GAAAG,GAAAH,EAAAI,KAAAtC,EAAAa,MAAAoB,EACAF,MAAA,GAAApD,EAAA4D,OAAAP,EAAAK,MAAA,IACAL,EAAAK,EACArC,EAAA8B,GAAAO,EAAAJ,MAMA,QAAAO,GAAAlD,EAAAU,GAMA,IALA,GAAAyC,GAAA9D,EAAA+D,KAAA1C,EAAA2C,aACAvD,EAAAC,WAAAC,GAAAqD,aACA9D,EAAA+D,SAAAC,OAAAJ,QAEAK,EAAAL,EAAAtB,OAAAnB,EAAA+C,UAAA5B,OACAsB,EAAAtB,OAAAnB,EAAA+C,UAAA5B,QACAsB,EAAAO,KAAAhD,EAAAQ,gBAKA,OADAsC,KAAA9C,EAAA2C,YAAAF,GACAA,EAAAQ,IAAAC,GAGA,QAAAA,GAAAC,GACA,MAAA,gBAAAA,IAAA,OAAAA,EAAAA,EACA,gBAAAA,IAAA,MAAAA,EAAA,GAAAC,EAAAC,EAAAF,EAAAG,OAAA,KACAC,IAGA,QAAAA,KACA,GAAAJ,IAAAK,EAAA,EAAA,KAAAA,EAAA,EAAA,KAAAA,EAAA,EAAA,KACA,OAAAJ,GAAAD,GAGA,QAAAC,GAAAD,GACA,OACAM,gBAAAC,EAAAP,EAAA,IACAQ,qBAAAD,EAAAP,EAAA,GACAS,0BAAAF,EAAAP,EAAA,IACAU,YAAAH,EAAAP,EAAA,GACAW,iBAAA,OACAC,sBAAAL,EAAAP,EAAA,IAIA,QAAAK,GAAAQ,EAAAC,GACA,MAAAC,MAAAC,MAAAD,KAAAE,UAAAH,EAAAD,EAAA,IAAAA,EAGA,QAAAN,GAAAP,EAAAkB,GAEA,MAAAC,GAAA,OAAAnB,EAAAoB,KAAA,KAAA,IAAA,QAAApB,EAAAqB,OAAAH,GAAAE,KAAA,KAAA,IAIA,QAAAlB,GAAAoB,GACA,GAAAC,GAAAC,SAAAF,EAAA,IACAG,EAAAF,GAAA,GAAA,IACAG,EAAAH,GAAA,EAAA,IACAI,EAAA,IAAAJ,CAEA,QAAAE,EAAAC,EAAAC,GAGA,QAAA3E,GAAAH,GACA,MAAAA,GAAA+C,WAAA/C,EAAA+C,UAAA5B,OAGA,QAAAV,GAAAT,GACA,MAAA,kBAAAA,GAAAQ,cAAAR,EAAAQ,cAAA+C,EAGA,QAAA5C,GAAArB,EAAAU,GACA,GAAAyC,GAAAD,EAAAlD,EAAAU,EACA,OAAAoB,OAAAC,QAAArB,EAAA+C,UAAA,IACAgC,EAAA/E,EAAAgF,YAAAhF,EAAA+C,UAAA/C,EAAAiF,gBAAAxC,EAAAzC,EAAAkF,sBACAC,EAAAnF,EAAAgF,YAAAhF,EAAA+C,UAAAN,EAAAzC,EAAAkF,sBAGA,QAAAH,GAAAK,EAAA1E,EAAA2E,EAAA5C,EAAA6C,GACA,OACAF,OAAAA,EACAG,SAAA7E,EAAAuC,IAAA,SAAAuC,EAAAC,GACA,GAAAC,GAAA/G,EAAAa,UAAAiD,EAAAgD,IACAE,MAAAN,EAAAI,GACA/E,KAAA8E,GAKA,OAHAF,IAAAA,EAAAnE,QAAAsE,GACA9G,EAAAiH,MAAAF,EAAAJ,EAAAG,IAEAC,KAKA,QAAAP,GAAAC,EAAA1E,EAAA+B,EAAA6C,GACA,GAAAI,IACAN,OAAAA,EACAG,WACA7E,KAAAA,EACA+C,gBAAAhB,EAAAQ,IAAA,SAAAE,GACA,MAAAA,GAAAQ,uBAEAkC,qBAAApD,EAAAQ,IAAA,SAAAE,GACA,MAAAA,GAAAM,oBAOA,OAHA6B,IACA3G,EAAAiH,MAAAF,EAAAH,SAAA,GAAAD,GAEAI,EAGA,QAAAxF,GAAAZ,EAAAU,GACA,MAAArB,GAAAa,UAAAJ,EAAAC,WAAAC,GAAAU,EAAA8F,cAGA,QAAA/E,GAAAV,EAAAL,GACAK,EAAA0F,QAAA/F,EAAAgG,WAAAnE,EAAA7B,EAAA,cAAA,GAAArB,EAAAsH,KACA5F,EAAA6F,YAAAlG,EAAAmG,WAAAtE,EAAA7B,EAAA,cAAA,GAAArB,EAAAsH,KAGA,QAAAG,GAAAC,EAAArG,GACAoB,MAAAC,QAAArB,EAAA+C,UAAA,IACA/C,EAAAa,MAAAH,KAAA6E,SAAAe,QAAA,SAAAZ,EAAAD,GACAC,EAAAhF,KAAA2F,EAAAZ,KAGAzF,EAAAa,MAAAH,KAAA6E,SAAA,GAAA7E,KAAA2F,EAGArG,EAAAa,MAAA0F,SACAvG,EAAAc,MAAA,eAAAd,EAAAa,OAGA,QAAA2F,GAAAC,GACA,OAAAA,GACArF,MAAAC,QAAAoF,KAAAA,EAAAtF,QACA,gBAAAsF,KAAAC,OAAAC,KAAAF,GAAAtF,OAGA,QAAAf,GAAAd,EAAAU,EAAAC,EAAAf,GAEA,MAAAA,GAAAC,YAAA,IAAAc,EAAA,GAAA2G,cACA9G,EAAA,WACAC,EAAAT,EAAAU,EAAAC,IACA,IAAA,IACA,IAEA,EAGA,QAAAW,GAAAZ,GACAA,EAAAa,QACAb,EAAAa,MAAAgG,UACA7G,EAAAc,MAAA,gBAAAd,EAAAa,QA5QA,MAAA,UAAAvB,GACA,OACAwH,SAAA,KACA9G,OACAQ,cAAA,KACAuG,UAAA,IACAhE,UAAA,KACAiC,YAAA,KACAc,aAAA,KACAb,YAAA,KACAtC,YAAA,KACAqD,WAAA,KACAG,WAAA,KACAjB,qBAAA,MAEA8B,KAAA,SAAAhH,EAAAC,GAoBA,QAAAgH,GAAAhG,EAAAC,GACA,IAAAD,IAAAA,EAAAE,QAAAC,MAAAC,QAAAJ,EAAA,MAAAA,EAAA,GAAAE,OAEA,WADAP,GAAAZ,EAGA,IAAA+G,GAAAzH,GAAAU,EAAA+G,SACA,IAAAA,EAEA,MAAA/G,GAAAa,OAAAG,EAAAC,EAAAC,GACAkF,EAAAnF,EAAAjB,OAEAD,GAAAgH,EAAA/G,EAAAC,GAGA,QAAAiH,GAAAjG,EAAAC,GACA,IAAAsF,EAAAvF,KACAtC,EAAA4D,OAAAtB,EAAAC,GAAA,CACA,GAAA6F,GAAAzH,GAAAU,EAAA+G,SACAA,IAIAhH,EAAAgH,EAAA/G,EAAAC,IAGA,QAAAkH,GAAAlG,EAAAC,GACAsF,EAAAvF,IACAtC,EAAA4D,OAAAtB,EAAAC,IACAnB,EAAAkB,EAAAjB,EAAAC,GA/CAqE,GAAA8C,OAAAC,mBAAAC,YAAArH,EAAA,IAGAD,EAAAuH,OAAA,YAAAN,GAAA,GACAjH,EAAAuH,OAAA,cAAAL,GAAA,GACAlH,EAAAuH,OAAA,cAAAL,GAAA,GACAlH,EAAAuH,OAAA,eAAAL,GAAA,GACAlH,EAAAuH,OAAA,cAAAL,GAAA,GACAlH,EAAAuH,OAAA,uBAAAL,GAAA,GACAlH,EAAAuH,OAAA,YAAAJ,GAAA,GAEAnH,EAAAwH,IAAA,WAAA,WACA5G,EAAAZ,KAGAA,EAAAwH,IAAA,UAAA,WACAxH,EAAAa,OAAAb,EAAAa,MAAA4G,cA1GA5I,EAAA+D,SAAAC,OAAA6E,qBAAA,6DACA7I,EAAA+D,SAAAC,OAAA8E,SAAAC,KAAA,QACA/I,EAAA+D,SAAAC,OAAAgF,SAAAC,KAAAC,YAAA,EACAlJ,EAAA+D,SAAAC,OAAAgF,SAAAG,UAAAD,YAAA,EACAlJ,EAAA+D,SAAAC,OAAAoF,OAAAC,SAAA,EACArJ,EAAA+D,SAAAC,OAAAJ,QACA,UACA,UACA,UACA,UACA,UACA,UACA,UAGA,IAAA6B,GAAA,gBAAA8C,QAAAC,oBACA,OAAAD,OAAAC,oBACA,kBAAAD,QAAAC,mBAAAC,WAIA,OAFAhD,KAAAzF,EAAA+D,SAAAC,OAAAsF,WAAA,GAEAxJ,EAAAD,OAAA,eACA0J,SAAA,UAAAnJ,GACAT,QAAA,kBAAA,UAAA,WAAAqB,IACAwI,UAAA,aAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,MACAwI,UAAA,aAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,WACAwI,UAAA,YAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,UACAwI,UAAA,sBAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,oBACAwI,UAAA,cAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,YACAwI,UAAA,iBAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,eACAwI,UAAA,YAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,UACAwI,UAAA,kBAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,gBACAwI,UAAA,eAAA,iBAAA,SAAAxI,GAAA,MAAA,IAAAA,GAAA,aACAyI","file":"angular-chart.min.js","sourcesContent":["(function (factory) {\n  'use strict';\n  if (typeof exports === 'object') {\n    // Node/CommonJS\n    module.exports = factory(\n      typeof angular !== 'undefined' ? angular : require('angular'),\n      typeof Chart !== 'undefined' ? Chart : require('chart.js'));\n  }  else if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['angular', 'chart'], factory);\n  } else {\n    // Browser globals\n    if (typeof angular === 'undefined' || typeof Chart === 'undefined')\n      throw new Error('Chart.js library needs to included, see http://jtblin.github.io/angular-chart.js/');\n    factory(angular, Chart);\n  }\n}(function (angular, Chart) {\n  'use strict';\n\n  Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>';\n  Chart.defaults.global.tooltips.mode = 'label';\n  Chart.defaults.global.elements.line.borderWidth = 2;\n  Chart.defaults.global.elements.rectangle.borderWidth = 2;\n  Chart.defaults.global.legend.display = false;\n  Chart.defaults.global.colors = [\n    '#97BBCD', // blue\n    '#DCDCDC', // light grey\n    '#F7464A', // red\n    '#46BFBD', // green\n    '#FDB45C', // yellow\n    '#949FB1', // grey\n    '#4D5360'  // dark grey\n  ];\n\n  var useExcanvas = typeof window.G_vmlCanvasManager === 'object' &&\n    window.G_vmlCanvasManager !== null &&\n    typeof window.G_vmlCanvasManager.initElement === 'function';\n\n  if (useExcanvas) Chart.defaults.global.animation = false;\n\n  return angular.module('chart.js', [])\n    .provider('ChartJs', ChartJsProvider)\n    .factory('ChartJsFactory', ['ChartJs', '$timeout', ChartJsFactory])\n    .directive('chartBase', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory(); }])\n    .directive('chartLine', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('line'); }])\n    .directive('chartBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bar'); }])\n    .directive('chartHorizontalBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('horizontalBar'); }])\n    .directive('chartRadar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('radar'); }])\n    .directive('chartDoughnut', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('doughnut'); }])\n    .directive('chartPie', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('pie'); }])\n    .directive('chartPolarArea', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('polarArea'); }])\n    .directive('chartBubble', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bubble'); }])\n    .name;\n\n  /**\n   * Wrapper for chart.js\n   * Allows configuring chart js using the provider\n   *\n   * angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) {\n   *   ChartJsProvider.setOptions({ responsive: false });\n   *   ChartJsProvider.setOptions('Line', { responsive: true });\n   * })))\n   */\n  function ChartJsProvider () {\n    var options = { responsive: true };\n    var ChartJs = {\n      Chart: Chart,\n      getOptions: function (type) {\n        var typeOptions = type && options[type] || {};\n        return angular.extend({}, options, typeOptions);\n      }\n    };\n\n    /**\n     * Allow to set global options during configuration\n     */\n    this.setOptions = function (type, customOptions) {\n      // If no type was specified set option for the global object\n      if (! customOptions) {\n        customOptions = type;\n        options = angular.extend(options, customOptions);\n        return;\n      }\n      // Set options for the specific chart\n      options[type] = angular.extend(options[type] || {}, customOptions);\n    };\n\n    this.$get = function () {\n      return ChartJs;\n    };\n  }\n\n  function ChartJsFactory (ChartJs, $timeout) {\n    return function chart (type) {\n      return {\n        restrict: 'CA',\n        scope: {\n          chartGetColor: '=?',\n          chartType: '=',\n          chartData: '=?',\n          chartLabels: '=?',\n          chartOptions: '=?',\n          chartSeries: '=?',\n          chartColors: '=?',\n          chartClick: '=?',\n          chartHover: '=?',\n          chartDatasetOverride: '=?'\n        },\n        link: function (scope, elem/*, attrs */) {\n          if (useExcanvas) window.G_vmlCanvasManager.initElement(elem[0]);\n\n          // Order of setting \"watch\" matter\n          scope.$watch('chartData', watchData, true);\n          scope.$watch('chartSeries', watchOther, true);\n          scope.$watch('chartLabels', watchOther, true);\n          scope.$watch('chartOptions', watchOther, true);\n          scope.$watch('chartColors', watchOther, true);\n          scope.$watch('chartDatasetOverride', watchOther, true);\n          scope.$watch('chartType', watchType, false);\n\n          scope.$on('$destroy', function () {\n            destroyChart(scope);\n          });\n\n          scope.$on('$resize', function () {\n            if (scope.chart) scope.chart.resize();\n          });\n\n          function watchData (newVal, oldVal) {\n            if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) {\n              destroyChart(scope);\n              return;\n            }\n            var chartType = type || scope.chartType;\n            if (! chartType) return;\n\n            if (scope.chart && canUpdateChart(newVal, oldVal))\n              return updateChart(newVal, scope);\n\n            createChart(chartType, scope, elem);\n          }\n\n          function watchOther (newVal, oldVal) {\n            if (isEmpty(newVal)) return;\n            if (angular.equals(newVal, oldVal)) return;\n            var chartType = type || scope.chartType;\n            if (! chartType) return;\n\n            // chart.update() doesn't work for series and labels\n            // so we have to re-create the chart entirely\n            createChart(chartType, scope, elem);\n          }\n\n          function watchType (newVal, oldVal) {\n            if (isEmpty(newVal)) return;\n            if (angular.equals(newVal, oldVal)) return;\n            createChart(newVal, scope, elem);\n          }\n        }\n      };\n    };\n\n    function createChart (type, scope, elem) {\n      var options = getChartOptions(type, scope);\n      if (! hasData(scope) || ! canDisplay(type, scope, elem, options)) return;\n\n      var cvs = elem[0];\n      var ctx = cvs.getContext('2d');\n\n      scope.chartGetColor = getChartColorFn(scope);\n      var data = getChartData(type, scope);\n\n      // Destroy old chart if it exists to avoid ghost charts issue\n      // https://github.com/jtblin/angular-chart.js/issues/187\n      destroyChart(scope);\n\n      scope.chart = new ChartJs.Chart(ctx, {\n        type: type,\n        data: data,\n        options: options\n      });\n      scope.$emit('chart-create', scope.chart);\n      bindEvents(cvs, scope);\n    }\n\n    function canUpdateChart (newVal, oldVal) {\n      if (newVal && oldVal && newVal.length && oldVal.length) {\n        return Array.isArray(newVal[0]) ?\n        newVal.length === oldVal.length && newVal.every(function (element, index) {\n          return element.length === oldVal[index].length; }) :\n          oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false;\n      }\n      return false;\n    }\n\n    function sum (carry, val) {\n      return carry + val;\n    }\n\n    function getEventHandler (scope, action, triggerOnlyOnChange) {\n      var lastState = null;\n      return function (evt) {\n        var atEvent = scope.chart.getElementsAtEvent || scope.chart.getPointsAtEvent;\n        if (atEvent) {\n          var activePoints = atEvent.call(scope.chart, evt);\n          if (triggerOnlyOnChange === false || angular.equals(lastState, activePoints) === false) {\n            lastState = activePoints;\n            scope[action](activePoints, evt);\n          }\n        }\n      };\n    }\n\n    function getColors (type, scope) {\n      var colors = angular.copy(scope.chartColors ||\n        ChartJs.getOptions(type).chartColors ||\n        Chart.defaults.global.colors\n      );\n      var notEnoughColors = colors.length < scope.chartData.length;\n      while (colors.length < scope.chartData.length) {\n        colors.push(scope.chartGetColor());\n      }\n      // mutate colors in this case as we don't want\n      // the colors to change on each refresh\n      if (notEnoughColors) scope.chartColors = colors;\n      return colors.map(convertColor);\n    }\n\n    function convertColor (color) {\n      if (typeof color === 'object' && color !== null) return color;\n      if (typeof color === 'string' && color[0] === '#') return getColor(hexToRgb(color.substr(1)));\n      return getRandomColor();\n    }\n\n    function getRandomColor () {\n      var color = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)];\n      return getColor(color);\n    }\n\n    function getColor (color) {\n      return {\n        backgroundColor: rgba(color, 0.2),\n        pointBackgroundColor: rgba(color, 1),\n        pointHoverBackgroundColor: rgba(color, 0.8),\n        borderColor: rgba(color, 1),\n        pointBorderColor: '#fff',\n        pointHoverBorderColor: rgba(color, 1)\n      };\n    }\n\n    function getRandomInt (min, max) {\n      return Math.floor(Math.random() * (max - min + 1)) + min;\n    }\n\n    function rgba (color, alpha) {\n      // rgba not supported by IE8\n      return useExcanvas ? 'rgb(' + color.join(',') + ')' : 'rgba(' + color.concat(alpha).join(',') + ')';\n    }\n\n    // Credit: http://stackoverflow.com/a/11508164/1190235\n    function hexToRgb (hex) {\n      var bigint = parseInt(hex, 16),\n        r = (bigint >> 16) & 255,\n        g = (bigint >> 8) & 255,\n        b = bigint & 255;\n\n      return [r, g, b];\n    }\n\n    function hasData (scope) {\n      return scope.chartData && scope.chartData.length;\n    }\n\n    function getChartColorFn (scope) {\n      return typeof scope.chartGetColor === 'function' ? scope.chartGetColor : getRandomColor;\n    }\n\n    function getChartData (type, scope) {\n      var colors = getColors(type, scope);\n      return Array.isArray(scope.chartData[0]) ?\n        getDataSets(scope.chartLabels, scope.chartData, scope.chartSeries || [], colors, scope.chartDatasetOverride) :\n        getData(scope.chartLabels, scope.chartData, colors, scope.chartDatasetOverride);\n    }\n\n    function getDataSets (labels, data, series, colors, datasetOverride) {\n      return {\n        labels: labels,\n        datasets: data.map(function (item, i) {\n          var dataset = angular.extend({}, colors[i], {\n            label: series[i],\n            data: item\n          });\n          if (datasetOverride && datasetOverride.length >= i) {\n            angular.merge(dataset, datasetOverride[i]);\n          }\n          return dataset;\n        })\n      };\n    }\n\n    function getData (labels, data, colors, datasetOverride) {\n      var dataset = {\n        labels: labels,\n        datasets: [{\n          data: data,\n          backgroundColor: colors.map(function (color) {\n            return color.pointBackgroundColor;\n          }),\n          hoverBackgroundColor: colors.map(function (color) {\n            return color.backgroundColor;\n          })\n        }]\n      };\n      if (datasetOverride) {\n        angular.merge(dataset.datasets[0], datasetOverride);\n      }\n      return dataset;\n    }\n\n    function getChartOptions (type, scope) {\n      return angular.extend({}, ChartJs.getOptions(type), scope.chartOptions);\n    }\n\n    function bindEvents (cvs, scope) {\n      cvs.onclick = scope.chartClick ? getEventHandler(scope, 'chartClick', false) : angular.noop;\n      cvs.onmousemove = scope.chartHover ? getEventHandler(scope, 'chartHover', true) : angular.noop;\n    }\n\n    function updateChart (values, scope) {\n      if (Array.isArray(scope.chartData[0])) {\n        scope.chart.data.datasets.forEach(function (dataset, i) {\n          dataset.data = values[i];\n        });\n      } else {\n        scope.chart.data.datasets[0].data = values;\n      }\n\n      scope.chart.update();\n      scope.$emit('chart-update', scope.chart);\n    }\n\n    function isEmpty (value) {\n      return ! value ||\n        (Array.isArray(value) && ! value.length) ||\n        (typeof value === 'object' && ! Object.keys(value).length);\n    }\n\n    function canDisplay (type, scope, elem, options) {\n      // TODO: check parent?\n      if (options.responsive && elem[0].clientHeight === 0) {\n        $timeout(function () {\n          createChart(type, scope, elem);\n        }, 50, false);\n        return false;\n      }\n      return true;\n    }\n\n    function destroyChart(scope) {\n      if(! scope.chart) return;\n      scope.chart.destroy();\n      scope.$emit('chart-destroy', scope.chart);\n    }\n  }\n}));\n"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/tp/angular-cookies.js b/web/gui/src/main/webapp/tp/angular-cookies.js
deleted file mode 100644
index f400db2..0000000
--- a/web/gui/src/main/webapp/tp/angular-cookies.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * @license AngularJS v1.3.5
- * (c) 2010-2014 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular, undefined) {'use strict';
-
-/**
- * @ngdoc module
- * @name ngCookies
- * @description
- *
- * # ngCookies
- *
- * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
- *
- *
- * <div doc-module-components="ngCookies"></div>
- *
- * See {@link ngCookies.$cookies `$cookies`} and
- * {@link ngCookies.$cookieStore `$cookieStore`} for usage.
- */
-
-
-angular.module('ngCookies', ['ng']).
-  /**
-   * @ngdoc service
-   * @name $cookies
-   *
-   * @description
-   * Provides read/write access to browser's cookies.
-   *
-   * Only a simple Object is exposed and by adding or removing properties to/from this object, new
-   * cookies are created/deleted at the end of current $eval.
-   * The object's properties can only be strings.
-   *
-   * Requires the {@link ngCookies `ngCookies`} module to be installed.
-   *
-   * @example
-   *
-   * ```js
-   * angular.module('cookiesExample', ['ngCookies'])
-   *   .controller('ExampleController', ['$cookies', function($cookies) {
-   *     // Retrieving a cookie
-   *     var favoriteCookie = $cookies.myFavorite;
-   *     // Setting a cookie
-   *     $cookies.myFavorite = 'oatmeal';
-   *   }]);
-   * ```
-   */
-   factory('$cookies', ['$rootScope', '$browser', function($rootScope, $browser) {
-      var cookies = {},
-          lastCookies = {},
-          lastBrowserCookies,
-          runEval = false,
-          copy = angular.copy,
-          isUndefined = angular.isUndefined;
-
-      //creates a poller fn that copies all cookies from the $browser to service & inits the service
-      $browser.addPollFn(function() {
-        var currentCookies = $browser.cookies();
-        if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
-          lastBrowserCookies = currentCookies;
-          copy(currentCookies, lastCookies);
-          copy(currentCookies, cookies);
-          if (runEval) $rootScope.$apply();
-        }
-      })();
-
-      runEval = true;
-
-      //at the end of each eval, push cookies
-      //TODO: this should happen before the "delayed" watches fire, because if some cookies are not
-      //      strings or browser refuses to store some cookies, we update the model in the push fn.
-      $rootScope.$watch(push);
-
-      return cookies;
-
-
-      /**
-       * Pushes all the cookies from the service to the browser and verifies if all cookies were
-       * stored.
-       */
-      function push() {
-        var name,
-            value,
-            browserCookies,
-            updated;
-
-        //delete any cookies deleted in $cookies
-        for (name in lastCookies) {
-          if (isUndefined(cookies[name])) {
-            $browser.cookies(name, undefined);
-          }
-        }
-
-        //update all cookies updated in $cookies
-        for (name in cookies) {
-          value = cookies[name];
-          if (!angular.isString(value)) {
-            value = '' + value;
-            cookies[name] = value;
-          }
-          if (value !== lastCookies[name]) {
-            $browser.cookies(name, value);
-            updated = true;
-          }
-        }
-
-        //verify what was actually stored
-        if (updated) {
-          updated = false;
-          browserCookies = $browser.cookies();
-
-          for (name in cookies) {
-            if (cookies[name] !== browserCookies[name]) {
-              //delete or reset all cookies that the browser dropped from $cookies
-              if (isUndefined(browserCookies[name])) {
-                delete cookies[name];
-              } else {
-                cookies[name] = browserCookies[name];
-              }
-              updated = true;
-            }
-          }
-        }
-      }
-    }]).
-
-
-  /**
-   * @ngdoc service
-   * @name $cookieStore
-   * @requires $cookies
-   *
-   * @description
-   * Provides a key-value (string-object) storage, that is backed by session cookies.
-   * Objects put or retrieved from this storage are automatically serialized or
-   * deserialized by angular's toJson/fromJson.
-   *
-   * Requires the {@link ngCookies `ngCookies`} module to be installed.
-   *
-   * @example
-   *
-   * ```js
-   * angular.module('cookieStoreExample', ['ngCookies'])
-   *   .controller('ExampleController', ['$cookieStore', function($cookieStore) {
-   *     // Put cookie
-   *     $cookieStore.put('myFavorite','oatmeal');
-   *     // Get cookie
-   *     var favoriteCookie = $cookieStore.get('myFavorite');
-   *     // Removing a cookie
-   *     $cookieStore.remove('myFavorite');
-   *   }]);
-   * ```
-   */
-   factory('$cookieStore', ['$cookies', function($cookies) {
-
-      return {
-        /**
-         * @ngdoc method
-         * @name $cookieStore#get
-         *
-         * @description
-         * Returns the value of given cookie key
-         *
-         * @param {string} key Id to use for lookup.
-         * @returns {Object} Deserialized cookie value.
-         */
-        get: function(key) {
-          var value = $cookies[key];
-          return value ? angular.fromJson(value) : value;
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cookieStore#put
-         *
-         * @description
-         * Sets a value for given cookie key
-         *
-         * @param {string} key Id for the `value`.
-         * @param {Object} value Value to be stored.
-         */
-        put: function(key, value) {
-          $cookies[key] = angular.toJson(value);
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cookieStore#remove
-         *
-         * @description
-         * Remove given cookie
-         *
-         * @param {string} key Id of the key-value pair to delete.
-         */
-        remove: function(key) {
-          delete $cookies[key];
-        }
-      };
-
-    }]);
-
-
-})(window, window.angular);
diff --git a/web/gui/src/main/webapp/tp/angular-cookies.min.js b/web/gui/src/main/webapp/tp/angular-cookies.min.js
deleted file mode 100644
index 20333da..0000000
--- a/web/gui/src/main/webapp/tp/angular-cookies.min.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- AngularJS v1.3.5
- (c) 2010-2014 Google, Inc. http://angularjs.org
- License: MIT
-*/
-(function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(e,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&e.$apply())})();k=!0;e.$watch(function(){var a,d,e;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)d=c[a],f.isString(d)||(d=""+d,c[a]=d),d!==g[a]&&(b.cookies(a,d),e=!0);if(e)for(a in d=b.cookies(),c)c[a]!==d[a]&&(m(d[a])?delete c[a]:c[a]=d[a])});return c}]).factory("$cookieStore",
-["$cookies",function(e){return{get:function(b){return(b=e[b])?f.fromJson(b):b},put:function(b,c){e[b]=f.toJson(c)},remove:function(b){delete e[b]}}}])})(window,window.angular);
-//# sourceMappingURL=angular-cookies.min.js.map
diff --git a/web/gui/src/main/webapp/tp/angular-mocks.js b/web/gui/src/main/webapp/tp/angular-mocks.js
deleted file mode 100644
index 3d33b22..0000000
--- a/web/gui/src/main/webapp/tp/angular-mocks.js
+++ /dev/null
@@ -1,2380 +0,0 @@
-/**
- * @license AngularJS v1.3.5
- * (c) 2010-2014 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular, undefined) {
-
-'use strict';
-
-/**
- * @ngdoc object
- * @name angular.mock
- * @description
- *
- * Namespace from 'angular-mocks.js' which contains testing related code.
- */
-angular.mock = {};
-
-/**
- * ! This is a private undocumented service !
- *
- * @name $browser
- *
- * @description
- * This service is a mock implementation of {@link ng.$browser}. It provides fake
- * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr,
- * cookies, etc...
- *
- * The api of this service is the same as that of the real {@link ng.$browser $browser}, except
- * that there are several helper methods available which can be used in tests.
- */
-angular.mock.$BrowserProvider = function() {
-  this.$get = function() {
-    return new angular.mock.$Browser();
-  };
-};
-
-angular.mock.$Browser = function() {
-  var self = this;
-
-  this.isMock = true;
-  self.$$url = "http://server/";
-  self.$$lastUrl = self.$$url; // used by url polling fn
-  self.pollFns = [];
-
-  // TODO(vojta): remove this temporary api
-  self.$$completeOutstandingRequest = angular.noop;
-  self.$$incOutstandingRequestCount = angular.noop;
-
-
-  // register url polling fn
-
-  self.onUrlChange = function(listener) {
-    self.pollFns.push(
-      function() {
-        if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) {
-          self.$$lastUrl = self.$$url;
-          self.$$lastState = self.$$state;
-          listener(self.$$url, self.$$state);
-        }
-      }
-    );
-
-    return listener;
-  };
-
-  self.$$checkUrlChange = angular.noop;
-
-  self.cookieHash = {};
-  self.lastCookieHash = {};
-  self.deferredFns = [];
-  self.deferredNextId = 0;
-
-  self.defer = function(fn, delay) {
-    delay = delay || 0;
-    self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId});
-    self.deferredFns.sort(function(a, b) { return a.time - b.time;});
-    return self.deferredNextId++;
-  };
-
-
-  /**
-   * @name $browser#defer.now
-   *
-   * @description
-   * Current milliseconds mock time.
-   */
-  self.defer.now = 0;
-
-
-  self.defer.cancel = function(deferId) {
-    var fnIndex;
-
-    angular.forEach(self.deferredFns, function(fn, index) {
-      if (fn.id === deferId) fnIndex = index;
-    });
-
-    if (fnIndex !== undefined) {
-      self.deferredFns.splice(fnIndex, 1);
-      return true;
-    }
-
-    return false;
-  };
-
-
-  /**
-   * @name $browser#defer.flush
-   *
-   * @description
-   * Flushes all pending requests and executes the defer callbacks.
-   *
-   * @param {number=} number of milliseconds to flush. See {@link #defer.now}
-   */
-  self.defer.flush = function(delay) {
-    if (angular.isDefined(delay)) {
-      self.defer.now += delay;
-    } else {
-      if (self.deferredFns.length) {
-        self.defer.now = self.deferredFns[self.deferredFns.length - 1].time;
-      } else {
-        throw new Error('No deferred tasks to be flushed');
-      }
-    }
-
-    while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
-      self.deferredFns.shift().fn();
-    }
-  };
-
-  self.$$baseHref = '/';
-  self.baseHref = function() {
-    return this.$$baseHref;
-  };
-};
-angular.mock.$Browser.prototype = {
-
-/**
-  * @name $browser#poll
-  *
-  * @description
-  * run all fns in pollFns
-  */
-  poll: function poll() {
-    angular.forEach(this.pollFns, function(pollFn) {
-      pollFn();
-    });
-  },
-
-  addPollFn: function(pollFn) {
-    this.pollFns.push(pollFn);
-    return pollFn;
-  },
-
-  url: function(url, replace, state) {
-    if (angular.isUndefined(state)) {
-      state = null;
-    }
-    if (url) {
-      this.$$url = url;
-      // Native pushState serializes & copies the object; simulate it.
-      this.$$state = angular.copy(state);
-      return this;
-    }
-
-    return this.$$url;
-  },
-
-  state: function() {
-    return this.$$state;
-  },
-
-  cookies:  function(name, value) {
-    if (name) {
-      if (angular.isUndefined(value)) {
-        delete this.cookieHash[name];
-      } else {
-        if (angular.isString(value) &&       //strings only
-            value.length <= 4096) {          //strict cookie storage limits
-          this.cookieHash[name] = value;
-        }
-      }
-    } else {
-      if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
-        this.lastCookieHash = angular.copy(this.cookieHash);
-        this.cookieHash = angular.copy(this.cookieHash);
-      }
-      return this.cookieHash;
-    }
-  },
-
-  notifyWhenNoOutstandingRequests: function(fn) {
-    fn();
-  }
-};
-
-
-/**
- * @ngdoc provider
- * @name $exceptionHandlerProvider
- *
- * @description
- * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
- * passed to the `$exceptionHandler`.
- */
-
-/**
- * @ngdoc service
- * @name $exceptionHandler
- *
- * @description
- * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed
- * to it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration
- * information.
- *
- *
- * ```js
- *   describe('$exceptionHandlerProvider', function() {
- *
- *     it('should capture log messages and exceptions', function() {
- *
- *       module(function($exceptionHandlerProvider) {
- *         $exceptionHandlerProvider.mode('log');
- *       });
- *
- *       inject(function($log, $exceptionHandler, $timeout) {
- *         $timeout(function() { $log.log(1); });
- *         $timeout(function() { $log.log(2); throw 'banana peel'; });
- *         $timeout(function() { $log.log(3); });
- *         expect($exceptionHandler.errors).toEqual([]);
- *         expect($log.assertEmpty());
- *         $timeout.flush();
- *         expect($exceptionHandler.errors).toEqual(['banana peel']);
- *         expect($log.log.logs).toEqual([[1], [2], [3]]);
- *       });
- *     });
- *   });
- * ```
- */
-
-angular.mock.$ExceptionHandlerProvider = function() {
-  var handler;
-
-  /**
-   * @ngdoc method
-   * @name $exceptionHandlerProvider#mode
-   *
-   * @description
-   * Sets the logging mode.
-   *
-   * @param {string} mode Mode of operation, defaults to `rethrow`.
-   *
-   *   - `rethrow`: If any errors are passed to the handler in tests, it typically means that there
-   *                is a bug in the application or test, so this mock will make these tests fail.
-   *   - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log`
-   *            mode stores an array of errors in `$exceptionHandler.errors`, to allow later
-   *            assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and
-   *            {@link ngMock.$log#reset reset()}
-   */
-  this.mode = function(mode) {
-    switch (mode) {
-      case 'rethrow':
-        handler = function(e) {
-          throw e;
-        };
-        break;
-      case 'log':
-        var errors = [];
-
-        handler = function(e) {
-          if (arguments.length == 1) {
-            errors.push(e);
-          } else {
-            errors.push([].slice.call(arguments, 0));
-          }
-        };
-
-        handler.errors = errors;
-        break;
-      default:
-        throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
-    }
-  };
-
-  this.$get = function() {
-    return handler;
-  };
-
-  this.mode('rethrow');
-};
-
-
-/**
- * @ngdoc service
- * @name $log
- *
- * @description
- * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays
- * (one array per logging level). These arrays are exposed as `logs` property of each of the
- * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`.
- *
- */
-angular.mock.$LogProvider = function() {
-  var debug = true;
-
-  function concat(array1, array2, index) {
-    return array1.concat(Array.prototype.slice.call(array2, index));
-  }
-
-  this.debugEnabled = function(flag) {
-    if (angular.isDefined(flag)) {
-      debug = flag;
-      return this;
-    } else {
-      return debug;
-    }
-  };
-
-  this.$get = function() {
-    var $log = {
-      log: function() { $log.log.logs.push(concat([], arguments, 0)); },
-      warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },
-      info: function() { $log.info.logs.push(concat([], arguments, 0)); },
-      error: function() { $log.error.logs.push(concat([], arguments, 0)); },
-      debug: function() {
-        if (debug) {
-          $log.debug.logs.push(concat([], arguments, 0));
-        }
-      }
-    };
-
-    /**
-     * @ngdoc method
-     * @name $log#reset
-     *
-     * @description
-     * Reset all of the logging arrays to empty.
-     */
-    $log.reset = function() {
-      /**
-       * @ngdoc property
-       * @name $log#log.logs
-       *
-       * @description
-       * Array of messages logged using {@link ng.$log#log `log()`}.
-       *
-       * @example
-       * ```js
-       * $log.log('Some Log');
-       * var first = $log.log.logs.unshift();
-       * ```
-       */
-      $log.log.logs = [];
-      /**
-       * @ngdoc property
-       * @name $log#info.logs
-       *
-       * @description
-       * Array of messages logged using {@link ng.$log#info `info()`}.
-       *
-       * @example
-       * ```js
-       * $log.info('Some Info');
-       * var first = $log.info.logs.unshift();
-       * ```
-       */
-      $log.info.logs = [];
-      /**
-       * @ngdoc property
-       * @name $log#warn.logs
-       *
-       * @description
-       * Array of messages logged using {@link ng.$log#warn `warn()`}.
-       *
-       * @example
-       * ```js
-       * $log.warn('Some Warning');
-       * var first = $log.warn.logs.unshift();
-       * ```
-       */
-      $log.warn.logs = [];
-      /**
-       * @ngdoc property
-       * @name $log#error.logs
-       *
-       * @description
-       * Array of messages logged using {@link ng.$log#error `error()`}.
-       *
-       * @example
-       * ```js
-       * $log.error('Some Error');
-       * var first = $log.error.logs.unshift();
-       * ```
-       */
-      $log.error.logs = [];
-        /**
-       * @ngdoc property
-       * @name $log#debug.logs
-       *
-       * @description
-       * Array of messages logged using {@link ng.$log#debug `debug()`}.
-       *
-       * @example
-       * ```js
-       * $log.debug('Some Error');
-       * var first = $log.debug.logs.unshift();
-       * ```
-       */
-      $log.debug.logs = [];
-    };
-
-    /**
-     * @ngdoc method
-     * @name $log#assertEmpty
-     *
-     * @description
-     * Assert that all of the logging methods have no logged messages. If any messages are present,
-     * an exception is thrown.
-     */
-    $log.assertEmpty = function() {
-      var errors = [];
-      angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {
-        angular.forEach($log[logLevel].logs, function(log) {
-          angular.forEach(log, function(logItem) {
-            errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' +
-                        (logItem.stack || ''));
-          });
-        });
-      });
-      if (errors.length) {
-        errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or " +
-          "an expected log message was not checked and removed:");
-        errors.push('');
-        throw new Error(errors.join('\n---------\n'));
-      }
-    };
-
-    $log.reset();
-    return $log;
-  };
-};
-
-
-/**
- * @ngdoc service
- * @name $interval
- *
- * @description
- * Mock implementation of the $interval service.
- *
- * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
- * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
- * time.
- *
- * @param {function()} fn A function that should be called repeatedly.
- * @param {number} delay Number of milliseconds between each function call.
- * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
- *   indefinitely.
- * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
- *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
- * @returns {promise} A promise which will be notified on each iteration.
- */
-angular.mock.$IntervalProvider = function() {
-  this.$get = ['$browser', '$rootScope', '$q', '$$q',
-       function($browser,   $rootScope,   $q,   $$q) {
-    var repeatFns = [],
-        nextRepeatId = 0,
-        now = 0;
-
-    var $interval = function(fn, delay, count, invokeApply) {
-      var iteration = 0,
-          skipApply = (angular.isDefined(invokeApply) && !invokeApply),
-          deferred = (skipApply ? $$q : $q).defer(),
-          promise = deferred.promise;
-
-      count = (angular.isDefined(count)) ? count : 0;
-      promise.then(null, null, fn);
-
-      promise.$$intervalId = nextRepeatId;
-
-      function tick() {
-        deferred.notify(iteration++);
-
-        if (count > 0 && iteration >= count) {
-          var fnIndex;
-          deferred.resolve(iteration);
-
-          angular.forEach(repeatFns, function(fn, index) {
-            if (fn.id === promise.$$intervalId) fnIndex = index;
-          });
-
-          if (fnIndex !== undefined) {
-            repeatFns.splice(fnIndex, 1);
-          }
-        }
-
-        if (skipApply) {
-          $browser.defer.flush();
-        } else {
-          $rootScope.$apply();
-        }
-      }
-
-      repeatFns.push({
-        nextTime:(now + delay),
-        delay: delay,
-        fn: tick,
-        id: nextRepeatId,
-        deferred: deferred
-      });
-      repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});
-
-      nextRepeatId++;
-      return promise;
-    };
-    /**
-     * @ngdoc method
-     * @name $interval#cancel
-     *
-     * @description
-     * Cancels a task associated with the `promise`.
-     *
-     * @param {promise} promise A promise from calling the `$interval` function.
-     * @returns {boolean} Returns `true` if the task was successfully cancelled.
-     */
-    $interval.cancel = function(promise) {
-      if (!promise) return false;
-      var fnIndex;
-
-      angular.forEach(repeatFns, function(fn, index) {
-        if (fn.id === promise.$$intervalId) fnIndex = index;
-      });
-
-      if (fnIndex !== undefined) {
-        repeatFns[fnIndex].deferred.reject('canceled');
-        repeatFns.splice(fnIndex, 1);
-        return true;
-      }
-
-      return false;
-    };
-
-    /**
-     * @ngdoc method
-     * @name $interval#flush
-     * @description
-     *
-     * Runs interval tasks scheduled to be run in the next `millis` milliseconds.
-     *
-     * @param {number=} millis maximum timeout amount to flush up until.
-     *
-     * @return {number} The amount of time moved forward.
-     */
-    $interval.flush = function(millis) {
-      now += millis;
-      while (repeatFns.length && repeatFns[0].nextTime <= now) {
-        var task = repeatFns[0];
-        task.fn();
-        task.nextTime += task.delay;
-        repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});
-      }
-      return millis;
-    };
-
-    return $interval;
-  }];
-};
-
-
-/* jshint -W101 */
-/* The R_ISO8061_STR regex is never going to fit into the 100 char limit!
- * This directive should go inside the anonymous function but a bug in JSHint means that it would
- * not be enacted early enough to prevent the warning.
- */
-var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/;
-
-function jsonStringToDate(string) {
-  var match;
-  if (match = string.match(R_ISO8061_STR)) {
-    var date = new Date(0),
-        tzHour = 0,
-        tzMin  = 0;
-    if (match[9]) {
-      tzHour = int(match[9] + match[10]);
-      tzMin = int(match[9] + match[11]);
-    }
-    date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
-    date.setUTCHours(int(match[4] || 0) - tzHour,
-                     int(match[5] || 0) - tzMin,
-                     int(match[6] || 0),
-                     int(match[7] || 0));
-    return date;
-  }
-  return string;
-}
-
-function int(str) {
-  return parseInt(str, 10);
-}
-
-function padNumber(num, digits, trim) {
-  var neg = '';
-  if (num < 0) {
-    neg =  '-';
-    num = -num;
-  }
-  num = '' + num;
-  while (num.length < digits) num = '0' + num;
-  if (trim)
-    num = num.substr(num.length - digits);
-  return neg + num;
-}
-
-
-/**
- * @ngdoc type
- * @name angular.mock.TzDate
- * @description
- *
- * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
- *
- * Mock of the Date type which has its timezone specified via constructor arg.
- *
- * The main purpose is to create Date-like instances with timezone fixed to the specified timezone
- * offset, so that we can test code that depends on local timezone settings without dependency on
- * the time zone settings of the machine where the code is running.
- *
- * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
- * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
- *
- * @example
- * !!!! WARNING !!!!!
- * This is not a complete Date object so only methods that were implemented can be called safely.
- * To make matters worse, TzDate instances inherit stuff from Date via a prototype.
- *
- * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
- * incomplete we might be missing some non-standard methods. This can result in errors like:
- * "Date.prototype.foo called on incompatible Object".
- *
- * ```js
- * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
- * newYearInBratislava.getTimezoneOffset() => -60;
- * newYearInBratislava.getFullYear() => 2010;
- * newYearInBratislava.getMonth() => 0;
- * newYearInBratislava.getDate() => 1;
- * newYearInBratislava.getHours() => 0;
- * newYearInBratislava.getMinutes() => 0;
- * newYearInBratislava.getSeconds() => 0;
- * ```
- *
- */
-angular.mock.TzDate = function(offset, timestamp) {
-  var self = new Date(0);
-  if (angular.isString(timestamp)) {
-    var tsStr = timestamp;
-
-    self.origDate = jsonStringToDate(timestamp);
-
-    timestamp = self.origDate.getTime();
-    if (isNaN(timestamp))
-      throw {
-        name: "Illegal Argument",
-        message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
-      };
-  } else {
-    self.origDate = new Date(timestamp);
-  }
-
-  var localOffset = new Date(timestamp).getTimezoneOffset();
-  self.offsetDiff = localOffset * 60 * 1000 - offset * 1000 * 60 * 60;
-  self.date = new Date(timestamp + self.offsetDiff);
-
-  self.getTime = function() {
-    return self.date.getTime() - self.offsetDiff;
-  };
-
-  self.toLocaleDateString = function() {
-    return self.date.toLocaleDateString();
-  };
-
-  self.getFullYear = function() {
-    return self.date.getFullYear();
-  };
-
-  self.getMonth = function() {
-    return self.date.getMonth();
-  };
-
-  self.getDate = function() {
-    return self.date.getDate();
-  };
-
-  self.getHours = function() {
-    return self.date.getHours();
-  };
-
-  self.getMinutes = function() {
-    return self.date.getMinutes();
-  };
-
-  self.getSeconds = function() {
-    return self.date.getSeconds();
-  };
-
-  self.getMilliseconds = function() {
-    return self.date.getMilliseconds();
-  };
-
-  self.getTimezoneOffset = function() {
-    return offset * 60;
-  };
-
-  self.getUTCFullYear = function() {
-    return self.origDate.getUTCFullYear();
-  };
-
-  self.getUTCMonth = function() {
-    return self.origDate.getUTCMonth();
-  };
-
-  self.getUTCDate = function() {
-    return self.origDate.getUTCDate();
-  };
-
-  self.getUTCHours = function() {
-    return self.origDate.getUTCHours();
-  };
-
-  self.getUTCMinutes = function() {
-    return self.origDate.getUTCMinutes();
-  };
-
-  self.getUTCSeconds = function() {
-    return self.origDate.getUTCSeconds();
-  };
-
-  self.getUTCMilliseconds = function() {
-    return self.origDate.getUTCMilliseconds();
-  };
-
-  self.getDay = function() {
-    return self.date.getDay();
-  };
-
-  // provide this method only on browsers that already have it
-  if (self.toISOString) {
-    self.toISOString = function() {
-      return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +
-            padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +
-            padNumber(self.origDate.getUTCDate(), 2) + 'T' +
-            padNumber(self.origDate.getUTCHours(), 2) + ':' +
-            padNumber(self.origDate.getUTCMinutes(), 2) + ':' +
-            padNumber(self.origDate.getUTCSeconds(), 2) + '.' +
-            padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z';
-    };
-  }
-
-  //hide all methods not implemented in this mock that the Date prototype exposes
-  var unimplementedMethods = ['getUTCDay',
-      'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
-      'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
-      'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
-      'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
-      'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
-
-  angular.forEach(unimplementedMethods, function(methodName) {
-    self[methodName] = function() {
-      throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock");
-    };
-  });
-
-  return self;
-};
-
-//make "tzDateInstance instanceof Date" return true
-angular.mock.TzDate.prototype = Date.prototype;
-/* jshint +W101 */
-
-angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
-
-  .config(['$provide', function($provide) {
-
-    var reflowQueue = [];
-    $provide.value('$$animateReflow', function(fn) {
-      var index = reflowQueue.length;
-      reflowQueue.push(fn);
-      return function cancel() {
-        reflowQueue.splice(index, 1);
-      };
-    });
-
-    $provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser',
-                            function($delegate,   $$asyncCallback,   $timeout,   $browser) {
-      var animate = {
-        queue: [],
-        cancel: $delegate.cancel,
-        enabled: $delegate.enabled,
-        triggerCallbackEvents: function() {
-          $$asyncCallback.flush();
-        },
-        triggerCallbackPromise: function() {
-          $timeout.flush(0);
-        },
-        triggerCallbacks: function() {
-          this.triggerCallbackEvents();
-          this.triggerCallbackPromise();
-        },
-        triggerReflow: function() {
-          angular.forEach(reflowQueue, function(fn) {
-            fn();
-          });
-          reflowQueue = [];
-        }
-      };
-
-      angular.forEach(
-        ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) {
-        animate[method] = function() {
-          animate.queue.push({
-            event: method,
-            element: arguments[0],
-            options: arguments[arguments.length - 1],
-            args: arguments
-          });
-          return $delegate[method].apply($delegate, arguments);
-        };
-      });
-
-      return animate;
-    }]);
-
-  }]);
-
-
-/**
- * @ngdoc function
- * @name angular.mock.dump
- * @description
- *
- * *NOTE*: this is not an injectable instance, just a globally available function.
- *
- * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for
- * debugging.
- *
- * This method is also available on window, where it can be used to display objects on debug
- * console.
- *
- * @param {*} object - any object to turn into string.
- * @return {string} a serialized string of the argument
- */
-angular.mock.dump = function(object) {
-  return serialize(object);
-
-  function serialize(object) {
-    var out;
-
-    if (angular.isElement(object)) {
-      object = angular.element(object);
-      out = angular.element('<div></div>');
-      angular.forEach(object, function(element) {
-        out.append(angular.element(element).clone());
-      });
-      out = out.html();
-    } else if (angular.isArray(object)) {
-      out = [];
-      angular.forEach(object, function(o) {
-        out.push(serialize(o));
-      });
-      out = '[ ' + out.join(', ') + ' ]';
-    } else if (angular.isObject(object)) {
-      if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {
-        out = serializeScope(object);
-      } else if (object instanceof Error) {
-        out = object.stack || ('' + object.name + ': ' + object.message);
-      } else {
-        // TODO(i): this prevents methods being logged,
-        // we should have a better way to serialize objects
-        out = angular.toJson(object, true);
-      }
-    } else {
-      out = String(object);
-    }
-
-    return out;
-  }
-
-  function serializeScope(scope, offset) {
-    offset = offset ||  '  ';
-    var log = [offset + 'Scope(' + scope.$id + '): {'];
-    for (var key in scope) {
-      if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) {
-        log.push('  ' + key + ': ' + angular.toJson(scope[key]));
-      }
-    }
-    var child = scope.$$childHead;
-    while (child) {
-      log.push(serializeScope(child, offset + '  '));
-      child = child.$$nextSibling;
-    }
-    log.push('}');
-    return log.join('\n' + offset);
-  }
-};
-
-/**
- * @ngdoc service
- * @name $httpBackend
- * @description
- * Fake HTTP backend implementation suitable for unit testing applications that use the
- * {@link ng.$http $http service}.
- *
- * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less
- * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}.
- *
- * During unit testing, we want our unit tests to run quickly and have no external dependencies so
- * we don’t want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or
- * [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is
- * to verify whether a certain request has been sent or not, or alternatively just let the
- * application make requests, respond with pre-trained responses and assert that the end result is
- * what we expect it to be.
- *
- * This mock implementation can be used to respond with static or dynamic responses via the
- * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc).
- *
- * When an Angular application needs some data from a server, it calls the $http service, which
- * sends the request to a real server using $httpBackend service. With dependency injection, it is
- * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify
- * the requests and respond with some testing data without sending a request to a real server.
- *
- * There are two ways to specify what test data should be returned as http responses by the mock
- * backend when the code under test makes http requests:
- *
- * - `$httpBackend.expect` - specifies a request expectation
- * - `$httpBackend.when` - specifies a backend definition
- *
- *
- * # Request Expectations vs Backend Definitions
- *
- * Request expectations provide a way to make assertions about requests made by the application and
- * to define responses for those requests. The test will fail if the expected requests are not made
- * or they are made in the wrong order.
- *
- * Backend definitions allow you to define a fake backend for your application which doesn't assert
- * if a particular request was made or not, it just returns a trained response if a request is made.
- * The test will pass whether or not the request gets made during testing.
- *
- *
- * <table class="table">
- *   <tr><th width="220px"></th><th>Request expectations</th><th>Backend definitions</th></tr>
- *   <tr>
- *     <th>Syntax</th>
- *     <td>.expect(...).respond(...)</td>
- *     <td>.when(...).respond(...)</td>
- *   </tr>
- *   <tr>
- *     <th>Typical usage</th>
- *     <td>strict unit tests</td>
- *     <td>loose (black-box) unit testing</td>
- *   </tr>
- *   <tr>
- *     <th>Fulfills multiple requests</th>
- *     <td>NO</td>
- *     <td>YES</td>
- *   </tr>
- *   <tr>
- *     <th>Order of requests matters</th>
- *     <td>YES</td>
- *     <td>NO</td>
- *   </tr>
- *   <tr>
- *     <th>Request required</th>
- *     <td>YES</td>
- *     <td>NO</td>
- *   </tr>
- *   <tr>
- *     <th>Response required</th>
- *     <td>optional (see below)</td>
- *     <td>YES</td>
- *   </tr>
- * </table>
- *
- * In cases where both backend definitions and request expectations are specified during unit
- * testing, the request expectations are evaluated first.
- *
- * If a request expectation has no response specified, the algorithm will search your backend
- * definitions for an appropriate response.
- *
- * If a request didn't match any expectation or if the expectation doesn't have the response
- * defined, the backend definitions are evaluated in sequential order to see if any of them match
- * the request. The response from the first matched definition is returned.
- *
- *
- * # Flushing HTTP requests
- *
- * The $httpBackend used in production always responds to requests asynchronously. If we preserved
- * this behavior in unit testing, we'd have to create async unit tests, which are hard to write,
- * to follow and to maintain. But neither can the testing mock respond synchronously; that would
- * change the execution of the code under test. For this reason, the mock $httpBackend has a
- * `flush()` method, which allows the test to explicitly flush pending requests. This preserves
- * the async api of the backend, while allowing the test to execute synchronously.
- *
- *
- * # Unit testing with mock $httpBackend
- * The following code shows how to setup and use the mock backend when unit testing a controller.
- * First we create the controller under test:
- *
-  ```js
-  // The module code
-  angular
-    .module('MyApp', [])
-    .controller('MyController', MyController);
-
-  // The controller code
-  function MyController($scope, $http) {
-    var authToken;
-
-    $http.get('/auth.py').success(function(data, status, headers) {
-      authToken = headers('A-Token');
-      $scope.user = data;
-    });
-
-    $scope.saveMessage = function(message) {
-      var headers = { 'Authorization': authToken };
-      $scope.status = 'Saving...';
-
-      $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
-        $scope.status = '';
-      }).error(function() {
-        $scope.status = 'ERROR!';
-      });
-    };
-  }
-  ```
- *
- * Now we setup the mock backend and create the test specs:
- *
-  ```js
-    // testing controller
-    describe('MyController', function() {
-       var $httpBackend, $rootScope, createController, authRequestHandler;
-
-       // Set up the module
-       beforeEach(module('MyApp'));
-
-       beforeEach(inject(function($injector) {
-         // Set up the mock http service responses
-         $httpBackend = $injector.get('$httpBackend');
-         // backend definition common for all tests
-         authRequestHandler = $httpBackend.when('GET', '/auth.py')
-                                .respond({userId: 'userX'}, {'A-Token': 'xxx'});
-
-         // Get hold of a scope (i.e. the root scope)
-         $rootScope = $injector.get('$rootScope');
-         // The $controller service is used to create instances of controllers
-         var $controller = $injector.get('$controller');
-
-         createController = function() {
-           return $controller('MyController', {'$scope' : $rootScope });
-         };
-       }));
-
-
-       afterEach(function() {
-         $httpBackend.verifyNoOutstandingExpectation();
-         $httpBackend.verifyNoOutstandingRequest();
-       });
-
-
-       it('should fetch authentication token', function() {
-         $httpBackend.expectGET('/auth.py');
-         var controller = createController();
-         $httpBackend.flush();
-       });
-
-
-       it('should fail authentication', function() {
-
-         // Notice how you can change the response even after it was set
-         authRequestHandler.respond(401, '');
-
-         $httpBackend.expectGET('/auth.py');
-         var controller = createController();
-         $httpBackend.flush();
-         expect($rootScope.status).toBe('Failed...');
-       });
-
-
-       it('should send msg to server', function() {
-         var controller = createController();
-         $httpBackend.flush();
-
-         // now you don’t care about the authentication, but
-         // the controller will still send the request and
-         // $httpBackend will respond without you having to
-         // specify the expectation and response for this request
-
-         $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, '');
-         $rootScope.saveMessage('message content');
-         expect($rootScope.status).toBe('Saving...');
-         $httpBackend.flush();
-         expect($rootScope.status).toBe('');
-       });
-
-
-       it('should send auth header', function() {
-         var controller = createController();
-         $httpBackend.flush();
-
-         $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
-           // check if the header was send, if it wasn't the expectation won't
-           // match the request and the test will fail
-           return headers['Authorization'] == 'xxx';
-         }).respond(201, '');
-
-         $rootScope.saveMessage('whatever');
-         $httpBackend.flush();
-       });
-    });
-   ```
- */
-angular.mock.$HttpBackendProvider = function() {
-  this.$get = ['$rootScope', createHttpBackendMock];
-};
-
-/**
- * General factory function for $httpBackend mock.
- * Returns instance for unit testing (when no arguments specified):
- *   - passing through is disabled
- *   - auto flushing is disabled
- *
- * Returns instance for e2e testing (when `$delegate` and `$browser` specified):
- *   - passing through (delegating request to real backend) is enabled
- *   - auto flushing is enabled
- *
- * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified)
- * @param {Object=} $browser Auto-flushing enabled if specified
- * @return {Object} Instance of $httpBackend mock
- */
-function createHttpBackendMock($rootScope, $delegate, $browser) {
-  var definitions = [],
-      expectations = [],
-      responses = [],
-      responsesPush = angular.bind(responses, responses.push),
-      copy = angular.copy;
-
-  function createResponse(status, data, headers, statusText) {
-    if (angular.isFunction(status)) return status;
-
-    return function() {
-      return angular.isNumber(status)
-          ? [status, data, headers, statusText]
-          : [200, status, data, headers];
-    };
-  }
-
-  // TODO(vojta): change params to: method, url, data, headers, callback
-  function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
-    var xhr = new MockXhr(),
-        expectation = expectations[0],
-        wasExpected = false;
-
-    function prettyPrint(data) {
-      return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)
-          ? data
-          : angular.toJson(data);
-    }
-
-    function wrapResponse(wrapped) {
-      if (!$browser && timeout && timeout.then) timeout.then(handleTimeout);
-
-      return handleResponse;
-
-      function handleResponse() {
-        var response = wrapped.response(method, url, data, headers);
-        xhr.$$respHeaders = response[2];
-        callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(),
-                 copy(response[3] || ''));
-      }
-
-      function handleTimeout() {
-        for (var i = 0, ii = responses.length; i < ii; i++) {
-          if (responses[i] === handleResponse) {
-            responses.splice(i, 1);
-            callback(-1, undefined, '');
-            break;
-          }
-        }
-      }
-    }
-
-    if (expectation && expectation.match(method, url)) {
-      if (!expectation.matchData(data))
-        throw new Error('Expected ' + expectation + ' with different data\n' +
-            'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT:      ' + data);
-
-      if (!expectation.matchHeaders(headers))
-        throw new Error('Expected ' + expectation + ' with different headers\n' +
-                        'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT:      ' +
-                        prettyPrint(headers));
-
-      expectations.shift();
-
-      if (expectation.response) {
-        responses.push(wrapResponse(expectation));
-        return;
-      }
-      wasExpected = true;
-    }
-
-    var i = -1, definition;
-    while ((definition = definitions[++i])) {
-      if (definition.match(method, url, data, headers || {})) {
-        if (definition.response) {
-          // if $browser specified, we do auto flush all requests
-          ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
-        } else if (definition.passThrough) {
-          $delegate(method, url, data, callback, headers, timeout, withCredentials);
-        } else throw new Error('No response defined !');
-        return;
-      }
-    }
-    throw wasExpected ?
-        new Error('No response defined !') :
-        new Error('Unexpected request: ' + method + ' ' + url + '\n' +
-                  (expectation ? 'Expected ' + expectation : 'No more request expected'));
-  }
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#when
-   * @description
-   * Creates a new backend definition.
-   *
-   * @param {string} method HTTP method.
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
-   *   data string and returns true if the data is as expected.
-   * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
-   *   object and returns true if the headers match the current definition.
-   * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
-   *   request is handled. You can save this object for later use and invoke `respond` again in
-   *   order to change how a matched request is handled.
-   *
-   *  - respond –
-   *      `{function([status,] data[, headers, statusText])
-   *      | function(function(method, url, data, headers)}`
-   *    – The respond method takes a set of static data to be returned or a function that can
-   *    return an array containing response status (number), response data (string), response
-   *    headers (Object), and the text for the status (string). The respond method returns the
-   *    `requestHandler` object for possible overrides.
-   */
-  $httpBackend.when = function(method, url, data, headers) {
-    var definition = new MockHttpExpectation(method, url, data, headers),
-        chain = {
-          respond: function(status, data, headers, statusText) {
-            definition.passThrough = undefined;
-            definition.response = createResponse(status, data, headers, statusText);
-            return chain;
-          }
-        };
-
-    if ($browser) {
-      chain.passThrough = function() {
-        definition.response = undefined;
-        definition.passThrough = true;
-        return chain;
-      };
-    }
-
-    definitions.push(definition);
-    return chain;
-  };
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#whenGET
-   * @description
-   * Creates a new backend definition for GET requests. For more info see `when()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(Object|function(Object))=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   * request is handled. You can save this object for later use and invoke `respond` again in
-   * order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#whenHEAD
-   * @description
-   * Creates a new backend definition for HEAD requests. For more info see `when()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(Object|function(Object))=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   * request is handled. You can save this object for later use and invoke `respond` again in
-   * order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#whenDELETE
-   * @description
-   * Creates a new backend definition for DELETE requests. For more info see `when()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(Object|function(Object))=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   * request is handled. You can save this object for later use and invoke `respond` again in
-   * order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#whenPOST
-   * @description
-   * Creates a new backend definition for POST requests. For more info see `when()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
-   *   data string and returns true if the data is as expected.
-   * @param {(Object|function(Object))=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   * request is handled. You can save this object for later use and invoke `respond` again in
-   * order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#whenPUT
-   * @description
-   * Creates a new backend definition for PUT requests.  For more info see `when()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
-   *   data string and returns true if the data is as expected.
-   * @param {(Object|function(Object))=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   * request is handled. You can save this object for later use and invoke `respond` again in
-   * order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#whenJSONP
-   * @description
-   * Creates a new backend definition for JSONP requests. For more info see `when()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   * request is handled. You can save this object for later use and invoke `respond` again in
-   * order to change how a matched request is handled.
-   */
-  createShortMethods('when');
-
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expect
-   * @description
-   * Creates a new request expectation.
-   *
-   * @param {string} method HTTP method.
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
-   *  receives data string and returns true if the data is as expected, or Object if request body
-   *  is in JSON format.
-   * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
-   *   object and returns true if the headers match the current expectation.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   *  request is handled. You can save this object for later use and invoke `respond` again in
-   *  order to change how a matched request is handled.
-   *
-   *  - respond –
-   *    `{function([status,] data[, headers, statusText])
-   *    | function(function(method, url, data, headers)}`
-   *    – The respond method takes a set of static data to be returned or a function that can
-   *    return an array containing response status (number), response data (string), response
-   *    headers (Object), and the text for the status (string). The respond method returns the
-   *    `requestHandler` object for possible overrides.
-   */
-  $httpBackend.expect = function(method, url, data, headers) {
-    var expectation = new MockHttpExpectation(method, url, data, headers),
-        chain = {
-          respond: function(status, data, headers, statusText) {
-            expectation.response = createResponse(status, data, headers, statusText);
-            return chain;
-          }
-        };
-
-    expectations.push(expectation);
-    return chain;
-  };
-
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expectGET
-   * @description
-   * Creates a new request expectation for GET requests. For more info see `expect()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {Object=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   * request is handled. You can save this object for later use and invoke `respond` again in
-   * order to change how a matched request is handled. See #expect for more info.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expectHEAD
-   * @description
-   * Creates a new request expectation for HEAD requests. For more info see `expect()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {Object=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   *   request is handled. You can save this object for later use and invoke `respond` again in
-   *   order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expectDELETE
-   * @description
-   * Creates a new request expectation for DELETE requests. For more info see `expect()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {Object=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   *   request is handled. You can save this object for later use and invoke `respond` again in
-   *   order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expectPOST
-   * @description
-   * Creates a new request expectation for POST requests. For more info see `expect()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
-   *  receives data string and returns true if the data is as expected, or Object if request body
-   *  is in JSON format.
-   * @param {Object=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   *   request is handled. You can save this object for later use and invoke `respond` again in
-   *   order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expectPUT
-   * @description
-   * Creates a new request expectation for PUT requests. For more info see `expect()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
-   *  receives data string and returns true if the data is as expected, or Object if request body
-   *  is in JSON format.
-   * @param {Object=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   *   request is handled. You can save this object for later use and invoke `respond` again in
-   *   order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expectPATCH
-   * @description
-   * Creates a new request expectation for PATCH requests. For more info see `expect()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
-   *  receives data string and returns true if the data is as expected, or Object if request body
-   *  is in JSON format.
-   * @param {Object=} headers HTTP headers.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   *   request is handled. You can save this object for later use and invoke `respond` again in
-   *   order to change how a matched request is handled.
-   */
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#expectJSONP
-   * @description
-   * Creates a new request expectation for JSONP requests. For more info see `expect()`.
-   *
-   * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
-   *   and returns true if the url match the current definition.
-   * @returns {requestHandler} Returns an object with `respond` method that control how a matched
-   *   request is handled. You can save this object for later use and invoke `respond` again in
-   *   order to change how a matched request is handled.
-   */
-  createShortMethods('expect');
-
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#flush
-   * @description
-   * Flushes all pending requests using the trained responses.
-   *
-   * @param {number=} count Number of responses to flush (in the order they arrived). If undefined,
-   *   all pending requests will be flushed. If there are no pending requests when the flush method
-   *   is called an exception is thrown (as this typically a sign of programming error).
-   */
-  $httpBackend.flush = function(count, digest) {
-    if (digest !== false) $rootScope.$digest();
-    if (!responses.length) throw new Error('No pending request to flush !');
-
-    if (angular.isDefined(count) && count !== null) {
-      while (count--) {
-        if (!responses.length) throw new Error('No more pending request to flush !');
-        responses.shift()();
-      }
-    } else {
-      while (responses.length) {
-        responses.shift()();
-      }
-    }
-    $httpBackend.verifyNoOutstandingExpectation(digest);
-  };
-
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#verifyNoOutstandingExpectation
-   * @description
-   * Verifies that all of the requests defined via the `expect` api were made. If any of the
-   * requests were not made, verifyNoOutstandingExpectation throws an exception.
-   *
-   * Typically, you would call this method following each test case that asserts requests using an
-   * "afterEach" clause.
-   *
-   * ```js
-   *   afterEach($httpBackend.verifyNoOutstandingExpectation);
-   * ```
-   */
-  $httpBackend.verifyNoOutstandingExpectation = function(digest) {
-    if (digest !== false) $rootScope.$digest();
-    if (expectations.length) {
-      throw new Error('Unsatisfied requests: ' + expectations.join(', '));
-    }
-  };
-
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#verifyNoOutstandingRequest
-   * @description
-   * Verifies that there are no outstanding requests that need to be flushed.
-   *
-   * Typically, you would call this method following each test case that asserts requests using an
-   * "afterEach" clause.
-   *
-   * ```js
-   *   afterEach($httpBackend.verifyNoOutstandingRequest);
-   * ```
-   */
-  $httpBackend.verifyNoOutstandingRequest = function() {
-    if (responses.length) {
-      throw new Error('Unflushed requests: ' + responses.length);
-    }
-  };
-
-
-  /**
-   * @ngdoc method
-   * @name $httpBackend#resetExpectations
-   * @description
-   * Resets all request expectations, but preserves all backend definitions. Typically, you would
-   * call resetExpectations during a multiple-phase test when you want to reuse the same instance of
-   * $httpBackend mock.
-   */
-  $httpBackend.resetExpectations = function() {
-    expectations.length = 0;
-    responses.length = 0;
-  };
-
-  return $httpBackend;
-
-
-  function createShortMethods(prefix) {
-    angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) {
-     $httpBackend[prefix + method] = function(url, headers) {
-       return $httpBackend[prefix](method, url, undefined, headers);
-     };
-    });
-
-    angular.forEach(['PUT', 'POST', 'PATCH'], function(method) {
-      $httpBackend[prefix + method] = function(url, data, headers) {
-        return $httpBackend[prefix](method, url, data, headers);
-      };
-    });
-  }
-}
-
-function MockHttpExpectation(method, url, data, headers) {
-
-  this.data = data;
-  this.headers = headers;
-
-  this.match = function(m, u, d, h) {
-    if (method != m) return false;
-    if (!this.matchUrl(u)) return false;
-    if (angular.isDefined(d) && !this.matchData(d)) return false;
-    if (angular.isDefined(h) && !this.matchHeaders(h)) return false;
-    return true;
-  };
-
-  this.matchUrl = function(u) {
-    if (!url) return true;
-    if (angular.isFunction(url.test)) return url.test(u);
-    if (angular.isFunction(url)) return url(u);
-    return url == u;
-  };
-
-  this.matchHeaders = function(h) {
-    if (angular.isUndefined(headers)) return true;
-    if (angular.isFunction(headers)) return headers(h);
-    return angular.equals(headers, h);
-  };
-
-  this.matchData = function(d) {
-    if (angular.isUndefined(data)) return true;
-    if (data && angular.isFunction(data.test)) return data.test(d);
-    if (data && angular.isFunction(data)) return data(d);
-    if (data && !angular.isString(data)) {
-      return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d));
-    }
-    return data == d;
-  };
-
-  this.toString = function() {
-    return method + ' ' + url;
-  };
-}
-
-function createMockXhr() {
-  return new MockXhr();
-}
-
-function MockXhr() {
-
-  // hack for testing $http, $httpBackend
-  MockXhr.$$lastInstance = this;
-
-  this.open = function(method, url, async) {
-    this.$$method = method;
-    this.$$url = url;
-    this.$$async = async;
-    this.$$reqHeaders = {};
-    this.$$respHeaders = {};
-  };
-
-  this.send = function(data) {
-    this.$$data = data;
-  };
-
-  this.setRequestHeader = function(key, value) {
-    this.$$reqHeaders[key] = value;
-  };
-
-  this.getResponseHeader = function(name) {
-    // the lookup must be case insensitive,
-    // that's why we try two quick lookups first and full scan last
-    var header = this.$$respHeaders[name];
-    if (header) return header;
-
-    name = angular.lowercase(name);
-    header = this.$$respHeaders[name];
-    if (header) return header;
-
-    header = undefined;
-    angular.forEach(this.$$respHeaders, function(headerVal, headerName) {
-      if (!header && angular.lowercase(headerName) == name) header = headerVal;
-    });
-    return header;
-  };
-
-  this.getAllResponseHeaders = function() {
-    var lines = [];
-
-    angular.forEach(this.$$respHeaders, function(value, key) {
-      lines.push(key + ': ' + value);
-    });
-    return lines.join('\n');
-  };
-
-  this.abort = angular.noop;
-}
-
-
-/**
- * @ngdoc service
- * @name $timeout
- * @description
- *
- * This service is just a simple decorator for {@link ng.$timeout $timeout} service
- * that adds a "flush" and "verifyNoPendingTasks" methods.
- */
-
-angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $browser) {
-
-  /**
-   * @ngdoc method
-   * @name $timeout#flush
-   * @description
-   *
-   * Flushes the queue of pending tasks.
-   *
-   * @param {number=} delay maximum timeout amount to flush up until
-   */
-  $delegate.flush = function(delay) {
-    $browser.defer.flush(delay);
-  };
-
-  /**
-   * @ngdoc method
-   * @name $timeout#verifyNoPendingTasks
-   * @description
-   *
-   * Verifies that there are no pending tasks that need to be flushed.
-   */
-  $delegate.verifyNoPendingTasks = function() {
-    if ($browser.deferredFns.length) {
-      throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
-          formatPendingTasksAsString($browser.deferredFns));
-    }
-  };
-
-  function formatPendingTasksAsString(tasks) {
-    var result = [];
-    angular.forEach(tasks, function(task) {
-      result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');
-    });
-
-    return result.join(', ');
-  }
-
-  return $delegate;
-}];
-
-angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
-  var queue = [];
-  var rafFn = function(fn) {
-    var index = queue.length;
-    queue.push(fn);
-    return function() {
-      queue.splice(index, 1);
-    };
-  };
-
-  rafFn.supported = $delegate.supported;
-
-  rafFn.flush = function() {
-    if (queue.length === 0) {
-      throw new Error('No rAF callbacks present');
-    }
-
-    var length = queue.length;
-    for (var i = 0; i < length; i++) {
-      queue[i]();
-    }
-
-    queue = [];
-  };
-
-  return rafFn;
-}];
-
-angular.mock.$AsyncCallbackDecorator = ['$delegate', function($delegate) {
-  var callbacks = [];
-  var addFn = function(fn) {
-    callbacks.push(fn);
-  };
-  addFn.flush = function() {
-    angular.forEach(callbacks, function(fn) {
-      fn();
-    });
-    callbacks = [];
-  };
-  return addFn;
-}];
-
-/**
- *
- */
-angular.mock.$RootElementProvider = function() {
-  this.$get = function() {
-    return angular.element('<div ng-app></div>');
-  };
-};
-
-/**
- * @ngdoc module
- * @name ngMock
- * @packageName angular-mocks
- * @description
- *
- * # ngMock
- *
- * The `ngMock` module provides support to inject and mock Angular services into unit tests.
- * In addition, ngMock also extends various core ng services such that they can be
- * inspected and controlled in a synchronous manner within test code.
- *
- *
- * <div doc-module-components="ngMock"></div>
- *
- */
-angular.module('ngMock', ['ng']).provider({
-  $browser: angular.mock.$BrowserProvider,
-  $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
-  $log: angular.mock.$LogProvider,
-  $interval: angular.mock.$IntervalProvider,
-  $httpBackend: angular.mock.$HttpBackendProvider,
-  $rootElement: angular.mock.$RootElementProvider
-}).config(['$provide', function($provide) {
-  $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
-  $provide.decorator('$$rAF', angular.mock.$RAFDecorator);
-  $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
-  $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
-}]);
-
-/**
- * @ngdoc module
- * @name ngMockE2E
- * @module ngMockE2E
- * @packageName angular-mocks
- * @description
- *
- * The `ngMockE2E` is an angular module which 