diff --git a/tools/gui/gulp-tasks/bundles/bundle-js/index.js b/tools/gui/gulp-tasks/bundles/bundle-js/index.js
index 4af3432..90a0e24 100644
--- a/tools/gui/gulp-tasks/bundles/bundle-js/index.js
+++ b/tools/gui/gulp-tasks/bundles/bundle-js/index.js
@@ -29,7 +29,7 @@
     'tp/angular-cookies.js',
     'tp/d3.js',
     'tp/topojson.v1.min.js',
-    'tp/Chart.min.js',
+    'tp/Chart.js',
     'tp/lodash.min.js',
 ];
 
diff --git a/web/gui/src/main/webapp/app/view/app/app.js b/web/gui/src/main/webapp/app/view/app/app.js
index a71cb2d..1a09682 100644
--- a/web/gui/src/main/webapp/app/view/app/app.js
+++ b/web/gui/src/main/webapp/app/view/app/app.js
@@ -404,7 +404,7 @@
             };
         }])
 
-    .directive("filedrop", function ($parse, $document) {
+    .directive("filedrop", ['$parse', '$document', function ($parse, $document) {
         return {
             restrict: "A",
             link: function (scope, element, attrs) {
@@ -440,7 +440,7 @@
                     });
             }
         };
-    })
+    }])
 
     .directive('applicationDetailsPanel',
         ['$rootScope', '$window', '$timeout', 'KeyService',
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index e74329b..b8eaca0 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -30,7 +30,16 @@
     <title>ONOS</title>
 
     <!-- Third party library code included here -->
-    <script src="dist/vendor.js"></script>
+    <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>
 
     <!-- {INJECTED-USER-START} -->
     <!-- {INJECTED-USER-END} -->
diff --git a/web/gui/src/main/webapp/tp/Chart.js b/web/gui/src/main/webapp/tp/Chart.js
index 34f9728..24ffad0 100644
--- a/web/gui/src/main/webapp/tp/Chart.js
+++ b/web/gui/src/main/webapp/tp/Chart.js
@@ -1,10397 +1,12757 @@
 /*!
  * Chart.js
  * http://chartjs.org/
- * Version: 2.2.1
+ * Version: 2.6.0
  *
- * Copyright 2016 Nick Downie
+ * 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;
-}
+    /* 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.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 {
-			throw new Error('Unable to parse color from string "' + obj + '"');
-		}
-	} 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);
-		} else {
-			throw new Error('Unable to parse color from object ' + JSON.stringify(obj));
-		}
-	}
-};
-
-Color.prototype = {
-	rgb: function () {
-		return this.setSpace('rgb', arguments);
-	},
-	hsl: function () {
-		return this.setSpace('hsl', arguments);
-	},
-	hsv: function () {
-		return this.setSpace('hsv', arguments);
-	},
-	hwb: function () {
-		return this.setSpace('hwb', arguments);
-	},
-	cmyk: function () {
-		return this.setSpace('cmyk', arguments);
-	},
-
-	rgbArray: function () {
-		return this.values.rgb;
-	},
-	hslArray: function () {
-		return this.values.hsl;
-	},
-	hsvArray: function () {
-		return this.values.hsv;
-	},
-	hwbArray: function () {
-		var 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;
-
-	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;
+    /* 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 */
+    /* MIT license */
 
-module.exports = {
-  rgb2hsl: rgb2hsl,
-  rgb2hsv: rgb2hsv,
-  rgb2hwb: rgb2hwb,
-  rgb2cmyk: rgb2cmyk,
-  rgb2keyword: rgb2keyword,
-  rgb2xyz: rgb2xyz,
-  rgb2lab: rgb2lab,
-  rgb2lch: rgb2lch,
+    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,
+        hsl2rgb: hsl2rgb,
+        hsl2hsv: hsl2hsv,
+        hsl2hwb: hsl2hwb,
+        hsl2cmyk: hsl2cmyk,
+        hsl2keyword: hsl2keyword,
 
-  hsv2rgb: hsv2rgb,
-  hsv2hsl: hsv2hsl,
-  hsv2hwb: hsv2hwb,
-  hsv2cmyk: hsv2cmyk,
-  hsv2keyword: hsv2keyword,
+        hsv2rgb: hsv2rgb,
+        hsv2hsl: hsv2hsl,
+        hsv2hwb: hsv2hwb,
+        hsv2cmyk: hsv2cmyk,
+        hsv2keyword: hsv2keyword,
 
-  hwb2rgb: hwb2rgb,
-  hwb2hsl: hwb2hsl,
-  hwb2hsv: hwb2hsv,
-  hwb2cmyk: hwb2cmyk,
-  hwb2keyword: hwb2keyword,
+        hwb2rgb: hwb2rgb,
+        hwb2hsl: hwb2hsl,
+        hwb2hsv: hwb2hsv,
+        hwb2cmyk: hwb2cmyk,
+        hwb2keyword: hwb2keyword,
 
-  cmyk2rgb: cmyk2rgb,
-  cmyk2hsl: cmyk2hsl,
-  cmyk2hsv: cmyk2hsv,
-  cmyk2hwb: cmyk2hwb,
-  cmyk2keyword: cmyk2keyword,
+        cmyk2rgb: cmyk2rgb,
+        cmyk2hsl: cmyk2hsl,
+        cmyk2hsv: cmyk2hsv,
+        cmyk2hwb: cmyk2hwb,
+        cmyk2keyword: cmyk2keyword,
 
-  keyword2rgb: keyword2rgb,
-  keyword2hsl: keyword2hsl,
-  keyword2hsv: keyword2hsv,
-  keyword2hwb: keyword2hwb,
-  keyword2cmyk: keyword2cmyk,
-  keyword2lab: keyword2lab,
-  keyword2xyz: keyword2xyz,
+        keyword2rgb: keyword2rgb,
+        keyword2hsl: keyword2hsl,
+        keyword2hsv: keyword2hsv,
+        keyword2hwb: keyword2hwb,
+        keyword2cmyk: keyword2cmyk,
+        keyword2lab: keyword2lab,
+        keyword2xyz: keyword2xyz,
 
-  xyz2rgb: xyz2rgb,
-  xyz2lab: xyz2lab,
-  xyz2lch: xyz2lch,
+        xyz2rgb: xyz2rgb,
+        xyz2lab: xyz2lab,
+        xyz2lch: xyz2lch,
 
-  lab2xyz: lab2xyz,
-  lab2rgb: lab2rgb,
-  lab2lch: lab2lch,
+        lab2xyz: lab2xyz,
+        lab2rgb: lab2rgb,
+        lab2lch: lab2lch,
 
-  lch2lab: lch2lab,
-  lch2xyz: lch2xyz,
-  lch2rgb: lch2rgb
-}
+        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;
+    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;
+        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);
+        h = Math.min(h * 60, 360);
 
-  if (h < 0)
-    h += 360;
+        if (h < 0)
+            h += 360;
 
-  l = (min + max) / 2;
+        l = (min + max) / 2;
 
-  if (max == min)
-    s = 0;
-  else if (l <= 0.5)
-    s = delta / (max + min);
-  else
-    s = delta / (2 - max - min);
+        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];
-}
+        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;
+    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 == 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;
+        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);
+        h = Math.min(h * 60, 360);
 
-  if (h < 0)
-    h += 360;
+        if (h < 0)
+            h += 360;
 
-  v = ((max / 255) * 1000) / 10;
+        v = ((max / 255) * 1000) / 10;
 
-  return [h, s, v];
-}
+        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));
+    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];
-}
+        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;
+    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];
-}
+        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 rgb2keyword(rgb) {
+        return reverseKeywords[JSON.stringify(rgb)];
+    }
 
-function rgb2xyz(rgb) {
-  var r = rgb[0] / 255,
-      g = rgb[1] / 255,
-      b = rgb[2] / 255;
+    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);
+        // 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);
+        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];
-}
+        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;
+    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 /= 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);
+        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);
+        l = (116 * y) - 16;
+        a = 500 * (x - y);
+        b = 200 * (y - z);
 
-  return [l, a, b];
-}
+        return [l, a, b];
+    }
 
-function rgb2lch(args) {
-  return lab2lch(rgb2lab(args));
-}
+    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;
+    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 (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;
+        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--;
+        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;
+            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;
-  }
+            rgb[i] = val * 255;
+        }
 
-  return rgb;
-}
+        return rgb;
+    }
 
-function hsl2hsv(hsl) {
-  var h = hsl[0],
-      s = hsl[1] / 100,
-      l = hsl[2] / 100,
-      sv, v;
+    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];
-  }
+        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];
-}
+        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 hsl2hwb(args) {
+        return rgb2hwb(hsl2rgb(args));
+    }
 
-function hsl2cmyk(args) {
-  return rgb2cmyk(hsl2rgb(args));
-}
+    function hsl2cmyk(args) {
+        return rgb2cmyk(hsl2rgb(args));
+    }
 
-function hsl2keyword(args) {
-  return rgb2keyword(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;
+    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;
+        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];
-  }
-}
+        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;
+    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];
-}
+        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 hsv2hwb(args) {
+        return rgb2hwb(hsv2rgb(args))
+    }
 
-function hsv2cmyk(args) {
-  return rgb2cmyk(hsv2rgb(args));
-}
+    function hsv2cmyk(args) {
+        return rgb2cmyk(hsv2rgb(args));
+    }
 
-function hsv2keyword(args) {
-  return rgb2keyword(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;
+    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;
-  }
+        // 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
+        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;
-  }
+        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];
-}
+        return [r * 255, g * 255, b * 255];
+    }
 
-function hwb2hsl(args) {
-  return rgb2hsl(hwb2rgb(args));
-}
+    function hwb2hsl(args) {
+        return rgb2hsl(hwb2rgb(args));
+    }
 
-function hwb2hsv(args) {
-  return rgb2hsv(hwb2rgb(args));
-}
+    function hwb2hsv(args) {
+        return rgb2hsv(hwb2rgb(args));
+    }
 
-function hwb2cmyk(args) {
-  return rgb2cmyk(hwb2rgb(args));
-}
+    function hwb2cmyk(args) {
+        return rgb2cmyk(hwb2rgb(args));
+    }
 
-function hwb2keyword(args) {
-  return rgb2keyword(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;
+    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];
-}
+        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 cmyk2hsl(args) {
+        return rgb2hsl(cmyk2rgb(args));
+    }
 
-function cmyk2hsv(args) {
-  return rgb2hsv(cmyk2rgb(args));
-}
+    function cmyk2hsv(args) {
+        return rgb2hsv(cmyk2rgb(args));
+    }
 
-function cmyk2hwb(args) {
-  return rgb2hwb(cmyk2rgb(args));
-}
+    function cmyk2hwb(args) {
+        return rgb2hwb(cmyk2rgb(args));
+    }
 
-function cmyk2keyword(args) {
-  return rgb2keyword(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;
+    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);
+        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);
+        // 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);
+        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);
+        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);
+        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];
-}
+        return [r * 255, g * 255, b * 255];
+    }
 
-function xyz2lab(xyz) {
-  var x = xyz[0],
-      y = xyz[1],
-      z = xyz[2],
-      l, a, b;
+    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 /= 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);
+        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);
+        l = (116 * y) - 16;
+        a = 500 * (x - y);
+        b = 200 * (y - z);
 
-  return [l, a, b];
-}
+        return [l, a, b];
+    }
 
-function xyz2lch(args) {
-  return lab2lch(xyz2lab(args));
-}
+    function xyz2lch(args) {
+        return lab2lch(xyz2lab(args));
+    }
 
-function lab2xyz(lab) {
-  var l = lab[0],
-      a = lab[1],
-      b = lab[2],
-      x, y, z, y2;
+    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);
-  }
+        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);
+        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);
+        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];
-}
+        return [x, y, z];
+    }
 
-function lab2lch(lab) {
-  var l = lab[0],
-      a = lab[1],
-      b = lab[2],
-      hr, h, c;
+    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];
-}
+        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 lab2rgb(args) {
+        return xyz2rgb(lab2xyz(args));
+    }
 
-function lch2lab(lch) {
-  var l = lch[0],
-      c = lch[1],
-      h = lch[2],
-      a, b, hr;
+    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];
-}
+        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 lch2xyz(args) {
+        return lab2xyz(lch2lab(args));
+    }
 
-function lch2rgb(args) {
-  return lab2rgb(lch2lab(args));
-}
+    function lch2rgb(args) {
+        return lab2rgb(lch2lab(args));
+    }
 
-function keyword2rgb(keyword) {
-  return cssKeywords[keyword];
-}
+    function keyword2rgb(keyword) {
+        return cssKeywords[keyword];
+    }
 
-function keyword2hsl(args) {
-  return rgb2hsl(keyword2rgb(args));
-}
+    function keyword2hsl(args) {
+        return rgb2hsl(keyword2rgb(args));
+    }
 
-function keyword2hsv(args) {
-  return rgb2hsv(keyword2rgb(args));
-}
+    function keyword2hsv(args) {
+        return rgb2hsv(keyword2rgb(args));
+    }
 
-function keyword2hwb(args) {
-  return rgb2hwb(keyword2rgb(args));
-}
+    function keyword2hwb(args) {
+        return rgb2hwb(keyword2rgb(args));
+    }
 
-function keyword2cmyk(args) {
-  return rgb2cmyk(keyword2rgb(args));
-}
+    function keyword2cmyk(args) {
+        return rgb2cmyk(keyword2rgb(args));
+    }
 
-function keyword2lab(args) {
-  return rgb2lab(keyword2rgb(args));
-}
+    function keyword2lab(args) {
+        return rgb2lab(keyword2rgb(args));
+    }
 
-function keyword2xyz(args) {
-  return rgb2xyz(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 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;
-}
+    var reverseKeywords = {};
+    for (var key in cssKeywords) {
+        reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
+    }
 
 },{}],5:[function(require,module,exports){
-var conversions = require(4);
+    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);
+    var convert = function() {
+        return new Converter();
     }
-  })(func);
 
-  var pair = /(\w+)2(\w+)/.exec(func),
-      from = pair[1],
-      to = pair[2];
+    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);
 
-  // export rgb2hsl and ["rgb"]["hsl"]
-  convert[from] = convert[from] || {};
+        var pair = /(\w+)2(\w+)/.exec(func),
+            from = pair[1],
+            to = pair[2];
 
-  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
+        // export rgb2hsl and ["rgb"]["hsl"]
+        convert[from] = convert[from] || {};
 
-      for (var i = 0; i < val.length; i++)
-        val[i] = Math.round(val[i]);
-      return val;
+        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);
     }
-  })(func);
-}
 
 
-/* Converter does lazy conversion and caching */
-var Converter = function() {
-   this.convs = {};
-};
+    /* 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);        
-   }
+    /* 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;
-};
+        return this.setValues(space, values);
+    };
 
-/* 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);
+    /* 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;
+    };
 
-      this.convs[space] = vals;
-   }
-  return vals;
-};
+    /* 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);
 
-["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
-   Converter.prototype[space] = function(vals) {
-      return this.routeSpace(space, arguments);
-   }
-});
+            this.convs[space] = vals;
+        }
+        return vals;
+    };
 
-module.exports = convert;
+    ["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]
-};
+    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(27)();
+    /**
+     * @namespace Chart
+     */
+    var Chart = require(28)();
 
-require(26)(Chart);
-require(22)(Chart);
-require(25)(Chart);
-require(21)(Chart);
-require(23)(Chart);
-require(24)(Chart);
-require(28)(Chart);
-require(32)(Chart);
-require(30)(Chart);
-require(31)(Chart);
-require(33)(Chart);
-require(29)(Chart);
-require(34)(Chart);
+    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(35)(Chart);
+    require(36)(Chart);
+    require(37)(Chart);
+    require(38)(Chart);
 
-require(41)(Chart);
-require(39)(Chart);
-require(40)(Chart);
-require(42)(Chart);
-require(43)(Chart);
-require(44)(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(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);
+    require(8)(Chart);
+    require(9)(Chart);
+    require(10)(Chart);
+    require(11)(Chart);
+    require(12)(Chart);
+    require(13)(Chart);
+    require(14)(Chart);
 
-window.Chart = module.exports = Chart;
+// Loading built-it plugins
+    var plugins = [];
 
-},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"44":44,"8":8,"9":9}],8:[function(require,module,exports){
-"use strict";
+    plugins.push(
+        require(41)(Chart),
+        require(42)(Chart),
+        require(43)(Chart)
+    );
 
-module.exports = function(Chart) {
+    Chart.plugins.register(plugins);
 
-	Chart.Bar = function(context, config) {
-		config.type = 'bar';
+    module.exports = Chart;
+    if (typeof window !== 'undefined') {
+        window.Chart = Chart;
+    }
 
-		return new Chart(context, config);
-	};
+},{"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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.Bubble = function(context, config) {
-		config.type = 'bubble';
-		return new Chart(context, config);
-	};
+        Chart.Bubble = function(context, config) {
+            config.type = 'bubble';
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],10:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.Doughnut = function(context, config) {
-		config.type = 'doughnut';
+        Chart.Doughnut = function(context, config) {
+            config.type = 'doughnut';
 
-		return new Chart(context, config);
-	};
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],11:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.Line = function(context, config) {
-		config.type = 'line';
+        Chart.Line = function(context, config) {
+            config.type = 'line';
 
-		return new Chart(context, config);
-	};
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],12:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.PolarArea = function(context, config) {
-		config.type = 'polarArea';
+        Chart.PolarArea = function(context, config) {
+            config.type = 'polarArea';
 
-		return new Chart(context, config);
-	};
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],13:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
-	
-	Chart.Radar = function(context, config) {
-		config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options);
-		config.type = 'radar';
+    module.exports = function(Chart) {
 
-		return new Chart(context, config);
-	};
+        Chart.Radar = function(context, config) {
+            config.type = 'radar';
 
-};
+            return new Chart(context, config);
+        };
+
+    };
 
 },{}],14:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var defaultConfig = {
-		hover: {
-			mode: 'single'
-		},
+        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"
-			}]
-		},
+            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 + ')';
-				}
-			}
-		}
-	};
+            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;
+        // Register the default config for this type
+        Chart.defaults.scatter = defaultConfig;
 
-	// Scatter charts use line controllers
-	Chart.controllers.scatter = Chart.controllers.line;
+        // Scatter charts use line controllers
+        Chart.controllers.scatter = Chart.controllers.line;
 
-	Chart.Scatter = function(context, config) {
-		config.type = 'scatter';
-		return new Chart(context, config);
-	};
+        Chart.Scatter = function(context, config) {
+            config.type = 'scatter';
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],15:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.bar = {
-		hover: {
-			mode: "label"
-		},
+        Chart.defaults.bar = {
+            hover: {
+                mode: 'label'
+            },
 
-		scales: {
-			xAxes: [{
-				type: "category",
+            scales: {
+                xAxes: [{
+                    type: 'category',
 
-				// Specific to Bar Controller
-				categoryPercentage: 0.8,
-				barPercentage: 0.9,
+                    // Specific to Bar Controller
+                    categoryPercentage: 0.8,
+                    barPercentage: 0.9,
 
-				// grid line settings
-				gridLines: {
-					offsetGridLines: true
-				}
-			}],
-			yAxes: [{
-				type: "linear"
-			}]
-		}
-	};
+                    // grid line settings
+                    gridLines: {
+                        offsetGridLines: true
+                    }
+                }],
+                yAxes: [{
+                    type: 'linear'
+                }]
+            }
+        };
 
-	Chart.controllers.bar = Chart.DatasetController.extend({
+        Chart.controllers.bar = Chart.DatasetController.extend({
 
-		dataElementType: Chart.elements.Rectangle,
+            dataElementType: Chart.elements.Rectangle,
 
-		initialize: function(chart, datasetIndex) {
-			Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);
+            initialize: function() {
+                var me = this;
+                var meta;
 
-			// Use this to indicate that this is a bar dataset.
-			this.getMeta().bar = true;
-		},
+                Chart.DatasetController.prototype.initialize.apply(me, arguments);
 
-		// Get the number of datasets that display bars. We use this to correctly calculate the bar width
-		getBarCount: function() {
-			var me = this;
-			var barCount = 0;
-			helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
-				var meta = me.chart.getDatasetMeta(datasetIndex);
-				if (meta.bar && me.chart.isDatasetVisible(datasetIndex)) {
-					++barCount;
-				}
-			}, me);
-			return barCount;
-		},
+                meta = me.getMeta();
+                meta.stack = me.getDataset().stack;
+                meta.bar = true;
+            },
 
-		update: function(reset) {
-			var me = this;
-			helpers.each(me.getMeta().data, function(rectangle, index) {
-				me.updateElement(rectangle, index, reset);
-			}, me);
-		},
+            update: function(reset) {
+                var me = this;
+                var elements = me.getMeta().data;
+                var i, ilen;
 
-		updateElement: function(rectangle, index, reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var scaleBase = yScale.getBasePixel();
-			var rectangleElementOptions = me.chart.options.elements.rectangle;
-			var custom = rectangle.custom || {};
-			var dataset = me.getDataset();
+                me._ruler = me.getRuler();
 
-			helpers.extend(rectangle, {
-				// Utility
-				_xScale: xScale,
-				_yScale: yScale,
-				_datasetIndex: me.index,
-				_index: index,
+                for (i = 0, ilen = elements.length; i < ilen; ++i) {
+                    me.updateElement(elements[i], i, reset);
+                }
+            },
 
-				// Desired view properties
-				_model: {
-					x: me.calculateBarX(index, me.index),
-					y: reset ? scaleBase : me.calculateBarY(index, me.index),
+            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;
 
-					// Tooltip
-					label: me.chart.data.labels[index],
-					datasetLabel: dataset.label,
+                rectangle._xScale = me.getScaleForId(meta.xAxisID);
+                rectangle._yScale = me.getScaleForId(meta.yAxisID);
+                rectangle._datasetIndex = me.index;
+                rectangle._index = index;
 
-					// Appearance
-					base: reset ? scaleBase : me.calculateBarBase(me.index, index),
-					width: me.calculateBarWidth(index),
-					backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
-					borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
-					borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
-					borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
-				}
-			});
-			rectangle.pivot();
-		},
+                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)
+                };
 
-		calculateBarBase: function(datasetIndex, index) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var base = 0;
+                me.updateElementGeometry(rectangle, index, reset);
 
-			if (yScale.options.stacked) {
-				var chart = me.chart;
-				var datasets = chart.data.datasets;
-				var value = Number(datasets[datasetIndex].data[index]);
+                rectangle.pivot();
+            },
 
-				for (var i = 0; i < datasetIndex; i++) {
-					var currentDs = datasets[i];
-					var currentDsMeta = chart.getDatasetMeta(i);
-					if (currentDsMeta.bar && currentDsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
-						var currentVal = Number(currentDs.data[index]);
-						base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
-					}
-				}
+            /**
+             * @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);
 
-				return yScale.getPixelForValue(base);
-			}
+                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;
+            },
 
-			return yScale.getBasePixel();
-		},
+            /**
+             * @private
+             */
+            getValueScaleId: function() {
+                return this.getMeta().yAxisID;
+            },
 
-		getRuler: function(index) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var datasetCount = me.getBarCount();
+            /**
+             * @private
+             */
+            getIndexScaleId: function() {
+                return this.getMeta().xAxisID;
+            },
 
-			var tickWidth;
+            /**
+             * @private
+             */
+            getValueScale: function() {
+                return this.getScaleForId(this.getValueScaleId());
+            },
 
-			if (xScale.options.type === 'category') {
-				tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index);
-			} else {
-				// Average width
-				tickWidth = xScale.width / xScale.ticks.length;
-			}
-			var categoryWidth = tickWidth * xScale.options.categoryPercentage;
-			var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
-			var fullBarWidth = categoryWidth / datasetCount;
+            /**
+             * @private
+             */
+            getIndexScale: function() {
+                return this.getScaleForId(this.getIndexScaleId());
+            },
 
-			if (xScale.ticks.length !== me.chart.data.labels.length) {
-			    var perc = xScale.ticks.length / me.chart.data.labels.length;
-			    fullBarWidth = fullBarWidth * perc;
-			}
+            /**
+             * 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;
 
-			var barWidth = fullBarWidth * xScale.options.barPercentage;
-			var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);
+                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 {
-				datasetCount: datasetCount,
-				tickWidth: tickWidth,
-				categoryWidth: categoryWidth,
-				categorySpacing: categorySpacing,
-				fullBarWidth: fullBarWidth,
-				barWidth: barWidth,
-				barSpacing: barSpacing
-			};
-		},
+                return stacks.length;
+            },
 
-		calculateBarWidth: function(index) {
-			var xScale = this.getScaleForId(this.getMeta().xAxisID);
-			if (xScale.options.barThickness) {
-				return xScale.options.barThickness;
-			}
-			var ruler = this.getRuler(index);
-			return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;
-		},
+            /**
+             * Returns the stack index for the given dataset based on groups and bar visibility.
+             * @private
+             */
+            getStackIndex: function(datasetIndex) {
+                return this.getStackCount(datasetIndex) - 1;
+            },
 
-		// Get bar index from the given dataset index accounting for the fact that not all bars are visible
-		getBarIndex: function(datasetIndex) {
-			var barIndex = 0;
-			var meta, j;
+            /**
+             * @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;
 
-			for (j = 0; j < datasetIndex; ++j) {
-				meta = this.chart.getDatasetMeta(j);
-				if (meta.bar && this.chart.isDatasetVisible(j)) {
-					++barIndex;
-				}
-			}
+                barSize = Math.min(
+                    helpers.getValueOrDefault(options.barThickness, barSize),
+                    helpers.getValueOrDefault(options.maxBarThickness, Infinity));
 
-			return barIndex;
-		},
+                return {
+                    stackCount: stackCount,
+                    tickSize: tickSize,
+                    categorySize: categorySize,
+                    categorySpacing: tickSize - categorySize,
+                    fullBarSize: fullBarSize,
+                    barSize: barSize,
+                    barSpacing: fullBarSize - barSize,
+                    scale: scale
+                };
+            },
 
-		calculateBarX: function(index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var barIndex = me.getBarIndex(datasetIndex);
+            /**
+             * 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;
 
-			var ruler = me.getRuler(index);
-			var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
-			leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0;
+                if (stacked || (stacked === undefined && stack !== undefined)) {
+                    for (i = 0; i < datasetIndex; ++i) {
+                        imeta = chart.getDatasetMeta(i);
 
-			if (xScale.options.stacked) {
-				return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;
-			}
+                        if (imeta.bar &&
+                            imeta.stack === stack &&
+                            imeta.controller.getValueScaleId() === scale.id &&
+                            chart.isDatasetVisible(i)) {
 
-			return leftTick +
-				(ruler.barWidth / 2) +
-				ruler.categorySpacing +
-				(ruler.barWidth * barIndex) +
-				(ruler.barSpacing / 2) +
-				(ruler.barSpacing * barIndex);
-		},
+                            ivalue = Number(datasets[i].data[index]);
+                            if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {
+                                start += ivalue;
+                            }
+                        }
+                    }
+                }
 
-		calculateBarY: function(index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var value = Number(me.getDataset().data[index]);
+                base = scale.getPixelForValue(start);
+                head = scale.getPixelForValue(start + value);
+                size = (head - base) / 2;
 
-			if (yScale.options.stacked) {
+                return {
+                    size: size,
+                    base: base,
+                    head: head,
+                    center: head + size / 2
+                };
+            },
 
-				var sumPos = 0,
-					sumNeg = 0;
+            /**
+             * @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;
 
-				for (var i = 0; i < datasetIndex; i++) {
-					var ds = me.chart.data.datasets[i];
-					var dsMeta = me.chart.getDatasetMeta(i);
-					if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) {
-						var stackedVal = Number(ds.data[index]);
-						if (stackedVal < 0) {
-							sumNeg += stackedVal || 0;
-						} else {
-							sumPos += stackedVal || 0;
-						}
-					}
-				}
+                base -= isCombo? ruler.tickSize / 2 : 0;
+                base += ruler.fullBarSize * stackIndex;
+                base += ruler.categorySpacing / 2;
+                base += ruler.barSpacing / 2;
 
-				if (value < 0) {
-					return yScale.getPixelForValue(sumNeg + value);
-				} else {
-					return yScale.getPixelForValue(sumPos + value);
-				}
-			}
-
-			return yScale.getPixelForValue(value);
-		},
-
-		draw: function(ease) {
-			var me = this;
-			var easingDecimal = ease || 1;
-			helpers.each(me.getMeta().data, function(rectangle, index) {
-				var d = me.getDataset().data[index];
-				if (d !== null && d !== undefined && !isNaN(d)) {
-					rectangle.transition(easingDecimal).draw();
-				}
-			}, me);
-		},
-
-		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({
-		updateElement: function(rectangle, index, reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var scaleBase = xScale.getBasePixel();
-			var custom = rectangle.custom || {};
-			var dataset = me.getDataset();
-			var rectangleElementOptions = me.chart.options.elements.rectangle;
-
-			helpers.extend(rectangle, {
-				// Utility
-				_xScale: xScale,
-				_yScale: yScale,
-				_datasetIndex: me.index,
-				_index: index,
-
-				// Desired view properties
-				_model: {
-					x: reset ? scaleBase : me.calculateBarX(index, me.index),
-					y: me.calculateBarY(index, me.index),
-
-					// Tooltip
-					label: me.chart.data.labels[index],
-					datasetLabel: dataset.label,
-
-					// Appearance
-					base: reset ? scaleBase : me.calculateBarBase(me.index, index),
-					height: me.calculateBarHeight(index),
-					backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
-					borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
-					borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
-					borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
-				},
-
-				draw: function () {
-					var ctx = this._chart.ctx;
-					var vm = this._view;
-
-					var halfHeight = vm.height / 2,
-						topY = vm.y - halfHeight,
-						bottomY = vm.y + halfHeight,
-						right = vm.base - (vm.base - vm.x),
-						halfStroke = vm.borderWidth / 2;
-
-					// 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 (vm.borderWidth) {
-						topY += halfStroke;
-						bottomY -= halfStroke;
-						right += halfStroke;
-					}
-
-					ctx.beginPath();
-
-					ctx.fillStyle = vm.backgroundColor;
-					ctx.strokeStyle = vm.borderColor;
-					ctx.lineWidth = vm.borderWidth;
-
-					// Corner points, from bottom-left to bottom-right clockwise
-					// | 1 2 |
-					// | 0 3 |
-					var corners = [
-						[vm.base, bottomY],
-						[vm.base, topY],
-						[right, topY],
-						[right, bottomY]
-					];
-
-					// Find first (starting) corner with fallback to 'bottom'
-					var borders = ['bottom', 'left', 'top', 'right'];
-					var startCorner = borders.indexOf(vm.borderSkipped, 0);
-					if (startCorner === -1)
-						startCorner = 0;
-
-					function cornerAt(index) {
-						return corners[(startCorner + index) % 4];
-					}
-
-					// Draw rectangle from 'startCorner'
-					ctx.moveTo.apply(ctx, cornerAt(0));
-					for (var i = 1; i < 4; i++)
-						ctx.lineTo.apply(ctx, cornerAt(i));
-
-					ctx.fill();
-					if (vm.borderWidth) {
-						ctx.stroke();
-					}
-				},
-
-				inRange: function (mouseX, mouseY) {
-					var vm = this._view;
-					var inRange = false;
-
-					if (vm) {
-						if (vm.x < vm.base) {
-							inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base);
-						} else {
-							inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x);
-						}
-					}
-
-					return inRange;
-				}
-			});
-
-			rectangle.pivot();
-		},
-
-		calculateBarBase: function (datasetIndex, index) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var base = 0;
-
-			if (xScale.options.stacked) {
-				var chart = me.chart;
-				var datasets = chart.data.datasets;
-				var value = Number(datasets[datasetIndex].data[index]);
-
-				for (var i = 0; i < datasetIndex; i++) {
-					var currentDs = datasets[i];
-					var currentDsMeta = chart.getDatasetMeta(i);
-					if (currentDsMeta.bar && currentDsMeta.xAxisID === xScale.id && chart.isDatasetVisible(i)) {
-						var currentVal = Number(currentDs.data[index]);
-						base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
-					}
-				}
-
-				return xScale.getPixelForValue(base);
-			}
+                return {
+                    size: size,
+                    base: base,
+                    head: base + size,
+                    center: base + size / 2
+                };
+            },
 
-			return xScale.getBasePixel();
-		},
+            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;
 
-		getRuler: function (index) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var datasetCount = me.getBarCount();
+                helpers.canvas.clipArea(chart.ctx, chart.chartArea);
 
-			var tickHeight;
-			if (yScale.options.type === 'category') {
-				tickHeight = yScale.getPixelForTick(index + 1) - yScale.getPixelForTick(index);
-			} else {
-				// Average width
-				tickHeight = yScale.width / yScale.ticks.length;
-			}
-			var categoryHeight = tickHeight * yScale.options.categoryPercentage;
-			var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2;
-			var fullBarHeight = categoryHeight / datasetCount;
+                for (; i<ilen; ++i) {
+                    d = dataset.data[i];
+                    if (d !== null && d !== undefined && !isNaN(d)) {
+                        elements[i].draw();
+                    }
+                }
 
-			if (yScale.ticks.length !== me.chart.data.labels.length) {
-				var perc = yScale.ticks.length / me.chart.data.labels.length;
-				fullBarHeight = fullBarHeight * perc;
-			}
+                helpers.canvas.unclipArea(chart.ctx);
+            },
 
-			var barHeight = fullBarHeight * yScale.options.barPercentage;
-			var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage);
+            setHoverStyle: function(rectangle) {
+                var dataset = this.chart.data.datasets[rectangle._datasetIndex];
+                var index = rectangle._index;
+                var custom = rectangle.custom || {};
+                var model = rectangle._model;
 
-			return {
-				datasetCount: datasetCount,
-				tickHeight: tickHeight,
-				categoryHeight: categoryHeight,
-				categorySpacing: categorySpacing,
-				fullBarHeight: fullBarHeight,
-				barHeight: barHeight,
-				barSpacing: barSpacing,
-			};
-		},
+                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);
+            },
 
-		calculateBarHeight: function (index) {
-			var me = this;
-			var yScale = me.getScaleForId(me.getMeta().yAxisID);
-			if (yScale.options.barThickness) {
-				return yScale.options.barThickness;
-			}
-			var ruler = me.getRuler(index);
-			return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;
-		},
+            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;
 
-		calculateBarX: function (index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var value = Number(me.getDataset().data[index]);
+                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);
+            }
+        });
 
-			if (xScale.options.stacked) {
 
-				var sumPos = 0,
-					sumNeg = 0;
+        // 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'
+            },
 
-				for (var i = 0; i < datasetIndex; i++) {
-					var ds = me.chart.data.datasets[i];
-					var dsMeta = me.chart.getDatasetMeta(i);
-					if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {
-						var stackedVal = Number(ds.data[index]);
-						if (stackedVal < 0) {
-							sumNeg += stackedVal || 0;
-						} else {
-							sumPos += stackedVal || 0;
-						}
-					}
-				}
+            scales: {
+                xAxes: [{
+                    type: 'linear',
+                    position: 'bottom'
+                }],
+                yAxes: [{
+                    position: 'left',
+                    type: 'category',
 
-				if (value < 0) {
-					return xScale.getPixelForValue(sumNeg + value);
-				} else {
-					return xScale.getPixelForValue(sumPos + value);
-				}
-			}
+                    // Specific to Horizontal Bar Controller
+                    categoryPercentage: 0.8,
+                    barPercentage: 0.9,
 
-			return xScale.getPixelForValue(value);
-		},
+                    // grid line settings
+                    gridLines: {
+                        offsetGridLines: true
+                    }
+                }]
+            },
+            elements: {
+                rectangle: {
+                    borderSkipped: 'left'
+                }
+            },
+            tooltips: {
+                callbacks: {
+                    title: function(tooltipItems, data) {
+                        // Pick first xLabel for now
+                        var title = '';
 
-		calculateBarY: function (index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var barIndex = me.getBarIndex(datasetIndex);
+                        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];
+                            }
+                        }
 
-			var ruler = me.getRuler(index);
-			var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
-			topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;
+                        return title;
+                    },
+                    label: function(tooltipItem, data) {
+                        var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
+                        return datasetLabel + ': ' + tooltipItem.xLabel;
+                    }
+                }
+            }
+        };
 
-			if (yScale.options.stacked) {
-				return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;
-			}
+        Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
+            /**
+             * @private
+             */
+            getValueScaleId: function() {
+                return this.getMeta().xAxisID;
+            },
 
-			return topTick +
-				(ruler.barHeight / 2) +
-				ruler.categorySpacing +
-				(ruler.barHeight * barIndex) +
-				(ruler.barSpacing / 2) +
-				(ruler.barSpacing * barIndex);
-		}
-	});
-};
+            /**
+             * @private
+             */
+            getIndexScaleId: function() {
+                return this.getMeta().yAxisID;
+            }
+        });
+    };
 
 },{}],16:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.bubble = {
-		hover: {
-			mode: "single"
-		},
+        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"
-			}]
-		},
+            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 + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')';
-				}
-			}
-		}
-	};
+            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({
+        Chart.controllers.bubble = Chart.DatasetController.extend({
 
-		dataElementType: Chart.elements.Point,
+            dataElementType: Chart.elements.Point,
 
-		update: function(reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var points = meta.data;
+            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);
-			});
-		},
+                // 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);
+            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;
+                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,
+                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),
+                    // 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)
-				}
-			});
+                        // 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);
+                // 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));
+                var model = point._model;
+                model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));
 
-			point.pivot();
-		},
+                point.pivot();
+            },
 
-		getRadius: function(value) {
-			return value.r || this.chart.options.elements.point.radius;
-		},
+            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);
+            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]);
-		},
+                // 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);
+            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;
+                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);
-		}
-	});
-};
+                model.radius = custom.radius ? custom.radius : me.getRadius(dataVal);
+            }
+        });
+    };
 
 },{}],17:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers,
-		defaults = Chart.defaults;
+        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">');
+        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;
+                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>');
-				}
-			}
+                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);
+                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,
+                                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
-							};
-						});
-					} else {
-						return [];
-					}
-				}
-			},
+                                    // 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;
+                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;
-				}
+                    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();
-			}
-		},
+                    chart.update();
+                }
+            },
 
-		//The percentage of the chart that we cut out of the middle.
-		cutoutPercentage: 50,
+            // 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 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,
+            // 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) {
-					return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
-				}
-			}
-		}
-	};
+            // 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];
 
-	defaults.pie = helpers.clone(defaults.doughnut);
-	helpers.extend(defaults.pie, {
-		cutoutPercentage: 0
-	});
+                        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;
+                        }
 
-
-	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) : 1, 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 = me.outerRadius - chart.radiusLength;
-
-			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);
-			} else {
-				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 dataLabel;
+                    }
+                }
             }
-            return max;
-        }
-	});
-};
+        };
+
+        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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.line = {
-		showLines: true,
-		spanGaps: false,
+        Chart.defaults.line = {
+            showLines: true,
+            spanGaps: false,
 
-		hover: {
-			mode: "label"
-		},
+            hover: {
+                mode: 'label'
+            },
 
-		scales: {
-			xAxes: [{
-				type: "category",
-				id: 'x-axis-0'
-			}],
-			yAxes: [{
-				type: "linear",
-				id: 'y-axis-0'
-			}]
-		}
-	};
+            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);
-	}
+        function lineEnabled(dataset, options) {
+            return helpers.getValueOrDefault(dataset.showLine, options.showLines);
+        }
 
-	Chart.controllers.line = Chart.DatasetController.extend({
+        Chart.controllers.line = Chart.DatasetController.extend({
 
-		datasetElementType: Chart.elements.Line,
+            datasetElementType: Chart.elements.Line,
 
-		dataElementType: Chart.elements.Point,
+            dataElementType: Chart.elements.Point,
 
-		addElementAndReset: function(index) {
-			var me = this;
-			var options = me.chart.options;
-			var meta = me.getMeta();
+            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);
 
-			Chart.DatasetController.prototype.addElementAndReset.call(me, index);
+                // Update Line
+                if (showLine) {
+                    custom = line.custom || {};
 
-			// Make sure bezier control points are updated
-			if (lineEnabled(me.getDataset(), options) && meta.dataset._model.tension !== 0) {
-				me.updateBezierControlPoints();
-			}
-		},
+                    // 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;
+                    }
 
-		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);
+                    // 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),
+                    };
 
-			// Update Line
-			if (showLine) {
-				custom = line.custom || {};
+                    line.pivot();
+                }
 
-				// 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;
-				}
+                // Update Points
+                for (i=0, ilen=points.length; i<ilen; ++i) {
+                    me.updateElement(points[i], i, reset);
+                }
 
-				// 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 linse 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),
-					// Scale
-					scaleTop: scale.top,
-					scaleBottom: scale.bottom,
-					scaleZero: scale.getBasePixel()
-				};
+                if (showLine && line._model.tension !== 0) {
+                    me.updateBezierControlPoints();
+                }
 
-				line.pivot();
-			}
+                // Now pivot the point for animation
+                for (i=0, ilen=points.length; i<ilen; ++i) {
+                    points[i].pivot();
+                }
+            },
 
-			// Update Points
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				me.updateElement(points[i], i, reset);
-			}
+            getPointBackgroundColor: function(point, index) {
+                var backgroundColor = this.chart.options.elements.point.backgroundColor;
+                var dataset = this.getDataset();
+                var custom = point.custom || {};
 
-			if (showLine && line._model.tension !== 0) {
-				me.updateBezierControlPoints();
-			}
+                if (custom.backgroundColor) {
+                    backgroundColor = custom.backgroundColor;
+                } else if (dataset.pointBackgroundColor) {
+                    backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
+                } else if (dataset.backgroundColor) {
+                    backgroundColor = dataset.backgroundColor;
+                }
 
-			// Now pivot the point for animation
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				points[i].pivot();
-			}
-		},
+                return backgroundColor;
+            },
 
-		getPointBackgroundColor: function(point, index) {
-			var backgroundColor = this.chart.options.elements.point.backgroundColor;
-			var dataset = this.getDataset();
-			var custom = point.custom || {};
+            getPointBorderColor: function(point, index) {
+                var borderColor = this.chart.options.elements.point.borderColor;
+                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;
-			}
+                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 backgroundColor;
-		},
+                return borderColor;
+            },
 
-		getPointBorderColor: function(point, index) {
-			var borderColor = this.chart.options.elements.point.borderColor;
-			var dataset = this.getDataset();
-			var custom = point.custom || {};
+            getPointBorderWidth: function(point, index) {
+                var borderWidth = this.chart.options.elements.point.borderWidth;
+                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;
-			}
+                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 borderColor;
-		},
+                return borderWidth;
+            },
 
-		getPointBorderWidth: function(point, index) {
-			var borderWidth = this.chart.options.elements.point.borderWidth;
-			var dataset = this.getDataset();
-			var custom = point.custom || {};
+            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;
 
-			if (custom.borderWidth) {
-				borderWidth = custom.borderWidth;
-			} else if (dataset.pointBorderWidth) {
-				borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
-			} else if (dataset.borderWidth) {
-				borderWidth = dataset.borderWidth;
-			}
+                // 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;
+                }
 
-			return borderWidth;
-		},
+                x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);
+                y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
 
-		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;
+                // Utility
+                point._xScale = xScale;
+                point._yScale = yScale;
+                point._datasetIndex = datasetIndex;
+                point._index = 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;
-			}
+                // 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)
+                };
+            },
 
-			x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, me.chart.isCombo);
-			y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
+            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;
 
-			// Utility
-			point._xScale = xScale;
-			point._yScale = yScale;
-			point._datasetIndex = datasetIndex;
-			point._index = index;
+                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;
+                            }
+                        }
+                    }
 
-			// 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)
-			};
-		},
+                    var rightValue = Number(yScale.getRightValue(value));
+                    if (rightValue < 0) {
+                        return yScale.getPixelForValue(sumNeg + rightValue);
+                    }
+                    return yScale.getPixelForValue(sumPos + rightValue);
+                }
 
-		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;
+                return yScale.getPixelForValue(value);
+            },
 
-			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;
-						}
-					}
-				}
+            updateBezierControlPoints: function() {
+                var me = this;
+                var meta = me.getMeta();
+                var area = me.chart.chartArea;
+                var points = (meta.data || []);
+                var i, ilen, point, model, controlPoints;
 
-				var rightValue = Number(yScale.getRightValue(value));
-				if (rightValue < 0) {
-					return yScale.getPixelForValue(sumNeg + rightValue);
-				} else {
-					return yScale.getPixelForValue(sumPos + rightValue);
-				}
-			}
+                // 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;
+                    });
+                }
 
-			return yScale.getPixelForValue(value);
-		},
+                function capControlPoint(pt, min, max) {
+                    return Math.max(Math.min(pt, max), min);
+                }
 
-		updateBezierControlPoints: function() {
-			var me = this;
-			var meta = me.getMeta();
-			var area = me.chart.chartArea;
+                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;
+                    }
+                }
 
-			// only consider points that are drawn in case the spanGaps option is ued
-			var points = (meta.data || []).filter(function(pt) { return !pt._model.skip; });
-			var i, ilen, point, model, controlPoints;
+                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);
+                    }
+                }
+            },
 
-			var needToCap = me.chart.options.elements.line.capBezierPoints;
-			function capIfNecessary(pt, min, max) {
-				return needToCap ? Math.max(Math.min(pt, max), min) : pt;
-			}
+            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;
 
-			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
-				);
+                Chart.canvasHelpers.clipArea(chart.ctx, area);
 
-				model.controlPointPreviousX = capIfNecessary(controlPoints.previous.x, area.left, area.right);
-				model.controlPointPreviousY = capIfNecessary(controlPoints.previous.y, area.top, area.bottom);
-				model.controlPointNextX = capIfNecessary(controlPoints.next.x, area.left, area.right);
-				model.controlPointNextY = capIfNecessary(controlPoints.next.y, area.top, area.bottom);
-			}
-		},
+                if (lineEnabled(me.getDataset(), chart.options)) {
+                    meta.dataset.draw();
+                }
 
-		draw: function(ease) {
-			var me = this;
-			var meta = me.getMeta();
-			var points = meta.data || [];
-			var easingDecimal = ease || 1;
-			var i, ilen;
+                Chart.canvasHelpers.unclipArea(chart.ctx);
 
-			// Transition Point Locations
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				points[i].transition(easingDecimal);
-			}
+                // Draw the points
+                for (; i<ilen; ++i) {
+                    points[i].draw(area);
+                }
+            },
 
-			// Transition and Draw the line
-			if (lineEnabled(me.getDataset(), me.chart.options)) {
-				meta.dataset.transition(easingDecimal).draw();
-			}
+            setHoverStyle: function(point) {
+                // Point
+                var dataset = this.chart.data.datasets[point._datasetIndex];
+                var index = point._index;
+                var custom = point.custom || {};
+                var model = point._model;
 
-			// Draw the points
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				points[i].draw();
-			}
-		},
+                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);
+            },
 
-		setHoverStyle: function(point) {
-			// Point
-			var dataset = this.chart.data.datasets[point._datasetIndex];
-			var index = point._index;
-			var custom = point.custom || {};
-			var model = point._model;
+            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;
 
-			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);
-		},
+                // 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;
+                }
 
-		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);
-		}
-	});
-};
+                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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.polarArea = {
+        Chart.defaults.polarArea = {
 
-		scale: {
-			type: "radialLinear",
-			lineArc: true, // so that lines are circular
-			ticks: {
-				beginAtZero: true
-			}
-		},
+            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
-		},
+            // 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">');
+            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;
+                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] + '">');
-					if (labels[i]) {
-						text.push(labels[i]);
-					}
-					text.push('</span></li>');
-				}
-			}
+                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);
+                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,
+                                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
-							};
-						});
-					} else {
-						return [];
-					}
-				}
-			},
+                                    // 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;
+                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;
-				}
+                    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();
-			}
-		},
+                    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;
-				}
-			}
-		}
-	};
+            // 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({
+        Chart.controllers.polarArea = Chart.DatasetController.extend({
 
-		dataElementType: Chart.elements.Arc,
+            dataElementType: Chart.elements.Arc,
 
-		linkScales: helpers.noop,
+            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();
+            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;
+                me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
+                me.innerRadius = me.outerRadius - chart.radiusLength;
 
-			meta.count = me.countVisibleElements();
+                meta.count = me.countVisibleElements();
 
-			helpers.each(meta.data, function(arc, index) {
-				me.updateElement(arc, index, reset);
-			});
-		},
+                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;
+            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;
+                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;
-				}
-			}
+                // 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 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]);
+                var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
 
-			helpers.extend(arc, {
-				// Utility
-				_datasetIndex: me.index,
-				_index: index,
-				_scale: scale,
+                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])
-				}
-			});
+                    // 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);
+                // Apply border and fill style
+                me.removeHoverStyle(arc);
 
-			arc.pivot();
-		},
+                arc.pivot();
+            },
 
-		removeHoverStyle: function(arc) {
-			Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
-		},
+            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;
+            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++;
-				}
-			});
+                helpers.each(meta.data, function(element, index) {
+                    if (!isNaN(dataset.data[index]) && !element.hidden) {
+                        count++;
+                    }
+                });
 
-			return count;
-		},
+                return count;
+            },
 
-		calculateCircumference: function(value) {
-			var count = this.getMeta().count;
-			if (count > 0 && !isNaN(value)) {
-				return (2 * Math.PI) / count;
-			} else {
-				return 0;
-			}
-		}
-	});
-};
+            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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.radar = {
-		scale: {
-			type: "radialLinear"
-		},
-		elements: {
-			line: {
-				tension: 0 // no bezier in radar
-			}
-		}
-	};
+        Chart.defaults.radar = {
+            aspectRatio: 1,
+            scale: {
+                type: 'radialLinear'
+            },
+            elements: {
+                line: {
+                    tension: 0 // no bezier in radar
+                }
+            }
+        };
 
-	Chart.controllers.radar = Chart.DatasetController.extend({
+        Chart.controllers.radar = Chart.DatasetController.extend({
 
-		datasetElementType: Chart.elements.Line,
+            datasetElementType: Chart.elements.Line,
 
-		dataElementType: Chart.elements.Point,
+            dataElementType: Chart.elements.Point,
 
-		linkScales: helpers.noop,
+            linkScales: helpers.noop,
 
-		addElementAndReset: function(index) {
-			Chart.DatasetController.prototype.addElementAndReset.call(this, index);
+            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;
 
-			// Make sure bezier control points are updated
-			this.updateBezierControlPoints();
-		},
+                // 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;
+                }
 
-		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;
+                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),
+                    }
+                });
 
-			// 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;
-			}
+                meta.dataset.pivot();
 
-			helpers.extend(meta.dataset, {
-				// Utility
-				_datasetIndex: me.index,
-				// 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),
+                // Update Points
+                helpers.each(points, function(point, index) {
+                    me.updateElement(point, index, reset);
+                }, me);
 
-					// Scale
-					scaleTop: scale.top,
-					scaleBottom: scale.bottom,
-					scaleZero: scale.getBasePosition()
-				}
-			});
+                // 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]);
 
-			meta.dataset.pivot();
+                // 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;
+                }
 
-			// Update Points
-			helpers.each(points, function(point, index) {
-				me.updateElement(point, index, reset);
-			}, me);
+                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,
 
-			// 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]);
+                        // 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),
 
-			helpers.extend(point, {
-				// Utility
-				_datasetIndex: me.index,
-				_index: index,
-				_scale: scale,
+                        // Tooltip
+                        hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)
+                    }
+                });
 
-				// 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,
+                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();
 
-					// Appearance
-					tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, 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),
+                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
+                    );
 
-					// Tooltip
-					hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)
-				}
-			});
+                    // 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);
 
-			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();
+                    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);
 
-			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
-				);
+                    // Now pivot the point for animation
+                    point.pivot();
+                });
+            },
 
-				// 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);
+            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.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);
+                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);
+            },
 
-				// Now pivot the point for animation
-				point.pivot();
-			});
-		},
+            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;
 
-		draw: function(ease) {
-			var meta = this.getMeta();
-			var easingDecimal = ease || 1;
-
-			// Transition Point Locations
-			helpers.each(meta.data, function(point) {
-				point.transition(easingDecimal);
-			});
-
-			// Transition and Draw the line
-			meta.dataset.transition(easingDecimal).draw();
-
-			// Draw the points
-			helpers.each(meta.data, function(point) {
-				point.draw();
-			});
-		},
-
-		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.radius, 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);
-		}
-	});
-};
+                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";
+    /* global window: false */
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.animation = {
-		duration: 1000,
-		easing: "easeOutQuart",
-		onProgress: helpers.noop,
-		onComplete: helpers.noop
-	};
+        Chart.defaults.global.animation = {
+            duration: 1000,
+            easing: 'easeOutQuart',
+            onProgress: helpers.noop,
+            onComplete: helpers.noop
+        };
 
-	Chart.Animation = Chart.Element.extend({
-		currentStep: null, // 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
+        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
-	});
+            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,
-		addAnimation: function(chartInstance, animationObject, duration, lazy) {
-			var me = this;
+        Chart.animationService = {
+            frameDuration: 17,
+            animations: [],
+            dropFrames: 0,
+            request: null,
 
-			if (!lazy) {
-				chartInstance.animating = true;
-			}
+            /**
+             * @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;
 
-			for (var index = 0; index < me.animations.length; ++index) {
-				if (me.animations[index].chartInstance === chartInstance) {
-					// replacing an in progress animation
-					me.animations[index].animationObject = animationObject;
-					return;
-				}
-			}
+                animation.chart = chart;
 
-			me.animations.push({
-				chartInstance: chartInstance,
-				animationObject: animationObject
-			});
+                if (!lazy) {
+                    chart.animating = true;
+                }
 
-			// If there are no animations queued, manually kickstart a digest, for lack of a better word
-			if (me.animations.length === 1) {
-				me.requestAnimationFrame();
-			}
-		},
-		// Cancel the animation for a given chart instance
-		cancelAnimation: function(chartInstance) {
-			var index = helpers.findIndex(this.animations, function(animationWrapper) {
-				return animationWrapper.chartInstance === chartInstance;
-			});
+                for (i=0, ilen=animations.length; i < ilen; ++i) {
+                    if (animations[i].chart === chart) {
+                        animations[i] = animation;
+                        return;
+                    }
+                }
 
-			if (index !== -1) {
-				this.animations.splice(index, 1);
-				chartInstance.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();
-				});
-			}
-		},
-		startDigest: function() {
-			var me = this;
+                animations.push(animation);
 
-			var startTime = Date.now();
-			var framesToDrop = 0;
+                // If there are no animations queued, manually kickstart a digest, for lack of a better word
+                if (animations.length === 1) {
+                    this.requestAnimationFrame();
+                }
+            },
 
-			if (me.dropFrames > 1) {
-				framesToDrop = Math.floor(me.dropFrames);
-				me.dropFrames = me.dropFrames % 1;
-			}
+            cancelAnimation: function(chart) {
+                var index = helpers.findIndex(this.animations, function(animation) {
+                    return animation.chart === chart;
+                });
 
-			var i = 0;
-			while (i < me.animations.length) {
-				if (me.animations[i].animationObject.currentStep === null) {
-					me.animations[i].animationObject.currentStep = 0;
-				}
+                if (index !== -1) {
+                    this.animations.splice(index, 1);
+                    chart.animating = false;
+                }
+            },
 
-				me.animations[i].animationObject.currentStep += 1 + framesToDrop;
+            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();
+                    });
+                }
+            },
 
-				if (me.animations[i].animationObject.currentStep > me.animations[i].animationObject.numSteps) {
-					me.animations[i].animationObject.currentStep = me.animations[i].animationObject.numSteps;
-				}
+            /**
+             * @private
+             */
+            startDigest: function() {
+                var me = this;
+                var startTime = Date.now();
+                var framesToDrop = 0;
 
-				me.animations[i].animationObject.render(me.animations[i].chartInstance, me.animations[i].animationObject);
-				if (me.animations[i].animationObject.onAnimationProgress && me.animations[i].animationObject.onAnimationProgress.call) {
-					me.animations[i].animationObject.onAnimationProgress.call(me.animations[i].chartInstance, me.animations[i]);
-				}
+                if (me.dropFrames > 1) {
+                    framesToDrop = Math.floor(me.dropFrames);
+                    me.dropFrames = me.dropFrames % 1;
+                }
 
-				if (me.animations[i].animationObject.currentStep === me.animations[i].animationObject.numSteps) {
-					if (me.animations[i].animationObject.onAnimationComplete && me.animations[i].animationObject.onAnimationComplete.call) {
-						me.animations[i].animationObject.onAnimationComplete.call(me.animations[i].chartInstance, me.animations[i]);
-					}
+                me.advance(1 + framesToDrop);
 
-					// executed the last frame. Remove the animation.
-					me.animations[i].chartInstance.animating = false;
+                var endTime = Date.now();
 
-					me.animations.splice(i, 1);
-				} else {
-					++i;
-				}
-			}
+                me.dropFrames += (endTime - startTime) / me.frameDuration;
 
-			var endTime = Date.now();
-			var dropFrames = (endTime - startTime) / me.frameDuration;
+                // Do we have more stuff to animate?
+                if (me.animations.length > 0) {
+                    me.requestAnimationFrame();
+                }
+            },
 
-			me.dropFrames += dropFrames;
+            /**
+             * @private
+             */
+            advance: function(count) {
+                var animations = this.animations;
+                var animation, chart;
+                var i = 0;
 
-			// Do we have more stuff to animate?
-			if (me.animations.length > 0) {
-				me.requestAnimationFrame();
-			}
-		}
-	};
-};
+                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";
+    'use strict';
 
-module.exports = function(Chart) {
-	// Global Chart canvas helpers object for drawing items to canvas
-	var helpers = Chart.canvasHelpers = {};
+    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;
+        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);
-				return;
-			}
-		}
+            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;
-		}
+            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 '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;
-		}
+            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();
-	};
-};
+            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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	//Create a dictionary of chart types, to allow for extension of existing types
-	Chart.types = {};
+        var helpers = Chart.helpers;
+        var plugins = Chart.plugins;
+        var platform = Chart.platform;
 
-	//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 = {};
+        // Create a dictionary of chart types, to allow for extension of existing types
+        Chart.types = {};
 
-	// Controllers available for dataset visualization eg. bar, line, slice, etc.
-	Chart.controllers = {};
+        // 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 = {};
 
-	/**
-	 * @class Chart.Controller
-	 * The main controller of a chart.
-	 */
-	Chart.Controller = function(instance) {
+        // Controllers available for dataset visualization eg. bar, line, slice, etc.
+        Chart.controllers = {};
 
-		this.chart = instance;
-		this.config = instance.config;
-		this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});
-		this.id = helpers.uid();
+        /**
+         * Initializes the given config with global and chart default values.
+         */
+        function initConfig(config) {
+            config = config || {};
 
-		Object.defineProperty(this, 'data', {
-			get: function() {
-				return this.config.data;
-			}
-		});
+            // 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 || [];
 
-		//Add the chart instance to the global namespace
-		Chart.instances[this.id] = this;
+            config.options = helpers.configMerge(
+                Chart.defaults.global,
+                Chart.defaults[config.type],
+                config.options || {});
 
-		if (this.options.responsive) {
-			// Silent resize before chart draws
-			this.resize(true);
-		}
+            return config;
+        }
 
-		this.initialize();
+        /**
+         * Updates the config of the chart
+         * @param chart {Chart} chart to update the options for
+         */
+        function updateConfig(chart) {
+            var newOptions = chart.options;
 
-		return this;
-	};
+            // 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;
+                });
+            }
 
-	helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ {
+            // Tooltip
+            chart.tooltip._options = newOptions.tooltips;
+        }
 
-		initialize: function() {
-			var me = this;
-			// Before init plugin notification
-			Chart.plugins.notify('beforeInit', [me]);
+        function positionIsHorizontal(position) {
+            return position === 'top' || position === 'bottom';
+        }
 
-			me.bindEvents();
+        helpers.extend(Chart.prototype, /** @lends Chart */ {
+            /**
+             * @private
+             */
+            construct: function(item, config) {
+                var me = this;
 
-			// Make sure controllers are built first so that each dataset is bound to an axis before the scales
-			// are built
-			me.ensureScalesHaveIDs();
-			me.buildOrUpdateControllers();
-			me.buildScales();
-			me.updateLayout();
-			me.resetElements();
-			me.initToolTip();
-			me.update();
+                config = initConfig(config);
 
-			// After init plugin notification
-			Chart.plugins.notify('afterInit', [me]);
+                var context = platform.acquireContext(item, config);
+                var canvas = context && context.canvas;
+                var height = canvas && canvas.height;
+                var width = canvas && canvas.width;
 
-			return me;
-		},
+                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;
 
-		clear: function() {
-			helpers.clear(this.chart);
-			return this;
-		},
+                /**
+                 * 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
 
-		stop: function() {
-			// Stops any current animation loop occuring
-			Chart.animationService.cancelAnimation(this);
-			return this;
-		},
+                // Add the chart instance to the global namespace
+                Chart.instances[me.id] = me;
 
-		resize: function resize(silent) {
-			var me = this;
-			var chart = me.chart;
-			var canvas = chart.canvas;
-			var newWidth = helpers.getMaximumWidth(canvas);
-			var aspectRatio = chart.aspectRatio;
-			var newHeight = (me.options.maintainAspectRatio && isNaN(aspectRatio) === false && isFinite(aspectRatio) && aspectRatio !== 0) ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas);
+                // 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;
+                    }
+                });
 
-			var sizeChanged = chart.width !== newWidth || chart.height !== newHeight;
+                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;
+                }
 
-			if (!sizeChanged) {
-				return me;
-			}
+                me.initialize();
+                me.update();
+            },
 
-			canvas.width = chart.width = newWidth;
-			canvas.height = chart.height = newHeight;
+            /**
+             * @private
+             */
+            initialize: function() {
+                var me = this;
 
-			helpers.retinaScale(chart);
+                // Before init plugin notification
+                plugins.notify(me, 'beforeInit');
 
-			// Notify any plugins about the resize
-			var newSize = { width: newWidth, height: newHeight };
-			Chart.plugins.notify('resize', [me, newSize]);
+                helpers.retinaScale(me);
 
-			// Notify of resize
-			if (me.options.onResize) {
-				me.options.onResize(me, newSize);
-			}
+                me.bindEvents();
 
-			if (!silent) {
-				me.stop();
-				me.update(me.options.responsiveAnimationDuration);
-			}
+                if (me.options.responsive) {
+                    // Initial resize before chart draws (must be silent to preserve initial animations).
+                    me.resize(true);
+                }
 
-			return me;
-		},
+                // Make sure scales have IDs and are built before we build any controllers.
+                me.ensureScalesHaveIDs();
+                me.buildScales();
+                me.initToolTip();
 
-		ensureScalesHaveIDs: function() {
-			var options = this.options;
-			var scalesOptions = options.scales || {};
-			var scaleOptions = options.scale;
+                // After init plugin notification
+                plugins.notify(me, 'afterInit');
 
-			helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
-				xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
-			});
+                return me;
+            },
 
-			helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
-				yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
-			});
+            clear: function() {
+                helpers.clear(this);
+                return this;
+            },
 
-			if (scaleOptions) {
-				scaleOptions.id = scaleOptions.id || 'scale';
-			}
-		},
+            stop: function() {
+                // Stops any current animation loop occurring
+                Chart.animationService.cancelAnimation(this);
+                return this;
+            },
 
-		/**
-		 * 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 = [];
+            resize: function(silent) {
+                var me = this;
+                var options = me.options;
+                var canvas = me.canvas;
+                var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
 
-			if (options.scales) {
-				items = items.concat(
-					(options.scales.xAxes || []).map(function(xAxisOptions) {
-						return { options: xAxisOptions, dtype: 'category' }; }),
-					(options.scales.yAxes || []).map(function(yAxisOptions) {
-						return { options: yAxisOptions, dtype: 'linear' }; }));
-			}
+                // 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 (options.scale) {
-				items.push({ options: options.scale, dtype: 'radialLinear', isDefault: true });
-			}
+                if (me.width === newWidth && me.height === newHeight) {
+                    return;
+                }
 
-			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;
-				}
+                canvas.width = me.width = newWidth;
+                canvas.height = me.height = newHeight;
+                canvas.style.width = newWidth + 'px';
+                canvas.style.height = newHeight + 'px';
 
-				var scale = new scaleClass({
-					id: scaleOptions.id,
-					options: scaleOptions,
-					ctx: me.chart.ctx,
-					chart: me
-				});
+                helpers.retinaScale(me);
 
-				scales[scale.id] = scale;
+                if (!silent) {
+                    // Notify any plugins about the resize
+                    var newSize = {width: newWidth, height: newHeight};
+                    plugins.notify(me, 'resize', [newSize]);
 
-				// 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;
-				}
-			});
+                    // Notify of resize
+                    if (me.options.onResize) {
+                        me.options.onResize(me, newSize);
+                    }
 
-			Chart.scaleService.addScalesToLayout(this);
-		},
+                    me.stop();
+                    me.update(me.options.responsiveAnimationDuration);
+                }
+            },
 
-		updateLayout: function() {
-			Chart.layoutService.update(this, this.chart.width, this.chart.height);
-		},
+            ensureScalesHaveIDs: function() {
+                var options = this.options;
+                var scalesOptions = options.scales || {};
+                var scaleOptions = options.scale;
 
-		buildOrUpdateControllers: function() {
-			var me = this;
-			var types = [];
-			var newControllers = [];
+                helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
+                    xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
+                });
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				var meta = me.getDatasetMeta(datasetIndex);
-				if (!meta.type) {
-					meta.type = dataset.type || me.config.type;
-				}
+                helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
+                    yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
+                });
 
-				types.push(meta.type);
+                if (scaleOptions) {
+                    scaleOptions.id = scaleOptions.id || 'scale';
+                }
+            },
 
-				if (meta.controller) {
-					meta.controller.updateIndex(datasetIndex);
-				} else {
-					meta.controller = new Chart.controllers[meta.type](me, datasetIndex);
-					newControllers.push(meta.controller);
-				}
-			}, me);
+            /**
+             * 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 (types.length > 1) {
-				for (var i = 1; i < types.length; i++) {
-					if (types[i] !== types[i - 1]) {
-						me.isCombo = true;
-						break;
-					}
-				}
-			}
+                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'};
+                        })
+                    );
+                }
 
-			return newControllers;
-		},
+                if (options.scale) {
+                    items.push({
+                        options: options.scale,
+                        dtype: 'radialLinear',
+                        isDefault: true,
+                        dposition: 'chartArea'
+                    });
+                }
 
-		resetElements: function() {
-			var me = this;
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				me.getDatasetMeta(datasetIndex).controller.reset();
-			}, me);
-		},
+                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;
+                    }
 
-		update: function update(animationDuration, lazy) {
-			var me = this;
-			Chart.plugins.notify('beforeUpdate', [me]);
+                    if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
+                        scaleOptions.position = item.dposition;
+                    }
 
-			// In case the entire data object changed
-			me.tooltip._data = me.data;
+                    var scale = new scaleClass({
+                        id: scaleOptions.id,
+                        options: scaleOptions,
+                        ctx: me.ctx,
+                        chart: me
+                    });
 
-			// Make sure dataset controllers are updated and new controllers are reset
-			var newControllers = me.buildOrUpdateControllers();
+                    scales[scale.id] = scale;
 
-			// Make sure all dataset controllers have correct meta data counts
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
-			}, me);
+                    // 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.layoutService.update(me, me.chart.width, me.chart.height);
+                Chart.scaleService.addScalesToLayout(this);
+            },
 
-			// Apply changes to the dataets that require the scales to have been calculated i.e BorderColor chages
-			Chart.plugins.notify('afterScaleUpdate', [me]);
+            buildOrUpdateControllers: function() {
+                var me = this;
+                var types = [];
+                var newControllers = [];
 
-			// Can only reset the new controllers after the scales have been updated
-			helpers.each(newControllers, function(controller) {
-				controller.reset();
-			});
+                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+                    var meta = me.getDatasetMeta(datasetIndex);
+                    if (!meta.type) {
+                        meta.type = dataset.type || me.config.type;
+                    }
 
-			me.updateDatasets();
+                    types.push(meta.type);
 
-			// Do this before render so that any plugins that need final scale updates can use it
-			Chart.plugins.notify('afterUpdate', [me]);
+                    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.');
+                        }
 
-			me.render(animationDuration, lazy);
-		},
+                        meta.controller = new ControllerClass(me, datasetIndex);
+                        newControllers.push(meta.controller);
+                    }
+                }, me);
 
-		/**
-		 * @method beforeDatasetsUpdate
-		 * @description Called before all datasets are updated. If a plugin returns false,
-		 * the datasets update will be cancelled until another chart update is triggered.
-		 * @param {Object} instance the chart instance being updated.
-		 * @returns {Boolean} false to cancel the datasets update.
-		 * @memberof Chart.PluginBase
-		 * @since version 2.1.5
-		 * @instance
-		 */
+                if (types.length > 1) {
+                    for (var i = 1; i < types.length; i++) {
+                        if (types[i] !== types[i - 1]) {
+                            me.isCombo = true;
+                            break;
+                        }
+                    }
+                }
 
-		/**
-		 * @method afterDatasetsUpdate
-		 * @description Called after all datasets have been updated. Note that this
-		 * extension will not be called if the datasets update has been cancelled.
-		 * @param {Object} instance the chart instance being updated.
-		 * @memberof Chart.PluginBase
-		 * @since version 2.1.5
-		 * @instance
-		 */
+                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;
+                }
 
-		/**
-		 * Updates all datasets unless a plugin returns false to the beforeDatasetsUpdate
-		 * extension, in which case no datasets will be updated and the afterDatasetsUpdate
-		 * notification will be skipped.
-		 * @protected
-		 * @instance
-		 */
-		updateDatasets: function() {
-			var me = this;
-			var i, ilen;
+                me.transition(easingValue);
 
-			if (Chart.plugins.notify('beforeDatasetsUpdate', [ me ])) {
-				for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
-					me.getDatasetMeta(i).controller.update();
-				}
+                if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {
+                    return;
+                }
 
-				Chart.plugins.notify('afterDatasetsUpdate', [ me ]);
-			}
-		},
+                // Draw all the scales
+                helpers.each(me.boxes, function(box) {
+                    box.draw(me.chartArea);
+                }, me);
 
-		render: function render(duration, lazy) {
-			var me = this;
-			Chart.plugins.notify('beforeRender', [me]);
+                if (me.scale) {
+                    me.scale.draw();
+                }
 
-			var animationOptions = me.options.animation;
-			if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {
-				var animation = new Chart.Animation();
-				animation.numSteps = (duration || animationOptions.duration) / 16.66; //60 fps
-				animation.easing = animationOptions.easing;
+                me.drawDatasets(easingValue);
 
-				// render function
-				animation.render = function(chartInstance, animationObject) {
-					var easingFunction = helpers.easingEffects[animationObject.easing];
-					var stepDecimal = animationObject.currentStep / animationObject.numSteps;
-					var easeDecimal = easingFunction(stepDecimal);
+                // Finally draw the tooltip
+                me.tooltip.draw();
 
-					chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);
-				};
+                plugins.notify(me, 'afterDraw', [easingValue]);
+            },
 
-				// user events
-				animation.onAnimationProgress = animationOptions.onProgress;
-				animation.onAnimationComplete = animationOptions.onComplete;
+            /**
+             * @private
+             */
+            transition: function(easingValue) {
+                var me = this;
 
-				Chart.animationService.addAnimation(me, animation, duration, lazy);
-			} else {
-				me.draw();
-				if (animationOptions && animationOptions.onComplete && animationOptions.onComplete.call) {
-					animationOptions.onComplete.call(me);
-				}
-			}
-			return me;
-		},
+                for (var i=0, ilen=(me.data.datasets || []).length; i<ilen; ++i) {
+                    if (me.isDatasetVisible(i)) {
+                        me.getDatasetMeta(i).controller.transition(easingValue);
+                    }
+                }
 
-		draw: function(ease) {
-			var me = this;
-			var easingDecimal = ease || 1;
-			me.clear();
+                me.tooltip.transition(easingValue);
+            },
 
-			Chart.plugins.notify('beforeDraw', [me, easingDecimal]);
+            /**
+             * 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;
 
-			// Draw all the scales
-			helpers.each(me.boxes, function(box) {
-				box.draw(me.chartArea);
-			}, me);
-			if (me.scale) {
-				me.scale.draw();
-			}
+                if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
+                    return;
+                }
 
-			Chart.plugins.notify('beforeDatasetsDraw', [me, easingDecimal]);
+                // 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);
+                    }
+                }
 
-			// Draw each dataset via its respective controller (reversed to support proper line stacking)
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					me.getDatasetMeta(datasetIndex).controller.draw(ease);
-				}
-			}, me, true);
+                plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
+            },
 
-			Chart.plugins.notify('afterDatasetsDraw', [me, easingDecimal]);
+            /**
+             * 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
+                };
 
-			// Finally draw the tooltip
-			me.tooltip.transition(easingDecimal).draw();
+                if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {
+                    return;
+                }
 
-			Chart.plugins.notify('afterDraw', [me, easingDecimal]);
-		},
+                meta.controller.draw(easingValue);
 
-		// 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) {
-			var me = this;
-			var eventPosition = helpers.getRelativePosition(e, me.chart);
-			var elementsArray = [];
+                plugins.notify(me, 'afterDatasetDraw', [args]);
+            },
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					var meta = me.getDatasetMeta(datasetIndex);
-					helpers.each(meta.data, function(element) {
-						if (element.inRange(eventPosition.x, eventPosition.y)) {
-							elementsArray.push(element);
-							return elementsArray;
-						}
-					});
-				}
-			});
+            // 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);
+            },
 
-			return elementsArray.slice(0, 1);
-		},
+            getElementsAtEvent: function(e) {
+                return Chart.Interaction.modes.label(this, e, {intersect: true});
+            },
 
-		getElementsAtEvent: function(e) {
-			var me = this;
-			var eventPosition = helpers.getRelativePosition(e, me.chart);
-			var elementsArray = [];
+            getElementsAtXAxis: function(e) {
+                return Chart.Interaction.modes['x-axis'](this, e, {intersect: true});
+            },
 
-			var found = (function() {
-				if (me.data.datasets) {
-					for (var i = 0; i < me.data.datasets.length; i++) {
-						var meta = me.getDatasetMeta(i);
-						if (me.isDatasetVisible(i)) {
-							for (var j = 0; j < meta.data.length; j++) {
-								if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) {
-									return meta.data[j];
-								}
-							}
-						}
-					}
-				}
-			}).call(me);
+            getElementsAtEventForMode: function(e, mode, options) {
+                var method = Chart.Interaction.modes[mode];
+                if (typeof method === 'function') {
+                    return method(this, e, options);
+                }
 
-			if (!found) {
-				return elementsArray;
-			}
+                return [];
+            },
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					var meta = me.getDatasetMeta(datasetIndex),
-						element = meta.data[found._index];
-					if(element && !element._view.skip){
-						elementsArray.push(element);
-					}
-				}
-			}, me);
+            getDatasetAtEvent: function(e) {
+                return Chart.Interaction.modes.dataset(this, e, {intersect: true});
+            },
 
-			return elementsArray;
-		},
+            getDatasetMeta: function(datasetIndex) {
+                var me = this;
+                var dataset = me.data.datasets[datasetIndex];
+                if (!dataset._meta) {
+                    dataset._meta = {};
+                }
 
-		getElementsAtXAxis: function(e) {
-			var me = this;
-			var eventPosition = helpers.getRelativePosition(e, me.chart);
-			var elementsArray = [];
+                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
+                    };
+                }
 
-			var found = (function() {
-				if (me.data.datasets) {
-					for (var i = 0; i < me.data.datasets.length; i++) {
-						var meta = me.getDatasetMeta(i);
-						if (me.isDatasetVisible(i)) {
-							for (var j = 0; j < meta.data.length; j++) {
-								if (meta.data[j].inLabelRange(eventPosition.x, eventPosition.y)) {
-									return meta.data[j];
-								}
-							}
-						}
-					}
-				}
-			}).call(me);
+                return meta;
+            },
 
-			if (!found) {
-				return elementsArray;
-			}
+            getVisibleDatasetCount: function() {
+                var count = 0;
+                for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {
+                    if (this.isDatasetVisible(i)) {
+                        count++;
+                    }
+                }
+                return count;
+            },
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					var meta = me.getDatasetMeta(datasetIndex);
-					var index = helpers.findIndex(meta.data, function (it) {
-						return found._model.x === it._model.x;
-					});
-					if(index !== -1 && !meta.data[index]._view.skip) {
-						elementsArray.push(meta.data[index]);
-					}
-				}
-			}, me);
+            isDatasetVisible: function(datasetIndex) {
+                var meta = this.getDatasetMeta(datasetIndex);
 
-			return elementsArray;
-		},		
+                // 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;
+            },
 
-		getElementsAtEventForMode: function(e, mode) {
-			var me = this;
-			switch (mode) {
-			case 'single':
-				return me.getElementAtEvent(e);
-			case 'label':
-				return me.getElementsAtEvent(e);
-			case 'dataset':
-				return me.getDatasetAtEvent(e);
-            case 'x-axis':
-                return me.getElementsAtXAxis(e);
-			default:
-				return e;
-			}
-		},
+            generateLegend: function() {
+                return this.options.legendCallback(this);
+            },
 
-		getDatasetAtEvent: function(e) {
-			var elementsArray = this.getElementAtEvent(e);
+            destroy: function() {
+                var me = this;
+                var canvas = me.canvas;
+                var meta, i, ilen;
 
-			if (elementsArray.length > 0) {
-				elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data;
-			}
+                me.stop();
 
-			return elementsArray;
-		},
+                // 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;
+                    }
+                }
 
-		getDatasetMeta: function(datasetIndex) {
-			var me = this;
-			var dataset = me.data.datasets[datasetIndex];
-			if (!dataset._meta) {
-				dataset._meta = {};
-			}
+                if (canvas) {
+                    me.unbindEvents();
+                    helpers.clear(me);
+                    platform.releaseContext(me.ctx);
+                    me.canvas = null;
+                    me.ctx = null;
+                }
 
-			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
-			};
-			}
+                plugins.notify(me, 'destroy');
 
-			return meta;
-		},
+                delete Chart.instances[me.id];
+            },
 
-		getVisibleDatasetCount: function() {
-			var count = 0;
-			for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {
-				 if (this.isDatasetVisible(i)) {
-					count++;
-				}
-			}
-			return count;
-		},
+            toBase64Image: function() {
+                return this.canvas.toDataURL.apply(this.canvas, arguments);
+            },
 
-		isDatasetVisible: function(datasetIndex) {
-			var meta = this.getDatasetMeta(datasetIndex);
+            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();
+            },
 
-			// 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;
-		},
+            /**
+             * @private
+             */
+            bindEvents: function() {
+                var me = this;
+                var listeners = me._listeners = {};
+                var listener = function() {
+                    me.eventHandler.apply(me, arguments);
+                };
 
-		generateLegend: function() {
-			return this.options.legendCallback(this);
-		},
+                helpers.each(me.options.events, function(type) {
+                    platform.addEventListener(me, type, listener);
+                    listeners[type] = listener;
+                });
 
-		destroy: function() {
-			var me = this;
-			me.stop();
-			me.clear();
-			helpers.unbindEvents(me, me.events);
-			helpers.removeResizeListener(me.chart.canvas.parentNode);
+                // 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();
+                    };
 
-			// Reset canvas height/width attributes
-			var canvas = me.chart.canvas;
-			canvas.width = me.chart.width;
-			canvas.height = me.chart.height;
+                    platform.addEventListener(me, 'resize', listener);
+                    listeners.resize = listener;
+                }
+            },
 
-			// if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here
-			if (me.chart.originalDevicePixelRatio !== undefined) {
-				me.chart.ctx.scale(1 / me.chart.originalDevicePixelRatio, 1 / me.chart.originalDevicePixelRatio);
-			}
+            /**
+             * @private
+             */
+            unbindEvents: function() {
+                var me = this;
+                var listeners = me._listeners;
+                if (!listeners) {
+                    return;
+                }
 
-			// Reset to the old style since it may have been changed by the device pixel ratio changes
-			canvas.style.width = me.chart.originalCanvasStyleWidth;
-			canvas.style.height = me.chart.originalCanvasStyleHeight;
+                delete me._listeners;
+                helpers.each(listeners, function(listener, type) {
+                    platform.removeEventListener(me, type, listener);
+                });
+            },
 
-			Chart.plugins.notify('destroy', [me]);
+            updateHoverStyle: function(elements, mode, enabled) {
+                var method = enabled? 'setHoverStyle' : 'removeHoverStyle';
+                var element, i, ilen;
 
-			delete Chart.instances[me.id];
-		},
+                for (i=0, ilen=elements.length; i<ilen; ++i) {
+                    element = elements[i];
+                    if (element) {
+                        this.getDatasetMeta(element._datasetIndex).controller[method](element);
+                    }
+                }
+            },
 
-		toBase64Image: function() {
-			return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
-		},
+            /**
+             * @private
+             */
+            eventHandler: function(e) {
+                var me = this;
+                var tooltip = me.tooltip;
 
-		initToolTip: function() {
-			var me = this;
-			me.tooltip = new Chart.Tooltip({
-				_chart: me.chart,
-				_chartInstance: me,
-				_data: me.data,
-				_options: me.options.tooltips
-			}, me);
-		},
+                if (plugins.notify(me, 'beforeEvent', [e]) === false) {
+                    return;
+                }
 
-		bindEvents: function() {
-			var me = this;
-			helpers.bindEvents(me, me.options.events, function(evt) {
-				me.eventHandler(evt);
-			});
-		},
+                // Buffer any update calls so that renders do not occur
+                me._bufferedRender = true;
+                me._bufferedRequest = null;
 
-		updateHoverStyle: function(elements, mode, enabled) {
-			var method = enabled? 'setHoverStyle' : 'removeHoverStyle';
-			var element, i, ilen;
+                var changed = me.handleEvent(e);
+                changed |= tooltip && tooltip.handleEvent(e);
 
-			switch (mode) {
-			case 'single':
-				elements = [ elements[0] ];
-				break;
-			case 'label':
-			case 'dataset':
-            case 'x-axis':
-				// elements = elements;
-				break;
-			default:
-				// unsupported mode
-				return;
-			}
+                plugins.notify(me, 'afterEvent', [e]);
 
-			for (i=0, ilen=elements.length; i<ilen; ++i) {
-				element = elements[i];
-				if (element) {
-					this.getDatasetMeta(element._datasetIndex).controller[method](element);
-				}
-			}
-		},
+                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();
 
-		eventHandler: function eventHandler(e) {
-			var me = this;
-			var tooltip = me.tooltip;
-			var options = me.options || {};
-			var hoverOptions = options.hover;
-			var tooltipsOptions = options.tooltips;
+                    // 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.lastActive = me.lastActive || [];
-			me.lastTooltipActive = me.lastTooltipActive || [];
+                me._bufferedRender = false;
+                me._bufferedRequest = null;
 
-			// Find Active Elements for hover and tooltips
-			if (e.type === 'mouseout') {
-				me.active = [];
-				me.tooltipActive = [];
-			} else {
-				me.active = me.getElementsAtEventForMode(e, hoverOptions.mode);
-				me.tooltipActive =  me.getElementsAtEventForMode(e, tooltipsOptions.mode);
-			}
+                return me;
+            },
 
-			// On Hover hook
-			if (hoverOptions.onHover) {
-				hoverOptions.onHover.call(me, me.active);
-			}
+            /**
+             * 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;
 
-			if (e.type === 'mouseup' || e.type === 'click') {
-				if (options.onClick) {
-					options.onClick.call(me, e, me.active);
-				}
-				if (me.legend && me.legend.handleEvent) {
-					me.legend.handleEvent(e);
-				}
-			}
+                me.lastActive = me.lastActive || [];
 
-			// Remove styling for last active (even if it may still be active)
-			if (me.lastActive.length) {
-				me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
-			}
+                // Find Active Elements for hover and tooltips
+                if (e.type === 'mouseout') {
+                    me.active = [];
+                } else {
+                    me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
+                }
 
-			// Built in hover styling
-			if (me.active.length && hoverOptions.mode) {
-				me.updateHoverStyle(me.active, hoverOptions.mode, true);
-			}
+                // 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);
+                }
 
-			// Built in Tooltips
-			if (tooltipsOptions.enabled || tooltipsOptions.custom) {
-				tooltip.initialize();
-				tooltip._active = me.tooltipActive;
-				tooltip.update(true);
-			}
+                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);
+                    }
+                }
 
-			// Hover animations
-			tooltip.pivot();
+                // Remove styling for last active (even if it may still be active)
+                if (me.lastActive.length) {
+                    me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
+                }
 
-			if (!me.animating) {
-				// If entering, leaving, or changing elements, animate the change via pivot
-				if (!helpers.arrayEquals(me.active, me.lastActive) ||
-					!helpers.arrayEquals(me.tooltipActive, me.lastTooltipActive)) {
+                // Built in hover styling
+                if (me.active.length && hoverOptions.mode) {
+                    me.updateHoverStyle(me.active, hoverOptions.mode, true);
+                }
 
-					me.stop();
+                changed = !helpers.arrayEquals(me.active, me.lastActive);
 
-					if (tooltipsOptions.enabled || tooltipsOptions.custom) {
-						tooltip.update(true);
-					}
+                // Remember Last Actives
+                me.lastActive = me.active;
 
-					// We only need to render at this point. Updating will cause scales to be
-					// recomputed generating flicker & using more memory than necessary.
-					me.render(hoverOptions.animationDuration, true);
-				}
-			}
+                return changed;
+            }
+        });
 
-			// Remember Last Actives
-			me.lastActive = me.active;
-			me.lastTooltipActive = me.tooltipActive;
-			return me;
-		}
-	});
-};
+        /**
+         * 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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var noop = helpers.noop;
+        var helpers = Chart.helpers;
 
-	// Base class for all dataset controllers (line, bar, etc)
-	Chart.DatasetController = function(chart, datasetIndex) {
-		this.initialize.call(this, chart, datasetIndex);
-	};
+        var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
 
-	helpers.extend(Chart.DatasetController.prototype, {
+        /**
+         * 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;
+            }
 
-		/**
-		 * Element type used to generate a meta dataset (e.g. Chart.element.Line).
-		 * @type {Chart.core.element}
-		 */
-		datasetElementType: null,
+            Object.defineProperty(array, '_chartjs', {
+                configurable: true,
+                enumerable: false,
+                value: {
+                    listeners: [listener]
+                }
+            });
 
-		/**
-		 * Element type used to generate a meta data (e.g. Chart.element.Point).
-		 * @type {Chart.core.element}
-		 */
-		dataElementType: null,
+            arrayEvents.forEach(function(key) {
+                var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
+                var base = array[key];
 
-		initialize: function(chart, datasetIndex) {
-			var me = this;
-			me.chart = chart;
-			me.index = datasetIndex;
-			me.linkScales();
-			me.addElements();
-		},
+                Object.defineProperty(array, key, {
+                    configurable: true,
+                    enumerable: false,
+                    value: function() {
+                        var args = Array.prototype.slice.call(arguments);
+                        var res = base.apply(this, args);
 
-		updateIndex: function(datasetIndex) {
-			this.index = datasetIndex;
-		},
+                        helpers.each(array._chartjs.listeners, function(object) {
+                            if (typeof object[method] === 'function') {
+                                object[method].apply(object, args);
+                            }
+                        });
 
-		linkScales: function() {
-			var me = this;
-			var meta = me.getMeta();
-			var dataset = me.getDataset();
+                        return res;
+                    }
+                });
+            });
+        }
 
-			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;
-			}
-		},
+        /**
+         * 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;
+            }
 
-		getDataset: function() {
-			return this.chart.data.datasets[this.index];
-		},
+            var listeners = stub.listeners;
+            var index = listeners.indexOf(listener);
+            if (index !== -1) {
+                listeners.splice(index, 1);
+            }
 
-		getMeta: function() {
-			return this.chart.getDatasetMeta(this.index);
-		},
+            if (listeners.length > 0) {
+                return;
+            }
 
-		getScaleForId: function(scaleID) {
-			return this.chart.scales[scaleID];
-		},
+            arrayEvents.forEach(function(key) {
+                delete array[key];
+            });
 
-		reset: function() {
-			this.update(true);
-		},
+            delete array._chartjs;
+        }
 
-		createMetaDataset: function() {
-			var me = this;
-			var type = me.datasetElementType;
-			return type && new type({
-				_chart: me.chart.chart,
-				_datasetIndex: me.index
-			});
-		},
+        // Base class for all dataset controllers (line, bar, etc)
+        Chart.DatasetController = function(chart, datasetIndex) {
+            this.initialize(chart, datasetIndex);
+        };
 
-		createMetaData: function(index) {
-			var me = this;
-			var type = me.dataElementType;
-			return type && new type({
-				_chart: me.chart.chart,
-				_datasetIndex: me.index,
-				_index: index
-			});
-		},
+        helpers.extend(Chart.DatasetController.prototype, {
 
-		addElements: function() {
-			var me = this;
-			var meta = me.getMeta();
-			var data = me.getDataset().data || [];
-			var metaData = meta.data;
-			var i, ilen;
+            /**
+             * Element type used to generate a meta dataset (e.g. Chart.element.Line).
+             * @type {Chart.core.element}
+             */
+            datasetElementType: null,
 
-			for (i=0, ilen=data.length; i<ilen; ++i) {
-				metaData[i] = metaData[i] || me.createMetaData(meta, i);
-			}
+            /**
+             * Element type used to generate a meta data (e.g. Chart.element.Point).
+             * @type {Chart.core.element}
+             */
+            dataElementType: null,
 
-			meta.dataset = meta.dataset || me.createMetaDataset();
-		},
+            initialize: function(chart, datasetIndex) {
+                var me = this;
+                me.chart = chart;
+                me.index = datasetIndex;
+                me.linkScales();
+                me.addElements();
+            },
 
-		addElementAndReset: function(index) {
-			var me = this;
-			var element = me.createMetaData(index);
-			me.getMeta().data.splice(index, 0, element);
-			me.updateElement(element, index, true);
-		},
+            updateIndex: function(datasetIndex) {
+                this.index = datasetIndex;
+            },
 
-		buildOrUpdateElements: function() {
-			// Handle the number of data points changing
-			var meta = this.getMeta(),
-				md = meta.data,
-				numData = this.getDataset().data.length,
-				numMetaData = md.length;
+            linkScales: function() {
+                var me = this;
+                var meta = me.getMeta();
+                var dataset = me.getDataset();
 
-			// Make sure that we handle number of datapoints changing
-			if (numData < numMetaData) {
-				// Remove excess bars for data points that have been removed
-				md.splice(numData, numMetaData - numData);
-			} else if (numData > numMetaData) {
-				// Add new elements
-				for (var index = numMetaData; index < numData; ++index) {
-					this.addElementAndReset(index);
-				}
-			}
-		},
+                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;
+                }
+            },
 
-		update: noop,
+            getDataset: function() {
+                return this.chart.data.datasets[this.index];
+            },
 
-		draw: function(ease) {
-			var easingDecimal = ease || 1;
-			helpers.each(this.getMeta().data, function(element) {
-				element.transition(easingDecimal).draw();
-			});
-		},
+            getMeta: function() {
+                return this.chart.getDatasetMeta(this.index);
+            },
 
-		removeHoverStyle: function(element, elementOpts) {
-			var dataset = this.chart.data.datasets[element._datasetIndex],
-				index = element._index,
-				custom = element.custom || {},
-				valueOrDefault = helpers.getValueAtIndexOrDefault,
-				model = element._model;
+            getScaleForId: function(scaleID) {
+                return this.chart.scales[scaleID];
+            },
 
-			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);
-		},
+            reset: function() {
+                this.update(true);
+            },
 
-		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;
+            /**
+             * @private
+             */
+            destroy: function() {
+                if (this._data) {
+                    unlistenArrayEvents(this._data, this);
+                }
+            },
 
-			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);
-		}
-		
-    });
-	
+            createMetaDataset: function() {
+                var me = this;
+                var type = me.datasetElementType;
+                return type && new type({
+                        _chart: me.chart,
+                        _datasetIndex: me.index
+                    });
+            },
 
-	Chart.DatasetController.extend = helpers.inherits;
-};
+            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";
+    'use strict';
 
-module.exports = function(Chart) {
+    var color = require(3);
 
-  var helpers = Chart.helpers;
+    module.exports = function(Chart) {
 
-  Chart.elements = {};
+        var helpers = Chart.helpers;
 
-  Chart.Element = function(configuration) {
-    helpers.extend(this, configuration);
-    this.initialize.apply(this, arguments);
-  };
+        function interpolate(start, view, model, ease) {
+            var keys = Object.keys(model);
+            var i, ilen, key, actual, origin, target, type, c0, c1;
 
-  helpers.extend(Chart.Element.prototype, {
+            for (i=0, ilen=keys.length; i<ilen; ++i) {
+                key = keys[i];
 
-    initialize: function() {
-      this.hidden = false;
-    },
+                target = model[key];
 
-    pivot: function() {
-      var me = this;
-      if (!me._view) {
-        me._view = helpers.clone(me._model);
-      }
-      me._start = helpers.clone(me._view);
-      return me;
-    },
+                // 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;
+                }
 
-    transition: function(ease) {
-      var me = this;
-      
-      if (!me._view) {
-        me._view = helpers.clone(me._model);
-      }
+                actual = view[key];
 
-      // No animation -> No Transition
-      if (ease === 1) {
-        me._view = me._model;
-        me._start = null;
-        return me;
-      }
+                if (actual === target || key[0] === '_') {
+                    continue;
+                }
 
-      if (!me._start) {
-        me.pivot();
-      }
+                if (!start.hasOwnProperty(key)) {
+                    start[key] = actual;
+                }
 
-      helpers.each(me._model, function(value, key) {
+                origin = start[key];
 
-        if (key[0] === '_') {
-          // Only non-underscored properties
+                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;
+            }
         }
 
-        // Init if doesn't exist
-        else if (!me._view.hasOwnProperty(key)) {
-          if (typeof value === 'number' && !isNaN(me._view[key])) {
-            me._view[key] = value * ease;
-          } else {
-            me._view[key] = value;
-          }
+        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;
         }
 
-        // No unnecessary computations
-        else if (value === me._view[key]) {
-          // It's the same! Woohoo!
+        /**
+         * Returns if the given value contains an effective constraint.
+         * @private
+         */
+        function isConstrainedValue(value) {
+            return value !== undefined && value !== null && value !== 'none';
         }
 
-        // Color transitions if possible
-        else if (typeof value === 'string') {
-          try {
-            var color = helpers.color(me._model[key]).mix(helpers.color(me._start[key]), ease);
-            me._view[key] = color.rgbString();
-          } catch (err) {
-            me._view[key] = value;
-          }
+        // 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';
         }
-        // Number transitions
-        else if (typeof value === 'number') {
-          var startVal = me._start[key] !== undefined && isNaN(me._start[key]) === false ? me._start[key] : 0;
-          me._view[key] = ((me._model[key] - startVal) * ease) + startVal;
-        }
-        // Everything else
-        else {
-          me._view[key] = value;
-        }
-      }, me);
+        // 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;
+            }
 
-      return me;
-    },
+            var canvas = chart.canvas;
+            var height = chart.height;
+            var width = chart.width;
 
-    tooltipPosition: function() {
-      return {
-        x: this._model.x,
-        y: this._model.y
-      };
-    },
+            canvas.height = height * pixelRatio;
+            canvas.width = width * pixelRatio;
+            chart.ctx.scale(pixelRatio, pixelRatio);
 
-    hasValue: function() {
-      return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
-    }
-  });
+            // 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 || [];
 
-  Chart.Element.extend = helpers.inherits;
+            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);
+                        }
+                    });
+                }
+            });
 
-},{}],26:[function(require,module,exports){
-/*global window: false */
-/*global document: false */
-"use strict";
+            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();
+        };
 
-var color = require(3);
+        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;
+                }
 
-module.exports = function(Chart) {
-	//Global Chart helpers object for utility methods and classes
-	var helpers = Chart.helpers = {};
+                return color(value);
+            };
 
-	//-- 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) {
-				if (key === 'scales') {
-					// Scale config merging is complex. Add out own function here for that
-					base[key] = helpers.scaleMerge(base.hasOwnProperty(key) ? base[key] : {}, 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;
 
-				} else if (key === 'scale') {
-					// Used in polar area & radar charts since there is only one scale
-					base[key] = helpers.configMerge(base.hasOwnProperty(key) ? base[key] : {}, Chart.scaleService.getScaleDefaults(value.type), value);
-				} else if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {
-					// In this case we have an array of objects replacing another array. Rather than doing a strict replace,
-					// merge. This allows easy scale option merging
-					var baseArray = base[key];
+            if (!a0 || !a1 || a0.length !== a1.length) {
+                return false;
+            }
 
-					helpers.each(value, function(valueObj, index) {
+            for (i = 0, ilen=a0.length; i < ilen; ++i) {
+                v0 = a0[i];
+                v1 = a1[i];
 
-						if (index < baseArray.length) {
-							if (typeof baseArray[index] === 'object' && baseArray[index] !== null && typeof valueObj === 'object' && valueObj !== null) {
-								// Two objects are coming together. Do a merge of them.
-								baseArray[index] = helpers.configMerge(baseArray[index], valueObj);
-							} else {
-								// Just overwrite in this case since there is nothing to merge
-								baseArray[index] = valueObj;
-							}
-						} else {
-							baseArray.push(valueObj); // nothing to merge
-						}
-					});
+                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;
+                }
+            }
 
-				} 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);
+            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();
+        };
 
-				} 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);
-		} else {
-			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 parent = this;
-		var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function() {
-			return parent.apply(this, arguments);
-		};
-
-		var Surrogate = function() {
-			this.constructor = ChartElement;
-		};
-		Surrogate.prototype = parent.prototype;
-		ChartElement.prototype = new Surrogate();
-
-		ChartElement.extend = helpers.inherits;
-
-		if (extensions) {
-			helpers.extend(ChartElement.prototype, extensions);
-		}
-
-		ChartElement.__super__ = parent.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.max = function(array) {
-		return array.reduce(function(max, value) {
-			if (!isNaN(value)) {
-				return Math.max(max, value);
-			} else {
-				return max;
-			}
-		}, Number.NEGATIVE_INFINITY);
-	};
-	helpers.min = function(array) {
-		return array.reduce(function(min, value) {
-			if (!isNaN(value)) {
-				return Math.min(min, value);
-			} else {
-				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.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.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);
-			} else {
-				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() {
-		return window.requestAnimationFrame ||
-			window.webkitRequestAnimationFrame ||
-			window.mozRequestAnimationFrame ||
-			window.oRequestAnimationFrame ||
-			window.msRequestAnimationFrame ||
-			function(callback) {
-				return window.setTimeout(callback, 1000 / 60);
-			};
-	})();
-	helpers.cancelAnimFrame = (function() {
-		return window.cancelAnimationFrame ||
-			window.webkitCancelAnimationFrame ||
-			window.mozCancelAnimationFrame ||
-			window.oCancelAnimationFrame ||
-			window.msCancelAnimationFrame ||
-			function(callback) {
-				return window.clearTimeout(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;
-		}
-	};
-	helpers.bindEvents = function(chartInstance, arrayOfEvents, handler) {
-		// Create the events object if it's not already present
-		var events = chartInstance.events = chartInstance.events || {};
-
-		helpers.each(arrayOfEvents, function(eventName) {
-			events[eventName] = function() {
-				handler.apply(chartInstance, arguments);
-			};
-			helpers.addEvent(chartInstance.chart.canvas, eventName, events[eventName]);
-		});
-	};
-	helpers.unbindEvents = function(chartInstance, arrayOfEvents) {
-		var canvas = chartInstance.chart.canvas;
-		helpers.each(arrayOfEvents, function(handler, eventName) {
-			helpers.removeEvent(canvas, eventName, handler);
-		});
-	};
-
-	// 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 padding = parseInt(helpers.getStyle(container, 'padding-left')) + parseInt(helpers.getStyle(container, 'padding-right'));
-		var w = container.clientWidth - padding;
-		var cw = helpers.getConstraintWidth(domNode);
-		return isNaN(cw)? w : Math.min(w, cw);
-	};
-	helpers.getMaximumHeight = function(domNode) {
-		var container = domNode.parentNode;
-		var padding = parseInt(helpers.getStyle(container, 'padding-top')) + parseInt(helpers.getStyle(container, 'padding-bottom'));
-		var h = container.clientHeight - padding;
-		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 ctx = chart.ctx;
-		var canvas = chart.canvas;
-		var width = canvas.width;
-		var height = canvas.height;
-		var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
-
-		if (pixelRatio !== 1) {
-			canvas.height = height * pixelRatio;
-			canvas.width = width * pixelRatio;
-			ctx.scale(pixelRatio, pixelRatio);
-
-			// Store the device pixel ratio so that we can go backwards in `destroy`.
-			// The devicePixelRatio changes with zoom, so there are no guarantees that it is the same
-			// when destroy is called
-			chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || pixelRatio;
-		}
-
-		canvas.style.width = width + 'px';
-		canvas.style.height = height + '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 = function(c) {
-		if (!color) {
-			console.log('Color.js not found!');
-			return c;
-		}
-
-		/* global CanvasGradient */
-		if (c instanceof CanvasGradient) {
-			return color(Chart.defaults.global.defaultColor);
-		}
-
-		return color(c);
-	};
-	helpers.addResizeListener = function(node, callback) {
-		// Hide an iframe before the node
-		var hiddenIframe = document.createElement('iframe');
-		var hiddenIframeClass = 'chartjs-hidden-iframe';
-
-		if (hiddenIframe.classlist) {
-			// can use classlist
-			hiddenIframe.classlist.add(hiddenIframeClass);
-		} else {
-			hiddenIframe.setAttribute('class', hiddenIframeClass);
-		}
-
-		// Set the style
-		var style = hiddenIframe.style;
-		style.width = '100%';
-		style.display = 'block';
-		style.border = 0;
-		style.height = 0;
-		style.margin = 0;
-		style.position = 'absolute';
-		style.left = 0;
-		style.right = 0;
-		style.top = 0;
-		style.bottom = 0;
-
-		// Insert the iframe so that contentWindow is available
-		node.insertBefore(hiddenIframe, node.firstChild);
-
-		(hiddenIframe.contentWindow || hiddenIframe).onresize = function() {
-			if (callback) {
-				callback();
-			}
-		};
-	};
-	helpers.removeResizeListener = function(node) {
-		var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');
-
-		// Remove the resize detect iframe
-		if (hiddenIframe) {
-			hiddenIframe.parentNode.removeChild(hiddenIframe);
-		}
-	};
-	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.callCallback = function(fn, args, _tArg) {
-		if (fn && typeof fn.call === 'function') {
-			fn.apply(_tArg, args);
-		}
-	};
-	helpers.getHoverColor = function(color) {
-		/* global CanvasPattern */
-		return (color instanceof CanvasPattern) ?
-			color :
-			helpers.color(color).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";
+    'use strict';
 
-module.exports = function() {
+    module.exports = function(Chart) {
+        var helpers = Chart.helpers;
 
-	//Occupy the global variable of Chart, and create a simple base class
-	var Chart = function(context, config) {
-		var me = this;
-		var helpers = Chart.helpers;
-		me.config = config || { 
-			data: {
-				datasets: []
-			}
-		};
+        /**
+         * 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
+                };
+            }
 
-		// Support a jQuery'd canvas element
-		if (context.length && context[0].getContext) {
-			context = context[0];
-		}
+            return helpers.getRelativePosition(e, chart);
+        }
 
-		// Support a canvas domnode
-		if (context.getContext) {
-			context = context.getContext("2d");
-		}
+        /**
+         * 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;
 
-		me.ctx = context;
-		me.canvas = context.canvas;
+            for (i = 0, ilen = datasets.length; i < ilen; ++i) {
+                if (!chart.isDatasetVisible(i)) {
+                    continue;
+                }
 
-		context.canvas.style.display = context.canvas.style.display || 'block';
+                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);
+                    }
+                }
+            }
+        }
 
-		// Figure out what the size of the chart will be.
-		// If the canvas has a specified width and height, we use those else
-		// we look to see if the canvas node has a CSS width and height.
-		// If there is still no height, fill the parent container
-		me.width = context.canvas.width || parseInt(helpers.getStyle(context.canvas, 'width'), 10) || helpers.getMaximumWidth(context.canvas);
-		me.height = context.canvas.height || parseInt(helpers.getStyle(context.canvas, 'height'), 10) || helpers.getMaximumHeight(context.canvas);
+        /**
+         * 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 = [];
 
-		me.aspectRatio = me.width / me.height;
+            parseVisibleItems(chart, function(element) {
+                if (element.inRange(position.x, position.y)) {
+                    elements.push(element);
+                }
+            });
 
-		if (isNaN(me.aspectRatio) || isFinite(me.aspectRatio) === false) {
-			// If the canvas has no size, try and figure out what the aspect ratio will be.
-			// Some charts prefer square canvases (pie, radar, etc). If that is specified, use that
-			// else use the canvas default ratio of 2
-			me.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;
-		}
+            return elements;
+        }
 
-		// Store the original style of the element so we can set it back
-		me.originalCanvasStyleWidth = context.canvas.style.width;
-		me.originalCanvasStyleHeight = context.canvas.style.height;
+        /**
+         * 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 = [];
 
-		// High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
-		helpers.retinaScale(me);
-		me.controller = new Chart.Controller(me);
+            if (!distanceMetric) {
+                distanceMetric = helpers.distanceBetweenPoints;
+            }
 
-		// Always bind this so that if the responsive state changes we still work
-		helpers.addResizeListener(context.canvas.parentNode, function() {
-			if (me.controller && me.controller.config.options.responsive) {
-				me.controller.resize();
-			}
-		});
+            parseVisibleItems(chart, function(element) {
+                if (intersect && !element.inRange(position.x, position.y)) {
+                    return;
+                }
 
-		return me.controller ? me.controller : me;
+                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);
+                }
+            });
 
-	//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: 'single',
-				animationDuration: 400
-			},
-			onClick: null,
-			defaultColor: 'rgba(0,0,0,0.1)',
-			defaultFontColor: '#666',
-			defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
-			defaultFontSize: 12,
-			defaultFontStyle: 'normal',
-			showLines: true,
+            return nearestItems;
+        }
 
-			// Element defaults defined in element extensions
-			elements: {},
+        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 = [];
 
-			// 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>');
+            if (!items.length) {
+                return [];
+            }
 
-				return text.join("");
-			}
-		}
-	};
+            chart.data.datasets.forEach(function(dataset, datasetIndex) {
+                if (chart.isDatasetVisible(datasetIndex)) {
+                    var meta = chart.getDatasetMeta(datasetIndex),
+                        element = meta.data[items[0]._index];
 
-	Chart.Chart = Chart;
+                    // don't count items that are skipped (null data)
+                    if (element && !element._view.skip) {
+                        elements.push(element);
+                    }
+                }
+            });
 
-	return Chart;
+            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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function() {
 
-	var helpers = Chart.helpers;
+        // Occupy the global variable of Chart, and create a simple base class
+        var Chart = function(item, config) {
+            this.construct(item, config);
+            return this;
+        };
 
-	// 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: {},
+        // 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,
 
-		// Register a box to a chartInstance. A box is simply a reference to an object that requires layout. eg. Scales, Legend, Plugins.
-		addBox: function(chartInstance, box) {
-			if (!chartInstance.boxes) {
-				chartInstance.boxes = [];
-			}
-			chartInstance.boxes.push(box);
-		},
+                // Element defaults defined in element extensions
+                elements: {},
 
-		removeBox: function(chartInstance, box) {
-			if (!chartInstance.boxes) {
-				return;
-			}
-			chartInstance.boxes.splice(chartInstance.boxes.indexOf(box), 1);
-		},
+                // 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>');
 
-		// The most important function
-		update: function(chartInstance, width, height) {
+                    return text.join('');
+                }
+            }
+        };
 
-			if (!chartInstance) {
-				return;
-			}
+        Chart.Chart = Chart;
 
-			var xPadding = 0;
-			var yPadding = 0;
-
-			var leftBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "left";
-			});
-			var rightBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "right";
-			});
-			var topBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "top";
-			});
-			var bottomBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "bottom";
-			});
-
-			// Boxes that overlay the chartarea such as the radialLinear scale
-			var chartAreaBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "chartArea";
-			});
-
-			// Ensure that full width boxes are at the very top / bottom
-			topBoxes.sort(function(a, b) {
-				return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0);
-			});
-			bottomBoxes.sort(function(a, b) {
-				return (a.options.fullWidth ? 1 : 0) - (b.options.fullWidth ? 1 : 0);
-			});
-
-			// 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 - (2 * xPadding);
-			var chartHeight = height - (2 * yPadding);
-			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 = [];
-
-			helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
-
-			function getMinimumBoxSize(box) {
-				var minSize;
-				var isHorizontal = box.isHorizontal();
-
-				if (isHorizontal) {
-					minSize = box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
-					maxChartAreaHeight -= minSize.height;
-				} else {
-					minSize = box.update(verticalBoxWidth, chartAreaHeight);
-					maxChartAreaWidth -= minSize.width;
-				}
-
-				minBoxSizes.push({
-					horizontal: isHorizontal,
-					minSize: minSize,
-					box: box
-				});
-			}
-
-			// 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 = xPadding;
-			var totalRightBoxesWidth = xPadding;
-			var totalTopBoxesHeight = yPadding;
-			var totalBottomBoxesHeight = yPadding;
-
-			// 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);
-
-			// Function to fit a box
-			function fitBox(box) {
-				var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
-					return minBoxSize.box === box;
-				});
-
-				if (minBoxSize) {
-					if (box.isHorizontal()) {
-						var scaleMargin = {
-							left: totalLeftBoxesWidth,
-							right: totalRightBoxesWidth,
-							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.options.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
-					} else {
-						box.update(minBoxSize.minSize.width, maxChartAreaHeight);
-					}
-				}
-			}
-
-			// 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;
-			});
-
-			// Let the left layout know the final margin
-			helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
-
-			function finalFitVerticalBox(box) {
-				var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
-					return minBoxSize.box === box;
-				});
-
-				var scaleMargin = {
-					left: 0,
-					right: 0,
-					top: totalTopBoxesHeight,
-					bottom: totalBottomBoxesHeight
-				};
-
-				if (minBoxSize) {
-					box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
-				}
-			}
-
-			// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
-			totalLeftBoxesWidth = xPadding;
-			totalRightBoxesWidth = xPadding;
-			totalTopBoxesHeight = yPadding;
-			totalBottomBoxesHeight = yPadding;
-
-			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;
-			});
-
-			// 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.options.fullWidth) {
-						box.width = newMaxChartAreaWidth;
-					}
-				});
-
-				helpers.each(bottomBoxes, function(box) {
-					if (!box.options.fullWidth) {
-						box.width = newMaxChartAreaWidth;
-					}
-				});
-
-				maxChartAreaHeight = newMaxChartAreaHeight;
-				maxChartAreaWidth = newMaxChartAreaWidth;
-			}
-
-			// Step 7 - Position the boxes
-			var left = xPadding;
-			var top = yPadding;
-
-			helpers.each(leftBoxes.concat(topBoxes), placeBox);
-
-			// Account for chart width and height
-			left += maxChartAreaWidth;
-			top += maxChartAreaHeight;
-
-			helpers.each(rightBoxes, placeBox);
-			helpers.each(bottomBoxes, placeBox);
-
-			function placeBox(box) {
-				if (box.isHorizontal()) {
-					box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;
-					box.right = box.options.fullWidth ? width - xPadding : 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;
-				}
-			}
-
-			// Step 8
-			chartInstance.chartArea = {
-				left: totalLeftBoxesWidth,
-				top: totalTopBoxesHeight,
-				right: totalLeftBoxesWidth + maxChartAreaWidth,
-				bottom: totalTopBoxesHeight + maxChartAreaHeight
-			};
-
-			// Step 9
-			helpers.each(chartAreaBoxes, function(box) {
-				box.left = chartInstance.chartArea.left;
-				box.top = chartInstance.chartArea.top;
-				box.right = chartInstance.chartArea.right;
-				box.bottom = chartInstance.chartArea.bottom;
-
-				box.update(maxChartAreaWidth, maxChartAreaHeight);
-			});
-		}
-	};
-};
+        return Chart;
+    };
 
 },{}],29:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var noop = helpers.noop;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.legend = {
+        function filterByPosition(array, position) {
+            return helpers.where(array, function(v) {
+                return v.position === position;
+            });
+        }
 
-		display: true,
-		position: 'top',
-		fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
-		reverse: false,
+        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_;
+            });
+        }
 
-		// a callback that will handle
-		onClick: function(e, legendItem) {
-			var index = legendItem.datasetIndex;
-			var ci = this.chart;
-			var meta = ci.getDatasetMeta(index);
+        /**
+         * @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
+         */
 
-			// See controller.isDatasetVisible comment
-			meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
+        // 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: {},
 
-			// We hid a dataset ... rerender the chart
-			ci.update();
-		},
+            /**
+             * 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 = [];
+                }
 
-		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,
+                // initialize item with default values
+                item.fullWidth = item.fullWidth || false;
+                item.position = item.position || 'top';
+                item.weight = item.weight || 0;
 
-						// Below is extra data used for toggling the datasets
-						datasetIndex: i
-					};
-				}, this) : [];
-			}
-		}
-	};
+                chart.boxes.push(item);
+            },
 
-	Chart.Legend = Chart.Element.extend({
+            /**
+             * 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);
+                }
+            },
 
-		initialize: function(config) {
-			helpers.extend(this, config);
+            /**
+             * 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;
 
-			// Contains hit boxes for each dataset (in dataset order)
-			this.legendHitBoxes = [];
+                for (; i<ilen; ++i) {
+                    prop = props[i];
+                    if (options.hasOwnProperty(prop)) {
+                        item[prop] = options[prop];
+                    }
+                }
+            },
 
-			// Are we in doughnut mode which has a different data type
-			this.doughnutMode = false;
-		},
+            /**
+             * 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;
+                }
 
-		// These methods are ordered by lifecyle. Utilities then follow.
-		// Any function defined here is inherited by all legend types.
-		// Any function can be extended by the legend type
+                var layoutOptions = chart.options.layout;
+                var padding = layoutOptions ? layoutOptions.padding : null;
 
-		beforeUpdate: noop,
-		update: function(maxWidth, maxHeight, margins) {
-			var me = this;
+                var leftPadding = 0;
+                var rightPadding = 0;
+                var topPadding = 0;
+                var bottomPadding = 0;
 
-			// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-			me.beforeUpdate();
+                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;
+                }
 
-			// Absorb the master measurements
-			me.maxWidth = maxWidth;
-			me.maxHeight = maxHeight;
-			me.margins = margins;
+                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');
 
-			// Dimensions
-			me.beforeSetDimensions();
-			me.setDimensions();
-			me.afterSetDimensions();
-			// Labels
-			me.beforeBuildLabels();
-			me.buildLabels();
-			me.afterBuildLabels();
+                // 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);
 
-			// Fit
-			me.beforeFit();
-			me.fit();
-			me.afterFit();
-			//
-			me.afterUpdate();
+                // 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
 
-			return me.minSize;
-		},
-		afterUpdate: noop,
+                // 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);
 
-		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;
+                // Step 3
+                var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
 
-				// Reset position before calculating rotation
-				me.top = 0;
-				me.bottom = me.height;
-			}
+                // Step 4
+                var maxChartAreaWidth = chartWidth;
+                var maxChartAreaHeight = chartHeight;
+                var minBoxSizes = [];
 
-			// Reset padding
-			me.paddingLeft = 0;
-			me.paddingTop = 0;
-			me.paddingRight = 0;
-			me.paddingBottom = 0;
+                function getMinimumBoxSize(box) {
+                    var minSize;
+                    var isHorizontal = box.isHorizontal();
 
-			// Reset minSize
-			me.minSize = {
-				width: 0,
-				height: 0
-			};
-		},
-		afterSetDimensions: noop,
+                    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,
+                    });
+                }
 
-		beforeBuildLabels: noop,
-		buildLabels: function() {
-			var me = this;
-			me.legendItems = me.options.labels.generateLabels.call(me, me.chart);
-			if(me.options.reverse){
-				me.legendItems.reverse();
-			}
-		},
-		afterBuildLabels: noop,
+                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;
 
-		beforeFit: noop,
-		fit: function() {
-			var me = this;
-			var opts = me.options;
-			var labelOpts = opts.labels;
-			var display = opts.display;
+                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);
+                    }
+                });
 
-			var ctx = me.ctx;
+                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);
+                    }
+                });
 
-			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);
+                // 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;
 
-			// Reset hit boxes
-			var hitboxes = me.legendHitBoxes = [];
+                // Function to fit a box
+                function fitBox(box) {
+                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
+                        return minBox.box === box;
+                    });
 
-			var minSize = me.minSize;
-			var isHorizontal = me.isHorizontal();
+                    if (minBoxSize) {
+                        if (box.isHorizontal()) {
+                            var scaleMargin = {
+                                left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
+                                right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
+                                top: 0,
+                                bottom: 0
+                            };
 
-			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 = labelOpts.usePointStyle ?
-							fontSize * Math.sqrt(2) :
-							labelOpts.boxWidth;
-
-						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) {
-						// If usePointStyle is set, multiple boxWidth by 2 since it represents
-						// the radius and not truly the width
-						var boxWidth = labelOpts.usePointStyle ? 2 * labelOpts.boxWidth : labelOpts.boxWidth;
+                            // 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);
+                        }
+                    }
+                }
 
-						var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+                // Update, and calculate the left and right margins for the horizontal boxes
+                helpers.each(leftBoxes.concat(rightBoxes), fitBox);
 
-						// If too tall, go to new column
-						if (currentColHeight + itemHeight > minSize.height) {
-							totalWidth += currentColWidth + labelOpts.padding;
-							columnWidths.push(currentColWidth); // previous column width
+                helpers.each(leftBoxes, function(box) {
+                    totalLeftBoxesWidth += box.width;
+                });
 
-							currentColWidth = 0;
-							currentColHeight = 0;
-						}
+                helpers.each(rightBoxes, function(box) {
+                    totalRightBoxesWidth += box.width;
+                });
 
-						// Get max width
-						currentColWidth = Math.max(currentColWidth, itemWidth);
-						currentColHeight += itemHeight;
+                // Set the Left and Right margins for the horizontal boxes
+                helpers.each(topBoxes.concat(bottomBoxes), fitBox);
 
-						// Store the hitbox width and height here. Final position will be updated in `draw`
-						hitboxes[i] = {
-							left: 0,
-							top: 0,
-							width: itemWidth,
-							height: fontSize
-						};
-					});
+                // Figure out how much margin is on the top and bottom of the vertical boxes
+                helpers.each(topBoxes, function(box) {
+                    totalTopBoxesHeight += box.height;
+                });
 
-					totalWidth += currentColWidth;
-					columnWidths.push(currentColWidth);
-					minSize.width += totalWidth;
-				}
-			}
+                helpers.each(bottomBoxes, function(box) {
+                    totalBottomBoxesHeight += box.height;
+                });
 
-			me.width = minSize.width;
-			me.height = minSize.height;
-		},
-		afterFit: noop,
+                function finalFitVerticalBox(box) {
+                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
+                        return minSize.box === box;
+                    });
 
-		// Shared Methods
-		isHorizontal: function() {
-			return this.options.position === "top" || this.options.position === "bottom";
-		},
+                    var scaleMargin = {
+                        left: 0,
+                        right: 0,
+                        top: totalTopBoxesHeight,
+                        bottom: totalBottomBoxesHeight
+                    };
 
-		// Actualy 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 (minBoxSize) {
+                        box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
+                    }
+                }
 
-			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);
+                // Let the left layout know the final margin
+                helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
 
-				// 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;
+                // 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;
 
-				var boxWidth = labelOpts.boxWidth,
-					hitboxes = me.legendHitBoxes;
+                helpers.each(leftBoxes, function(box) {
+                    totalLeftBoxesWidth += box.width;
+                });
 
-				// current position
-				var drawLegendBox = function(x, y, legendItem) {
-					if (isNaN(boxWidth) || boxWidth <= 0) {
-						return;
-					}
+                helpers.each(rightBoxes, function(box) {
+                    totalRightBoxesWidth += box.width;
+                });
 
-					// Set the ctx for the box
-					ctx.save();
+                helpers.each(topBoxes, function(box) {
+                    totalTopBoxesHeight += box.height;
+                });
+                helpers.each(bottomBoxes, function(box) {
+                    totalBottomBoxesHeight += box.height;
+                });
 
-					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);
+                // 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);
 
-					if (ctx.setLineDash) {
-						// IE 9 and 10 do not support line dash
-						ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
-					}
+                var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);
+                totalTopBoxesHeight += topPaddingAddition;
+                totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);
 
-					if (opts.labels && opts.labels.usePointStyle) {
-						// Recalulate 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;
+                // 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;
 
-						// Draw pointStyle as legend symbol
-						Chart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
-					}
-					else {
-						// Draw box as legend symbol
-						ctx.strokeRect(x, y, boxWidth, fontSize);
-						ctx.fillRect(x, y, boxWidth, fontSize);
-					}
+                if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
+                    helpers.each(leftBoxes, function(box) {
+                        box.height = newMaxChartAreaHeight;
+                    });
 
-					ctx.restore();
-				};
-				var fillText = function(x, y, legendItem, textWidth) {
-					ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);
+                    helpers.each(rightBoxes, function(box) {
+                        box.height = newMaxChartAreaHeight;
+                    });
 
-					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();
-					}
-				};
+                    helpers.each(topBoxes, function(box) {
+                        if (!box.fullWidth) {
+                            box.width = newMaxChartAreaWidth;
+                        }
+                    });
 
-				// 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
-					};
-				}
+                    helpers.each(bottomBoxes, function(box) {
+                        if (!box.fullWidth) {
+                            box.width = newMaxChartAreaWidth;
+                        }
+                    });
 
-				var itemHeight = fontSize + labelOpts.padding;
-				helpers.each(me.legendItems, function(legendItem, i) {
-					var textWidth = ctx.measureText(legendItem.text).width,
-						width = labelOpts.usePointStyle ?
-							fontSize + (fontSize / 2) + textWidth :
-							boxWidth + (fontSize / 2) + textWidth,
-						x = cursor.x,
-						y = cursor.y;
+                    maxChartAreaHeight = newMaxChartAreaHeight;
+                    maxChartAreaWidth = newMaxChartAreaWidth;
+                }
 
-					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;
-							cursor.line++;
-						}
-					}
+                // Step 7 - Position the boxes
+                var left = leftPadding + leftPaddingAddition;
+                var top = topPadding + topPaddingAddition;
 
-					drawLegendBox(x, y, legendItem);
+                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;
 
-					hitboxes[i].left = x;
-					hitboxes[i].top = y;
+                        // Move to next point
+                        top = box.bottom;
 
-					// Fill the actual label
-					fillText(x, y, legendItem, textWidth);
+                    } else {
 
-					if (isHorizontal) {
-						cursor.x += width + (labelOpts.padding);
-					} else {
-						cursor.y += itemHeight;
-					}
+                        box.left = left;
+                        box.right = left + box.width;
+                        box.top = totalTopBoxesHeight;
+                        box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
 
-				});
-			}
-		},
+                        // Move to next point
+                        left = box.right;
+                    }
+                }
 
-		// Handle an event
-		handleEvent: function(e) {
-			var me = this;
-			var position = helpers.getRelativePosition(e, me.chart.chart),
-				x = position.x,
-				y = position.y,
-				opts = me.options;
+                helpers.each(leftBoxes.concat(topBoxes), placeBox);
 
-			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];
+                // Account for chart width and height
+                left += maxChartAreaWidth;
+                top += maxChartAreaHeight;
 
-					if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
-						// Touching an element
-						if (opts.onClick) {
-							opts.onClick.call(me, e, me.legendItems[i]);
-						}
-						break;
-					}
-				}
-			}
-		}
-	});
+                helpers.each(rightBoxes, placeBox);
+                helpers.each(bottomBoxes, placeBox);
 
-	// Register the legend plugin
-	Chart.plugins.register({
-		beforeInit: function(chartInstance) {
-			var opts = chartInstance.options;
-			var legendOpts = opts.legend;
+                // Step 8
+                chart.chartArea = {
+                    left: totalLeftBoxesWidth,
+                    top: totalTopBoxesHeight,
+                    right: totalLeftBoxesWidth + maxChartAreaWidth,
+                    bottom: totalTopBoxesHeight + maxChartAreaHeight
+                };
 
-			if (legendOpts) {
-				chartInstance.legend = new Chart.Legend({
-					ctx: chartInstance.chart.ctx,
-					options: legendOpts,
-					chart: chartInstance
-				});
+                // 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;
 
-				Chart.layoutService.addBox(chartInstance, chartInstance.legend);
-			}
-		}
-	});
-};
+                    box.update(maxChartAreaWidth, maxChartAreaHeight);
+                });
+            }
+        };
+    };
 
 },{}],30:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var noop = Chart.helpers.noop;
+        var helpers = Chart.helpers;
 
-	/**
-	 * The plugin service singleton
-	 * @namespace Chart.plugins
-	 * @since 2.1.0
-	 */
-	Chart.plugins = {
-		_plugins: [],
+        Chart.defaults.global.plugins = {};
 
-		/**
-		 * 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);
-				}
-			});
-		},
+        /**
+         * The plugin service singleton
+         * @namespace Chart.plugins
+         * @since 2.1.0
+         */
+        Chart.plugins = {
+            /**
+             * Globally registered plugins.
+             * @private
+             */
+            _plugins: [],
 
-		/**
-		 * 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 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,
 
-		/**
-		 * Remove all registered p^lugins.
-		 * @since 2.1.5
-		 */
-		clear: function() {
-			this._plugins = [];
-		},
+            /**
+             * 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);
+                    }
+                });
 
-		/**
-		 * Returns the number of registered plugins?
-		 * @returns {Number}
-		 * @since 2.1.5
-		 */
-		count: function() {
-			return this._plugins.length;
-		},
+                this._cacheId++;
+            },
 
-		/**
-		 * Returns all registered plugin intances.
-		 * @returns {Array} array of plugin objects.
-		 * @since 2.1.5
-		 */
-		getAll: function() {
-			return this._plugins;
-		},
+            /**
+             * 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);
+                    }
+                });
 
-		/**
-		 * Calls registered plugins on the specified extension, 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 {String} extension the name of the plugin method to call (e.g. 'beforeUpdate').
-		 * @param {Array} [args] extra arguments to apply to the extension call.
-		 * @returns {Boolean} false if any of the plugins return false, else returns true.
-		 */
-		notify: function(extension, args) {
-			var plugins = this._plugins;
-			var ilen = plugins.length;
-			var i, plugin;
+                this._cacheId++;
+            },
 
-			for (i=0; i<ilen; ++i) {
-				plugin = plugins[i];
-				if (typeof plugin[extension] === 'function') {
-					if (plugin[extension].apply(plugin, args || []) === false) {
-						return false;
-					}
-				}
-			}
+            /**
+             * Remove all registered plugins.
+             * @since 2.1.5
+             */
+            clear: function() {
+                this._plugins = [];
+                this._cacheId++;
+            },
 
-			return true;
-		}
-	};
+            /**
+             * Returns the number of registered plugins?
+             * @returns {Number}
+             * @since 2.1.5
+             */
+            count: function() {
+                return this._plugins.length;
+            },
 
-	/**
-	 * Plugin extension methods.
-	 * @interface Chart.PluginBase
-	 * @since 2.1.0
-	 */
-	Chart.PluginBase = Chart.Element.extend({
-		// Called at start of chart init
-		beforeInit: noop,
+            /**
+             * Returns all registered plugin instances.
+             * @returns {Array} array of plugin objects.
+             * @since 2.1.5
+             */
+            getAll: function() {
+                return this._plugins;
+            },
 
-		// Called at end of chart init
-		afterInit: noop,
+            /**
+             * 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;
 
-		// Called at start of update
-		beforeUpdate: noop,
+                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;
+                        }
+                    }
+                }
 
-		// Called at end of update
-		afterUpdate: noop,
+                return true;
+            },
 
-		// Called at start of draw
-		beforeDraw: noop,
+            /**
+             * 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;
+                }
 
-		// Called at end of draw
-		afterDraw: noop,
+                var plugins = [];
+                var descriptors = [];
+                var config = (chart && chart.config) || {};
+                var defaults = Chart.defaults.global.plugins;
+                var options = (config.options && config.options.plugins) || {};
 
-		// Called during destroy
-		destroy: noop
-	});
+                this._plugins.concat(config.plugins || []).forEach(function(plugin) {
+                    var idx = plugins.indexOf(plugin);
+                    if (idx !== -1) {
+                        return;
+                    }
 
-	/**
-	 * Provided for backward compatibility, use Chart.plugins instead
-	 * @namespace Chart.pluginService
-	 * @deprecated since version 2.1.5
-	 * @todo remove me at version 3
-	 */
-	Chart.pluginService = Chart.plugins;
-};
+                    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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.scale = {
-		display: true,
-		position: "left",
+        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)",
-			offsetGridLines: false
-		},
+            // 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: '',
+            // scale label
+            scaleLabel: {
+                // actual label
+                labelString: '',
 
-			// display property
-			display: false
-		},
+                // display property
+                display: false
+            },
 
-		// label settings
-		ticks: {
-			beginAtZero: false,
-			minRotation: 0,
-			maxRotation: 50,
-			mirror: false,
-			padding: 10,
-			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: function(value) {
-				return helpers.isArray(value) ? value : '' + value;
-			}
-		}
-	};
+            // 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
+            }
+        };
 
-	Chart.Scale = Chart.Element.extend({
+        function computeTextSize(context, tick, font) {
+            return helpers.isArray(tick) ?
+                helpers.longestText(context, font, tick) :
+                context.measureText(tick).width;
+        }
 
-		// 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
+        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);
 
-		beforeUpdate: function() {
-			helpers.callCallback(this.options.beforeUpdate, [this]);
-		},
-		update: function(maxWidth, maxHeight, margins) {
-			var me = this;
+            return {
+                size: size,
+                style: style,
+                family: family,
+                font: helpers.fontString(size, style, family)
+            };
+        }
 
-			// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-			me.beforeUpdate();
+        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
+                };
+            },
 
-			// Absorb the master measurements
-			me.maxWidth = maxWidth;
-			me.maxHeight = maxHeight;
-			me.margins = helpers.extend({
-				left: 0,
-				right: 0,
-				top: 0,
-				bottom: 0
-			}, margins);
+            // 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
 
-			// Dimensions
-			me.beforeSetDimensions();
-			me.setDimensions();
-			me.afterSetDimensions();
+            beforeUpdate: function() {
+                helpers.callback(this.options.beforeUpdate, [this]);
+            },
+            update: function(maxWidth, maxHeight, margins) {
+                var me = this;
 
-			// Data min/max
-			me.beforeDataLimits();
-			me.determineDataLimits();
-			me.afterDataLimits();
+                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+                me.beforeUpdate();
 
-			// Ticks
-			me.beforeBuildTicks();
-			me.buildTicks();
-			me.afterBuildTicks();
+                // 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 || {};
 
-			me.beforeTickToLabelConversion();
-			me.convertTicksToLabels();
-			me.afterTickToLabelConversion();
+                // Dimensions
+                me.beforeSetDimensions();
+                me.setDimensions();
+                me.afterSetDimensions();
 
-			// Tick Rotation
-			me.beforeCalculateTickRotation();
-			me.calculateTickRotation();
-			me.afterCalculateTickRotation();
-			// Fit
-			me.beforeFit();
-			me.fit();
-			me.afterFit();
-			//
-			me.afterUpdate();
+                // Data min/max
+                me.beforeDataLimits();
+                me.determineDataLimits();
+                me.afterDataLimits();
 
-			return me.minSize;
+                // Ticks
+                me.beforeBuildTicks();
+                me.buildTicks();
+                me.afterBuildTicks();
 
-		},
-		afterUpdate: function() {
-			helpers.callCallback(this.options.afterUpdate, [this]);
-		},
+                me.beforeTickToLabelConversion();
+                me.convertTicksToLabels();
+                me.afterTickToLabelConversion();
 
-		//
+                // Tick Rotation
+                me.beforeCalculateTickRotation();
+                me.calculateTickRotation();
+                me.afterCalculateTickRotation();
+                // Fit
+                me.beforeFit();
+                me.fit();
+                me.afterFit();
+                //
+                me.afterUpdate();
 
-		beforeSetDimensions: function() {
-			helpers.callCallback(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;
+                return me.minSize;
 
-				// Reset position before calculating rotation
-				me.top = 0;
-				me.bottom = me.height;
-			}
+            },
+            afterUpdate: function() {
+                helpers.callback(this.options.afterUpdate, [this]);
+            },
 
-			// Reset padding
-			me.paddingLeft = 0;
-			me.paddingTop = 0;
-			me.paddingRight = 0;
-			me.paddingBottom = 0;
-		},
-		afterSetDimensions: function() {
-			helpers.callCallback(this.options.afterSetDimensions, [this]);
-		},
+            //
 
-		// Data limits
-		beforeDataLimits: function() {
-			helpers.callCallback(this.options.beforeDataLimits, [this]);
-		},
-		determineDataLimits: helpers.noop,
-		afterDataLimits: function() {
-			helpers.callCallback(this.options.afterDataLimits, [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;
 
-		//
-		beforeBuildTicks: function() {
-			helpers.callCallback(this.options.beforeBuildTicks, [this]);
-		},
-		buildTicks: helpers.noop,
-		afterBuildTicks: function() {
-			helpers.callCallback(this.options.afterBuildTicks, [this]);
-		},
+                    // Reset position before calculating rotation
+                    me.top = 0;
+                    me.bottom = me.height;
+                }
 
-		beforeTickToLabelConversion: function() {
-			helpers.callCallback(this.options.beforeTickToLabelConversion, [this]);
-		},
-		convertTicksToLabels: function() {
-			var me = this;
-			// Convert ticks to strings
-			me.ticks = me.ticks.map(function(numericalTick, index, ticks) {
-					if (me.options.ticks.userCallback) {
-						return me.options.ticks.userCallback(numericalTick, index, ticks);
-					}
-					return me.options.ticks.callback(numericalTick, index, ticks);
-				},
-				me);
-		},
-		afterTickToLabelConversion: function() {
-			helpers.callCallback(this.options.afterTickToLabelConversion, [this]);
-		},
+                // 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]);
+            },
 
-		beforeCalculateTickRotation: function() {
-			helpers.callCallback(this.options.beforeCalculateTickRotation, [this]);
-		},
-		calculateTickRotation: function() {
-			var me = this;
-			var context = me.ctx;
-			var globalDefaults = Chart.defaults.global;
-			var optionTicks = me.options.ticks;
+            //
+            beforeBuildTicks: function() {
+                helpers.callback(this.options.beforeBuildTicks, [this]);
+            },
+            buildTicks: helpers.noop,
+            afterBuildTicks: function() {
+                helpers.callback(this.options.afterBuildTicks, [this]);
+            },
 
-			//Get the width of each grid by calculating the difference
-			//between x offsets between 0 and 1.
-			var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-			context.font = tickLabelFont;
+            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]);
+            },
 
-			var firstWidth = context.measureText(me.ticks[0]).width;
-			var lastWidth = context.measureText(me.ticks[me.ticks.length - 1]).width;
-			var firstRotated;
+            //
 
-			me.labelRotation = optionTicks.minRotation || 0;
-			me.paddingRight = 0;
-			me.paddingLeft = 0;
+            beforeCalculateTickRotation: function() {
+                helpers.callback(this.options.beforeCalculateTickRotation, [this]);
+            },
+            calculateTickRotation: function() {
+                var me = this;
+                var context = me.ctx;
+                var tickOpts = me.options.ticks;
 
-			if (me.options.display) {
-				if (me.isHorizontal()) {
-					me.paddingRight = lastWidth / 2 + 3;
-					me.paddingLeft = firstWidth / 2 + 3;
+                // 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;
 
-					if (!me.longestTextCache) {
-						me.longestTextCache = {};
-					}
-					var originalLabelWidth = helpers.longestText(context, tickLabelFont, me.ticks, me.longestTextCache);
-					var labelWidth = originalLabelWidth;
-					var cosRotation;
-					var sinRotation;
+                var labelRotation = tickOpts.minRotation || 0;
 
-					// Allow 3 pixels x2 padding either side for label readability
-					// only the index matters for a dataset scale, but we want a consistent interface between scales
-					var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
+                if (me.options.display && me.isHorizontal()) {
+                    var originalLabelWidth = helpers.longestText(context, tickFont.font, me.ticks, me.longestTextCache);
+                    var labelWidth = originalLabelWidth;
+                    var cosRotation;
+                    var sinRotation;
 
-					//Max label rotation can be set or default to 90 - also act as a loop counter
-					while (labelWidth > tickWidth && me.labelRotation < optionTicks.maxRotation) {
-						cosRotation = Math.cos(helpers.toRadians(me.labelRotation));
-						sinRotation = Math.sin(helpers.toRadians(me.labelRotation));
+                    // Allow 3 pixels x2 padding either side for label readability
+                    var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
 
-						firstRotated = cosRotation * firstWidth;
+                    // 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);
 
-						// We're right aligning the text now.
-						if (firstRotated + tickFontSize / 2 > me.yLabelWidth) {
-							me.paddingLeft = firstRotated + tickFontSize / 2;
-						}
+                        if (sinRotation * originalLabelWidth > me.maxHeight) {
+                            // go back one step
+                            labelRotation--;
+                            break;
+                        }
 
-						me.paddingRight = tickFontSize / 2;
+                        labelRotation++;
+                        labelWidth = cosRotation * originalLabelWidth;
+                    }
+                }
 
-						if (sinRotation * originalLabelWidth > me.maxHeight) {
-							// go back one step
-							me.labelRotation--;
-							break;
-						}
+                me.labelRotation = labelRotation;
+            },
+            afterCalculateTickRotation: function() {
+                helpers.callback(this.options.afterCalculateTickRotation, [this]);
+            },
 
-						me.labelRotation++;
-						labelWidth = cosRotation * originalLabelWidth;
-					}
-				}
-			}
+            //
 
-			if (me.margins) {
-				me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
-				me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
-			}
-		},
-		afterCalculateTickRotation: function() {
-			helpers.callCallback(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();
 
-		beforeFit: function() {
-			helpers.callCallback(this.options.beforeFit, [this]);
-		},
-		fit: function() {
-			var me = this;
-			// Reset
-			var minSize = me.minSize = {
-				width: 0,
-				height: 0
-			};
+                var tickFont = parseFontOptions(tickOpts);
+                var scaleLabelFontSize = parseFontOptions(scaleLabelOpts).size * 1.5;
+                var tickMarkLength = opts.gridLines.tickMarkLength;
 
-			var opts = me.options;
-			var globalDefaults = Chart.defaults.global;
-			var tickOpts = opts.ticks;
-			var scaleLabelOpts = opts.scaleLabel;
-			var display = opts.display;
-			var isHorizontal = me.isHorizontal();
+                // 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;
+                }
 
-			var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
+                // height
+                if (isHorizontal) {
+                    minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
+                } else {
+                    minSize.height = me.maxHeight; // fill all the height
+                }
 
-			var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabelOpts.fontSize, globalDefaults.defaultFontSize);
+                // Are we showing a title for the scale?
+                if (scaleLabelOpts.display && display) {
+                    if (isHorizontal) {
+                        minSize.height += scaleLabelFontSize;
+                    } else {
+                        minSize.width += scaleLabelFontSize;
+                    }
+                }
 
-			var tickMarkLength = opts.gridLines.tickMarkLength;
+                // 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;
 
-			// 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 ? tickMarkLength : 0;
-			}
+                    if (isHorizontal) {
+                        // A horizontal axis is more constrained by the height.
+                        me.longestLabelWidth = largestTextWidth;
 
-			// height
-			if (isHorizontal) {
-				minSize.height = display ? tickMarkLength : 0;
-			} else {
-				minSize.height = me.maxHeight; // fill all the height
-			}
+                        var angleRadians = helpers.toRadians(me.labelRotation);
+                        var cosRotation = Math.cos(angleRadians);
+                        var sinRotation = Math.sin(angleRadians);
 
-			// Are we showing a title for the scale?
-			if (scaleLabelOpts.display && display) {
-				if (isHorizontal) {
-					minSize.height += (scaleLabelFontSize * 1.5);
-				} else {
-					minSize.width += (scaleLabelFontSize * 1.5);
-				}
-			}
+                        // TODO - improve this calculation
+                        var labelHeight = (sinRotation * largestTextWidth)
+                            + (tickFont.size * tallestLabelHeightInLines)
+                            + (lineSpace * tallestLabelHeightInLines);
 
-			if (tickOpts.display && display) {
-				// Don't bother fitting the ticks if we are not showing them
-				if (!me.longestTextCache) {
-					me.longestTextCache = {};
-				}
+                        minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);
+                        me.ctx.font = tickFont.font;
 
-				var largestTextWidth = helpers.longestText(me.ctx, tickLabelFont, me.ticks, me.longestTextCache);
-				var tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);
-				var lineSpace = tickFontSize * 0.5;
+                        var firstTick = me.ticks[0];
+                        var firstLabelWidth = computeTextSize(me.ctx, firstTick, tickFont.font);
 
-				if (isHorizontal) {
-					// A horizontal axis is more constrained by the height.
-					me.longestLabelWidth = largestTextWidth;
+                        var lastTick = me.ticks[me.ticks.length - 1];
+                        var lastLabelWidth = computeTextSize(me.ctx, lastTick, tickFont.font);
 
-					// TODO - improve this calculation
-					var labelHeight = (Math.sin(helpers.toRadians(me.labelRotation)) * me.longestLabelWidth) + (tickFontSize * tallestLabelHeightInLines) + (lineSpace * tallestLabelHeightInLines);
+                        // 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
 
-					minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);
-					me.ctx.font = tickLabelFont;
+                        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;
+                    }
+                }
 
-					var firstLabelWidth = me.ctx.measureText(me.ticks[0]).width;
-					var lastLabelWidth = me.ctx.measureText(me.ticks[me.ticks.length - 1]).width;
+                me.handleMargins();
 
-					// 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
-					var cosRotation = Math.cos(helpers.toRadians(me.labelRotation));
-					var sinRotation = Math.sin(helpers.toRadians(me.labelRotation));
-					me.paddingLeft = me.labelRotation !== 0 ? (cosRotation * firstLabelWidth) + 3 : firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
-					me.paddingRight = me.labelRotation !== 0 ? (sinRotation * (tickFontSize / 2)) + 3 : lastLabelWidth / 2 + 3; // when rotated
-				} else {
-					// A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first
-					var maxLabelWidth = me.maxWidth - minSize.width;
+                me.width = minSize.width;
+                me.height = minSize.height;
+            },
 
-					// Account for padding
-					var mirror = tickOpts.mirror;
-					if (!mirror) {
-						largestTextWidth += me.options.ticks.padding;
-					} else {
-						// If mirrored text is on the inside so don't expand
-						largestTextWidth = 0;
-					}
+            /**
+             * 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);
+                }
+            },
 
-					if (largestTextWidth < maxLabelWidth) {
-						// We don't need all the room
-						minSize.width += largestTextWidth;
-					} else {
-						// Expand to max size
-						minSize.width = me.maxWidth;
-					}
+            afterFit: function() {
+                helpers.callback(this.options.afterFit, [this]);
+            },
 
-					me.paddingTop = tickFontSize / 2;
-					me.paddingBottom = tickFontSize / 2;
-				}
-			}
-
-			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);
-			}
+            // Shared Methods
+            isHorizontal: function() {
+                return this.options.position === 'top' || this.options.position === 'bottom';
+            },
+            isFullWidth: function() {
+                return (this.options.fullWidth);
+            },
 
-			me.width = minSize.width;
-			me.height = minSize.height;
+            // 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);
+                }
 
-		},
-		afterFit: function() {
-			helpers.callCallback(this.options.afterFit, [this]);
-		},
+                // Value is good, return it
+                return rawValue;
+            },
 
-		// Shared Methods
-		isHorizontal: function() {
-			return this.options.position === "top" || this.options.position === "bottom";
-		},
-		isFullWidth: function() {
-			return (this.options.fullWidth);
-		},
+            // Used to get the value to display in the tooltip for the data at the given index
+            // function getLabelForIndex(index, datasetIndex)
+            getLabelForIndex: helpers.noop,
 
-		// 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
-			if (typeof(rawValue) === 'number' && isNaN(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;
-				} else {
-					return this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
-				}
-			}
+            // Used to get data value locations.  Value can either be an index or a numerical value
+            getPixelForValue: helpers.noop,
 
-			// Value is good, return it
-			return rawValue;
-		},
+            // Used to get the data value from a given pixel. This is the inverse of getPixelForValue
+            getValueForPixel: helpers.noop,
 
-		// 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 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;
 
-		// Used to get data value locations.  Value can either be an index or a numerical value
-		getPixelForValue: helpers.noop,
+                    if (includeOffset) {
+                        pixel += tickWidth / 2;
+                    }
 
-		// Used to get the data value from a given pixel. This is the inverse of getPixelForValue
-		getValueForPixel: helpers.noop,
+                    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)));
+            },
 
-		// 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;
+            // 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;
 
-				if (includeOffset) {
-					pixel += tickWidth / 2;
-				}
+                    var finalVal = me.left + Math.round(valueOffset);
+                    finalVal += me.isFullWidth() ? me.margins.left : 0;
+                    return finalVal;
+                }
+                return me.top + (decimal * me.height);
+            },
 
-				var finalVal = me.left + Math.round(pixel);
-				finalVal += me.isFullWidth() ? me.margins.left : 0;
-				return finalVal;
-			} else {
-				var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
-				return me.top + (index * (innerHeight / (me.ticks.length - 1)));
-			}
-		},
+            getBasePixel: function() {
+                return this.getPixelForValue(this.getBaseValue());
+            },
 
-		// 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;
+            getBaseValue: function() {
+                var me = this;
+                var min = me.min;
+                var max = me.max;
 
-				var finalVal = me.left + Math.round(valueOffset);
-				finalVal += me.isFullWidth() ? me.margins.left : 0;
-				return finalVal;
-			} else {
-				return me.top + (decimal * me.height);
-			}
-		},
+                return me.beginAtZero ? 0:
+                    min < 0 && max < 0? max :
+                        min > 0 && max > 0? min :
+                            0;
+            },
 
-		getBasePixel: function() {
-			var me = this;
-			var min = me.min;
-			var max = me.max;
+            // 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;
+                }
 
-			return me.getPixelForValue(
-				me.beginAtZero? 0:
-				min < 0 && max < 0? max :
-				min > 0 && max > 0? min :
-				0);
-		},
+                var context = me.ctx;
+                var globalDefaults = Chart.defaults.global;
+                var optionTicks = options.ticks;
+                var gridLines = options.gridLines;
+                var scaleLabel = options.scaleLabel;
 
-		// Actualy 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 isRotated = me.labelRotation !== 0;
+                var skipRatio;
+                var useAutoskipper = optionTicks.autoSkip;
+                var isHorizontal = me.isHorizontal();
 
-			var context = me.ctx;
-			var globalDefaults = Chart.defaults.global;
-			var optionTicks = options.ticks;
-			var gridLines = options.gridLines;
-			var scaleLabel = options.scaleLabel;
+                // figure out the maximum number of gridlines to show
+                var maxTicks;
+                if (optionTicks.maxTicksLimit) {
+                    maxTicks = optionTicks.maxTicksLimit;
+                }
 
-			var isRotated = me.labelRotation !== 0;
-			var skipRatio;
-			var useAutoskipper = optionTicks.autoSkip;
-			var isHorizontal = me.isHorizontal();
+                var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
+                var tickFont = parseFontOptions(optionTicks);
 
-			// figure out the maximum number of gridlines to show
-			var maxTicks;
-			if (optionTicks.maxTicksLimit) {
-				maxTicks = optionTicks.maxTicksLimit;
-			}
+                var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;
 
-			var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
-			var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-			var tl = gridLines.tickMarkLength;
+                var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
+                var scaleLabelFont = parseFontOptions(scaleLabel);
 
-			var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
-			var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize);
-			var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle);
-			var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily);
-			var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);
+                var labelRotationRadians = helpers.toRadians(me.labelRotation);
+                var cosRotation = Math.cos(labelRotationRadians);
+                var longestRotatedLabel = me.longestLabelWidth * cosRotation;
 
-			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;
 
-			// Make sure we draw text in the correct color and font
-			context.fillStyle = tickFontColor;
+                var itemsToDraw = [];
 
-			var itemsToDraw = [];
+                if (isHorizontal) {
+                    skipRatio = false;
 
-			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)));
+                    }
 
-				// Only calculate the skip ratio with the half width of longestRotateLabel if we got an actual rotation
-				// See #2584
-				if (isRotated) {
-					longestRotatedLabel /= 2;
-				}
+                    // 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 ((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 (!useAutoskipper) {
+                        skipRatio = false;
+                    }
+                }
 
-				// 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 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;
+                    var isLastTick = me.ticks.length === index + 1;
 
-			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;
-				}
+                    // 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 isLastTick = me.ticks.length === index + 1;
+                    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);
+                    }
 
-				// 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;
-				}
+                    // Common properties
+                    var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
+                    var textAlign = 'middle';
+                    var textBaseline = 'middle';
 
-				var lineWidth, lineColor;
-				if (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {
-					// Draw the first index specially
-					lineWidth = gridLines.zeroLineWidth;
-					lineColor = gridLines.zeroLineColor;
-				} else  {
-					lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);
-					lineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);
-				}
+                    if (isHorizontal) {
 
-				// Common properties
-				var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
-				var textAlign, textBaseline = 'middle';
+                        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;
+                        }
 
-				if (isHorizontal) {
-					if (!isRotated) {
-						textBaseline = options.position === 'top' ? 'bottom' : 'top';
-					}
+                        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)
 
-					textAlign = isRotated ? 'right' : 'center';
+                        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;
 
-					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)
-					labelY = (isRotated) ? me.top + 12 : options.position === 'top' ? me.bottom - tl : me.top + tl;
+                        if (optionTicks.mirror) {
+                            textAlign = isLeft ? 'left' : 'right';
+                            labelXOffset = tickPadding;
+                        } else {
+                            textAlign = isLeft ? 'right' : 'left';
+                            labelXOffset = tl + tickPadding;
+                        }
 
-					tx1 = tx2 = x1 = x2 = xLineValue;
-					ty1 = yTickStart;
-					ty2 = yTickEnd;
-					y1 = chartArea.top;
-					y2 = chartArea.bottom;
-				} else {
-					if (options.position === 'left') {
-						if (optionTicks.mirror) {
-							labelX = me.right + optionTicks.padding;
-							textAlign = 'left';
-						} else {
-							labelX = me.right - optionTicks.padding;
-							textAlign = 'right';
-						}
-					} else {
-						// right side
-						if (optionTicks.mirror) {
-							labelX = me.left - optionTicks.padding;
-							textAlign = 'right';
-						} else {
-							labelX = me.left + optionTicks.padding;
-							textAlign = 'left';
-						}
-					}
+                        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);
+                        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;
-				}
+                        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,
-					rotation: -1 * labelRotationRadians,
-					label: label,
-					textBaseline: textBaseline,
-					textAlign: textAlign
-				});
-			});
+                    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.lineWidth = itemToDraw.glWidth;
-					context.strokeStyle = itemToDraw.glColor;
+                // 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();
+                        context.beginPath();
 
-					if (gridLines.drawTicks) {
-						context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
-						context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
-					}
+                        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);
-					}
+                        if (gridLines.drawOnChartArea) {
+                            context.moveTo(itemToDraw.x1, itemToDraw.y1);
+                            context.lineTo(itemToDraw.x2, itemToDraw.y2);
+                        }
 
-					context.stroke();
-				}
+                        context.stroke();
+                        context.restore();
+                    }
 
-				if (optionTicks.display) {
-					context.save();
-					context.translate(itemToDraw.labelX, itemToDraw.labelY);
-					context.rotate(itemToDraw.rotation);
-					context.font = tickLabelFont;
-					context.textBaseline = itemToDraw.textBaseline;
-					context.textAlign = itemToDraw.textAlign;
+                    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 += (tickFontSize * 1.5);
-						}
-					} else {
-						context.fillText(label, 0, 0);
-					}
-					context.restore();
-				}
-			});
+                        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 (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 - (scaleLabelFontSize / 2) : me.top + (scaleLabelFontSize / 2);
-				} else {
-					var isLeft = options.position === 'left';
-					scaleLabelX = isLeft ? me.left + (scaleLabelFontSize / 2) : me.right - (scaleLabelFontSize / 2);
-					scaleLabelY = me.top + ((me.bottom - me.top) / 2);
-					rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
-				}
+                    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;
-				context.fillText(scaleLabel.labelString, 0, 0);
-				context.restore();
-			}
+                    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;
+                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;
-				}
+                    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();
-			}
-		}
-	});
-};
+                    context.beginPath();
+                    context.moveTo(x1, y1);
+                    context.lineTo(x2, y2);
+                    context.stroke();
+                }
+            }
+        });
+    };
 
 },{}],32:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        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
+        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(chartInstance) {
-			// Adds each scale to the chart.boxes array to be sized accordingly
-			helpers.each(chartInstance.scales, function(scale) {
-				Chart.layoutService.addBox(chartInstance, scale);
-			});
-		}
-	};
-};
+            // 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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.title = {
-		display: false,
-		position: 'top',
-		fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
+        /**
+         * 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
+                 */
 
-		fontStyle: 'bold',
-		padding: 10,
+                /**
+                 * 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.
 
-		// actual title
-		text: ''
-	};
+                    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;
 
-	var noop = helpers.noop;
-	Chart.Title = Chart.Element.extend({
+                    // 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;
+                        }
+                    }
 
-		initialize: function(config) {
-			var me = this;
-			helpers.extend(me, config);
-			me.options = helpers.configMerge(Chart.defaults.global.title, config.options);
+                    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);
+                    }
 
-			// Contains hit boxes for each dataset (in dataset order)
-			me.legendHitBoxes = [];
-		},
+                    // 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);
 
-		// These methods are ordered by lifecyle. Utilities then follow.
+                    return ticks;
+                },
 
-		beforeUpdate: function () {
-			var chartOpts = this.chart.options;
-			if (chartOpts && chartOpts.title) {
-				this.options = helpers.configMerge(Chart.defaults.global.title, chartOpts.title);
-			}
-		},
-		update: function(maxWidth, maxHeight, margins) {
-			var me = this;
+                /**
+                 * 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;
 
-			// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-			me.beforeUpdate();
+                    // 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))));
 
-			// Absorb the master measurements
-			me.maxWidth = maxWidth;
-			me.maxHeight = maxHeight;
-			me.margins = margins;
+                    var endExp = Math.floor(helpers.log10(dataRange.max));
+                    var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
+                    var exp;
+                    var significand;
 
-			// Dimensions
-			me.beforeSetDimensions();
-			me.setDimensions();
-			me.afterSetDimensions();
-			// Labels
-			me.beforeBuildLabels();
-			me.buildLabels();
-			me.afterBuildLabels();
+                    if (tickVal === 0) {
+                        exp = Math.floor(helpers.log10(dataRange.minNotZero));
+                        significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
 
-			// Fit
-			me.beforeFit();
-			me.fit();
-			me.afterFit();
-			//
-			me.afterUpdate();
+                        ticks.push(tickVal);
+                        tickVal = significand * Math.pow(10, exp);
+                    } else {
+                        exp = Math.floor(helpers.log10(tickVal));
+                        significand = Math.floor(tickVal / Math.pow(10, exp));
+                    }
 
-			return me.minSize;
+                    do {
+                        ticks.push(tickVal);
 
-		},
-		afterUpdate: noop,
+                        ++significand;
+                        if (significand === 10) {
+                            significand = 1;
+                            ++exp;
+                        }
 
-		//
+                        tickVal = significand * Math.pow(10, exp);
+                    } while (exp < endExp || (exp === endExp && significand < endSignificand));
 
-		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;
+                    var lastTick = getValueOrDefault(generationOptions.max, tickVal);
+                    ticks.push(lastTick);
 
-				// Reset position before calculating rotation
-				me.top = 0;
-				me.bottom = me.height;
-			}
+                    return ticks;
+                }
+            },
 
-			// Reset padding
-			me.paddingLeft = 0;
-			me.paddingTop = 0;
-			me.paddingRight = 0;
-			me.paddingBottom = 0;
+            /**
+             * 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;
+                },
 
-			// Reset minSize
-			me.minSize = {
-				width: 0,
-				height: 0
-			};
-		},
-		afterSetDimensions: noop,
+                /**
+                 * 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);
+                        }
+                    }
 
-		beforeBuildLabels: noop,
-		buildLabels: noop,
-		afterBuildLabels: noop,
+                    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
+                    }
 
-		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;
+                    return tickString;
+                },
 
-			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
-			}
+                logarithmic: function(tickValue, index, ticks) {
+                    var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
 
-			me.width = minSize.width;
-			me.height = minSize.height;
-
-		},
-		afterFit: noop,
-
-		// Shared Methods
-		isHorizontal: function() {
-			var pos = this.options.position;
-			return pos === "top" || pos === "bottom";
-		},
-
-		// Actualy 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;
-
-				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
-				} else {
-					titleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);
-					titleY = top + ((bottom - top) / 2);
-					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);
-				ctx.restore();
-			}
-		}
-	});
-
-	// Register the title plugin
-	Chart.plugins.register({
-		beforeInit: function(chartInstance) {
-			var opts = chartInstance.options;
-			var titleOpts = opts.title;
-
-			if (titleOpts) {
-				chartInstance.titleBlock = new Chart.Title({
-					ctx: chartInstance.chart.ctx,
-					options: titleOpts,
-					chart: chartInstance
-				});
-
-				Chart.layoutService.addBox(chartInstance, chartInstance.titleBlock);
-			}
-		}
-	});
-};
+                    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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.tooltips = {
-		enabled: true,
-		custom: null,
-		mode: 'single',
-		backgroundColor: "rgba(0,0,0,0.8)",
-		titleFontStyle: "bold",
-		titleSpacing: 2,
-		titleMarginBottom: 6,
-		titleFontColor: "#fff",
-		titleAlign: "left",
-		bodySpacing: 2,
-		bodyFontColor: "#fff",
-		bodyAlign: "left",
-		footerFontStyle: "bold",
-		footerSpacing: 2,
-		footerMarginTop: 6,
-		footerFontColor: "#fff",
-		footerAlign: "left",
-		yPadding: 6,
-		xPadding: 6,
-		yAlign : 'center',
-		xAlign : 'center',
-		caretSize: 5,
-		cornerRadius: 6,
-		multiKeyBackground: '#fff',
-		callbacks: {
-			// 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;
+        /**
+         * 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();
+        }
 
-				if (tooltipItems.length > 0) {
-					var item = tooltipItems[0];
+        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 (item.xLabel) {
-						title = item.xLabel;
-					} else if (labelCount > 0 && item.index < labelCount) {
-						title = labels[item.index];
-					}
-				}
+                    if (tooltipItems.length > 0) {
+                        var item = tooltipItems[0];
 
-				return title;
-			},
-			afterTitle: helpers.noop,
+                        if (item.xLabel) {
+                            title = item.xLabel;
+                        } else if (labelCount > 0 && item.index < labelCount) {
+                            title = labels[item.index];
+                        }
+                    }
 
-			// Args are: (tooltipItems, data)
-			beforeBody: helpers.noop,
+                    return title;
+                },
+                afterTitle: helpers.noop,
 
-			// Args are: (tooltipItem, data)
-			beforeLabel: helpers.noop,
-			label: function(tooltipItem, data) {
-				var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
-				return datasetLabel + ': ' + tooltipItem.yLabel;
-			},
-			labelColor: function(tooltipItem, chartInstance) {
-				var meta = chartInstance.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)
+                beforeBody: helpers.noop,
 
-			// Args are: (tooltipItems, data)
-			afterBody: helpers.noop,
+                // Args are: (tooltipItem, data)
+                beforeLabel: helpers.noop,
+                label: function(tooltipItem, data) {
+                    var label = data.datasets[tooltipItem.datasetIndex].label || '';
 
-			// Args are: (tooltipItems, data)
-			beforeFooter: helpers.noop,
-			footer: helpers.noop,
-			afterFooter: helpers.noop
-		}
-	};
+                    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,
 
-	// 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);
-			}
-		}
+                // Args are: (tooltipItems, data)
+                afterBody: helpers.noop,
 
-		return base;
-	}
+                // Args are: (tooltipItems, data)
+                beforeFooter: helpers.noop,
+                footer: helpers.noop,
+                afterFooter: helpers.noop
+            }
+        };
 
-	function getAveragePosition(elements) {
-		if (!elements.length) {
-			return false;
-		}
+        // 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);
+                }
+            }
 
-		var i, len;
-		var xPositions = [];
-		var yPositions = [];
+            return base;
+        }
 
-		for (i = 0, len = elements.length; i < len; ++i) {
-			var el = elements[i];
-			if (el && el.hasValue()){
-				var pos = el.tooltipPosition();
-				xPositions.push(pos.x);
-				yPositions.push(pos.y);
-			}
-		}
+        // 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;
 
-		var x = 0,
-			y = 0;
-		for (i = 0; i < xPositions.length; ++i) {
-			if (xPositions[ i ]) {
-				x += xPositions[i];
-				y += yPositions[i];
-			}
-		}
+            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
+            };
+        }
 
-		return {
-			x: Math.round(x / xPositions.length),
-			y: Math.round(y / xPositions.length)
-		};
-	}
+        /**
+         * 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;
 
-	// Private helper to create a tooltip iteam 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 {
+                // Positioning
+                xPadding: tooltipOpts.xPadding,
+                yPadding: tooltipOpts.yPadding,
+                xAlign: tooltipOpts.xAlign,
+                yAlign: tooltipOpts.yAlign,
 
-		return {
-			xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
-			yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
-			index: index,
-			datasetIndex: datasetIndex
-		};
-	}
+                // 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,
 
-	Chart.Tooltip = Chart.Element.extend({
-		initialize: function() {
-			var me = this;
-			var globalDefaults = Chart.defaults.global;
-			var tooltipOpts = me._options;
-			var getValueOrDefault = helpers.getValueOrDefault;
+                // 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,
 
-			helpers.extend(me, {
-				_model: {
-					// Positioning
-					xPadding: tooltipOpts.xPadding,
-					yPadding: tooltipOpts.yPadding,
-					xAlign : tooltipOpts.xAlign,
-					yAlign : tooltipOpts.yAlign,
+                // 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,
 
-					// 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,
+                // Appearance
+                caretSize: tooltipOpts.caretSize,
+                cornerRadius: tooltipOpts.cornerRadius,
+                backgroundColor: tooltipOpts.backgroundColor,
+                opacity: 0,
+                legendColorBackground: tooltipOpts.multiKeyBackground,
+                displayColors: tooltipOpts.displayColors,
+                borderColor: tooltipOpts.borderColor,
+                borderWidth: tooltipOpts.borderWidth
+            };
+        }
 
-					// 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,
+        /**
+         * Get the size of the tooltip
+         */
+        function getTooltipSize(tooltip, model) {
+            var ctx = tooltip._chart.ctx;
 
-					// 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,
+            var height = model.yPadding * 2; // Tooltip Padding
+            var width = 0;
 
-					// Appearance
-					caretSize: tooltipOpts.caretSize,
-					cornerRadius: tooltipOpts.cornerRadius,
-					backgroundColor: tooltipOpts.backgroundColor,
-					opacity: 0,
-					legendColorBackground: tooltipOpts.multiKeyBackground
-				}
-			});
-		},
+            // 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;
 
-		// Get the title
-		// Args are: (tooltipItem, data)
-		getTitle: function() {
-			var me = this;
-			var opts = me._options;
-			var callbacks = opts.callbacks;
+            var titleLineCount = model.title.length;
+            var footerLineCount = model.footer.length;
+            var titleFontSize = model.titleFontSize,
+                bodyFontSize = model.bodyFontSize,
+                footerFontSize = model.footerFontSize;
 
-			var beforeTitle = callbacks.beforeTitle.apply(me, arguments),
-				title = callbacks.title.apply(me, arguments),
-				afterTitle = callbacks.afterTitle.apply(me, arguments);
+            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
 
-			var lines = [];
-			lines = pushOrConcat(lines, beforeTitle);
-			lines = pushOrConcat(lines, title);
-			lines = pushOrConcat(lines, afterTitle);
+            // Title width
+            var widthPadding = 0;
+            var maxLineWidth = function(line) {
+                width = Math.max(width, ctx.measureText(line).width + widthPadding);
+            };
 
-			return lines;
-		},
+            ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
+            helpers.each(model.title, maxLineWidth);
 
-		// Args are: (tooltipItem, data)
-		getBeforeBody: function() {
-			var lines = this._options.callbacks.beforeBody.apply(this, arguments);
-			return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
-		},
+            // Body width
+            ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
+            helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);
 
-		// Args are: (tooltipItem, data)
-		getBody: function(tooltipItems, data) {
-			var me = this;
-			var callbacks = me._options.callbacks;
-			var bodyItems = [];
+            // 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);
+            });
 
-			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));
+            // Reset back to 0
+            widthPadding = 0;
 
-				bodyItems.push(bodyItem);
-			});
+            // Footer width
+            ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
+            helpers.each(model.footer, maxLineWidth);
 
-			return bodyItems;
-		},
+            // Add padding
+            width += 2 * model.xPadding;
 
-		// Args are: (tooltipItem, data)
-		getAfterBody: function() {
-			var lines = this._options.callbacks.afterBody.apply(this, arguments);
-			return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
-		},
+            return {
+                width: width,
+                height: height
+            };
+        }
 
-		// Get the footer and beforeFooter and afterFooter lines
-		// Args are: (tooltipItem, data)
-		getFooter: function() {
-			var me = this;
-			var callbacks = me._options.callbacks;
+        /**
+         * 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';
 
-			var beforeFooter = callbacks.beforeFooter.apply(me, arguments);
-			var footer = callbacks.footer.apply(me, arguments);
-			var afterFooter = callbacks.afterFooter.apply(me, arguments);
+            if (model.y < size.height) {
+                yAlign = 'top';
+            } else if (model.y > (chart.height - size.height)) {
+                yAlign = 'bottom';
+            }
 
-			var lines = [];
-			lines = pushOrConcat(lines, beforeFooter);
-			lines = pushOrConcat(lines, footer);
-			lines = pushOrConcat(lines, afterFooter);
+            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;
 
-			return lines;
-		},
+            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));
+                };
+            }
 
-		update: function(changed) {
-			var me = this;
-			var opts = me._options;
-			var model = me._model;
-			var active = me._active;
+            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';
+            };
 
-			var data = me._data;
-			var chartInstance = me._chartInstance;
+            if (lf(model.x)) {
+                xAlign = 'left';
 
-			var i, len;
+                // 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';
 
-			if (active.length) {
-				model.opacity = 1;
+                // Is tooltip too wide and goes outside left edge of canvas?
+                if (orf(model.x)) {
+                    xAlign = 'center';
+                    yAlign = yf(model.y);
+                }
+            }
 
-				var labelColors = [],
-					tooltipPosition = getAveragePosition(active);
+            var opts = tooltip._options;
+            return {
+                xAlign: opts.xAlign ? opts.xAlign : xAlign,
+                yAlign: opts.yAlign ? opts.yAlign : yAlign
+            };
+        }
 
-				var tooltipItems = [];
-				for (i = 0, len = active.length; i < len; ++i) {
-					tooltipItems.push(createTooltipItem(active[i]));
-				}
+        /**
+         * @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);
 
-				// If the user provided a sorting function, use it to modify the tooltip items
-				if (opts.itemSort) {
-					tooltipItems = tooltipItems.sort(opts.itemSort);
-				}
+                    // Initial positioning and colors
+                    model.x = Math.round(tooltipPosition.x);
+                    model.y = Math.round(tooltipPosition.y);
+                    model.caretPadding = opts.caretPadding;
+                    model.labelColors = labelColors;
 
-				// If there is more than one item, show color items
-				if (active.length > 1) {
-					helpers.each(tooltipItems, function(tooltipItem) {
-						labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, chartInstance));
-					});
-				}
+                    // data points
+                    model.dataPoints = tooltipItems;
 
-				// Build the Text Lines
-				helpers.extend(model, {
-					title: me.getTitle(tooltipItems, data),
-					beforeBody: me.getBeforeBody(tooltipItems, data),
-					body: me.getBody(tooltipItems, data),
-					afterBody: me.getAfterBody(tooltipItems, data),
-					footer: me.getFooter(tooltipItems, data),
-					x: Math.round(tooltipPosition.x),
-					y: Math.round(tooltipPosition.y),
-					caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),
-					labelColors: labelColors
-				});
+                    // 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;
+                }
 
-				// We need to determine alignment of
-				var tooltipSize = me.getTooltipSize(model);
-				me.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas
+                model.xAlign = alignment.xAlign;
+                model.yAlign = alignment.yAlign;
+                model.x = backgroundPoint.x;
+                model.y = backgroundPoint.y;
+                model.width = tooltipSize.width;
+                model.height = tooltipSize.height;
 
-				helpers.extend(model, me.getBackgroundPoint(model, tooltipSize));
-			} else {
-				me._model.opacity = 0;
-			}
+                // Point where the caret on the tooltip points to
+                model.caretX = tooltipPosition.x;
+                model.caretY = tooltipPosition.y;
 
-			if (changed && opts.custom) {
-				opts.custom.call(me, model);
-			}
+                me._model = model;
 
-			return me;
-		},
-		getTooltipSize: function(vm) {
-			var ctx = this._chart.ctx;
+                if (changed && opts.custom) {
+                    opts.custom.call(me, model);
+                }
 
-			var size = {
-				height: vm.yPadding * 2, // Tooltip Padding
-				width: 0
-			};
+                return me;
+            },
+            drawCaret: function(tooltipPoint, size) {
+                var ctx = this._chart.ctx;
+                var vm = this._view;
+                var caretPosition = this.getCaretPosition(tooltipPoint, size, vm);
 
-			// Count of all lines in the body
-			var body = vm.body;
-			var combinedBodyLength = body.reduce(function(count, bodyItem) {
-				return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
-			}, 0);
-			combinedBodyLength += vm.beforeBody.length + vm.afterBody.length;
+                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;
 
-			var titleLineCount = vm.title.length;
-			var footerLineCount = vm.footer.length;
-			var titleFontSize = vm.titleFontSize,
-				bodyFontSize = vm.bodyFontSize,
-				footerFontSize = vm.footerFontSize;
+                if (yAlign === 'center') {
+                    y2 = ptY + (height / 2);
 
-			size.height += titleLineCount * titleFontSize; // Title Lines
-			size.height += (titleLineCount - 1) * vm.titleSpacing; // Title Line Spacing
-			size.height += titleLineCount ? vm.titleMarginBottom : 0; // Title's bottom Margin
-			size.height += combinedBodyLength * bodyFontSize; // Body Lines
-			size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing
-			size.height += footerLineCount ? vm.footerMarginTop : 0; // Footer Margin
-			size.height += footerLineCount * (footerFontSize); // Footer Lines
-			size.height += footerLineCount ? (footerLineCount - 1) * vm.footerSpacing : 0; // Footer Line Spacing
+                    if (xAlign === 'left') {
+                        x1 = ptX;
+                        x2 = x1 - caretSize;
+                        x3 = x1;
 
-			// Title width
-			var widthPadding = 0;
-			var maxLineWidth = function(line) {
-				size.width = Math.max(size.width, ctx.measureText(line).width + widthPadding);
-			};
+                        y1 = y2 + caretSize;
+                        y3 = y2 - caretSize;
+                    } else {
+                        x1 = ptX + width;
+                        x2 = x1 + caretSize;
+                        x3 = x1;
 
-			ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
-			helpers.each(vm.title, maxLineWidth);
+                        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;
 
-			// Body width
-			ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
-			helpers.each(vm.beforeBody.concat(vm.afterBody), maxLineWidth);
+                if (title.length) {
+                    ctx.textAlign = vm._titleAlign;
+                    ctx.textBaseline = 'top';
 
-			// Body lines may include some extra width due to the color box
-			widthPadding = body.length > 1 ? (bodyFontSize + 2) : 0;
-			helpers.each(body, function(bodyItem) {
-				helpers.each(bodyItem.before, maxLineWidth);
-				helpers.each(bodyItem.lines, maxLineWidth);
-				helpers.each(bodyItem.after, maxLineWidth);
-			});
+                    var titleFontSize = vm.titleFontSize,
+                        titleSpacing = vm.titleSpacing;
 
-			// Reset back to 0
-			widthPadding = 0;
+                    ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
+                    ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
 
-			// Footer width
-			ctx.font = helpers.fontString(footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
-			helpers.each(vm.footer, maxLineWidth);
+                    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
 
-			// Add padding
-			size.width += 2 * vm.xPadding;
+                        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;
 
-			return size;
-		},
-		determineAlignment: function(size) {
-			var me = this;
-			var model = me._model;
-			var chart = me._chart;
-			var chartArea = me._chartInstance.chartArea;
+                ctx.textAlign = vm._bodyAlign;
+                ctx.textBaseline = 'top';
 
-			if (model.y < size.height) {
-				model.yAlign = 'top';
-			} else if (model.y > (chart.height - size.height)) {
-				model.yAlign = 'bottom';
-			}
+                var textColor = mergeOpacity(vm.bodyFontColor, opacity);
+                ctx.fillStyle = textColor;
+                ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
 
-			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;
+                // Before Body
+                var xLinePadding = 0;
+                var fillLineOfText = function(line) {
+                    ctx.fillText(line, pt.x + xLinePadding, pt.y);
+                    pt.y += bodyFontSize + bodySpacing;
+                };
 
-			if (model.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));
-				};
-			}
+                // Before body lines
+                helpers.each(vm.beforeBody, fillLineOfText);
 
-			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';
-			};
+                var drawColorBoxes = vm.displayColors;
+                xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
 
-			if (lf(model.x)) {
-				model.xAlign = 'left';
+                // Draw body lines now
+                helpers.each(body, function(bodyItem, i) {
+                    helpers.each(bodyItem.before, fillLineOfText);
 
-				// Is tooltip too wide and goes over the right side of the chart.?
-				if (olf(model.x)) {
-					model.xAlign = 'center';
-					model.yAlign = yf(model.y);
-				}
-			} else if (rf(model.x)) {
-				model.xAlign = 'right';
+                    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);
 
-				// Is tooltip too wide and goes outside left edge of canvas?
-				if (orf(model.x)) {
-					model.xAlign = 'center';
-					model.yAlign = yf(model.y);
-				}
-			}
-		},
-		getBackgroundPoint: function(vm, size) {
-			// Background Position
-			var pt = {
-				x: vm.x,
-				y: vm.y
-			};
+                            // Border
+                            ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
+                            ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
 
-			var caretSize = vm.caretSize,
-				caretPadding = vm.caretPadding,
-				cornerRadius = vm.cornerRadius,
-				xAlign = vm.xAlign,
-				yAlign = vm.yAlign,
-				paddingAndSize = caretSize + caretPadding,
-				radiusAndPadding = cornerRadius + caretPadding;
+                            // Inner square
+                            ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
+                            ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
 
-			if (xAlign === 'right') {
-				pt.x -= size.width;
-			} else if (xAlign === 'center') {
-				pt.x -= (size.width / 2);
-			}
+                            ctx.fillStyle = textColor;
+                        }
 
-			if (yAlign === 'top') {
-				pt.y += paddingAndSize;
-			} else if (yAlign === 'bottom') {
-				pt.y -= size.height + paddingAndSize;
-			} else {
-				pt.y -= (size.height / 2);
-			}
+                        fillLineOfText(line);
+                    });
 
-			if (yAlign === 'center') {
-				if (xAlign === 'left') {
-					pt.x += paddingAndSize;
-				} else if (xAlign === 'right') {
-					pt.x -= paddingAndSize;
-				}
-			} else {
-				if (xAlign === 'left') {
-					pt.x -= radiusAndPadding;
-				} else if (xAlign === 'right') {
-					pt.x += radiusAndPadding;
-				}
-			}
+                    helpers.each(bodyItem.after, fillLineOfText);
+                });
 
-			return pt;
-		},
-		drawCaret: function(tooltipPoint, size, opacity) {
-			var vm = this._view;
-			var ctx = this._chart.ctx;
-			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;
+                // Reset back to 0 for after body
+                xLinePadding = 0;
 
-			if (yAlign === 'center') {
-				// Left or right side
-				if (xAlign === 'left') {
-					x1 = ptX;
-					x2 = x1 - caretSize;
-					x3 = x1;
-				} else {
-					x1 = ptX + width;
-					x2 = x1 + caretSize;
-					x3 = x1;
-				}
+                // 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;
 
-				y2 = ptY + (height / 2);
-				y1 = y2 - caretSize;
-				y3 = y2 + caretSize;
-			} else {
-				if (xAlign === 'left') {
-					x1 = ptX + cornerRadius;
-					x2 = x1 + caretSize;
-					x3 = x2 + caretSize;
-				} else if (xAlign === 'right') {
-					x1 = ptX + width - cornerRadius;
-					x2 = x1 - caretSize;
-					x3 = x2 - caretSize;
-				} else {
-					x2 = ptX + (width / 2);
-					x1 = x2 - caretSize;
-					x3 = x2 + caretSize;
-				}
+                if (footer.length) {
+                    pt.y += vm.footerMarginTop;
 
-				if (yAlign === 'top') {
-					y1 = ptY;
-					y2 = y1 - caretSize;
-					y3 = y1;
-				} else {
-					y1 = ptY + height;
-					y2 = y1 + caretSize;
-					y3 = y1;
-				}
-			}
+                    ctx.textAlign = vm._footerAlign;
+                    ctx.textBaseline = 'top';
 
-			var bgColor = helpers.color(vm.backgroundColor);
-			ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
-			ctx.beginPath();
-			ctx.moveTo(x1, y1);
-			ctx.lineTo(x2, y2);
-			ctx.lineTo(x3, y3);
-			ctx.closePath();
-			ctx.fill();
-		},
-		drawTitle: function(pt, vm, ctx, opacity) {
-			var title = vm.title;
+                    ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
+                    ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
 
-			if (title.length) {
-				ctx.textAlign = vm._titleAlign;
-				ctx.textBaseline = "top";
+                    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;
 
-				var titleFontSize = vm.titleFontSize,
-					titleSpacing = vm.titleSpacing;
+                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();
 
-				var titleFontColor = helpers.color(vm.titleFontColor);
-				ctx.fillStyle = titleFontColor.alpha(opacity * titleFontColor.alpha()).rgbString();
-				ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
+                ctx.fill();
 
-				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 (vm.borderWidth > 0) {
+                    ctx.stroke();
+                }
+            },
+            draw: function() {
+                var ctx = this._chart.ctx;
+                var vm = this._view;
 
-					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;
+                if (vm.opacity === 0) {
+                    return;
+                }
 
-			ctx.textAlign = vm._bodyAlign;
-			ctx.textBaseline = "top";
+                var tooltipSize = {
+                    width: vm.width,
+                    height: vm.height
+                };
+                var pt = {
+                    x: vm.x,
+                    y: vm.y
+                };
 
-			var bodyFontColor = helpers.color(vm.bodyFontColor);
-			var textColor = bodyFontColor.alpha(opacity * bodyFontColor.alpha()).rgbString();
-			ctx.fillStyle = textColor;
-			ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
+                // IE11/Edge does not like very small opacities, so snap to 0
+                var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
 
-			// Before Body
-			var xLinePadding = 0;
-			var fillLineOfText = function(line) {
-				ctx.fillText(line, pt.x + xLinePadding, pt.y);
-				pt.y += bodyFontSize + bodySpacing;
-			};
+                // Truthy/falsey value for empty tooltip
+                var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
 
-			// Before body lines
-			helpers.each(vm.beforeBody, fillLineOfText);
+                if (this._options.enabled && hasTooltipContent) {
+                    // Draw Background
+                    this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
 
-			var drawColorBoxes = body.length > 1;
-			xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
+                    // Draw Title, Body, and Footer
+                    pt.x += vm.xPadding;
+                    pt.y += vm.yPadding;
 
-			// Draw body lines now
-			helpers.each(body, function(bodyItem, i) {
-				helpers.each(bodyItem.before, fillLineOfText);
+                    // Titles
+                    this.drawTitle(pt, vm, ctx, opacity);
 
-				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 = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();
-						ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+                    // Body
+                    this.drawBody(pt, vm, ctx, opacity);
 
-						// Border
-						ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();
-						ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+                    // Footer
+                    this.drawFooter(pt, vm, ctx, opacity);
+                }
+            },
 
-						// Inner square
-						ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();
-						ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
+            /**
+             * 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;
 
-						ctx.fillStyle = textColor;
-					}
+                me._lastActive = me._lastActive || [];
 
-					fillLineOfText(line);
-				});
+                // Find Active Elements for tooltips
+                if (e.type === 'mouseout') {
+                    me._active = [];
+                } else {
+                    me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
+                }
 
-				helpers.each(bodyItem.after, fillLineOfText);
-			});
+                // Remember Last Actives
+                changed = !helpers.arrayEquals(me._active, me._lastActive);
 
-			// Reset back to 0 for after body
-			xLinePadding = 0;
+                // If tooltip didn't change, do not handle the target event
+                if (!changed) {
+                    return false;
+                }
 
-			// 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;
+                me._lastActive = me._active;
 
-			if (footer.length) {
-				pt.y += vm.footerMarginTop;
+                if (options.enabled || options.custom) {
+                    me._eventPosition = {
+                        x: e.x,
+                        y: e.y
+                    };
 
-				ctx.textAlign = vm._footerAlign;
-				ctx.textBaseline = "top";
+                    var model = me._model;
+                    me.update(true);
+                    me.pivot();
 
-				var footerFontColor = helpers.color(vm.footerFontColor);
-				ctx.fillStyle = footerFontColor.alpha(opacity * footerFontColor.alpha()).rgbString();
-				ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
+                    // See if our tooltip position changed
+                    changed |= (model.x !== me._model.x) || (model.y !== me._model.y);
+                }
 
-				helpers.each(footer, function(line) {
-					ctx.fillText(line, pt.x, pt.y);
-					pt.y += vm.footerFontSize + vm.footerSpacing;
-				});
-			}
-		},
-		draw: function() {
-			var ctx = this._chart.ctx;
-			var vm = this._view;
+                return changed;
+            }
+        });
 
-			if (vm.opacity === 0) {
-				return;
-			}
+        /**
+         * @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 tooltipSize = this.getTooltipSize(vm);
-			var pt = {
-				x: vm.x,
-				y: vm.y
-			};
+                var i, len;
+                var x = 0;
+                var y = 0;
+                var count = 0;
 
-			// IE11/Edge does not like very small opacities, so snap to 0
-			var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
+                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;
+                    }
+                }
 
-			if (this._options.enabled) {
-				// Draw Background
-				var bgColor = helpers.color(vm.backgroundColor);
-				ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
-				helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);
-				ctx.fill();
+                return {
+                    x: Math.round(x / count),
+                    y: Math.round(y / count)
+                };
+            },
 
-				// Draw Caret
-				this.drawCaret(pt, tooltipSize, opacity);
+            /**
+             * 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;
 
-				// Draw Title, Body, and Footer
-				pt.x += vm.xPadding;
-				pt.y += vm.yPadding;
+                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);
 
-				// Titles
-				this.drawTitle(pt, vm, ctx, opacity);
+                        if (d < minDistance) {
+                            minDistance = d;
+                            nearestElement = el;
+                        }
+                    }
+                }
 
-				// Body
-				this.drawBody(pt, vm, ctx, opacity);
+                if (nearestElement) {
+                    var tp = nearestElement.tooltipPosition();
+                    x = tp.x;
+                    y = tp.y;
+                }
 
-				// Footer
-				this.drawFooter(pt, vm, ctx, opacity);
-			}
-		}
-	});
-};
+                return {
+                    x: x,
+                    y: y
+                };
+            }
+        };
+    };
 
 },{}],35:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-  var helpers = Chart.helpers,
-    globalOpts = Chart.defaults.global;
+        var helpers = Chart.helpers,
+            globalOpts = Chart.defaults.global;
 
-  globalOpts.elements.arc = {
-    backgroundColor: globalOpts.defaultColor,
-    borderColor: "#fff",
-    borderWidth: 2
-  };
+        globalOpts.elements.arc = {
+            backgroundColor: globalOpts.defaultColor,
+            borderColor: '#fff',
+            borderWidth: 2
+        };
 
-  Chart.elements.Arc = Chart.Element.extend({
-    inLabelRange: function(mouseX) {
-      var vm = this._view;
+        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));
-      } else {
-        return false;
-      }
-    },
-    inRange: function(chartX, chartY) {
-      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;
+                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;
-        }
+                    // 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);
+                    // 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);
-      } else {
-        return false;
-      }
-    },
-    tooltipPosition: function() {
-      var vm = this._view;
+                    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 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;
+                var ctx = this._chart.ctx,
+                    vm = this._view,
+                    sA = vm.startAngle,
+                    eA = vm.endAngle;
 
-      ctx.beginPath();
+                ctx.beginPath();
 
-      ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
-      ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
+                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.closePath();
+                ctx.strokeStyle = vm.borderColor;
+                ctx.lineWidth = vm.borderWidth;
 
-      ctx.fillStyle = vm.backgroundColor;
+                ctx.fillStyle = vm.backgroundColor;
 
-      ctx.fill();
-      ctx.lineJoin = 'bevel';
+                ctx.fill();
+                ctx.lineJoin = 'bevel';
 
-      if (vm.borderWidth) {
-        ctx.stroke();
-      }
-    }
-  });
-};
+                if (vm.borderWidth) {
+                    ctx.stroke();
+                }
+            }
+        });
+    };
 
 },{}],36:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var globalDefaults = Chart.defaults.global;
+        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.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 spanGaps = vm.spanGaps;
-			var scaleZero = vm.scaleZero;
-			var loop = me._loop;
+        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;
 
-			var ctx = me._chart.ctx;
-			ctx.save();
+                // If we are looping, adding the first point again
+                if (me._loop && points.length) {
+                    points.push(points[0]);
+                }
 
-			// Helper function to draw a line to a point
-			function lineToPoint(previousPoint, point) {
-				var vm = point._view;
-				if (point._view.steppedLine === true) {
-					ctx.lineTo(point._view.x, previousPoint._view.y);
-					ctx.lineTo(point._view.x, point._view.y);				
-				} else if (point._view.tension === 0) {
-					ctx.lineTo(vm.x, vm.y);
-				} else {
-					ctx.bezierCurveTo(
-						previousPoint._view.controlPointNextX,
-						previousPoint._view.controlPointNextY,
-						vm.controlPointPreviousX,
-						vm.controlPointPreviousY,
-						vm.x,
-						vm.y
-					);
-				}
-			}
+                ctx.save();
 
-			var points = me._children.slice(); // clone array
-			var lastDrawnIndex = -1;
+                // Stroke Line Options
+                ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
 
-			// If we are looping, adding the first point again
-			if (loop && points.length) {
-				points.push(points[0]);
-			}
+                // IE 9 and 10 do not support line dash
+                if (ctx.setLineDash) {
+                    ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
+                }
 
-			var index, current, previous, currentVM;
+                ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
+                ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
+                ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
+                ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
 
-			// Fill Line
-			if (points.length && vm.fill) {
-				ctx.beginPath();
+                // Stroke Line
+                ctx.beginPath();
+                lastDrawnIndex = -1;
 
-				for (index = 0; index < points.length; ++index) {
-					current = points[index];
-					previous = helpers.previousItem(points, index);
-					currentVM = current._view;
+                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 (loop) {
-							ctx.moveTo(scaleZero.x, scaleZero.y);
-						} else {
-							ctx.moveTo(currentVM.x, scaleZero);
-						}
+                    // 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) {
-							lastDrawnIndex = index;
-							ctx.lineTo(currentVM.x, currentVM.y);
-						}
-					} 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;
+                        }
+                    }
+                }
 
-						if (currentVM.skip) {
-							// Only do this if this is the first point that is skipped
-							if (!spanGaps && lastDrawnIndex === (index - 1)) {
-								if (loop) {
-									ctx.lineTo(scaleZero.x, scaleZero.y);
-								} else {
-									ctx.lineTo(previous._view.x, scaleZero);
-								}
-							}
-						} else {
-							if (lastDrawnIndex !== (index - 1)) {
-								// There was a gap and this is the first point after the gap. If we've never drawn a point, this is a special case. 
-								// If the first data point is NaN, then there is no real gap to skip
-								if (spanGaps && lastDrawnIndex !== -1) {
-									// We are spanning the gap, so simple draw a line to this point
-									lineToPoint(previous, current);
-								} else {
-									if (loop) {
-										ctx.lineTo(currentVM.x, currentVM.y);
-									} else {
-										ctx.lineTo(currentVM.x, scaleZero);
-										ctx.lineTo(currentVM.x, currentVM.y);
-									}
-								}
-							} else {
-								// Line to next point
-								lineToPoint(previous, current);
-							}
-							lastDrawnIndex = index;
-						}
-					}
-				}
+                ctx.stroke();
+                ctx.restore();
+            }
+        });
+    };
 
-				if (!loop) {
-					ctx.lineTo(points[lastDrawnIndex]._view.x, scaleZero);
-				}
-
-				ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;
-				ctx.closePath();
-				ctx.fill();
-			}
-
-			// Stroke Line Options
-			var globalOptionLineElements = globalDefaults.elements.line;
-			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) {
-						
-					} else {
-						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
-							lineToPoint(previous, current);
-						}
-						lastDrawnIndex = index;
-					}
-				}
-			}
-
-			ctx.stroke();
-			ctx.restore();
-		}
-	});
-};
 },{}],37:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers,
-		globalOpts = Chart.defaults.global,
-		defaultColor = globalOpts.defaultColor;
+        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
-	};
+        globalOpts.elements.point = {
+            radius: 3,
+            pointStyle: 'circle',
+            backgroundColor: defaultColor,
+            borderWidth: 1,
+            borderColor: defaultColor,
+            // Hover
+            hitRadius: 1,
+            hoverRadius: 4,
+            hoverBorderWidth: 1
+        };
 
-	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: function(mouseX) {
-			var vm = this._view;
-			return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
-		},
-		tooltipPosition: function() {
-			var vm = this._view;
-			return {
-				x: vm.x,
-				y: vm.y,
-				padding: vm.radius + vm.borderWidth
-			};
-		},
-		draw: function() {
-			var vm = this._view;
-			var ctx = this._chart.ctx;
-			var pointStyle = vm.pointStyle;
-			var radius = vm.radius;
-			var x = vm.x;
-			var y = vm.y;
+        function xRange(mouseX) {
+            var vm = this._view;
+            return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
+        }
 
-			if (vm.skip) {
-				return;
-			}
+        function yRange(mouseY) {
+            var vm = this._view;
+            return vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
+        }
 
-			ctx.strokeStyle = vm.borderColor || defaultColor;
-			ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);
-			ctx.fillStyle = vm.backgroundColor || defaultColor;
+        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;
+            },
 
-			Chart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);
-		}
-	});
-};
+            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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var globalOpts = Chart.defaults.global;
+        var globalOpts = Chart.defaults.global;
 
-	globalOpts.elements.rectangle = {
-		backgroundColor: globalOpts.defaultColor,
-		borderWidth: 0,
-		borderColor: globalOpts.defaultColor,
-		borderSkipped: 'bottom'
-	};
+        globalOpts.elements.rectangle = {
+            backgroundColor: globalOpts.defaultColor,
+            borderWidth: 0,
+            borderColor: globalOpts.defaultColor,
+            borderSkipped: 'bottom'
+        };
 
-	Chart.elements.Rectangle = Chart.Element.extend({
-		draw: function() {
-			var ctx = this._chart.ctx;
-			var vm = this._view;
+        function isVertical(bar) {
+            return bar._view.width !== undefined;
+        }
 
-			var halfWidth = vm.width / 2,
-				leftX = vm.x - halfWidth,
-				rightX = vm.x + halfWidth,
-				top = vm.base - (vm.base - vm.y),
-				halfStroke = vm.borderWidth / 2;
+        /**
+         * 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;
 
-			// 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 (vm.borderWidth) {
-				leftX += halfStroke;
-				rightX -= halfStroke;
-				top += halfStroke;
-			}
+            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;
+            }
 
-			ctx.beginPath();
-			ctx.fillStyle = vm.backgroundColor;
-			ctx.strokeStyle = vm.borderColor;
-			ctx.lineWidth = vm.borderWidth;
+            return {
+                left: x1,
+                top: y1,
+                right: x2,
+                bottom: y2
+            };
+        }
 
-			// Corner points, from bottom-left to bottom-right clockwise
-			// | 1 2 |
-			// | 0 3 |
-			var corners = [
-				[leftX, vm.base],
-				[leftX, top],
-				[rightX, top],
-				[rightX, vm.base]
-			];
+        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;
 
-			// Find first (starting) corner with fallback to 'bottom'
-			var borders = ['bottom', 'left', 'top', 'right'];
-			var startCorner = borders.indexOf(vm.borderSkipped, 0);
-			if (startCorner === -1)
-				startCorner = 0;
+                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';
+                }
 
-			function cornerAt(index) {
-				return corners[(startCorner + index) % 4];
-			}
+                // 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;
+                    }
+                }
 
-			// Draw rectangle from 'startCorner'
-			ctx.moveTo.apply(ctx, cornerAt(0));
-			for (var i = 1; i < 4; i++)
-				ctx.lineTo.apply(ctx, cornerAt(i));
+                ctx.beginPath();
+                ctx.fillStyle = vm.backgroundColor;
+                ctx.strokeStyle = vm.borderColor;
+                ctx.lineWidth = borderWidth;
 
-			ctx.fill();
-			if (vm.borderWidth) {
-				ctx.stroke();
-			}
-		},
-		height: function() {
-			var vm = this._view;
-			return vm.base - vm.y;
-		},
-		inRange: function(mouseX, mouseY) {
-			var vm = this._view;
-			return vm ?
-					(vm.y < vm.base ?
-						(mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.y && mouseY <= vm.base) :
-						(mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.base && mouseY <= vm.y)) :
-					false;
-		},
-		inLabelRange: function(mouseX) {
-			var vm = this._view;
-			return vm ? (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) : false;
-		},
-		tooltipPosition: function() {
-			var vm = this._view;
-			return {
-				x: vm.x,
-				y: vm.y
-			};
-		}
-	});
+                // 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";
+    'use strict';
 
-module.exports = function(Chart) {
+// Chart.Platform implementation for targeting a web browser
+    module.exports = function(Chart) {
+        var helpers = Chart.helpers;
 
-	var helpers = Chart.helpers;
-	// Default config for a category scale
-	var defaultConfig = {
-		position: "bottom"
-	};
+        // 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',
 
-	var DatasetScale = Chart.Scale.extend({
-		/**
-		* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use tose
-		* else fall back to data.labels
-		* @private
-		*/
-		getLabels: function() {
-			var data = this.chart.data;
-			return (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
-		},
-		// Implement this so that
-		determineDataLimits: function() {
-			var me = this;
-			var labels = me.getLabels(); 
-			me.minIndex = 0;
-			me.maxIndex = labels.length - 1;
-			var findIndex;
+            // Pointer events
+            pointerenter: 'mouseenter',
+            pointerdown: 'mousedown',
+            pointermove: 'mousemove',
+            pointerup: 'mouseup',
+            pointerleave: 'mouseout',
+            pointerout: 'mouseout'
+        };
 
-			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;
-			}
+        /**
+         * 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;
+        }
 
-			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;
-			}
+        /**
+         * 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;
 
-			me.min = labels[me.minIndex];
-			me.max = labels[me.maxIndex];
-		},
+            // 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');
 
-		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);
-		},
+            // 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
+                    }
+                }
+            };
 
-		getLabelForIndex: function(index) {
-			return this.ticks[index];
-		},
+            // 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';
 
-		// 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 (renderWidth === null || renderWidth === '') {
+                var displayWidth = readUsedSize(canvas, 'width');
+                if (displayWidth !== undefined) {
+                    canvas.width = displayWidth;
+                }
+            }
 
-			if (value !== undefined) {
-				var labels = me.getLabels();
-				var idx = labels.indexOf(value);
-				index = idx !== -1 ? idx : index;
-			}
+            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;
+                    }
+                }
+            }
 
-			if (me.isHorizontal()) {
-				var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-				var valueWidth = innerWidth / offsetAmt;
-				var widthOffset = (valueWidth * (index - me.minIndex)) + me.paddingLeft;
+            return canvas;
+        }
 
-				if (me.options.gridLines.offsetGridLines && includeOffset) {
-					widthOffset += (valueWidth / 2);
-				}
+        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,
+            };
+        }
 
-				return me.left + Math.round(widthOffset);
-			} else {
-				var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
-				var valueHeight = innerHeight / offsetAmt;
-				var heightOffset = (valueHeight * (index - me.minIndex)) + me.paddingTop;
+        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);
+        }
 
-				if (me.options.gridLines.offsetGridLines && includeOffset) {
-					heightOffset += (valueHeight / 2);
-				}
+        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;';
 
-				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 innerDimension = horz ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);
-			var valueDimension = innerDimension / offsetAmt;
+            // Prevent the iframe to gain focus on tab.
+            // https://github.com/chartjs/Chart.js/issues/3090
+            iframe.tabIndex = -1;
 
-			pixel -= horz ? me.left : me.top;
+            // 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);
 
-			if (me.options.gridLines.offsetGridLines) {
-				pixel -= (valueDimension / 2);
-			}
-			pixel -= horz ? me.paddingLeft : me.paddingTop;
+                // The iframe size might have changed while loading, which can also
+                // happen if the size has been changed while detached from the DOM.
+                handler();
+            });
 
-			if (pixel <= 0) {
-				value = 0;
-			} else {
-				value = Math.round(pixel / valueDimension);
-			}
+            return iframe;
+        }
 
-			return value;
-		},
-		getBasePixel: function() {
-			return this.bottom;
-		}
-	});
+        function addResizeListener(node, listener, chart) {
+            var stub = node._chartjs = {
+                ticking: false
+            };
 
-	Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);
+            // 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";
+    'use strict';
 
-module.exports = function(Chart) {
+// By default, select the browser (DOM) platform.
+// @TODO Make possible to select another platform at build time.
+    var implementation = require(39);
 
-	var helpers = Chart.helpers;
+    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() {},
 
-	var defaultConfig = {
-		position: "left",
-		ticks: {
-			callback: 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];
+            /**
+             * 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() {},
 
-				// 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);
-					}
-				}
+            /**
+             * 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() {},
 
-				var logDelta = helpers.log10(Math.abs(delta));
-				var tickString = '';
+            /**
+             * 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() {}
+        };
 
-				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
-				}
+        /**
+         * @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
+         */
 
-				return tickString;
-			}
-		}
-	};
+        /**
+         * @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)
+         */
 
-	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();
+        Chart.helpers.extend(Chart.platform, implementation(Chart));
+    };
 
-			function IDMatches(meta) {
-				return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
-			}
+},{"39":39}],41:[function(require,module,exports){
+    'use strict';
 
-			// First Calculate the range
-			me.min = null;
-			me.max = null;
+    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
+        };
 
-			if (opts.stacked) {
-				var valuesPerType = {};
-				var hasPositiveValues = false;
-				var hasNegativeValues = false;
+        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) || [];
 
-				helpers.each(datasets, function(dataset, datasetIndex) {
-					var meta = chart.getDatasetMeta(datasetIndex);
-					if (valuesPerType[meta.type] === undefined) {
-						valuesPerType[meta.type] = {
-							positiveValues: [],
-							negativeValues: []
-						};
-					}
+                return !points.length? null : function(point, i) {
+                    return points[i]._view || null;
+                };
+            },
 
-					// Store these per type
-					var positiveValues = valuesPerType[meta.type].positiveValues;
-					var negativeValues = valuesPerType[meta.type].negativeValues;
+            boundary: function(source) {
+                var boundary = source.boundary;
+                var x = boundary? boundary.x : null;
+                var y = boundary? boundary.y : null;
 
-					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;
-							}
+                return function(point) {
+                    return {
+                        x: x === null? point.x : x,
+                        y: y === null? point.y : y,
+                    };
+                };
+            }
+        };
 
-							positiveValues[index] = positiveValues[index] || 0;
-							negativeValues[index] = negativeValues[index] || 0;
+        // @todo if (fill[0] === '#')
+        function decodeFill(el, index, count) {
+            var model = el._model || {};
+            var fill = model.fill;
+            var target;
 
-							if (opts.relativePoints) {
-								positiveValues[index] = 100;
-							} else {
-								if (value < 0) {
-									hasNegativeValues = true;
-									negativeValues[index] += value;
-								} else {
-									hasPositiveValues = true;
-									positiveValues[index] += value;
-								}
-							}
-						});
-					}
-				});
+            if (fill === undefined) {
+                fill = !!model.backgroundColor;
+            }
 
-				helpers.each(valuesPerType, 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);
-				});
+            if (fill === false || fill === null) {
+                return false;
+            }
 
-			} 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 (fill === true) {
+                return 'origin';
+            }
 
-							if (me.min === null) {
-								me.min = value;
-							} else if (value < me.min) {
-								me.min = value;
-							}
+            target = parseFloat(fill, 10);
+            if (isFinite(target) && Math.floor(target) === target) {
+                if (fill[0] === '-' || fill[0] === '+') {
+                    target = index + target;
+                }
 
-							if (me.max === null) {
-								me.max = value;
-							} else if (value > me.max) {
-								me.max = value;
-							}
-						});
-					}
-				});
-			}
+                if (target === index || target < 0 || target >= count) {
+                    return false;
+                }
 
-			// 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;
+                return target;
+            }
 
-			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)));
-			}
+            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;
+            }
+        }
 
-			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 paddingLeft = me.paddingLeft;
-			var paddingBottom = me.paddingBottom;
-			var start = me.start;
+        function computeBoundary(source) {
+            var model = source.el._model || {};
+            var scale = source.el._scale || {};
+            var fill = source.fill;
+            var target = null;
+            var horizontal;
 
-			var rightValue = +me.getRightValue(value);
-			var pixel;
-			var innerDimension;
-			var range = me.end - start;
+            if (isFinite(fill)) {
+                return null;
+            }
 
-			if (me.isHorizontal()) {
-				innerDimension = me.width - (paddingLeft + me.paddingRight);
-				pixel = me.left + (innerDimension / range * (rightValue - start));
-				return Math.round(pixel + paddingLeft);
-			} else {
-				innerDimension = me.height - (me.paddingTop + paddingBottom);
-				pixel = (me.bottom - paddingBottom) - (innerDimension / range * (rightValue - start));
-				return Math.round(pixel);
-			}
-		},
-		getValueForPixel: function(pixel) {
-			var me = this;
-			var isHorizontal = me.isHorizontal();
-			var paddingLeft = me.paddingLeft;
-			var paddingBottom = me.paddingBottom;
-			var innerDimension = isHorizontal ? me.width - (paddingLeft + me.paddingRight) : me.height - (me.paddingTop + paddingBottom);
-			var offset = (isHorizontal ? pixel - me.left - paddingLeft : me.bottom - paddingBottom - 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);
+            // 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).
 
-};
-},{}],41:[function(require,module,exports){
-"use strict";
+            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();
+            }
 
-module.exports = function(Chart) {
+            if (target !== undefined && target !== null) {
+                if (target.x !== undefined && target.y !== undefined) {
+                    return target;
+                }
 
-	var helpers = Chart.helpers,
-		noop = helpers.noop;
+                if (typeof target === 'number' && isFinite(target)) {
+                    horizontal = scale.isHorizontal();
+                    return {
+                        x: horizontal? target : null,
+                        y: horizontal? null : target
+                    };
+                }
+            }
 
-	Chart.LinearScaleBase = Chart.Scale.extend({
-		handleTickRangeOptions: function() {
-			var me = this;
-			var opts = me.options;
-			var tickOpts = opts.ticks;
+            return null;
+        }
 
-			// 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);
+        function resolveTarget(sources, index, propagate) {
+            var source = sources[index];
+            var fill = source.fill;
+            var visited = [index];
+            var target;
 
-				if (minSign < 0 && maxSign < 0) {
-					// move the top up to 0
-					me.max = 0;
-				} else if (minSign > 0 && maxSign > 0) {
-					// move the botttom down to 0
-					me.min = 0;
-				}
-			}
+            if (!propagate) {
+                return fill;
+            }
 
-			if (tickOpts.min !== undefined) {
-				me.min = tickOpts.min;
-			} else if (tickOpts.suggestedMin !== undefined) {
-				me.min = Math.min(me.min, tickOpts.suggestedMin);
-			}
+            while (fill !== false && visited.indexOf(fill) === -1) {
+                if (!isFinite(fill)) {
+                    return fill;
+                }
 
-			if (tickOpts.max !== undefined) {
-				me.max = tickOpts.max;
-			} else if (tickOpts.suggestedMax !== undefined) {
-				me.max = Math.max(me.max, tickOpts.suggestedMax);
-			}
+                target = sources[fill];
+                if (!target) {
+                    return false;
+                }
 
-			if (me.min === me.max) {
-				me.max++;
+                if (target.visible) {
+                    return fill;
+                }
 
-				if (!tickOpts.beginAtZero) {
-					me.min--;
-				}
-			}
-		},
-		getTickLimit: noop,
-		handleDirectionalChanges: noop,
+                visited.push(fill);
+                fill = target.fill;
+            }
 
-		buildTicks: function() {
-			var me = this;
-			var opts = me.options;
-			var ticks = me.ticks = [];
-			var tickOpts = opts.ticks;
-			var getValueOrDefault = helpers.getValueOrDefault;
+            return false;
+        }
 
-			// 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
+        function createMapper(source) {
+            var fill = source.fill;
+            var type = 'dataset';
 
-			var maxTicks = me.getTickLimit();
+            if (fill === false) {
+                return null;
+            }
 
-			// Make sure we always have at least 2 ticks
-			maxTicks = Math.max(2, maxTicks);
+            if (!isFinite(fill)) {
+                type = 'boundary';
+            }
 
-			// 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.
+            return mappers[type](source);
+        }
 
-			var spacing;
-			var fixedStepSizeSet = (tickOpts.fixedStepSize && tickOpts.fixedStepSize > 0) || (tickOpts.stepSize && tickOpts.stepSize > 0);
-			if (fixedStepSizeSet) {
-				spacing = getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize);
-			} else {
-				var niceRange = helpers.niceNum(me.max - me.min, false);
-				spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);
-			}
-			var niceMin = Math.floor(me.min / spacing) * spacing;
-			var niceMax = Math.ceil(me.max / spacing) * spacing;
-			var numSpaces = (niceMax - niceMin) / spacing;
+        function isDrawable(point) {
+            return point && !point.skip;
+        }
 
-			// 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);
-			}
+        function drawArea(ctx, curve0, curve1, len0, len1) {
+            var i;
 
-			// Put the values into the ticks array
-			ticks.push(tickOpts.min !== undefined ? tickOpts.min : niceMin);
-			for (var j = 1; j < numSpaces; ++j) {
-				ticks.push(niceMin + (j * spacing));
-			}
-			ticks.push(tickOpts.max !== undefined ? tickOpts.max : niceMax);
+            if (!len0 || !len1) {
+                return;
+            }
 
-			me.handleDirectionalChanges();
+            // 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]);
+            }
 
-			// 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);
+            // joining the two area curves
+            ctx.lineTo(curve1[len1-1].x, curve1[len1-1].y);
 
-			if (tickOpts.reverse) {
-				ticks.reverse();
+            // building opposite area curve (reverse)
+            for (i=len1-1; i>0; --i) {
+                helpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true);
+            }
+        }
 
-				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);
+        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;
 
-			Chart.Scale.prototype.convertTicksToLabels.call(me);
-		},
-	});
-};
+            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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
+        var layout = Chart.layoutService;
+        var noop = helpers.noop;
 
-	var defaultConfig = {
-		position: "left",
+        Chart.defaults.global.legend = {
+            display: true,
+            position: 'top',
+            fullWidth: true,
+            reverse: false,
+            weight: 1000,
 
-		// label settings
-		ticks: {
-			callback: function(value, index, arr) {
-				var remain = value / (Math.pow(10, Math.floor(helpers.log10(value))));
+            // a callback that will handle
+            onClick: function(e, legendItem) {
+                var index = legendItem.datasetIndex;
+                var ci = this.chart;
+                var meta = ci.getDatasetMeta(index);
 
-				if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) {
-					return value.toExponential();
-				} else {
-					return '';
-				}
-			}
-		}
-	};
+                // See controller.isDatasetVisible comment
+                meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
 
-	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;
-			}
+                // We hid a dataset ... rerender the chart
+                ci.update();
+            },
 
-			// Calculate Range
-			me.min = null;
-			me.max = null;
+            onHover: null,
 
-			if (opts.stacked) {
-				var valuesPerType = {};
+            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,
 
-				helpers.each(datasets, function(dataset, datasetIndex) {
-					var meta = chart.getDatasetMeta(datasetIndex);
-					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-						if (valuesPerType[meta.type] === undefined) {
-							valuesPerType[meta.type] = [];
-						}
+                            // Below is extra data used for toggling the datasets
+                            datasetIndex: i
+                        };
+                    }, this) : [];
+                }
+            }
+        };
 
-						helpers.each(dataset.data, function(rawValue, index) {
-							var values = valuesPerType[meta.type];
-							var value = +me.getRightValue(rawValue);
-							if (isNaN(value) || meta.data[index].hidden) {
-								return;
-							}
+        /**
+         * 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;
+        }
 
-							values[index] = values[index] || 0;
+        Chart.Legend = Chart.Element.extend({
 
-							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;
-							}
-						});
-					}
-				});
+            initialize: function(config) {
+                helpers.extend(this, config);
 
-				helpers.each(valuesPerType, 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);
-				});
+                // Contains hit boxes for each dataset (in dataset order)
+                this.legendHitBoxes = [];
 
-			} 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;
-							}
+                // Are we in doughnut mode which has a different data type
+                this.doughnutMode = false;
+            },
 
-							if (me.min === null) {
-								me.min = value;
-							} else if (value < me.min) {
-								me.min = value;
-							}
+            // 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
 
-							if (me.max === null) {
-								me.max = value;
-							} else if (value > me.max) {
-								me.max = value;
-							}
-						});
-					}
-				});
-			}
+            beforeUpdate: noop,
+            update: function(maxWidth, maxHeight, margins) {
+                var me = this;
 
-			me.min = getValueOrDefault(tickOpts.min, me.min);
-			me.max = getValueOrDefault(tickOpts.max, me.max);
+                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+                me.beforeUpdate();
 
-			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 getValueOrDefault = helpers.getValueOrDefault;
+                // Absorb the master measurements
+                me.maxWidth = maxWidth;
+                me.maxHeight = maxHeight;
+                me.margins = margins;
 
-			// Reset the ticks array. Later on, we will draw a grid line at these positions
-			// The array simply contains the numerical value of the spots where ticks will be
-			var ticks = me.ticks = [];
+                // Dimensions
+                me.beforeSetDimensions();
+                me.setDimensions();
+                me.afterSetDimensions();
+                // Labels
+                me.beforeBuildLabels();
+                me.buildLabels();
+                me.afterBuildLabels();
 
-			// 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
+                // Fit
+                me.beforeFit();
+                me.fit();
+                me.afterFit();
+                //
+                me.afterUpdate();
 
-			var tickVal = getValueOrDefault(tickOpts.min, Math.pow(10, Math.floor(helpers.log10(me.min))));
+                return me.minSize;
+            },
+            afterUpdate: noop,
 
-			while (tickVal < me.max) {
-				ticks.push(tickVal);
+            //
 
-				var exp = Math.floor(helpers.log10(tickVal));
-				var significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;
+            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;
 
-				if (significand === 10) {
-					significand = 1;
-					++exp;
-				}
+                    // Reset position before calculating rotation
+                    me.top = 0;
+                    me.bottom = me.height;
+                }
 
-				tickVal = significand * Math.pow(10, exp);
-			}
+                // Reset padding
+                me.paddingLeft = 0;
+                me.paddingTop = 0;
+                me.paddingRight = 0;
+                me.paddingBottom = 0;
 
-			var lastTick = getValueOrDefault(tickOpts.max, tickVal);
-			ticks.push(lastTick);
+                // Reset minSize
+                me.minSize = {
+                    width: 0,
+                    height: 0
+                };
+            },
+            afterSetDimensions: noop,
 
-			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);
+            beforeBuildLabels: noop,
+            buildLabels: function() {
+                var me = this;
+                var labelOpts = me.options.labels;
+                var legendItems = labelOpts.generateLabels.call(me, me.chart);
 
-			if (tickOpts.reverse) {
-				ticks.reverse();
+                if (labelOpts.filter) {
+                    legendItems = legendItems.filter(function(item) {
+                        return labelOpts.filter(item, me.chart.data);
+                    });
+                }
 
-				me.start = me.max;
-				me.end = me.min;
-			} else {
-				me.start = me.min;
-				me.end = me.max;
-			}
-		},
-		convertTicksToLabels: function() {
-			this.tickValues = this.ticks.slice();
+                if (me.options.reverse) {
+                    legendItems.reverse();
+                }
 
-			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;
+                me.legendItems = legendItems;
+            },
+            afterBuildLabels: noop,
 
-			var start = me.start;
-			var newVal = +me.getRightValue(value);
-			var range = helpers.log10(me.end) - helpers.log10(start);
-			var paddingTop = me.paddingTop;
-			var paddingBottom = me.paddingBottom;
-			var paddingLeft = me.paddingLeft;
+            //
 
-			if (me.isHorizontal()) {
+            beforeFit: noop,
+            fit: function() {
+                var me = this;
+                var opts = me.options;
+                var labelOpts = opts.labels;
+                var display = opts.display;
 
-				if (newVal === 0) {
-					pixel = me.left + paddingLeft;
-				} else {
-					innerDimension = me.width - (paddingLeft + me.paddingRight);
-					pixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
-					pixel += paddingLeft;
-				}
-			} else {
-				// Bottom - top since pixels increase downard on a screen
-				if (newVal === 0) {
-					pixel = me.top + paddingTop;
-				} else {
-					innerDimension = me.height - (paddingTop + paddingBottom);
-					pixel = (me.bottom - paddingBottom) - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
-				}
-			}
+                var ctx = me.ctx;
 
-			return pixel;
-		},
-		getValueForPixel: function(pixel) {
-			var me = this;
-			var range = helpers.log10(me.end) - helpers.log10(me.start);
-			var value, innerDimension;
+                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);
 
-			if (me.isHorizontal()) {
-				innerDimension = me.width - (me.paddingLeft + me.paddingRight);
-				value = me.start * Math.pow(10, (pixel - me.left - me.paddingLeft) * range / innerDimension);
-			} else {
-				innerDimension = me.height - (me.paddingTop + me.paddingBottom);
-				value = Math.pow(10, (me.bottom - me.paddingBottom - pixel) * range / innerDimension) / me.start;
-			}
+                // Reset hit boxes
+                var hitboxes = me.legendHitBoxes = [];
 
-			return value;
-		}
-	});
-	Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);
+                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";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var globalDefaults = Chart.defaults.global;
+        var helpers = Chart.helpers;
+        var layout = Chart.layoutService;
+        var noop = helpers.noop;
 
-	var defaultConfig = {
-		display: true,
+        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,
 
-		//Boolean - Whether to animate scaling the chart from the centre
-		animate: true,
-		lineArc: false,
-		position: "chartArea",
+            // actual title
+            text: ''
+        };
 
-		angleLines: {
-			display: true,
-			color: "rgba(0, 0, 0, 0.1)",
-			lineWidth: 1
-		},
+        Chart.Title = Chart.Element.extend({
+            initialize: function(config) {
+                var me = this;
+                helpers.extend(me, config);
 
-		// label settings
-		ticks: {
-			//Boolean - Show a backdrop to the scale label
-			showLabelBackdrop: true,
+                // Contains hit boxes for each dataset (in dataset order)
+                me.legendHitBoxes = [];
+            },
 
-			//String - The colour of the label backdrop
-			backdropColor: "rgba(255,255,255,0.75)",
+            // These methods are ordered by lifecycle. Utilities then follow.
 
-			//Number - The backdrop padding above & below the label in pixels
-			backdropPaddingY: 2,
+            beforeUpdate: noop,
+            update: function(maxWidth, maxHeight, margins) {
+                var me = this;
 
-			//Number - The backdrop padding to the side of the label in pixels
-			backdropPaddingX: 2
-		},
+                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+                me.beforeUpdate();
 
-		pointLabels: {
-			//Number - Point label font size in pixels
-			fontSize: 10,
+                // Absorb the master measurements
+                me.maxWidth = maxWidth;
+                me.maxHeight = maxHeight;
+                me.margins = margins;
 
-			//Function - Used to convert point labels
-			callback: function(label) {
-				return label;
-			}
-		}
-	};
+                // Dimensions
+                me.beforeSetDimensions();
+                me.setDimensions();
+                me.afterSetDimensions();
+                // Labels
+                me.beforeBuildLabels();
+                me.buildLabels();
+                me.afterBuildLabels();
 
-	var LinearRadialScale = Chart.LinearScaleBase.extend({
-		getValueCount: function() {
-			return this.chart.data.labels.length;
-		},
-		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);
+                // Fit
+                me.beforeFit();
+                me.fit();
+                me.afterFit();
+                //
+                me.afterUpdate();
 
-			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;
-			me.min = null;
-			me.max = null;
+                return me.minSize;
 
+            },
+            afterUpdate: noop,
 
-			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;
-						}
+            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;
 
-						if (me.min === null) {
-							me.min = value;
-						} else if (value < me.min) {
-							me.min = value;
-						}
+                    // Reset position before calculating rotation
+                    me.top = 0;
+                    me.bottom = me.height;
+                }
 
-						if (me.max === null) {
-							me.max = value;
-						} else if (value > me.max) {
-							me.max = value;
-						}
-					});
-				}
-			});
+                // Reset padding
+                me.paddingLeft = 0;
+                me.paddingTop = 0;
+                me.paddingRight = 0;
+                me.paddingBottom = 0;
 
-			// 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);
+                // Reset minSize
+                me.minSize = {
+                    width: 0,
+                    height: 0
+                };
+            },
+            afterSetDimensions: noop,
 
-			// 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() {
-			/*
-			 * 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 pointLabels = this.options.pointLabels;
-			var pointLabelFontSize = helpers.getValueOrDefault(pointLabels.fontSize, globalDefaults.defaultFontSize);
-			var pointLabeFontStyle = helpers.getValueOrDefault(pointLabels.fontStyle, globalDefaults.defaultFontStyle);
-			var pointLabeFontFamily = helpers.getValueOrDefault(pointLabels.fontFamily, globalDefaults.defaultFontFamily);
-			var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);
+            beforeBuildLabels: noop,
+            buildLabels: noop,
+            afterBuildLabels: noop,
 
-			// 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 = helpers.min([(this.height / 2 - pointLabelFontSize - 5), this.width / 2]),
-				pointPosition,
-				i,
-				textWidth,
-				halfTextWidth,
-				furthestRight = this.width,
-				furthestRightIndex,
-				furthestRightAngle,
-				furthestLeft = 0,
-				furthestLeftIndex,
-				furthestLeftAngle,
-				xProtrusionLeft,
-				xProtrusionRight,
-				radiusReductionRight,
-				radiusReductionLeft;
-			this.ctx.font = pointLabeFont;
+            //
 
-			for (i = 0; i < this.getValueCount(); i++) {
-				// 5px to space the text slightly out - similar to what we do in the draw function.
-				pointPosition = this.getPointPosition(i, largestPossibleRadius);
-				textWidth = this.ctx.measureText(this.pointLabels[i] ? this.pointLabels[i] : '').width + 5;
+            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;
 
-				// Add quarter circle to make degree 0 mean top of circle
-				var angleRadians = this.getIndexAngle(i) + (Math.PI / 2);
-				var angle = (angleRadians * 360 / (2 * Math.PI)) % 360;
+                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
+                }
 
-				if (angle === 0 || angle === 180) {
-					// At angle 0 and 180, we're at exactly the top/bottom
-					// of the radar chart, so text will be aligned centrally, so we'll half it and compare
-					// w/left and right text sizes
-					halfTextWidth = textWidth / 2;
-					if (pointPosition.x + halfTextWidth > furthestRight) {
-						furthestRight = pointPosition.x + halfTextWidth;
-						furthestRightIndex = i;
-					}
-					if (pointPosition.x - halfTextWidth < furthestLeft) {
-						furthestLeft = pointPosition.x - halfTextWidth;
-						furthestLeftIndex = i;
-					}
-				} else if (angle < 180) {
-					// Less than half the values means we'll left align the text
-					if (pointPosition.x + textWidth > furthestRight) {
-						furthestRight = pointPosition.x + textWidth;
-						furthestRightIndex = i;
-					}
-				} else {
-					// More than half the values means we'll right align the text
-					if (pointPosition.x - textWidth < furthestLeft) {
-						furthestLeft = pointPosition.x - textWidth;
-						furthestLeftIndex = i;
-					}
-				}
-			}
+                me.width = minSize.width;
+                me.height = minSize.height;
 
-			xProtrusionLeft = furthestLeft;
-			xProtrusionRight = Math.ceil(furthestRight - this.width);
+            },
+            afterFit: noop,
 
-			furthestRightAngle = this.getIndexAngle(furthestRightIndex);
-			furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
+            // Shared Methods
+            isHorizontal: function() {
+                var pos = this.options.position;
+                return pos === 'top' || pos === 'bottom';
+            },
 
-			radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI / 2);
-			radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI / 2);
+            // 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;
 
-			// Ensure we actually need to reduce the size of the chart
-			radiusReductionRight = (helpers.isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
-			radiusReductionLeft = (helpers.isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
+                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;
 
-			this.drawingArea = Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2);
-			this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
-		},
-		setCenterPoint: function(leftMovement, rightMovement) {
-			var me = this;
-			var maxRight = me.width - rightMovement - me.drawingArea,
-				maxLeft = leftMovement + me.drawingArea;
+                    ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
+                    ctx.font = titleFont;
 
-			me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);
-			// Always vertically in the centre as the text height doesn't change
-			me.yCenter = Math.round((me.height / 2) + me.top);
-		},
+                    // 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);
+                    }
 
-		getIndexAngle: function(index) {
-			var angleMultiplier = (Math.PI * 2) / this.getValueCount();
-			var startAngle = this.chart.options && this.chart.options.startAngle ?
-				this.chart.options.startAngle :
-				0;
+                    ctx.save();
+                    ctx.translate(titleX, titleY);
+                    ctx.rotate(rotation);
+                    ctx.textAlign = 'center';
+                    ctx.textBaseline = 'middle';
+                    ctx.fillText(opts.text, 0, 0, maxWidth);
+                    ctx.restore();
+                }
+            }
+        });
 
-			var startAngleRadians = startAngle * Math.PI * 2 / 360;
+        function createNewTitleBlockAndAttach(chart, titleOpts) {
+            var title = new Chart.Title({
+                ctx: chart.ctx,
+                options: titleOpts,
+                chart: chart
+            });
 
-			// Start from the top instead of right, so remove a quarter of the circle
-			return index * angleMultiplier - (Math.PI / 2) + startAngleRadians;
-		},
-		getDistanceFromCenterForValue: function(value) {
-			var me = this;
+            layout.configure(chart, title, titleOpts);
+            layout.addBox(chart, title);
+            chart.titleBlock = title;
+        }
 
-			if (value === null) {
-				return 0; // null always in center
-			}
+        return {
+            id: 'title',
 
-			// 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;
-			} else {
-				return (value - me.min) * scalingFactor;
-			}
-		},
-		getPointPosition: function(index, distanceFromCenter) {
-			var me = this;
-			var thisAngle = me.getIndexAngle(index);
-			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));
-		},
+            beforeInit: function(chart) {
+                var titleOpts = chart.options.title;
 
-		getBasePosition: function() {
-			var me = this;
-			var min = me.min;
-			var max = me.max;
+                if (titleOpts) {
+                    createNewTitleBlockAndAttach(chart, titleOpts);
+                }
+            },
 
-			return me.getPointPositionForValue(0,
-				me.beginAtZero? 0:
-				min < 0 && max < 0? max :
-				min > 0 && max > 0? min :
-				0);
-		},
+            beforeUpdate: function(chart) {
+                var titleOpts = chart.options.title;
+                var titleBlock = chart.titleBlock;
 
-		draw: function() {
-			var me = this;
-			var opts = me.options;
-			var gridLineOpts = opts.gridLines;
-			var tickOpts = opts.ticks;
-			var angleLineOpts = opts.angleLines;
-			var pointLabelOpts = opts.pointLabels;
-			var getValueOrDefault = helpers.getValueOrDefault;
+                if (titleOpts) {
+                    titleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);
 
-			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) {
-							ctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);
-							ctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
-
-							if (opts.lineArc) {
-								// Draw circular arcs between the points
-								ctx.beginPath();
-								ctx.arc(me.xCenter, me.yCenter, yCenterOffset, 0, Math.PI * 2);
-								ctx.closePath();
-								ctx.stroke();
-							} else {
-								// Draw straight lines connecting each index
-								ctx.beginPath();
-								for (var i = 0; i < me.getValueCount(); i++) {
-									var pointPosition = me.getPointPosition(i, yCenterOffset);
-									if (i === 0) {
-										ctx.moveTo(pointPosition.x, pointPosition.y);
-									} else {
-										ctx.lineTo(pointPosition.x, pointPosition.y);
-									}
-								}
-								ctx.closePath();
-								ctx.stroke();
-							}
-						}
-
-						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.lineArc) {
-					ctx.lineWidth = angleLineOpts.lineWidth;
-					ctx.strokeStyle = angleLineOpts.color;
-
-					var outerDistance = me.getDistanceFromCenterForValue(opts.reverse ? me.min : me.max);
-
-					// Point Label Font
-					var pointLabelFontSize = getValueOrDefault(pointLabelOpts.fontSize, globalDefaults.defaultFontSize);
-					var pointLabeFontStyle = getValueOrDefault(pointLabelOpts.fontStyle, globalDefaults.defaultFontStyle);
-					var pointLabeFontFamily = getValueOrDefault(pointLabelOpts.fontFamily, globalDefaults.defaultFontFamily);
-					var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);
-
-					for (var i = me.getValueCount() - 1; i >= 0; i--) {
-						if (angleLineOpts.display) {
-							var outerPosition = me.getPointPosition(i, outerDistance);
-							ctx.beginPath();
-							ctx.moveTo(me.xCenter, me.yCenter);
-							ctx.lineTo(outerPosition.x, outerPosition.y);
-							ctx.stroke();
-							ctx.closePath();
-						}
-						// Extra 3px out for some label spacing
-						var pointLabelPosition = me.getPointPosition(i, outerDistance + 5);
-
-						// Keep this in loop since we may support array properties here
-						var pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);
-						ctx.font = pointLabeFont;
-						ctx.fillStyle = pointLabelFontColor;
-
-						var pointLabels = me.pointLabels;
-
-						// Add quarter circle to make degree 0 mean top of circle
-						var angleRadians = this.getIndexAngle(i) + (Math.PI / 2);
-						var angle = (angleRadians * 360 / (2 * Math.PI)) % 360;
-
-						if (angle === 0 || angle === 180) {
-							ctx.textAlign = 'center';
-						} else if (angle < 180) {
-							ctx.textAlign = 'left';
-						} else {
-							ctx.textAlign = 'right';
-						}
-
-						// Set the correct text baseline based on outer positioning
-						if (angle === 90 || angle === 270) {
-							ctx.textBaseline = 'middle';
-						} else if (angle > 270 || angle < 90) {
-							ctx.textBaseline = 'bottom';
-						} else {
-							ctx.textBaseline = 'top';
-						}
-
-						ctx.fillText(pointLabels[i] ? pointLabels[i] : '', pointLabelPosition.x, pointLabelPosition.y);
-					}
-				}
-			}
-		}
-	});
-	Chart.scaleService.registerScaleType("radialLinear", LinearRadialScale, defaultConfig);
-
-};
+                    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){
-/*global window: false */
-"use strict";
+    'use strict';
 
-var moment = require(1);
-moment = typeof(moment) === 'function' ? moment : window.moment;
+    module.exports = function(Chart) {
 
-module.exports = function(Chart) {
+        var helpers = Chart.helpers;
+        // Default config for a category scale
+        var defaultConfig = {
+            position: 'bottom'
+        };
 
-	var helpers = Chart.helpers;
-	var time = {
-		units: [{
-			name: 'millisecond',
-			steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
-		}, {
-			name: 'second',
-			steps: [1, 2, 5, 10, 30]
-		}, {
-			name: 'minute',
-			steps: [1, 2, 5, 10, 30]
-		}, {
-			name: 'hour',
-			steps: [1, 2, 3, 6, 12]
-		}, {
-			name: 'day',
-			steps: [1, 2, 5]
-		}, {
-			name: 'week',
-			maxStep: 4
-		}, {
-			name: 'month',
-			maxStep: 3
-		}, {
-			name: 'quarter',
-			maxStep: 4
-		}, {
-			name: 'year',
-			maxStep: false
-		}]
-	};
+        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;
+            },
 
-	var defaultConfig = {
-		position: "bottom",
+            determineDataLimits: function() {
+                var me = this;
+                var labels = me.getLabels();
+                me.minIndex = 0;
+                me.maxIndex = labels.length - 1;
+                var findIndex;
 
-		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/
+                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;
+                }
 
-			// 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
-		}
-	};
+                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;
+                }
 
-	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');
-			}
+                me.min = labels[me.minIndex];
+                me.max = labels[me.maxIndex];
+            },
 
-			Chart.Scale.prototype.initialize.call(this);
-		},
-		getLabelMoment: function(datasetIndex, index) {
-			if (typeof this.labelMoments[datasetIndex] != 'undefined') {
-				return this.labelMoments[datasetIndex][index];
-			}
+            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);
+            },
 
-			return null;
-		},
-		getMomentStartOf: function(tick) {
-			var me = this;
-			if (me.options.time.unit === 'week' && me.options.time.isoWeekday !== false) {
-				return tick.clone().startOf('isoWeek').isoWeekday(me.options.time.isoWeekday);
-			} else {
-				return tick.clone().startOf(me.tickUnit);
-			}
-		},
-		determineDataLimits: function() {
-			var me = this;
-			me.labelMoments = [];
+            getLabelForIndex: function(index, datasetIndex) {
+                var me = this;
+                var data = me.chart.data;
+                var isHorizontal = me.isHorizontal();
 
-			// Only parse these once. If the dataset does not have data as x,y pairs, we will use
-			// these
-			var scaleLabelMoments = [];
-			if (me.chart.data.labels && me.chart.data.labels.length > 0) {
-				helpers.each(me.chart.data.labels, function(label) {
-					var labelMoment = me.parseTime(label);
+                if (data.yLabels && !isHorizontal) {
+                    return me.getRightValue(data.datasets[datasetIndex].data[index]);
+                }
+                return me.ticks[index - me.minIndex];
+            },
 
-					if (labelMoment.isValid()) {
-						if (me.options.time.round) {
-							labelMoment.startOf(me.options.time.round);
-						}
-						scaleLabelMoments.push(labelMoment);
-					}
-				}, me);
+            // 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);
 
-				me.firstTick = moment.min.call(me, scaleLabelMoments);
-				me.lastTick = moment.max.call(me, scaleLabelMoments);
-			} else {
-				me.firstTick = null;
-				me.lastTick = null;
-			}
+                // 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;
+                }
 
-			helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
-				var momentsForDataset = [];
-				var datasetVisible = me.chart.isDatasetVisible(datasetIndex);
+                if (me.isHorizontal()) {
+                    var valueWidth = me.width / offsetAmt;
+                    var widthOffset = (valueWidth * (index - me.minIndex));
 
-				if (typeof dataset.data[0] === 'object' && dataset.data[0] !== null) {
-					helpers.each(dataset.data, function(value) {
-						var labelMoment = me.parseTime(me.getRightValue(value));
+                    if (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {
+                        widthOffset += (valueWidth / 2);
+                    }
 
-						if (labelMoment.isValid()) {
-							if (me.options.time.round) {
-								labelMoment.startOf(me.options.time.round);
-							}
-							momentsForDataset.push(labelMoment);
+                    return me.left + Math.round(widthOffset);
+                }
+                var valueHeight = me.height / offsetAmt;
+                var heightOffset = (valueHeight * (index - me.minIndex));
 
-							if (datasetVisible) {
-								// May have gone outside the scale ranges, make sure we keep the first and last ticks updated
-								me.firstTick = me.firstTick !== null ? moment.min(me.firstTick, labelMoment) : labelMoment;
-								me.lastTick = me.lastTick !== null ? moment.max(me.lastTick, labelMoment) : labelMoment;
-							}
-						}
-					}, me);
-				} else {
-					// We have no labels. Use the ones from the scale
-					momentsForDataset = scaleLabelMoments;
-				}
+                if (me.options.gridLines.offsetGridLines && includeOffset) {
+                    heightOffset += (valueHeight / 2);
+                }
 
-				me.labelMoments.push(momentsForDataset);
-			}, me);
+                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;
 
-			// Set these after we've done all the data
-			if (me.options.time.min) {
-				me.firstTick = me.parseTime(me.options.time.min);
-			}
+                pixel -= horz ? me.left : me.top;
 
-			if (me.options.time.max) {
-				me.lastTick = me.parseTime(me.options.time.max);
-			}
+                if (me.options.gridLines.offsetGridLines) {
+                    pixel -= (valueDimension / 2);
+                }
 
-			// We will modify these, so clone for later
-			me.firstTick = (me.firstTick || moment()).clone();
-			me.lastTick = (me.lastTick || moment()).clone();
-		},
-		buildTicks: function() {
-			var me = this;
+                if (pixel <= 0) {
+                    value = 0;
+                } else {
+                    value = Math.round(pixel / valueDimension);
+                }
 
-			me.ctx.save();
-			var tickFontSize = helpers.getValueOrDefault(me.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(me.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(me.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-			me.ctx.font = tickLabelFont;
+                return value;
+            },
+            getBasePixel: function() {
+                return this.bottom;
+            }
+        });
 
-			me.ticks = [];
-			me.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step
-			me.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc)
+        Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);
 
-			// Set unit override if applicable
-			if (me.options.time.unit) {
-				me.tickUnit = me.options.time.unit || 'day';
-				me.displayFormat = me.options.time.displayFormats[me.tickUnit];
-				me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-				me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, 1);
-			} else {
-				// Determine the smallest needed unit of the time
-				var innerWidth = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);
+    };
 
-				// Crude approximation of what the label length might be
-				var tempFirstLabel = me.tickFormatFunction(me.firstTick, 0, []);
-				var tickLabelWidth = me.ctx.measureText(tempFirstLabel).width;
-				var cosRotation = Math.cos(helpers.toRadians(me.options.ticks.maxRotation));
-				var sinRotation = Math.sin(helpers.toRadians(me.options.ticks.maxRotation));
-				tickLabelWidth = (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
-				var labelCapacity = innerWidth / (tickLabelWidth);
+},{}],45:[function(require,module,exports){
+    'use strict';
 
-				// Start as small as possible
-				me.tickUnit = 'millisecond';
-				me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-				me.displayFormat = me.options.time.displayFormats[me.tickUnit];
+    module.exports = function(Chart) {
 
-				var unitDefinitionIndex = 0;
-				var unitDefinition = time.units[unitDefinitionIndex];
+        var helpers = Chart.helpers;
 
-				// While we aren't ideal and we don't have units left
-				while (unitDefinitionIndex < time.units.length) {
-					// Can we scale this unit. If `false` we can scale infinitely
-					me.unitScale = 1;
+        var defaultConfig = {
+            position: 'left',
+            ticks: {
+                callback: Chart.Ticks.formatters.linear
+            }
+        };
 
-					if (helpers.isArray(unitDefinition.steps) && Math.ceil(me.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) {
-						// Use one of the prefedined steps
-						for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {
-							if (unitDefinition.steps[idx] >= Math.ceil(me.scaleSizeInUnits / labelCapacity)) {
-								me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, unitDefinition.steps[idx]);
-								break;
-							}
-						}
+        var LinearScale = Chart.LinearScaleBase.extend({
 
-						break;
-					} else if ((unitDefinition.maxStep === false) || (Math.ceil(me.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep)) {
-						// We have a max step. Scale this unit
-						me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, Math.ceil(me.scaleSizeInUnits / labelCapacity));
-						break;
-					} else {
-						// Move to the next unit up
-						++unitDefinitionIndex;
-						unitDefinition = time.units[unitDefinitionIndex];
+            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;
 
-						me.tickUnit = unitDefinition.name;
-						var leadingUnitBuffer = me.firstTick.diff(me.getMomentStartOf(me.firstTick), me.tickUnit, true);
-						var trailingUnitBuffer = me.getMomentStartOf(me.lastTick.clone().add(1, me.tickUnit)).diff(me.lastTick, me.tickUnit, true);
-						me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true) + leadingUnitBuffer + trailingUnitBuffer;
-						me.displayFormat = me.options.time.displayFormats[unitDefinition.name];
-					}
-				}
-			}
+                function IDMatches(meta) {
+                    return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
+                }
 
-			var roundedStart;
+                // First Calculate the range
+                me.min = null;
+                me.max = null;
 
-			// Only round the first tick if we have no hard minimum
-			if (!me.options.time.min) {
-				me.firstTick = me.getMomentStartOf(me.firstTick);
-				roundedStart = me.firstTick;
-			} else {
-				roundedStart = me.getMomentStartOf(me.firstTick);
-			}
+                var hasStacks = opts.stacked;
+                if (hasStacks === undefined) {
+                    helpers.each(datasets, function(dataset, datasetIndex) {
+                        if (hasStacks) {
+                            return;
+                        }
 
-			// Only round the last tick if we have no hard maximum
-			if (!me.options.time.max) {
-				var roundedEnd = me.getMomentStartOf(me.lastTick);
-				var delta = roundedEnd.diff(me.lastTick, me.tickUnit, true);
-				if (delta < 0) {
-					// Do not use end of because we need me to be in the next time unit
-					me.lastTick = me.getMomentStartOf(me.lastTick.add(1, me.tickUnit));
-				} else if (delta >= 0) {
-					me.lastTick = roundedEnd;
-				}
+                        var meta = chart.getDatasetMeta(datasetIndex);
+                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
+                            meta.stack !== undefined) {
+                            hasStacks = true;
+                        }
+                    });
+                }
 
-				me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-			}
+                if (opts.stacked || hasStacks) {
+                    var valuesPerStack = {};
 
-			me.smallestLabelSeparation = me.width;
+                    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('.');
 
-			helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
-				for (var i = 1; i < me.labelMoments[datasetIndex].length; i++) {
-					me.smallestLabelSeparation = Math.min(me.smallestLabelSeparation, me.labelMoments[datasetIndex][i].diff(me.labelMoments[datasetIndex][i - 1], me.tickUnit, true));
-				}
-			}, me);
+                        if (valuesPerStack[key] === undefined) {
+                            valuesPerStack[key] = {
+                                positiveValues: [],
+                                negativeValues: []
+                            };
+                        }
 
-			// Tick displayFormat override
-			if (me.options.time.displayFormat) {
-				me.displayFormat = me.options.time.displayFormat;
-			}
+                        // Store these per type
+                        var positiveValues = valuesPerStack[key].positiveValues;
+                        var negativeValues = valuesPerStack[key].negativeValues;
 
-			// first tick. will have been rounded correctly if options.time.min is not specified
-			me.ticks.push(me.firstTick.clone());
+                        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;
+                                }
 
-			// For every unit in between the first and last moment, create a moment and add it to the ticks tick
-			for (var i = 1; i <= me.scaleSizeInUnits; ++i) {
-				var newTick = roundedStart.clone().add(i, me.tickUnit);
+                                positiveValues[index] = positiveValues[index] || 0;
+                                negativeValues[index] = negativeValues[index] || 0;
 
-				// Are we greater than the max time
-				if (me.options.time.max && newTick.diff(me.lastTick, me.tickUnit, true) >= 0) {
-					break;
-				}
+                                if (opts.relativePoints) {
+                                    positiveValues[index] = 100;
+                                } else if (value < 0) {
+                                    negativeValues[index] += value;
+                                } else {
+                                    positiveValues[index] += value;
+                                }
+                            });
+                        }
+                    });
 
-				if (i % me.unitScale === 0) {
-					me.ticks.push(newTick);
-				}
-			}
+                    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);
+                    });
 
-			// Always show the right tick
-			var diff = me.ticks[me.ticks.length - 1].diff(me.lastTick, me.tickUnit);
-			if (diff !== 0 || me.scaleSizeInUnits === 0) {
-				// this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart
-				// but the last tick was not rounded.
-				if (me.options.time.max) {
-					me.ticks.push(me.lastTick.clone());
-					me.scaleSizeInUnits = me.lastTick.diff(me.ticks[0], me.tickUnit, true);
-				} else {
-					me.ticks.push(me.lastTick.clone());
-					me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-				}
-			}
+                } 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;
+                                }
 
-			me.ctx.restore();
-		},
-		// 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] : '';
+                                if (me.min === null) {
+                                    me.min = value;
+                                } else if (value < me.min) {
+                                    me.min = value;
+                                }
 
-			if (typeof me.chart.data.datasets[datasetIndex].data[0] === 'object') {
-				label = me.getRightValue(me.chart.data.datasets[datasetIndex].data[index]);
-			}
+                                if (me.max === null) {
+                                    me.max = value;
+                                } else if (value > me.max) {
+                                    me.max = value;
+                                }
+                            });
+                        }
+                    });
+                }
 
-			// Format nicely
-			if (me.options.time.tooltipFormat) {
-				label = me.parseTime(label).format(me.options.time.tooltipFormat);
-			}
+                me.min = isFinite(me.min) ? me.min : DEFAULT_MIN;
+                me.max = isFinite(me.max) ? me.max : DEFAULT_MAX;
 
-			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);
+                // 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 (callback) {
-				return callback(formattedTick, index, ticks);
-			} else {
-				return formattedTick;
-			}
-		},
-		convertTicksToLabels: function() {
-			var me = this;
-			me.tickMoments = me.ticks;
-			me.ticks = me.ticks.map(me.tickFormatFunction, me);
-		},
-		getPixelForValue: function(value, index, datasetIndex) {
-			var me = this;
-			if (!value || !value.isValid) {
-				// not already a moment object
-				value = moment(me.getRightValue(value));
-			}
-			var labelMoment = value && value.isValid && value.isValid() ? value : me.getLabelMoment(datasetIndex, index);
+                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)));
+                }
 
-			if (labelMoment) {
-				var offset = labelMoment.diff(me.firstTick, me.tickUnit, true);
+                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 decimal = offset !== 0 ? offset / me.scaleSizeInUnits : offset;
+                var rightValue = +me.getRightValue(value);
+                var pixel;
+                var range = me.end - start;
 
-				if (me.isHorizontal()) {
-					var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-					var valueOffset = (innerWidth * decimal) + me.paddingLeft;
+                if (me.isHorizontal()) {
+                    pixel = me.left + (me.width / range * (rightValue - start));
+                    return Math.round(pixel);
+                }
 
-					return me.left + Math.round(valueOffset);
-				} else {
-					var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
-					var heightOffset = (innerHeight * decimal) + me.paddingTop;
+                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);
 
-					return me.top + Math.round(heightOffset);
-				}
-			}
-		},
-		getPixelForTick: function(index) {
-			return this.getPixelForValue(this.tickMoments[index], null, null);
-		},
-		getValueForPixel: function(pixel) {
-			var me = this;
-			var innerDimension = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);
-			var offset = (pixel - (me.isHorizontal() ? me.left + me.paddingLeft : me.top + me.paddingTop)) / innerDimension;
-			offset *= me.scaleSizeInUnits;
-			return me.firstTick.clone().add(moment.duration(offset, me.tickUnit).asSeconds(), 'seconds');
-		},
-		parseTime: function(label) {
-			var me = this;
-			if (typeof me.options.time.parser === 'string') {
-				return moment(label, me.options.time.parser);
-			}
-			if (typeof me.options.time.parser === 'function') {
-				return me.options.time.parser(label);
-			}
-			// Date objects
-			if (typeof label.getMonth === 'function' || typeof label === 'number') {
-				return moment(label);
-			}
-			// Moment support
-			if (label.isValid && label.isValid()) {
-				return label;
-			}
-			// Custom parsing (return an instance of moment)
-			if (typeof me.options.time.format !== 'string' && me.options.time.format.call) {
-				console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale");
-				return me.options.time.format(label);
-			}
-			// Moment format parsing
-			return moment(label, me.options.time.format);
-		}
-	});
-	Chart.scaleService.registerScaleType("time", TimeScale, 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
index 4d5cdcd..cf50797 100644
--- a/web/gui/src/main/webapp/tp/Chart.min.js
+++ b/web/gui/src/main/webapp/tp/Chart.min.js
@@ -1,14 +1,14 @@
 /*!
  * Chart.js
  * http://chartjs.org/
- * Version: 2.2.1
+ * Version: 2.6.0
  *
- * Copyright 2016 Nick Downie
+ * 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,a,i){function n(r,l){if(!a[r]){if(!e[r]){var s="function"==typeof require&&require;if(!l&&s)return s(r,!0);if(o)return o(r,!0);var d=new Error("Cannot find module '"+r+"'");throw d.code="MODULE_NOT_FOUND",d}var u=a[r]={exports:{}};e[r][0].call(u.exports,function(t){var a=e[r][1][t];return n(a?a:t)},u,u.exports,t,e,a,i)}return a[r].exports}for(var o="function"==typeof require&&require,r=0;r<i.length;r++)n(i[r]);return n}({1:[function(t,e,a){},{}],2:[function(t,e,a){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,a=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,n=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,o=/(\w+)/,r=[0,0,0],l=1,s=t.match(e);if(s){s=s[1];for(var d=0;d<r.length;d++)r[d]=parseInt(s[d]+s[d],16)}else if(s=t.match(a)){s=s[1];for(var d=0;d<r.length;d++)r[d]=parseInt(s.slice(2*d,2*d+2),16)}else if(s=t.match(i)){for(var d=0;d<r.length;d++)r[d]=parseInt(s[d+1]);l=parseFloat(s[4])}else if(s=t.match(n)){for(var d=0;d<r.length;d++)r[d]=Math.round(2.55*parseFloat(s[d+1]));l=parseFloat(s[4])}else if(s=t.match(o)){if("transparent"==s[1])return[0,0,0,0];if(r=y[s[1]],!r)return}for(var d=0;d<r.length;d++)r[d]=v(r[d],0,255);return l=l||0==l?v(l,0,1):1,r[3]=l,r}}function n(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=v(parseInt(a[1]),0,360),o=v(parseFloat(a[2]),0,100),r=v(parseFloat(a[3]),0,100),l=v(isNaN(i)?1:i,0,1);return[n,o,r,l]}}}function o(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=v(parseInt(a[1]),0,360),o=v(parseFloat(a[2]),0,100),r=v(parseFloat(a[3]),0,100),l=v(isNaN(i)?1:i,0,1);return[n,o,r,l]}}}function r(t){var e=i(t);return e&&e.slice(0,3)}function l(t){var e=n(t);return e&&e.slice(0,3)}function s(t){var e=i(t);return e?e[3]:(e=n(t))?e[3]:(e=o(t))?e[3]:void 0}function d(t){return"#"+x(t[0])+x(t[1])+x(t[2])}function u(t,e){return 1>e||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(1>e||t[3]&&t[3]<1)return f(t,e);var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgb("+a+"%, "+i+"%, "+n+"%)"}function f(t,e){var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgba("+a+"%, "+i+"%, "+n+"%, "+(e||t[3]||1)+")"}function g(t,e){return 1>e||t[3]&&t[3]<1?p(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function b(t){return k[t.slice(0,3)]}function v(t,e,a){return Math.min(Math.max(e,t),a)}function x(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y=t(6);e.exports={getRgba:i,getHsla:n,getRgb:r,getHsl:l,getHwb:o,getAlpha:s,hexString:d,rgbString:u,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:p,hwbString:m,keyword:b};var k={};for(var S in y)k[y[S]]=S},{6:6}],3:[function(t,e,a){var i=t(5),n=t(2),o=function(t){if(t instanceof o)return t;if(!(this instanceof o))return new o(t);this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;if("string"==typeof t)if(e=n.getRgba(t))this.setValues("rgb",e);else if(e=n.getHsla(t))this.setValues("hsl",e);else{if(!(e=n.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}else if("object"==typeof t)if(e=t,void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}};o.prototype={rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=0>t?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return n.hexString(this.values.rgb)},rgbString:function(){return n.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return n.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return n.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return n.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return n.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return n.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return n.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],a=0;a<t.length;a++){var i=t[a]/255;e[a]=.03928>=i?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),a=t.luminosity();return e>a?(e+.05)/(a+.05):(a+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return 128>e},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;3>e;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,a=(e[0]+t)%360;return e[0]=0>a?360+a:a,this.setValues("hsl",e),this},mix:function(t,e){var a=this,i=t,n=void 0===e?.5:e,o=2*n-1,r=a.alpha()-i.alpha(),l=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,s=1-l;return this.rgb(l*a.red()+s*i.red(),l*a.green()+s*i.green(),l*a.blue()+s*i.blue()).alpha(a.alpha()*n+i.alpha()*(1-n))},toJSON:function(){return this.rgb()},clone:function(){var t,e,a=new o,i=this.values,n=a.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?n[r]=t.slice(0):"[object Number]"===e?n[r]=t:console.error("unexpected color value:",t));return a}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,a={},i=0;i<t.length;i++)a[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(a.a=e.alpha),a},o.prototype.setValues=function(t,e){var a,n=this.values,o=this.spaces,r=this.maxes,l=1;if("alpha"===t)l=e;else if(e.length)n[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(a=0;a<t.length;a++)n[t][a]=e[t.charAt(a)];l=e.a}else if(void 0!==e[o[t][0]]){var s=o[t];for(a=0;a<t.length;a++)n[t][a]=e[s[a]];l=e.alpha}if(n.alpha=Math.max(0,Math.min(1,void 0===l?n.alpha:l)),"alpha"===t)return!1;var d;for(a=0;a<t.length;a++)d=Math.max(0,Math.min(r[t][a],n[t][a])),n[t][a]=Math.round(d);for(var u in o)u!==t&&(n[u]=i[t][u](n[t]));return!0},o.prototype.setSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a),this)},o.prototype.setChannel=function(t,e,a){var i=this.values[t];return void 0===a?i[e]:a===i[e]?this:(i[e]=a,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,a){function i(t){var e,a,i,n=t[0]/255,o=t[1]/255,r=t[2]/255,l=Math.min(n,o,r),s=Math.max(n,o,r),d=s-l;return s==l?e=0:n==s?e=(o-r)/d:o==s?e=2+(r-n)/d:r==s&&(e=4+(n-o)/d),e=Math.min(60*e,360),0>e&&(e+=360),i=(l+s)/2,a=s==l?0:.5>=i?d/(s+l):d/(2-s-l),[e,100*a,100*i]}function n(t){var e,a,i,n=t[0],o=t[1],r=t[2],l=Math.min(n,o,r),s=Math.max(n,o,r),d=s-l;return a=0==s?0:d/s*1e3/10,s==l?e=0:n==s?e=(o-r)/d:o==s?e=2+(r-n)/d:r==s&&(e=4+(n-o)/d),e=Math.min(60*e,360),0>e&&(e+=360),i=s/255*1e3/10,[e,a,i]}function o(t){var e=t[0],a=t[1],n=t[2],o=i(t)[0],r=1/255*Math.min(e,Math.min(a,n)),n=1-1/255*Math.max(e,Math.max(a,n));return[o,100*r,100*n]}function l(t){var e,a,i,n,o=t[0]/255,r=t[1]/255,l=t[2]/255;return n=Math.min(1-o,1-r,1-l),e=(1-o-n)/(1-n)||0,a=(1-r-n)/(1-n)||0,i=(1-l-n)/(1-n)||0,[100*e,100*a,100*i,100*n]}function s(t){return Z[JSON.stringify(t)]}function d(t){var e=t[0]/255,a=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var n=.4124*e+.3576*a+.1805*i,o=.2126*e+.7152*a+.0722*i,r=.0193*e+.1192*a+.9505*i;return[100*n,100*o,100*r]}function u(t){var e,a,i,n=d(t),o=n[0],r=n[1],l=n[2];return o/=95.047,r/=100,l/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,l=l>.008856?Math.pow(l,1/3):7.787*l+16/116,e=116*r-16,a=500*(o-r),i=200*(r-l),[e,a,i]}function c(t){return W(u(t))}function h(t){var e,a,i,n,o,r=t[0]/360,l=t[1]/100,s=t[2]/100;if(0==l)return o=255*s,[o,o,o];a=.5>s?s*(1+l):s+l-s*l,e=2*s-a,n=[0,0,0];for(var d=0;3>d;d++)i=r+1/3*-(d-1),0>i&&i++,i>1&&i--,o=1>6*i?e+6*(a-e)*i:1>2*i?a:2>3*i?e+(a-e)*(2/3-i)*6:e,n[d]=255*o;return n}function f(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,n*=1>=o?o:2-o,a=(o+n)/2,e=2*n/(o+n),[i,100*e,100*a])}function p(t){return o(h(t))}function m(t){return l(h(t))}function v(t){return s(h(t))}function x(t){var e=t[0]/60,a=t[1]/100,i=t[2]/100,n=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-a),l=255*i*(1-a*o),s=255*i*(1-a*(1-o)),i=255*i;switch(n){case 0:return[i,s,r];case 1:return[l,i,r];case 2:return[r,i,s];case 3:return[r,l,i];case 4:return[s,r,i];case 5:return[i,r,l]}}function y(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return a=(2-n)*o,e=n*o,e/=1>=a?a:2-a,e=e||0,a/=2,[i,100*e,100*a]}function k(t){return o(x(t))}function S(t){return l(x(t))}function w(t){return s(x(t))}function C(t){var e,a,i,n,o=t[0]/360,l=t[1]/100,s=t[2]/100,d=l+s;switch(d>1&&(l/=d,s/=d),e=Math.floor(6*o),a=1-s,i=6*o-e,0!=(1&e)&&(i=1-i),n=l+i*(a-l),e){default:case 6:case 0:r=a,g=n,b=l;break;case 1:r=n,g=a,b=l;break;case 2:r=l,g=a,b=n;break;case 3:r=l,g=n,b=a;break;case 4:r=n,g=l,b=a;break;case 5:r=a,g=l,b=n}return[255*r,255*g,255*b]}function M(t){return i(C(t))}function D(t){return n(C(t))}function A(t){return l(C(t))}function I(t){return s(C(t))}function T(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100,l=t[3]/100;return e=1-Math.min(1,n*(1-l)+l),a=1-Math.min(1,o*(1-l)+l),i=1-Math.min(1,r*(1-l)+l),[255*e,255*a,255*i]}function F(t){return i(T(t))}function P(t){return n(T(t))}function R(t){return o(T(t))}function _(t){return s(T(t))}function V(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*n+-1.5372*o+r*-.4986,a=n*-.9689+1.8758*o+.0415*r,i=.0557*n+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e=12.92*e,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a=12.92*a,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i=12.92*i,e=Math.min(Math.max(0,e),1),a=Math.min(Math.max(0,a),1),i=Math.min(Math.max(0,i),1),[255*e,255*a,255*i]}function L(t){var e,a,i,n=t[0],o=t[1],r=t[2];return n/=95.047,o/=100,r/=108.883,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*o-16,a=500*(n-o),i=200*(o-r),[e,a,i]}function O(t){return W(L(t))}function B(t){var e,a,i,n,o=t[0],r=t[1],l=t[2];return 8>=o?(a=100*o/903.3,n=7.787*(a/100)+16/116):(a=100*Math.pow((o+16)/116,3),n=Math.pow(a/100,1/3)),e=.008856>=e/95.047?e=95.047*(r/500+n-16/116)/7.787:95.047*Math.pow(r/500+n,3),i=.008859>=i/108.883?i=108.883*(n-l/200-16/116)/7.787:108.883*Math.pow(n-l/200,3),[e,a,i]}function W(t){var e,a,i,n=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),a=360*e/2/Math.PI,0>a&&(a+=360),i=Math.sqrt(o*o+r*r),[n,i,a]}function z(t){return V(B(t))}function N(t){var e,a,i,n=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),a=o*Math.sin(i),[n,e,a]}function H(t){return B(N(t))}function E(t){return z(N(t))}function U(t){return Q[t]}function q(t){return i(U(t))}function j(t){return n(U(t))}function Y(t){return o(U(t))}function J(t){return l(U(t))}function X(t){return u(U(t))}function G(t){return d(U(t))}e.exports={rgb2hsl:i,rgb2hsv:n,rgb2hwb:o,rgb2cmyk:l,rgb2keyword:s,rgb2xyz:d,rgb2lab:u,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:S,hsv2keyword:w,hwb2rgb:C,hwb2hsl:M,hwb2hsv:D,hwb2cmyk:A,hwb2keyword:I,cmyk2rgb:T,cmyk2hsl:F,cmyk2hsv:P,cmyk2hwb:R,cmyk2keyword:_,keyword2rgb:U,keyword2hsl:q,keyword2hsv:j,keyword2hwb:Y,keyword2cmyk:J,keyword2lab:X,keyword2xyz:G,xyz2rgb:V,xyz2lab:L,xyz2lch:O,lab2xyz:B,lab2rgb:z,lab2lch:W,lch2lab:N,lch2xyz:H,lch2rgb:E};var Q={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 $ in Q)Z[JSON.stringify(Q[$])]=$},{}],5:[function(t,e,a){var i=t(4),n=function(){return new d};for(var o in i){n[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),l=r[1],s=r[2];n[l]=n[l]||{},n[l][s]=n[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var a=i[t](e);if("string"==typeof a||void 0===a)return a;for(var n=0;n<a.length;n++)a[n]=Math.round(a[n]);return a}}(o)}var d=function(){this.convs={}};d.prototype.routeSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a))},d.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},d.prototype.getValues=function(t){var e=this.convs[t];if(!e){var a=this.space,i=this.convs[a];e=n[a][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){d.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=n},{4:4}],6:[function(t,e,a){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],7:[function(t,e,a){var i=t(27)();t(26)(i),t(22)(i),t(25)(i),t(21)(i),t(23)(i),t(24)(i),t(28)(i),t(32)(i),t(30)(i),t(31)(i),t(33)(i),t(29)(i),t(34)(i),t(35)(i),t(36)(i),t(37)(i),t(38)(i),t(41)(i),t(39)(i),t(40)(i),t(42)(i),t(43)(i),t(44)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i),window.Chart=e.exports=i},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,44:44,8:8,9:9}],8:[function(t,e,a){"use strict";e.exports=function(t){t.Bar=function(e,a){return a.type="bar",new t(e,a)}}},{}],9:[function(t,e,a){"use strict";e.exports=function(t){t.Bubble=function(e,a){return a.type="bubble",new t(e,a)}}},{}],10:[function(t,e,a){"use strict";e.exports=function(t){t.Doughnut=function(e,a){return a.type="doughnut",new t(e,a)}}},{}],11:[function(t,e,a){"use strict";e.exports=function(t){t.Line=function(e,a){return a.type="line",new t(e,a)}}},{}],12:[function(t,e,a){"use strict";e.exports=function(t){t.PolarArea=function(e,a){return a.type="polarArea",new t(e,a)}}},{}],13:[function(t,e,a){"use strict";e.exports=function(t){t.Radar=function(e,a){return a.options=t.helpers.configMerge({aspectRatio:1},a.options),a.type="radar",new t(e,a)}}},{}],14:[function(t,e,a){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,a){return a.type="scatter",new t(e,a)}}},{}],15:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(e,a){t.DatasetController.prototype.initialize.call(this,e,a),this.getMeta().bar=!0},getBarCount:function(){var t=this,a=0;return e.each(t.chart.data.datasets,function(e,i){var n=t.chart.getDatasetMeta(i);n.bar&&t.chart.isDatasetVisible(i)&&++a},t),a},update:function(t){var a=this;e.each(a.getMeta().data,function(e,i){a.updateElement(e,i,t)},a)},updateElement:function(t,a,i){var n=this,o=n.getMeta(),r=n.getScaleForId(o.xAxisID),l=n.getScaleForId(o.yAxisID),s=l.getBasePixel(),d=n.chart.options.elements.rectangle,u=t.custom||{},c=n.getDataset();e.extend(t,{_xScale:r,_yScale:l,_datasetIndex:n.index,_index:a,_model:{x:n.calculateBarX(a,n.index),y:i?s:n.calculateBarY(a,n.index),label:n.chart.data.labels[a],datasetLabel:c.label,base:i?s:n.calculateBarBase(n.index,a),width:n.calculateBarWidth(a),backgroundColor:u.backgroundColor?u.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,a,d.backgroundColor),borderSkipped:u.borderSkipped?u.borderSkipped:d.borderSkipped,borderColor:u.borderColor?u.borderColor:e.getValueAtIndexOrDefault(c.borderColor,a,d.borderColor),borderWidth:u.borderWidth?u.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,a,d.borderWidth)}}),t.pivot()},calculateBarBase:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=0;if(n.options.stacked){for(var r=a.chart,l=r.data.datasets,s=Number(l[t].data[e]),d=0;t>d;d++){var u=l[d],c=r.getDatasetMeta(d);if(c.bar&&c.yAxisID===n.id&&r.isDatasetVisible(d)){var h=Number(u.data[e]);o+=0>s?Math.min(h,0):Math.max(h,0)}}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(t){var e,a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=a.getBarCount();e="category"===n.options.type?n.getPixelForTick(t+1)-n.getPixelForTick(t):n.width/n.ticks.length;var r=e*n.options.categoryPercentage,l=(e-e*n.options.categoryPercentage)/2,s=r/o;if(n.ticks.length!==a.chart.data.labels.length){var d=n.ticks.length/a.chart.data.labels.length;s*=d}var u=s*n.options.barPercentage,c=s-s*n.options.barPercentage;return{datasetCount:o,tickWidth:e,categoryWidth:r,categorySpacing:l,fullBarWidth:s,barWidth:u,barSpacing:c}},calculateBarWidth:function(t){var e=this.getScaleForId(this.getMeta().xAxisID);if(e.options.barThickness)return e.options.barThickness;var a=this.getRuler(t);return e.options.stacked?a.categoryWidth:a.barWidth},getBarIndex:function(t){var e,a,i=0;for(a=0;t>a;++a)e=this.chart.getDatasetMeta(a),e.bar&&this.chart.isDatasetVisible(a)&&++i;return i},calculateBarX:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=a.getBarIndex(e),r=a.getRuler(t),l=n.getPixelForValue(null,t,e,a.chart.isCombo);return l-=a.chart.isCombo?r.tickWidth/2:0,n.options.stacked?l+r.categoryWidth/2+r.categorySpacing:l+r.barWidth/2+r.categorySpacing+r.barWidth*o+r.barSpacing/2+r.barSpacing*o},calculateBarY:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=Number(a.getDataset().data[t]);if(n.options.stacked){for(var r=0,l=0,s=0;e>s;s++){var d=a.chart.data.datasets[s],u=a.chart.getDatasetMeta(s);if(u.bar&&u.yAxisID===n.id&&a.chart.isDatasetVisible(s)){var c=Number(d.data[t]);0>c?l+=c||0:r+=c||0}}return 0>o?n.getPixelForValue(l+o):n.getPixelForValue(r+o)}return n.getPixelForValue(o)},draw:function(t){var a=this,i=t||1;e.each(a.getMeta().data,function(t,e){var n=a.getDataset().data[e];null===n||void 0===n||isNaN(n)||t.transition(i).draw()},a)},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.hoverBackgroundColor,i,e.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor?n.hoverBorderColor:e.getValueAtIndexOrDefault(a.hoverBorderColor,i,e.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:e.getValueAtIndexOrDefault(a.hoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model,r=this.chart.options.elements.rectangle;o.backgroundColor=n.backgroundColor?n.backgroundColor:e.getValueAtIndexOrDefault(a.backgroundColor,i,r.backgroundColor),o.borderColor=n.borderColor?n.borderColor:e.getValueAtIndexOrDefault(a.borderColor,i,r.borderColor),o.borderWidth=n.borderWidth?n.borderWidth:e.getValueAtIndexOrDefault(a.borderWidth,i,r.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var a="";return t.length>0&&(t[0].yLabel?a=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(a=e.labels[t[0].index])),a},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({updateElement:function(t,a,i){var n=this,o=n.getMeta(),r=n.getScaleForId(o.xAxisID),l=n.getScaleForId(o.yAxisID),s=r.getBasePixel(),d=t.custom||{},u=n.getDataset(),c=n.chart.options.elements.rectangle;e.extend(t,{_xScale:r,_yScale:l,_datasetIndex:n.index,_index:a,_model:{x:i?s:n.calculateBarX(a,n.index),y:n.calculateBarY(a,n.index),label:n.chart.data.labels[a],datasetLabel:u.label,base:i?s:n.calculateBarBase(n.index,a),height:n.calculateBarHeight(a),backgroundColor:d.backgroundColor?d.backgroundColor:e.getValueAtIndexOrDefault(u.backgroundColor,a,c.backgroundColor),borderSkipped:d.borderSkipped?d.borderSkipped:c.borderSkipped,borderColor:d.borderColor?d.borderColor:e.getValueAtIndexOrDefault(u.borderColor,a,c.borderColor),borderWidth:d.borderWidth?d.borderWidth:e.getValueAtIndexOrDefault(u.borderWidth,a,c.borderWidth)},draw:function(){function t(t){return s[(u+t)%4]}var e=this._chart.ctx,a=this._view,i=a.height/2,n=a.y-i,o=a.y+i,r=a.base-(a.base-a.x),l=a.borderWidth/2;a.borderWidth&&(n+=l,o-=l,r+=l),e.beginPath(),e.fillStyle=a.backgroundColor,e.strokeStyle=a.borderColor,e.lineWidth=a.borderWidth;var s=[[a.base,o],[a.base,n],[r,n],[r,o]],d=["bottom","left","top","right"],u=d.indexOf(a.borderSkipped,0);-1===u&&(u=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),a.borderWidth&&e.stroke()},inRange:function(t,e){var a=this._view,i=!1;return a&&(i=a.x<a.base?e>=a.y-a.height/2&&e<=a.y+a.height/2&&t>=a.x&&t<=a.base:e>=a.y-a.height/2&&e<=a.y+a.height/2&&t>=a.base&&t<=a.x),i}}),t.pivot()},calculateBarBase:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=0;
-if(n.options.stacked){for(var r=a.chart,l=r.data.datasets,s=Number(l[t].data[e]),d=0;t>d;d++){var u=l[d],c=r.getDatasetMeta(d);if(c.bar&&c.xAxisID===n.id&&r.isDatasetVisible(d)){var h=Number(u.data[e]);o+=0>s?Math.min(h,0):Math.max(h,0)}}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(t){var e,a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=a.getBarCount();e="category"===n.options.type?n.getPixelForTick(t+1)-n.getPixelForTick(t):n.width/n.ticks.length;var r=e*n.options.categoryPercentage,l=(e-e*n.options.categoryPercentage)/2,s=r/o;if(n.ticks.length!==a.chart.data.labels.length){var d=n.ticks.length/a.chart.data.labels.length;s*=d}var u=s*n.options.barPercentage,c=s-s*n.options.barPercentage;return{datasetCount:o,tickHeight:e,categoryHeight:r,categorySpacing:l,fullBarHeight:s,barHeight:u,barSpacing:c}},calculateBarHeight:function(t){var e=this,a=e.getScaleForId(e.getMeta().yAxisID);if(a.options.barThickness)return a.options.barThickness;var i=e.getRuler(t);return a.options.stacked?i.categoryHeight:i.barHeight},calculateBarX:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=Number(a.getDataset().data[t]);if(n.options.stacked){for(var r=0,l=0,s=0;e>s;s++){var d=a.chart.data.datasets[s],u=a.chart.getDatasetMeta(s);if(u.bar&&u.xAxisID===n.id&&a.chart.isDatasetVisible(s)){var c=Number(d.data[t]);0>c?l+=c||0:r+=c||0}}return 0>o?n.getPixelForValue(l+o):n.getPixelForValue(r+o)}return n.getPixelForValue(o)},calculateBarY:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=a.getBarIndex(e),r=a.getRuler(t),l=n.getPixelForValue(null,t,e,a.chart.isCombo);return l-=a.chart.isCombo?r.tickHeight/2:0,n.options.stacked?l+r.categoryHeight/2+r.categorySpacing:l+r.barHeight/2+r.categorySpacing+r.barHeight*o+r.barSpacing/2+r.barSpacing*o}})}},{}],16:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return a+": ("+i.x+", "+i.y+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var a=this,i=a.getMeta(),n=i.data;e.each(n,function(e,i){a.updateElement(e,i,t)})},updateElement:function(a,i,n){var o=this,r=o.getMeta(),l=o.getScaleForId(r.xAxisID),s=o.getScaleForId(r.yAxisID),d=a.custom||{},u=o.getDataset(),c=u.data[i],h=o.chart.options.elements.point,f=o.index;e.extend(a,{_xScale:l,_yScale:s,_datasetIndex:f,_index:i,_model:{x:n?l.getPixelForDecimal(.5):l.getPixelForValue("object"==typeof c?c:NaN,i,f,o.chart.isCombo),y:n?s.getBasePixel():s.getPixelForValue(c,i,f),radius:n?0:d.radius?d.radius:o.getRadius(c),hitRadius:d.hitRadius?d.hitRadius:e.getValueAtIndexOrDefault(u.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(o,a,h);var g=a._model;g.skip=d.skip?d.skip:isNaN(g.x)||isNaN(g.y),a.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(a){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,a);var n=i.chart.data.datasets[a._datasetIndex],o=a._index,r=a.custom||{},l=a._model;l.radius=r.hoverRadius?r.hoverRadius:e.getValueAtIndexOrDefault(n.hoverRadius,o,i.chart.options.elements.point.hoverRadius)+i.getRadius(n.data[o])},removeHoverStyle:function(e){var a=this;t.DatasetController.prototype.removeHoverStyle.call(a,e,a.chart.options.elements.point);var i=a.chart.data.datasets[e._datasetIndex].data[e._index],n=e.custom||{},o=e._model;o.radius=n.radius?n.radius:a.getRadius(i)}})}},{}],17:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults;a.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),n[o]&&e.push(n[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],l=o.data[n],s=l&&l.custom||{},d=e.getValueAtIndexOrDefault,u=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:d(r.backgroundColor,n,u.backgroundColor),h=s.borderColor?s.borderColor:d(r.borderColor,n,u.borderColor),f=s.borderWidth?s.borderWidth:d(r.borderWidth,n,u.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;i>a;++a)n=r.getDatasetMeta(a),n.data[o].hidden=!n.data[o].hidden;r.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+e.datasets[t.datasetIndex].data[t.index]}}}},a.pie=e.clone(a.doughnut),e.extend(a.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,a=0;t>a;++a)this.chart.isDatasetVisible(a)&&++e;return e},update:function(t){var a=this,i=a.chart,n=i.chartArea,o=i.options,r=o.elements.arc,l=n.right-n.left-r.borderWidth,s=n.bottom-n.top-r.borderWidth,d=Math.min(l,s),u={x:0,y:0},c=a.getMeta(),h=o.cutoutPercentage,f=o.circumference;if(f<2*Math.PI){var g=o.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},b={x:Math.cos(p),y:Math.sin(p)},v=0>=g&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,x=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,y=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,w={x:y?-1:Math.min(m.x*(m.x<0?1:S),b.x*(b.x<0?1:S)),y:k?-1:Math.min(m.y*(m.y<0?1:S),b.y*(b.y<0?1:S))},C={x:v?1:Math.max(m.x*(m.x>0?1:S),b.x*(b.x>0?1:S)),y:x?1:Math.max(m.y*(m.y>0?1:S),b.y*(b.y>0?1:S))},M={width:.5*(C.x-w.x),height:.5*(C.y-w.y)};d=Math.min(l/M.width,s/M.height),u={x:(C.x+w.x)*-.5,y:(C.y+w.y)*-.5}}i.borderWidth=a.getMaxBorderWidth(c.data),i.outerRadius=Math.max((d-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=u.x*i.outerRadius,i.offsetY=u.y*i.outerRadius,c.total=a.calculateTotal(),a.outerRadius=i.outerRadius-i.radiusLength*a.getRingIndex(a.index),a.innerRadius=a.outerRadius-i.radiusLength,e.each(c.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){var n=this,o=n.chart,r=o.chartArea,l=o.options,s=l.animation,d=(r.left+r.right)/2,u=(r.top+r.bottom)/2,c=l.rotation,h=l.rotation,f=n.getDataset(),g=i&&s.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[a])*(l.circumference/(2*Math.PI)),p=i&&s.animateScale?0:n.innerRadius,m=i&&s.animateScale?0:n.outerRadius,b=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:n.index,_index:a,_model:{x:d+o.offsetX,y:u+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:b(f.label,a,o.data.labels[a])}});var v=t._model;this.removeHoverStyle(t),i&&s.animateRotate||(0===a?v.startAngle=l.rotation:v.startAngle=n.getMeta().data[a-1]._model.endAngle,v.endAngle=v.startAngle+v.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,a=this.getDataset(),i=this.getMeta(),n=0;return e.each(i.data,function(e,i){t=a.data[i],isNaN(t)||e.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,a,i=0,n=this.index,o=t.length,r=0;o>r;r++)e=t[r]._model?t[r]._model.borderWidth:0,a=t[r]._chart?t[r]._chart.config.data.datasets[n].hoverBorderWidth:0,i=e>i?e:i,i=a>i?a:i;return i}})}},{}],18:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return a.getValueOrDefault(t.showLine,e.showLines)}var a=t.helpers;t.defaults.line={showLines:!0,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,addElementAndReset:function(a){var i=this,n=i.chart.options,o=i.getMeta();t.DatasetController.prototype.addElementAndReset.call(i,a),e(i.getDataset(),n)&&0!==o.dataset._model.tension&&i.updateBezierControlPoints()},update:function(t){var i,n,o,r=this,l=r.getMeta(),s=l.dataset,d=l.data||[],u=r.chart.options,c=u.elements.line,h=r.getScaleForId(l.yAxisID),f=r.getDataset(),g=e(f,u);for(g&&(o=s.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),s._scale=h,s._datasetIndex=r.index,s._children=d,s._model={spanGaps:f.spanGaps?f.spanGaps:u.spanGaps,tension:o.tension?o.tension:a.getValueOrDefault(f.lineTension,c.tension),backgroundColor:o.backgroundColor?o.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:f.borderWidth||c.borderWidth,borderColor:o.borderColor?o.borderColor:f.borderColor||c.borderColor,borderCapStyle:o.borderCapStyle?o.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:o.borderDash?o.borderDash:f.borderDash||c.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:o.fill?o.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:o.steppedLine?o.steppedLine:a.getValueOrDefault(f.steppedLine,c.stepped),scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},s.pivot()),i=0,n=d.length;n>i;++i)r.updateElement(d[i],i,t);for(g&&0!==s._model.tension&&r.updateBezierControlPoints(),i=0,n=d.length;n>i;++i)d[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,n=this.getDataset(),o=t.custom||{};return o.backgroundColor?i=o.backgroundColor:n.pointBackgroundColor?i=a.getValueAtIndexOrDefault(n.pointBackgroundColor,e,i):n.backgroundColor&&(i=n.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,n=this.getDataset(),o=t.custom||{};return o.borderColor?i=o.borderColor:n.pointBorderColor?i=a.getValueAtIndexOrDefault(n.pointBorderColor,e,i):n.borderColor&&(i=n.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,n=this.getDataset(),o=t.custom||{};return o.borderWidth?i=o.borderWidth:n.pointBorderWidth?i=a.getValueAtIndexOrDefault(n.pointBorderWidth,e,i):n.borderWidth&&(i=n.borderWidth),i},updateElement:function(t,e,i){var n,o,r=this,l=r.getMeta(),s=t.custom||{},d=r.getDataset(),u=r.index,c=d.data[e],h=r.getScaleForId(l.yAxisID),f=r.getScaleForId(l.xAxisID),g=r.chart.options.elements.point;void 0!==d.radius&&void 0===d.pointRadius&&(d.pointRadius=d.radius),void 0!==d.hitRadius&&void 0===d.pointHitRadius&&(d.pointHitRadius=d.hitRadius),n=f.getPixelForValue("object"==typeof c?c:NaN,e,u,r.chart.isCombo),o=i?h.getBasePixel():r.calculatePointY(c,e,u),t._xScale=f,t._yScale=h,t._datasetIndex=u,t._index=e,t._model={x:n,y:o,skip:s.skip||isNaN(n)||isNaN(o),radius:s.radius||a.getValueAtIndexOrDefault(d.pointRadius,e,g.radius),pointStyle:s.pointStyle||a.getValueAtIndexOrDefault(d.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:l.dataset._model?l.dataset._model.tension:0,steppedLine:l.dataset._model?l.dataset._model.steppedLine:!1,hitRadius:s.hitRadius||a.getValueAtIndexOrDefault(d.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,a){var i,n,o,r=this,l=r.chart,s=r.getMeta(),d=r.getScaleForId(s.yAxisID),u=0,c=0;if(d.options.stacked){for(i=0;a>i;i++)if(n=l.data.datasets[i],o=l.getDatasetMeta(i),"line"===o.type&&o.yAxisID===d.id&&l.isDatasetVisible(i)){var h=Number(d.getRightValue(n.data[e]));0>h?c+=h||0:u+=h||0}var f=Number(d.getRightValue(t));return 0>f?d.getPixelForValue(c+f):d.getPixelForValue(u+f)}return d.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,a){return c?Math.max(Math.min(t,a),e):t}var e,i,n,o,r,l=this,s=l.getMeta(),d=l.chart.chartArea,u=(s.data||[]).filter(function(t){return!t._model.skip}),c=l.chart.options.elements.line.capBezierPoints;for(e=0,i=u.length;i>e;++e)n=u[e],o=n._model,r=a.splineCurve(a.previousItem(u,e)._model,o,a.nextItem(u,e)._model,s.dataset._model.tension),o.controlPointPreviousX=t(r.previous.x,d.left,d.right),o.controlPointPreviousY=t(r.previous.y,d.top,d.bottom),o.controlPointNextX=t(r.next.x,d.left,d.right),o.controlPointNextY=t(r.next.y,d.top,d.bottom)},draw:function(t){var a,i,n=this,o=n.getMeta(),r=o.data||[],l=t||1;for(a=0,i=r.length;i>a;++a)r[a].transition(l);for(e(n.getDataset(),n.chart.options)&&o.dataset.transition(l).draw(),a=0,i=r.length;i>a;++a)r[a].draw()},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.radius=n.hoverRadius||a.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),o.backgroundColor=n.hoverBackgroundColor||a.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,a.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor||a.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,a.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth||a.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=o.radius||a.getValueAtIndexOrDefault(i.pointRadius,n,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,n),r.borderColor=e.getPointBorderColor(t,n),r.borderWidth=e.getPointBorderWidth(t,n)}})}},{}],19:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0,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 a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'">'),n[o]&&e.push(n[o]),e.push("</span></li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],l=o.data[n],s=l.custom||{},d=e.getValueAtIndexOrDefault,u=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:d(r.backgroundColor,n,u.backgroundColor),h=s.borderColor?s.borderColor:d(r.borderColor,n,u.borderColor),f=s.borderWidth?s.borderWidth:d(r.borderWidth,n,u.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;i>a;++a)n=r.getDatasetMeta(a),n.data[o].hidden=!n.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var a=this,i=a.chart,n=i.chartArea,o=a.getMeta(),r=i.options,l=r.elements.arc,s=Math.min(n.right-n.left,n.bottom-n.top);i.outerRadius=Math.max((s-l.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),a.outerRadius=i.outerRadius-i.radiusLength*a.index,a.innerRadius=a.outerRadius-i.radiusLength,o.count=a.countVisibleElements(),e.each(o.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){for(var n=this,o=n.chart,r=n.getDataset(),l=o.options,s=l.animation,d=o.scale,u=e.getValueAtIndexOrDefault,c=o.data.labels,h=n.calculateCircumference(r.data[a]),f=d.xCenter,g=d.yCenter,p=0,m=n.getMeta(),b=0;a>b;++b)isNaN(r.data[b])||m.data[b].hidden||++p;var v=l.startAngle,x=t.hidden?0:d.getDistanceFromCenterForValue(r.data[a]),y=v+h*p,k=y+(t.hidden?0:h),S=s.animateScale?0:d.getDistanceFromCenterForValue(r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:d,_model:{x:f,y:g,innerRadius:0,outerRadius:i?S:x,startAngle:i&&s.animateRotate?v:y,endAngle:i&&s.animateRotate?v:k,label:u(c,a,c[a])}}),n.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),a=this.getMeta(),i=0;return e.each(a.data,function(e,a){isNaN(t.data[a])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,addElementAndReset:function(e){t.DatasetController.prototype.addElementAndReset.call(this,e),this.updateBezierControlPoints()},update:function(t){var a=this,i=a.getMeta(),n=i.dataset,o=i.data,r=n.custom||{},l=a.getDataset(),s=a.chart.options.elements.line,d=a.chart.scale;void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),e.extend(i.dataset,{_datasetIndex:a.index,_children:o,_loop:!0,_model:{tension:r.tension?r.tension:e.getValueOrDefault(l.lineTension,s.tension),backgroundColor:r.backgroundColor?r.backgroundColor:l.backgroundColor||s.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:l.borderWidth||s.borderWidth,borderColor:r.borderColor?r.borderColor:l.borderColor||s.borderColor,fill:r.fill?r.fill:void 0!==l.fill?l.fill:s.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:l.borderCapStyle||s.borderCapStyle,borderDash:r.borderDash?r.borderDash:l.borderDash||s.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:l.borderDashOffset||s.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:l.borderJoinStyle||s.borderJoinStyle,scaleTop:d.top,scaleBottom:d.bottom,scaleZero:d.getBasePosition()}}),i.dataset.pivot(),e.each(o,function(e,i){a.updateElement(e,i,t)},a),a.updateBezierControlPoints()},updateElement:function(t,a,i){var n=this,o=t.custom||{},r=n.getDataset(),l=n.chart.scale,s=n.chart.options.elements.point,d=l.getPointPositionForValue(a,r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:l,_model:{x:i?l.xCenter:d.x,y:i?l.yCenter:d.y,tension:o.tension?o.tension:e.getValueOrDefault(r.tension,n.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,a,s.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,a,s.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,a,s.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,a,s.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,a,s.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.hitRadius,a,s.hitRadius)}}),t._model.skip=o.skip?o.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,a=this.getMeta();e.each(a.data,function(i,n){var o=i._model,r=e.splineCurve(e.previousItem(a.data,n,!0)._model,o,e.nextItem(a.data,n,!0)._model,o.tension);o.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),o.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),o.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),o.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var a=this.getMeta(),i=t||1;e.each(a.data,function(t){t.transition(i)}),a.dataset.transition(i).draw(),e.each(a.data,function(t){t.draw()})},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(a.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.pointHoverBackgroundColor,n,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(a.pointHoverBorderColor,n,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(a.pointHoverBorderWidth,n,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(a.radius,n,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(a.pointBackgroundColor,n,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(a.pointBorderColor,n,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(a.pointBorderWidth,n,r.borderWidth)}})}},{}],21:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,a,i){var n=this;i||(t.animating=!0);for(var o=0;o<n.animations.length;++o)if(n.animations[o].chartInstance===t)return void(n.animations[o].animationObject=e);n.animations.push({chartInstance:t,animationObject:e}),1===n.animations.length&&n.requestAnimationFrame()},cancelAnimation:function(t){var a=e.findIndex(this.animations,function(e){return e.chartInstance===t});-1!==a&&(this.animations.splice(a,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),a=0;t.dropFrames>1&&(a=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;i<t.animations.length;)null===t.animations[i].animationObject.currentStep&&(t.animations[i].animationObject.currentStep=0),t.animations[i].animationObject.currentStep+=1+a,t.animations[i].animationObject.currentStep>t.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var n=Date.now(),o=(n-e)/t.frameDuration;t.dropFrames+=o,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,a){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(t,e,a,i,n){var o,r,l,s,d,u;if("object"==typeof e&&(o=e.toString(),"[object HTMLImageElement]"===o||"[object HTMLCanvasElement]"===o))return void t.drawImage(e,i-e.width/2,n-e.height/2);if(!(isNaN(a)||0>=a)){switch(e){default:t.beginPath(),t.arc(i,n,a,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),r=3*a/Math.sqrt(3),d=r*Math.sqrt(3)/2,t.moveTo(i-r/2,n+d/3),t.lineTo(i+r/2,n+d/3),t.lineTo(i,n-2*d/3),t.closePath(),t.fill();break;case"rect":u=1/Math.SQRT2*a,t.beginPath(),t.fillRect(i-u,n-u,2*u,2*u),t.strokeRect(i-u,n-u,2*u,2*u);break;case"rectRot":u=1/Math.SQRT2*a,t.beginPath(),t.moveTo(i-u,n),t.lineTo(i,n+u),t.lineTo(i+u,n),t.lineTo(i,n-u),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(i,n+a),t.lineTo(i,n-a),t.moveTo(i-a,n),t.lineTo(i+a,n),t.closePath();break;case"crossRot":t.beginPath(),l=Math.cos(Math.PI/4)*a,s=Math.sin(Math.PI/4)*a,t.moveTo(i-l,n-s),t.lineTo(i+l,n+s),t.moveTo(i-l,n+s),t.lineTo(i+l,n-s),t.closePath();break;case"star":t.beginPath(),t.moveTo(i,n+a),t.lineTo(i,n-a),t.moveTo(i-a,n),t.lineTo(i+a,n),l=Math.cos(Math.PI/4)*a,s=Math.sin(Math.PI/4)*a,t.moveTo(i-l,n-s),t.lineTo(i+l,n+s),t.moveTo(i-l,n+s),t.lineTo(i+l,n-s),t.closePath();break;case"line":t.beginPath(),t.moveTo(i-a,n),t.lineTo(i+a,n),t.closePath();break;case"dash":t.beginPath(),t.moveTo(i,n),t.lineTo(i+a,n),t.closePath()}t.stroke()}}}},{}],23:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.types={},t.instances={},t.controllers={},t.Controller=function(a){return this.chart=a,this.config=a.config,this.options=this.config.options=e.configMerge(t.defaults.global,t.defaults[this.config.type],this.config.options||{}),this.id=e.uid(),Object.defineProperty(this,"data",{get:function(){return this.config.data}}),t.instances[this.id]=this,this.options.responsive&&this.resize(!0),this.initialize(),this},e.extend(t.Controller.prototype,{initialize:function(){var e=this;return t.plugins.notify("beforeInit",[e]),e.bindEvents(),e.ensureScalesHaveIDs(),e.buildOrUpdateControllers(),e.buildScales(),e.updateLayout(),e.resetElements(),e.initToolTip(),e.update(),t.plugins.notify("afterInit",[e]),e},clear:function(){return e.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(a){var i=this,n=i.chart,o=n.canvas,r=e.getMaximumWidth(o),l=n.aspectRatio,s=i.options.maintainAspectRatio&&isNaN(l)===!1&&isFinite(l)&&0!==l?r/l:e.getMaximumHeight(o),d=n.width!==r||n.height!==s;if(!d)return i;o.width=n.width=r,o.height=n.height=s,e.retinaScale(n);var u={width:r,height:s};return t.plugins.notify("resize",[i,u]),i.options.onResize&&i.options.onResize(i,u),a||(i.stop(),i.update(i.options.responsiveAnimationDuration)),i},ensureScalesHaveIDs:function(){var t=this.options,a=t.scales||{},i=t.scale;e.each(a.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),e.each(a.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildScales:function(){var a=this,i=a.options,n=a.scales={},o=[];i.scales&&(o=o.concat((i.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(i.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),i.scale&&o.push({options:i.scale,dtype:"radialLinear",isDefault:!0}),e.each(o,function(i){var o=i.options,r=e.getValueOrDefault(o.type,i.dtype),l=t.scaleService.getScaleConstructor(r);if(l){var s=new l({id:o.id,options:o,ctx:a.chart.ctx,chart:a});n[s.id]=s,i.isDefault&&(a.scale=s)}}),t.scaleService.addScalesToLayout(this)},updateLayout:function(){t.layoutService.update(this,this.chart.width,this.chart.height)},buildOrUpdateControllers:function(){var a=this,i=[],n=[];if(e.each(a.data.datasets,function(e,o){var r=a.getDatasetMeta(o);r.type||(r.type=e.type||a.config.type),i.push(r.type),r.controller?r.controller.updateIndex(o):(r.controller=new t.controllers[r.type](a,o),n.push(r.controller))},a),i.length>1)for(var o=1;o<i.length;o++)if(i[o]!==i[o-1]){a.isCombo=!0;break}return n},resetElements:function(){var t=this;e.each(t.data.datasets,function(e,a){t.getDatasetMeta(a).controller.reset()},t)},update:function(a,i){var n=this;t.plugins.notify("beforeUpdate",[n]),n.tooltip._data=n.data;var o=n.buildOrUpdateControllers();e.each(n.data.datasets,function(t,e){n.getDatasetMeta(e).controller.buildOrUpdateElements()},n),t.layoutService.update(n,n.chart.width,n.chart.height),t.plugins.notify("afterScaleUpdate",[n]),e.each(o,function(t){t.reset()}),n.updateDatasets(),t.plugins.notify("afterUpdate",[n]),n.render(a,i)},updateDatasets:function(){var e,a,i=this;if(t.plugins.notify("beforeDatasetsUpdate",[i])){for(e=0,a=i.data.datasets.length;a>e;++e)i.getDatasetMeta(e).controller.update();t.plugins.notify("afterDatasetsUpdate",[i])}},render:function(a,i){var n=this;t.plugins.notify("beforeRender",[n]);var o=n.options.animation;if(o&&("undefined"!=typeof a&&0!==a||"undefined"==typeof a&&0!==o.duration)){var r=new t.Animation;r.numSteps=(a||o.duration)/16.66,r.easing=o.easing,r.render=function(t,a){var i=e.easingEffects[a.easing],n=a.currentStep/a.numSteps,o=i(n);t.draw(o,n,a.currentStep)},r.onAnimationProgress=o.onProgress,r.onAnimationComplete=o.onComplete,t.animationService.addAnimation(n,r,a,i)}else n.draw(),o&&o.onComplete&&o.onComplete.call&&o.onComplete.call(n);return n},draw:function(a){var i=this,n=a||1;i.clear(),t.plugins.notify("beforeDraw",[i,n]),e.each(i.boxes,function(t){t.draw(i.chartArea)},i),i.scale&&i.scale.draw(),t.plugins.notify("beforeDatasetsDraw",[i,n]),e.each(i.data.datasets,function(t,e){i.isDatasetVisible(e)&&i.getDatasetMeta(e).controller.draw(a)},i,!0),t.plugins.notify("afterDatasetsDraw",[i,n]),i.tooltip.transition(n).draw(),t.plugins.notify("afterDraw",[i,n])},getElementAtEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[];return e.each(a.data.datasets,function(t,o){if(a.isDatasetVisible(o)){var r=a.getDatasetMeta(o);e.each(r.data,function(t){return t.inRange(i.x,i.y)?(n.push(t),n):void 0})}}),n.slice(0,1)},getElementsAtEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[],o=function(){if(a.data.datasets)for(var t=0;t<a.data.datasets.length;t++){var e=a.getDatasetMeta(t);if(a.isDatasetVisible(t))for(var n=0;n<e.data.length;n++)if(e.data[n].inRange(i.x,i.y))return e.data[n]}}.call(a);return o?(e.each(a.data.datasets,function(t,e){if(a.isDatasetVisible(e)){var i=a.getDatasetMeta(e),r=i.data[o._index];r&&!r._view.skip&&n.push(r)}},a),n):n},getElementsAtXAxis:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[],o=function(){if(a.data.datasets)for(var t=0;t<a.data.datasets.length;t++){var e=a.getDatasetMeta(t);if(a.isDatasetVisible(t))for(var n=0;n<e.data.length;n++)if(e.data[n].inLabelRange(i.x,i.y))return e.data[n]}}.call(a);return o?(e.each(a.data.datasets,function(t,i){if(a.isDatasetVisible(i)){var r=a.getDatasetMeta(i),l=e.findIndex(r.data,function(t){return o._model.x===t._model.x});-1===l||r.data[l]._view.skip||n.push(r.data[l])}},a),n):n},getElementsAtEventForMode:function(t,e){var a=this;switch(e){case"single":return a.getElementAtEvent(t);case"label":return a.getElementsAtEvent(t);case"dataset":return a.getDatasetAtEvent(t);case"x-axis":return a.getElementsAtXAxis(t);default:return t}},getDatasetAtEvent:function(t){var e=this.getElementAtEvent(t);return e.length>0&&(e=this.getDatasetMeta(e[0]._datasetIndex).data),e},getDatasetMeta:function(t){var e=this,a=e.data.datasets[t];a._meta||(a._meta={});var i=a._meta[e.id];return i||(i=a._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,a=this.data.datasets.length;a>e;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden;
-},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var a=this;a.stop(),a.clear(),e.unbindEvents(a,a.events),e.removeResizeListener(a.chart.canvas.parentNode);var i=a.chart.canvas;i.width=a.chart.width,i.height=a.chart.height,void 0!==a.chart.originalDevicePixelRatio&&a.chart.ctx.scale(1/a.chart.originalDevicePixelRatio,1/a.chart.originalDevicePixelRatio),i.style.width=a.chart.originalCanvasStyleWidth,i.style.height=a.chart.originalCanvasStyleHeight,t.plugins.notify("destroy",[a]),delete t.instances[a.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e.chart,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this;e.bindEvents(t,t.options.events,function(e){t.eventHandler(e)})},updateHoverStyle:function(t,e,a){var i,n,o,r=a?"setHoverStyle":"removeHoverStyle";switch(e){case"single":t=[t[0]];break;case"label":case"dataset":case"x-axis":break;default:return}for(n=0,o=t.length;o>n;++n)i=t[n],i&&this.getDatasetMeta(i._datasetIndex).controller[r](i)},eventHandler:function(t){var a=this,i=a.tooltip,n=a.options||{},o=n.hover,r=n.tooltips;return a.lastActive=a.lastActive||[],a.lastTooltipActive=a.lastTooltipActive||[],"mouseout"===t.type?(a.active=[],a.tooltipActive=[]):(a.active=a.getElementsAtEventForMode(t,o.mode),a.tooltipActive=a.getElementsAtEventForMode(t,r.mode)),o.onHover&&o.onHover.call(a,a.active),("mouseup"===t.type||"click"===t.type)&&(n.onClick&&n.onClick.call(a,t,a.active),a.legend&&a.legend.handleEvent&&a.legend.handleEvent(t)),a.lastActive.length&&a.updateHoverStyle(a.lastActive,o.mode,!1),a.active.length&&o.mode&&a.updateHoverStyle(a.active,o.mode,!0),(r.enabled||r.custom)&&(i.initialize(),i._active=a.tooltipActive,i.update(!0)),i.pivot(),a.animating||e.arrayEquals(a.active,a.lastActive)&&e.arrayEquals(a.tooltipActive,a.lastTooltipActive)||(a.stop(),(r.enabled||r.custom)&&i.update(!0),a.render(o.animationDuration,!0)),a.lastActive=a.active,a.lastTooltipActive=a.tooltipActive,a}})}},{}],24:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.DatasetController=function(t,e){this.initialize.call(this,t,e)},e.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var a=this;a.chart=t,a.index=e,a.linkScales(),a.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),a=t.getDataset();null===e.xAxisID&&(e.xAxisID=a.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=a.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,a=e.dataElementType;return a&&new a({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,a=this,i=a.getMeta(),n=a.getDataset().data||[],o=i.data;for(t=0,e=n.length;e>t;++t)o[t]=o[t]||a.createMetaData(i,t);i.dataset=i.dataset||a.createMetaDataset()},addElementAndReset:function(t){var e=this,a=e.createMetaData(t);e.getMeta().data.splice(t,0,a),e.updateElement(a,t,!0)},buildOrUpdateElements:function(){var t=this.getMeta(),e=t.data,a=this.getDataset().data.length,i=e.length;if(i>a)e.splice(a,i-a);else if(a>i)for(var n=i;a>n;++n)this.addElementAndReset(n)},update:a,draw:function(t){var a=t||1;e.each(this.getMeta().data,function(t){t.transition(a).draw()})},removeHoverStyle:function(t,a){var i=this.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=e.getValueAtIndexOrDefault,l=t._model;l.backgroundColor=o.backgroundColor?o.backgroundColor:r(i.backgroundColor,n,a.backgroundColor),l.borderColor=o.borderColor?o.borderColor:r(i.borderColor,n,a.borderColor),l.borderWidth=o.borderWidth?o.borderWidth:r(i.borderWidth,n,a.borderWidth)},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=e.getValueAtIndexOrDefault,r=e.getHoverColor,l=t._model;l.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:o(a.hoverBackgroundColor,i,r(l.backgroundColor)),l.borderColor=n.hoverBorderColor?n.hoverBorderColor:o(a.hoverBorderColor,i,r(l.borderColor)),l.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:o(a.hoverBorderWidth,i,l.borderWidth)}}),t.DatasetController.extend=e.inherits}},{}],25:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=e.clone(t._model)),t._start=e.clone(t._view),t},transition:function(t){var a=this;return a._view||(a._view=e.clone(a._model)),1===t?(a._view=a._model,a._start=null,a):(a._start||a.pivot(),e.each(a._model,function(i,n){if("_"===n[0]);else if(a._view.hasOwnProperty(n))if(i===a._view[n]);else if("string"==typeof i)try{var o=e.color(a._model[n]).mix(e.color(a._start[n]),t);a._view[n]=o.rgbString()}catch(r){a._view[n]=i}else if("number"==typeof i){var l=void 0!==a._start[n]&&isNaN(a._start[n])===!1?a._start[n]:0;a._view[n]=(a._model[n]-l)*t+l}else a._view[n]=i;else"number"!=typeof i||isNaN(a._view[n])?a._view[n]=i:a._view[n]=i*t},a),a)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],26:[function(t,e,a){"use strict";var i=t(3);e.exports=function(t){function e(t,e,a){var i;return"string"==typeof t?(i=parseInt(t,10),-1!=t.indexOf("%")&&(i=i/100*e.parentNode[a])):i=t,i}function a(t){return void 0!==t&&null!==t&&"none"!==t}function n(t,i,n){var o=document.defaultView,r=t.parentNode,l=o.getComputedStyle(t)[i],s=o.getComputedStyle(r)[i],d=a(l),u=a(s),c=Number.POSITIVE_INFINITY;return d||u?Math.min(d?e(l,t,n):c,u?e(s,r,n):c):"none"}var o=t.helpers={};o.each=function(t,e,a,i){var n,r;if(o.isArray(t))if(r=t.length,i)for(n=r-1;n>=0;n--)e.call(a,t[n],n);else for(n=0;r>n;n++)e.call(a,t[n],n);else if("object"==typeof t){var l=Object.keys(t);for(r=l.length,n=0;r>n;n++)e.call(a,t[l[n]],l[n])}},o.clone=function(t){var e={};return o.each(t,function(t,a){o.isArray(t)?e[a]=t.slice(0):"object"==typeof t&&null!==t?e[a]=o.clone(t):e[a]=t}),e},o.extend=function(t){for(var e=function(e,a){t[a]=e},a=1,i=arguments.length;i>a;a++)o.each(arguments[a],e);return t},o.configMerge=function(e){var a=o.clone(e);return o.each(Array.prototype.slice.call(arguments,1),function(e){o.each(e,function(e,i){if("scales"===i)a[i]=o.scaleMerge(a.hasOwnProperty(i)?a[i]:{},e);else if("scale"===i)a[i]=o.configMerge(a.hasOwnProperty(i)?a[i]:{},t.scaleService.getScaleDefaults(e.type),e);else if(a.hasOwnProperty(i)&&o.isArray(a[i])&&o.isArray(e)){var n=a[i];o.each(e,function(t,e){e<n.length?"object"==typeof n[e]&&null!==n[e]&&"object"==typeof t&&null!==t?n[e]=o.configMerge(n[e],t):n[e]=t:n.push(t)})}else a.hasOwnProperty(i)&&"object"==typeof a[i]&&null!==a[i]&&"object"==typeof e?a[i]=o.configMerge(a[i],e):a[i]=e})}),a},o.scaleMerge=function(e,a){var i=o.clone(e);return o.each(a,function(e,a){"xAxes"===a||"yAxes"===a?i.hasOwnProperty(a)?o.each(e,function(e,n){var r=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear"),l=t.scaleService.getScaleDefaults(r);n>=i[a].length||!i[a][n].type?i[a].push(o.configMerge(l,e)):e.type&&e.type!==i[a][n].type?i[a][n]=o.configMerge(i[a][n],l,e):i[a][n]=o.configMerge(i[a][n],e)}):(i[a]=[],o.each(e,function(e){var n=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear");i[a].push(o.configMerge(t.scaleService.getScaleDefaults(n),e))})):i.hasOwnProperty(a)&&"object"==typeof i[a]&&null!==i[a]&&"object"==typeof e?i[a]=o.configMerge(i[a],e):i[a]=e}),i},o.getValueAtIndexOrDefault=function(t,e,a){return void 0===t||null===t?a:o.isArray(t)?e<t.length?t[e]:a:t},o.getValueOrDefault=function(t,e){return void 0===t?e:t},o.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var a=0,i=t.length;i>a;++a)if(t[a]===e)return a;return-1},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var a=[];return o.each(t,function(t){e(t)&&a.push(t)}),a},o.findIndex=Array.prototype.findIndex?function(t,e,a){return t.findIndex(e,a)}:function(t,e,a){a=void 0===a?t:a;for(var i=0,n=t.length;n>i;++i)if(e.call(a,t[i],i,t))return i;return-1},o.findNextWhere=function(t,e,a){(void 0===a||null===a)&&(a=-1);for(var i=a+1;i<t.length;i++){var n=t[i];if(e(n))return n}},o.findPreviousWhere=function(t,e,a){(void 0===a||null===a)&&(a=t.length);for(var i=a-1;i>=0;i--){var n=t[i];if(e(n))return n}},o.inherits=function(t){var e=this,a=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=a};return i.prototype=e.prototype,a.prototype=new i,a.extend=o.inherits,t&&o.extend(a.prototype,t),a.__super__=e.prototype,a},o.noop=function(){},o.uid=function(){var t=0;return function(){return t++}}(),o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,a){return Math.abs(t-e)<a},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var a=e.x-t.x,i=e.y-t.y,n=Math.sqrt(a*a+i*i),o=Math.atan2(i,a);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:n}},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,a,i){var n=t.skip?e:t,o=e,r=a.skip?e:a,l=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),s=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),d=l/(l+s),u=s/(l+s);d=isNaN(d)?0:d,u=isNaN(u)?0:u;var c=i*d,h=i*u;return{previous:{x:o.x-c*(r.x-n.x),y:o.y-c*(r.y-n.y)},next:{x:o.x+h*(r.x-n.x),y:o.y+h*(r.y-n.y)}}},o.nextItem=function(t,e,a){return a?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,a){return a?0>=e?t[t.length-1]:t[e-1]:0>=e?t[0]:t[e-1]},o.niceNum=function(t,e){var a,i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return a=e?1.5>n?1:3>n?2:7>n?5:10:1>=n?1:2>=n?2:5>=n?5:10,a*Math.pow(10,i)};var r=o.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)))},easeOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/a)+1)},easeInOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:2===(t/=.5)?1:(a||(a=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),1>t?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-r.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*r.easeInBounce(2*t):.5*r.easeOutBounce(2*t-1)+.5}};o.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),o.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),o.getRelativePosition=function(t,e){var a,i,n=t.originalEvent||t,r=t.currentTarget||t.srcElement,l=r.getBoundingClientRect(),s=n.touches;s&&s.length>0?(a=s[0].clientX,i=s[0].clientY):(a=n.clientX,i=n.clientY);var d=parseFloat(o.getStyle(r,"padding-left")),u=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=l.right-l.left-d-c,g=l.bottom-l.top-u-h;return a=Math.round((a-l.left-d)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-l.top-u)/g*r.height/e.currentDevicePixelRatio),{x:a,y:i}},o.addEvent=function(t,e,a){t.addEventListener?t.addEventListener(e,a):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a},o.removeEvent=function(t,e,a){t.removeEventListener?t.removeEventListener(e,a,!1):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=o.noop},o.bindEvents=function(t,e,a){var i=t.events=t.events||{};o.each(e,function(e){i[e]=function(){a.apply(t,arguments)},o.addEvent(t.chart.canvas,e,i[e])})},o.unbindEvents=function(t,e){var a=t.chart.canvas;o.each(e,function(t,e){o.removeEvent(a,e,t)})},o.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-left"))+parseInt(o.getStyle(e,"padding-right")),i=e.clientWidth-a,n=o.getConstraintWidth(t);return isNaN(n)?i:Math.min(i,n)},o.getMaximumHeight=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-top"))+parseInt(o.getStyle(e,"padding-bottom")),i=e.clientHeight-a,n=o.getConstraintHeight(t);return isNaN(n)?i:Math.min(i,n)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t){var e=t.ctx,a=t.canvas,i=a.width,n=a.height,o=t.currentDevicePixelRatio=window.devicePixelRatio||1;1!==o&&(a.height=n*o,a.width=i*o,e.scale(o,o),t.originalDevicePixelRatio=t.originalDevicePixelRatio||o),a.style.width=i+"px",a.style.height=n+"px"},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,a){return e+" "+t+"px "+a},o.longestText=function(t,e,a,i){i=i||{};var n=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(n=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var l=0;o.each(a,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?l=o.measureText(t,n,r,l,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(l=o.measureText(t,n,r,l,e))})});var s=r.length/2;if(s>a.length){for(var d=0;s>d;d++)delete n[r[d]];r.splice(0,s)}return l},o.measureText=function(t,e,a,i,n){var o=e[n];return o||(o=e[n]=t.measureText(n).width,a.push(n)),o>i&&(i=o),i},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.drawRoundedRectangle=function(t,e,a,i,n,o){t.beginPath(),t.moveTo(e+o,a),t.lineTo(e+i-o,a),t.quadraticCurveTo(e+i,a,e+i,a+o),t.lineTo(e+i,a+n-o),t.quadraticCurveTo(e+i,a+n,e+i-o,a+n),t.lineTo(e+o,a+n),t.quadraticCurveTo(e,a+n,e,a+n-o),t.lineTo(e,a+o),t.quadraticCurveTo(e,a,e+o,a),t.closePath()},o.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.log("Color.js not found!"),e)},o.addResizeListener=function(t,e){var a=document.createElement("iframe"),i="chartjs-hidden-iframe";a.classlist?a.classlist.add(i):a.setAttribute("class",i);var n=a.style;n.width="100%",n.display="block",n.border=0,n.height=0,n.margin=0,n.position="absolute",n.left=0,n.right=0,n.top=0,n.bottom=0,t.insertBefore(a,t.firstChild),(a.contentWindow||a).onresize=function(){e&&e()}},o.removeResizeListener=function(t){var e=t.querySelector(".chartjs-hidden-iframe");e&&e.parentNode.removeChild(e)},o.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},o.arrayEquals=function(t,e){var a,i,n,r;if(!t||!e||t.length!=e.length)return!1;for(a=0,i=t.length;i>a;++a)if(n=t[a],r=e[a],n instanceof Array&&r instanceof Array){if(!o.arrayEquals(n,r))return!1}else if(n!=r)return!1;return!0},o.callCallback=function(t,e,a){t&&"function"==typeof t.call&&t.apply(a,e)},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{3:3}],27:[function(t,e,a){"use strict";e.exports=function(){var t=function(e,a){var i=this,n=t.helpers;return i.config=a||{data:{datasets:[]}},e.length&&e[0].getContext&&(e=e[0]),e.getContext&&(e=e.getContext("2d")),i.ctx=e,i.canvas=e.canvas,e.canvas.style.display=e.canvas.style.display||"block",i.width=e.canvas.width||parseInt(n.getStyle(e.canvas,"width"),10)||n.getMaximumWidth(e.canvas),i.height=e.canvas.height||parseInt(n.getStyle(e.canvas,"height"),10)||n.getMaximumHeight(e.canvas),i.aspectRatio=i.width/i.height,(isNaN(i.aspectRatio)||isFinite(i.aspectRatio)===!1)&&(i.aspectRatio=void 0!==a.aspectRatio?a.aspectRatio:2),i.originalCanvasStyleWidth=e.canvas.style.width,i.originalCanvasStyleHeight=e.canvas.style.height,n.retinaScale(i),i.controller=new t.Controller(i),n.addResizeListener(e.canvas.parentNode,function(){i.controller&&i.controller.config.options.responsive&&i.controller.resize()}),i.controller?i.controller:i};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"single",animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var a=0;a<t.data.datasets.length;a++)e.push('<li><span style="background-color:'+t.data.datasets[a].backgroundColor+'"></span>'),t.data.datasets[a].label&&e.push(t.data.datasets[a].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],28:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,a,i){function n(t){var e,a=t.isHorizontal();a?(e=t.update(t.options.fullWidth?p:k,y),S-=e.height):(e=t.update(x,v),k-=e.width),w.push({horizontal:a,minSize:e,box:t})}function o(t){var a=e.findNextWhere(w,function(e){return e.box===t});if(a)if(t.isHorizontal()){var i={left:C,right:M,top:0,bottom:0};t.update(t.options.fullWidth?p:k,m/2,i)}else t.update(a.minSize.width,S)}function r(t){var a=e.findNextWhere(w,function(e){return e.box===t}),i={left:0,right:0,top:D,bottom:A};a&&t.update(a.minSize.width,S,i)}function l(t){t.isHorizontal()?(t.left=t.options.fullWidth?s:C,t.right=t.options.fullWidth?a-s:C+k,t.top=P,t.bottom=P+t.height,P=t.bottom):(t.left=F,t.right=F+t.width,t.top=D,t.bottom=D+S,F=t.right)}if(t){var s=0,d=0,u=e.where(t.boxes,function(t){return"left"===t.options.position}),c=e.where(t.boxes,function(t){return"right"===t.options.position}),h=e.where(t.boxes,function(t){return"top"===t.options.position}),f=e.where(t.boxes,function(t){return"bottom"===t.options.position}),g=e.where(t.boxes,function(t){return"chartArea"===t.options.position});h.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),f.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var p=a-2*s,m=i-2*d,b=p/2,v=m/2,x=(a-b)/(u.length+c.length),y=(i-v)/(h.length+f.length),k=p,S=m,w=[];e.each(u.concat(c,h,f),n);var C=s,M=s,D=d,A=d;e.each(u.concat(c),o),e.each(u,function(t){C+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h.concat(f),o),e.each(h,function(t){D+=t.height}),e.each(f,function(t){A+=t.height}),e.each(u.concat(c),r),C=s,M=s,D=d,A=d,e.each(u,function(t){C+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h,function(t){D+=t.height}),e.each(f,function(t){A+=t.height});var I=i-D-A,T=a-C-M;(T!==k||I!==S)&&(e.each(u,function(t){t.height=I}),e.each(c,function(t){t.height=I}),e.each(h,function(t){t.options.fullWidth||(t.width=T)}),e.each(f,function(t){t.options.fullWidth||(t.width=T)}),S=I,k=T);var F=s,P=d;e.each(u.concat(h),l),F+=k,P+=S,e.each(c,l),e.each(f,l),t.chartArea={left:C,top:D,right:C+k,bottom:D+S},e.each(g,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(k,S)})}}}}},{}],29:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var a=e.datasetIndex,i=this.chart,n=i.getDatasetMeta(a);n.hidden=null===n.hidden?!i.data.datasets[a].hidden:null,i.update()},labels:{boxWidth:40,padding:10,generateLabels:function(t){var a=t.data;return e.isArray(a.datasets)?a.datasets.map(function(a,i){return{text:a.label,fillStyle:e.isArray(a.backgroundColor)?a.backgroundColor[0]:a.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,datasetIndex:i}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){e.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:a,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:a,beforeSetDimensions:a,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:a,beforeBuildLabels:a,buildLabels:function(){var t=this;t.legendItems=t.options.labels.generateLabels.call(t,t.chart),t.options.reverse&&t.legendItems.reverse()},afterBuildLabels:a,beforeFit:a,fit:function(){var a=this,i=a.options,n=i.labels,o=i.display,r=a.ctx,l=t.defaults.global,s=e.getValueOrDefault,d=s(n.fontSize,l.defaultFontSize),u=s(n.fontStyle,l.defaultFontStyle),c=s(n.fontFamily,l.defaultFontFamily),h=e.fontString(d,u,c),f=a.legendHitBoxes=[],g=a.minSize,p=a.isHorizontal();if(p?(g.width=a.maxWidth,g.height=o?10:0):(g.width=o?10:0,g.height=a.maxHeight),o)if(r.font=h,p){var m=a.lineWidths=[0],b=a.legendItems.length?d+n.padding:0;r.textAlign="left",r.textBaseline="top",e.each(a.legendItems,function(t,e){var i=n.usePointStyle?d*Math.sqrt(2):n.boxWidth,o=i+d/2+r.measureText(t.text).width;m[m.length-1]+o+n.padding>=a.width&&(b+=d+n.padding,m[m.length]=a.left),f[e]={left:0,top:0,width:o,height:d},m[m.length-1]+=o+n.padding}),g.height+=b}else{var v=n.padding,x=a.columnWidths=[],y=n.padding,k=0,S=0,w=d+v;e.each(a.legendItems,function(t,e){var a=n.usePointStyle?2*n.boxWidth:n.boxWidth,i=a+d/2+r.measureText(t.text).width;S+w>g.height&&(y+=k+n.padding,x.push(k),k=0,S=0),k=Math.max(k,i),S+=w,f[e]={left:0,top:0,width:i,height:d}}),y+=k,x.push(k),g.width+=y}a.width=g.width,a.height=g.height},afterFit:a,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var a=this,i=a.options,n=i.labels,o=t.defaults.global,r=o.elements.line,l=a.width,s=a.lineWidths;if(i.display){var d,u=a.ctx,c=e.getValueOrDefault,h=c(n.fontColor,o.defaultFontColor),f=c(n.fontSize,o.defaultFontSize),g=c(n.fontStyle,o.defaultFontStyle),p=c(n.fontFamily,o.defaultFontFamily),m=e.fontString(f,g,p);u.textAlign="left",u.textBaseline="top",u.lineWidth=.5,u.strokeStyle=h,u.fillStyle=h,u.font=m;var b=n.boxWidth,v=a.legendHitBoxes,x=function(e,a,n){if(!(isNaN(b)||0>=b)){if(u.save(),u.fillStyle=c(n.fillStyle,o.defaultColor),u.lineCap=c(n.lineCap,r.borderCapStyle),u.lineDashOffset=c(n.lineDashOffset,r.borderDashOffset),u.lineJoin=c(n.lineJoin,r.borderJoinStyle),u.lineWidth=c(n.lineWidth,r.borderWidth),u.strokeStyle=c(n.strokeStyle,o.defaultColor),u.setLineDash&&u.setLineDash(c(n.lineDash,r.borderDash)),i.labels&&i.labels.usePointStyle){var l=f*Math.SQRT2/2,s=l/Math.SQRT2,d=e+s,h=a+s;t.canvasHelpers.drawPoint(u,n.pointStyle,l,d,h)}else u.strokeRect(e,a,b,f),u.fillRect(e,a,b,f);u.restore()}},y=function(t,e,a,i){u.fillText(a.text,b+f/2+t,e),a.hidden&&(u.beginPath(),u.lineWidth=2,u.moveTo(b+f/2+t,e+f/2),u.lineTo(b+f/2+t+i,e+f/2),u.stroke())},k=a.isHorizontal();d=k?{x:a.left+(l-s[0])/2,y:a.top+n.padding,line:0}:{x:a.left+n.padding,y:a.top+n.padding,line:0};var S=f+n.padding;e.each(a.legendItems,function(t,e){var i=u.measureText(t.text).width,o=n.usePointStyle?f+f/2+i:b+f/2+i,r=d.x,c=d.y;k?r+o>=l&&(c=d.y+=S,d.line++,r=d.x=a.left+(l-s[d.line])/2):c+S>a.bottom&&(r=d.x=r+a.columnWidths[d.line]+n.padding,c=d.y=a.top,d.line++),x(r,c,t),v[e].left=r,v[e].top=c,y(r,c,t,i),k?d.x+=o+n.padding:d.y+=S})}},handleEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart.chart),n=i.x,o=i.y,r=a.options;if(n>=a.left&&n<=a.right&&o>=a.top&&o<=a.bottom)for(var l=a.legendHitBoxes,s=0;s<l.length;++s){var d=l[s];if(n>=d.left&&n<=d.left+d.width&&o>=d.top&&o<=d.top+d.height){r.onClick&&r.onClick.call(a,t,a.legendItems[s]);break}}}}),t.plugins.register({beforeInit:function(e){var a=e.options,i=a.legend;i&&(e.legend=new t.Legend({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.legend))}})}},{}],30:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers.noop;t.plugins={_plugins:[],register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)})},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var a=e.indexOf(t);-1!==a&&e.splice(a,1)})},clear:function(){this._plugins=[]},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e){var a,i,n=this._plugins,o=n.length;for(a=0;o>a;++a)if(i=n[a],"function"==typeof i[t]&&i[t].apply(i,e||[])===!1)return!1;return!0}},t.PluginBase=t.Element.extend({beforeInit:e,afterInit:e,beforeUpdate:e,afterUpdate:e,beforeDraw:e,afterDraw:e,destroy:e}),t.pluginService=t.plugins}},{}],31:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:10,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:function(t){return e.isArray(t)?t:""+t}}},t.Scale=t.Element.extend({beforeUpdate:function(){e.callCallback(this.options.beforeUpdate,[this])},update:function(t,a,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=a,n.margins=e.extend({left:0,right:0,top:0,bottom:0},i),n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeDataLimits(),n.determineDataLimits(),n.afterDataLimits(),n.beforeBuildTicks(),n.buildTicks(),n.afterBuildTicks(),n.beforeTickToLabelConversion(),n.convertTicksToLabels(),n.afterTickToLabelConversion(),n.beforeCalculateTickRotation(),n.calculateTickRotation(),n.afterCalculateTickRotation(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:function(){e.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){e.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){e.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){e.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:e.noop,afterDataLimits:function(){e.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){e.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:e.noop,afterBuildTicks:function(){e.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){e.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this;t.ticks=t.ticks.map(function(e,a,i){return t.options.ticks.userCallback?t.options.ticks.userCallback(e,a,i):t.options.ticks.callback(e,a,i)},t)},afterTickToLabelConversion:function(){e.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){e.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var a=this,i=a.ctx,n=t.defaults.global,o=a.options.ticks,r=e.getValueOrDefault(o.fontSize,n.defaultFontSize),l=e.getValueOrDefault(o.fontStyle,n.defaultFontStyle),s=e.getValueOrDefault(o.fontFamily,n.defaultFontFamily),d=e.fontString(r,l,s);i.font=d;var u,c=i.measureText(a.ticks[0]).width,h=i.measureText(a.ticks[a.ticks.length-1]).width;if(a.labelRotation=o.minRotation||0,a.paddingRight=0,a.paddingLeft=0,a.options.display&&a.isHorizontal()){a.paddingRight=h/2+3,a.paddingLeft=c/2+3,a.longestTextCache||(a.longestTextCache={});for(var f,g,p=e.longestText(i,d,a.ticks,a.longestTextCache),m=p,b=a.getPixelForTick(1)-a.getPixelForTick(0)-6;m>b&&a.labelRotation<o.maxRotation;){if(f=Math.cos(e.toRadians(a.labelRotation)),g=Math.sin(e.toRadians(a.labelRotation)),u=f*c,u+r/2>a.yLabelWidth&&(a.paddingLeft=u+r/2),a.paddingRight=r/2,g*p>a.maxHeight){a.labelRotation--;break}a.labelRotation++,m=f*p}}a.margins&&(a.paddingLeft=Math.max(a.paddingLeft-a.margins.left,0),a.paddingRight=Math.max(a.paddingRight-a.margins.right,0))},afterCalculateTickRotation:function(){e.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){e.callCallback(this.options.beforeFit,[this]);
-},fit:function(){var a=this,i=a.minSize={width:0,height:0},n=a.options,o=t.defaults.global,r=n.ticks,l=n.scaleLabel,s=n.display,d=a.isHorizontal(),u=e.getValueOrDefault(r.fontSize,o.defaultFontSize),c=e.getValueOrDefault(r.fontStyle,o.defaultFontStyle),h=e.getValueOrDefault(r.fontFamily,o.defaultFontFamily),f=e.fontString(u,c,h),g=e.getValueOrDefault(l.fontSize,o.defaultFontSize),p=n.gridLines.tickMarkLength;if(d?i.width=a.isFullWidth()?a.maxWidth-a.margins.left-a.margins.right:a.maxWidth:i.width=s?p:0,d?i.height=s?p:0:i.height=a.maxHeight,l.display&&s&&(d?i.height+=1.5*g:i.width+=1.5*g),r.display&&s){a.longestTextCache||(a.longestTextCache={});var m=e.longestText(a.ctx,f,a.ticks,a.longestTextCache),b=e.numberOfLabelLines(a.ticks),v=.5*u;if(d){a.longestLabelWidth=m;var x=Math.sin(e.toRadians(a.labelRotation))*a.longestLabelWidth+u*b+v*b;i.height=Math.min(a.maxHeight,i.height+x),a.ctx.font=f;var y=a.ctx.measureText(a.ticks[0]).width,k=a.ctx.measureText(a.ticks[a.ticks.length-1]).width,S=Math.cos(e.toRadians(a.labelRotation)),w=Math.sin(e.toRadians(a.labelRotation));a.paddingLeft=0!==a.labelRotation?S*y+3:y/2+3,a.paddingRight=0!==a.labelRotation?w*(u/2)+3:k/2+3}else{var C=a.maxWidth-i.width,M=r.mirror;M?m=0:m+=a.options.ticks.padding,C>m?i.width+=m:i.width=a.maxWidth,a.paddingTop=u/2,a.paddingBottom=u/2}}a.margins&&(a.paddingLeft=Math.max(a.paddingLeft-a.margins.left,0),a.paddingTop=Math.max(a.paddingTop-a.margins.top,0),a.paddingRight=Math.max(a.paddingRight-a.margins.right,0),a.paddingBottom=Math.max(a.paddingBottom-a.margins.bottom,0)),a.width=i.width,a.height=i.height},afterFit:function(){e.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"==typeof t&&isNaN(t)?NaN:"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t},getLabelForIndex:e.noop,getPixelForValue:e.noop,getValueForPixel:e.noop,getPixelForTick:function(t,e){var a=this;if(a.isHorizontal()){var i=a.width-(a.paddingLeft+a.paddingRight),n=i/Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),o=n*t+a.paddingLeft;e&&(o+=n/2);var r=a.left+Math.round(o);return r+=a.isFullWidth()?a.margins.left:0}var l=a.height-(a.paddingTop+a.paddingBottom);return a.top+t*(l/(a.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var a=e.width-(e.paddingLeft+e.paddingRight),i=a*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){var t=this,e=t.min,a=t.max;return t.getPixelForValue(t.beginAtZero?0:0>e&&0>a?a:e>0&&a>0?e:0)},draw:function(a){var i=this,n=i.options;if(n.display){var o,r,l=i.ctx,s=t.defaults.global,d=n.ticks,u=n.gridLines,c=n.scaleLabel,h=0!==i.labelRotation,f=d.autoSkip,g=i.isHorizontal();d.maxTicksLimit&&(r=d.maxTicksLimit);var p=e.getValueOrDefault(d.fontColor,s.defaultFontColor),m=e.getValueOrDefault(d.fontSize,s.defaultFontSize),b=e.getValueOrDefault(d.fontStyle,s.defaultFontStyle),v=e.getValueOrDefault(d.fontFamily,s.defaultFontFamily),x=e.fontString(m,b,v),y=u.tickMarkLength,k=e.getValueOrDefault(c.fontColor,s.defaultFontColor),S=e.getValueOrDefault(c.fontSize,s.defaultFontSize),w=e.getValueOrDefault(c.fontStyle,s.defaultFontStyle),C=e.getValueOrDefault(c.fontFamily,s.defaultFontFamily),M=e.fontString(S,w,C),D=e.toRadians(i.labelRotation),A=Math.cos(D),I=i.longestLabelWidth*A;l.fillStyle=p;var T=[];if(g){if(o=!1,h&&(I/=2),(I+d.autoSkipPadding)*i.ticks.length>i.width-(i.paddingLeft+i.paddingRight)&&(o=1+Math.floor((I+d.autoSkipPadding)*i.ticks.length/(i.width-(i.paddingLeft+i.paddingRight)))),r&&i.ticks.length>r)for(;!o||i.ticks.length/(o||1)>r;)o||(o=1),o+=1;f||(o=!1)}var F="right"===n.position?i.left:i.right-y,P="right"===n.position?i.left+y:i.right,R="bottom"===n.position?i.top:i.bottom-y,_="bottom"===n.position?i.top+y:i.bottom;if(e.each(i.ticks,function(t,r){if(void 0!==t&&null!==t){var l=i.ticks.length===r+1,s=o>1&&r%o>0||r%o===0&&r+o>=i.ticks.length;if((!s||l)&&void 0!==t&&null!==t){var c,f;r===("undefined"!=typeof i.zeroLineIndex?i.zeroLineIndex:0)?(c=u.zeroLineWidth,f=u.zeroLineColor):(c=e.getValueAtIndexOrDefault(u.lineWidth,r),f=e.getValueAtIndexOrDefault(u.color,r));var p,m,b,v,x,k,S,w,C,M,A,I="middle";if(g){h||(I="top"===n.position?"bottom":"top"),A=h?"right":"center";var V=i.getPixelForTick(r)+e.aliasPixel(c);C=i.getPixelForTick(r,u.offsetGridLines)+d.labelOffset,M=h?i.top+12:"top"===n.position?i.bottom-y:i.top+y,p=b=x=S=V,m=R,v=_,k=a.top,w=a.bottom}else{"left"===n.position?d.mirror?(C=i.right+d.padding,A="left"):(C=i.right-d.padding,A="right"):d.mirror?(C=i.left-d.padding,A="right"):(C=i.left+d.padding,A="left");var L=i.getPixelForTick(r);L+=e.aliasPixel(c),M=i.getPixelForTick(r,u.offsetGridLines),p=F,b=P,x=a.left,S=a.right,m=v=k=w=L}T.push({tx1:p,ty1:m,tx2:b,ty2:v,x1:x,y1:k,x2:S,y2:w,labelX:C,labelY:M,glWidth:c,glColor:f,rotation:-1*D,label:t,textBaseline:I,textAlign:A})}}}),e.each(T,function(t){if(u.display&&(l.lineWidth=t.glWidth,l.strokeStyle=t.glColor,l.beginPath(),u.drawTicks&&(l.moveTo(t.tx1,t.ty1),l.lineTo(t.tx2,t.ty2)),u.drawOnChartArea&&(l.moveTo(t.x1,t.y1),l.lineTo(t.x2,t.y2)),l.stroke()),d.display){l.save(),l.translate(t.labelX,t.labelY),l.rotate(t.rotation),l.font=x,l.textBaseline=t.textBaseline,l.textAlign=t.textAlign;var a=t.label;if(e.isArray(a))for(var i=0,n=0;i<a.length;++i)l.fillText(""+a[i],0,n),n+=1.5*m;else l.fillText(a,0,0);l.restore()}}),c.display){var V,L,O=0;if(g)V=i.left+(i.right-i.left)/2,L="bottom"===n.position?i.bottom-S/2:i.top+S/2;else{var B="left"===n.position;V=B?i.left+S/2:i.right-S/2,L=i.top+(i.bottom-i.top)/2,O=B?-.5*Math.PI:.5*Math.PI}l.save(),l.translate(V,L),l.rotate(O),l.textAlign="center",l.textBaseline="middle",l.fillStyle=k,l.font=M,l.fillText(c.labelString,0,0),l.restore()}if(u.drawBorder){l.lineWidth=e.getValueAtIndexOrDefault(u.lineWidth,0),l.strokeStyle=e.getValueAtIndexOrDefault(u.color,0);var W=i.left,z=i.right,N=i.top,H=i.bottom,E=e.aliasPixel(l.lineWidth);g?(N=H="top"===n.position?i.bottom:i.top,N+=E,H+=E):(W=z="left"===n.position?i.right:i.left,W+=E,z+=E),l.beginPath(),l.moveTo(W,N),l.lineTo(z,H),l.stroke()}}}})}},{}],32:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,a,i){this.constructors[t]=a,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(a){return this.defaults.hasOwnProperty(a)?e.scaleMerge(t.defaults.scale,this.defaults[a]):{}},updateScaleDefaults:function(t,a){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],a))},addScalesToLayout:function(a){e.each(a.scales,function(e){t.layoutService.addBox(a,e)})}}}},{}],33:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var a=e.noop;t.Title=t.Element.extend({initialize:function(a){var i=this;e.extend(i,a),i.options=e.configMerge(t.defaults.global.title,a.options),i.legendHitBoxes=[]},beforeUpdate:function(){var a=this.chart.options;a&&a.title&&(this.options=e.configMerge(t.defaults.global.title,a.title))},update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:a,beforeSetDimensions:a,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:a,beforeBuildLabels:a,buildLabels:a,afterBuildLabels:a,beforeFit:a,fit:function(){var a=this,i=e.getValueOrDefault,n=a.options,o=t.defaults.global,r=n.display,l=i(n.fontSize,o.defaultFontSize),s=a.minSize;a.isHorizontal()?(s.width=a.maxWidth,s.height=r?l+2*n.padding:0):(s.width=r?l+2*n.padding:0,s.height=a.maxHeight),a.width=s.width,a.height=s.height},afterFit:a,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var a=this,i=a.ctx,n=e.getValueOrDefault,o=a.options,r=t.defaults.global;if(o.display){var l,s,d=n(o.fontSize,r.defaultFontSize),u=n(o.fontStyle,r.defaultFontStyle),c=n(o.fontFamily,r.defaultFontFamily),h=e.fontString(d,u,c),f=0,g=a.top,p=a.left,m=a.bottom,b=a.right;i.fillStyle=n(o.fontColor,r.defaultFontColor),i.font=h,a.isHorizontal()?(l=p+(b-p)/2,s=g+(m-g)/2):(l="left"===o.position?p+d/2:b-d/2,s=g+(m-g)/2,f=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(l,s),i.rotate(f),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0),i.restore()}}}),t.plugins.register({beforeInit:function(e){var a=e.options,i=a.title;i&&(e.titleBlock=new t.Title({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.titleBlock))}})}},{}],34:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return e&&(n.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function a(t){if(!t.length)return!1;var e,a,i=[],n=[];for(e=0,a=t.length;a>e;++e){var o=t[e];if(o&&o.hasValue()){var r=o.tooltipPosition();i.push(r.x),n.push(r.y)}}var l=0,s=0;for(e=0;e<i.length;++e)i[e]&&(l+=i[e],s+=n[e]);return{x:Math.round(l/i.length),y:Math.round(s/i.length)}}function i(t){var e=t._xScale,a=t._yScale||t._scale,i=t._index,n=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,n):"",yLabel:a?a.getLabelForIndex(i,n):"",index:i,datasetIndex:n}}var n=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"single",backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,yAlign:"center",xAlign:"center",caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",callbacks:{beforeTitle:n.noop,title:function(t,e){var a="",i=e.labels,n=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?a=o.xLabel:n>0&&o.index<n&&(a=i[o.index])}return a},afterTitle:n.noop,beforeBody:n.noop,beforeLabel:n.noop,label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.yLabel},labelColor:function(t,e){var a=e.getDatasetMeta(t.datasetIndex),i=a.data[t.index],n=i._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},afterLabel:n.noop,afterBody:n.noop,beforeFooter:n.noop,footer:n.noop,afterFooter:n.noop}},t.Tooltip=t.Element.extend({initialize:function(){var e=this,a=t.defaults.global,i=e._options,o=n.getValueOrDefault;n.extend(e,{_model:{xPadding:i.xPadding,yPadding:i.yPadding,xAlign:i.xAlign,yAlign:i.yAlign,bodyFontColor:i.bodyFontColor,_bodyFontFamily:o(i.bodyFontFamily,a.defaultFontFamily),_bodyFontStyle:o(i.bodyFontStyle,a.defaultFontStyle),_bodyAlign:i.bodyAlign,bodyFontSize:o(i.bodyFontSize,a.defaultFontSize),bodySpacing:i.bodySpacing,titleFontColor:i.titleFontColor,_titleFontFamily:o(i.titleFontFamily,a.defaultFontFamily),_titleFontStyle:o(i.titleFontStyle,a.defaultFontStyle),titleFontSize:o(i.titleFontSize,a.defaultFontSize),_titleAlign:i.titleAlign,titleSpacing:i.titleSpacing,titleMarginBottom:i.titleMarginBottom,footerFontColor:i.footerFontColor,_footerFontFamily:o(i.footerFontFamily,a.defaultFontFamily),_footerFontStyle:o(i.footerFontStyle,a.defaultFontStyle),footerFontSize:o(i.footerFontSize,a.defaultFontSize),_footerAlign:i.footerAlign,footerSpacing:i.footerSpacing,footerMarginTop:i.footerMarginTop,caretSize:i.caretSize,cornerRadius:i.cornerRadius,backgroundColor:i.backgroundColor,opacity:0,legendColorBackground:i.multiKeyBackground}})},getTitle:function(){var t=this,a=t._options,i=a.callbacks,n=i.beforeTitle.apply(t,arguments),o=i.title.apply(t,arguments),r=i.afterTitle.apply(t,arguments),l=[];return l=e(l,n),l=e(l,o),l=e(l,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return n.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,a){var i=this,o=i._options.callbacks,r=[];return n.each(t,function(t){var n={before:[],lines:[],after:[]};e(n.before,o.beforeLabel.call(i,t,a)),e(n.lines,o.label.call(i,t,a)),e(n.after,o.afterLabel.call(i,t,a)),r.push(n)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return n.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,a=t._options.callbacks,i=a.beforeFooter.apply(t,arguments),n=a.footer.apply(t,arguments),o=a.afterFooter.apply(t,arguments),r=[];return r=e(r,i),r=e(r,n),r=e(r,o)},update:function(t){var e,o,r=this,l=r._options,s=r._model,d=r._active,u=r._data,c=r._chartInstance;if(d.length){s.opacity=1;var h=[],f=a(d),g=[];for(e=0,o=d.length;o>e;++e)g.push(i(d[e]));l.itemSort&&(g=g.sort(l.itemSort)),d.length>1&&n.each(g,function(t){h.push(l.callbacks.labelColor.call(r,t,c))}),n.extend(s,{title:r.getTitle(g,u),beforeBody:r.getBeforeBody(g,u),body:r.getBody(g,u),afterBody:r.getAfterBody(g,u),footer:r.getFooter(g,u),x:Math.round(f.x),y:Math.round(f.y),caretPadding:n.getValueOrDefault(f.padding,2),labelColors:h});var p=r.getTooltipSize(s);r.determineAlignment(p),n.extend(s,r.getBackgroundPoint(s,p))}else r._model.opacity=0;return t&&l.custom&&l.custom.call(r,s),r},getTooltipSize:function(t){var e=this._chart.ctx,a={height:2*t.yPadding,width:0},i=t.body,o=i.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);o+=t.beforeBody.length+t.afterBody.length;var r=t.title.length,l=t.footer.length,s=t.titleFontSize,d=t.bodyFontSize,u=t.footerFontSize;a.height+=r*s,a.height+=(r-1)*t.titleSpacing,a.height+=r?t.titleMarginBottom:0,a.height+=o*d,a.height+=o?(o-1)*t.bodySpacing:0,a.height+=l?t.footerMarginTop:0,a.height+=l*u,a.height+=l?(l-1)*t.footerSpacing:0;var c=0,h=function(t){a.width=Math.max(a.width,e.measureText(t).width+c)};return e.font=n.fontString(s,t._titleFontStyle,t._titleFontFamily),n.each(t.title,h),e.font=n.fontString(d,t._bodyFontStyle,t._bodyFontFamily),n.each(t.beforeBody.concat(t.afterBody),h),c=i.length>1?d+2:0,n.each(i,function(t){n.each(t.before,h),n.each(t.lines,h),n.each(t.after,h)}),c=0,e.font=n.fontString(u,t._footerFontStyle,t._footerFontFamily),n.each(t.footer,h),a.width+=2*t.xPadding,a},determineAlignment:function(t){var e=this,a=e._model,i=e._chart,n=e._chartInstance.chartArea;a.y<t.height?a.yAlign="top":a.y>i.height-t.height&&(a.yAlign="bottom");var o,r,l,s,d,u=(n.left+n.right)/2,c=(n.top+n.bottom)/2;"center"===a.yAlign?(o=function(t){return u>=t},r=function(t){return t>u}):(o=function(e){return e<=t.width/2},r=function(e){return e>=i.width-t.width/2}),l=function(e){return e+t.width>i.width},s=function(e){return e-t.width<0},d=function(t){return c>=t?"top":"bottom"},o(a.x)?(a.xAlign="left",l(a.x)&&(a.xAlign="center",a.yAlign=d(a.y))):r(a.x)&&(a.xAlign="right",s(a.x)&&(a.xAlign="center",a.yAlign=d(a.y)))},getBackgroundPoint:function(t,e){var a={x:t.x,y:t.y},i=t.caretSize,n=t.caretPadding,o=t.cornerRadius,r=t.xAlign,l=t.yAlign,s=i+n,d=o+n;return"right"===r?a.x-=e.width:"center"===r&&(a.x-=e.width/2),"top"===l?a.y+=s:"bottom"===l?a.y-=e.height+s:a.y-=e.height/2,"center"===l?"left"===r?a.x+=s:"right"===r&&(a.x-=s):"left"===r?a.x-=d:"right"===r&&(a.x+=d),a},drawCaret:function(t,e,a){var i,o,r,l,s,d,u=this._view,c=this._chart.ctx,h=u.caretSize,f=u.cornerRadius,g=u.xAlign,p=u.yAlign,m=t.x,b=t.y,v=e.width,x=e.height;"center"===p?("left"===g?(i=m,o=i-h,r=i):(i=m+v,o=i+h,r=i),s=b+x/2,l=s-h,d=s+h):("left"===g?(i=m+f,o=i+h,r=o+h):"right"===g?(i=m+v-f,o=i-h,r=o-h):(o=m+v/2,i=o-h,r=o+h),"top"===p?(l=b,s=l-h,d=l):(l=b+x,s=l+h,d=l));var y=n.color(u.backgroundColor);c.fillStyle=y.alpha(a*y.alpha()).rgbString(),c.beginPath(),c.moveTo(i,l),c.lineTo(o,s),c.lineTo(r,d),c.closePath(),c.fill()},drawTitle:function(t,e,a,i){var o=e.title;if(o.length){a.textAlign=e._titleAlign,a.textBaseline="top";var r=e.titleFontSize,l=e.titleSpacing,s=n.color(e.titleFontColor);a.fillStyle=s.alpha(i*s.alpha()).rgbString(),a.font=n.fontString(r,e._titleFontStyle,e._titleFontFamily);var d,u;for(d=0,u=o.length;u>d;++d)a.fillText(o[d],t.x,t.y),t.y+=r+l,d+1===o.length&&(t.y+=e.titleMarginBottom-l)}},drawBody:function(t,e,a,i){var o=e.bodyFontSize,r=e.bodySpacing,l=e.body;a.textAlign=e._bodyAlign,a.textBaseline="top";var s=n.color(e.bodyFontColor),d=s.alpha(i*s.alpha()).rgbString();a.fillStyle=d,a.font=n.fontString(o,e._bodyFontStyle,e._bodyFontFamily);var u=0,c=function(e){a.fillText(e,t.x+u,t.y),t.y+=o+r};n.each(e.beforeBody,c);var h=l.length>1;u=h?o+2:0,n.each(l,function(r,l){n.each(r.before,c),n.each(r.lines,function(r){h&&(a.fillStyle=n.color(e.legendColorBackground).alpha(i).rgbaString(),a.fillRect(t.x,t.y,o,o),a.strokeStyle=n.color(e.labelColors[l].borderColor).alpha(i).rgbaString(),a.strokeRect(t.x,t.y,o,o),a.fillStyle=n.color(e.labelColors[l].backgroundColor).alpha(i).rgbaString(),a.fillRect(t.x+1,t.y+1,o-2,o-2),a.fillStyle=d),c(r)}),n.each(r.after,c)}),u=0,n.each(e.afterBody,c),t.y-=r},drawFooter:function(t,e,a,i){var o=e.footer;if(o.length){t.y+=e.footerMarginTop,a.textAlign=e._footerAlign,a.textBaseline="top";var r=n.color(e.footerFontColor);a.fillStyle=r.alpha(i*r.alpha()).rgbString(),a.font=n.fontString(e.footerFontSize,e._footerFontStyle,e._footerFontFamily),n.each(o,function(i){a.fillText(i,t.x,t.y),t.y+=e.footerFontSize+e.footerSpacing})}},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var a=this.getTooltipSize(e),i={x:e.x,y:e.y},o=Math.abs(e.opacity<.001)?0:e.opacity;if(this._options.enabled){var r=n.color(e.backgroundColor);t.fillStyle=r.alpha(o*r.alpha()).rgbString(),n.drawRoundedRectangle(t,i.x,i.y,a.width,a.height,e.cornerRadius),t.fill(),this.drawCaret(i,a,o),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,o),this.drawBody(i,e,t,o),this.drawFooter(i,e,t,o)}}}})}},{}],35:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;a.elements.arc={backgroundColor:a.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2):!1},inRange:function(t,a){var i=this._view;if(i){for(var n=e.getAngleFromPoint(i,{x:t,y:a}),o=n.angle,r=n.distance,l=i.startAngle,s=i.endAngle;l>s;)s+=2*Math.PI;for(;o>s;)o-=2*Math.PI;for(;l>o;)o+=2*Math.PI;var d=o>=l&&s>=o,u=r>=i.innerRadius&&r<=i.outerRadius;return d&&u}return!1},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,a=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},draw:function(){var t=this._chart.ctx,e=this._view,a=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,a,i),t.arc(e.x,e.y,e.innerRadius,i,a,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],36:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:a.defaultColor,borderWidth:3,borderColor:a.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){function t(t,e){var a=e._view;e._view.steppedLine===!0?(s.lineTo(e._view.x,t._view.y),s.lineTo(e._view.x,e._view.y)):0===e._view.tension?s.lineTo(a.x,a.y):s.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,a.controlPointPreviousX,a.controlPointPreviousY,a.x,a.y)}var i=this,n=i._view,o=n.spanGaps,r=n.scaleZero,l=i._loop,s=i._chart.ctx;s.save();var d=i._children.slice(),u=-1;l&&d.length&&d.push(d[0]);var c,h,f,g;if(d.length&&n.fill){for(s.beginPath(),c=0;c<d.length;++c)h=d[c],f=e.previousItem(d,c),g=h._view,0===c?(l?s.moveTo(r.x,r.y):s.moveTo(g.x,r),g.skip||(u=c,s.lineTo(g.x,g.y))):(f=-1===u?f:d[u],g.skip?o||u!==c-1||(l?s.lineTo(r.x,r.y):s.lineTo(f._view.x,r)):(u!==c-1?o&&-1!==u?t(f,h):l?s.lineTo(g.x,g.y):(s.lineTo(g.x,r),s.lineTo(g.x,g.y)):t(f,h),u=c));l||s.lineTo(d[u]._view.x,r),s.fillStyle=n.backgroundColor||a.defaultColor,s.closePath(),s.fill()}var p=a.elements.line;for(s.lineCap=n.borderCapStyle||p.borderCapStyle,s.setLineDash&&s.setLineDash(n.borderDash||p.borderDash),s.lineDashOffset=n.borderDashOffset||p.borderDashOffset,s.lineJoin=n.borderJoinStyle||p.borderJoinStyle,s.lineWidth=n.borderWidth||p.borderWidth,s.strokeStyle=n.borderColor||a.defaultColor,s.beginPath(),u=-1,c=0;c<d.length;++c)h=d[c],f=e.previousItem(d,c),g=h._view,0===c?g.skip||(s.moveTo(g.x,g.y),u=c):(f=-1===u?f:d[u],g.skip||(u!==c-1&&!o||-1===u?s.moveTo(g.x,g.y):t(f,h),u=c));s.stroke(),s.restore()}})}},{}],37:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global,i=a.defaultColor;a.elements.point={radius:3,pointStyle:"circle",backgroundColor:i,borderWidth:1,borderColor:i,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var a=this._view;return a?Math.pow(t-a.x,2)+Math.pow(e-a.y,2)<Math.pow(a.hitRadius+a.radius,2):!1},inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2):!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(){var n=this._view,o=this._chart.ctx,r=n.pointStyle,l=n.radius,s=n.x,d=n.y;n.skip||(o.strokeStyle=n.borderColor||i,o.lineWidth=e.getValueOrDefault(n.borderWidth,a.elements.point.borderWidth),o.fillStyle=n.backgroundColor||i,t.canvasHelpers.drawPoint(o,r,l,s,d))}})}},{}],38:[function(t,e,a){"use strict";e.exports=function(t){var e=t.defaults.global;e.elements.rectangle={backgroundColor:e.defaultColor,borderWidth:0,borderColor:e.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return s[(u+t)%4]}var e=this._chart.ctx,a=this._view,i=a.width/2,n=a.x-i,o=a.x+i,r=a.base-(a.base-a.y),l=a.borderWidth/2;a.borderWidth&&(n+=l,o-=l,r+=l),e.beginPath(),e.fillStyle=a.backgroundColor,e.strokeStyle=a.borderColor,e.lineWidth=a.borderWidth;var s=[[n,a.base],[n,r],[o,r],[o,a.base]],d=["bottom","left","top","right"],u=d.indexOf(a.borderSkipped,0);-1===u&&(u=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),a.borderWidth&&e.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var a=this._view;return a?a.y<a.base?t>=a.x-a.width/2&&t<=a.x+a.width/2&&e>=a.y&&e<=a.base:t>=a.x-a.width/2&&t<=a.x+a.width/2&&e>=a.base&&e<=a.y:!1},inLabelRange:function(t){var e=this._view;return e?t>=e.x-e.width/2&&t<=e.x+e.width/2:!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],39:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={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,a=t.getLabels();t.minIndex=0,t.maxIndex=a.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(a,t.options.ticks.min),t.minIndex=-1!==i?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(a,t.options.ticks.max),t.maxIndex=-1!==i?i:t.maxIndex),t.min=a[t.minIndex],t.max=a[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){return this.ticks[t]},getPixelForValue:function(t,e,a,i){var n=this,o=Math.max(n.maxIndex+1-n.minIndex-(n.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t){var r=n.getLabels(),l=r.indexOf(t);e=-1!==l?l:e}if(n.isHorizontal()){var s=n.width-(n.paddingLeft+n.paddingRight),d=s/o,u=d*(e-n.minIndex)+n.paddingLeft;return n.options.gridLines.offsetGridLines&&i&&(u+=d/2),n.left+Math.round(u)}var c=n.height-(n.paddingTop+n.paddingBottom),h=c/o,f=h*(e-n.minIndex)+n.paddingTop;return n.options.gridLines.offsetGridLines&&i&&(f+=h/2),n.top+Math.round(f)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,a=this,i=Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),n=a.isHorizontal(),o=n?a.width-(a.paddingLeft+a.paddingRight):a.height-(a.paddingTop+a.paddingBottom),r=o/i;return t-=n?a.left:a.top,a.options.gridLines.offsetGridLines&&(t-=r/2),t-=n?a.paddingLeft:a.paddingTop,e=0>=t?0:Math.round(t/r)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,a)}},{}],40:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:function(t,a,i){var n=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(n)>1&&t!==Math.floor(t)&&(n=t-Math.floor(t));var o=e.log10(Math.abs(n)),r="";if(0!==t){var l=-1*Math.floor(o);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r}}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return l?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=a.chart,o=n.data,r=o.datasets,l=a.isHorizontal();if(a.min=null,a.max=null,i.stacked){var s={},d=!1,u=!1;e.each(r,function(o,r){var l=n.getDatasetMeta(r);void 0===s[l.type]&&(s[l.type]={positiveValues:[],negativeValues:[]});var c=s[l.type].positiveValues,h=s[l.type].negativeValues;n.isDatasetVisible(r)&&t(l)&&e.each(o.data,function(t,e){var n=+a.getRightValue(t);isNaN(n)||l.data[e].hidden||(c[e]=c[e]||0,h[e]=h[e]||0,i.relativePoints?c[e]=100:0>n?(u=!0,h[e]+=n):(d=!0,c[e]+=n))})}),e.each(s,function(t){var i=t.positiveValues.concat(t.negativeValues),n=e.min(i),o=e.max(i);a.min=null===a.min?n:Math.min(a.min,n),a.max=null===a.max?o:Math.max(a.max,o)})}else e.each(r,function(i,o){var r=n.getDatasetMeta(o);n.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var a,i=this,n=i.options.ticks;if(i.isHorizontal())a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.width/50));else{var o=e.getValueOrDefault(n.fontSize,t.defaults.global.defaultFontSize);a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}return a},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,a,i=this,n=i.paddingLeft,o=i.paddingBottom,r=i.start,l=+i.getRightValue(t),s=i.end-r;return i.isHorizontal()?(a=i.width-(n+i.paddingRight),e=i.left+a/s*(l-r),Math.round(e+n)):(a=i.height-(i.paddingTop+o),e=i.bottom-o-a/s*(l-r),Math.round(e))},getValueForPixel:function(t){var e=this,a=e.isHorizontal(),i=e.paddingLeft,n=e.paddingBottom,o=a?e.width-(i+e.paddingRight):e.height-(e.paddingTop+n),r=(a?t-e.left-i:e.bottom-n-t)/o;return e.start+(e.end-e.start)*r},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,a)}},{}],41:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,a=t.options,i=a.ticks;if(i.beginAtZero){var n=e.sign(t.min),o=e.sign(t.max);0>n&&0>o?t.max=0:n>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:a,handleDirectionalChanges:a,buildTicks:function(){var t=this,a=t.options,i=t.ticks=[],n=a.ticks,o=e.getValueOrDefault,r=t.getTickLimit();r=Math.max(2,r);var l,s=n.fixedStepSize&&n.fixedStepSize>0||n.stepSize&&n.stepSize>0;if(s)l=o(n.fixedStepSize,n.stepSize);else{var d=e.niceNum(t.max-t.min,!1);l=e.niceNum(d/(r-1),!0)}var u=Math.floor(t.min/l)*l,c=Math.ceil(t.max/l)*l,h=(c-u)/l;h=e.almostEquals(h,Math.round(h),l/1e3)?Math.round(h):Math.ceil(h),i.push(void 0!==n.min?n.min:u);for(var f=1;h>f;++f)i.push(u+f*l);i.push(void 0!==n.max?n.max:c),t.handleDirectionalChanges(),t.max=e.max(i),t.min=e.min(i),n.reverse?(i.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],42:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:function(t,a,i){var n=t/Math.pow(10,Math.floor(e.log10(t)));return 1===n||2===n||5===n||0===a||a===i.length-1?t.toExponential():""}}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return d?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=i.ticks,o=a.chart,r=o.data,l=r.datasets,s=e.getValueOrDefault,d=a.isHorizontal();if(a.min=null,a.max=null,i.stacked){var u={};e.each(l,function(n,r){var l=o.getDatasetMeta(r);o.isDatasetVisible(r)&&t(l)&&(void 0===u[l.type]&&(u[l.type]=[]),e.each(n.data,function(t,e){var n=u[l.type],o=+a.getRightValue(t);isNaN(o)||l.data[e].hidden||(n[e]=n[e]||0,i.relativePoints?n[e]=100:n[e]+=o)}))}),e.each(u,function(t){var i=e.min(t),n=e.max(t);a.min=null===a.min?i:Math.min(a.min,i),a.max=null===a.max?n:Math.max(a.max,n)})}else e.each(l,function(i,n){var r=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i))})});a.min=s(n.min,a.min),a.max=s(n.max,a.max),a.min===a.max&&(0!==a.min&&null!==a.min?(a.min=Math.pow(10,Math.floor(e.log10(a.min))-1),a.max=Math.pow(10,Math.floor(e.log10(a.max))+1)):(a.min=1,a.max=10))},buildTicks:function(){for(var t=this,a=t.options,i=a.ticks,n=e.getValueOrDefault,o=t.ticks=[],r=n(i.min,Math.pow(10,Math.floor(e.log10(t.min))));r<t.max;){o.push(r);var l=Math.floor(e.log10(r)),s=Math.floor(r/Math.pow(10,l))+1;10===s&&(s=1,++l),r=s*Math.pow(10,l)}var d=n(i.max,r);o.push(d),t.isHorizontal()||o.reverse(),t.max=e.max(o),t.min=e.min(o),i.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var a,i,n=this,o=n.start,r=+n.getRightValue(t),l=e.log10(n.end)-e.log10(o),s=n.paddingTop,d=n.paddingBottom,u=n.paddingLeft;return n.isHorizontal()?0===r?i=n.left+u:(a=n.width-(u+n.paddingRight),i=n.left+a/l*(e.log10(r)-e.log10(o)),i+=u):0===r?i=n.top+s:(a=n.height-(s+d),i=n.bottom-d-a/l*(e.log10(r)-e.log10(o))),i},getValueForPixel:function(t){var a,i,n=this,o=e.log10(n.end)-e.log10(n.start);return n.isHorizontal()?(i=n.width-(n.paddingLeft+n.paddingRight),a=n.start*Math.pow(10,(t-n.left-n.paddingLeft)*o/i)):(i=n.height-(n.paddingTop+n.paddingBottom),a=Math.pow(10,(n.bottom-n.paddingBottom-t)*o/i)/n.start),a}});t.scaleService.registerScaleType("logarithmic",i,a)}},{}],43:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global,i={display:!0,animate:!0,lineArc:!1,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2},pointLabels:{fontSize:10,callback:function(t){return t}}},n=t.LinearScaleBase.extend({getValueCount:function(){return this.chart.data.labels.length;
-},setDimensions:function(){var t=this,i=t.options,n=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var o=e.min([t.height,t.width]),r=e.getValueOrDefault(n.fontSize,a.defaultFontSize);t.drawingArea=i.display?o/2-(r/2+n.backdropPaddingY):o/2},determineDataLimits:function(){var t=this,a=t.chart;t.min=null,t.max=null,e.each(a.data.datasets,function(i,n){if(a.isDatasetVisible(n)){var o=a.getDatasetMeta(n);e.each(i.data,function(e,a){var i=+t.getRightValue(e);isNaN(i)||o.data[a].hidden||(null===t.min?t.min=i:i<t.min&&(t.min=i),null===t.max?t.max=i:i>t.max&&(t.max=i))})}}),t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=e.getValueOrDefault(t.fontSize,a.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,i,n,o,r,l,s,d,u,c,h,f,g=this.options.pointLabels,p=e.getValueOrDefault(g.fontSize,a.defaultFontSize),m=e.getValueOrDefault(g.fontStyle,a.defaultFontStyle),b=e.getValueOrDefault(g.fontFamily,a.defaultFontFamily),v=e.fontString(p,m,b),x=e.min([this.height/2-p-5,this.width/2]),y=this.width,k=0;for(this.ctx.font=v,i=0;i<this.getValueCount();i++){t=this.getPointPosition(i,x),n=this.ctx.measureText(this.pointLabels[i]?this.pointLabels[i]:"").width+5;var S=this.getIndexAngle(i)+Math.PI/2,w=360*S/(2*Math.PI)%360;0===w||180===w?(o=n/2,t.x+o>y&&(y=t.x+o,r=i),t.x-o<k&&(k=t.x-o,s=i)):180>w?t.x+n>y&&(y=t.x+n,r=i):t.x-n<k&&(k=t.x-n,s=i)}u=k,c=Math.ceil(y-this.width),l=this.getIndexAngle(r),d=this.getIndexAngle(s),h=c/Math.sin(l+Math.PI/2),f=u/Math.sin(d+Math.PI/2),h=e.isNumber(h)?h:0,f=e.isNumber(f)?f:0,this.drawingArea=Math.round(x-(f+h)/2),this.setCenterPoint(f,h)},setCenterPoint:function(t,e){var a=this,i=a.width-e-a.drawingArea,n=t+a.drawingArea;a.xCenter=Math.round((n+i)/2+a.left),a.yCenter=Math.round(a.height/2+a.top)},getIndexAngle:function(t){var e=2*Math.PI/this.getValueCount(),a=this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0,i=a*Math.PI*2/360;return t*e-Math.PI/2+i},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var a=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*a:(t-e.min)*a},getPointPosition:function(t,e){var a=this,i=a.getIndexAngle(t);return{x:Math.round(Math.cos(i)*e)+a.xCenter,y:Math.round(Math.sin(i)*e)+a.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,a=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:0>e&&0>a?a:e>0&&a>0?e:0)},draw:function(){var t=this,i=t.options,n=i.gridLines,o=i.ticks,r=i.angleLines,l=i.pointLabels,s=e.getValueOrDefault;if(i.display){var d=t.ctx,u=s(o.fontSize,a.defaultFontSize),c=s(o.fontStyle,a.defaultFontStyle),h=s(o.fontFamily,a.defaultFontFamily),f=e.fontString(u,c,h);if(e.each(t.ticks,function(r,l){if(l>0||i.reverse){var c=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),h=t.yCenter-c;if(n.display&&0!==l)if(d.strokeStyle=e.getValueAtIndexOrDefault(n.color,l-1),d.lineWidth=e.getValueAtIndexOrDefault(n.lineWidth,l-1),i.lineArc)d.beginPath(),d.arc(t.xCenter,t.yCenter,c,0,2*Math.PI),d.closePath(),d.stroke();else{d.beginPath();for(var g=0;g<t.getValueCount();g++){var p=t.getPointPosition(g,c);0===g?d.moveTo(p.x,p.y):d.lineTo(p.x,p.y)}d.closePath(),d.stroke()}if(o.display){var m=s(o.fontColor,a.defaultFontColor);if(d.font=f,o.showLabelBackdrop){var b=d.measureText(r).width;d.fillStyle=o.backdropColor,d.fillRect(t.xCenter-b/2-o.backdropPaddingX,h-u/2-o.backdropPaddingY,b+2*o.backdropPaddingX,u+2*o.backdropPaddingY)}d.textAlign="center",d.textBaseline="middle",d.fillStyle=m,d.fillText(r,t.xCenter,h)}}}),!i.lineArc){d.lineWidth=r.lineWidth,d.strokeStyle=r.color;for(var g=t.getDistanceFromCenterForValue(i.reverse?t.min:t.max),p=s(l.fontSize,a.defaultFontSize),m=s(l.fontStyle,a.defaultFontStyle),b=s(l.fontFamily,a.defaultFontFamily),v=e.fontString(p,m,b),x=t.getValueCount()-1;x>=0;x--){if(r.display){var y=t.getPointPosition(x,g);d.beginPath(),d.moveTo(t.xCenter,t.yCenter),d.lineTo(y.x,y.y),d.stroke(),d.closePath()}var k=t.getPointPosition(x,g+5),S=s(l.fontColor,a.defaultFontColor);d.font=v,d.fillStyle=S;var w=t.pointLabels,C=this.getIndexAngle(x)+Math.PI/2,M=360*C/(2*Math.PI)%360;0===M||180===M?d.textAlign="center":180>M?d.textAlign="left":d.textAlign="right",90===M||270===M?d.textBaseline="middle":M>270||90>M?d.textBaseline="bottom":d.textBaseline="top",d.fillText(w[x]?w[x]:"",k.x,k.y)}}}}});t.scaleService.registerScaleType("radialLinear",n,i)}},{}],44:[function(t,e,a){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,a={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},n={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},o=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return"undefined"!=typeof this.labelMoments[t]?this.labelMoments[t][e]:null},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i))},t),t.firstTick=i.min.call(t,a),t.lastTick=i.max.call(t,a)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(n,o){var r=[],l=t.chart.isDatasetVisible(o);"object"==typeof n.data[0]&&null!==n.data[0]?e.each(n.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),r.push(a),l&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,a):a,t.lastTick=null!==t.lastTick?i.max(t.lastTick,a):a))},t):r=a,t.labelMoments.push(r)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildTicks:function(){var i=this;i.ctx.save();var n=e.getValueOrDefault(i.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=e.getValueOrDefault(i.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),r=e.getValueOrDefault(i.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),l=e.fontString(n,o,r);if(i.ctx.font=l,i.ticks=[],i.unitScale=1,i.scaleSizeInUnits=0,i.options.time.unit)i.tickUnit=i.options.time.unit||"day",i.displayFormat=i.options.time.displayFormats[i.tickUnit],i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,1);else{var s=i.isHorizontal()?i.width-(i.paddingLeft+i.paddingRight):i.height-(i.paddingTop+i.paddingBottom),d=i.tickFormatFunction(i.firstTick,0,[]),u=i.ctx.measureText(d).width,c=Math.cos(e.toRadians(i.options.ticks.maxRotation)),h=Math.sin(e.toRadians(i.options.ticks.maxRotation));u=u*c+n*h;var f=s/u;i.tickUnit="millisecond",i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.displayFormat=i.options.time.displayFormats[i.tickUnit];for(var g=0,p=a.units[g];g<a.units.length;){if(i.unitScale=1,e.isArray(p.steps)&&Math.ceil(i.scaleSizeInUnits/f)<e.max(p.steps)){for(var m=0;m<p.steps.length;++m)if(p.steps[m]>=Math.ceil(i.scaleSizeInUnits/f)){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,p.steps[m]);break}break}if(p.maxStep===!1||Math.ceil(i.scaleSizeInUnits/f)<p.maxStep){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,Math.ceil(i.scaleSizeInUnits/f));break}++g,p=a.units[g],i.tickUnit=p.name;var b=i.firstTick.diff(i.getMomentStartOf(i.firstTick),i.tickUnit,!0),v=i.getMomentStartOf(i.lastTick.clone().add(1,i.tickUnit)).diff(i.lastTick,i.tickUnit,!0);i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)+b+v,i.displayFormat=i.options.time.displayFormats[p.name]}}var x;if(i.options.time.min?x=i.getMomentStartOf(i.firstTick):(i.firstTick=i.getMomentStartOf(i.firstTick),x=i.firstTick),!i.options.time.max){var y=i.getMomentStartOf(i.lastTick),k=y.diff(i.lastTick,i.tickUnit,!0);0>k?i.lastTick=i.getMomentStartOf(i.lastTick.add(1,i.tickUnit)):k>=0&&(i.lastTick=y),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)}i.smallestLabelSeparation=i.width,e.each(i.chart.data.datasets,function(t,e){for(var a=1;a<i.labelMoments[e].length;a++)i.smallestLabelSeparation=Math.min(i.smallestLabelSeparation,i.labelMoments[e][a].diff(i.labelMoments[e][a-1],i.tickUnit,!0))},i),i.options.time.displayFormat&&(i.displayFormat=i.options.time.displayFormat),i.ticks.push(i.firstTick.clone());for(var S=1;S<=i.scaleSizeInUnits;++S){var w=x.clone().add(S,i.tickUnit);if(i.options.time.max&&w.diff(i.lastTick,i.tickUnit,!0)>=0)break;S%i.unitScale===0&&i.ticks.push(w)}var C=i.ticks[i.ticks.length-1].diff(i.lastTick,i.tickUnit);(0!==C||0===i.scaleSizeInUnits)&&(i.options.time.max?(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.ticks[0],i.tickUnit,!0)):(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0))),i.ctx.restore()},getLabelForIndex:function(t,e){var a=this,i=a.chart.data.labels&&t<a.chart.data.labels.length?a.chart.data.labels[t]:"";return"object"==typeof a.chart.data.datasets[e].data[0]&&(i=a.getRightValue(a.chart.data.datasets[e].data[t])),a.options.time.tooltipFormat&&(i=a.parseTime(i).format(a.options.time.tooltipFormat)),i},tickFormatFunction:function(t,a,i){var n=t.format(this.displayFormat),o=this.options.ticks,r=e.getValueOrDefault(o.callback,o.userCallback);return r?r(n,a,i):n},convertTicksToLabels:function(){var t=this;t.tickMoments=t.ticks,t.ticks=t.ticks.map(t.tickFormatFunction,t)},getPixelForValue:function(t,e,a){var n=this;t&&t.isValid||(t=i(n.getRightValue(t)));var o=t&&t.isValid&&t.isValid()?t:n.getLabelMoment(a,e);if(o){var r=o.diff(n.firstTick,n.tickUnit,!0),l=0!==r?r/n.scaleSizeInUnits:r;if(n.isHorizontal()){var s=n.width-(n.paddingLeft+n.paddingRight),d=s*l+n.paddingLeft;return n.left+Math.round(d)}var u=n.height-(n.paddingTop+n.paddingBottom),c=u*l+n.paddingTop;return n.top+Math.round(c)}},getPixelForTick:function(t){return this.getPixelForValue(this.tickMoments[t],null,null)},getValueForPixel:function(t){var e=this,a=e.isHorizontal()?e.width-(e.paddingLeft+e.paddingRight):e.height-(e.paddingTop+e.paddingBottom),n=(t-(e.isHorizontal()?e.left+e.paddingLeft:e.top+e.paddingTop))/a;return n*=e.scaleSizeInUnits,e.firstTick.clone().add(i.duration(n,e.tickUnit).asSeconds(),"seconds")},parseTime:function(t){var e=this;return"string"==typeof e.options.time.parser?i(t,e.options.time.parser):"function"==typeof e.options.time.parser?e.options.time.parser(t):"function"==typeof t.getMonth||"number"==typeof t?i(t):t.isValid&&t.isValid()?t:"string"!=typeof e.options.time.format&&e.options.time.format.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"),e.options.time.format(t)):i(t,e.options.time.format)}});t.scaleService.registerScaleType("time",o,n)}},{1:1}]},{},[7])(7)});
\ No newline at end of file
+!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
