Merge branch 'MDL-59247-master' of git://github.com/jleyva/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 2 Oct 2017 21:48:24 +0000 (23:48 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 2 Oct 2017 21:48:24 +0000 (23:48 +0200)
96 files changed:
analytics/classes/local/indicator/base.php
analytics/classes/local/time_splitting/base.php
analytics/tests/prediction_test.php
calendar/tests/rrule_manager_test.php
lib/amd/build/chartjs-lazy.min.js
lib/amd/src/chartjs-lazy.js
lib/htmlpurifier/HTMLPurifier.php
lib/htmlpurifier/HTMLPurifier.safe-includes.php
lib/htmlpurifier/HTMLPurifier/AttrDef.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Color.php
lib/htmlpurifier/HTMLPurifier/AttrDef/URI/Host.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/TargetNoopener.php [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/ChildDef/List.php
lib/htmlpurifier/HTMLPurifier/Config.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema.ser
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyRemoveScript.txt [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.LegacyEntityDecoder.txt [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoopener.txt [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer/README [changed mode: 0644->0755]
lib/htmlpurifier/HTMLPurifier/Encoder.php
lib/htmlpurifier/HTMLPurifier/EntityParser.php
lib/htmlpurifier/HTMLPurifier/Filter/ExtractStyleBlocks.php
lib/htmlpurifier/HTMLPurifier/Generator.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/TargetNoopener.php [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/HTMLModuleManager.php
lib/htmlpurifier/HTMLPurifier/Lexer.php
lib/htmlpurifier/HTMLPurifier/Lexer/DOMLex.php
lib/htmlpurifier/HTMLPurifier/Lexer/DirectLex.php
lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php
lib/htmlpurifier/HTMLPurifier/Strategy/MakeWellFormed.php
lib/htmlpurifier/HTMLPurifier/Token.php
lib/htmlpurifier/HTMLPurifier/URI.php
lib/htmlpurifier/readme_moodle.txt
lib/markdown/License.md
lib/markdown/Markdown.php
lib/markdown/MarkdownExtra.php
lib/markdown/MarkdownInterface.php
lib/markdown/Readme.md
lib/markdown/readme_moodle.txt
lib/minify/matthiasmullie-minify/data/js/keywords_before.txt
lib/minify/matthiasmullie-minify/data/js/operators_after.txt
lib/minify/matthiasmullie-minify/src/CSS.php
lib/minify/matthiasmullie-minify/src/JS.php
lib/minify/matthiasmullie-minify/src/Minify.php
lib/minify/matthiasmullie-pathconverter/src/Converter.php
lib/minify/matthiasmullie-pathconverter/src/ConverterInterface.php [new file with mode: 0644]
lib/minify/matthiasmullie-pathconverter/src/NoConverter.php [new file with mode: 0644]
lib/minify/readme_moodle.txt
lib/scssphp/Base/Range.php
lib/scssphp/Block.php
lib/scssphp/Colors.php
lib/scssphp/Compiler.php
lib/scssphp/Compiler/Environment.php
lib/scssphp/Exception/CompilerException.php
lib/scssphp/Exception/ParserException.php
lib/scssphp/Exception/RangeException.php [new file with mode: 0644]
lib/scssphp/Exception/ServerException.php
lib/scssphp/Formatter.php
lib/scssphp/Formatter/Compact.php
lib/scssphp/Formatter/Compressed.php
lib/scssphp/Formatter/Crunched.php
lib/scssphp/Formatter/Debug.php
lib/scssphp/Formatter/Expanded.php
lib/scssphp/Formatter/Nested.php
lib/scssphp/Formatter/OutputBlock.php
lib/scssphp/Node.php
lib/scssphp/Node/Number.php
lib/scssphp/Parser.php
lib/scssphp/Server.php
lib/scssphp/Type.php
lib/scssphp/Util.php
lib/scssphp/Version.php
lib/scssphp/moodle_readme.txt
lib/simplepie/LICENSE.txt [new file with mode: 0644]
lib/simplepie/autoloader.php
lib/simplepie/library/SimplePie.php
lib/simplepie/library/SimplePie/Category.php
lib/simplepie/library/SimplePie/Content/Type/Sniffer.php
lib/simplepie/library/SimplePie/File.php
lib/simplepie/library/SimplePie/Item.php
lib/simplepie/library/SimplePie/Locator.php
lib/simplepie/library/SimplePie/Misc.php
lib/simplepie/library/SimplePie/Parse/Date.php
lib/simplepie/library/SimplePie/Sanitize.php
lib/simplepie/readme_moodle.txt
lib/tests/htmlpurifier_test.php
lib/tests/markdown_test.php
lib/thirdpartylibs.xml
mod/quiz/classes/structure.php
mod/quiz/lang/en/quiz.php
mod/quiz/tests/behat/editing_section_headings.feature
report/insights/classes/output/insight.php

index 7c6aa3a..5cd88b9 100644 (file)
@@ -147,7 +147,7 @@ abstract class base extends \core_analytics\calculable {
      * @param integer $starttime Limit the calculation to this timestart
      * @param integer $endtime Limit the calculation to this timeend
      * @param array $existingcalculations Existing calculations of this indicator, indexed by sampleid.
-     * @return array array[0] with format [sampleid] = int[]|float[], array[1] with format [sampleid] = int|float
+     * @return array [0] = [$sampleid => int[]|float[]], [1] = [$sampleid => int|float], [2] = [$sampleid => $sampleid]
      */
     public function calculate($sampleids, $samplesorigin, $starttime = false, $endtime = false, $existingcalculations = array()) {
 
@@ -157,6 +157,7 @@ abstract class base extends \core_analytics\calculable {
 
         $calculations = array();
         $newcalculations = array();
+        $notnulls = array();
         foreach ($sampleids as $sampleid => $unusedsampleid) {
 
             if (isset($existingcalculations[$sampleid])) {
@@ -166,9 +167,12 @@ abstract class base extends \core_analytics\calculable {
                 $newcalculations[$sampleid] = $calculatedvalue;
             }
 
-            if (!is_null($calculatedvalue) && ($calculatedvalue > self::MAX_VALUE || $calculatedvalue < self::MIN_VALUE)) {
-                throw new \coding_exception('Calculated values should be higher than ' . self::MIN_VALUE .
-                    ' and lower than ' . self::MAX_VALUE . ' ' . $calculatedvalue . ' received');
+            if (!is_null($calculatedvalue)) {
+                $notnulls[$sampleid] = $sampleid;
+                if ($calculatedvalue > self::MAX_VALUE || $calculatedvalue < self::MIN_VALUE) {
+                    throw new \coding_exception('Calculated values should be higher than ' . self::MIN_VALUE .
+                        ' and lower than ' . self::MAX_VALUE . ' ' . $calculatedvalue . ' received');
+                }
             }
 
             $calculations[$sampleid] = $calculatedvalue;
@@ -176,6 +180,6 @@ abstract class base extends \core_analytics\calculable {
 
         $features = $this->to_features($calculations);
 
-        return array($features, $newcalculations);
+        return array($features, $newcalculations, $notnulls);
     }
 }
index f45934a..11532a9 100644 (file)
@@ -231,6 +231,9 @@ abstract class base {
                 $range['start'], $range['end'], $samplesorigin);
         }
 
+        // Here we store samples which calculations are not all null.
+        $notnulls = array();
+
         // Fill the dataset samples with indicators data.
         $newcalculations = array();
         foreach ($indicators as $indicator) {
@@ -250,7 +253,7 @@ abstract class base {
                 }
 
                 // Calculate the indicator for each sample in this time range.
-                list($samplesfeatures, $newindicatorcalculations) = $rangeindicator->calculate($sampleids,
+                list($samplesfeatures, $newindicatorcalculations, $indicatornotnulls) = $rangeindicator->calculate($sampleids,
                     $samplesorigin, $range['start'], $range['end'], $prevcalculations);
 
                 // Copy the features data to the dataset.
@@ -258,6 +261,10 @@ abstract class base {
 
                     $uniquesampleid = $this->append_rangeindex($analysersampleid, $rangeindex);
 
+                    if (!isset($notnulls[$uniquesampleid]) && !empty($indicatornotnulls[$analysersampleid])) {
+                        $notnulls[$uniquesampleid] = $uniquesampleid;
+                    }
+
                     // Init the sample if it is still empty.
                     if (!isset($dataset[$uniquesampleid])) {
                         $dataset[$uniquesampleid] = array();
@@ -307,6 +314,15 @@ abstract class base {
             $DB->insert_records('analytics_indicator_calc', $newcalculations);
         }
 
+        // Delete rows where all calculations are null.
+        // We still store the indicator calculation and we still store the sample id as
+        // processed so we don't have to process this sample again, but we exclude it
+        // from the dataset because it is not useful.
+        $nulls = array_diff_key($dataset, $notnulls);
+        foreach ($nulls as $uniqueid => $ignoredvalues) {
+            unset($dataset[$uniqueid]);
+        }
+
         return $dataset;
     }
 
index 1e21d8d..7f30037 100644 (file)
@@ -361,6 +361,57 @@ class core_analytics_prediction_testcase extends advanced_testcase {
         list($values, $unused) = $indicator->calculate($sampleids, $sampleorigin, $starttime, $endtime, $existingcalcs);
     }
 
+    /**
+     * test_not_null_samples
+     */
+    public function test_not_null_samples() {
+        $this->resetAfterTest(true);
+
+        $classname = '\core\analytics\time_splitting\quarters';
+        $timesplitting = \core_analytics\manager::get_time_splitting($classname);
+        $timesplitting->set_analysable(new \core_analytics\site());
+
+        $ranges = array(
+            array('start' => 111, 'end' => 222, 'time' => 222),
+            array('start' => 222, 'end' => 333, 'time' => 333)
+        );
+        $samples = array(123 => 123, 321 => 321);
+
+        $indicator1 = $this->getMockBuilder('test_indicator_max')
+            ->setMethods(['calculate_sample'])
+            ->getMock();
+        $indicator1->method('calculate_sample')
+            ->willReturn(null);
+
+        $indicator2 = \core_analytics\manager::get_indicator('test_indicator_min');
+
+        // Samples with at least 1 not null value are returned.
+        $params = array(
+            $samples,
+            'whatever',
+            array($indicator1, $indicator2),
+            $ranges
+        );
+        $dataset = phpunit_util::call_internal_method($timesplitting, 'calculate_indicators', $params, $classname);
+        $this->assertArrayHasKey('123-0', $dataset);
+        $this->assertArrayHasKey('123-1', $dataset);
+        $this->assertArrayHasKey('321-0', $dataset);
+        $this->assertArrayHasKey('321-1', $dataset);
+
+        // Samples with only null values are not returned.
+        $params = array(
+            $samples,
+            'whatever',
+            array($indicator1),
+            $ranges
+        );
+        $dataset = phpunit_util::call_internal_method($timesplitting, 'calculate_indicators', $params, $classname);
+        $this->assertArrayNotHasKey('123-0', $dataset);
+        $this->assertArrayNotHasKey('123-1', $dataset);
+        $this->assertArrayNotHasKey('321-0', $dataset);
+        $this->assertArrayNotHasKey('321-1', $dataset);
+    }
+
     /**
      * provider_ml_test_evaluation
      *
index ca28508..a6e2531 100644 (file)
@@ -872,7 +872,7 @@ class core_calendar_rrule_manager_testcase extends advanced_testcase {
         $records = $DB->get_records('event', ['repeatid' => $this->event->id], 'timestart ASC', 'id, repeatid, timestart');
         $expecteddate = new DateTime('first Monday of this month');
         // Move to the next interval's first Monday if the calculated start date is after this month's first Monday.
-        if ($expecteddate->getTimestamp() < $startdatetime->getTimestamp()) {
+        if ($expecteddate->getTimestamp() < $startdate->getTimestamp()) {
             $expecteddate->add($interval);
             $expecteddate->modify('first Monday of this month');
         }
index 62a3d19..b672fc1 100644 (file)
Binary files a/lib/amd/build/chartjs-lazy.min.js and b/lib/amd/build/chartjs-lazy.min.js differ
index 033e609..d27968a 100644 (file)
-/*!\r
- * Chart.js\r
- * http://chartjs.org/\r
- * Version: 2.2.2\r
- *\r
- * Copyright 2016 Nick Downie\r
- * Released under the MIT license\r
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md\r
- */\r
-\r
-/**\r
- * Description of import into Moodle:\r
- *\r
- * - Download from http://www.chartjs.org/docs/#getting-started-download-chart-js.\r
- * - Copy Chart.js to lib/amd/src/chartjs.js.\r
- * - Add these instructions to the file.\r
- * - Add the jshint ignore rules.\r
- * - Visit lib/tests/other/chartjstestpage.php to see if the library still works after the update.\r
- */\r
-\r
-(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){\r
-\r
-},{}],2:[function(require,module,exports){\r
-       /* MIT license */\r
-       var colorNames = require(6);\r
-\r
-       module.exports = {\r
-               getRgba: getRgba,\r
-               getHsla: getHsla,\r
-               getRgb: getRgb,\r
-               getHsl: getHsl,\r
-               getHwb: getHwb,\r
-               getAlpha: getAlpha,\r
-\r
-               hexString: hexString,\r
-               rgbString: rgbString,\r
-               rgbaString: rgbaString,\r
-               percentString: percentString,\r
-               percentaString: percentaString,\r
-               hslString: hslString,\r
-               hslaString: hslaString,\r
-               hwbString: hwbString,\r
-               keyword: keyword\r
-       }\r
-\r
-       function getRgba(string) {\r
-               if (!string) {\r
-                       return;\r
-               }\r
-               var abbr =  /^#([a-fA-F0-9]{3})$/,\r
-                       hex =  /^#([a-fA-F0-9]{6})$/,\r
-                       rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,\r
-                       per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,\r
-                       keyword = /(\w+)/;\r
-\r
-               var rgb = [0, 0, 0],\r
-                       a = 1,\r
-                       match = string.match(abbr);\r
-               if (match) {\r
-                       match = match[1];\r
-                       for (var i = 0; i < rgb.length; i++) {\r
-                               rgb[i] = parseInt(match[i] + match[i], 16);\r
-                       }\r
-               }\r
-               else if (match = string.match(hex)) {\r
-                       match = match[1];\r
-                       for (var i = 0; i < rgb.length; i++) {\r
-                               rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);\r
-                       }\r
-               }\r
-               else if (match = string.match(rgba)) {\r
-                       for (var i = 0; i < rgb.length; i++) {\r
-                               rgb[i] = parseInt(match[i + 1]);\r
-                       }\r
-                       a = parseFloat(match[4]);\r
-               }\r
-               else if (match = string.match(per)) {\r
-                       for (var i = 0; i < rgb.length; i++) {\r
-                               rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);\r
-                       }\r
-                       a = parseFloat(match[4]);\r
-               }\r
-               else if (match = string.match(keyword)) {\r
-                       if (match[1] == "transparent") {\r
-                               return [0, 0, 0, 0];\r
-                       }\r
-                       rgb = colorNames[match[1]];\r
-                       if (!rgb) {\r
-                               return;\r
-                       }\r
-               }\r
-\r
-               for (var i = 0; i < rgb.length; i++) {\r
-                       rgb[i] = scale(rgb[i], 0, 255);\r
-               }\r
-               if (!a && a != 0) {\r
-                       a = 1;\r
-               }\r
-               else {\r
-                       a = scale(a, 0, 1);\r
-               }\r
-               rgb[3] = a;\r
-               return rgb;\r
-       }\r
-\r
-       function getHsla(string) {\r
-               if (!string) {\r
-                       return;\r
-               }\r
-               var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;\r
-               var match = string.match(hsl);\r
-               if (match) {\r
-                       var alpha = parseFloat(match[4]);\r
-                       var h = scale(parseInt(match[1]), 0, 360),\r
-                               s = scale(parseFloat(match[2]), 0, 100),\r
-                               l = scale(parseFloat(match[3]), 0, 100),\r
-                               a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r
-                       return [h, s, l, a];\r
-               }\r
-       }\r
-\r
-       function getHwb(string) {\r
-               if (!string) {\r
-                       return;\r
-               }\r
-               var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;\r
-               var match = string.match(hwb);\r
-               if (match) {\r
-                       var alpha = parseFloat(match[4]);\r
-                       var h = scale(parseInt(match[1]), 0, 360),\r
-                               w = scale(parseFloat(match[2]), 0, 100),\r
-                               b = scale(parseFloat(match[3]), 0, 100),\r
-                               a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r
-                       return [h, w, b, a];\r
-               }\r
-       }\r
-\r
-       function getRgb(string) {\r
-               var rgba = getRgba(string);\r
-               return rgba && rgba.slice(0, 3);\r
-       }\r
-\r
-       function getHsl(string) {\r
-               var hsla = getHsla(string);\r
-               return hsla && hsla.slice(0, 3);\r
-       }\r
-\r
-       function getAlpha(string) {\r
-               var vals = getRgba(string);\r
-               if (vals) {\r
-                       return vals[3];\r
-               }\r
-               else if (vals = getHsla(string)) {\r
-                       return vals[3];\r
-               }\r
-               else if (vals = getHwb(string)) {\r
-                       return vals[3];\r
-               }\r
-       }\r
-\r
-// generators\r
-       function hexString(rgb) {\r
-               return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])\r
-                       + hexDouble(rgb[2]);\r
-       }\r
-\r
-       function rgbString(rgba, alpha) {\r
-               if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r
-                       return rgbaString(rgba, alpha);\r
-               }\r
-               return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";\r
-       }\r
-\r
-       function rgbaString(rgba, alpha) {\r
-               if (alpha === undefined) {\r
-                       alpha = (rgba[3] !== undefined ? rgba[3] : 1);\r
-               }\r
-               return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]\r
-                       + ", " + alpha + ")";\r
-       }\r
-\r
-       function percentString(rgba, alpha) {\r
-               if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r
-                       return percentaString(rgba, alpha);\r
-               }\r
-               var r = Math.round(rgba[0]/255 * 100),\r
-                       g = Math.round(rgba[1]/255 * 100),\r
-                       b = Math.round(rgba[2]/255 * 100);\r
-\r
-               return "rgb(" + r + "%, " + g + "%, " + b + "%)";\r
-       }\r
-\r
-       function percentaString(rgba, alpha) {\r
-               var r = Math.round(rgba[0]/255 * 100),\r
-                       g = Math.round(rgba[1]/255 * 100),\r
-                       b = Math.round(rgba[2]/255 * 100);\r
-               return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";\r
-       }\r
-\r
-       function hslString(hsla, alpha) {\r
-               if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {\r
-                       return hslaString(hsla, alpha);\r
-               }\r
-               return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";\r
-       }\r
-\r
-       function hslaString(hsla, alpha) {\r
-               if (alpha === undefined) {\r
-                       alpha = (hsla[3] !== undefined ? hsla[3] : 1);\r
-               }\r
-               return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "\r
-                       + alpha + ")";\r
-       }\r
-\r
-// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax\r
-// (hwb have alpha optional & 1 is default value)\r
-       function hwbString(hwb, alpha) {\r
-               if (alpha === undefined) {\r
-                       alpha = (hwb[3] !== undefined ? hwb[3] : 1);\r
-               }\r
-               return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"\r
-                       + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";\r
-       }\r
-\r
-       function keyword(rgb) {\r
-               return reverseNames[rgb.slice(0, 3)];\r
-       }\r
-\r
-// helpers\r
-       function scale(num, min, max) {\r
-               return Math.min(Math.max(min, num), max);\r
-       }\r
-\r
-       function hexDouble(num) {\r
-               var str = num.toString(16).toUpperCase();\r
-               return (str.length < 2) ? "0" + str : str;\r
-       }\r
-\r
-\r
-//create a list of reverse color names\r
-       var reverseNames = {};\r
-       for (var name in colorNames) {\r
-               reverseNames[colorNames[name]] = name;\r
-       }\r
-\r
-},{"6":6}],3:[function(require,module,exports){\r
-       /* MIT license */\r
-       var convert = require(5);\r
-       var string = require(2);\r
-\r
-       var Color = function (obj) {\r
-               if (obj instanceof Color) {\r
-                       return obj;\r
-               }\r
-               if (!(this instanceof Color)) {\r
-                       return new Color(obj);\r
-               }\r
-\r
-               this.values = {\r
-                       rgb: [0, 0, 0],\r
-                       hsl: [0, 0, 0],\r
-                       hsv: [0, 0, 0],\r
-                       hwb: [0, 0, 0],\r
-                       cmyk: [0, 0, 0, 0],\r
-                       alpha: 1\r
-               };\r
-\r
-               // parse Color() argument\r
-               var vals;\r
-               if (typeof obj === 'string') {\r
-                       vals = string.getRgba(obj);\r
-                       if (vals) {\r
-                               this.setValues('rgb', vals);\r
-                       } else if (vals = string.getHsla(obj)) {\r
-                               this.setValues('hsl', vals);\r
-                       } else if (vals = string.getHwb(obj)) {\r
-                               this.setValues('hwb', vals);\r
-                       } else {\r
-                               throw new Error('Unable to parse color from string "' + obj + '"');\r
-                       }\r
-               } else if (typeof obj === 'object') {\r
-                       vals = obj;\r
-                       if (vals.r !== undefined || vals.red !== undefined) {\r
-                               this.setValues('rgb', vals);\r
-                       } else if (vals.l !== undefined || vals.lightness !== undefined) {\r
-                               this.setValues('hsl', vals);\r
-                       } else if (vals.v !== undefined || vals.value !== undefined) {\r
-                               this.setValues('hsv', vals);\r
-                       } else if (vals.w !== undefined || vals.whiteness !== undefined) {\r
-                               this.setValues('hwb', vals);\r
-                       } else if (vals.c !== undefined || vals.cyan !== undefined) {\r
-                               this.setValues('cmyk', vals);\r
-                       } else {\r
-                               throw new Error('Unable to parse color from object ' + JSON.stringify(obj));\r
-                       }\r
-               }\r
-       };\r
-\r
-       Color.prototype = {\r
-               rgb: function () {\r
-                       return this.setSpace('rgb', arguments);\r
-               },\r
-               hsl: function () {\r
-                       return this.setSpace('hsl', arguments);\r
-               },\r
-               hsv: function () {\r
-                       return this.setSpace('hsv', arguments);\r
-               },\r
-               hwb: function () {\r
-                       return this.setSpace('hwb', arguments);\r
-               },\r
-               cmyk: function () {\r
-                       return this.setSpace('cmyk', arguments);\r
-               },\r
-\r
-               rgbArray: function () {\r
-                       return this.values.rgb;\r
-               },\r
-               hslArray: function () {\r
-                       return this.values.hsl;\r
-               },\r
-               hsvArray: function () {\r
-                       return this.values.hsv;\r
-               },\r
-               hwbArray: function () {\r
-                       var values = this.values;\r
-                       if (values.alpha !== 1) {\r
-                               return values.hwb.concat([values.alpha]);\r
-                       }\r
-                       return values.hwb;\r
-               },\r
-               cmykArray: function () {\r
-                       return this.values.cmyk;\r
-               },\r
-               rgbaArray: function () {\r
-                       var values = this.values;\r
-                       return values.rgb.concat([values.alpha]);\r
-               },\r
-               hslaArray: function () {\r
-                       var values = this.values;\r
-                       return values.hsl.concat([values.alpha]);\r
-               },\r
-               alpha: function (val) {\r
-                       if (val === undefined) {\r
-                               return this.values.alpha;\r
-                       }\r
-                       this.setValues('alpha', val);\r
-                       return this;\r
-               },\r
-\r
-               red: function (val) {\r
-                       return this.setChannel('rgb', 0, val);\r
-               },\r
-               green: function (val) {\r
-                       return this.setChannel('rgb', 1, val);\r
-               },\r
-               blue: function (val) {\r
-                       return this.setChannel('rgb', 2, val);\r
-               },\r
-               hue: function (val) {\r
-                       if (val) {\r
-                               val %= 360;\r
-                               val = val < 0 ? 360 + val : val;\r
-                       }\r
-                       return this.setChannel('hsl', 0, val);\r
-               },\r
-               saturation: function (val) {\r
-                       return this.setChannel('hsl', 1, val);\r
-               },\r
-               lightness: function (val) {\r
-                       return this.setChannel('hsl', 2, val);\r
-               },\r
-               saturationv: function (val) {\r
-                       return this.setChannel('hsv', 1, val);\r
-               },\r
-               whiteness: function (val) {\r
-                       return this.setChannel('hwb', 1, val);\r
-               },\r
-               blackness: function (val) {\r
-                       return this.setChannel('hwb', 2, val);\r
-               },\r
-               value: function (val) {\r
-                       return this.setChannel('hsv', 2, val);\r
-               },\r
-               cyan: function (val) {\r
-                       return this.setChannel('cmyk', 0, val);\r
-               },\r
-               magenta: function (val) {\r
-                       return this.setChannel('cmyk', 1, val);\r
-               },\r
-               yellow: function (val) {\r
-                       return this.setChannel('cmyk', 2, val);\r
-               },\r
-               black: function (val) {\r
-                       return this.setChannel('cmyk', 3, val);\r
-               },\r
-\r
-               hexString: function () {\r
-                       return string.hexString(this.values.rgb);\r
-               },\r
-               rgbString: function () {\r
-                       return string.rgbString(this.values.rgb, this.values.alpha);\r
-               },\r
-               rgbaString: function () {\r
-                       return string.rgbaString(this.values.rgb, this.values.alpha);\r
-               },\r
-               percentString: function () {\r
-                       return string.percentString(this.values.rgb, this.values.alpha);\r
-               },\r
-               hslString: function () {\r
-                       return string.hslString(this.values.hsl, this.values.alpha);\r
-               },\r
-               hslaString: function () {\r
-                       return string.hslaString(this.values.hsl, this.values.alpha);\r
-               },\r
-               hwbString: function () {\r
-                       return string.hwbString(this.values.hwb, this.values.alpha);\r
-               },\r
-               keyword: function () {\r
-                       return string.keyword(this.values.rgb, this.values.alpha);\r
-               },\r
-\r
-               rgbNumber: function () {\r
-                       var rgb = this.values.rgb;\r
-                       return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\r
-               },\r
-\r
-               luminosity: function () {\r
-                       // http://www.w3.org/TR/WCAG20/#relativeluminancedef\r
-                       var rgb = this.values.rgb;\r
-                       var lum = [];\r
-                       for (var i = 0; i < rgb.length; i++) {\r
-                               var chan = rgb[i] / 255;\r
-                               lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\r
-                       }\r
-                       return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\r
-               },\r
-\r
-               contrast: function (color2) {\r
-                       // http://www.w3.org/TR/WCAG20/#contrast-ratiodef\r
-                       var lum1 = this.luminosity();\r
-                       var lum2 = color2.luminosity();\r
-                       if (lum1 > lum2) {\r
-                               return (lum1 + 0.05) / (lum2 + 0.05);\r
-                       }\r
-                       return (lum2 + 0.05) / (lum1 + 0.05);\r
-               },\r
-\r
-               level: function (color2) {\r
-                       var contrastRatio = this.contrast(color2);\r
-                       if (contrastRatio >= 7.1) {\r
-                               return 'AAA';\r
-                       }\r
-\r
-                       return (contrastRatio >= 4.5) ? 'AA' : '';\r
-               },\r
-\r
-               dark: function () {\r
-                       // YIQ equation from http://24ways.org/2010/calculating-color-contrast\r
-                       var rgb = this.values.rgb;\r
-                       var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\r
-                       return yiq < 128;\r
-               },\r
-\r
-               light: function () {\r
-                       return !this.dark();\r
-               },\r
-\r
-               negate: function () {\r
-                       var rgb = [];\r
-                       for (var i = 0; i < 3; i++) {\r
-                               rgb[i] = 255 - this.values.rgb[i];\r
-                       }\r
-                       this.setValues('rgb', rgb);\r
-                       return this;\r
-               },\r
-\r
-               lighten: function (ratio) {\r
-                       var hsl = this.values.hsl;\r
-                       hsl[2] += hsl[2] * ratio;\r
-                       this.setValues('hsl', hsl);\r
-                       return this;\r
-               },\r
-\r
-               darken: function (ratio) {\r
-                       var hsl = this.values.hsl;\r
-                       hsl[2] -= hsl[2] * ratio;\r
-                       this.setValues('hsl', hsl);\r
-                       return this;\r
-               },\r
-\r
-               saturate: function (ratio) {\r
-                       var hsl = this.values.hsl;\r
-                       hsl[1] += hsl[1] * ratio;\r
-                       this.setValues('hsl', hsl);\r
-                       return this;\r
-               },\r
-\r
-               desaturate: function (ratio) {\r
-                       var hsl = this.values.hsl;\r
-                       hsl[1] -= hsl[1] * ratio;\r
-                       this.setValues('hsl', hsl);\r
-                       return this;\r
-               },\r
-\r
-               whiten: function (ratio) {\r
-                       var hwb = this.values.hwb;\r
-                       hwb[1] += hwb[1] * ratio;\r
-                       this.setValues('hwb', hwb);\r
-                       return this;\r
-               },\r
-\r
-               blacken: function (ratio) {\r
-                       var hwb = this.values.hwb;\r
-                       hwb[2] += hwb[2] * ratio;\r
-                       this.setValues('hwb', hwb);\r
-                       return this;\r
-               },\r
-\r
-               greyscale: function () {\r
-                       var rgb = this.values.rgb;\r
-                       // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\r
-                       var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\r
-                       this.setValues('rgb', [val, val, val]);\r
-                       return this;\r
-               },\r
-\r
-               clearer: function (ratio) {\r
-                       var alpha = this.values.alpha;\r
-                       this.setValues('alpha', alpha - (alpha * ratio));\r
-                       return this;\r
-               },\r
-\r
-               opaquer: function (ratio) {\r
-                       var alpha = this.values.alpha;\r
-                       this.setValues('alpha', alpha + (alpha * ratio));\r
-                       return this;\r
-               },\r
-\r
-               rotate: function (degrees) {\r
-                       var hsl = this.values.hsl;\r
-                       var hue = (hsl[0] + degrees) % 360;\r
-                       hsl[0] = hue < 0 ? 360 + hue : hue;\r
-                       this.setValues('hsl', hsl);\r
-                       return this;\r
-               },\r
-\r
-               /**\r
-                * Ported from sass implementation in C\r
-                * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\r
-                */\r
-               mix: function (mixinColor, weight) {\r
-                       var color1 = this;\r
-                       var color2 = mixinColor;\r
-                       var p = weight === undefined ? 0.5 : weight;\r
-\r
-                       var w = 2 * p - 1;\r
-                       var a = color1.alpha() - color2.alpha();\r
-\r
-                       var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\r
-                       var w2 = 1 - w1;\r
-\r
-                       return this\r
-                               .rgb(\r
-                                       w1 * color1.red() + w2 * color2.red(),\r
-                                       w1 * color1.green() + w2 * color2.green(),\r
-                                       w1 * color1.blue() + w2 * color2.blue()\r
-                               )\r
-                               .alpha(color1.alpha() * p + color2.alpha() * (1 - p));\r
-               },\r
-\r
-               toJSON: function () {\r
-                       return this.rgb();\r
-               },\r
-\r
-               clone: function () {\r
-                       // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,\r
-                       // making the final build way to big to embed in Chart.js. So let's do it manually,\r
-                       // assuming that values to clone are 1 dimension arrays containing only numbers,\r
-                       // except 'alpha' which is a number.\r
-                       var result = new Color();\r
-                       var source = this.values;\r
-                       var target = result.values;\r
-                       var value, type;\r
-\r
-                       for (var prop in source) {\r
-                               if (source.hasOwnProperty(prop)) {\r
-                                       value = source[prop];\r
-                                       type = ({}).toString.call(value);\r
-                                       if (type === '[object Array]') {\r
-                                               target[prop] = value.slice(0);\r
-                                       } else if (type === '[object Number]') {\r
-                                               target[prop] = value;\r
-                                       } else {\r
-                                               console.error('unexpected color value:', value);\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       return result;\r
-               }\r
-       };\r
-\r
-       Color.prototype.spaces = {\r
-               rgb: ['red', 'green', 'blue'],\r
-               hsl: ['hue', 'saturation', 'lightness'],\r
-               hsv: ['hue', 'saturation', 'value'],\r
-               hwb: ['hue', 'whiteness', 'blackness'],\r
-               cmyk: ['cyan', 'magenta', 'yellow', 'black']\r
-       };\r
-\r
-       Color.prototype.maxes = {\r
-               rgb: [255, 255, 255],\r
-               hsl: [360, 100, 100],\r
-               hsv: [360, 100, 100],\r
-               hwb: [360, 100, 100],\r
-               cmyk: [100, 100, 100, 100]\r
-       };\r
-\r
-       Color.prototype.getValues = function (space) {\r
-               var values = this.values;\r
-               var vals = {};\r
-\r
-               for (var i = 0; i < space.length; i++) {\r
-                       vals[space.charAt(i)] = values[space][i];\r
-               }\r
-\r
-               if (values.alpha !== 1) {\r
-                       vals.a = values.alpha;\r
-               }\r
-\r
-               // {r: 255, g: 255, b: 255, a: 0.4}\r
-               return vals;\r
-       };\r
-\r
-       Color.prototype.setValues = function (space, vals) {\r
-               var values = this.values;\r
-               var spaces = this.spaces;\r
-               var maxes = this.maxes;\r
-               var alpha = 1;\r
-               var i;\r
-\r
-               if (space === 'alpha') {\r
-                       alpha = vals;\r
-               } else if (vals.length) {\r
-                       // [10, 10, 10]\r
-                       values[space] = vals.slice(0, space.length);\r
-                       alpha = vals[space.length];\r
-               } else if (vals[space.charAt(0)] !== undefined) {\r
-                       // {r: 10, g: 10, b: 10}\r
-                       for (i = 0; i < space.length; i++) {\r
-                               values[space][i] = vals[space.charAt(i)];\r
-                       }\r
-\r
-                       alpha = vals.a;\r
-               } else if (vals[spaces[space][0]] !== undefined) {\r
-                       // {red: 10, green: 10, blue: 10}\r
-                       var chans = spaces[space];\r
-\r
-                       for (i = 0; i < space.length; i++) {\r
-                               values[space][i] = vals[chans[i]];\r
-                       }\r
-\r
-                       alpha = vals.alpha;\r
-               }\r
-\r
-               values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));\r
-\r
-               if (space === 'alpha') {\r
-                       return false;\r
-               }\r
-\r
-               var capped;\r
-\r
-               // cap values of the space prior converting all values\r
-               for (i = 0; i < space.length; i++) {\r
-                       capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));\r
-                       values[space][i] = Math.round(capped);\r
-               }\r
-\r
-               // convert to all the other color spaces\r
-               for (var sname in spaces) {\r
-                       if (sname !== space) {\r
-                               values[sname] = convert[space][sname](values[space]);\r
-                       }\r
-               }\r
-\r
-               return true;\r
-       };\r
-\r
-       Color.prototype.setSpace = function (space, args) {\r
-               var vals = args[0];\r
-\r
-               if (vals === undefined) {\r
-                       // color.rgb()\r
-                       return this.getValues(space);\r
-               }\r
-\r
-               // color.rgb(10, 10, 10)\r
-               if (typeof vals === 'number') {\r
-                       vals = Array.prototype.slice.call(args);\r
-               }\r
-\r
-               this.setValues(space, vals);\r
-               return this;\r
-       };\r
-\r
-       Color.prototype.setChannel = function (space, index, val) {\r
-               var svalues = this.values[space];\r
-               if (val === undefined) {\r
-                       // color.red()\r
-                       return svalues[index];\r
-               } else if (val === svalues[index]) {\r
-                       // color.red(color.red())\r
-                       return this;\r
-               }\r
-\r
-               // color.red(100)\r
-               svalues[index] = val;\r
-               this.setValues(space, svalues);\r
-\r
-               return this;\r
-       };\r
-\r
-       if (typeof window !== 'undefined') {\r
-               window.Color = Color;\r
-       }\r
-\r
-       module.exports = Color;\r
-\r
-},{"2":2,"5":5}],4:[function(require,module,exports){\r
-       /* MIT license */\r
-\r
-       module.exports = {\r
-               rgb2hsl: rgb2hsl,\r
-               rgb2hsv: rgb2hsv,\r
-               rgb2hwb: rgb2hwb,\r
-               rgb2cmyk: rgb2cmyk,\r
-               rgb2keyword: rgb2keyword,\r
-               rgb2xyz: rgb2xyz,\r
-               rgb2lab: rgb2lab,\r
-               rgb2lch: rgb2lch,\r
-\r
-               hsl2rgb: hsl2rgb,\r
-               hsl2hsv: hsl2hsv,\r
-               hsl2hwb: hsl2hwb,\r
-               hsl2cmyk: hsl2cmyk,\r
-               hsl2keyword: hsl2keyword,\r
-\r
-               hsv2rgb: hsv2rgb,\r
-               hsv2hsl: hsv2hsl,\r
-               hsv2hwb: hsv2hwb,\r
-               hsv2cmyk: hsv2cmyk,\r
-               hsv2keyword: hsv2keyword,\r
-\r
-               hwb2rgb: hwb2rgb,\r
-               hwb2hsl: hwb2hsl,\r
-               hwb2hsv: hwb2hsv,\r
-               hwb2cmyk: hwb2cmyk,\r
-               hwb2keyword: hwb2keyword,\r
-\r
-               cmyk2rgb: cmyk2rgb,\r
-               cmyk2hsl: cmyk2hsl,\r
-               cmyk2hsv: cmyk2hsv,\r
-               cmyk2hwb: cmyk2hwb,\r
-               cmyk2keyword: cmyk2keyword,\r
-\r
-               keyword2rgb: keyword2rgb,\r
-               keyword2hsl: keyword2hsl,\r
-               keyword2hsv: keyword2hsv,\r
-               keyword2hwb: keyword2hwb,\r
-               keyword2cmyk: keyword2cmyk,\r
-               keyword2lab: keyword2lab,\r
-               keyword2xyz: keyword2xyz,\r
-\r
-               xyz2rgb: xyz2rgb,\r
-               xyz2lab: xyz2lab,\r
-               xyz2lch: xyz2lch,\r
-\r
-               lab2xyz: lab2xyz,\r
-               lab2rgb: lab2rgb,\r
-               lab2lch: lab2lch,\r
-\r
-               lch2lab: lch2lab,\r
-               lch2xyz: lch2xyz,\r
-               lch2rgb: lch2rgb\r
-       }\r
-\r
-\r
-       function rgb2hsl(rgb) {\r
-               var r = rgb[0]/255,\r
-                       g = rgb[1]/255,\r
-                       b = rgb[2]/255,\r
-                       min = Math.min(r, g, b),\r
-                       max = Math.max(r, g, b),\r
-                       delta = max - min,\r
-                       h, s, l;\r
-\r
-               if (max == min)\r
-                       h = 0;\r
-               else if (r == max)\r
-                       h = (g - b) / delta;\r
-               else if (g == max)\r
-                       h = 2 + (b - r) / delta;\r
-               else if (b == max)\r
-                       h = 4 + (r - g)/ delta;\r
-\r
-               h = Math.min(h * 60, 360);\r
-\r
-               if (h < 0)\r
-                       h += 360;\r
-\r
-               l = (min + max) / 2;\r
-\r
-               if (max == min)\r
-                       s = 0;\r
-               else if (l <= 0.5)\r
-                       s = delta / (max + min);\r
-               else\r
-                       s = delta / (2 - max - min);\r
-\r
-               return [h, s * 100, l * 100];\r
-       }\r
-\r
-       function rgb2hsv(rgb) {\r
-               var r = rgb[0],\r
-                       g = rgb[1],\r
-                       b = rgb[2],\r
-                       min = Math.min(r, g, b),\r
-                       max = Math.max(r, g, b),\r
-                       delta = max - min,\r
-                       h, s, v;\r
-\r
-               if (max == 0)\r
-                       s = 0;\r
-               else\r
-                       s = (delta/max * 1000)/10;\r
-\r
-               if (max == min)\r
-                       h = 0;\r
-               else if (r == max)\r
-                       h = (g - b) / delta;\r
-               else if (g == max)\r
-                       h = 2 + (b - r) / delta;\r
-               else if (b == max)\r
-                       h = 4 + (r - g) / delta;\r
-\r
-               h = Math.min(h * 60, 360);\r
-\r
-               if (h < 0)\r
-                       h += 360;\r
-\r
-               v = ((max / 255) * 1000) / 10;\r
-\r
-               return [h, s, v];\r
-       }\r
-\r
-       function rgb2hwb(rgb) {\r
-               var r = rgb[0],\r
-                       g = rgb[1],\r
-                       b = rgb[2],\r
-                       h = rgb2hsl(rgb)[0],\r
-                       w = 1/255 * Math.min(r, Math.min(g, b)),\r
-                       b = 1 - 1/255 * Math.max(r, Math.max(g, b));\r
-\r
-               return [h, w * 100, b * 100];\r
-       }\r
-\r
-       function rgb2cmyk(rgb) {\r
-               var r = rgb[0] / 255,\r
-                       g = rgb[1] / 255,\r
-                       b = rgb[2] / 255,\r
-                       c, m, y, k;\r
-\r
-               k = Math.min(1 - r, 1 - g, 1 - b);\r
-               c = (1 - r - k) / (1 - k) || 0;\r
-               m = (1 - g - k) / (1 - k) || 0;\r
-               y = (1 - b - k) / (1 - k) || 0;\r
-               return [c * 100, m * 100, y * 100, k * 100];\r
-       }\r
-\r
-       function rgb2keyword(rgb) {\r
-               return reverseKeywords[JSON.stringify(rgb)];\r
-       }\r
-\r
-       function rgb2xyz(rgb) {\r
-               var r = rgb[0] / 255,\r
-                       g = rgb[1] / 255,\r
-                       b = rgb[2] / 255;\r
-\r
-               // assume sRGB\r
-               r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);\r
-               g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);\r
-               b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);\r
-\r
-               var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\r
-               var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\r
-               var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\r
-\r
-               return [x * 100, y *100, z * 100];\r
-       }\r
-\r
-       function rgb2lab(rgb) {\r
-               var xyz = rgb2xyz(rgb),\r
-                       x = xyz[0],\r
-                       y = xyz[1],\r
-                       z = xyz[2],\r
-                       l, a, b;\r
-\r
-               x /= 95.047;\r
-               y /= 100;\r
-               z /= 108.883;\r
-\r
-               x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);\r
-               y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);\r
-               z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);\r
-\r
-               l = (116 * y) - 16;\r
-               a = 500 * (x - y);\r
-               b = 200 * (y - z);\r
-\r
-               return [l, a, b];\r
-       }\r
-\r
-       function rgb2lch(args) {\r
-               return lab2lch(rgb2lab(args));\r
-       }\r
-\r
-       function hsl2rgb(hsl) {\r
-               var h = hsl[0] / 360,\r
-                       s = hsl[1] / 100,\r
-                       l = hsl[2] / 100,\r
-                       t1, t2, t3, rgb, val;\r
-\r
-               if (s == 0) {\r
-                       val = l * 255;\r
-                       return [val, val, val];\r
-               }\r
-\r
-               if (l < 0.5)\r
-                       t2 = l * (1 + s);\r
-               else\r
-                       t2 = l + s - l * s;\r
-               t1 = 2 * l - t2;\r
-\r
-               rgb = [0, 0, 0];\r
-               for (var i = 0; i < 3; i++) {\r
-                       t3 = h + 1 / 3 * - (i - 1);\r
-                       t3 < 0 && t3++;\r
-                       t3 > 1 && t3--;\r
-\r
-                       if (6 * t3 < 1)\r
-                               val = t1 + (t2 - t1) * 6 * t3;\r
-                       else if (2 * t3 < 1)\r
-                               val = t2;\r
-                       else if (3 * t3 < 2)\r
-                               val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\r
-                       else\r
-                               val = t1;\r
-\r
-                       rgb[i] = val * 255;\r
-               }\r
-\r
-               return rgb;\r
-       }\r
-\r
-       function hsl2hsv(hsl) {\r
-               var h = hsl[0],\r
-                       s = hsl[1] / 100,\r
-                       l = hsl[2] / 100,\r
-                       sv, v;\r
-\r
-               if(l === 0) {\r
-                       // no need to do calc on black\r
-                       // also avoids divide by 0 error\r
-                       return [0, 0, 0];\r
-               }\r
-\r
-               l *= 2;\r
-               s *= (l <= 1) ? l : 2 - l;\r
-               v = (l + s) / 2;\r
-               sv = (2 * s) / (l + s);\r
-               return [h, sv * 100, v * 100];\r
-       }\r
-\r
-       function hsl2hwb(args) {\r
-               return rgb2hwb(hsl2rgb(args));\r
-       }\r
-\r
-       function hsl2cmyk(args) {\r
-               return rgb2cmyk(hsl2rgb(args));\r
-       }\r
-\r
-       function hsl2keyword(args) {\r
-               return rgb2keyword(hsl2rgb(args));\r
-       }\r
-\r
-\r
-       function hsv2rgb(hsv) {\r
-               var h = hsv[0] / 60,\r
-                       s = hsv[1] / 100,\r
-                       v = hsv[2] / 100,\r
-                       hi = Math.floor(h) % 6;\r
-\r
-               var f = h - Math.floor(h),\r
-                       p = 255 * v * (1 - s),\r
-                       q = 255 * v * (1 - (s * f)),\r
-                       t = 255 * v * (1 - (s * (1 - f))),\r
-                       v = 255 * v;\r
-\r
-               switch(hi) {\r
-                       case 0:\r
-                               return [v, t, p];\r
-                       case 1:\r
-                               return [q, v, p];\r
-                       case 2:\r
-                               return [p, v, t];\r
-                       case 3:\r
-                               return [p, q, v];\r
-                       case 4:\r
-                               return [t, p, v];\r
-                       case 5:\r
-                               return [v, p, q];\r
-               }\r
-       }\r
-\r
-       function hsv2hsl(hsv) {\r
-               var h = hsv[0],\r
-                       s = hsv[1] / 100,\r
-                       v = hsv[2] / 100,\r
-                       sl, l;\r
-\r
-               l = (2 - s) * v;\r
-               sl = s * v;\r
-               sl /= (l <= 1) ? l : 2 - l;\r
-               sl = sl || 0;\r
-               l /= 2;\r
-               return [h, sl * 100, l * 100];\r
-       }\r
-\r
-       function hsv2hwb(args) {\r
-               return rgb2hwb(hsv2rgb(args))\r
-       }\r
-\r
-       function hsv2cmyk(args) {\r
-               return rgb2cmyk(hsv2rgb(args));\r
-       }\r
-\r
-       function hsv2keyword(args) {\r
-               return rgb2keyword(hsv2rgb(args));\r
-       }\r
-\r
-// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\r
-       function hwb2rgb(hwb) {\r
-               var h = hwb[0] / 360,\r
-                       wh = hwb[1] / 100,\r
-                       bl = hwb[2] / 100,\r
-                       ratio = wh + bl,\r
-                       i, v, f, n;\r
-\r
-               // wh + bl cant be > 1\r
-               if (ratio > 1) {\r
-                       wh /= ratio;\r
-                       bl /= ratio;\r
-               }\r
-\r
-               i = Math.floor(6 * h);\r
-               v = 1 - bl;\r
-               f = 6 * h - i;\r
-               if ((i & 0x01) != 0) {\r
-                       f = 1 - f;\r
-               }\r
-               n = wh + f * (v - wh);  // linear interpolation\r
-\r
-               switch (i) {\r
-                       default:\r
-                       case 6:\r
-                       case 0: r = v; g = n; b = wh; break;\r
-                       case 1: r = n; g = v; b = wh; break;\r
-                       case 2: r = wh; g = v; b = n; break;\r
-                       case 3: r = wh; g = n; b = v; break;\r
-                       case 4: r = n; g = wh; b = v; break;\r
-                       case 5: r = v; g = wh; b = n; break;\r
-               }\r
-\r
-               return [r * 255, g * 255, b * 255];\r
-       }\r
-\r
-       function hwb2hsl(args) {\r
-               return rgb2hsl(hwb2rgb(args));\r
-       }\r
-\r
-       function hwb2hsv(args) {\r
-               return rgb2hsv(hwb2rgb(args));\r
-       }\r
-\r
-       function hwb2cmyk(args) {\r
-               return rgb2cmyk(hwb2rgb(args));\r
-       }\r
-\r
-       function hwb2keyword(args) {\r
-               return rgb2keyword(hwb2rgb(args));\r
-       }\r
-\r
-       function cmyk2rgb(cmyk) {\r
-               var c = cmyk[0] / 100,\r
-                       m = cmyk[1] / 100,\r
-                       y = cmyk[2] / 100,\r
-                       k = cmyk[3] / 100,\r
-                       r, g, b;\r
-\r
-               r = 1 - Math.min(1, c * (1 - k) + k);\r
-               g = 1 - Math.min(1, m * (1 - k) + k);\r
-               b = 1 - Math.min(1, y * (1 - k) + k);\r
-               return [r * 255, g * 255, b * 255];\r
-       }\r
-\r
-       function cmyk2hsl(args) {\r
-               return rgb2hsl(cmyk2rgb(args));\r
-       }\r
-\r
-       function cmyk2hsv(args) {\r
-               return rgb2hsv(cmyk2rgb(args));\r
-       }\r
-\r
-       function cmyk2hwb(args) {\r
-               return rgb2hwb(cmyk2rgb(args));\r
-       }\r
-\r
-       function cmyk2keyword(args) {\r
-               return rgb2keyword(cmyk2rgb(args));\r
-       }\r
-\r
-\r
-       function xyz2rgb(xyz) {\r
-               var x = xyz[0] / 100,\r
-                       y = xyz[1] / 100,\r
-                       z = xyz[2] / 100,\r
-                       r, g, b;\r
-\r
-               r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\r
-               g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\r
-               b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\r
-\r
-               // assume sRGB\r
-               r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)\r
-                       : r = (r * 12.92);\r
-\r
-               g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)\r
-                       : g = (g * 12.92);\r
-\r
-               b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)\r
-                       : b = (b * 12.92);\r
-\r
-               r = Math.min(Math.max(0, r), 1);\r
-               g = Math.min(Math.max(0, g), 1);\r
-               b = Math.min(Math.max(0, b), 1);\r
-\r
-               return [r * 255, g * 255, b * 255];\r
-       }\r
-\r
-       function xyz2lab(xyz) {\r
-               var x = xyz[0],\r
-                       y = xyz[1],\r
-                       z = xyz[2],\r
-                       l, a, b;\r
-\r
-               x /= 95.047;\r
-               y /= 100;\r
-               z /= 108.883;\r
-\r
-               x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);\r
-               y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);\r
-               z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);\r
-\r
-               l = (116 * y) - 16;\r
-               a = 500 * (x - y);\r
-               b = 200 * (y - z);\r
-\r
-               return [l, a, b];\r
-       }\r
-\r
-       function xyz2lch(args) {\r
-               return lab2lch(xyz2lab(args));\r
-       }\r
-\r
-       function lab2xyz(lab) {\r
-               var l = lab[0],\r
-                       a = lab[1],\r
-                       b = lab[2],\r
-                       x, y, z, y2;\r
-\r
-               if (l <= 8) {\r
-                       y = (l * 100) / 903.3;\r
-                       y2 = (7.787 * (y / 100)) + (16 / 116);\r
-               } else {\r
-                       y = 100 * Math.pow((l + 16) / 116, 3);\r
-                       y2 = Math.pow(y / 100, 1/3);\r
-               }\r
-\r
-               x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);\r
-\r
-               z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);\r
-\r
-               return [x, y, z];\r
-       }\r
-\r
-       function lab2lch(lab) {\r
-               var l = lab[0],\r
-                       a = lab[1],\r
-                       b = lab[2],\r
-                       hr, h, c;\r
-\r
-               hr = Math.atan2(b, a);\r
-               h = hr * 360 / 2 / Math.PI;\r
-               if (h < 0) {\r
-                       h += 360;\r
-               }\r
-               c = Math.sqrt(a * a + b * b);\r
-               return [l, c, h];\r
-       }\r
-\r
-       function lab2rgb(args) {\r
-               return xyz2rgb(lab2xyz(args));\r
-       }\r
-\r
-       function lch2lab(lch) {\r
-               var l = lch[0],\r
-                       c = lch[1],\r
-                       h = lch[2],\r
-                       a, b, hr;\r
-\r
-               hr = h / 360 * 2 * Math.PI;\r
-               a = c * Math.cos(hr);\r
-               b = c * Math.sin(hr);\r
-               return [l, a, b];\r
-       }\r
-\r
-       function lch2xyz(args) {\r
-               return lab2xyz(lch2lab(args));\r
-       }\r
-\r
-       function lch2rgb(args) {\r
-               return lab2rgb(lch2lab(args));\r
-       }\r
-\r
-       function keyword2rgb(keyword) {\r
-               return cssKeywords[keyword];\r
-       }\r
-\r
-       function keyword2hsl(args) {\r
-               return rgb2hsl(keyword2rgb(args));\r
-       }\r
-\r
-       function keyword2hsv(args) {\r
-               return rgb2hsv(keyword2rgb(args));\r
-       }\r
-\r
-       function keyword2hwb(args) {\r
-               return rgb2hwb(keyword2rgb(args));\r
-       }\r
-\r
-       function keyword2cmyk(args) {\r
-               return rgb2cmyk(keyword2rgb(args));\r
-       }\r
-\r
-       function keyword2lab(args) {\r
-               return rgb2lab(keyword2rgb(args));\r
-       }\r
-\r
-       function keyword2xyz(args) {\r
-               return rgb2xyz(keyword2rgb(args));\r
-       }\r
-\r
-       var cssKeywords = {\r
-               aliceblue:  [240,248,255],\r
-               antiquewhite: [250,235,215],\r
-               aqua: [0,255,255],\r
-               aquamarine: [127,255,212],\r
-               azure:  [240,255,255],\r
-               beige:  [245,245,220],\r
-               bisque: [255,228,196],\r
-               black:  [0,0,0],\r
-               blanchedalmond: [255,235,205],\r
-               blue: [0,0,255],\r
-               blueviolet: [138,43,226],\r
-               brown:  [165,42,42],\r
-               burlywood:  [222,184,135],\r
-               cadetblue:  [95,158,160],\r
-               chartreuse: [127,255,0],\r
-               chocolate:  [210,105,30],\r
-               coral:  [255,127,80],\r
-               cornflowerblue: [100,149,237],\r
-               cornsilk: [255,248,220],\r
-               crimson:  [220,20,60],\r
-               cyan: [0,255,255],\r
-               darkblue: [0,0,139],\r
-               darkcyan: [0,139,139],\r
-               darkgoldenrod:  [184,134,11],\r
-               darkgray: [169,169,169],\r
-               darkgreen:  [0,100,0],\r
-               darkgrey: [169,169,169],\r
-               darkkhaki:  [189,183,107],\r
-               darkmagenta:  [139,0,139],\r
-               darkolivegreen: [85,107,47],\r
-               darkorange: [255,140,0],\r
-               darkorchid: [153,50,204],\r
-               darkred:  [139,0,0],\r
-               darksalmon: [233,150,122],\r
-               darkseagreen: [143,188,143],\r
-               darkslateblue:  [72,61,139],\r
-               darkslategray:  [47,79,79],\r
-               darkslategrey:  [47,79,79],\r
-               darkturquoise:  [0,206,209],\r
-               darkviolet: [148,0,211],\r
-               deeppink: [255,20,147],\r
-               deepskyblue:  [0,191,255],\r
-               dimgray:  [105,105,105],\r
-               dimgrey:  [105,105,105],\r
-               dodgerblue: [30,144,255],\r
-               firebrick:  [178,34,34],\r
-               floralwhite:  [255,250,240],\r
-               forestgreen:  [34,139,34],\r
-               fuchsia:  [255,0,255],\r
-               gainsboro:  [220,220,220],\r
-               ghostwhite: [248,248,255],\r
-               gold: [255,215,0],\r
-               goldenrod:  [218,165,32],\r
-               gray: [128,128,128],\r
-               green:  [0,128,0],\r
-               greenyellow:  [173,255,47],\r
-               grey: [128,128,128],\r
-               honeydew: [240,255,240],\r
-               hotpink:  [255,105,180],\r
-               indianred:  [205,92,92],\r
-               indigo: [75,0,130],\r
-               ivory:  [255,255,240],\r
-               khaki:  [240,230,140],\r
-               lavender: [230,230,250],\r
-               lavenderblush:  [255,240,245],\r
-               lawngreen:  [124,252,0],\r
-               lemonchiffon: [255,250,205],\r
-               lightblue:  [173,216,230],\r
-               lightcoral: [240,128,128],\r
-               lightcyan:  [224,255,255],\r
-               lightgoldenrodyellow: [250,250,210],\r
-               lightgray:  [211,211,211],\r
-               lightgreen: [144,238,144],\r
-               lightgrey:  [211,211,211],\r
-               lightpink:  [255,182,193],\r
-               lightsalmon:  [255,160,122],\r
-               lightseagreen:  [32,178,170],\r
-               lightskyblue: [135,206,250],\r
-               lightslategray: [119,136,153],\r
-               lightslategrey: [119,136,153],\r
-               lightsteelblue: [176,196,222],\r
-               lightyellow:  [255,255,224],\r
-               lime: [0,255,0],\r
-               limegreen:  [50,205,50],\r
-               linen:  [250,240,230],\r
-               magenta:  [255,0,255],\r
-               maroon: [128,0,0],\r
-               mediumaquamarine: [102,205,170],\r
-               mediumblue: [0,0,205],\r
-               mediumorchid: [186,85,211],\r
-               mediumpurple: [147,112,219],\r
-               mediumseagreen: [60,179,113],\r
-               mediumslateblue:  [123,104,238],\r
-               mediumspringgreen:  [0,250,154],\r
-               mediumturquoise:  [72,209,204],\r
-               mediumvioletred:  [199,21,133],\r
-               midnightblue: [25,25,112],\r
-               mintcream:  [245,255,250],\r
-               mistyrose:  [255,228,225],\r
-               moccasin: [255,228,181],\r
-               navajowhite:  [255,222,173],\r
-               navy: [0,0,128],\r
-               oldlace:  [253,245,230],\r
-               olive:  [128,128,0],\r
-               olivedrab:  [107,142,35],\r
-               orange: [255,165,0],\r
-               orangered:  [255,69,0],\r
-               orchid: [218,112,214],\r
-               palegoldenrod:  [238,232,170],\r
-               palegreen:  [152,251,152],\r
-               paleturquoise:  [175,238,238],\r
-               palevioletred:  [219,112,147],\r
-               papayawhip: [255,239,213],\r
-               peachpuff:  [255,218,185],\r
-               peru: [205,133,63],\r
-               pink: [255,192,203],\r
-               plum: [221,160,221],\r
-               powderblue: [176,224,230],\r
-               purple: [128,0,128],\r
-               rebeccapurple: [102, 51, 153],\r
-               red:  [255,0,0],\r
-               rosybrown:  [188,143,143],\r
-               royalblue:  [65,105,225],\r
-               saddlebrown:  [139,69,19],\r
-               salmon: [250,128,114],\r
-               sandybrown: [244,164,96],\r
-               seagreen: [46,139,87],\r
-               seashell: [255,245,238],\r
-               sienna: [160,82,45],\r
-               silver: [192,192,192],\r
-               skyblue:  [135,206,235],\r
-               slateblue:  [106,90,205],\r
-               slategray:  [112,128,144],\r
-               slategrey:  [112,128,144],\r
-               snow: [255,250,250],\r
-               springgreen:  [0,255,127],\r
-               steelblue:  [70,130,180],\r
-               tan:  [210,180,140],\r
-               teal: [0,128,128],\r
-               thistle:  [216,191,216],\r
-               tomato: [255,99,71],\r
-               turquoise:  [64,224,208],\r
-               violet: [238,130,238],\r
-               wheat:  [245,222,179],\r
-               white:  [255,255,255],\r
-               whitesmoke: [245,245,245],\r
-               yellow: [255,255,0],\r
-               yellowgreen:  [154,205,50]\r
-       };\r
-\r
-       var reverseKeywords = {};\r
-       for (var key in cssKeywords) {\r
-               reverseKeywords[JSON.stringify(cssKeywords[key])] = key;\r
-       }\r
-\r
-},{}],5:[function(require,module,exports){\r
-       var conversions = require(4);\r
-\r
-       var convert = function() {\r
-               return new Converter();\r
-       }\r
-\r
-       for (var func in conversions) {\r
-               // export Raw versions\r
-               convert[func + "Raw"] =  (function(func) {\r
-                       // accept array or plain args\r
-                       return function(arg) {\r
-                               if (typeof arg == "number")\r
-                                       arg = Array.prototype.slice.call(arguments);\r
-                               return conversions[func](arg);\r
-                       }\r
-               })(func);\r
-\r
-               var pair = /(\w+)2(\w+)/.exec(func),\r
-                       from = pair[1],\r
-                       to = pair[2];\r
-\r
-               // export rgb2hsl and ["rgb"]["hsl"]\r
-               convert[from] = convert[from] || {};\r
-\r
-               convert[from][to] = convert[func] = (function(func) {\r
-                       return function(arg) {\r
-                               if (typeof arg == "number")\r
-                                       arg = Array.prototype.slice.call(arguments);\r
-\r
-                               var val = conversions[func](arg);\r
-                               if (typeof val == "string" || val === undefined)\r
-                                       return val; // keyword\r
-\r
-                               for (var i = 0; i < val.length; i++)\r
-                                       val[i] = Math.round(val[i]);\r
-                               return val;\r
-                       }\r
-               })(func);\r
-       }\r
-\r
-\r
-       /* Converter does lazy conversion and caching */\r
-       var Converter = function() {\r
-               this.convs = {};\r
-       };\r
-\r
-       /* Either get the values for a space or\r
-        set the values for a space, depending on args */\r
-       Converter.prototype.routeSpace = function(space, args) {\r
-               var values = args[0];\r
-               if (values === undefined) {\r
-                       // color.rgb()\r
-                       return this.getValues(space);\r
-               }\r
-               // color.rgb(10, 10, 10)\r
-               if (typeof values == "number") {\r
-                       values = Array.prototype.slice.call(args);\r
-               }\r
-\r
-               return this.setValues(space, values);\r
-       };\r
-\r
-       /* Set the values for a space, invalidating cache */\r
-       Converter.prototype.setValues = function(space, values) {\r
-               this.space = space;\r
-               this.convs = {};\r
-               this.convs[space] = values;\r
-               return this;\r
-       };\r
-\r
-       /* Get the values for a space. If there's already\r
-        a conversion for the space, fetch it, otherwise\r
-        compute it */\r
-       Converter.prototype.getValues = function(space) {\r
-               var vals = this.convs[space];\r
-               if (!vals) {\r
-                       var fspace = this.space,\r
-                               from = this.convs[fspace];\r
-                       vals = convert[fspace][space](from);\r
-\r
-                       this.convs[space] = vals;\r
-               }\r
-               return vals;\r
-       };\r
-\r
-       ["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {\r
-               Converter.prototype[space] = function(vals) {\r
-                       return this.routeSpace(space, arguments);\r
-               }\r
-       });\r
-\r
-       module.exports = convert;\r
-},{"4":4}],6:[function(require,module,exports){\r
-       module.exports = {\r
-               "aliceblue": [240, 248, 255],\r
-               "antiquewhite": [250, 235, 215],\r
-               "aqua": [0, 255, 255],\r
-               "aquamarine": [127, 255, 212],\r
-               "azure": [240, 255, 255],\r
-               "beige": [245, 245, 220],\r
-               "bisque": [255, 228, 196],\r
-               "black": [0, 0, 0],\r
-               "blanchedalmond": [255, 235, 205],\r
-               "blue": [0, 0, 255],\r
-               "blueviolet": [138, 43, 226],\r
-               "brown": [165, 42, 42],\r
-               "burlywood": [222, 184, 135],\r
-               "cadetblue": [95, 158, 160],\r
-               "chartreuse": [127, 255, 0],\r
-               "chocolate": [210, 105, 30],\r
-               "coral": [255, 127, 80],\r
-               "cornflowerblue": [100, 149, 237],\r
-               "cornsilk": [255, 248, 220],\r
-               "crimson": [220, 20, 60],\r
-               "cyan": [0, 255, 255],\r
-               "darkblue": [0, 0, 139],\r
-               "darkcyan": [0, 139, 139],\r
-               "darkgoldenrod": [184, 134, 11],\r
-               "darkgray": [169, 169, 169],\r
-               "darkgreen": [0, 100, 0],\r
-               "darkgrey": [169, 169, 169],\r
-               "darkkhaki": [189, 183, 107],\r
-               "darkmagenta": [139, 0, 139],\r
-               "darkolivegreen": [85, 107, 47],\r
-               "darkorange": [255, 140, 0],\r
-               "darkorchid": [153, 50, 204],\r
-               "darkred": [139, 0, 0],\r
-               "darksalmon": [233, 150, 122],\r
-               "darkseagreen": [143, 188, 143],\r
-               "darkslateblue": [72, 61, 139],\r
-               "darkslategray": [47, 79, 79],\r
-               "darkslategrey": [47, 79, 79],\r
-               "darkturquoise": [0, 206, 209],\r
-               "darkviolet": [148, 0, 211],\r
-               "deeppink": [255, 20, 147],\r
-               "deepskyblue": [0, 191, 255],\r
-               "dimgray": [105, 105, 105],\r
-               "dimgrey": [105, 105, 105],\r
-               "dodgerblue": [30, 144, 255],\r
-               "firebrick": [178, 34, 34],\r
-               "floralwhite": [255, 250, 240],\r
-               "forestgreen": [34, 139, 34],\r
-               "fuchsia": [255, 0, 255],\r
-               "gainsboro": [220, 220, 220],\r
-               "ghostwhite": [248, 248, 255],\r
-               "gold": [255, 215, 0],\r
-               "goldenrod": [218, 165, 32],\r
-               "gray": [128, 128, 128],\r
-               "green": [0, 128, 0],\r
-               "greenyellow": [173, 255, 47],\r
-               "grey": [128, 128, 128],\r
-               "honeydew": [240, 255, 240],\r
-               "hotpink": [255, 105, 180],\r
-               "indianred": [205, 92, 92],\r
-               "indigo": [75, 0, 130],\r
-               "ivory": [255, 255, 240],\r
-               "khaki": [240, 230, 140],\r
-               "lavender": [230, 230, 250],\r
-               "lavenderblush": [255, 240, 245],\r
-               "lawngreen": [124, 252, 0],\r
-               "lemonchiffon": [255, 250, 205],\r
-               "lightblue": [173, 216, 230],\r
-               "lightcoral": [240, 128, 128],\r
-               "lightcyan": [224, 255, 255],\r
-               "lightgoldenrodyellow": [250, 250, 210],\r
-               "lightgray": [211, 211, 211],\r
-               "lightgreen": [144, 238, 144],\r
-               "lightgrey": [211, 211, 211],\r
-               "lightpink": [255, 182, 193],\r
-               "lightsalmon": [255, 160, 122],\r
-               "lightseagreen": [32, 178, 170],\r
-               "lightskyblue": [135, 206, 250],\r
-               "lightslategray": [119, 136, 153],\r
-               "lightslategrey": [119, 136, 153],\r
-               "lightsteelblue": [176, 196, 222],\r
-               "lightyellow": [255, 255, 224],\r
-               "lime": [0, 255, 0],\r
-               "limegreen": [50, 205, 50],\r
-               "linen": [250, 240, 230],\r
-               "magenta": [255, 0, 255],\r
-               "maroon": [128, 0, 0],\r
-               "mediumaquamarine": [102, 205, 170],\r
-               "mediumblue": [0, 0, 205],\r
-               "mediumorchid": [186, 85, 211],\r
-               "mediumpurple": [147, 112, 219],\r
-               "mediumseagreen": [60, 179, 113],\r
-               "mediumslateblue": [123, 104, 238],\r
-               "mediumspringgreen": [0, 250, 154],\r
-               "mediumturquoise": [72, 209, 204],\r
-               "mediumvioletred": [199, 21, 133],\r
-               "midnightblue": [25, 25, 112],\r
-               "mintcream": [245, 255, 250],\r
-               "mistyrose": [255, 228, 225],\r
-               "moccasin": [255, 228, 181],\r
-               "navajowhite": [255, 222, 173],\r
-               "navy": [0, 0, 128],\r
-               "oldlace": [253, 245, 230],\r
-               "olive": [128, 128, 0],\r
-               "olivedrab": [107, 142, 35],\r
-               "orange": [255, 165, 0],\r
-               "orangered": [255, 69, 0],\r
-               "orchid": [218, 112, 214],\r
-               "palegoldenrod": [238, 232, 170],\r
-               "palegreen": [152, 251, 152],\r
-               "paleturquoise": [175, 238, 238],\r
-               "palevioletred": [219, 112, 147],\r
-               "papayawhip": [255, 239, 213],\r
-               "peachpuff": [255, 218, 185],\r
-               "peru": [205, 133, 63],\r
-               "pink": [255, 192, 203],\r
-               "plum": [221, 160, 221],\r
-               "powderblue": [176, 224, 230],\r
-               "purple": [128, 0, 128],\r
-               "rebeccapurple": [102, 51, 153],\r
-               "red": [255, 0, 0],\r
-               "rosybrown": [188, 143, 143],\r
-               "royalblue": [65, 105, 225],\r
-               "saddlebrown": [139, 69, 19],\r
-               "salmon": [250, 128, 114],\r
-               "sandybrown": [244, 164, 96],\r
-               "seagreen": [46, 139, 87],\r
-               "seashell": [255, 245, 238],\r
-               "sienna": [160, 82, 45],\r
-               "silver": [192, 192, 192],\r
-               "skyblue": [135, 206, 235],\r
-               "slateblue": [106, 90, 205],\r
-               "slategray": [112, 128, 144],\r
-               "slategrey": [112, 128, 144],\r
-               "snow": [255, 250, 250],\r
-               "springgreen": [0, 255, 127],\r
-               "steelblue": [70, 130, 180],\r
-               "tan": [210, 180, 140],\r
-               "teal": [0, 128, 128],\r
-               "thistle": [216, 191, 216],\r
-               "tomato": [255, 99, 71],\r
-               "turquoise": [64, 224, 208],\r
-               "violet": [238, 130, 238],\r
-               "wheat": [245, 222, 179],\r
-               "white": [255, 255, 255],\r
-               "whitesmoke": [245, 245, 245],\r
-               "yellow": [255, 255, 0],\r
-               "yellowgreen": [154, 205, 50]\r
-       };\r
-},{}],7:[function(require,module,exports){\r
-       /**\r
-        * @namespace Chart\r
-        */\r
-       var Chart = require(27)();\r
-\r
-       require(26)(Chart);\r
-       require(22)(Chart);\r
-       require(25)(Chart);\r
-       require(21)(Chart);\r
-       require(23)(Chart);\r
-       require(24)(Chart);\r
-       require(28)(Chart);\r
-       require(32)(Chart);\r
-       require(30)(Chart);\r
-       require(31)(Chart);\r
-       require(33)(Chart);\r
-       require(29)(Chart);\r
-       require(34)(Chart);\r
-\r
-       require(35)(Chart);\r
-       require(36)(Chart);\r
-       require(37)(Chart);\r
-       require(38)(Chart);\r
-\r
-       require(41)(Chart);\r
-       require(39)(Chart);\r
-       require(40)(Chart);\r
-       require(42)(Chart);\r
-       require(43)(Chart);\r
-       require(44)(Chart);\r
-\r
-// Controllers must be loaded after elements\r
-// See Chart.core.datasetController.dataElementType\r
-       require(15)(Chart);\r
-       require(16)(Chart);\r
-       require(17)(Chart);\r
-       require(18)(Chart);\r
-       require(19)(Chart);\r
-       require(20)(Chart);\r
-\r
-       require(8)(Chart);\r
-       require(9)(Chart);\r
-       require(10)(Chart);\r
-       require(11)(Chart);\r
-       require(12)(Chart);\r
-       require(13)(Chart);\r
-       require(14)(Chart);\r
-\r
-       window.Chart = module.exports = Chart;\r
-\r
-},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"44":44,"8":8,"9":9}],8:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               Chart.Bar = function(context, config) {\r
-                       config.type = 'bar';\r
-\r
-                       return new Chart(context, config);\r
-               };\r
-\r
-       };\r
-},{}],9:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               Chart.Bubble = function(context, config) {\r
-                       config.type = 'bubble';\r
-                       return new Chart(context, config);\r
-               };\r
-\r
-       };\r
-},{}],10:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               Chart.Doughnut = function(context, config) {\r
-                       config.type = 'doughnut';\r
-\r
-                       return new Chart(context, config);\r
-               };\r
-\r
-       };\r
-},{}],11:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               Chart.Line = function(context, config) {\r
-                       config.type = 'line';\r
-\r
-                       return new Chart(context, config);\r
-               };\r
-\r
-       };\r
-},{}],12:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               Chart.PolarArea = function(context, config) {\r
-                       config.type = 'polarArea';\r
-\r
-                       return new Chart(context, config);\r
-               };\r
-\r
-       };\r
-},{}],13:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               Chart.Radar = function(context, config) {\r
-                       config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options);\r
-                       config.type = 'radar';\r
-\r
-                       return new Chart(context, config);\r
-               };\r
-\r
-       };\r
-\r
-},{}],14:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var defaultConfig = {\r
-                       hover: {\r
-                               mode: 'single'\r
-                       },\r
-\r
-                       scales: {\r
-                               xAxes: [{\r
-                                       type: "linear", // scatter should not use a category axis\r
-                                       position: "bottom",\r
-                                       id: "x-axis-1" // need an ID so datasets can reference the scale\r
-                               }],\r
-                               yAxes: [{\r
-                                       type: "linear",\r
-                                       position: "left",\r
-                                       id: "y-axis-1"\r
-                               }]\r
-                       },\r
-\r
-                       tooltips: {\r
-                               callbacks: {\r
-                                       title: function() {\r
-                                               // Title doesn't make sense for scatter since we format the data as a point\r
-                                               return '';\r
-                                       },\r
-                                       label: function(tooltipItem) {\r
-                                               return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';\r
-                                       }\r
-                               }\r
-                       }\r
-               };\r
-\r
-               // Register the default config for this type\r
-               Chart.defaults.scatter = defaultConfig;\r
-\r
-               // Scatter charts use line controllers\r
-               Chart.controllers.scatter = Chart.controllers.line;\r
-\r
-               Chart.Scatter = function(context, config) {\r
-                       config.type = 'scatter';\r
-                       return new Chart(context, config);\r
-               };\r
-\r
-       };\r
-},{}],15:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers;\r
-\r
-               Chart.defaults.bar = {\r
-                       hover: {\r
-                               mode: "label"\r
-                       },\r
-\r
-                       scales: {\r
-                               xAxes: [{\r
-                                       type: "category",\r
-\r
-                                       // Specific to Bar Controller\r
-                                       categoryPercentage: 0.8,\r
-                                       barPercentage: 0.9,\r
-\r
-                                       // grid line settings\r
-                                       gridLines: {\r
-                                               offsetGridLines: true\r
-                                       }\r
-                               }],\r
-                               yAxes: [{\r
-                                       type: "linear"\r
-                               }]\r
-                       }\r
-               };\r
-\r
-               Chart.controllers.bar = Chart.DatasetController.extend({\r
-\r
-                       dataElementType: Chart.elements.Rectangle,\r
-\r
-                       initialize: function(chart, datasetIndex) {\r
-                               Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);\r
-\r
-                               // Use this to indicate that this is a bar dataset.\r
-                               this.getMeta().bar = true;\r
-                       },\r
-\r
-                       // Get the number of datasets that display bars. We use this to correctly calculate the bar width\r
-                       getBarCount: function() {\r
-                               var me = this;\r
-                               var barCount = 0;\r
-                               helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {\r
-                                       var meta = me.chart.getDatasetMeta(datasetIndex);\r
-                                       if (meta.bar && me.chart.isDatasetVisible(datasetIndex)) {\r
-                                               ++barCount;\r
-                                       }\r
-                               }, me);\r
-                               return barCount;\r
-                       },\r
-\r
-                       update: function(reset) {\r
-                               var me = this;\r
-                               helpers.each(me.getMeta().data, function(rectangle, index) {\r
-                                       me.updateElement(rectangle, index, reset);\r
-                               }, me);\r
-                       },\r
-\r
-                       updateElement: function(rectangle, index, reset) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var scaleBase = yScale.getBasePixel();\r
-                               var rectangleElementOptions = me.chart.options.elements.rectangle;\r
-                               var custom = rectangle.custom || {};\r
-                               var dataset = me.getDataset();\r
-\r
-                               helpers.extend(rectangle, {\r
-                                       // Utility\r
-                                       _xScale: xScale,\r
-                                       _yScale: yScale,\r
-                                       _datasetIndex: me.index,\r
-                                       _index: index,\r
-\r
-                                       // Desired view properties\r
-                                       _model: {\r
-                                               x: me.calculateBarX(index, me.index),\r
-                                               y: reset ? scaleBase : me.calculateBarY(index, me.index),\r
-\r
-                                               // Tooltip\r
-                                               label: me.chart.data.labels[index],\r
-                                               datasetLabel: dataset.label,\r
-\r
-                                               // Appearance\r
-                                               base: reset ? scaleBase : me.calculateBarBase(me.index, index),\r
-                                               width: me.calculateBarWidth(index),\r
-                                               backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),\r
-                                               borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,\r
-                                               borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),\r
-                                               borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)\r
-                                       }\r
-                               });\r
-                               rectangle.pivot();\r
-                       },\r
-\r
-                       calculateBarBase: function(datasetIndex, index) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var base = 0;\r
-\r
-                               if (yScale.options.stacked) {\r
-                                       var chart = me.chart;\r
-                                       var datasets = chart.data.datasets;\r
-                                       var value = Number(datasets[datasetIndex].data[index]);\r
-\r
-                                       for (var i = 0; i < datasetIndex; i++) {\r
-                                               var currentDs = datasets[i];\r
-                                               var currentDsMeta = chart.getDatasetMeta(i);\r
-                                               if (currentDsMeta.bar && currentDsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\r
-                                                       var currentVal = Number(currentDs.data[index]);\r
-                                                       base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);\r
-                                               }\r
-                                       }\r
-\r
-                                       return yScale.getPixelForValue(base);\r
-                               }\r
-\r
-                               return yScale.getBasePixel();\r
-                       },\r
-\r
-                       getRuler: function(index) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var datasetCount = me.getBarCount();\r
-\r
-                               var tickWidth;\r
-\r
-                               if (xScale.options.type === 'category') {\r
-                                       tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index);\r
-                               } else {\r
-                                       // Average width\r
-                                       tickWidth = xScale.width / xScale.ticks.length;\r
-                               }\r
-                               var categoryWidth = tickWidth * xScale.options.categoryPercentage;\r
-                               var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;\r
-                               var fullBarWidth = categoryWidth / datasetCount;\r
-\r
-                               if (xScale.ticks.length !== me.chart.data.labels.length) {\r
-                                       var perc = xScale.ticks.length / me.chart.data.labels.length;\r
-                                       fullBarWidth = fullBarWidth * perc;\r
-                               }\r
-\r
-                               var barWidth = fullBarWidth * xScale.options.barPercentage;\r
-                               var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);\r
-\r
-                               return {\r
-                                       datasetCount: datasetCount,\r
-                                       tickWidth: tickWidth,\r
-                                       categoryWidth: categoryWidth,\r
-                                       categorySpacing: categorySpacing,\r
-                                       fullBarWidth: fullBarWidth,\r
-                                       barWidth: barWidth,\r
-                                       barSpacing: barSpacing\r
-                               };\r
-                       },\r
-\r
-                       calculateBarWidth: function(index) {\r
-                               var xScale = this.getScaleForId(this.getMeta().xAxisID);\r
-                               if (xScale.options.barThickness) {\r
-                                       return xScale.options.barThickness;\r
-                               }\r
-                               var ruler = this.getRuler(index);\r
-                               return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;\r
-                       },\r
-\r
-                       // Get bar index from the given dataset index accounting for the fact that not all bars are visible\r
-                       getBarIndex: function(datasetIndex) {\r
-                               var barIndex = 0;\r
-                               var meta, j;\r
-\r
-                               for (j = 0; j < datasetIndex; ++j) {\r
-                                       meta = this.chart.getDatasetMeta(j);\r
-                                       if (meta.bar && this.chart.isDatasetVisible(j)) {\r
-                                               ++barIndex;\r
-                                       }\r
-                               }\r
-\r
-                               return barIndex;\r
-                       },\r
-\r
-                       calculateBarX: function(index, datasetIndex) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var barIndex = me.getBarIndex(datasetIndex);\r
-\r
-                               var ruler = me.getRuler(index);\r
-                               var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);\r
-                               leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0;\r
-\r
-                               if (xScale.options.stacked) {\r
-                                       return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;\r
-                               }\r
-\r
-                               return leftTick +\r
-                                       (ruler.barWidth / 2) +\r
-                                       ruler.categorySpacing +\r
-                                       (ruler.barWidth * barIndex) +\r
-                                       (ruler.barSpacing / 2) +\r
-                                       (ruler.barSpacing * barIndex);\r
-                       },\r
-\r
-                       calculateBarY: function(index, datasetIndex) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var value = Number(me.getDataset().data[index]);\r
-\r
-                               if (yScale.options.stacked) {\r
-\r
-                                       var sumPos = 0,\r
-                                               sumNeg = 0;\r
-\r
-                                       for (var i = 0; i < datasetIndex; i++) {\r
-                                               var ds = me.chart.data.datasets[i];\r
-                                               var dsMeta = me.chart.getDatasetMeta(i);\r
-                                               if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) {\r
-                                                       var stackedVal = Number(ds.data[index]);\r
-                                                       if (stackedVal < 0) {\r
-                                                               sumNeg += stackedVal || 0;\r
-                                                       } else {\r
-                                                               sumPos += stackedVal || 0;\r
-                                                       }\r
-                                               }\r
-                                       }\r
-\r
-                                       if (value < 0) {\r
-                                               return yScale.getPixelForValue(sumNeg + value);\r
-                                       } else {\r
-                                               return yScale.getPixelForValue(sumPos + value);\r
-                                       }\r
-                               }\r
-\r
-                               return yScale.getPixelForValue(value);\r
-                       },\r
-\r
-                       draw: function(ease) {\r
-                               var me = this;\r
-                               var easingDecimal = ease || 1;\r
-                               helpers.each(me.getMeta().data, function(rectangle, index) {\r
-                                       var d = me.getDataset().data[index];\r
-                                       if (d !== null && d !== undefined && !isNaN(d)) {\r
-                                               rectangle.transition(easingDecimal).draw();\r
-                                       }\r
-                               }, me);\r
-                       },\r
-\r
-                       setHoverStyle: function(rectangle) {\r
-                               var dataset = this.chart.data.datasets[rectangle._datasetIndex];\r
-                               var index = rectangle._index;\r
-\r
-                               var custom = rectangle.custom || {};\r
-                               var model = rectangle._model;\r
-                               model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
-                               model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
-                               model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\r
-                       },\r
-\r
-                       removeHoverStyle: function(rectangle) {\r
-                               var dataset = this.chart.data.datasets[rectangle._datasetIndex];\r
-                               var index = rectangle._index;\r
-                               var custom = rectangle.custom || {};\r
-                               var model = rectangle._model;\r
-                               var rectangleElementOptions = this.chart.options.elements.rectangle;\r
-\r
-                               model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);\r
-                               model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);\r
-                               model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);\r
-                       }\r
-\r
-               });\r
-\r
-\r
-               // including horizontalBar in the bar file, instead of a file of its own\r
-               // it extends bar (like pie extends doughnut)\r
-               Chart.defaults.horizontalBar = {\r
-                       hover: {\r
-                               mode: "label"\r
-                       },\r
-\r
-                       scales: {\r
-                               xAxes: [{\r
-                                       type: "linear",\r
-                                       position: "bottom"\r
-                               }],\r
-                               yAxes: [{\r
-                                       position: "left",\r
-                                       type: "category",\r
-\r
-                                       // Specific to Horizontal Bar Controller\r
-                                       categoryPercentage: 0.8,\r
-                                       barPercentage: 0.9,\r
-\r
-                                       // grid line settings\r
-                                       gridLines: {\r
-                                               offsetGridLines: true\r
-                                       }\r
-                               }]\r
-                       },\r
-                       elements: {\r
-                               rectangle: {\r
-                                       borderSkipped: 'left'\r
-                               }\r
-                       },\r
-                       tooltips: {\r
-                               callbacks: {\r
-                                       title: function(tooltipItems, data) {\r
-                                               // Pick first xLabel for now\r
-                                               var title = '';\r
-\r
-                                               if (tooltipItems.length > 0) {\r
-                                                       if (tooltipItems[0].yLabel) {\r
-                                                               title = tooltipItems[0].yLabel;\r
-                                                       } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {\r
-                                                               title = data.labels[tooltipItems[0].index];\r
-                                                       }\r
-                                               }\r
-\r
-                                               return title;\r
-                                       },\r
-                                       label: function(tooltipItem, data) {\r
-                                               var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
-                                               return datasetLabel + ': ' + tooltipItem.xLabel;\r
-                                       }\r
-                               }\r
-                       }\r
-               };\r
-\r
-               Chart.controllers.horizontalBar = Chart.controllers.bar.extend({\r
-                       updateElement: function(rectangle, index, reset) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var scaleBase = xScale.getBasePixel();\r
-                               var custom = rectangle.custom || {};\r
-                               var dataset = me.getDataset();\r
-                               var rectangleElementOptions = me.chart.options.elements.rectangle;\r
-\r
-                               helpers.extend(rectangle, {\r
-                                       // Utility\r
-                                       _xScale: xScale,\r
-                                       _yScale: yScale,\r
-                                       _datasetIndex: me.index,\r
-                                       _index: index,\r
-\r
-                                       // Desired view properties\r
-                                       _model: {\r
-                                               x: reset ? scaleBase : me.calculateBarX(index, me.index),\r
-                                               y: me.calculateBarY(index, me.index),\r
-\r
-                                               // Tooltip\r
-                                               label: me.chart.data.labels[index],\r
-                                               datasetLabel: dataset.label,\r
-\r
-                                               // Appearance\r
-                                               base: reset ? scaleBase : me.calculateBarBase(me.index, index),\r
-                                               height: me.calculateBarHeight(index),\r
-                                               backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),\r
-                                               borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,\r
-                                               borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),\r
-                                               borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)\r
-                                       },\r
-\r
-                                       draw: function () {\r
-                                               var ctx = this._chart.ctx;\r
-                                               var vm = this._view;\r
-\r
-                                               var halfHeight = vm.height / 2,\r
-                                                       topY = vm.y - halfHeight,\r
-                                                       bottomY = vm.y + halfHeight,\r
-                                                       right = vm.base - (vm.base - vm.x),\r
-                                                       halfStroke = vm.borderWidth / 2;\r
-\r
-                                               // Canvas doesn't allow us to stroke inside the width so we can\r
-                                               // adjust the sizes to fit if we're setting a stroke on the line\r
-                                               if (vm.borderWidth) {\r
-                                                       topY += halfStroke;\r
-                                                       bottomY -= halfStroke;\r
-                                                       right += halfStroke;\r
-                                               }\r
-\r
-                                               ctx.beginPath();\r
-\r
-                                               ctx.fillStyle = vm.backgroundColor;\r
-                                               ctx.strokeStyle = vm.borderColor;\r
-                                               ctx.lineWidth = vm.borderWidth;\r
-\r
-                                               // Corner points, from bottom-left to bottom-right clockwise\r
-                                               // | 1 2 |\r
-                                               // | 0 3 |\r
-                                               var corners = [\r
-                                                       [vm.base, bottomY],\r
-                                                       [vm.base, topY],\r
-                                                       [right, topY],\r
-                                                       [right, bottomY]\r
-                                               ];\r
-\r
-                                               // Find first (starting) corner with fallback to 'bottom'\r
-                                               var borders = ['bottom', 'left', 'top', 'right'];\r
-                                               var startCorner = borders.indexOf(vm.borderSkipped, 0);\r
-                                               if (startCorner === -1)\r
-                                                       startCorner = 0;\r
-\r
-                                               function cornerAt(index) {\r
-                                                       return corners[(startCorner + index) % 4];\r
-                                               }\r
-\r
-                                               // Draw rectangle from 'startCorner'\r
-                                               ctx.moveTo.apply(ctx, cornerAt(0));\r
-                                               for (var i = 1; i < 4; i++)\r
-                                                       ctx.lineTo.apply(ctx, cornerAt(i));\r
-\r
-                                               ctx.fill();\r
-                                               if (vm.borderWidth) {\r
-                                                       ctx.stroke();\r
-                                               }\r
-                                       },\r
-\r
-                                       inRange: function (mouseX, mouseY) {\r
-                                               var vm = this._view;\r
-                                               var inRange = false;\r
-\r
-                                               if (vm) {\r
-                                                       if (vm.x < vm.base) {\r
-                                                               inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base);\r
-                                                       } else {\r
-                                                               inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x);\r
-                                                       }\r
-                                               }\r
-\r
-                                               return inRange;\r
-                                       }\r
-                               });\r
-\r
-                               rectangle.pivot();\r
-                       },\r
-\r
-                       calculateBarBase: function (datasetIndex, index) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var base = 0;\r
-\r
-                               if (xScale.options.stacked) {\r
-                                       var chart = me.chart;\r
-                                       var datasets = chart.data.datasets;\r
-                                       var value = Number(datasets[datasetIndex].data[index]);\r
-\r
-                                       for (var i = 0; i < datasetIndex; i++) {\r
-                                               var currentDs = datasets[i];\r
-                                               var currentDsMeta = chart.getDatasetMeta(i);\r
-                                               if (currentDsMeta.bar && currentDsMeta.xAxisID === xScale.id && chart.isDatasetVisible(i)) {\r
-                                                       var currentVal = Number(currentDs.data[index]);\r
-                                                       base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);\r
-                                               }\r
-                                       }\r
-\r
-                                       return xScale.getPixelForValue(base);\r
-                               }\r
-\r
-                               return xScale.getBasePixel();\r
-                       },\r
-\r
-                       getRuler: function (index) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var datasetCount = me.getBarCount();\r
-\r
-                               var tickHeight;\r
-                               if (yScale.options.type === 'category') {\r
-                                       tickHeight = yScale.getPixelForTick(index + 1) - yScale.getPixelForTick(index);\r
-                               } else {\r
-                                       // Average width\r
-                                       tickHeight = yScale.width / yScale.ticks.length;\r
-                               }\r
-                               var categoryHeight = tickHeight * yScale.options.categoryPercentage;\r
-                               var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2;\r
-                               var fullBarHeight = categoryHeight / datasetCount;\r
-\r
-                               if (yScale.ticks.length !== me.chart.data.labels.length) {\r
-                                       var perc = yScale.ticks.length / me.chart.data.labels.length;\r
-                                       fullBarHeight = fullBarHeight * perc;\r
-                               }\r
-\r
-                               var barHeight = fullBarHeight * yScale.options.barPercentage;\r
-                               var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage);\r
-\r
-                               return {\r
-                                       datasetCount: datasetCount,\r
-                                       tickHeight: tickHeight,\r
-                                       categoryHeight: categoryHeight,\r
-                                       categorySpacing: categorySpacing,\r
-                                       fullBarHeight: fullBarHeight,\r
-                                       barHeight: barHeight,\r
-                                       barSpacing: barSpacing\r
-                               };\r
-                       },\r
-\r
-                       calculateBarHeight: function (index) {\r
-                               var me = this;\r
-                               var yScale = me.getScaleForId(me.getMeta().yAxisID);\r
-                               if (yScale.options.barThickness) {\r
-                                       return yScale.options.barThickness;\r
-                               }\r
-                               var ruler = me.getRuler(index);\r
-                               return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;\r
-                       },\r
-\r
-                       calculateBarX: function (index, datasetIndex) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var value = Number(me.getDataset().data[index]);\r
-\r
-                               if (xScale.options.stacked) {\r
-\r
-                                       var sumPos = 0,\r
-                                               sumNeg = 0;\r
-\r
-                                       for (var i = 0; i < datasetIndex; i++) {\r
-                                               var ds = me.chart.data.datasets[i];\r
-                                               var dsMeta = me.chart.getDatasetMeta(i);\r
-                                               if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {\r
-                                                       var stackedVal = Number(ds.data[index]);\r
-                                                       if (stackedVal < 0) {\r
-                                                               sumNeg += stackedVal || 0;\r
-                                                       } else {\r
-                                                               sumPos += stackedVal || 0;\r
-                                                       }\r
-                                               }\r
-                                       }\r
-\r
-                                       if (value < 0) {\r
-                                               return xScale.getPixelForValue(sumNeg + value);\r
-                                       } else {\r
-                                               return xScale.getPixelForValue(sumPos + value);\r
-                                       }\r
-                               }\r
-\r
-                               return xScale.getPixelForValue(value);\r
-                       },\r
-\r
-                       calculateBarY: function (index, datasetIndex) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var barIndex = me.getBarIndex(datasetIndex);\r
-\r
-                               var ruler = me.getRuler(index);\r
-                               var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);\r
-                               topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;\r
-\r
-                               if (yScale.options.stacked) {\r
-                                       return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;\r
-                               }\r
-\r
-                               return topTick +\r
-                                       (ruler.barHeight / 2) +\r
-                                       ruler.categorySpacing +\r
-                                       (ruler.barHeight * barIndex) +\r
-                                       (ruler.barSpacing / 2) +\r
-                                       (ruler.barSpacing * barIndex);\r
-                       }\r
-               });\r
-       };\r
-\r
-},{}],16:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers;\r
-\r
-               Chart.defaults.bubble = {\r
-                       hover: {\r
-                               mode: "single"\r
-                       },\r
-\r
-                       scales: {\r
-                               xAxes: [{\r
-                                       type: "linear", // bubble should probably use a linear scale by default\r
-                                       position: "bottom",\r
-                                       id: "x-axis-0" // need an ID so datasets can reference the scale\r
-                               }],\r
-                               yAxes: [{\r
-                                       type: "linear",\r
-                                       position: "left",\r
-                                       id: "y-axis-0"\r
-                               }]\r
-                       },\r
-\r
-                       tooltips: {\r
-                               callbacks: {\r
-                                       title: function() {\r
-                                               // Title doesn't make sense for scatter since we format the data as a point\r
-                                               return '';\r
-                                       },\r
-                                       label: function(tooltipItem, data) {\r
-                                               var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\r
-                                               var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\r
-                                               return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')';\r
-                                       }\r
-                               }\r
-                       }\r
-               };\r
-\r
-               Chart.controllers.bubble = Chart.DatasetController.extend({\r
-\r
-                       dataElementType: Chart.elements.Point,\r
-\r
-                       update: function(reset) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var points = meta.data;\r
-\r
-                               // Update Points\r
-                               helpers.each(points, function(point, index) {\r
-                                       me.updateElement(point, index, reset);\r
-                               });\r
-                       },\r
-\r
-                       updateElement: function(point, index, reset) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-\r
-                               var custom = point.custom || {};\r
-                               var dataset = me.getDataset();\r
-                               var data = dataset.data[index];\r
-                               var pointElementOptions = me.chart.options.elements.point;\r
-                               var dsIndex = me.index;\r
-\r
-                               helpers.extend(point, {\r
-                                       // Utility\r
-                                       _xScale: xScale,\r
-                                       _yScale: yScale,\r
-                                       _datasetIndex: dsIndex,\r
-                                       _index: index,\r
-\r
-                                       // Desired view properties\r
-                                       _model: {\r
-                                               x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),\r
-                                               y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),\r
-                                               // Appearance\r
-                                               radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),\r
-\r
-                                               // Tooltip\r
-                                               hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\r
-                                       }\r
-                               });\r
-\r
-                               // Trick to reset the styles of the point\r
-                               Chart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);\r
-\r
-                               var model = point._model;\r
-                               model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));\r
-\r
-                               point.pivot();\r
-                       },\r
-\r
-                       getRadius: function(value) {\r
-                               return value.r || this.chart.options.elements.point.radius;\r
-                       },\r
-\r
-                       setHoverStyle: function(point) {\r
-                               var me = this;\r
-                               Chart.DatasetController.prototype.setHoverStyle.call(me, point);\r
-\r
-                               // Radius\r
-                               var dataset = me.chart.data.datasets[point._datasetIndex];\r
-                               var index = point._index;\r
-                               var custom = point.custom || {};\r
-                               var model = point._model;\r
-                               model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);\r
-                       },\r
-\r
-                       removeHoverStyle: function(point) {\r
-                               var me = this;\r
-                               Chart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);\r
-\r
-                               var dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];\r
-                               var custom = point.custom || {};\r
-                               var model = point._model;\r
-\r
-                               model.radius = custom.radius ? custom.radius : me.getRadius(dataVal);\r
-                       }\r
-               });\r
-       };\r
-\r
-},{}],17:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers,\r
-                       defaults = Chart.defaults;\r
-\r
-               defaults.doughnut = {\r
-                       animation: {\r
-                               //Boolean - Whether we animate the rotation of the Doughnut\r
-                               animateRotate: true,\r
-                               //Boolean - Whether we animate scaling the Doughnut from the centre\r
-                               animateScale: false\r
-                       },\r
-                       aspectRatio: 1,\r
-                       hover: {\r
-                               mode: 'single'\r
-                       },\r
-                       legendCallback: function(chart) {\r
-                               var text = [];\r
-                               text.push('<ul class="' + chart.id + '-legend">');\r
-\r
-                               var data = chart.data;\r
-                               var datasets = data.datasets;\r
-                               var labels = data.labels;\r
-\r
-                               if (datasets.length) {\r
-                                       for (var i = 0; i < datasets[0].data.length; ++i) {\r
-                                               text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');\r
-                                               if (labels[i]) {\r
-                                                       text.push(labels[i]);\r
-                                               }\r
-                                               text.push('</li>');\r
-                                       }\r
-                               }\r
-\r
-                               text.push('</ul>');\r
-                               return text.join("");\r
-                       },\r
-                       legend: {\r
-                               labels: {\r
-                                       generateLabels: function(chart) {\r
-                                               var data = chart.data;\r
-                                               if (data.labels.length && data.datasets.length) {\r
-                                                       return data.labels.map(function(label, i) {\r
-                                                               var meta = chart.getDatasetMeta(0);\r
-                                                               var ds = data.datasets[0];\r
-                                                               var arc = meta.data[i];\r
-                                                               var custom = arc && arc.custom || {};\r
-                                                               var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
-                                                               var arcOpts = chart.options.elements.arc;\r
-                                                               var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\r
-                                                               var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\r
-                                                               var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\r
-\r
-                                                               return {\r
-                                                                       text: label,\r
-                                                                       fillStyle: fill,\r
-                                                                       strokeStyle: stroke,\r
-                                                                       lineWidth: bw,\r
-                                                                       hidden: isNaN(ds.data[i]) || meta.data[i].hidden,\r
-\r
-                                                                       // Extra data used for toggling the correct item\r
-                                                                       index: i\r
-                                                               };\r
-                                                       });\r
-                                               } else {\r
-                                                       return [];\r
-                                               }\r
-                                       }\r
-                               },\r
-\r
-                               onClick: function(e, legendItem) {\r
-                                       var index = legendItem.index;\r
-                                       var chart = this.chart;\r
-                                       var i, ilen, meta;\r
-\r
-                                       for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r
-                                               meta = chart.getDatasetMeta(i);\r
-                                               meta.data[index].hidden = !meta.data[index].hidden;\r
-                                       }\r
-\r
-                                       chart.update();\r
-                               }\r
-                       },\r
-\r
-                       //The percentage of the chart that we cut out of the middle.\r
-                       cutoutPercentage: 50,\r
-\r
-                       //The rotation of the chart, where the first data arc begins.\r
-                       rotation: Math.PI * -0.5,\r
-\r
-                       //The total circumference of the chart.\r
-                       circumference: Math.PI * 2.0,\r
-\r
-                       // Need to override these to give a nice default\r
-                       tooltips: {\r
-                               callbacks: {\r
-                                       title: function() {\r
-                                               return '';\r
-                                       },\r
-                                       label: function(tooltipItem, data) {\r
-                                               return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\r
-                                       }\r
-                               }\r
-                       }\r
-               };\r
-\r
-               defaults.pie = helpers.clone(defaults.doughnut);\r
-               helpers.extend(defaults.pie, {\r
-                       cutoutPercentage: 0\r
-               });\r
-\r
-\r
-               Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({\r
-\r
-                       dataElementType: Chart.elements.Arc,\r
-\r
-                       linkScales: helpers.noop,\r
-\r
-                       // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\r
-                       getRingIndex: function(datasetIndex) {\r
-                               var ringIndex = 0;\r
-\r
-                               for (var j = 0; j < datasetIndex; ++j) {\r
-                                       if (this.chart.isDatasetVisible(j)) {\r
-                                               ++ringIndex;\r
-                                       }\r
-                               }\r
-\r
-                               return ringIndex;\r
-                       },\r
-\r
-                       update: function(reset) {\r
-                               var me = this;\r
-                               var chart = me.chart,\r
-                                       chartArea = chart.chartArea,\r
-                                       opts = chart.options,\r
-                                       arcOpts = opts.elements.arc,\r
-                                       availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,\r
-                                       availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,\r
-                                       minSize = Math.min(availableWidth, availableHeight),\r
-                                       offset = {\r
-                                               x: 0,\r
-                                               y: 0\r
-                                       },\r
-                                       meta = me.getMeta(),\r
-                                       cutoutPercentage = opts.cutoutPercentage,\r
-                                       circumference = opts.circumference;\r
-\r
-                               // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc\r
-                               if (circumference < Math.PI * 2.0) {\r
-                                       var startAngle = opts.rotation % (Math.PI * 2.0);\r
-                                       startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);\r
-                                       var endAngle = startAngle + circumference;\r
-                                       var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};\r
-                                       var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};\r
-                                       var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);\r
-                                       var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);\r
-                                       var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);\r
-                                       var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);\r
-                                       var cutout = cutoutPercentage / 100.0;\r
-                                       var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};\r
-                                       var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};\r
-                                       var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};\r
-                                       minSize = Math.min(availableWidth / size.width, availableHeight / size.height);\r
-                                       offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};\r
-                               }\r
-                               chart.borderWidth = me.getMaxBorderWidth(meta.data);\r
-\r
-                               chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);\r
-                               chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 1, 0);\r
-                               chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\r
-                               chart.offsetX = offset.x * chart.outerRadius;\r
-                               chart.offsetY = offset.y * chart.outerRadius;\r
-\r
-                               meta.total = me.calculateTotal();\r
-\r
-                               me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));\r
-                               me.innerRadius = me.outerRadius - chart.radiusLength;\r
-\r
-                               helpers.each(meta.data, function(arc, index) {\r
-                                       me.updateElement(arc, index, reset);\r
-                               });\r
-                       },\r
-\r
-                       updateElement: function(arc, index, reset) {\r
-                               var me = this;\r
-                               var chart = me.chart,\r
-                                       chartArea = chart.chartArea,\r
-                                       opts = chart.options,\r
-                                       animationOpts = opts.animation,\r
-                                       centerX = (chartArea.left + chartArea.right) / 2,\r
-                                       centerY = (chartArea.top + chartArea.bottom) / 2,\r
-                                       startAngle = opts.rotation, // non reset case handled later\r
-                                       endAngle = opts.rotation, // non reset case handled later\r
-                                       dataset = me.getDataset(),\r
-                                       circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),\r
-                                       innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,\r
-                                       outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,\r
-                                       valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
-\r
-                               helpers.extend(arc, {\r
-                                       // Utility\r
-                                       _datasetIndex: me.index,\r
-                                       _index: index,\r
-\r
-                                       // Desired view properties\r
-                                       _model: {\r
-                                               x: centerX + chart.offsetX,\r
-                                               y: centerY + chart.offsetY,\r
-                                               startAngle: startAngle,\r
-                                               endAngle: endAngle,\r
-                                               circumference: circumference,\r
-                                               outerRadius: outerRadius,\r
-                                               innerRadius: innerRadius,\r
-                                               label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\r
-                                       }\r
-                               });\r
-\r
-                               var model = arc._model;\r
-                               // Resets the visual styles\r
-                               this.removeHoverStyle(arc);\r
-\r
-                               // Set correct angles if not resetting\r
-                               if (!reset || !animationOpts.animateRotate) {\r
-                                       if (index === 0) {\r
-                                               model.startAngle = opts.rotation;\r
-                                       } else {\r
-                                               model.startAngle = me.getMeta().data[index - 1]._model.endAngle;\r
-                                       }\r
-\r
-                                       model.endAngle = model.startAngle + model.circumference;\r
-                               }\r
-\r
-                               arc.pivot();\r
-                       },\r
-\r
-                       removeHoverStyle: function(arc) {\r
-                               Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\r
-                       },\r
-\r
-                       calculateTotal: function() {\r
-                               var dataset = this.getDataset();\r
-                               var meta = this.getMeta();\r
-                               var total = 0;\r
-                               var value;\r
-\r
-                               helpers.each(meta.data, function(element, index) {\r
-                                       value = dataset.data[index];\r
-                                       if (!isNaN(value) && !element.hidden) {\r
-                                               total += Math.abs(value);\r
-                                       }\r
-                               });\r
-\r
-                               /*if (total === 0) {\r
-                                total = NaN;\r
-                                }*/\r
-\r
-                               return total;\r
-                       },\r
-\r
-                       calculateCircumference: function(value) {\r
-                               var total = this.getMeta().total;\r
-                               if (total > 0 && !isNaN(value)) {\r
-                                       return (Math.PI * 2.0) * (value / total);\r
-                               } else {\r
-                                       return 0;\r
-                               }\r
-                       },\r
-\r
-                       //gets the max border or hover width to properly scale pie charts\r
-                       getMaxBorderWidth: function (elements) {\r
-                               var max = 0,\r
-                                       index = this.index,\r
-                                       length = elements.length,\r
-                                       borderWidth,\r
-                                       hoverWidth;\r
-\r
-                               for (var i = 0; i < length; i++) {\r
-                                       borderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;\r
-                                       hoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;\r
-\r
-                                       max = borderWidth > max ? borderWidth : max;\r
-                                       max = hoverWidth > max ? hoverWidth : max;\r
-                               }\r
-                               return max;\r
-                       }\r
-               });\r
-       };\r
-\r
-},{}],18:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers;\r
-\r
-               Chart.defaults.line = {\r
-                       showLines: true,\r
-                       spanGaps: false,\r
-\r
-                       hover: {\r
-                               mode: "label"\r
-                       },\r
-\r
-                       scales: {\r
-                               xAxes: [{\r
-                                       type: "category",\r
-                                       id: 'x-axis-0'\r
-                               }],\r
-                               yAxes: [{\r
-                                       type: "linear",\r
-                                       id: 'y-axis-0'\r
-                               }]\r
-                       }\r
-               };\r
-\r
-               function lineEnabled(dataset, options) {\r
-                       return helpers.getValueOrDefault(dataset.showLine, options.showLines);\r
-               }\r
-\r
-               Chart.controllers.line = Chart.DatasetController.extend({\r
-\r
-                       datasetElementType: Chart.elements.Line,\r
-\r
-                       dataElementType: Chart.elements.Point,\r
-\r
-                       addElementAndReset: function(index) {\r
-                               var me = this;\r
-                               var options = me.chart.options;\r
-                               var meta = me.getMeta();\r
-\r
-                               Chart.DatasetController.prototype.addElementAndReset.call(me, index);\r
-\r
-                               // Make sure bezier control points are updated\r
-                               if (lineEnabled(me.getDataset(), options) && meta.dataset._model.tension !== 0) {\r
-                                       me.updateBezierControlPoints();\r
-                               }\r
-                       },\r
-\r
-                       update: function(reset) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var line = meta.dataset;\r
-                               var points = meta.data || [];\r
-                               var options = me.chart.options;\r
-                               var lineElementOptions = options.elements.line;\r
-                               var scale = me.getScaleForId(meta.yAxisID);\r
-                               var i, ilen, custom;\r
-                               var dataset = me.getDataset();\r
-                               var showLine = lineEnabled(dataset, options);\r
-\r
-                               // Update Line\r
-                               if (showLine) {\r
-                                       custom = line.custom || {};\r
-\r
-                                       // Compatibility: If the properties are defined with only the old name, use those values\r
-                                       if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\r
-                                               dataset.lineTension = dataset.tension;\r
-                                       }\r
-\r
-                                       // Utility\r
-                                       line._scale = scale;\r
-                                       line._datasetIndex = me.index;\r
-                                       // Data\r
-                                       line._children = points;\r
-                                       // Model\r
-                                       line._model = {\r
-                                               // Appearance\r
-                                               // The default behavior of lines is to break at null values, according\r
-                                               // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\r
-                                               // This option gives linse the ability to span gaps\r
-                                               spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,\r
-                                               tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\r
-                                               backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\r
-                                               borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\r
-                                               borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\r
-                                               borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\r
-                                               borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\r
-                                               borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\r
-                                               borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\r
-                                               fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\r
-                                               steppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),\r
-                                               cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.getValueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),\r
-                                               // Scale\r
-                                               scaleTop: scale.top,\r
-                                               scaleBottom: scale.bottom,\r
-                                               scaleZero: scale.getBasePixel()\r
-                                       };\r
-\r
-                                       line.pivot();\r
-                               }\r
-\r
-                               // Update Points\r
-                               for (i=0, ilen=points.length; i<ilen; ++i) {\r
-                                       me.updateElement(points[i], i, reset);\r
-                               }\r
-\r
-                               if (showLine && line._model.tension !== 0) {\r
-                                       me.updateBezierControlPoints();\r
-                               }\r
-\r
-                               // Now pivot the point for animation\r
-                               for (i=0, ilen=points.length; i<ilen; ++i) {\r
-                                       points[i].pivot();\r
-                               }\r
-                       },\r
-\r
-                       getPointBackgroundColor: function(point, index) {\r
-                               var backgroundColor = this.chart.options.elements.point.backgroundColor;\r
-                               var dataset = this.getDataset();\r
-                               var custom = point.custom || {};\r
-\r
-                               if (custom.backgroundColor) {\r
-                                       backgroundColor = custom.backgroundColor;\r
-                               } else if (dataset.pointBackgroundColor) {\r
-                                       backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);\r
-                               } else if (dataset.backgroundColor) {\r
-                                       backgroundColor = dataset.backgroundColor;\r
-                               }\r
-\r
-                               return backgroundColor;\r
-                       },\r
-\r
-                       getPointBorderColor: function(point, index) {\r
-                               var borderColor = this.chart.options.elements.point.borderColor;\r
-                               var dataset = this.getDataset();\r
-                               var custom = point.custom || {};\r
-\r
-                               if (custom.borderColor) {\r
-                                       borderColor = custom.borderColor;\r
-                               } else if (dataset.pointBorderColor) {\r
-                                       borderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);\r
-                               } else if (dataset.borderColor) {\r
-                                       borderColor = dataset.borderColor;\r
-                               }\r
-\r
-                               return borderColor;\r
-                       },\r
-\r
-                       getPointBorderWidth: function(point, index) {\r
-                               var borderWidth = this.chart.options.elements.point.borderWidth;\r
-                               var dataset = this.getDataset();\r
-                               var custom = point.custom || {};\r
-\r
-                               if (custom.borderWidth) {\r
-                                       borderWidth = custom.borderWidth;\r
-                               } else if (dataset.pointBorderWidth) {\r
-                                       borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);\r
-                               } else if (dataset.borderWidth) {\r
-                                       borderWidth = dataset.borderWidth;\r
-                               }\r
-\r
-                               return borderWidth;\r
-                       },\r
-\r
-                       updateElement: function(point, index, reset) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var custom = point.custom || {};\r
-                               var dataset = me.getDataset();\r
-                               var datasetIndex = me.index;\r
-                               var value = dataset.data[index];\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var xScale = me.getScaleForId(meta.xAxisID);\r
-                               var pointOptions = me.chart.options.elements.point;\r
-                               var x, y;\r
-                               var labels = me.chart.data.labels || [];\r
-                               var includeOffset = (labels.length === 1 || dataset.data.length === 1) || me.chart.isCombo;\r
-\r
-                               // Compatibility: If the properties are defined with only the old name, use those values\r
-                               if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\r
-                                       dataset.pointRadius = dataset.radius;\r
-                               }\r
-                               if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\r
-                                       dataset.pointHitRadius = dataset.hitRadius;\r
-                               }\r
-\r
-                               x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);\r
-                               y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);\r
-\r
-                               // Utility\r
-                               point._xScale = xScale;\r
-                               point._yScale = yScale;\r
-                               point._datasetIndex = datasetIndex;\r
-                               point._index = index;\r
-\r
-                               // Desired view properties\r
-                               point._model = {\r
-                                       x: x,\r
-                                       y: y,\r
-                                       skip: custom.skip || isNaN(x) || isNaN(y),\r
-                                       // Appearance\r
-                                       radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),\r
-                                       pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),\r
-                                       backgroundColor: me.getPointBackgroundColor(point, index),\r
-                                       borderColor: me.getPointBorderColor(point, index),\r
-                                       borderWidth: me.getPointBorderWidth(point, index),\r
-                                       tension: meta.dataset._model ? meta.dataset._model.tension : 0,\r
-                                       steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,\r
-                                       // Tooltip\r
-                                       hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)\r
-                               };\r
-                       },\r
-\r
-                       calculatePointY: function(value, index, datasetIndex) {\r
-                               var me = this;\r
-                               var chart = me.chart;\r
-                               var meta = me.getMeta();\r
-                               var yScale = me.getScaleForId(meta.yAxisID);\r
-                               var sumPos = 0;\r
-                               var sumNeg = 0;\r
-                               var i, ds, dsMeta;\r
-\r
-                               if (yScale.options.stacked) {\r
-                                       for (i = 0; i < datasetIndex; i++) {\r
-                                               ds = chart.data.datasets[i];\r
-                                               dsMeta = chart.getDatasetMeta(i);\r
-                                               if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\r
-                                                       var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));\r
-                                                       if (stackedRightValue < 0) {\r
-                                                               sumNeg += stackedRightValue || 0;\r
-                                                       } else {\r
-                                                               sumPos += stackedRightValue || 0;\r
-                                                       }\r
-                                               }\r
-                                       }\r
-\r
-                                       var rightValue = Number(yScale.getRightValue(value));\r
-                                       if (rightValue < 0) {\r
-                                               return yScale.getPixelForValue(sumNeg + rightValue);\r
-                                       } else {\r
-                                               return yScale.getPixelForValue(sumPos + rightValue);\r
-                                       }\r
-                               }\r
-\r
-                               return yScale.getPixelForValue(value);\r
-                       },\r
-\r
-                       updateBezierControlPoints: function() {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var area = me.chart.chartArea;\r
-\r
-                               // Only consider points that are drawn in case the spanGaps option is used\r
-                               var points = (meta.data || []);\r
-                               if (meta.dataset._model.spanGaps) points = points.filter(function(pt) { return !pt._model.skip; });\r
-                               var i, ilen, point, model, controlPoints;\r
-\r
-                               function capControlPoint(pt, min, max) {\r
-                                       return Math.max(Math.min(pt, max), min);\r
-                               }\r
-\r
-                               if (meta.dataset._model.cubicInterpolationMode == 'monotone') {\r
-                                       helpers.splineCurveMonotone(points);\r
-                               }\r
-                               else {\r
-                                       for (i = 0, ilen = points.length; i < ilen; ++i) {\r
-                                               point = points[i];\r
-                                               model = point._model;\r
-                                               controlPoints = helpers.splineCurve(\r
-                                                       helpers.previousItem(points, i)._model,\r
-                                                       model,\r
-                                                       helpers.nextItem(points, i)._model,\r
-                                                       meta.dataset._model.tension\r
-                                               );\r
-                                               model.controlPointPreviousX = controlPoints.previous.x;\r
-                                               model.controlPointPreviousY = controlPoints.previous.y;\r
-                                               model.controlPointNextX = controlPoints.next.x;\r
-                                               model.controlPointNextY = controlPoints.next.y;\r
-                                       }\r
-                               }\r
-\r
-                               if (me.chart.options.elements.line.capBezierPoints) {\r
-                                       for (i = 0, ilen = points.length; i < ilen; ++i) {\r
-                                               model = points[i]._model;\r
-                                               model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);\r
-                                               model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);\r
-                                               model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);\r
-                                               model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);\r
-                                       }\r
-                               }\r
-\r
-                       },\r
-\r
-                       draw: function(ease) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var points = meta.data || [];\r
-                               var easingDecimal = ease || 1;\r
-                               var i, ilen;\r
-\r
-                               // Transition Point Locations\r
-                               for (i=0, ilen=points.length; i<ilen; ++i) {\r
-                                       points[i].transition(easingDecimal);\r
-                               }\r
-\r
-                               // Transition and Draw the line\r
-                               if (lineEnabled(me.getDataset(), me.chart.options)) {\r
-                                       meta.dataset.transition(easingDecimal).draw();\r
-                               }\r
-\r
-                               // Draw the points\r
-                               for (i=0, ilen=points.length; i<ilen; ++i) {\r
-                                       points[i].draw();\r
-                               }\r
-                       },\r
-\r
-                       setHoverStyle: function(point) {\r
-                               // Point\r
-                               var dataset = this.chart.data.datasets[point._datasetIndex];\r
-                               var index = point._index;\r
-                               var custom = point.custom || {};\r
-                               var model = point._model;\r
-\r
-                               model.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\r
-                               model.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
-                               model.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
-                               model.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\r
-                       },\r
-\r
-                       removeHoverStyle: function(point) {\r
-                               var me = this;\r
-                               var dataset = me.chart.data.datasets[point._datasetIndex];\r
-                               var index = point._index;\r
-                               var custom = point.custom || {};\r
-                               var model = point._model;\r
-\r
-                               // Compatibility: If the properties are defined with only the old name, use those values\r
-                               if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\r
-                                       dataset.pointRadius = dataset.radius;\r
-                               }\r
-\r
-                               model.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);\r
-                               model.backgroundColor = me.getPointBackgroundColor(point, index);\r
-                               model.borderColor = me.getPointBorderColor(point, index);\r
-                               model.borderWidth = me.getPointBorderWidth(point, index);\r
-                       }\r
-               });\r
-       };\r
-\r
-},{}],19:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers;\r
-\r
-               Chart.defaults.polarArea = {\r
-\r
-                       scale: {\r
-                               type: "radialLinear",\r
-                               lineArc: true, // so that lines are circular\r
-                               ticks: {\r
-                                       beginAtZero: true\r
-                               }\r
-                       },\r
-\r
-                       //Boolean - Whether to animate the rotation of the chart\r
-                       animation: {\r
-                               animateRotate: true,\r
-                               animateScale: true\r
-                       },\r
-\r
-                       startAngle: -0.5 * Math.PI,\r
-                       aspectRatio: 1,\r
-                       legendCallback: function(chart) {\r
-                               var text = [];\r
-                               text.push('<ul class="' + chart.id + '-legend">');\r
-\r
-                               var data = chart.data;\r
-                               var datasets = data.datasets;\r
-                               var labels = data.labels;\r
-\r
-                               if (datasets.length) {\r
-                                       for (var i = 0; i < datasets[0].data.length; ++i) {\r
-                                               text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '">');\r
-                                               if (labels[i]) {\r
-                                                       text.push(labels[i]);\r
-                                               }\r
-                                               text.push('</span></li>');\r
-                                       }\r
-                               }\r
-\r
-                               text.push('</ul>');\r
-                               return text.join("");\r
-                       },\r
-                       legend: {\r
-                               labels: {\r
-                                       generateLabels: function(chart) {\r
-                                               var data = chart.data;\r
-                                               if (data.labels.length && data.datasets.length) {\r
-                                                       return data.labels.map(function(label, i) {\r
-                                                               var meta = chart.getDatasetMeta(0);\r
-                                                               var ds = data.datasets[0];\r
-                                                               var arc = meta.data[i];\r
-                                                               var custom = arc.custom || {};\r
-                                                               var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
-                                                               var arcOpts = chart.options.elements.arc;\r
-                                                               var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\r
-                                                               var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\r
-                                                               var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\r
-\r
-                                                               return {\r
-                                                                       text: label,\r
-                                                                       fillStyle: fill,\r
-                                                                       strokeStyle: stroke,\r
-                                                                       lineWidth: bw,\r
-                                                                       hidden: isNaN(ds.data[i]) || meta.data[i].hidden,\r
-\r
-                                                                       // Extra data used for toggling the correct item\r
-                                                                       index: i\r
-                                                               };\r
-                                                       });\r
-                                               } else {\r
-                                                       return [];\r
-                                               }\r
-                                       }\r
-                               },\r
-\r
-                               onClick: function(e, legendItem) {\r
-                                       var index = legendItem.index;\r
-                                       var chart = this.chart;\r
-                                       var i, ilen, meta;\r
-\r
-                                       for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r
-                                               meta = chart.getDatasetMeta(i);\r
-                                               meta.data[index].hidden = !meta.data[index].hidden;\r
-                                       }\r
-\r
-                                       chart.update();\r
-                               }\r
-                       },\r
-\r
-                       // Need to override these to give a nice default\r
-                       tooltips: {\r
-                               callbacks: {\r
-                                       title: function() {\r
-                                               return '';\r
-                                       },\r
-                                       label: function(tooltipItem, data) {\r
-                                               return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;\r
-                                       }\r
-                               }\r
-                       }\r
-               };\r
-\r
-               Chart.controllers.polarArea = Chart.DatasetController.extend({\r
-\r
-                       dataElementType: Chart.elements.Arc,\r
-\r
-                       linkScales: helpers.noop,\r
-\r
-                       update: function(reset) {\r
-                               var me = this;\r
-                               var chart = me.chart;\r
-                               var chartArea = chart.chartArea;\r
-                               var meta = me.getMeta();\r
-                               var opts = chart.options;\r
-                               var arcOpts = opts.elements.arc;\r
-                               var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\r
-                               chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);\r
-                               chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\r
-                               chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\r
-\r
-                               me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\r
-                               me.innerRadius = me.outerRadius - chart.radiusLength;\r
-\r
-                               meta.count = me.countVisibleElements();\r
-\r
-                               helpers.each(meta.data, function(arc, index) {\r
-                                       me.updateElement(arc, index, reset);\r
-                               });\r
-                       },\r
-\r
-                       updateElement: function(arc, index, reset) {\r
-                               var me = this;\r
-                               var chart = me.chart;\r
-                               var dataset = me.getDataset();\r
-                               var opts = chart.options;\r
-                               var animationOpts = opts.animation;\r
-                               var scale = chart.scale;\r
-                               var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\r
-                               var labels = chart.data.labels;\r
-\r
-                               var circumference = me.calculateCircumference(dataset.data[index]);\r
-                               var centerX = scale.xCenter;\r
-                               var centerY = scale.yCenter;\r
-\r
-                               // If there is NaN data before us, we need to calculate the starting angle correctly.\r
-                               // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data\r
-                               var visibleCount = 0;\r
-                               var meta = me.getMeta();\r
-                               for (var i = 0; i < index; ++i) {\r
-                                       if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {\r
-                                               ++visibleCount;\r
-                                       }\r
-                               }\r
-\r
-                               //var negHalfPI = -0.5 * Math.PI;\r
-                               var datasetStartAngle = opts.startAngle;\r
-                               var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r
-                               var startAngle = datasetStartAngle + (circumference * visibleCount);\r
-                               var endAngle = startAngle + (arc.hidden ? 0 : circumference);\r
-\r
-                               var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r
-\r
-                               helpers.extend(arc, {\r
-                                       // Utility\r
-                                       _datasetIndex: me.index,\r
-                                       _index: index,\r
-                                       _scale: scale,\r
-\r
-                                       // Desired view properties\r
-                                       _model: {\r
-                                               x: centerX,\r
-                                               y: centerY,\r
-                                               innerRadius: 0,\r
-                                               outerRadius: reset ? resetRadius : distance,\r
-                                               startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,\r
-                                               endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,\r
-                                               label: getValueAtIndexOrDefault(labels, index, labels[index])\r
-                                       }\r
-                               });\r
-\r
-                               // Apply border and fill style\r
-                               me.removeHoverStyle(arc);\r
-\r
-                               arc.pivot();\r
-                       },\r
-\r
-                       removeHoverStyle: function(arc) {\r
-                               Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\r
-                       },\r
-\r
-                       countVisibleElements: function() {\r
-                               var dataset = this.getDataset();\r
-                               var meta = this.getMeta();\r
-                               var count = 0;\r
-\r
-                               helpers.each(meta.data, function(element, index) {\r
-                                       if (!isNaN(dataset.data[index]) && !element.hidden) {\r
-                                               count++;\r
-                                       }\r
-                               });\r
-\r
-                               return count;\r
-                       },\r
-\r
-                       calculateCircumference: function(value) {\r
-                               var count = this.getMeta().count;\r
-                               if (count > 0 && !isNaN(value)) {\r
-                                       return (2 * Math.PI) / count;\r
-                               } else {\r
-                                       return 0;\r
-                               }\r
-                       }\r
-               });\r
-       };\r
-\r
-},{}],20:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers;\r
-\r
-               Chart.defaults.radar = {\r
-                       scale: {\r
-                               type: "radialLinear"\r
-                       },\r
-                       elements: {\r
-                               line: {\r
-                                       tension: 0 // no bezier in radar\r
-                               }\r
-                       }\r
-               };\r
-\r
-               Chart.controllers.radar = Chart.DatasetController.extend({\r
-\r
-                       datasetElementType: Chart.elements.Line,\r
-\r
-                       dataElementType: Chart.elements.Point,\r
-\r
-                       linkScales: helpers.noop,\r
-\r
-                       addElementAndReset: function(index) {\r
-                               Chart.DatasetController.prototype.addElementAndReset.call(this, index);\r
-\r
-                               // Make sure bezier control points are updated\r
-                               this.updateBezierControlPoints();\r
-                       },\r
-\r
-                       update: function(reset) {\r
-                               var me = this;\r
-                               var meta = me.getMeta();\r
-                               var line = meta.dataset;\r
-                               var points = meta.data;\r
-                               var custom = line.custom || {};\r
-                               var dataset = me.getDataset();\r
-                               var lineElementOptions = me.chart.options.elements.line;\r
-                               var scale = me.chart.scale;\r
-\r
-                               // Compatibility: If the properties are defined with only the old name, use those values\r
-                               if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\r
-                                       dataset.lineTension = dataset.tension;\r
-                               }\r
-\r
-                               helpers.extend(meta.dataset, {\r
-                                       // Utility\r
-                                       _datasetIndex: me.index,\r
-                                       // Data\r
-                                       _children: points,\r
-                                       _loop: true,\r
-                                       // Model\r
-                                       _model: {\r
-                                               // Appearance\r
-                                               tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\r
-                                               backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\r
-                                               borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\r
-                                               borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\r
-                                               fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\r
-                                               borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\r
-                                               borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\r
-                                               borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\r
-                                               borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\r
-\r
-                                               // Scale\r
-                                               scaleTop: scale.top,\r
-                                               scaleBottom: scale.bottom,\r
-                                               scaleZero: scale.getBasePosition()\r
-                                       }\r
-                               });\r
-\r
-                               meta.dataset.pivot();\r
-\r
-                               // Update Points\r
-                               helpers.each(points, function(point, index) {\r
-                                       me.updateElement(point, index, reset);\r
-                               }, me);\r
-\r
-\r
-                               // Update bezier control points\r
-                               me.updateBezierControlPoints();\r
-                       },\r
-                       updateElement: function(point, index, reset) {\r
-                               var me = this;\r
-                               var custom = point.custom || {};\r
-                               var dataset = me.getDataset();\r
-                               var scale = me.chart.scale;\r
-                               var pointElementOptions = me.chart.options.elements.point;\r
-                               var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\r
-\r
-                               helpers.extend(point, {\r
-                                       // Utility\r
-                                       _datasetIndex: me.index,\r
-                                       _index: index,\r
-                                       _scale: scale,\r
-\r
-                                       // Desired view properties\r
-                                       _model: {\r
-                                               x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales\r
-                                               y: reset ? scale.yCenter : pointPosition.y,\r
-\r
-                                               // Appearance\r
-                                               tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, me.chart.options.elements.line.tension),\r
-                                               radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),\r
-                                               backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),\r
-                                               borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),\r
-                                               borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),\r
-                                               pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),\r
-\r
-                                               // Tooltip\r
-                                               hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\r
-                                       }\r
-                               });\r
-\r
-                               point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));\r
-                       },\r
-                       updateBezierControlPoints: function() {\r
-                               var chartArea = this.chart.chartArea;\r
-                               var meta = this.getMeta();\r
-\r
-                               helpers.each(meta.data, function(point, index) {\r
-                                       var model = point._model;\r
-                                       var controlPoints = helpers.splineCurve(\r
-                                               helpers.previousItem(meta.data, index, true)._model,\r
-                                               model,\r
-                                               helpers.nextItem(meta.data, index, true)._model,\r
-                                               model.tension\r
-                                       );\r
-\r
-                                       // Prevent the bezier going outside of the bounds of the graph\r
-                                       model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);\r
-                                       model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);\r
-\r
-                                       model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);\r
-                                       model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);\r
-\r
-                                       // Now pivot the point for animation\r
-                                       point.pivot();\r
-                               });\r
-                       },\r
-\r
-                       draw: function(ease) {\r
-                               var meta = this.getMeta();\r
-                               var easingDecimal = ease || 1;\r
-\r
-                               // Transition Point Locations\r
-                               helpers.each(meta.data, function(point) {\r
-                                       point.transition(easingDecimal);\r
-                               });\r
-\r
-                               // Transition and Draw the line\r
-                               meta.dataset.transition(easingDecimal).draw();\r
-\r
-                               // Draw the points\r
-                               helpers.each(meta.data, function(point) {\r
-                                       point.draw();\r
-                               });\r
-                       },\r
-\r
-                       setHoverStyle: function(point) {\r
-                               // Point\r
-                               var dataset = this.chart.data.datasets[point._datasetIndex];\r
-                               var custom = point.custom || {};\r
-                               var index = point._index;\r
-                               var model = point._model;\r
-\r
-                               model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\r
-                               model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\r
-                               model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\r
-                               model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\r
-                       },\r
-\r
-                       removeHoverStyle: function(point) {\r
-                               var dataset = this.chart.data.datasets[point._datasetIndex];\r
-                               var custom = point.custom || {};\r
-                               var index = point._index;\r
-                               var model = point._model;\r
-                               var pointElementOptions = this.chart.options.elements.point;\r
-\r
-                               model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius);\r
-                               model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);\r
-                               model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);\r
-                               model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);\r
-                       }\r
-               });\r
-       };\r
-\r
-},{}],21:[function(require,module,exports){\r
-       /*global window: false */\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers;\r
-\r
-               Chart.defaults.global.animation = {\r
-                       duration: 1000,\r
-                       easing: "easeOutQuart",\r
-                       onProgress: helpers.noop,\r
-                       onComplete: helpers.noop\r
-               };\r
-\r
-               Chart.Animation = Chart.Element.extend({\r
-                       currentStep: null, // the current animation step\r
-                       numSteps: 60, // default number of steps\r
-                       easing: "", // the easing to use for this animation\r
-                       render: null, // render function used by the animation service\r
-\r
-                       onAnimationProgress: null, // user specified callback to fire on each step of the animation\r
-                       onAnimationComplete: null // user specified callback to fire when the animation finishes\r
-               });\r
-\r
-               Chart.animationService = {\r
-                       frameDuration: 17,\r
-                       animations: [],\r
-                       dropFrames: 0,\r
-                       request: null,\r
-                       addAnimation: function(chartInstance, animationObject, duration, lazy) {\r
-                               var me = this;\r
-\r
-                               if (!lazy) {\r
-                                       chartInstance.animating = true;\r
-                               }\r
-\r
-                               for (var index = 0; index < me.animations.length; ++index) {\r
-                                       if (me.animations[index].chartInstance === chartInstance) {\r
-                                               // replacing an in progress animation\r
-                                               me.animations[index].animationObject = animationObject;\r
-                                               return;\r
-                                       }\r
-                               }\r
-\r
-                               me.animations.push({\r
-                                       chartInstance: chartInstance,\r
-                                       animationObject: animationObject\r
-                               });\r
-\r
-                               // If there are no animations queued, manually kickstart a digest, for lack of a better word\r
-                               if (me.animations.length === 1) {\r
-                                       me.requestAnimationFrame();\r
-                               }\r
-                       },\r
-                       // Cancel the animation for a given chart instance\r
-                       cancelAnimation: function(chartInstance) {\r
-                               var index = helpers.findIndex(this.animations, function(animationWrapper) {\r
-                                       return animationWrapper.chartInstance === chartInstance;\r
-                               });\r
-\r
-                               if (index !== -1) {\r
-                                       this.animations.splice(index, 1);\r
-                                       chartInstance.animating = false;\r
-                               }\r
-                       },\r
-                       requestAnimationFrame: function() {\r
-                               var me = this;\r
-                               if (me.request === null) {\r
-                                       // Skip animation frame requests until the active one is executed.\r
-                                       // This can happen when processing mouse events, e.g. 'mousemove'\r
-                                       // and 'mouseout' events will trigger multiple renders.\r
-                                       me.request = helpers.requestAnimFrame.call(window, function() {\r
-                                               me.request = null;\r
-                                               me.startDigest();\r
-                                       });\r
-                               }\r
-                       },\r
-                       startDigest: function() {\r
-                               var me = this;\r
-\r
-                               var startTime = Date.now();\r
-                               var framesToDrop = 0;\r
-\r
-                               if (me.dropFrames > 1) {\r
-                                       framesToDrop = Math.floor(me.dropFrames);\r
-                                       me.dropFrames = me.dropFrames % 1;\r
-                               }\r
-\r
-                               var i = 0;\r
-                               while (i < me.animations.length) {\r
-                                       if (me.animations[i].animationObject.currentStep === null) {\r
-                                               me.animations[i].animationObject.currentStep = 0;\r
-                                       }\r
-\r
-                                       me.animations[i].animationObject.currentStep += 1 + framesToDrop;\r
-\r
-                                       if (me.animations[i].animationObject.currentStep > me.animations[i].animationObject.numSteps) {\r
-                                               me.animations[i].animationObject.currentStep = me.animations[i].animationObject.numSteps;\r
-                                       }\r
-\r
-                                       me.animations[i].animationObject.render(me.animations[i].chartInstance, me.animations[i].animationObject);\r
-                                       if (me.animations[i].animationObject.onAnimationProgress && me.animations[i].animationObject.onAnimationProgress.call) {\r
-                                               me.animations[i].animationObject.onAnimationProgress.call(me.animations[i].chartInstance, me.animations[i]);\r
-                                       }\r
-\r
-                                       if (me.animations[i].animationObject.currentStep === me.animations[i].animationObject.numSteps) {\r
-                                               if (me.animations[i].animationObject.onAnimationComplete && me.animations[i].animationObject.onAnimationComplete.call) {\r
-                                                       me.animations[i].animationObject.onAnimationComplete.call(me.animations[i].chartInstance, me.animations[i]);\r
-                                               }\r
-\r
-                                               // executed the last frame. Remove the animation.\r
-                                               me.animations[i].chartInstance.animating = false;\r
-\r
-                                               me.animations.splice(i, 1);\r
-                                       } else {\r
-                                               ++i;\r
-                                       }\r
-                               }\r
-\r
-                               var endTime = Date.now();\r
-                               var dropFrames = (endTime - startTime) / me.frameDuration;\r
-\r
-                               me.dropFrames += dropFrames;\r
-\r
-                               // Do we have more stuff to animate?\r
-                               if (me.animations.length > 0) {\r
-                                       me.requestAnimationFrame();\r
-                               }\r
-                       }\r
-               };\r
-       };\r
-},{}],22:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-               // Global Chart canvas helpers object for drawing items to canvas\r
-               var helpers = Chart.canvasHelpers = {};\r
-\r
-               helpers.drawPoint = function(ctx, pointStyle, radius, x, y) {\r
-                       var type, edgeLength, xOffset, yOffset, height, size;\r
-\r
-                       if (typeof pointStyle === 'object') {\r
-                               type = pointStyle.toString();\r
-                               if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\r
-                                       ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);\r
-                                       return;\r
-                               }\r
-                       }\r
-\r
-                       if (isNaN(radius) || radius <= 0) {\r
-                               return;\r
-                       }\r
-\r
-                       switch (pointStyle) {\r
-                               // Default includes circle\r
-                               default:\r
-                                       ctx.beginPath();\r
-                                       ctx.arc(x, y, radius, 0, Math.PI * 2);\r
-                                       ctx.closePath();\r
-                                       ctx.fill();\r
-                                       break;\r
-                               case 'triangle':\r
-                                       ctx.beginPath();\r
-                                       edgeLength = 3 * radius / Math.sqrt(3);\r
-                                       height = edgeLength * Math.sqrt(3) / 2;\r
-                                       ctx.moveTo(x - edgeLength / 2, y + height / 3);\r
-                                       ctx.lineTo(x + edgeLength / 2, y + height / 3);\r
-                                       ctx.lineTo(x, y - 2 * height / 3);\r
-                                       ctx.closePath();\r
-                                       ctx.fill();\r
-                                       break;\r
-                               case 'rect':\r
-                                       size = 1 / Math.SQRT2 * radius;\r
-                                       ctx.beginPath();\r
-                                       ctx.fillRect(x - size, y - size, 2 * size,  2 * size);\r
-                                       ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);\r
-                                       break;\r
-                               case 'rectRot':\r
-                                       size = 1 / Math.SQRT2 * radius;\r
-                                       ctx.beginPath();\r
-                                       ctx.moveTo(x - size, y);\r
-                                       ctx.lineTo(x, y + size);\r
-                                       ctx.lineTo(x + size, y);\r
-                                       ctx.lineTo(x, y - size);\r
-                                       ctx.closePath();\r
-                                       ctx.fill();\r
-                                       break;\r
-                               case 'cross':\r
-                                       ctx.beginPath();\r
-                                       ctx.moveTo(x, y + radius);\r
-                                       ctx.lineTo(x, y - radius);\r
-                                       ctx.moveTo(x - radius, y);\r
-                                       ctx.lineTo(x + radius, y);\r
-                                       ctx.closePath();\r
-                                       break;\r
-                               case 'crossRot':\r
-                                       ctx.beginPath();\r
-                                       xOffset = Math.cos(Math.PI / 4) * radius;\r
-                                       yOffset = Math.sin(Math.PI / 4) * radius;\r
-                                       ctx.moveTo(x - xOffset, y - yOffset);\r
-                                       ctx.lineTo(x + xOffset, y + yOffset);\r
-                                       ctx.moveTo(x - xOffset, y + yOffset);\r
-                                       ctx.lineTo(x + xOffset, y - yOffset);\r
-                                       ctx.closePath();\r
-                                       break;\r
-                               case 'star':\r
-                                       ctx.beginPath();\r
-                                       ctx.moveTo(x, y + radius);\r
-                                       ctx.lineTo(x, y - radius);\r
-                                       ctx.moveTo(x - radius, y);\r
-                                       ctx.lineTo(x + radius, y);\r
-                                       xOffset = Math.cos(Math.PI / 4) * radius;\r
-                                       yOffset = Math.sin(Math.PI / 4) * radius;\r
-                                       ctx.moveTo(x - xOffset, y - yOffset);\r
-                                       ctx.lineTo(x + xOffset, y + yOffset);\r
-                                       ctx.moveTo(x - xOffset, y + yOffset);\r
-                                       ctx.lineTo(x + xOffset, y - yOffset);\r
-                                       ctx.closePath();\r
-                                       break;\r
-                               case 'line':\r
-                                       ctx.beginPath();\r
-                                       ctx.moveTo(x - radius, y);\r
-                                       ctx.lineTo(x + radius, y);\r
-                                       ctx.closePath();\r
-                                       break;\r
-                               case 'dash':\r
-                                       ctx.beginPath();\r
-                                       ctx.moveTo(x, y);\r
-                                       ctx.lineTo(x + radius, y);\r
-                                       ctx.closePath();\r
-                                       break;\r
-                       }\r
-\r
-                       ctx.stroke();\r
-               };\r
-       };\r
-},{}],23:[function(require,module,exports){\r
-       "use strict";\r
-\r
-       module.exports = function(Chart) {\r
-\r
-               var helpers = Chart.helpers;\r
-               //Create a dictionary of chart types, to allow for extension of existing types\r
-               Chart.types = {};\r
-\r
-               //Store a reference to each instance - allowing us to globally resize chart instances on window resize.\r
-               //Destroy method on the chart will remove the instance of the chart from this reference.\r
-               Chart.instances = {};\r
-\r
-               // Controllers available for dataset visualization eg. bar, line, slice, etc.\r
-               Chart.controllers = {};\r
-\r
-               /**\r
-                * @class Chart.Controller\r
-                * The main controller of a chart.\r
-                */\r
-               Chart.Controller = function(instance) {\r
-\r
-                       this.chart = instance;\r
-                       this.config = instance.config;\r
-                       this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});\r
-                       this.id = helpers.uid();\r
-\r
-                       Object.defineProperty(this, 'data', {\r
-                               get: function() {\r
-                                       return this.config.data;\r
-                               }\r
-                       });\r
-\r
-                       //Add the chart instance to the global namespace\r
-                       Chart.instances[this.id] = this;\r
-\r
-                       if (this.options.responsive) {\r
-                               // Silent resize before chart draws\r
-                               this.resize(true);\r
-                       }\r
-\r
-                       this.initialize();\r
-\r
-                       return this;\r
-               };\r
-\r
-               helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ {\r
-\r
-                       initialize: function() {\r
-                               var me = this;\r
-                               // Before init plugin notification\r
-                               Chart.plugins.notify('beforeInit', [me]);\r
-\r
-                               me.bindEvents();\r
-\r
-                               // Make sure controllers are built first so that each dataset is bound to an axis before the scales\r
-                               // are built\r
-                               me.ensureScalesHaveIDs();\r
-                               me.buildOrUpdateControllers();\r
-                               me.buildScales();\r
-                               me.updateLayout();\r
-                               me.resetElements();\r
-                               me.initToolTip();\r
-                               me.update();\r
-\r
-                               // After init plugin notification\r
-                               Chart.plugins.notify('afterInit', [me]);\r
-\r
-                               return me;\r
-                       },\r
-\r
-                       clear: function() {\r
-                               helpers.clear(this.chart);\r
-                               return this;\r
-                       },\r
-\r
-                       stop: function() {\r
-                               // Stops any current animation loop occuring\r
-                               Chart.animationService.cancelAnimation(this);\r
-                               return this;\r
-                       },\r
-\r
-                       resize: function resize(silent) {\r
-                               var me = this;\r
-                               var chart = me.chart;\r
-                               var canvas = chart.canvas;\r
-                               var newWidth = helpers.getMaximumWidth(canvas);\r
-                               var aspectRatio = chart.aspectRatio;\r
-                               var newHeight = (me.options.maintainAspectRatio && isNaN(aspectRatio) === false && isFinite(aspectRatio) && aspectRatio !== 0) ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas);\r
-\r
-                               var sizeChanged = chart.width !== newWidth || chart.height !== newHeight;\r
-\r
-                               if (!sizeChanged) {\r
-                                       return me;\r
-                               }\r
-\r
-                               canvas.width = chart.width = newWidth;\r
-                               canvas.height = chart.height = newHeight;\r
-\r
-                               helpers.retinaScale(chart);\r
-\r
-                               // Notify any plugins about the resize\r
-                               var newSize = { width: newWidth, height: newHeight };\r
-                               Chart.plugins.notify('resize', [me, newSize]);\r
-\r
-                               // Notify of resize\r
-                               if (me.options.onResize) {\r
-                                       me.options.onResize(me, newSize);\r
-                               }\r
-\r
-                               if (!silent) {\r
-                                       me.stop();\r
-                                       me.update(me.options.responsiveAnimationDuration);\r
-                               }\r
-\r
-                               return me;\r
-                       },\r
-\r
-                       ensureScalesHaveIDs: function() {\r
-                               var options = this.options;\r
-                               var scalesOptions = options.scales || {};\r
-                               var scaleOptions = options.scale;\r
-\r
-                               helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {\r
-                                       xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);\r
-                               });\r
-\r
-                               helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {\r
-                                       yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);\r
-                               });\r
-\r
-                               if (scaleOptions) {\r
-                                       scaleOptions.id = scaleOptions.id || 'scale';\r
-                               }\r
-                       },\r
-\r
-                       /**\r
-                        * Builds a map of scale ID to scale object for future lookup.\r
-                        */\r
-                       buildScales: function() {\r
-                               var me = this;\r
-                               var options = me.options;\r
-                               var scales = me.scales = {};\r
-                               var items = [];\r
-\r
-                               if (options.scales) {\r
-                                       items = items.concat(\r
-                                               (options.scales.xAxes || []).map(function(xAxisOptions) {\r
-                                                       return { options: xAxisOptions, dtype: 'category' }; }),\r
-                                               (options.scales.yAxes || []).map(function(yAxisOptions) {\r
-                                                       return { options: yAxisOptions, dtype: 'linear' }; }));\r
-                               }\r
-\r
-                               if (options.scale) {\r
-                                       items.push({ options: options.scale, dtype: 'radialLinear', isDefault: true });\r
-                               }\r
-\r
-                               helpers.each(items, function(item) {\r
-                                       var scaleOptions = item.options;\r
-                                       var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);\r
-                                       var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);\r
-                                       if (!scaleClass) {\r
-                                               return;\r
-                                       }\r
-\r
-                                       var scale = new scaleClass({\r
-                                               id: scaleOptions.id,\r
-                                               options: scaleOptions,\r
-                                               ctx: me.chart.ctx,\r
-                                               chart: me\r
-                                       });\r
-\r
-                                       scales[scale.id] = scale;\r
-\r
-                                       // TODO(SB): I think we should be able to remove this custom case (options.scale)\r
-                                       // and consider it as a regular scale part of the "scales"" map only! This would\r
-                                       // make the logic easier and remove some useless? custom code.\r
-                                       if (item.isDefault) {\r
-                                               me.scale = scale;\r
-                                       }\r
-                               });\r
-\r
-                               Chart.scaleService.addScalesToLayout(this);\r
-                       },\r
-\r
-                       updateLayout: function() {\r
-                               Chart.layoutService.update(this, this.chart.width, this.chart.height);\r
-                       },\r
-\r
-                       buildOrUpdateControllers: function() {\r
-                               var me = this;\r
-                               var types = [];\r
-                               var newContro