From 9f03824f2a73eaf38fd480396573411b2f45b9f8 Mon Sep 17 00:00:00 2001 From: Blesilda Ramirez Date: Thu, 22 Aug 2024 07:54:26 +0800 Subject: [PATCH] pkp/pkp-lib#9753 [main] Update jquery, jquery-ui and chart.js to address security vulnerability reports (#10168) * pkp/pkp-lib#9753 Update chartjs from v2.0.1 to v2.9.4 * pkp/pkp-lib#9753 Upgrade jquery validation from v1.11.1 to v1.19.5 * pkp/pkp-lib#9753 Remove components/jqueryui as a composer dependency * pkp/pkp-lib#9753 Manually add jquery-ui v1.13.3 to jquery plugins * pkp/pkp-lib#9753 Move import of jqueryui from vendors to js plugins * pkp/pkp-lib#9753 Remove jquery-ui local files * pkp/pkp-lib#9753 Add jquery-ui dependency to composer from npm * pkp/pkp-lib#9753 Remove jquery-validation local files * pkp/pkp-lib#9753 Add query-validation to composer from npm * pkp/pkp-lib#9753 Add missing import of Laravel Cache * pkp/pkp-lib#9753 Adjust tooltips configuration for chart.js * pkp/pkp-lib#9753 Remove chart.js local files * pkp/pkp-lib#9753 Remove jquery, jquery-ui and jquery-validation from composer dependencies * pkp/pkp-lib#9753 [main] Update paths when importing chart.js, jquery, jquery-ui and jquery-validation * pkp/pkp-lib#9753 Adjust chart.js config options to be compatible with v4 * pkp/pkp-lib#9753 Update line chart options to make it like the previous design * pkp/pkp-lib#9753 Remove committed languages.json file --- classes/plugins/ThemePlugin.php | 4 +- classes/template/PKPTemplateManager.php | 8 +- composer.json | 5 +- composer.lock | 140 +- js/lib/Chart.js | 9166 ----------------- js/lib/Chart.min.js | 14 - .../plugins/validate/additional-methods.js | 617 -- .../validate/additional-methods.min.js | 2 - .../plugins/validate/jquery.validate.js | 1231 --- .../plugins/validate/jquery.validate.min.js | 2 - .../validate/localization/messages_ar.js | 25 - .../validate/localization/messages_bg.js | 25 - .../validate/localization/messages_ca.js | 25 - .../validate/localization/messages_cs.js | 25 - .../validate/localization/messages_da.js | 22 - .../validate/localization/messages_de.js | 22 - .../validate/localization/messages_el.js | 25 - .../validate/localization/messages_es.js | 25 - .../validate/localization/messages_et.js | 23 - .../validate/localization/messages_eu.js | 25 - .../validate/localization/messages_fa.js | 25 - .../validate/localization/messages_fi.js | 23 - .../validate/localization/messages_fr.js | 47 - .../validate/localization/messages_he.js | 25 - .../validate/localization/messages_hr.js | 25 - .../validate/localization/messages_hu.js | 24 - .../validate/localization/messages_it.js | 25 - .../validate/localization/messages_ja.js | 25 - .../validate/localization/messages_ka.js | 25 - .../validate/localization/messages_kk.js | 25 - .../validate/localization/messages_ko.js | 25 - .../validate/localization/messages_lt.js | 25 - .../validate/localization/messages_lv.js | 25 - .../validate/localization/messages_my.js | 25 - .../validate/localization/messages_nl.js | 35 - .../validate/localization/messages_no.js | 25 - .../validate/localization/messages_pl.js | 25 - .../validate/localization/messages_pt_BR.js | 26 - .../validate/localization/messages_pt_PT.js | 26 - .../validate/localization/messages_ro.js | 25 - .../validate/localization/messages_ru.js | 25 - .../validate/localization/messages_si.js | 25 - .../validate/localization/messages_sk.js | 22 - .../validate/localization/messages_sl.js | 25 - .../validate/localization/messages_sr.js | 25 - .../validate/localization/messages_sv.js | 23 - .../validate/localization/messages_th.js | 25 - .../validate/localization/messages_tr.js | 25 - .../validate/localization/messages_uk.js | 25 - .../validate/localization/messages_vi.js | 25 - .../validate/localization/messages_zh.js | 25 - .../validate/localization/messages_zh_TW.js | 26 - .../validate/localization/methods_de.js | 12 - .../validate/localization/methods_nl.js | 9 - .../validate/localization/methods_pt.js | 9 - js/usage-stats-chart.js | 61 +- 56 files changed, 36 insertions(+), 12313 deletions(-) delete mode 100644 js/lib/Chart.js delete mode 100644 js/lib/Chart.min.js delete mode 100644 js/lib/jquery/plugins/validate/additional-methods.js delete mode 100644 js/lib/jquery/plugins/validate/additional-methods.min.js delete mode 100644 js/lib/jquery/plugins/validate/jquery.validate.js delete mode 100644 js/lib/jquery/plugins/validate/jquery.validate.min.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_ar.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_bg.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_ca.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_cs.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_da.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_de.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_el.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_es.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_et.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_eu.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_fa.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_fi.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_fr.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_he.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_hr.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_hu.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_it.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_ja.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_ka.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_kk.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_ko.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_lt.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_lv.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_my.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_nl.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_no.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_pl.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_pt_BR.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_pt_PT.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_ro.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_ru.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_si.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_sk.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_sl.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_sr.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_sv.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_th.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_tr.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_uk.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_vi.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_zh.js delete mode 100644 js/lib/jquery/plugins/validate/localization/messages_zh_TW.js delete mode 100644 js/lib/jquery/plugins/validate/localization/methods_de.js delete mode 100644 js/lib/jquery/plugins/validate/localization/methods_nl.js delete mode 100644 js/lib/jquery/plugins/validate/localization/methods_pt.js diff --git a/classes/plugins/ThemePlugin.php b/classes/plugins/ThemePlugin.php index 7d6d9da0994..e9021f2d840 100644 --- a/classes/plugins/ThemePlugin.php +++ b/classes/plugins/ThemePlugin.php @@ -16,6 +16,7 @@ namespace PKP\plugins; +use Illuminate\Support\Facades\Cache; use APP\core\Application; use APP\core\Request; use APP\facades\Repo; @@ -911,10 +912,9 @@ protected function loadChartJavascript(): void $templateMgr = TemplateManager::getManager($request); // Register Chart.js on the frontend article view - $min = Config::getVar('general', 'enable_minified') ? '.min' : ''; $templateMgr->addJavaScript( 'chartJS', - $request->getBaseUrl() . '/lib/pkp/js/lib/Chart' . $min . '.js', + $request->getBaseUrl() . '/js/build/chart.js/chart.umd.js', [ 'contexts' => $this->getSubmissionViewContext(), ] diff --git a/classes/template/PKPTemplateManager.php b/classes/template/PKPTemplateManager.php index 9dbfc3b64e5..4327a11df51 100644 --- a/classes/template/PKPTemplateManager.php +++ b/classes/template/PKPTemplateManager.php @@ -664,10 +664,10 @@ public function registerJSLibrary(): void // properly by our build script $this->addJavaScript( 'jqueryValidate', - $baseUrl . '/lib/pkp/js/lib/jquery/plugins/validate/jquery.validate.min.js', + $baseUrl . '/js/build/jquery-validation/jquery.validate.min.js', $args ); - $jqvLocalePath = 'lib/pkp/js/lib/jquery/plugins/validate/localization/messages_'; + $jqvLocalePath = 'js/build/jquery-validation/localization/messages_'; foreach ($localeChecks as $localeCheck) { if (file_exists($jqvLocalePath . $localeCheck . '.js')) { $this->addJavaScript('jqueryValidateLocale', $baseUrl . '/' . $jqvLocalePath . $localeCheck . '.js', $args); @@ -868,7 +868,7 @@ public function setupBackendPage() $min = Config::getVar('general', 'enable_minified') ? '.min' : ''; $this->addJavaScript( 'jquery', - $request->getBaseUrl() . '/lib/pkp/lib/vendor/components/jquery/jquery' . $min . '.js', + $request->getBaseUrl() . '/js/build/jquery/jquery' . $min . '.js', [ 'priority' => self::STYLE_SEQUENCE_CORE, 'contexts' => 'backend', @@ -876,7 +876,7 @@ public function setupBackendPage() ); $this->addJavaScript( 'jqueryUI', - $request->getBaseUrl() . '/lib/pkp/lib/vendor/components/jqueryui/jquery-ui' . $min . '.js', + $request->getBaseUrl() . '/js/build/jquery-ui/jquery-ui' . $min . '.js', [ 'priority' => self::STYLE_SEQUENCE_CORE, 'contexts' => 'backend', diff --git a/composer.json b/composer.json index 84c46d11e2c..d0f7906667e 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,6 @@ { "require": { "php": "^8.2", - "components/jquery": "^3.5", - "components/jqueryui": "1.*", "composer/semver": "^3.4", "cweagans/composer-patches": "^1.7", "dflydev/base32-crockford": "^1.0", @@ -57,7 +55,8 @@ "@weblateFilesDownload" ], "isoFileCheck": [ - "PKP\\dev\\ComposerScript::isoFileCheck" ], + "PKP\\dev\\ComposerScript::isoFileCheck" + ], "weblateFilesDownload": [ "PKP\\dev\\ComposerScript::weblateFilesDownload" ] diff --git a/composer.lock b/composer.lock index 8fef5392258..a03a08f2264 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "46a40dd4b957f927d4ae301469a462a6", + "content-hash": "f4b9ee6c1f6e26880c56112d8ca61efe", "packages": [ { "name": "brick/math", @@ -135,144 +135,6 @@ ], "time": "2024-02-09T16:56:22+00:00" }, - { - "name": "components/jquery", - "version": "v3.7.1", - "source": { - "type": "git", - "url": "https://github.com/components/jquery.git", - "reference": "8edc7785239bb8c2ad2b83302b856a1d61de60e7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/components/jquery/zipball/8edc7785239bb8c2ad2b83302b856a1d61de60e7", - "reference": "8edc7785239bb8c2ad2b83302b856a1d61de60e7", - "shasum": "" - }, - "type": "component", - "extra": { - "component": { - "scripts": [ - "jquery.js" - ], - "files": [ - "jquery.min.js", - "jquery.min.map", - "jquery.slim.js", - "jquery.slim.min.js", - "jquery.slim.min.map" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "JS Foundation and other contributors" - } - ], - "description": "jQuery JavaScript Library", - "homepage": "http://jquery.com", - "support": { - "forum": "http://forum.jquery.com", - "irc": "irc://irc.freenode.org/jquery", - "issues": "https://github.com/jquery/jquery/issues", - "source": "https://github.com/jquery/jquery", - "wiki": "http://docs.jquery.com/" - }, - "time": "2023-09-22T01:43:46+00:00" - }, - { - "name": "components/jqueryui", - "version": "1.12.1", - "source": { - "type": "git", - "url": "https://github.com/components/jqueryui.git", - "reference": "44ecf3794cc56b65954cc19737234a3119d036cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/components/jqueryui/zipball/44ecf3794cc56b65954cc19737234a3119d036cc", - "reference": "44ecf3794cc56b65954cc19737234a3119d036cc", - "shasum": "" - }, - "require": { - "components/jquery": ">=1.6" - }, - "type": "component", - "extra": { - "component": { - "name": "jquery-ui", - "scripts": [ - "jquery-ui.js" - ], - "files": [ - "ui/**", - "themes/**", - "jquery-ui.min.js" - ], - "shim": { - "deps": [ - "jquery" - ], - "exports": "jQuery" - } - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "jQuery UI Team", - "homepage": "http://jqueryui.com/about" - }, - { - "name": "Joern Zaefferer", - "email": "joern.zaefferer@gmail.com", - "homepage": "http://bassistance.de" - }, - { - "name": "Scott Gonzalez", - "email": "scott.gonzalez@gmail.com", - "homepage": "http://scottgonzalez.com" - }, - { - "name": "Kris Borchers", - "email": "kris.borchers@gmail.com", - "homepage": "http://krisborchers.com" - }, - { - "name": "Mike Sherov", - "email": "mike.sherov@gmail.com", - "homepage": "http://mike.sherov.com" - }, - { - "name": "TJ VanToll", - "email": "tj.vantoll@gmail.com", - "homepage": "http://tjvantoll.com" - }, - { - "name": "Corey Frang", - "email": "gnarf37@gmail.com", - "homepage": "http://gnarf.net" - }, - { - "name": "Felix Nagel", - "email": "info@felixnagel.com", - "homepage": "http://www.felixnagel.com" - } - ], - "description": "jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library. Whether you're building highly interactive web applications or you just need to add a date picker to a form control, jQuery UI is the perfect choice.", - "support": { - "issues": "https://github.com/components/jqueryui/issues", - "source": "https://github.com/components/jqueryui/tree/master" - }, - "time": "2016-09-16T05:47:55+00:00" - }, { "name": "composer/ca-bundle", "version": "1.5.1", diff --git a/js/lib/Chart.js b/js/lib/Chart.js deleted file mode 100644 index f47976124d6..00000000000 --- a/js/lib/Chart.js +++ /dev/null @@ -1,9166 +0,0 @@ -(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 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y *100, z * 100]; -} - -function rgb2lab(rgb) { - var xyz = rgb2xyz(rgb), - x = xyz[0], - y = xyz[1], - z = xyz[2], - l, a, b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -} - -function rgb2lch(args) { - return lab2lch(rgb2lab(args)); -} - -function hsl2rgb(hsl) { - var h = hsl[0] / 360, - s = hsl[1] / 100, - l = hsl[2] / 100, - t1, t2, t3, rgb, val; - - if (s == 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) - t2 = l * (1 + s); - else - t2 = l + s - l * s; - t1 = 2 * l - t2; - - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * - (i - 1); - t3 < 0 && t3++; - t3 > 1 && t3--; - - if (6 * t3 < 1) - val = t1 + (t2 - t1) * 6 * t3; - else if (2 * t3 < 1) - val = t2; - else if (3 * t3 < 2) - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - else - val = t1; - - rgb[i] = val * 255; - } - - return rgb; -} - -function hsl2hsv(hsl) { - var h = hsl[0], - s = hsl[1] / 100, - l = hsl[2] / 100, - sv, v; - - if(l === 0) { - // no need to do calc on black - // also avoids divide by 0 error - return [0, 0, 0]; - } - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - v = (l + s) / 2; - sv = (2 * s) / (l + s); - return [h, sv * 100, v * 100]; -} - -function hsl2hwb(args) { - return rgb2hwb(hsl2rgb(args)); -} - -function hsl2cmyk(args) { - return rgb2cmyk(hsl2rgb(args)); -} - -function hsl2keyword(args) { - return rgb2keyword(hsl2rgb(args)); -} - - -function hsv2rgb(hsv) { - var h = hsv[0] / 60, - s = hsv[1] / 100, - v = hsv[2] / 100, - hi = Math.floor(h) % 6; - - var f = h - Math.floor(h), - p = 255 * v * (1 - s), - q = 255 * v * (1 - (s * f)), - t = 255 * v * (1 - (s * (1 - f))), - v = 255 * v; - - switch(hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -} - -function hsv2hsl(hsv) { - var h = hsv[0], - s = hsv[1] / 100, - v = hsv[2] / 100, - sl, l; - - l = (2 - s) * v; - sl = s * v; - sl /= (l <= 1) ? l : 2 - l; - sl = sl || 0; - l /= 2; - return [h, sl * 100, l * 100]; -} - -function hsv2hwb(args) { - return rgb2hwb(hsv2rgb(args)) -} - -function hsv2cmyk(args) { - return rgb2cmyk(hsv2rgb(args)); -} - -function hsv2keyword(args) { - return rgb2keyword(hsv2rgb(args)); -} - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -function hwb2rgb(hwb) { - var h = hwb[0] / 360, - wh = hwb[1] / 100, - bl = hwb[2] / 100, - ratio = wh + bl, - i, v, f, n; - - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; - if ((i & 0x01) != 0) { - f = 1 - f; - } - n = wh + f * (v - wh); // linear interpolation - - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - - return [r * 255, g * 255, b * 255]; -} - -function hwb2hsl(args) { - return rgb2hsl(hwb2rgb(args)); -} - -function hwb2hsv(args) { - return rgb2hsv(hwb2rgb(args)); -} - -function hwb2cmyk(args) { - return rgb2cmyk(hwb2rgb(args)); -} - -function hwb2keyword(args) { - return rgb2keyword(hwb2rgb(args)); -} - -function cmyk2rgb(cmyk) { - var c = cmyk[0] / 100, - m = cmyk[1] / 100, - y = cmyk[2] / 100, - k = cmyk[3] / 100, - r, g, b; - - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); - return [r * 255, g * 255, b * 255]; -} - -function cmyk2hsl(args) { - return rgb2hsl(cmyk2rgb(args)); -} - -function cmyk2hsv(args) { - return rgb2hsv(cmyk2rgb(args)); -} - -function cmyk2hwb(args) { - return rgb2hwb(cmyk2rgb(args)); -} - -function cmyk2keyword(args) { - return rgb2keyword(cmyk2rgb(args)); -} - - -function xyz2rgb(xyz) { - var x = xyz[0] / 100, - y = xyz[1] / 100, - z = xyz[2] / 100, - r, g, b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // assume sRGB - r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r = (r * 12.92); - - g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g = (g * 12.92); - - b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b = (b * 12.92); - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -} - -function xyz2lab(xyz) { - var x = xyz[0], - y = xyz[1], - z = xyz[2], - l, a, b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -} - -function xyz2lch(args) { - return lab2lch(xyz2lab(args)); -} - -function lab2xyz(lab) { - var l = lab[0], - a = lab[1], - b = lab[2], - x, y, z, y2; - - if (l <= 8) { - y = (l * 100) / 903.3; - y2 = (7.787 * (y / 100)) + (16 / 116); - } else { - y = 100 * Math.pow((l + 16) / 116, 3); - y2 = Math.pow(y / 100, 1/3); - } - - x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3); - - z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3); - - return [x, y, z]; -} - -function lab2lch(lab) { - var l = lab[0], - a = lab[1], - b = lab[2], - hr, h, c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - if (h < 0) { - h += 360; - } - c = Math.sqrt(a * a + b * b); - return [l, c, h]; -} - -function lab2rgb(args) { - return xyz2rgb(lab2xyz(args)); -} - -function lch2lab(lch) { - var l = lch[0], - c = lch[1], - h = lch[2], - a, b, hr; - - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - return [l, a, b]; -} - -function lch2xyz(args) { - return lab2xyz(lch2lab(args)); -} - -function lch2rgb(args) { - return lab2rgb(lch2lab(args)); -} - -function keyword2rgb(keyword) { - return cssKeywords[keyword]; -} - -function keyword2hsl(args) { - return rgb2hsl(keyword2rgb(args)); -} - -function keyword2hsv(args) { - return rgb2hsv(keyword2rgb(args)); -} - -function keyword2hwb(args) { - return rgb2hwb(keyword2rgb(args)); -} - -function keyword2cmyk(args) { - return rgb2cmyk(keyword2rgb(args)); -} - -function keyword2lab(args) { - return rgb2lab(keyword2rgb(args)); -} - -function keyword2xyz(args) { - return rgb2xyz(keyword2rgb(args)); -} - -var cssKeywords = { - aliceblue: [240,248,255], - antiquewhite: [250,235,215], - aqua: [0,255,255], - aquamarine: [127,255,212], - azure: [240,255,255], - beige: [245,245,220], - bisque: [255,228,196], - black: [0,0,0], - blanchedalmond: [255,235,205], - blue: [0,0,255], - blueviolet: [138,43,226], - brown: [165,42,42], - burlywood: [222,184,135], - cadetblue: [95,158,160], - chartreuse: [127,255,0], - chocolate: [210,105,30], - coral: [255,127,80], - cornflowerblue: [100,149,237], - cornsilk: [255,248,220], - crimson: [220,20,60], - cyan: [0,255,255], - darkblue: [0,0,139], - darkcyan: [0,139,139], - darkgoldenrod: [184,134,11], - darkgray: [169,169,169], - darkgreen: [0,100,0], - darkgrey: [169,169,169], - darkkhaki: [189,183,107], - darkmagenta: [139,0,139], - darkolivegreen: [85,107,47], - darkorange: [255,140,0], - darkorchid: [153,50,204], - darkred: [139,0,0], - darksalmon: [233,150,122], - darkseagreen: [143,188,143], - darkslateblue: [72,61,139], - darkslategray: [47,79,79], - darkslategrey: [47,79,79], - darkturquoise: [0,206,209], - darkviolet: [148,0,211], - deeppink: [255,20,147], - deepskyblue: [0,191,255], - dimgray: [105,105,105], - dimgrey: [105,105,105], - dodgerblue: [30,144,255], - firebrick: [178,34,34], - floralwhite: [255,250,240], - forestgreen: [34,139,34], - fuchsia: [255,0,255], - gainsboro: [220,220,220], - ghostwhite: [248,248,255], - gold: [255,215,0], - goldenrod: [218,165,32], - gray: [128,128,128], - green: [0,128,0], - greenyellow: [173,255,47], - grey: [128,128,128], - honeydew: [240,255,240], - hotpink: [255,105,180], - indianred: [205,92,92], - indigo: [75,0,130], - ivory: [255,255,240], - khaki: [240,230,140], - lavender: [230,230,250], - lavenderblush: [255,240,245], - lawngreen: [124,252,0], - lemonchiffon: [255,250,205], - lightblue: [173,216,230], - lightcoral: [240,128,128], - lightcyan: [224,255,255], - lightgoldenrodyellow: [250,250,210], - lightgray: [211,211,211], - lightgreen: [144,238,144], - lightgrey: [211,211,211], - lightpink: [255,182,193], - lightsalmon: [255,160,122], - lightseagreen: [32,178,170], - lightskyblue: [135,206,250], - lightslategray: [119,136,153], - lightslategrey: [119,136,153], - lightsteelblue: [176,196,222], - lightyellow: [255,255,224], - lime: [0,255,0], - limegreen: [50,205,50], - linen: [250,240,230], - magenta: [255,0,255], - maroon: [128,0,0], - mediumaquamarine: [102,205,170], - mediumblue: [0,0,205], - mediumorchid: [186,85,211], - mediumpurple: [147,112,219], - mediumseagreen: [60,179,113], - mediumslateblue: [123,104,238], - mediumspringgreen: [0,250,154], - mediumturquoise: [72,209,204], - mediumvioletred: [199,21,133], - midnightblue: [25,25,112], - mintcream: [245,255,250], - mistyrose: [255,228,225], - moccasin: [255,228,181], - navajowhite: [255,222,173], - navy: [0,0,128], - oldlace: [253,245,230], - olive: [128,128,0], - olivedrab: [107,142,35], - orange: [255,165,0], - orangered: [255,69,0], - orchid: [218,112,214], - palegoldenrod: [238,232,170], - palegreen: [152,251,152], - paleturquoise: [175,238,238], - palevioletred: [219,112,147], - papayawhip: [255,239,213], - peachpuff: [255,218,185], - peru: [205,133,63], - pink: [255,192,203], - plum: [221,160,221], - powderblue: [176,224,230], - purple: [128,0,128], - rebeccapurple: [102, 51, 153], - red: [255,0,0], - rosybrown: [188,143,143], - royalblue: [65,105,225], - saddlebrown: [139,69,19], - salmon: [250,128,114], - sandybrown: [244,164,96], - seagreen: [46,139,87], - seashell: [255,245,238], - sienna: [160,82,45], - silver: [192,192,192], - skyblue: [135,206,235], - slateblue: [106,90,205], - slategray: [112,128,144], - slategrey: [112,128,144], - snow: [255,250,250], - springgreen: [0,255,127], - steelblue: [70,130,180], - tan: [210,180,140], - teal: [0,128,128], - thistle: [216,191,216], - tomato: [255,99,71], - turquoise: [64,224,208], - violet: [238,130,238], - wheat: [245,222,179], - white: [255,255,255], - whitesmoke: [245,245,245], - yellow: [255,255,0], - yellowgreen: [154,205,50] -}; - -var reverseKeywords = {}; -for (var key in cssKeywords) { - reverseKeywords[JSON.stringify(cssKeywords[key])] = key; -} - -},{}],3:[function(require,module,exports){ -var conversions = require("./conversions"); - -var convert = function() { - return new Converter(); -} - -for (var func in conversions) { - // export Raw versions - convert[func + "Raw"] = (function(func) { - // accept array or plain args - return function(arg) { - if (typeof arg == "number") - arg = Array.prototype.slice.call(arguments); - return conversions[func](arg); - } - })(func); - - var pair = /(\w+)2(\w+)/.exec(func), - from = pair[1], - to = pair[2]; - - // export rgb2hsl and ["rgb"]["hsl"] - convert[from] = convert[from] || {}; - - convert[from][to] = convert[func] = (function(func) { - return function(arg) { - if (typeof arg == "number") - arg = Array.prototype.slice.call(arguments); - - var val = conversions[func](arg); - if (typeof val == "string" || val === undefined) - return val; // keyword - - for (var i = 0; i < val.length; i++) - val[i] = Math.round(val[i]); - return val; - } - })(func); -} - - -/* Converter does lazy conversion and caching */ -var Converter = function() { - this.convs = {}; -}; - -/* Either get the values for a space or - set the values for a space, depending on args */ -Converter.prototype.routeSpace = function(space, args) { - var values = args[0]; - if (values === undefined) { - // color.rgb() - return this.getValues(space); - } - // color.rgb(10, 10, 10) - if (typeof values == "number") { - values = Array.prototype.slice.call(args); - } - - return this.setValues(space, values); -}; - -/* Set the values for a space, invalidating cache */ -Converter.prototype.setValues = function(space, values) { - this.space = space; - this.convs = {}; - this.convs[space] = values; - return this; -}; - -/* Get the values for a space. If there's already - a conversion for the space, fetch it, otherwise - compute it */ -Converter.prototype.getValues = function(space) { - var vals = this.convs[space]; - if (!vals) { - var fspace = this.space, - from = this.convs[fspace]; - vals = convert[fspace][space](from); - - this.convs[space] = vals; - } - return vals; -}; - -["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) { - Converter.prototype[space] = function(vals) { - return this.routeSpace(space, arguments); - } -}); - -module.exports = convert; -},{"./conversions":2}],4:[function(require,module,exports){ -/* MIT license */ -var colorNames = require('color-name'); - -module.exports = { - getRgba: getRgba, - getHsla: getHsla, - getRgb: getRgb, - getHsl: getHsl, - getHwb: getHwb, - getAlpha: getAlpha, - - hexString: hexString, - rgbString: rgbString, - rgbaString: rgbaString, - percentString: percentString, - percentaString: percentaString, - hslString: hslString, - hslaString: hslaString, - hwbString: hwbString, - keyword: keyword -} - -function getRgba(string) { - if (!string) { - return; - } - var abbr = /^#([a-fA-F0-9]{3})$/, - hex = /^#([a-fA-F0-9]{6})$/, - rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/, - per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/, - keyword = /(\w+)/; - - var rgb = [0, 0, 0], - a = 1, - match = string.match(abbr); - if (match) { - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i] + match[i], 16); - } - } - else if (match = string.match(hex)) { - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); - } - } - else if (match = string.match(rgba)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i + 1]); - } - a = parseFloat(match[4]); - } - else if (match = string.match(per)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); - } - a = parseFloat(match[4]); - } - else if (match = string.match(keyword)) { - if (match[1] == "transparent") { - return [0, 0, 0, 0]; - } - rgb = colorNames[match[1]]; - if (!rgb) { - return; - } - } - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = scale(rgb[i], 0, 255); - } - if (!a && a != 0) { - a = 1; - } - else { - a = scale(a, 0, 1); - } - rgb[3] = a; - return rgb; -} - -function getHsla(string) { - if (!string) { - return; - } - var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hsl); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - s = scale(parseFloat(match[2]), 0, 100), - l = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, s, l, a]; - } -} - -function getHwb(string) { - if (!string) { - return; - } - var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hwb); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - w = scale(parseFloat(match[2]), 0, 100), - b = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, w, b, a]; - } -} - -function getRgb(string) { - var rgba = getRgba(string); - return rgba && rgba.slice(0, 3); -} - -function getHsl(string) { - var hsla = getHsla(string); - return hsla && hsla.slice(0, 3); -} - -function getAlpha(string) { - var vals = getRgba(string); - if (vals) { - return vals[3]; - } - else if (vals = getHsla(string)) { - return vals[3]; - } - else if (vals = getHwb(string)) { - return vals[3]; - } -} - -// generators -function hexString(rgb) { - return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1]) - + hexDouble(rgb[2]); -} - -function rgbString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return rgbaString(rgba, alpha); - } - return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")"; -} - -function rgbaString(rgba, alpha) { - if (alpha === undefined) { - alpha = (rgba[3] !== undefined ? rgba[3] : 1); - } - return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] - + ", " + alpha + ")"; -} - -function percentString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return percentaString(rgba, alpha); - } - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - - return "rgb(" + r + "%, " + g + "%, " + b + "%)"; -} - -function percentaString(rgba, alpha) { - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")"; -} - -function hslString(hsla, alpha) { - if (alpha < 1 || (hsla[3] && hsla[3] < 1)) { - return hslaString(hsla, alpha); - } - return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; -} - -function hslaString(hsla, alpha) { - if (alpha === undefined) { - alpha = (hsla[3] !== undefined ? hsla[3] : 1); - } - return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " - + alpha + ")"; -} - -// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax -// (hwb have alpha optional & 1 is default value) -function hwbString(hwb, alpha) { - if (alpha === undefined) { - alpha = (hwb[3] !== undefined ? hwb[3] : 1); - } - return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%" - + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")"; -} - -function keyword(rgb) { - return reverseNames[rgb.slice(0, 3)]; -} - -// helpers -function scale(num, min, max) { - return Math.min(Math.max(min, num), max); -} - -function hexDouble(num) { - var str = num.toString(16).toUpperCase(); - return (str.length < 2) ? "0" + str : str; -} - - -//create a list of reverse color names -var reverseNames = {}; -for (var name in colorNames) { - reverseNames[colorNames[name]] = name; -} - -},{"color-name":6}],5:[function(require,module,exports){ -/* MIT license */ - -var convert = require("color-convert"), - string = require("color-string"); - -var Color = function(obj) { - if (obj instanceof Color) return obj; - if (!(this instanceof Color)) return new Color(obj); - - this.values = { - rgb: [0, 0, 0], - hsl: [0, 0, 0], - hsv: [0, 0, 0], - hwb: [0, 0, 0], - cmyk: [0, 0, 0, 0], - alpha: 1 - } - - // parse Color() argument - if (typeof obj == "string") { - var vals = string.getRgba(obj); - if (vals) { - this.setValues("rgb", vals); - } else if (vals = string.getHsla(obj)) { - this.setValues("hsl", vals); - } else if (vals = string.getHwb(obj)) { - this.setValues("hwb", vals); - } else { - throw new Error("Unable to parse color from string \"" + obj + "\""); - } - } else if (typeof obj == "object") { - var vals = obj; - if (vals["r"] !== undefined || vals["red"] !== undefined) { - this.setValues("rgb", vals) - } else if (vals["l"] !== undefined || vals["lightness"] !== undefined) { - this.setValues("hsl", vals) - } else if (vals["v"] !== undefined || vals["value"] !== undefined) { - this.setValues("hsv", vals) - } else if (vals["w"] !== undefined || vals["whiteness"] !== undefined) { - this.setValues("hwb", vals) - } else if (vals["c"] !== undefined || vals["cyan"] !== undefined) { - this.setValues("cmyk", vals) - } else { - throw new Error("Unable to parse color from object " + JSON.stringify(obj)); - } - } -} - -Color.prototype = { - rgb: function(vals) { - return this.setSpace("rgb", arguments); - }, - hsl: function(vals) { - return this.setSpace("hsl", arguments); - }, - hsv: function(vals) { - return this.setSpace("hsv", arguments); - }, - hwb: function(vals) { - return this.setSpace("hwb", arguments); - }, - cmyk: function(vals) { - return this.setSpace("cmyk", arguments); - }, - - rgbArray: function() { - return this.values.rgb; - }, - hslArray: function() { - return this.values.hsl; - }, - hsvArray: function() { - return this.values.hsv; - }, - hwbArray: function() { - if (this.values.alpha !== 1) { - return this.values.hwb.concat([this.values.alpha]) - } - return this.values.hwb; - }, - cmykArray: function() { - return this.values.cmyk; - }, - rgbaArray: function() { - var rgb = this.values.rgb; - return rgb.concat([this.values.alpha]); - }, - hslaArray: function() { - var hsl = this.values.hsl; - return hsl.concat([this.values.alpha]); - }, - alpha: function(val) { - if (val === undefined) { - return this.values.alpha; - } - this.setValues("alpha", val); - return this; - }, - - red: function(val) { - return this.setChannel("rgb", 0, val); - }, - green: function(val) { - return this.setChannel("rgb", 1, val); - }, - blue: function(val) { - return this.setChannel("rgb", 2, val); - }, - hue: function(val) { - return this.setChannel("hsl", 0, val); - }, - saturation: function(val) { - return this.setChannel("hsl", 1, val); - }, - lightness: function(val) { - return this.setChannel("hsl", 2, val); - }, - saturationv: function(val) { - return this.setChannel("hsv", 1, val); - }, - whiteness: function(val) { - return this.setChannel("hwb", 1, val); - }, - blackness: function(val) { - return this.setChannel("hwb", 2, val); - }, - value: function(val) { - return this.setChannel("hsv", 2, val); - }, - cyan: function(val) { - return this.setChannel("cmyk", 0, val); - }, - magenta: function(val) { - return this.setChannel("cmyk", 1, val); - }, - yellow: function(val) { - return this.setChannel("cmyk", 2, val); - }, - black: function(val) { - return this.setChannel("cmyk", 3, val); - }, - - hexString: function() { - return string.hexString(this.values.rgb); - }, - rgbString: function() { - return string.rgbString(this.values.rgb, this.values.alpha); - }, - rgbaString: function() { - return string.rgbaString(this.values.rgb, this.values.alpha); - }, - percentString: function() { - return string.percentString(this.values.rgb, this.values.alpha); - }, - hslString: function() { - return string.hslString(this.values.hsl, this.values.alpha); - }, - hslaString: function() { - return string.hslaString(this.values.hsl, this.values.alpha); - }, - hwbString: function() { - return string.hwbString(this.values.hwb, this.values.alpha); - }, - keyword: function() { - return string.keyword(this.values.rgb, this.values.alpha); - }, - - rgbNumber: function() { - return (this.values.rgb[0] << 16) | (this.values.rgb[1] << 8) | this.values.rgb[2]; - }, - - luminosity: function() { - // http://www.w3.org/TR/WCAG20/#relativeluminancedef - var rgb = this.values.rgb; - var lum = []; - for (var i = 0; i < rgb.length; i++) { - var chan = rgb[i] / 255; - lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4) - } - return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; - }, - - contrast: function(color2) { - // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - var lum1 = this.luminosity(); - var lum2 = color2.luminosity(); - if (lum1 > lum2) { - return (lum1 + 0.05) / (lum2 + 0.05) - }; - return (lum2 + 0.05) / (lum1 + 0.05); - }, - - level: function(color2) { - var contrastRatio = this.contrast(color2); - return (contrastRatio >= 7.1) ? 'AAA' : (contrastRatio >= 4.5) ? 'AA' : ''; - }, - - dark: function() { - // YIQ equation from http://24ways.org/2010/calculating-color-contrast - var rgb = this.values.rgb, - yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; - return yiq < 128; - }, - - light: function() { - return !this.dark(); - }, - - negate: function() { - var rgb = [] - for (var i = 0; i < 3; i++) { - rgb[i] = 255 - this.values.rgb[i]; - } - this.setValues("rgb", rgb); - return this; - }, - - lighten: function(ratio) { - this.values.hsl[2] += this.values.hsl[2] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - darken: function(ratio) { - this.values.hsl[2] -= this.values.hsl[2] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - saturate: function(ratio) { - this.values.hsl[1] += this.values.hsl[1] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - desaturate: function(ratio) { - this.values.hsl[1] -= this.values.hsl[1] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - whiten: function(ratio) { - this.values.hwb[1] += this.values.hwb[1] * ratio; - this.setValues("hwb", this.values.hwb); - return this; - }, - - blacken: function(ratio) { - this.values.hwb[2] += this.values.hwb[2] * ratio; - this.setValues("hwb", this.values.hwb); - return this; - }, - - greyscale: function() { - var rgb = this.values.rgb; - // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; - this.setValues("rgb", [val, val, val]); - return this; - }, - - clearer: function(ratio) { - this.setValues("alpha", this.values.alpha - (this.values.alpha * ratio)); - return this; - }, - - opaquer: function(ratio) { - this.setValues("alpha", this.values.alpha + (this.values.alpha * ratio)); - return this; - }, - - rotate: function(degrees) { - var hue = this.values.hsl[0]; - hue = (hue + degrees) % 360; - hue = hue < 0 ? 360 + hue : hue; - this.values.hsl[0] = hue; - this.setValues("hsl", this.values.hsl); - return this; - }, - - mix: function(color2, weight) { - weight = 1 - (weight == null ? 0.5 : weight); - - // algorithm from Sass's mix(). Ratio of first color in mix is - // determined by the alphas of both colors and the weight - var t1 = weight * 2 - 1, - d = this.alpha() - color2.alpha(); - - var weight1 = (((t1 * d == -1) ? t1 : (t1 + d) / (1 + t1 * d)) + 1) / 2; - var weight2 = 1 - weight1; - - var rgb = this.rgbArray(); - var rgb2 = color2.rgbArray(); - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = rgb[i] * weight1 + rgb2[i] * weight2; - } - this.setValues("rgb", rgb); - - var alpha = this.alpha() * weight + color2.alpha() * (1 - weight); - this.setValues("alpha", alpha); - - return this; - }, - - toJSON: function() { - return this.rgb(); - }, - - clone: function() { - return new Color(this.rgb()); - } -} - - -Color.prototype.getValues = function(space) { - var vals = {}; - for (var i = 0; i < space.length; i++) { - vals[space.charAt(i)] = this.values[space][i]; - } - if (this.values.alpha != 1) { - vals["a"] = this.values.alpha; - } - // {r: 255, g: 255, b: 255, a: 0.4} - return vals; -} - -Color.prototype.setValues = function(space, vals) { - var spaces = { - "rgb": ["red", "green", "blue"], - "hsl": ["hue", "saturation", "lightness"], - "hsv": ["hue", "saturation", "value"], - "hwb": ["hue", "whiteness", "blackness"], - "cmyk": ["cyan", "magenta", "yellow", "black"] - }; - - var maxes = { - "rgb": [255, 255, 255], - "hsl": [360, 100, 100], - "hsv": [360, 100, 100], - "hwb": [360, 100, 100], - "cmyk": [100, 100, 100, 100] - }; - - var alpha = 1; - if (space == "alpha") { - alpha = vals; - } else if (vals.length) { - // [10, 10, 10] - this.values[space] = vals.slice(0, space.length); - alpha = vals[space.length]; - } else if (vals[space.charAt(0)] !== undefined) { - // {r: 10, g: 10, b: 10} - for (var i = 0; i < space.length; i++) { - this.values[space][i] = vals[space.charAt(i)]; - } - alpha = vals.a; - } else if (vals[spaces[space][0]] !== undefined) { - // {red: 10, green: 10, blue: 10} - var chans = spaces[space]; - for (var i = 0; i < space.length; i++) { - this.values[space][i] = vals[chans[i]]; - } - alpha = vals.alpha; - } - this.values.alpha = Math.max(0, Math.min(1, (alpha !== undefined ? alpha : this.values.alpha))); - if (space == "alpha") { - return; - } - - // cap values of the space prior converting all values - for (var i = 0; i < space.length; i++) { - var capped = Math.max(0, Math.min(maxes[space][i], this.values[space][i])); - this.values[space][i] = Math.round(capped); - } - - // convert to all the other color spaces - for (var sname in spaces) { - if (sname != space) { - this.values[sname] = convert[space][sname](this.values[space]) - } - - // cap values - for (var i = 0; i < sname.length; i++) { - var capped = Math.max(0, Math.min(maxes[sname][i], this.values[sname][i])); - this.values[sname][i] = Math.round(capped); - } - } - return true; -} - -Color.prototype.setSpace = function(space, args) { - var vals = args[0]; - if (vals === undefined) { - // color.rgb() - return this.getValues(space); - } - // color.rgb(10, 10, 10) - if (typeof vals == "number") { - vals = Array.prototype.slice.call(args); - } - this.setValues(space, vals); - return this; -} - -Color.prototype.setChannel = function(space, index, val) { - if (val === undefined) { - // color.red() - return this.values[space][index]; - } - // color.red(100) - this.values[space][index] = val; - this.setValues(space, this.values[space]); - return this; -} - -window.Color = module.exports = Color - -},{"color-convert":3,"color-string":4}],6:[function(require,module,exports){ -module.exports = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; -},{}],7:[function(require,module,exports){ -/*! - * Chart.js - * http://chartjs.org/ - * Version: 2.0.1 - * - * Copyright 2015 Nick Downie - * Released under the MIT license - * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md - */ - - -var Chart = require('./core/core.js')(); - -require('./core/core.helpers')(Chart); -require('./core/core.element')(Chart); -require('./core/core.animation')(Chart); -require('./core/core.controller')(Chart); -require('./core/core.datasetController')(Chart); -require('./core/core.layoutService')(Chart); -require('./core/core.legend')(Chart); -require('./core/core.scale')(Chart); -require('./core/core.scaleService')(Chart); -require('./core/core.title')(Chart); -require('./core/core.tooltip')(Chart); - -require('./controllers/controller.bar')(Chart); -require('./controllers/controller.bubble')(Chart); -require('./controllers/controller.doughnut')(Chart); -require('./controllers/controller.line')(Chart); -require('./controllers/controller.polarArea')(Chart); -require('./controllers/controller.radar')(Chart); - -require('./scales/scale.category')(Chart); -require('./scales/scale.linear')(Chart); -require('./scales/scale.logarithmic')(Chart); -require('./scales/scale.radialLinear')(Chart); -require('./scales/scale.time')(Chart); - -require('./elements/element.arc')(Chart); -require('./elements/element.line')(Chart); -require('./elements/element.point')(Chart); -require('./elements/element.rectangle')(Chart); - -require('./charts/Chart.Bar')(Chart); -require('./charts/Chart.Bubble')(Chart); -require('./charts/Chart.Doughnut')(Chart); -require('./charts/Chart.Line')(Chart); -require('./charts/Chart.PolarArea')(Chart); -require('./charts/Chart.Radar')(Chart); -require('./charts/Chart.Scatter')(Chart); - -window.Chart = module.exports = Chart; - -},{"./charts/Chart.Bar":8,"./charts/Chart.Bubble":9,"./charts/Chart.Doughnut":10,"./charts/Chart.Line":11,"./charts/Chart.PolarArea":12,"./charts/Chart.Radar":13,"./charts/Chart.Scatter":14,"./controllers/controller.bar":15,"./controllers/controller.bubble":16,"./controllers/controller.doughnut":17,"./controllers/controller.line":18,"./controllers/controller.polarArea":19,"./controllers/controller.radar":20,"./core/core.animation":21,"./core/core.controller":22,"./core/core.datasetController":23,"./core/core.element":24,"./core/core.helpers":25,"./core/core.js":26,"./core/core.layoutService":27,"./core/core.legend":28,"./core/core.scale":29,"./core/core.scaleService":30,"./core/core.title":31,"./core/core.tooltip":32,"./elements/element.arc":33,"./elements/element.line":34,"./elements/element.point":35,"./elements/element.rectangle":36,"./scales/scale.category":37,"./scales/scale.linear":38,"./scales/scale.logarithmic":39,"./scales/scale.radialLinear":40,"./scales/scale.time":41}],8:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Bar = function(context, config) { - config.type = 'bar'; - - return new Chart(context, config); - }; - -}; -},{}],9:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Bubble = function(context, config) { - config.type = 'bubble'; - return new Chart(context, config); - }; - -}; -},{}],10:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Doughnut = function(context, config) { - config.type = 'doughnut'; - - return new Chart(context, config); - }; - -}; -},{}],11:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Line = function(context, config) { - config.type = 'line'; - - return new Chart(context, config); - }; - -}; -},{}],12:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.PolarArea = function(context, config) { - config.type = 'polarArea'; - - return new Chart(context, config); - }; - -}; -},{}],13:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - var defaultConfig = { - aspectRatio: 1 - }; - - Chart.Radar = function(context, config) { - config.options = helpers.configMerge(defaultConfig, config.options); - config.type = 'radar'; - - return new Chart(context, config); - }; - -}; - -},{}],14:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var defaultConfig = { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - type: "linear", // scatter should not use a category axis - position: "bottom", - id: "x-axis-1" // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: "linear", - position: "left", - id: "y-axis-1" - }] - }, - - tooltips: { - callbacks: { - title: function(tooltipItems, data) { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(tooltipItem, data) { - return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')'; - } - } - } - }; - - // Register the default config for this type - Chart.defaults.scatter = defaultConfig; - - // Scatter charts use line controllers - Chart.controllers.scatter = Chart.controllers.line; - - Chart.Scatter = function(context, config) { - config.type = 'scatter'; - return new Chart(context, config); - }; - -}; -},{}],15:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.bar = { - hover: { - mode: "label" - }, - - scales: { - xAxes: [{ - type: "category", - - // Specific to Bar Controller - categoryPercentage: 0.8, - barPercentage: 0.9, - - // grid line settings - gridLines: { - offsetGridLines: true - } - }], - yAxes: [{ - type: "linear" - }] - } - }; - - Chart.controllers.bar = Chart.DatasetController.extend({ - initialize: function(chart, datasetIndex) { - Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex); - - // Use this to indicate that this is a bar dataset. - this.getDataset().bar = true; - }, - // Get the number of datasets that display bars. We use this to correctly calculate the bar width - getBarCount: function getBarCount() { - var barCount = 0; - helpers.each(this.chart.data.datasets, function(dataset) { - if (helpers.isDatasetVisible(dataset) && dataset.bar) { - ++barCount; - } - }); - return barCount; - }, - - addElements: function() { - this.getDataset().metaData = this.getDataset().metaData || []; - helpers.each(this.getDataset().data, function(value, index) { - this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Rectangle({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - addElementAndReset: function(index) { - this.getDataset().metaData = this.getDataset().metaData || []; - var rectangle = new Chart.elements.Rectangle({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - var numBars = this.getBarCount(); - - this.updateElement(rectangle, index, true, numBars); - this.getDataset().metaData.splice(index, 0, rectangle); - }, - - update: function update(reset) { - var numBars = this.getBarCount(); - - helpers.each(this.getDataset().metaData, function(rectangle, index) { - this.updateElement(rectangle, index, reset, numBars); - }, this); - }, - - updateElement: function updateElement(rectangle, index, reset, numBars) { - - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var yScale = this.getScaleForId(this.getDataset().yAxisID); - - var yScalePoint; - - if (yScale.min < 0 && yScale.max < 0) { - // all less than 0. use the top - yScalePoint = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - yScalePoint = yScale.getPixelForValue(yScale.min); - } else { - yScalePoint = yScale.getPixelForValue(0); - } - - helpers.extend(rectangle, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - - // Desired view properties - _model: { - x: this.calculateBarX(index, this.index), - y: reset ? yScalePoint : this.calculateBarY(index, this.index), - - // Tooltip - label: this.chart.data.labels[index], - datasetLabel: this.getDataset().label, - - // Appearance - base: reset ? yScalePoint : this.calculateBarBase(this.index, index), - width: this.calculateBarWidth(numBars), - backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) - } - }); - rectangle.pivot(); - }, - - calculateBarBase: function(datasetIndex, index) { - - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var yScale = this.getScaleForId(this.getDataset().yAxisID); - - var base = 0; - - if (yScale.options.stacked) { - - var value = this.chart.data.datasets[datasetIndex].data[index]; - - if (value < 0) { - for (var i = 0; i < datasetIndex; i++) { - var negDS = this.chart.data.datasets[i]; - if (helpers.isDatasetVisible(negDS) && negDS.yAxisID === yScale.id && negDS.bar) { - base += negDS.data[index] < 0 ? negDS.data[index] : 0; - } - } - } else { - for (var j = 0; j < datasetIndex; j++) { - var posDS = this.chart.data.datasets[j]; - if (helpers.isDatasetVisible(posDS) && posDS.yAxisID === yScale.id && posDS.bar) { - base += posDS.data[index] > 0 ? posDS.data[index] : 0; - } - } - } - - return yScale.getPixelForValue(base); - } - - base = yScale.getPixelForValue(yScale.min); - - if (yScale.beginAtZero || ((yScale.min <= 0 && yScale.max >= 0) || (yScale.min >= 0 && yScale.max <= 0))) { - base = yScale.getPixelForValue(0, 0); - //base += yScale.options.gridLines.lineWidth; - } else if (yScale.min < 0 && yScale.max < 0) { - // All values are negative. Use the top as the base - base = yScale.getPixelForValue(yScale.max); - } - - return base; - - }, - - getRuler: function() { - - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var yScale = this.getScaleForId(this.getDataset().yAxisID); - var datasetCount = this.getBarCount(); - - var tickWidth = (function() { - var min = xScale.getPixelForTick(1) - xScale.getPixelForTick(0); - for (var i = 2; i < this.getDataset().data.length; i++) { - min = Math.min(xScale.getPixelForTick(i) - xScale.getPixelForTick(i - 1), min); - } - return min; - }).call(this); - var categoryWidth = tickWidth * xScale.options.categoryPercentage; - var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2; - var fullBarWidth = categoryWidth / datasetCount; - var barWidth = fullBarWidth * xScale.options.barPercentage; - var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage); - - return { - datasetCount: datasetCount, - tickWidth: tickWidth, - categoryWidth: categoryWidth, - categorySpacing: categorySpacing, - fullBarWidth: fullBarWidth, - barWidth: barWidth, - barSpacing: barSpacing - }; - }, - - calculateBarWidth: function() { - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var ruler = this.getRuler(); - return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth; - }, - - // Get bar index from the given dataset index accounting for the fact that not all bars are visible - getBarIndex: function(datasetIndex) { - var barIndex = 0; - - for (var j = 0; j < datasetIndex; ++j) { - if (helpers.isDatasetVisible(this.chart.data.datasets[j]) && this.chart.data.datasets[j].bar) { - ++barIndex; - } - } - - return barIndex; - }, - - calculateBarX: function(index, datasetIndex) { - - var yScale = this.getScaleForId(this.getDataset().yAxisID); - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var barIndex = this.getBarIndex(datasetIndex); - - var ruler = this.getRuler(); - var leftTick = xScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo); - leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0; - - if (xScale.options.stacked) { - return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing; - } - - return leftTick + - (ruler.barWidth / 2) + - ruler.categorySpacing + - (ruler.barWidth * barIndex) + - (ruler.barSpacing / 2) + - (ruler.barSpacing * barIndex); - }, - - calculateBarY: function(index, datasetIndex) { - - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var yScale = this.getScaleForId(this.getDataset().yAxisID); - - var value = this.getDataset().data[index]; - - if (yScale.options.stacked) { - - var sumPos = 0, - sumNeg = 0; - - for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - if (helpers.isDatasetVisible(ds) && ds.bar && ds.yAxisID === yScale.id) { - if (ds.data[index] < 0) { - sumNeg += ds.data[index] || 0; - } else { - sumPos += ds.data[index] || 0; - } - } - } - - if (value < 0) { - return yScale.getPixelForValue(sumNeg + value); - } else { - return yScale.getPixelForValue(sumPos + value); - } - - return yScale.getPixelForValue(value); - } - - return yScale.getPixelForValue(value); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getDataset().metaData, function(rectangle, index) { - var d = this.getDataset().data[index]; - if (d !== null && d !== undefined && !isNaN(d)) { - rectangle.transition(easingDecimal).draw(); - } - }, this); - }, - - setHoverStyle: function(rectangle) { - var dataset = this.chart.data.datasets[rectangle._datasetIndex]; - var index = rectangle._index; - - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.hoverBackgroundColor ? rectangle.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(rectangle._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.hoverBorderColor ? rectangle.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(rectangle._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.hoverBorderWidth ? rectangle.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, rectangle._model.borderWidth); - }, - - removeHoverStyle: function(rectangle) { - var dataset = this.chart.data.datasets[rectangle._datasetIndex]; - var index = rectangle._index; - - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth); - } - - }); -}; - -},{}],16:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.bubble = { - hover: { - mode: "single" - }, - - scales: { - xAxes: [{ - type: "linear", // bubble should probably use a linear scale by default - position: "bottom", - id: "x-axis-0" // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: "linear", - position: "left", - id: "y-axis-0" - }] - }, - - tooltips: { - callbacks: { - title: function(tooltipItems, data) { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(tooltipItem, data) { - var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; - var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')'; - } - } - } - }; - - - Chart.controllers.bubble = Chart.DatasetController.extend({ - addElements: function() { - - this.getDataset().metaData = this.getDataset().metaData || []; - - helpers.each(this.getDataset().data, function(value, index) { - this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - addElementAndReset: function(index) { - this.getDataset().metaData = this.getDataset().metaData || []; - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Reset the point - this.updateElement(point, index, true); - - // Add to the points array - this.getDataset().metaData.splice(index, 0, point); - }, - - update: function update(reset) { - var points = this.getDataset().metaData; - - var yScale = this.getScaleForId(this.getDataset().yAxisID); - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - }, - - updateElement: function(point, index, reset) { - var yScale = this.getScaleForId(this.getDataset().yAxisID); - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - helpers.extend(point, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - // Desired view properties - _model: { - x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo), - y: reset ? scaleBase : yScale.getPixelForValue(this.getDataset().data[index], index, this.index), - // Appearance - radius: reset ? 0 : point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[index]), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth), - - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) - } - }); - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - - point.pivot(); - }, - - getRadius: function(value) { - return value.r || this.chart.options.elements.point.radius; - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - - // Transition and Draw the Points - helpers.each(this.getDataset().metaData, function(point, index) { - point.transition(easingDecimal); - point.draw(); - }); - - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth); - } - }); -}; -},{}],17:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.doughnut = { - animation: { - //Boolean - Whether we animate the rotation of the Doughnut - animateRotate: true, - //Boolean - Whether we animate scaling the Doughnut from the centre - animateScale: false - }, - aspectRatio: 1, - hover: { - mode: 'single' - }, - legendCallback: function(chart) { - var text = []; - text.push(''); - return text.join(""); - }, - legend: { - labels: { - generateLabels: function(data) { - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - return { - text: label, - fillStyle: data.datasets[0].backgroundColor[i], - hidden: isNaN(data.datasets[0].data[i]), - - // Extra data used for toggling the correct item - index: i - }; - }); - } else { - return []; - } - } - }, - onClick: function(e, legendItem) { - helpers.each(this.chart.data.datasets, function(dataset) { - dataset.metaHiddenData = dataset.metaHiddenData || []; - var idx = legendItem.index; - - if (!isNaN(dataset.data[idx])) { - dataset.metaHiddenData[idx] = dataset.data[idx]; - dataset.data[idx] = NaN; - } else if (!isNaN(dataset.metaHiddenData[idx])) { - dataset.data[idx] = dataset.metaHiddenData[idx]; - } - }); - - this.chart.update(); - } - }, - - //The percentage of the chart that we cut out of the middle. - cutoutPercentage: 50, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - } - } - } - }; - - Chart.defaults.pie = helpers.clone(Chart.defaults.doughnut); - helpers.extend(Chart.defaults.pie, { - cutoutPercentage: 0 - }); - - - Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ - linkScales: function() { - // no scales for doughnut - }, - - addElements: function() { - this.getDataset().metaData = this.getDataset().metaData || []; - helpers.each(this.getDataset().data, function(value, index) { - this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - addElementAndReset: function(index, colorForNewElement) { - this.getDataset().metaData = this.getDataset().metaData || []; - var arc = new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - if (colorForNewElement && helpers.isArray(this.getDataset().backgroundColor)) { - this.getDataset().backgroundColor.splice(index, 0, colorForNewElement); - } - - // Reset the point - this.updateElement(arc, index, true); - - // Add to the points array - this.getDataset().metaData.splice(index, 0, arc); - }, - - getVisibleDatasetCount: function getVisibleDatasetCount() { - return helpers.where(this.chart.data.datasets, function(ds) { - return helpers.isDatasetVisible(ds); - }).length; - }, - - // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly - getRingIndex: function getRingIndex(datasetIndex) { - var ringIndex = 0; - - for (var j = 0; j < datasetIndex; ++j) { - if (helpers.isDatasetVisible(this.chart.data.datasets[j])) { - ++ringIndex; - } - } - - return ringIndex; - }, - - update: function update(reset) { - var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top); - - this.chart.outerRadius = Math.max((minSize / 2) - this.chart.options.elements.arc.borderWidth / 2, 0); - this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); - this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount(); - - this.getDataset().total = 0; - helpers.each(this.getDataset().data, function(value) { - if (!isNaN(value)) { - this.getDataset().total += Math.abs(value); - } - }, this); - - this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.getRingIndex(this.index)); - this.innerRadius = this.outerRadius - this.chart.radiusLength; - - helpers.each(this.getDataset().metaData, function(arc, index) { - this.updateElement(arc, index, reset); - }, this); - }, - updateElement: function(arc, index, reset) { - var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2; - var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2; - var startAngle = Math.PI * -0.5; // non reset case handled later - var endAngle = Math.PI * -0.5; // non reset case handled later - var circumference = reset && this.chart.options.animation.animateRotate ? 0 : this.calculateCircumference(this.getDataset().data[index]); - var innerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.innerRadius; - var outerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.outerRadius; - - helpers.extend(arc, { - // Utility - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - - // Desired view properties - _model: { - x: centerX, - y: centerY, - startAngle: startAngle, - endAngle: endAngle, - circumference: circumference, - outerRadius: outerRadius, - innerRadius: innerRadius, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.getDataset().label, index, this.chart.data.labels[index]) - } - }); - - // Set correct angles if not resetting - if (!reset) { - - if (index === 0) { - arc._model.startAngle = Math.PI * -0.5; // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function - } else { - arc._model.startAngle = this.getDataset().metaData[index - 1]._model.endAngle; - } - - arc._model.endAngle = arc._model.startAngle + arc._model.circumference; - } - - arc.pivot(); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getDataset().metaData, function(arc, index) { - arc.transition(easingDecimal).draw(); - }); - }, - - setHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth); - }, - - removeHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor); - arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor); - arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth); - }, - - calculateCircumference: function(value) { - if (this.getDataset().total > 0 && !isNaN(value)) { - return (Math.PI * 1.999999) * (value / this.getDataset().total); - } else { - return 0; - } - } - }); -}; -},{}],18:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.line = { - showLines: true, - - hover: { - mode: "label" - }, - - scales: { - xAxes: [{ - type: "category", - id: 'x-axis-0' - }], - yAxes: [{ - type: "linear", - id: 'y-axis-0' - }] - } - }; - - - Chart.controllers.line = Chart.DatasetController.extend({ - addElements: function() { - - this.getDataset().metaData = this.getDataset().metaData || []; - - this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _points: this.getDataset().metaData - }); - - helpers.each(this.getDataset().data, function(value, index) { - this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - addElementAndReset: function(index) { - this.getDataset().metaData = this.getDataset().metaData || []; - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Reset the point - this.updateElement(point, index, true); - - // Add to the points array - this.getDataset().metaData.splice(index, 0, point); - - // Make sure bezier control points are updated - if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0) - this.updateBezierControlPoints(); - }, - - update: function update(reset) { - var line = this.getDataset().metaDataset; - var points = this.getDataset().metaData; - - var yScale = this.getScaleForId(this.getDataset().yAxisID); - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Update Line - if (this.chart.options.showLines) { - // Utility - line._scale = yScale; - line._datasetIndex = this.index; - // Data - line._children = points; - // Model - line._model = { - // Appearance - tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension), - backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor), - borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth), - borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor), - borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle), - borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash), - borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset), - borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle), - fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), - // Scale - scaleTop: yScale.top, - scaleBottom: yScale.bottom, - scaleZero: scaleBase - }; - line.pivot(); - } - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0) - this.updateBezierControlPoints(); - }, - - getPointBackgroundColor: function(point, index) { - var backgroundColor = this.chart.options.elements.point.backgroundColor; - var dataset = this.getDataset(); - - if (point.custom && point.custom.backgroundColor) { - backgroundColor = point.custom.backgroundColor; - } else if (dataset.pointBackgroundColor) { - backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor); - } else if (dataset.backgroundColor) { - backgroundColor = dataset.backgroundColor; - } - - return backgroundColor; - }, - getPointBorderColor: function(point, index) { - var borderColor = this.chart.options.elements.point.borderColor; - var dataset = this.getDataset(); - - if (point.custom && point.custom.borderColor) { - borderColor = point.custom.borderColor; - } else if (dataset.pointBorderColor) { - borderColor = helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, borderColor); - } else if (dataset.borderColor) { - borderColor = dataset.borderColor; - } - - return borderColor; - }, - getPointBorderWidth: function(point, index) { - var borderWidth = this.chart.options.elements.point.borderWidth; - var dataset = this.getDataset(); - - if (point.custom && point.custom.borderWidth !== undefined) { - borderWidth = point.custom.borderWidth; - } else if (dataset.pointBorderWidth !== undefined) { - borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth); - } else if (dataset.borderWidth !== undefined) { - borderWidth = dataset.borderWidth; - } - - return borderWidth; - }, - - updateElement: function(point, index, reset) { - var yScale = this.getScaleForId(this.getDataset().yAxisID); - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Utility - point._chart = this.chart.chart; - point._xScale = xScale; - point._yScale = yScale; - point._datasetIndex = this.index; - point._index = index; - - // Desired view properties - point._model = { - x: xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo), - y: reset ? scaleBase : this.calculatePointY(this.getDataset().data[index], index, this.index, this.chart.isCombo), - // Appearance - tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension), - radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius), - pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle), - backgroundColor: this.getPointBackgroundColor(point, index), - borderColor: this.getPointBorderColor(point, index), - borderWidth: this.getPointBorderWidth(point, index), - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) - }; - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - }, - - calculatePointY: function(value, index, datasetIndex, isCombo) { - - var xScale = this.getScaleForId(this.getDataset().xAxisID); - var yScale = this.getScaleForId(this.getDataset().yAxisID); - - if (yScale.options.stacked) { - - var sumPos = 0, - sumNeg = 0; - - for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - if (ds.type === 'line' && helpers.isDatasetVisible(ds)) { - if (ds.data[index] < 0) { - sumNeg += ds.data[index] || 0; - } else { - sumPos += ds.data[index] || 0; - } - } - } - - if (value < 0) { - return yScale.getPixelForValue(sumNeg + value); - } else { - return yScale.getPixelForValue(sumPos + value); - } - } - - return yScale.getPixelForValue(value); - }, - - updateBezierControlPoints: function() { - // Update bezier control points - helpers.each(this.getDataset().metaData, function(point, index) { - var controlPoints = helpers.splineCurve( - helpers.previousItem(this.getDataset().metaData, index)._model, - point._model, - helpers.nextItem(this.getDataset().metaData, index)._model, - point._model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - // Now pivot the point for animation - point.pivot(); - }, this); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - - // Transition Point Locations - helpers.each(this.getDataset().metaData, function(point) { - point.transition(easingDecimal); - }); - - // Transition and Draw the line - if (this.chart.options.showLines) - this.getDataset().metaDataset.transition(easingDecimal).draw(); - - // Draw the points - helpers.each(this.getDataset().metaData, function(point) { - point.draw(); - }); - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius); - point._model.backgroundColor = this.getPointBackgroundColor(point, index); - point._model.borderColor = this.getPointBorderColor(point, index); - point._model.borderWidth = this.getPointBorderWidth(point, index); - } - }); -}; - -},{}],19:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.polarArea = { - - scale: { - type: "radialLinear", - lineArc: true // so that lines are circular - }, - - //Boolean - Whether to animate the rotation of the chart - animateRotate: true, - animateScale: true, - - aspectRatio: 1, - legendCallback: function(chart) { - var text = []; - text.push(''); - return text.join(""); - }, - legend: { - labels: { - generateLabels: function(data) { - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - return { - text: label, - fillStyle: data.datasets[0].backgroundColor[i], - hidden: isNaN(data.datasets[0].data[i]), - - // Extra data used for toggling the correct item - index: i - }; - }); - } else { - return []; - } - } - }, - onClick: function(e, legendItem) { - helpers.each(this.chart.data.datasets, function(dataset) { - dataset.metaHiddenData = dataset.metaHiddenData || []; - var idx = legendItem.index; - - if (!isNaN(dataset.data[idx])) { - dataset.metaHiddenData[idx] = dataset.data[idx]; - dataset.data[idx] = NaN; - } else if (!isNaN(dataset.metaHiddenData[idx])) { - dataset.data[idx] = dataset.metaHiddenData[idx]; - } - }); - - this.chart.update(); - } - }, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel; - } - } - } - }; - - Chart.controllers.polarArea = Chart.DatasetController.extend({ - linkScales: function() { - // no scales for doughnut - }, - addElements: function() { - this.getDataset().metaData = this.getDataset().metaData || []; - helpers.each(this.getDataset().data, function(value, index) { - this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - addElementAndReset: function(index) { - this.getDataset().metaData = this.getDataset().metaData || []; - var arc = new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Reset the point - this.updateElement(arc, index, true); - - // Add to the points array - this.getDataset().metaData.splice(index, 0, arc); - }, - getVisibleDatasetCount: function getVisibleDatasetCount() { - return helpers.where(this.chart.data.datasets, function(ds) { - return helpers.isDatasetVisible(ds); - }).length; - }, - - update: function update(reset) { - var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top); - this.chart.outerRadius = Math.max((minSize - this.chart.options.elements.arc.borderWidth / 2) / 2, 0); - this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); - this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount(); - - this.getDataset().total = 0; - helpers.each(this.getDataset().data, function(value) { - this.getDataset().total += Math.abs(value); - }, this); - - this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index); - this.innerRadius = this.outerRadius - this.chart.radiusLength; - - helpers.each(this.getDataset().metaData, function(arc, index) { - this.updateElement(arc, index, reset); - }, this); - }, - - updateElement: function(arc, index, reset) { - var circumference = this.calculateCircumference(this.getDataset().data[index]); - var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2; - var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2; - - // If there is NaN data before us, we need to calculate the starting angle correctly. - // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data - var notNullIndex = 0; - for (var i = 0; i < index; ++i) { - if (!isNaN(this.getDataset().data[i])) { - ++notNullIndex; - } - } - - var startAngle = (-0.5 * Math.PI) + (circumference * notNullIndex); - var endAngle = startAngle + circumference; - - var resetModel = { - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: this.chart.options.animateScale ? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]), - startAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : startAngle, - endAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : endAngle, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) - }; - - helpers.extend(arc, { - // Utility - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - _scale: this.chart.scale, - - // Desired view properties - _model: reset ? resetModel : { - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]), - startAngle: startAngle, - endAngle: endAngle, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) - } - }); - - arc.pivot(); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getDataset().metaData, function(arc, index) { - arc.transition(easingDecimal).draw(); - }); - }, - - setHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth); - }, - - removeHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor); - arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor); - arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth); - }, - - calculateCircumference: function(value) { - if (isNaN(value)) { - return 0; - } else { - // Count the number of NaN values - var numNaN = helpers.where(this.getDataset().data, function(data) { - return isNaN(data); - }).length; - - return (2 * Math.PI) / (this.getDataset().data.length - numNaN); - } - } - }); - -}; -},{}],20:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - - Chart.defaults.radar = { - scale: { - type: "radialLinear" - }, - elements: { - line: { - tension: 0 // no bezier in radar - } - } - }; - - Chart.controllers.radar = Chart.DatasetController.extend({ - linkScales: function() { - // No need. Single scale only - }, - - addElements: function() { - - this.getDataset().metaData = this.getDataset().metaData || []; - - this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _points: this.getDataset().metaData, - _loop: true - }); - - helpers.each(this.getDataset().data, function(value, index) { - this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - _model: { - x: 0, //xScale.getPixelForValue(null, index, true), - y: 0 //this.chartArea.bottom, - } - }); - }, this); - }, - addElementAndReset: function(index) { - this.getDataset().metaData = this.getDataset().metaData || []; - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Reset the point - this.updateElement(point, index, true); - - // Add to the points array - this.getDataset().metaData.splice(index, 0, point); - - // Make sure bezier control points are updated - this.updateBezierControlPoints(); - }, - - update: function update(reset) { - - var line = this.getDataset().metaDataset; - var points = this.getDataset().metaData; - - var scale = this.chart.scale; - var scaleBase; - - if (scale.min < 0 && scale.max < 0) { - scaleBase = scale.getPointPositionForValue(0, scale.max); - } else if (scale.min > 0 && scale.max > 0) { - scaleBase = scale.getPointPositionForValue(0, scale.min); - } else { - scaleBase = scale.getPointPositionForValue(0, 0); - } - - helpers.extend(this.getDataset().metaDataset, { - // Utility - _datasetIndex: this.index, - // Data - _children: this.getDataset().metaData, - // Model - _model: { - // Appearance - tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension), - backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor), - borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth), - borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor), - fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), - borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle), - borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash), - borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset), - borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle), - - // Scale - scaleTop: scale.top, - scaleBottom: scale.bottom, - scaleZero: scaleBase - } - }); - - this.getDataset().metaDataset.pivot(); - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - - // Update bezier control points - this.updateBezierControlPoints(); - }, - updateElement: function(point, index, reset) { - var pointPosition = this.chart.scale.getPointPositionForValue(index, this.getDataset().data[index]); - - helpers.extend(point, { - // Utility - _datasetIndex: this.index, - _index: index, - _scale: this.chart.scale, - - // Desired view properties - _model: { - x: reset ? this.chart.scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales - y: reset ? this.chart.scale.yCenter : pointPosition.y, - - // Appearance - tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension), - radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth), - pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle), - - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) - } - }); - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - }, - updateBezierControlPoints: function() { - helpers.each(this.getDataset().metaData, function(point, index) { - var controlPoints = helpers.splineCurve( - helpers.previousItem(this.getDataset().metaData, index, true)._model, - point._model, - helpers.nextItem(this.getDataset().metaData, index, true)._model, - point._model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - // Now pivot the point for animation - point.pivot(); - }, this); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - - // Transition Point Locations - helpers.each(this.getDataset().metaData, function(point, index) { - point.transition(easingDecimal); - }); - - // Transition and Draw the line - this.getDataset().metaDataset.transition(easingDecimal).draw(); - - // Draw the points - helpers.each(this.getDataset().metaData, function(point) { - point.draw(); - }); - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth); - } - }); -}; -},{}],21:[function(require,module,exports){ -/*global window: false */ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.animation = { - duration: 1000, - easing: "easeOutQuart", - onProgress: helpers.noop, - onComplete: helpers.noop - }; - - Chart.Animation = Chart.Element.extend({ - currentStep: null, // the current animation step - numSteps: 60, // default number of steps - easing: "", // the easing to use for this animation - render: null, // render function used by the animation service - - onAnimationProgress: null, // user specified callback to fire on each step of the animation - onAnimationComplete: null // user specified callback to fire when the animation finishes - }); - - Chart.animationService = { - frameDuration: 17, - animations: [], - dropFrames: 0, - request: null, - addAnimation: function(chartInstance, animationObject, duration, lazy) { - - if (!lazy) { - chartInstance.animating = true; - } - - for (var index = 0; index < this.animations.length; ++index) { - if (this.animations[index].chartInstance === chartInstance) { - // replacing an in progress animation - this.animations[index].animationObject = animationObject; - return; - } - } - - this.animations.push({ - chartInstance: chartInstance, - animationObject: animationObject - }); - - // If there are no animations queued, manually kickstart a digest, for lack of a better word - if (this.animations.length === 1) { - this.requestAnimationFrame(); - } - }, - // Cancel the animation for a given chart instance - cancelAnimation: function(chartInstance) { - var index = helpers.findIndex(this.animations, function(animationWrapper) { - return animationWrapper.chartInstance === chartInstance; - }); - - if (index !== -1) { - this.animations.splice(index, 1); - chartInstance.animating = false; - } - }, - requestAnimationFrame: function() { - var me = this; - if (me.request === null) { - // Skip animation frame requests until the active one is executed. - // This can happen when processing mouse events, e.g. 'mousemove' - // and 'mouseout' events will trigger multiple renders. - me.request = helpers.requestAnimFrame.call(window, function() { - me.request = null; - me.startDigest(); - }); - } - }, - startDigest: function() { - - var startTime = Date.now(); - var framesToDrop = 0; - - if (this.dropFrames > 1) { - framesToDrop = Math.floor(this.dropFrames); - this.dropFrames = this.dropFrames % 1; - } - - var i = 0; - while (i < this.animations.length) { - if (this.animations[i].animationObject.currentStep === null) { - this.animations[i].animationObject.currentStep = 0; - } - - this.animations[i].animationObject.currentStep += 1 + framesToDrop; - - if (this.animations[i].animationObject.currentStep > this.animations[i].animationObject.numSteps) { - this.animations[i].animationObject.currentStep = this.animations[i].animationObject.numSteps; - } - - this.animations[i].animationObject.render(this.animations[i].chartInstance, this.animations[i].animationObject); - if (this.animations[i].animationObject.onAnimationProgress && this.animations[i].animationObject.onAnimationProgress.call) { - this.animations[i].animationObject.onAnimationProgress.call(this.animations[i].chartInstance, this.animations[i]); - } - - if (this.animations[i].animationObject.currentStep === this.animations[i].animationObject.numSteps) { - if (this.animations[i].animationObject.onAnimationComplete && this.animations[i].animationObject.onAnimationComplete.call) { - this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance, this.animations[i]); - } - - // executed the last frame. Remove the animation. - this.animations[i].chartInstance.animating = false; - - this.animations.splice(i, 1); - } else { - ++i; - } - } - - var endTime = Date.now(); - var dropFrames = (endTime - startTime) / this.frameDuration; - - this.dropFrames += dropFrames; - - // Do we have more stuff to animate? - if (this.animations.length > 0) { - this.requestAnimationFrame(); - } - } - }; -}; -},{}],22:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - //Create a dictionary of chart types, to allow for extension of existing types - Chart.types = {}; - - //Store a reference to each instance - allowing us to globally resize chart instances on window resize. - //Destroy method on the chart will remove the instance of the chart from this reference. - Chart.instances = {}; - - // Controllers available for dataset visualization eg. bar, line, slice, etc. - Chart.controllers = {}; - - // The main controller of a chart - Chart.Controller = function(instance) { - - this.chart = instance; - this.config = instance.config; - this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {}); - this.id = helpers.uid(); - - Object.defineProperty(this, 'data', { - get: function() { - return this.config.data; - } - }); - - //Add the chart instance to the global namespace - Chart.instances[this.id] = this; - - if (this.options.responsive) { - // Silent resize before chart draws - this.resize(true); - } - - this.initialize(); - - return this; - }; - - helpers.extend(Chart.Controller.prototype, { - - initialize: function initialize() { - - // TODO - // If BeforeInit(this) doesn't return false, proceed - - this.bindEvents(); - - // Make sure controllers are built first so that each dataset is bound to an axis before the scales - // are built - this.ensureScalesHaveIDs(); - this.buildOrUpdateControllers(); - this.buildScales(); - this.buildSurroundingItems(); - this.updateLayout(); - this.resetElements(); - this.initToolTip(); - this.update(); - - // TODO - // If AfterInit(this) doesn't return false, proceed - - return this; - }, - - clear: function clear() { - helpers.clear(this.chart); - return this; - }, - - stop: function stop() { - // Stops any current animation loop occuring - Chart.animationService.cancelAnimation(this); - return this; - }, - - resize: function resize(silent) { - var canvas = this.chart.canvas; - var newWidth = helpers.getMaximumWidth(this.chart.canvas); - var newHeight = (this.options.maintainAspectRatio && isNaN(this.chart.aspectRatio) === false && isFinite(this.chart.aspectRatio) && this.chart.aspectRatio !== 0) ? newWidth / this.chart.aspectRatio : helpers.getMaximumHeight(this.chart.canvas); - - var sizeChanged = this.chart.width !== newWidth || this.chart.height !== newHeight; - - if (!sizeChanged) - return this; - - canvas.width = this.chart.width = newWidth; - canvas.height = this.chart.height = newHeight; - - helpers.retinaScale(this.chart); - - if (!silent) { - this.stop(); - this.update(this.options.responsiveAnimationDuration); - } - - return this; - }, - ensureScalesHaveIDs: function ensureScalesHaveIDs() { - var defaultXAxisID = 'x-axis-'; - var defaultYAxisID = 'y-axis-'; - - if (this.options.scales) { - if (this.options.scales.xAxes && this.options.scales.xAxes.length) { - helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) { - xAxisOptions.id = xAxisOptions.id || (defaultXAxisID + index); - }); - } - - if (this.options.scales.yAxes && this.options.scales.yAxes.length) { - // Build the y axes - helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) { - yAxisOptions.id = yAxisOptions.id || (defaultYAxisID + index); - }); - } - } - }, - buildScales: function buildScales() { - // Map of scale ID to scale object so we can lookup later - this.scales = {}; - - // Build the x axes - if (this.options.scales) { - if (this.options.scales.xAxes && this.options.scales.xAxes.length) { - helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) { - var xType = helpers.getValueOrDefault(xAxisOptions.type, 'category'); - var ScaleClass = Chart.scaleService.getScaleConstructor(xType); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: xAxisOptions, - chart: this, - id: xAxisOptions.id - }); - - this.scales[scale.id] = scale; - } - }, this); - } - - if (this.options.scales.yAxes && this.options.scales.yAxes.length) { - // Build the y axes - helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) { - var yType = helpers.getValueOrDefault(yAxisOptions.type, 'linear'); - var ScaleClass = Chart.scaleService.getScaleConstructor(yType); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: yAxisOptions, - chart: this, - id: yAxisOptions.id - }); - - this.scales[scale.id] = scale; - } - }, this); - } - } - if (this.options.scale) { - // Build radial axes - var ScaleClass = Chart.scaleService.getScaleConstructor(this.options.scale.type); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: this.options.scale, - chart: this - }); - - this.scale = scale; - - this.scales.radialScale = scale; - } - } - - Chart.scaleService.addScalesToLayout(this); - }, - - buildSurroundingItems: function() { - if (this.options.title) { - this.titleBlock = new Chart.Title({ - ctx: this.chart.ctx, - options: this.options.title, - chart: this - }); - - Chart.layoutService.addBox(this, this.titleBlock); - } - - if (this.options.legend) { - this.legend = new Chart.Legend({ - ctx: this.chart.ctx, - options: this.options.legend, - chart: this - }); - - Chart.layoutService.addBox(this, this.legend); - } - }, - - updateLayout: function() { - Chart.layoutService.update(this, this.chart.width, this.chart.height); - }, - - buildOrUpdateControllers: function buildOrUpdateControllers() { - var types = []; - var newControllers = []; - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (!dataset.type) { - dataset.type = this.config.type; - } - - var type = dataset.type; - types.push(type); - - if (dataset.controller) { - dataset.controller.updateIndex(datasetIndex); - } else { - dataset.controller = new Chart.controllers[type](this, datasetIndex); - newControllers.push(dataset.controller); - } - }, this); - - if (types.length > 1) { - for (var i = 1; i < types.length; i++) { - if (types[i] !== types[i - 1]) { - this.isCombo = true; - break; - } - } - } - - return newControllers; - }, - - resetElements: function resetElements() { - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - dataset.controller.reset(); - }); - }, - - update: function update(animationDuration, lazy) { - // In case the entire data object changed - this.tooltip._data = this.data; - - // Make sure dataset controllers are updated and new controllers are reset - var newControllers = this.buildOrUpdateControllers(); - - Chart.layoutService.update(this, this.chart.width, this.chart.height); - - // Can only reset the new controllers after the scales have been updated - helpers.each(newControllers, function(controller) { - controller.reset(); - }); - - // Make sure all dataset controllers have correct meta data counts - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - dataset.controller.buildOrUpdateElements(); - }); - - // This will loop through any data and do the appropriate element update for the type - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - dataset.controller.update(); - }); - this.render(animationDuration, lazy); - }, - - render: function render(duration, lazy) { - - if (this.options.animation && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && this.options.animation.duration !== 0))) { - var animation = new Chart.Animation(); - animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps - animation.easing = this.options.animation.easing; - - // render function - animation.render = function(chartInstance, animationObject) { - var easingFunction = helpers.easingEffects[animationObject.easing]; - var stepDecimal = animationObject.currentStep / animationObject.numSteps; - var easeDecimal = easingFunction(stepDecimal); - - chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep); - }; - - // user events - animation.onAnimationProgress = this.options.animation.onProgress; - animation.onAnimationComplete = this.options.animation.onComplete; - - Chart.animationService.addAnimation(this, animation, duration, lazy); - } else { - this.draw(); - if (this.options.animation && this.options.animation.onComplete && this.options.animation.onComplete.call) { - this.options.animation.onComplete.call(this); - } - } - return this; - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - this.clear(); - - // Draw all the scales - helpers.each(this.boxes, function(box) { - box.draw(this.chartArea); - }, this); - if (this.scale) { - this.scale.draw(); - } - - // Clip out the chart area so that anything outside does not draw. This is necessary for zoom and pan to function - this.chart.ctx.save(); - this.chart.ctx.beginPath(); - this.chart.ctx.rect(this.chartArea.left, this.chartArea.top, this.chartArea.right - this.chartArea.left, this.chartArea.bottom - this.chartArea.top); - this.chart.ctx.clip(); - - // Draw each dataset via its respective controller (reversed to support proper line stacking) - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (helpers.isDatasetVisible(dataset)) { - dataset.controller.draw(ease); - } - }, null, true); - - // Restore from the clipping operation - this.chart.ctx.restore(); - - // Finally draw the tooltip - this.tooltip.transition(easingDecimal).draw(); - }, - - // Get the single element that was clicked on - // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw - getElementAtEvent: function(e) { - - var eventPosition = helpers.getRelativePosition(e, this.chart); - var elementsArray = []; - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (helpers.isDatasetVisible(dataset)) { - helpers.each(dataset.metaData, function(element, index) { - if (element.inRange(eventPosition.x, eventPosition.y)) { - elementsArray.push(element); - return elementsArray; - } - }); - } - }); - - return elementsArray; - }, - - getElementsAtEvent: function(e) { - var eventPosition = helpers.getRelativePosition(e, this.chart); - var elementsArray = []; - - var found = (function() { - if (this.data.datasets) { - for (var i = 0; i < this.data.datasets.length; i++) { - if (helpers.isDatasetVisible(this.data.datasets[i])) { - for (var j = 0; j < this.data.datasets[i].metaData.length; j++) { - if (this.data.datasets[i].metaData[j].inRange(eventPosition.x, eventPosition.y)) { - return this.data.datasets[i].metaData[j]; - } - } - } - } - } - }).call(this); - - if (!found) { - return elementsArray; - } - - helpers.each(this.data.datasets, function(dataset, dsIndex) { - if (helpers.isDatasetVisible(dataset)) { - elementsArray.push(dataset.metaData[found._index]); - } - }); - - return elementsArray; - }, - - getDatasetAtEvent: function(e) { - var elementsArray = this.getElementAtEvent(e); - - if (elementsArray.length > 0) { - elementsArray = this.data.datasets[elementsArray[0]._datasetIndex].metaData; - } - - return elementsArray; - }, - - generateLegend: function generateLegend() { - return this.options.legendCallback(this); - }, - - destroy: function destroy() { - this.clear(); - helpers.unbindEvents(this, this.events); - helpers.removeResizeListener(this.chart.canvas.parentNode); - - // Reset canvas height/width attributes - var canvas = this.chart.canvas; - canvas.width = this.chart.width; - canvas.height = this.chart.height; - - // if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here - if (this.chart.originalDevicePixelRatio !== undefined) { - this.chart.ctx.scale(1 / this.chart.originalDevicePixelRatio, 1 / this.chart.originalDevicePixelRatio); - } - - // Reset to the old style since it may have been changed by the device pixel ratio changes - canvas.style.width = this.chart.originalCanvasStyleWidth; - canvas.style.height = this.chart.originalCanvasStyleHeight; - - delete Chart.instances[this.id]; - }, - - toBase64Image: function toBase64Image() { - return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments); - }, - - initToolTip: function initToolTip() { - this.tooltip = new Chart.Tooltip({ - _chart: this.chart, - _chartInstance: this, - _data: this.data, - _options: this.options - }, this); - }, - - bindEvents: function bindEvents() { - helpers.bindEvents(this, this.options.events, function(evt) { - this.eventHandler(evt); - }); - }, - eventHandler: function eventHandler(e) { - this.lastActive = this.lastActive || []; - this.lastTooltipActive = this.lastTooltipActive || []; - - // Find Active Elements for hover and tooltips - if (e.type === 'mouseout') { - this.active = []; - this.tooltipActive = []; - } else { - - var _this = this; - var getItemsForMode = function(mode) { - switch (mode) { - case 'single': - return _this.getElementAtEvent(e); - case 'label': - return _this.getElementsAtEvent(e); - case 'dataset': - return _this.getDatasetAtEvent(e); - default: - return e; - } - }; - - this.active = getItemsForMode(this.options.hover.mode); - this.tooltipActive = getItemsForMode(this.options.tooltips.mode); - } - - // On Hover hook - if (this.options.hover.onHover) { - this.options.hover.onHover.call(this, this.active); - } - - if (e.type === 'mouseup' || e.type === 'click') { - if (this.options.onClick) { - this.options.onClick.call(this, e, this.active); - } - - if (this.legend && this.legend.handleEvent) { - this.legend.handleEvent(e); - } - } - - var dataset; - var index; - - // Remove styling for last active (even if it may still be active) - if (this.lastActive.length) { - switch (this.options.hover.mode) { - case 'single': - this.data.datasets[this.lastActive[0]._datasetIndex].controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index); - break; - case 'label': - case 'dataset': - for (var i = 0; i < this.lastActive.length; i++) { - if (this.lastActive[i]) - this.data.datasets[this.lastActive[i]._datasetIndex].controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index); - } - break; - default: - // Don't change anything - } - } - - // Built in hover styling - if (this.active.length && this.options.hover.mode) { - switch (this.options.hover.mode) { - case 'single': - this.data.datasets[this.active[0]._datasetIndex].controller.setHoverStyle(this.active[0]); - break; - case 'label': - case 'dataset': - for (var j = 0; j < this.active.length; j++) { - if (this.active[j]) - this.data.datasets[this.active[j]._datasetIndex].controller.setHoverStyle(this.active[j]); - } - break; - default: - // Don't change anything - } - } - - - // Built in Tooltips - if (this.options.tooltips.enabled || this.options.tooltips.custom) { - - // The usual updates - this.tooltip.initialize(); - this.tooltip._active = this.tooltipActive; - this.tooltip.update(); - } - - // Hover animations - this.tooltip.pivot(); - - if (!this.animating) { - var changed; - - helpers.each(this.active, function(element, index) { - if (element !== this.lastActive[index]) { - changed = true; - } - }, this); - - helpers.each(this.tooltipActive, function(element, index) { - if (element !== this.lastTooltipActive[index]) { - changed = true; - } - }, this); - - // If entering, leaving, or changing elements, animate the change via pivot - if ((this.lastActive.length !== this.active.length) || - (this.lastTooltipActive.length !== this.tooltipActive.length) || - changed) { - - this.stop(); - - if (this.options.tooltips.enabled || this.options.tooltips.custom) { - this.tooltip.update(true); - } - - // We only need to render at this point. Updating will cause scales to be recomputed generating flicker & using more - // memory than necessary. - this.render(this.options.hover.animationDuration, true); - } - } - - // Remember Last Actives - this.lastActive = this.active; - this.lastTooltipActive = this.tooltipActive; - return this; - } - }); -}; - -},{}],23:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - // Base class for all dataset controllers (line, bar, etc) - Chart.DatasetController = function(chart, datasetIndex) { - this.initialize.call(this, chart, datasetIndex); - }; - - helpers.extend(Chart.DatasetController.prototype, { - initialize: function(chart, datasetIndex) { - this.chart = chart; - this.index = datasetIndex; - this.linkScales(); - this.addElements(); - }, - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - - linkScales: function() { - if (!this.getDataset().xAxisID) { - this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id; - } - - if (!this.getDataset().yAxisID) { - this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id; - } - }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - - reset: function() { - this.update(true); - }, - - buildOrUpdateElements: function buildOrUpdateElements() { - // Handle the number of data points changing - var numData = this.getDataset().data.length; - var numMetaData = this.getDataset().metaData.length; - - // Make sure that we handle number of datapoints changing - if (numData < numMetaData) { - // Remove excess bars for data points that have been removed - this.getDataset().metaData.splice(numData, numMetaData - numData); - } else if (numData > numMetaData) { - // Add new elements - for (var index = numMetaData; index < numData; ++index) { - this.addElementAndReset(index); - } - } - }, - - // Controllers should implement the following - addElements: helpers.noop, - addElementAndReset: helpers.noop, - draw: helpers.noop, - removeHoverStyle: helpers.noop, - setHoverStyle: helpers.noop, - update: helpers.noop - }); - - Chart.DatasetController.extend = helpers.inherits; - -}; -},{}],24:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.elements = {}; - - Chart.Element = function(configuration) { - helpers.extend(this, configuration); - this.initialize.apply(this, arguments); - }; - helpers.extend(Chart.Element.prototype, { - initialize: function() {}, - pivot: function() { - if (!this._view) { - this._view = helpers.clone(this._model); - } - this._start = helpers.clone(this._view); - return this; - }, - transition: function(ease) { - if (!this._view) { - this._view = helpers.clone(this._model); - } - - // No animation -> No Transition - if (ease === 1) { - this._view = this._model; - this._start = null; - return this; - } - - if (!this._start) { - this.pivot(); - } - - helpers.each(this._model, function(value, key) { - - if (key[0] === '_' || !this._model.hasOwnProperty(key)) { - // Only non-underscored properties - } - - // Init if doesn't exist - else if (!this._view.hasOwnProperty(key)) { - if (typeof value === 'number' && !isNaN(this._view[key])) { - this._view[key] = value * ease; - } else { - this._view[key] = value; - } - } - - // No unnecessary computations - else if (value === this._view[key]) { - // It's the same! Woohoo! - } - - // Color transitions if possible - else if (typeof value === 'string') { - try { - var color = helpers.color(this._start[key]).mix(helpers.color(this._model[key]), ease); - this._view[key] = color.rgbString(); - } catch (err) { - this._view[key] = value; - } - } - // Number transitions - else if (typeof value === 'number') { - var startVal = this._start[key] !== undefined && isNaN(this._start[key]) === false ? this._start[key] : 0; - this._view[key] = ((this._model[key] - startVal) * ease) + startVal; - } - // Everything else - else { - this._view[key] = value; - } - }, this); - - return this; - }, - tooltipPosition: function() { - return { - x: this._model.x, - y: this._model.y - }; - }, - hasValue: function() { - return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y); - } - }); - - Chart.Element.extend = helpers.inherits; - -}; - -},{}],25:[function(require,module,exports){ -/*global window: false */ -/*global document: false */ -"use strict"; - -var color = require('chartjs-color'); - -module.exports = function(Chart) { - - //Global Chart helpers object for utility methods and classes - var helpers = Chart.helpers = {}; - - //-- Basic js utility methods - helpers.each = function(loopable, callback, self, reverse) { - // Check to see if null or undefined firstly. - var i, len; - if (helpers.isArray(loopable)) { - len = loopable.length; - if (reverse) { - for (i = len - 1; i >= 0; i--) { - callback.call(self, loopable[i], i); - } - } else { - for (i = 0; i < len; i++) { - callback.call(self, loopable[i], i); - } - } - } else if (typeof loopable === 'object') { - var keys = Object.keys(loopable); - len = keys.length; - for (i = 0; i < len; i++) { - callback.call(self, loopable[keys[i]], keys[i]); - } - } - }; - helpers.clone = function(obj) { - var objClone = {}; - helpers.each(obj, function(value, key) { - if (obj.hasOwnProperty(key)) { - if (helpers.isArray(value)) { - objClone[key] = value.slice(0); - } else if (typeof value === 'object' && value !== null) { - objClone[key] = helpers.clone(value); - } else { - objClone[key] = value; - } - } - }); - return objClone; - }; - helpers.extend = function(base) { - var len = arguments.length; - var additionalArgs = []; - for (var i = 1; i < len; i++) { - additionalArgs.push(arguments[i]); - } - helpers.each(additionalArgs, function(extensionObject) { - helpers.each(extensionObject, function(value, key) { - if (extensionObject.hasOwnProperty(key)) { - base[key] = value; - } - }); - }); - return base; - }; - // Need a special merge function to chart configs since they are now grouped - helpers.configMerge = function(_base) { - var base = helpers.clone(_base); - helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) { - helpers.each(extension, function(value, key) { - if (extension.hasOwnProperty(key)) { - if (key === 'scales') { - // Scale config merging is complex. Add out own function here for that - base[key] = helpers.scaleMerge(base.hasOwnProperty(key) ? base[key] : {}, value); - - } else if (key === 'scale') { - // Used in polar area & radar charts since there is only one scale - base[key] = helpers.configMerge(base.hasOwnProperty(key) ? base[key] : {}, Chart.scaleService.getScaleDefaults(value.type), value); - } else if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) { - // In this case we have an array of objects replacing another array. Rather than doing a strict replace, - // merge. This allows easy scale option merging - var baseArray = base[key]; - - helpers.each(value, function(valueObj, index) { - - if (index < baseArray.length) { - if (typeof baseArray[index] === 'object' && baseArray[index] !== null && typeof valueObj === 'object' && valueObj !== null) { - // Two objects are coming together. Do a merge of them. - baseArray[index] = helpers.configMerge(baseArray[index], valueObj); - } else { - // Just overwrite in this case since there is nothing to merge - baseArray[index] = valueObj; - } - } else { - baseArray.push(valueObj); // nothing to merge - } - }); - - } else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") { - // If we are overwriting an object with an object, do a merge of the properties. - base[key] = helpers.configMerge(base[key], value); - - } else { - // can just overwrite the value in this case - base[key] = value; - } - } - }); - }); - - return base; - }; - helpers.extendDeep = function(_base) { - return _extendDeep.apply(this, arguments); - - function _extendDeep(dst) { - helpers.each(arguments, function(obj) { - if (obj !== dst) { - helpers.each(obj, function(value, key) { - if (dst[key] && dst[key].constructor && dst[key].constructor === Object) { - _extendDeep(dst[key], value); - } else { - dst[key] = value; - } - }); - } - }); - return dst; - } - }; - helpers.scaleMerge = function(_base, extension) { - var base = helpers.clone(_base); - - helpers.each(extension, function(value, key) { - if (extension.hasOwnProperty(key)) { - if (key === 'xAxes' || key === 'yAxes') { - // These properties are arrays of items - if (base.hasOwnProperty(key)) { - helpers.each(value, function(valueObj, index) { - var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear'); - var axisDefaults = Chart.scaleService.getScaleDefaults(axisType); - if (index >= base[key].length || !base[key][index].type) { - base[key].push(helpers.configMerge(axisDefaults, valueObj)); - } else if (valueObj.type && valueObj.type !== base[key][index].type) { - // Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults - base[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj); - } else { - // Type is the same - base[key][index] = helpers.configMerge(base[key][index], valueObj); - } - }); - } else { - base[key] = []; - helpers.each(value, function(valueObj) { - var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear'); - base[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj)); - }); - } - } else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") { - // If we are overwriting an object with an object, do a merge of the properties. - base[key] = helpers.configMerge(base[key], value); - - } else { - // can just overwrite the value in this case - base[key] = value; - } - } - }); - - return base; - }; - helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) { - if (value === undefined || value === null) { - return defaultValue; - } - - if (helpers.isArray(value)) { - return index < value.length ? value[index] : defaultValue; - } - - return value; - }; - helpers.getValueOrDefault = function(value, defaultValue) { - return value === undefined ? defaultValue : value; - }; - helpers.indexOf = function(arrayToSearch, item) { - if (Array.prototype.indexOf) { - return arrayToSearch.indexOf(item); - } else { - for (var i = 0; i < arrayToSearch.length; i++) { - if (arrayToSearch[i] === item) - return i; - } - return -1; - } - }; - helpers.where = function(collection, filterCallback) { - var filtered = []; - - helpers.each(collection, function(item) { - if (filterCallback(item)) { - filtered.push(item); - } - }); - - return filtered; - }; - helpers.findIndex = function(arrayToSearch, callback, thisArg) { - var index = -1; - if (Array.prototype.findIndex) { - index = arrayToSearch.findIndex(callback, thisArg); - } else { - for (var i = 0; i < arrayToSearch.length; ++i) { - thisArg = thisArg !== undefined ? thisArg : arrayToSearch; - - if (callback.call(thisArg, arrayToSearch[i], i, arrayToSearch)) { - index = i; - break; - } - } - } - - return index; - }; - helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) { - // Default to start of the array - if (startIndex === undefined || startIndex === null) { - startIndex = -1; - } - for (var i = startIndex + 1; i < arrayToSearch.length; i++) { - var currentItem = arrayToSearch[i]; - if (filterCallback(currentItem)) { - return currentItem; - } - } - }; - helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) { - // Default to end of the array - if (startIndex === undefined || startIndex === null) { - startIndex = arrayToSearch.length; - } - for (var i = startIndex - 1; i >= 0; i--) { - var currentItem = arrayToSearch[i]; - if (filterCallback(currentItem)) { - return currentItem; - } - } - }; - helpers.inherits = function(extensions) { - //Basic javascript inheritance based on the model created in Backbone.js - var parent = this; - var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function() { - return parent.apply(this, arguments); - }; - - var Surrogate = function() { - this.constructor = ChartElement; - }; - Surrogate.prototype = parent.prototype; - ChartElement.prototype = new Surrogate(); - - ChartElement.extend = helpers.inherits; - - if (extensions) { - helpers.extend(ChartElement.prototype, extensions); - } - - ChartElement.__super__ = parent.prototype; - - return ChartElement; - }; - helpers.noop = function() {}; - helpers.uid = (function() { - var id = 0; - return function() { - return "chart-" + id++; - }; - })(); - helpers.warn = function(str) { - //Method for warning of errors - if (console && typeof console.warn === "function") { - console.warn(str); - } - }; - //-- Math methods - helpers.isNumber = function(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - }; - helpers.almostEquals = function(x, y, epsilon) { - return Math.abs(x - y) < epsilon; - }; - helpers.max = function(array) { - return array.reduce(function(max, value) { - if (!isNaN(value)) { - return Math.max(max, value); - } else { - return max; - } - }, Number.NEGATIVE_INFINITY); - }; - helpers.min = function(array) { - return array.reduce(function(min, value) { - if (!isNaN(value)) { - return Math.min(min, value); - } else { - return min; - } - }, Number.POSITIVE_INFINITY); - }; - helpers.sign = function(x) { - if (Math.sign) { - return Math.sign(x); - } else { - x = +x; // convert to a number - if (x === 0 || isNaN(x)) { - return x; - } - return x > 0 ? 1 : -1; - } - }; - helpers.log10 = function(x) { - if (Math.log10) { - return Math.log10(x); - } else { - return Math.log(x) / Math.LN10; - } - }; - helpers.toRadians = function(degrees) { - return degrees * (Math.PI / 180); - }; - helpers.toDegrees = function(radians) { - return radians * (180 / Math.PI); - }; - // Gets the angle from vertical upright to the point about a centre. - helpers.getAngleFromPoint = function(centrePoint, anglePoint) { - var distanceFromXCenter = anglePoint.x - centrePoint.x, - distanceFromYCenter = anglePoint.y - centrePoint.y, - radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); - - var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); - - if (angle < (-0.5 * Math.PI)) { - angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2] - } - - return { - angle: angle, - distance: radialDistanceFromCenter - }; - }; - helpers.aliasPixel = function(pixelWidth) { - return (pixelWidth % 2 === 0) ? 0 : 0.5; - }; - helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) { - //Props to Rob Spencer at scaled innovation for his post on splining between points - //http://scaledinnovation.com/analytics/splines/aboutSplines.html - - // This function must also respect "skipped" points - - var previous = firstPoint.skip ? middlePoint : firstPoint, - current = middlePoint, - next = afterPoint.skip ? middlePoint : afterPoint; - - var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2)); - var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2)); - - var s01 = d01 / (d01 + d12); - var s12 = d12 / (d01 + d12); - - // If all points are the same, s01 & s02 will be inf - s01 = isNaN(s01) ? 0 : s01; - s12 = isNaN(s12) ? 0 : s12; - - var fa = t * s01; // scaling factor for triangle Ta - var fb = t * s12; - - return { - previous: { - x: current.x - fa * (next.x - previous.x), - y: current.y - fa * (next.y - previous.y) - }, - next: { - x: current.x + fb * (next.x - previous.x), - y: current.y + fb * (next.y - previous.y) - } - }; - }; - helpers.nextItem = function(collection, index, loop) { - if (loop) { - return index >= collection.length - 1 ? collection[0] : collection[index + 1]; - } - - return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1]; - }; - helpers.previousItem = function(collection, index, loop) { - if (loop) { - return index <= 0 ? collection[collection.length - 1] : collection[index - 1]; - } - return index <= 0 ? collection[0] : collection[index - 1]; - }; - // Implementation of the nice number algorithm used in determining where axis labels will go - helpers.niceNum = function(range, round) { - var exponent = Math.floor(helpers.log10(range)); - var fraction = range / Math.pow(10, exponent); - var niceFraction; - - if (round) { - if (fraction < 1.5) { - niceFraction = 1; - } else if (fraction < 3) { - niceFraction = 2; - } else if (fraction < 7) { - niceFraction = 5; - } else { - niceFraction = 10; - } - } else { - if (fraction <= 1.0) { - niceFraction = 1; - } else if (fraction <= 2) { - niceFraction = 2; - } else if (fraction <= 5) { - niceFraction = 5; - } else { - niceFraction = 10; - } - } - - return niceFraction * Math.pow(10, exponent); - }; - //Easing functions adapted from Robert Penner's easing equations - //http://www.robertpenner.com/easing/ - var easingEffects = helpers.easingEffects = { - linear: function(t) { - return t; - }, - easeInQuad: function(t) { - return t * t; - }, - easeOutQuad: function(t) { - return -1 * t * (t - 2); - }, - easeInOutQuad: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t; - } - return -1 / 2 * ((--t) * (t - 2) - 1); - }, - easeInCubic: function(t) { - return t * t * t; - }, - easeOutCubic: function(t) { - return 1 * ((t = t / 1 - 1) * t * t + 1); - }, - easeInOutCubic: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t * t; - } - return 1 / 2 * ((t -= 2) * t * t + 2); - }, - easeInQuart: function(t) { - return t * t * t * t; - }, - easeOutQuart: function(t) { - return -1 * ((t = t / 1 - 1) * t * t * t - 1); - }, - easeInOutQuart: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t * t * t; - } - return -1 / 2 * ((t -= 2) * t * t * t - 2); - }, - easeInQuint: function(t) { - return 1 * (t /= 1) * t * t * t * t; - }, - easeOutQuint: function(t) { - return 1 * ((t = t / 1 - 1) * t * t * t * t + 1); - }, - easeInOutQuint: function(t) { - if ((t /= 1 / 2) < 1) { - return 1 / 2 * t * t * t * t * t; - } - return 1 / 2 * ((t -= 2) * t * t * t * t + 2); - }, - easeInSine: function(t) { - return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1; - }, - easeOutSine: function(t) { - return 1 * Math.sin(t / 1 * (Math.PI / 2)); - }, - easeInOutSine: function(t) { - return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1); - }, - easeInExpo: function(t) { - return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1)); - }, - easeOutExpo: function(t) { - return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1); - }, - easeInOutExpo: function(t) { - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if ((t /= 1 / 2) < 1) { - return 1 / 2 * Math.pow(2, 10 * (t - 1)); - } - return 1 / 2 * (-Math.pow(2, -10 * --t) + 2); - }, - easeInCirc: function(t) { - if (t >= 1) { - return t; - } - return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1); - }, - easeOutCirc: function(t) { - return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t); - }, - easeInOutCirc: function(t) { - if ((t /= 1 / 2) < 1) { - return -1 / 2 * (Math.sqrt(1 - t * t) - 1); - } - return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1); - }, - easeInElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 1) === 1) { - return 1; - } - if (!p) { - p = 1 * 0.3; - } - if (a < Math.abs(1)) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); - }, - easeOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 1) === 1) { - return 1; - } - if (!p) { - p = 1 * 0.3; - } - if (a < Math.abs(1)) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1; - }, - easeInOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 1 / 2) === 2) { - return 1; - } - if (!p) { - p = 1 * (0.3 * 1.5); - } - if (a < Math.abs(1)) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - if (t < 1) { - return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); - } - return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1; - }, - easeInBack: function(t) { - var s = 1.70158; - return 1 * (t /= 1) * t * ((s + 1) * t - s); - }, - easeOutBack: function(t) { - var s = 1.70158; - return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1); - }, - easeInOutBack: function(t) { - var s = 1.70158; - if ((t /= 1 / 2) < 1) { - return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)); - } - return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); - }, - easeInBounce: function(t) { - return 1 - easingEffects.easeOutBounce(1 - t); - }, - easeOutBounce: function(t) { - if ((t /= 1) < (1 / 2.75)) { - return 1 * (7.5625 * t * t); - } else if (t < (2 / 2.75)) { - return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75); - } else if (t < (2.5 / 2.75)) { - return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375); - } else { - return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375); - } - }, - easeInOutBounce: function(t) { - if (t < 1 / 2) { - return easingEffects.easeInBounce(t * 2) * 0.5; - } - return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5; - } - }; - //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ - helpers.requestAnimFrame = (function() { - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function(callback) { - return window.setTimeout(callback, 1000 / 60); - }; - })(); - helpers.cancelAnimFrame = (function() { - return window.cancelAnimationFrame || - window.webkitCancelAnimationFrame || - window.mozCancelAnimationFrame || - window.oCancelAnimationFrame || - window.msCancelAnimationFrame || - function(callback) { - return window.clearTimeout(callback, 1000 / 60); - }; - })(); - //-- DOM methods - helpers.getRelativePosition = function(evt, chart) { - var mouseX, mouseY; - var e = evt.originalEvent || evt, - canvas = evt.currentTarget || evt.srcElement, - boundingRect = canvas.getBoundingClientRect(); - - if (e.touches && e.touches.length > 0) { - mouseX = e.touches[0].clientX; - mouseY = e.touches[0].clientY; - - } else { - mouseX = e.clientX; - mouseY = e.clientY; - } - - // Scale mouse coordinates into canvas coordinates - // by following the pattern laid out by 'jerryj' in the comments of - // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/ - var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left')); - var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top')); - var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right')); - var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom')); - var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight; - var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom; - - // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However - // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here - mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio); - mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio); - - return { - x: mouseX, - y: mouseY - }; - - }; - helpers.addEvent = function(node, eventType, method) { - if (node.addEventListener) { - node.addEventListener(eventType, method); - } else if (node.attachEvent) { - node.attachEvent("on" + eventType, method); - } else { - node["on" + eventType] = method; - } - }; - helpers.removeEvent = function(node, eventType, handler) { - if (node.removeEventListener) { - node.removeEventListener(eventType, handler, false); - } else if (node.detachEvent) { - node.detachEvent("on" + eventType, handler); - } else { - node["on" + eventType] = helpers.noop; - } - }; - helpers.bindEvents = function(chartInstance, arrayOfEvents, handler) { - // Create the events object if it's not already present - if (!chartInstance.events) - chartInstance.events = {}; - - helpers.each(arrayOfEvents, function(eventName) { - chartInstance.events[eventName] = function() { - handler.apply(chartInstance, arguments); - }; - helpers.addEvent(chartInstance.chart.canvas, eventName, chartInstance.events[eventName]); - }); - }; - helpers.unbindEvents = function(chartInstance, arrayOfEvents) { - helpers.each(arrayOfEvents, function(handler, eventName) { - helpers.removeEvent(chartInstance.chart.canvas, eventName, handler); - }); - }; - - // Private helper function to convert max-width/max-height values that may be percentages into a number - function parseMaxStyle(styleValue, node, parentProperty) { - var valueInPixels; - if (typeof(styleValue) === 'string') { - valueInPixels = parseInt(styleValue, 10); - - if (styleValue.indexOf('%') != -1) { - // percentage * size in dimension - valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty]; - } - } else { - valueInPixels = styleValue; - } - - return valueInPixels; - } - - // Private helper to get a constraint dimension - // @param domNode : the node to check the constraint on - // @param maxStyle : the style that defines the maximum for the direction we are using (max-width / max-height) - // @param percentageProperty : property of parent to use when calculating width as a percentage - function getConstraintDimension(domNode, maxStyle, percentageProperty) { - var constrainedDimension; - var constrainedNode = document.defaultView.getComputedStyle(domNode)[maxStyle]; - var constrainedContainer = document.defaultView.getComputedStyle(domNode.parentNode)[maxStyle]; - var hasCNode = constrainedNode !== null && constrainedNode !== "none"; - var hasCContainer = constrainedContainer !== null && constrainedContainer !== "none"; - - if (hasCNode || hasCContainer) { - constrainedDimension = Math.min((hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : Number.POSITIVE_INFINITY), (hasCContainer ? parseMaxStyle(constrainedContainer, domNode.parentNode, percentageProperty) : Number.POSITIVE_INFINITY)); - } - return constrainedDimension; - } - // returns Number or undefined if no constraint - helpers.getConstraintWidth = function(domNode) { - return getConstraintDimension(domNode, 'max-width', 'clientWidth'); - }; - // returns Number or undefined if no constraint - helpers.getConstraintHeight = function(domNode) { - return getConstraintDimension(domNode, 'max-height', 'clientHeight'); - }; - helpers.getMaximumWidth = function(domNode) { - var container = domNode.parentNode; - var padding = parseInt(helpers.getStyle(container, 'padding-left')) + parseInt(helpers.getStyle(container, 'padding-right')); - - var w = container.clientWidth - padding; - var cw = helpers.getConstraintWidth(domNode); - if (cw !== undefined) { - w = Math.min(w, cw); - } - - return w; - }; - helpers.getMaximumHeight = function(domNode) { - var container = domNode.parentNode; - var padding = parseInt(helpers.getStyle(container, 'padding-top')) + parseInt(helpers.getStyle(container, 'padding-bottom')); - - var h = container.clientHeight - padding; - var ch = helpers.getConstraintHeight(domNode); - if (ch !== undefined) { - h = Math.min(h, ch); - } - - return h; - }; - helpers.getStyle = function(el, property) { - return el.currentStyle ? - el.currentStyle[property] : - document.defaultView.getComputedStyle(el, null).getPropertyValue(property); - }; - helpers.retinaScale = function(chart) { - var ctx = chart.ctx; - var width = chart.canvas.width; - var height = chart.canvas.height; - var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1; - - if (pixelRatio !== 1) { - ctx.canvas.height = height * pixelRatio; - ctx.canvas.width = width * pixelRatio; - ctx.scale(pixelRatio, pixelRatio); - - // Store the device pixel ratio so that we can go backwards in `destroy`. - // The devicePixelRatio changes with zoom, so there are no guarantees that it is the same - // when destroy is called - chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || pixelRatio; - } - - ctx.canvas.style.width = width + 'px'; - ctx.canvas.style.height = height + 'px'; - }; - //-- Canvas methods - helpers.clear = function(chart) { - chart.ctx.clearRect(0, 0, chart.width, chart.height); - }; - helpers.fontString = function(pixelSize, fontStyle, fontFamily) { - return fontStyle + " " + pixelSize + "px " + fontFamily; - }; - helpers.longestText = function(ctx, font, arrayOfStrings, cache) { - cache = cache || {}; - cache.data = cache.data || {}; - cache.garbageCollect = cache.garbageCollect || []; - - if (cache.font !== font) { - cache.data = {}; - cache.garbageCollect = []; - cache.font = font; - } - - ctx.font = font; - var longest = 0; - helpers.each(arrayOfStrings, function(string) { - // Undefined strings should not be measured - if (string !== undefined && string !== null) { - var textWidth = cache.data[string]; - if (!textWidth) { - textWidth = cache.data[string] = ctx.measureText(string).width; - cache.garbageCollect.push(string); - } - - if (textWidth > longest) { - longest = textWidth; - } - } - }); - - var gcLen = cache.garbageCollect.length / 2; - if (gcLen > arrayOfStrings.length) { - for (var i = 0; i < gcLen; i++) { - delete cache.data[cache.garbageCollect[i]]; - } - cache.garbageCollect.splice(0, gcLen); - } - - return longest; - }; - helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) { - ctx.beginPath(); - ctx.moveTo(x + radius, y); - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); - ctx.closePath(); - }; - helpers.color = function(c) { - if (!color) { - console.log('Color.js not found!'); - return c; - } - - /* global CanvasGradient */ - if (c instanceof CanvasGradient) { - return color(Chart.defaults.global.defaultColor); - } - - return color(c); - }; - helpers.addResizeListener = function(node, callback) { - // Hide an iframe before the node - var hiddenIframe = document.createElement('iframe'); - var hiddenIframeClass = 'chartjs-hidden-iframe'; - - if (hiddenIframe.classlist) { - // can use classlist - hiddenIframe.classlist.add(hiddenIframeClass); - } else { - hiddenIframe.setAttribute('class', hiddenIframeClass); - } - - // Set the style - hiddenIframe.style.width = '100%'; - hiddenIframe.style.display = 'block'; - hiddenIframe.style.border = 0; - hiddenIframe.style.height = 0; - hiddenIframe.style.margin = 0; - hiddenIframe.style.position = 'absolute'; - hiddenIframe.style.left = 0; - hiddenIframe.style.right = 0; - hiddenIframe.style.top = 0; - hiddenIframe.style.bottom = 0; - - // Insert the iframe so that contentWindow is available - node.insertBefore(hiddenIframe, node.firstChild); - - (hiddenIframe.contentWindow || hiddenIframe).onresize = function() { - if (callback) { - callback(); - } - }; - }; - helpers.removeResizeListener = function(node) { - var hiddenIframe = node.querySelector('.chartjs-hidden-iframe'); - - // Remove the resize detect iframe - if (hiddenIframe) { - hiddenIframe.parentNode.removeChild(hiddenIframe); - } - }; - helpers.isArray = function(obj) { - if (!Array.isArray) { - return Object.prototype.toString.call(obj) === '[object Array]'; - } - return Array.isArray(obj); - }; - helpers.pushAllIfDefined = function(element, array) { - if (typeof element === "undefined") { - return; - } - - if (helpers.isArray(element)) { - array.push.apply(array, element); - } else { - array.push(element); - } - }; - helpers.isDatasetVisible = function(dataset) { - return !dataset.hidden; - }; - helpers.callCallback = function(fn, args, _tArg) { - if (fn && typeof fn.call === 'function') { - fn.apply(_tArg, args); - } - }; - -}; - -},{"chartjs-color":5}],26:[function(require,module,exports){ -"use strict"; - -module.exports = function() { - - //Occupy the global variable of Chart, and create a simple base class - var Chart = function(context, config) { - this.config = config; - - // Support a jQuery'd canvas element - if (context.length && context[0].getContext) { - context = context[0]; - } - - // Support a canvas domnode - if (context.getContext) { - context = context.getContext("2d"); - } - - this.ctx = context; - this.canvas = context.canvas; - - // Figure out what the size of the chart will be. - // If the canvas has a specified width and height, we use those else - // we look to see if the canvas node has a CSS width and height. - // If there is still no height, fill the parent container - this.width = context.canvas.width || parseInt(Chart.helpers.getStyle(context.canvas, 'width')) || Chart.helpers.getMaximumWidth(context.canvas); - this.height = context.canvas.height || parseInt(Chart.helpers.getStyle(context.canvas, 'height')) || Chart.helpers.getMaximumHeight(context.canvas); - - this.aspectRatio = this.width / this.height; - - if (isNaN(this.aspectRatio) || isFinite(this.aspectRatio) === false) { - // If the canvas has no size, try and figure out what the aspect ratio will be. - // Some charts prefer square canvases (pie, radar, etc). If that is specified, use that - // else use the canvas default ratio of 2 - this.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2; - } - - // Store the original style of the element so we can set it back - this.originalCanvasStyleWidth = context.canvas.style.width; - this.originalCanvasStyleHeight = context.canvas.style.height; - - // High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale. - Chart.helpers.retinaScale(this); - - if (config) { - this.controller = new Chart.Controller(this); - } - - // Always bind this so that if the responsive state changes we still work - var _this = this; - Chart.helpers.addResizeListener(context.canvas.parentNode, function() { - if (_this.controller && _this.controller.config.options.responsive) { - _this.controller.resize(); - } - }); - - return this.controller ? this.controller : this; - - }; - - //Globally expose the defaults to allow for user updating/changing - Chart.defaults = { - global: { - responsive: true, - responsiveAnimationDuration: 0, - maintainAspectRatio: true, - events: ["mousemove", "mouseout", "click", "touchstart", "touchmove"], - hover: { - onHover: null, - mode: 'single', - animationDuration: 400 - }, - onClick: null, - defaultColor: 'rgba(0,0,0,0.1)', - defaultFontColor: '#666', - defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", - defaultFontSize: 12, - defaultFontStyle: 'normal', - showLines: true, - - // Element defaults defined in element extensions - elements: {}, - - // Legend callback string - legendCallback: function(chart) { - var text = []; - text.push(''); - - return text.join(""); - } - } - }; - - return Chart; - -}; - -},{}],27:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - // The layout service is very self explanatory. It's responsible for the layout within a chart. - // Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need - // It is this service's responsibility of carrying out that layout. - Chart.layoutService = { - defaults: {}, - - // Register a box to a chartInstance. A box is simply a reference to an object that requires layout. eg. Scales, Legend, Plugins. - addBox: function(chartInstance, box) { - if (!chartInstance.boxes) { - chartInstance.boxes = []; - } - chartInstance.boxes.push(box); - }, - - removeBox: function(chartInstance, box) { - if (!chartInstance.boxes) { - return; - } - chartInstance.boxes.splice(chartInstance.boxes.indexOf(box), 1); - }, - - // The most important function - update: function(chartInstance, width, height) { - - if (!chartInstance) { - return; - } - - var xPadding = 0; - var yPadding = 0; - - var leftBoxes = helpers.where(chartInstance.boxes, function(box) { - return box.options.position === "left"; - }); - var rightBoxes = helpers.where(chartInstance.boxes, function(box) { - return box.options.position === "right"; - }); - var topBoxes = helpers.where(chartInstance.boxes, function(box) { - return box.options.position === "top"; - }); - var bottomBoxes = helpers.where(chartInstance.boxes, function(box) { - return box.options.position === "bottom"; - }); - - // Boxes that overlay the chartarea such as the radialLinear scale - var chartAreaBoxes = helpers.where(chartInstance.boxes, function(box) { - return box.options.position === "chartArea"; - }); - - function fullWidthSorter(a, b) { - - } - - // Ensure that full width boxes are at the very top / bottom - topBoxes.sort(function(a, b) { - return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0); - }); - bottomBoxes.sort(function(a, b) { - return (a.options.fullWidth ? 1 : 0) - (b.options.fullWidth ? 1 : 0); - }); - - // Essentially we now have any number of boxes on each of the 4 sides. - // Our canvas looks like the following. - // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and - // B1 is the bottom axis - // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays - // These locations are single-box locations only, when trying to register a chartArea location that is already taken, - // an error will be thrown. - // - // |----------------------------------------------------| - // | T1 (Full Width) | - // |----------------------------------------------------| - // | | | T2 | | - // | |----|-------------------------------------|----| - // | | | C1 | | C2 | | - // | | |----| |----| | - // | | | | | - // | L1 | L2 | ChartArea (C0) | R1 | - // | | | | | - // | | |----| |----| | - // | | | C3 | | C4 | | - // | |----|-------------------------------------|----| - // | | | B1 | | - // |----------------------------------------------------| - // | B2 (Full Width) | - // |----------------------------------------------------| - // - // What we do to find the best sizing, we do the following - // 1. Determine the minimum size of the chart area. - // 2. Split the remaining width equally between each vertical axis - // 3. Split the remaining height equally between each horizontal axis - // 4. Give each layout the maximum size it can be. The layout will return it's minimum size - // 5. Adjust the sizes of each axis based on it's minimum reported size. - // 6. Refit each axis - // 7. Position each axis in the final location - // 8. Tell the chart the final location of the chart area - // 9. Tell any axes that overlay the chart area the positions of the chart area - - // Step 1 - var chartWidth = width - (2 * xPadding); - var chartHeight = height - (2 * yPadding); - var chartAreaWidth = chartWidth / 2; // min 50% - var chartAreaHeight = chartHeight / 2; // min 50% - - // Step 2 - var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length); - - // Step 3 - var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length); - - // Step 4 - var maxChartAreaWidth = chartWidth; - var maxChartAreaHeight = chartHeight; - var minBoxSizes = []; - - helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize); - - function getMinimumBoxSize(box) { - var minSize; - var isHorizontal = box.isHorizontal(); - - if (isHorizontal) { - minSize = box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight); - maxChartAreaHeight -= minSize.height; - } else { - minSize = box.update(verticalBoxWidth, chartAreaHeight); - maxChartAreaWidth -= minSize.width; - } - - minBoxSizes.push({ - horizontal: isHorizontal, - minSize: minSize, - box: box - }); - } - - // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could - // be if the axes are drawn at their minimum sizes. - - // Steps 5 & 6 - var totalLeftBoxesWidth = xPadding; - var totalRightBoxesWidth = xPadding; - var totalTopBoxesHeight = yPadding; - var totalBottomBoxesHeight = yPadding; - - // Update, and calculate the left and right margins for the horizontal boxes - helpers.each(leftBoxes.concat(rightBoxes), fitBox); - - helpers.each(leftBoxes, function(box) { - totalLeftBoxesWidth += box.width; - }); - - helpers.each(rightBoxes, function(box) { - totalRightBoxesWidth += box.width; - }); - - // Set the Left and Right margins for the horizontal boxes - helpers.each(topBoxes.concat(bottomBoxes), fitBox); - - // Function to fit a box - function fitBox(box) { - var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) { - return minBoxSize.box === box; - }); - - if (minBoxSize) { - if (box.isHorizontal()) { - var scaleMargin = { - left: totalLeftBoxesWidth, - right: totalRightBoxesWidth, - top: 0, - bottom: 0 - }; - - // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends - // on the margin. Sometimes they need to increase in size slightly - box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin); - } else { - box.update(minBoxSize.minSize.width, maxChartAreaHeight); - } - } - } - - // Figure out how much margin is on the top and bottom of the vertical boxes - helpers.each(topBoxes, function(box) { - totalTopBoxesHeight += box.height; - }); - - helpers.each(bottomBoxes, function(box) { - totalBottomBoxesHeight += box.height; - }); - - // Let the left layout know the final margin - helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox); - - function finalFitVerticalBox(box) { - var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) { - return minBoxSize.box === box; - }); - - var scaleMargin = { - left: 0, - right: 0, - top: totalTopBoxesHeight, - bottom: totalBottomBoxesHeight - }; - - if (minBoxSize) { - box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin); - } - } - - // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance) - totalLeftBoxesWidth = xPadding; - totalRightBoxesWidth = xPadding; - totalTopBoxesHeight = yPadding; - totalBottomBoxesHeight = yPadding; - - helpers.each(leftBoxes, function(box) { - totalLeftBoxesWidth += box.width; - }); - - helpers.each(rightBoxes, function(box) { - totalRightBoxesWidth += box.width; - }); - - helpers.each(topBoxes, function(box) { - totalTopBoxesHeight += box.height; - }); - helpers.each(bottomBoxes, function(box) { - totalBottomBoxesHeight += box.height; - }); - - // Figure out if our chart area changed. This would occur if the dataset layout label rotation - // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do - // without calling `fit` again - var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight; - var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth; - - if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) { - helpers.each(leftBoxes, function(box) { - box.height = newMaxChartAreaHeight; - }); - - helpers.each(rightBoxes, function(box) { - box.height = newMaxChartAreaHeight; - }); - - helpers.each(topBoxes, function(box) { - box.width = newMaxChartAreaWidth; - }); - - helpers.each(bottomBoxes, function(box) { - box.width = newMaxChartAreaWidth; - }); - - maxChartAreaHeight = newMaxChartAreaHeight; - maxChartAreaWidth = newMaxChartAreaWidth; - } - - // Step 7 - Position the boxes - var left = xPadding; - var top = yPadding; - var right = 0; - var bottom = 0; - - helpers.each(leftBoxes.concat(topBoxes), placeBox); - - // Account for chart width and height - left += maxChartAreaWidth; - top += maxChartAreaHeight; - - helpers.each(rightBoxes, placeBox); - helpers.each(bottomBoxes, placeBox); - - function placeBox(box) { - if (box.isHorizontal()) { - box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth; - box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth; - box.top = top; - box.bottom = top + box.height; - - // Move to next point - top = box.bottom; - - } else { - - box.left = left; - box.right = left + box.width; - box.top = totalTopBoxesHeight; - box.bottom = totalTopBoxesHeight + maxChartAreaHeight; - - // Move to next point - left = box.right; - } - } - - // Step 8 - chartInstance.chartArea = { - left: totalLeftBoxesWidth, - top: totalTopBoxesHeight, - right: totalLeftBoxesWidth + maxChartAreaWidth, - bottom: totalTopBoxesHeight + maxChartAreaHeight - }; - - // Step 9 - helpers.each(chartAreaBoxes, function(box) { - box.left = chartInstance.chartArea.left; - box.top = chartInstance.chartArea.top; - box.right = chartInstance.chartArea.right; - box.bottom = chartInstance.chartArea.bottom; - - box.update(maxChartAreaWidth, maxChartAreaHeight); - }); - } - }; -}; - -},{}],28:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.legend = { - - display: true, - position: 'top', - fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes) - reverse: false, - - // a callback that will handle - onClick: function(e, legendItem) { - var dataset = this.chart.data.datasets[legendItem.datasetIndex]; - dataset.hidden = !dataset.hidden; - - // We hid a dataset ... rerender the chart - this.chart.update(); - }, - - labels: { - boxWidth: 40, - padding: 10, - // Generates labels shown in the legend - // Valid properties to return: - // text : text to display - // fillStyle : fill of coloured box - // strokeStyle: stroke of coloured box - // hidden : if this legend item refers to a hidden item - // lineCap : cap style for line - // lineDash - // lineDashOffset : - // lineJoin : - // lineWidth : - generateLabels: function(data) { - return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) { - return { - text: dataset.label, - fillStyle: dataset.backgroundColor, - hidden: dataset.hidden, - lineCap: dataset.borderCapStyle, - lineDash: dataset.borderDash, - lineDashOffset: dataset.borderDashOffset, - lineJoin: dataset.borderJoinStyle, - lineWidth: dataset.borderWidth, - strokeStyle: dataset.borderColor, - - // Below is extra data used for toggling the datasets - datasetIndex: i - }; - }, this) : []; - } - } - }; - - Chart.Legend = Chart.Element.extend({ - - initialize: function(config) { - helpers.extend(this, config); - - // Contains hit boxes for each dataset (in dataset order) - this.legendHitBoxes = []; - - // Are we in doughnut mode which has a different data type - this.doughnutMode = false; - }, - - // These methods are ordered by lifecyle. Utilities then follow. - // Any function defined here is inherited by all legend types. - // Any function can be extended by the legend type - - beforeUpdate: helpers.noop, - update: function(maxWidth, maxHeight, margins) { - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - this.beforeUpdate(); - - // Absorb the master measurements - this.maxWidth = maxWidth; - this.maxHeight = maxHeight; - this.margins = margins; - - // Dimensions - this.beforeSetDimensions(); - this.setDimensions(); - this.afterSetDimensions(); - // Labels - this.beforeBuildLabels(); - this.buildLabels(); - this.afterBuildLabels(); - - // Fit - this.beforeFit(); - this.fit(); - this.afterFit(); - // - this.afterUpdate(); - - return this.minSize; - - }, - afterUpdate: helpers.noop, - - // - - beforeSetDimensions: helpers.noop, - setDimensions: function() { - // Set the unconstrained dimension before label rotation - if (this.isHorizontal()) { - // Reset position before calculating rotation - this.width = this.maxWidth; - this.left = 0; - this.right = this.width; - } else { - this.height = this.maxHeight; - - // Reset position before calculating rotation - this.top = 0; - this.bottom = this.height; - } - - // Reset padding - this.paddingLeft = 0; - this.paddingTop = 0; - this.paddingRight = 0; - this.paddingBottom = 0; - - // Reset minSize - this.minSize = { - width: 0, - height: 0 - }; - }, - afterSetDimensions: helpers.noop, - - // - - beforeBuildLabels: helpers.noop, - buildLabels: function() { - this.legendItems = this.options.labels.generateLabels.call(this, this.chart.data); - if(this.options.reverse){ - this.legendItems.reverse(); - } - }, - afterBuildLabels: helpers.noop, - - // - - beforeFit: helpers.noop, - fit: function() { - - var ctx = this.ctx; - var fontSize = helpers.getValueOrDefault(this.options.labels.fontSize, Chart.defaults.global.defaultFontSize); - var fontStyle = helpers.getValueOrDefault(this.options.labels.fontStyle, Chart.defaults.global.defaultFontStyle); - var fontFamily = helpers.getValueOrDefault(this.options.labels.fontFamily, Chart.defaults.global.defaultFontFamily); - var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily); - - // Reset hit boxes - this.legendHitBoxes = []; - - // Width - if (this.isHorizontal()) { - this.minSize.width = this.maxWidth; // fill all the width - } else { - this.minSize.width = this.options.display ? 10 : 0; - } - - // height - if (this.isHorizontal()) { - this.minSize.height = this.options.display ? 10 : 0; - } else { - this.minSize.height = this.maxHeight; // fill all the height - } - - // Increase sizes here - if (this.options.display) { - if (this.isHorizontal()) { - // Labels - - // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one - this.lineWidths = [0]; - var totalHeight = this.legendItems.length ? fontSize + (this.options.labels.padding) : 0; - - ctx.textAlign = "left"; - ctx.textBaseline = 'top'; - ctx.font = labelFont; - - helpers.each(this.legendItems, function(legendItem, i) { - var width = this.options.labels.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width; - if (this.lineWidths[this.lineWidths.length - 1] + width + this.options.labels.padding >= this.width) { - totalHeight += fontSize + (this.options.labels.padding); - this.lineWidths[this.lineWidths.length] = this.left; - } - - // Store the hitbox width and height here. Final position will be updated in `draw` - this.legendHitBoxes[i] = { - left: 0, - top: 0, - width: width, - height: fontSize - }; - - this.lineWidths[this.lineWidths.length - 1] += width + this.options.labels.padding; - }, this); - - this.minSize.height += totalHeight; - - } else { - // TODO vertical - } - } - - this.width = this.minSize.width; - this.height = this.minSize.height; - - }, - afterFit: helpers.noop, - - // Shared Methods - isHorizontal: function() { - return this.options.position === "top" || this.options.position === "bottom"; - }, - - // Actualy draw the legend on the canvas - draw: function() { - if (this.options.display) { - var ctx = this.ctx; - var cursor = { - x: this.left + ((this.width - this.lineWidths[0]) / 2), - y: this.top + this.options.labels.padding, - line: 0 - }; - - var fontColor = helpers.getValueOrDefault(this.options.labels.fontColor, Chart.defaults.global.defaultFontColor); - var fontSize = helpers.getValueOrDefault(this.options.labels.fontSize, Chart.defaults.global.defaultFontSize); - var fontStyle = helpers.getValueOrDefault(this.options.labels.fontStyle, Chart.defaults.global.defaultFontStyle); - var fontFamily = helpers.getValueOrDefault(this.options.labels.fontFamily, Chart.defaults.global.defaultFontFamily); - var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily); - - // Horizontal - if (this.isHorizontal()) { - // Labels - ctx.textAlign = "left"; - ctx.textBaseline = 'top'; - ctx.lineWidth = 0.5; - ctx.strokeStyle = fontColor; // for strikethrough effect - ctx.fillStyle = fontColor; // render in correct colour - ctx.font = labelFont; - - helpers.each(this.legendItems, function(legendItem, i) { - var textWidth = ctx.measureText(legendItem.text).width; - var width = this.options.labels.boxWidth + (fontSize / 2) + textWidth; - - if (cursor.x + width >= this.width) { - cursor.y += fontSize + (this.options.labels.padding); - cursor.line++; - cursor.x = this.left + ((this.width - this.lineWidths[cursor.line]) / 2); - } - - // Set the ctx for the box - ctx.save(); - - var itemOrDefault = function(item, defaulVal) { - return item !== undefined ? item : defaulVal; - }; - - ctx.fillStyle = itemOrDefault(legendItem.fillStyle, Chart.defaults.global.defaultColor); - ctx.lineCap = itemOrDefault(legendItem.lineCap, Chart.defaults.global.elements.line.borderCapStyle); - ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, Chart.defaults.global.elements.line.borderDashOffset); - ctx.lineJoin = itemOrDefault(legendItem.lineJoin, Chart.defaults.global.elements.line.borderJoinStyle); - ctx.lineWidth = itemOrDefault(legendItem.lineWidth, Chart.defaults.global.elements.line.borderWidth); - ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, Chart.defaults.global.defaultColor); - - if (ctx.setLineDash) { - // IE 9 and 10 do not support line dash - ctx.setLineDash(itemOrDefault(legendItem.lineDash, Chart.defaults.global.elements.line.borderDash)); - } - - // Draw the box - ctx.strokeRect(cursor.x, cursor.y, this.options.labels.boxWidth, fontSize); - ctx.fillRect(cursor.x, cursor.y, this.options.labels.boxWidth, fontSize); - - ctx.restore(); - - this.legendHitBoxes[i].left = cursor.x; - this.legendHitBoxes[i].top = cursor.y; - - // Fill the actual label - ctx.fillText(legendItem.text, this.options.labels.boxWidth + (fontSize / 2) + cursor.x, cursor.y); - - if (legendItem.hidden) { - // Strikethrough the text if hidden - ctx.beginPath(); - ctx.lineWidth = 2; - ctx.moveTo(this.options.labels.boxWidth + (fontSize / 2) + cursor.x, cursor.y + (fontSize / 2)); - ctx.lineTo(this.options.labels.boxWidth + (fontSize / 2) + cursor.x + textWidth, cursor.y + (fontSize / 2)); - ctx.stroke(); - } - - cursor.x += width + (this.options.labels.padding); - }, this); - } else { - - } - } - }, - - // Handle an event - handleEvent: function(e) { - var position = helpers.getRelativePosition(e, this.chart.chart); - - if (position.x >= this.left && position.x <= this.right && position.y >= this.top && position.y <= this.bottom) { - // See if we are touching one of the dataset boxes - for (var i = 0; i < this.legendHitBoxes.length; ++i) { - var hitBox = this.legendHitBoxes[i]; - - if (position.x >= hitBox.left && position.x <= hitBox.left + hitBox.width && position.y >= hitBox.top && position.y <= hitBox.top + hitBox.height) { - // Touching an element - if (this.options.onClick) { - this.options.onClick.call(this, e, this.legendItems[i]); - } - break; - } - } - } - } - }); - -}; - -},{}],29:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.scale = { - display: true, - - // grid line settings - gridLines: { - display: true, - color: "rgba(0, 0, 0, 0.1)", - lineWidth: 1, - drawOnChartArea: true, - drawTicks: true, - zeroLineWidth: 1, - zeroLineColor: "rgba(0,0,0,0.25)", - offsetGridLines: false - }, - - // scale label - scaleLabel: { - // actual label - labelString: '', - - // display property - display: false - }, - - // label settings - ticks: { - beginAtZero: false, - maxRotation: 90, - mirror: false, - padding: 10, - reverse: false, - display: true, - autoSkip: true, - autoSkipPadding: 20, - callback: function(value) { - return '' + value; - } - } - }; - - Chart.Scale = Chart.Element.extend({ - - // These methods are ordered by lifecyle. Utilities then follow. - // Any function defined here is inherited by all scale types. - // Any function can be extended by the scale type - - beforeUpdate: function() { - helpers.callCallback(this.options.beforeUpdate, [this]); - }, - update: function(maxWidth, maxHeight, margins) { - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - this.beforeUpdate(); - - // Absorb the master measurements - this.maxWidth = maxWidth; - this.maxHeight = maxHeight; - this.margins = helpers.extend({ - left: 0, - right: 0, - top: 0, - bottom: 0 - }, margins); - - // Dimensions - this.beforeSetDimensions(); - this.setDimensions(); - this.afterSetDimensions(); - - // Data min/max - this.beforeDataLimits(); - this.determineDataLimits(); - this.afterDataLimits(); - - // Ticks - this.beforeBuildTicks(); - this.buildTicks(); - this.afterBuildTicks(); - - this.beforeTickToLabelConversion(); - this.convertTicksToLabels(); - this.afterTickToLabelConversion(); - - // Tick Rotation - this.beforeCalculateTickRotation(); - this.calculateTickRotation(); - this.afterCalculateTickRotation(); - // Fit - this.beforeFit(); - this.fit(); - this.afterFit(); - // - this.afterUpdate(); - - return this.minSize; - - }, - afterUpdate: function() { - helpers.callCallback(this.options.afterUpdate, [this]); - }, - - // - - beforeSetDimensions: function() { - helpers.callCallback(this.options.beforeSetDimensions, [this]); - }, - setDimensions: function() { - // Set the unconstrained dimension before label rotation - if (this.isHorizontal()) { - // Reset position before calculating rotation - this.width = this.maxWidth; - this.left = 0; - this.right = this.width; - } else { - this.height = this.maxHeight; - - // Reset position before calculating rotation - this.top = 0; - this.bottom = this.height; - } - - // Reset padding - this.paddingLeft = 0; - this.paddingTop = 0; - this.paddingRight = 0; - this.paddingBottom = 0; - }, - afterSetDimensions: function() { - helpers.callCallback(this.options.afterSetDimensions, [this]); - }, - - // Data limits - beforeDataLimits: function() { - helpers.callCallback(this.options.beforeDataLimits, [this]); - }, - determineDataLimits: helpers.noop, - afterDataLimits: function() { - helpers.callCallback(this.options.afterDataLimits, [this]); - }, - - // - beforeBuildTicks: function() { - helpers.callCallback(this.options.beforeBuildTicks, [this]); - }, - buildTicks: helpers.noop, - afterBuildTicks: function() { - helpers.callCallback(this.options.afterBuildTicks, [this]); - }, - - beforeTickToLabelConversion: function() { - helpers.callCallback(this.options.beforeTickToLabelConversion, [this]); - }, - convertTicksToLabels: function() { - // Convert ticks to strings - this.ticks = this.ticks.map(function(numericalTick, index, ticks) { - if (this.options.ticks.userCallback) { - return this.options.ticks.userCallback(numericalTick, index, ticks); - } - return this.options.ticks.callback(numericalTick, index, ticks); - }, - this); - }, - afterTickToLabelConversion: function() { - helpers.callCallback(this.options.afterTickToLabelConversion, [this]); - }, - - // - - beforeCalculateTickRotation: function() { - helpers.callCallback(this.options.beforeCalculateTickRotation, [this]); - }, - calculateTickRotation: function() { - //Get the width of each grid by calculating the difference - //between x offsets between 0 and 1. - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); - var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - this.ctx.font = tickLabelFont; - - var firstWidth = this.ctx.measureText(this.ticks[0]).width; - var lastWidth = this.ctx.measureText(this.ticks[this.ticks.length - 1]).width; - var firstRotated; - - this.labelRotation = 0; - this.paddingRight = 0; - this.paddingLeft = 0; - - if (this.options.display) { - if (this.isHorizontal()) { - this.paddingRight = lastWidth / 2 + 3; - this.paddingLeft = firstWidth / 2 + 3; - - if (!this.longestTextCache) { - this.longestTextCache = {}; - } - var originalLabelWidth = helpers.longestText(this.ctx, tickLabelFont, this.ticks, this.longestTextCache); - var labelWidth = originalLabelWidth; - var cosRotation; - var sinRotation; - - // Allow 3 pixels x2 padding either side for label readability - // only the index matters for a dataset scale, but we want a consistent interface between scales - var tickWidth = this.getPixelForTick(1) - this.getPixelForTick(0) - 6; - - //Max label rotation can be set or default to 90 - also act as a loop counter - while (labelWidth > tickWidth && this.labelRotation < this.options.ticks.maxRotation) { - cosRotation = Math.cos(helpers.toRadians(this.labelRotation)); - sinRotation = Math.sin(helpers.toRadians(this.labelRotation)); - - firstRotated = cosRotation * firstWidth; - - // We're right aligning the text now. - if (firstRotated + tickFontSize / 2 > this.yLabelWidth) { - this.paddingLeft = firstRotated + tickFontSize / 2; - } - - this.paddingRight = tickFontSize / 2; - - if (sinRotation * originalLabelWidth > this.maxHeight) { - // go back one step - this.labelRotation--; - break; - } - - this.labelRotation++; - labelWidth = cosRotation * originalLabelWidth; - } - } - } - - if (this.margins) { - this.paddingLeft = Math.max(this.paddingLeft - this.margins.left, 0); - this.paddingRight = Math.max(this.paddingRight - this.margins.right, 0); - } - }, - afterCalculateTickRotation: function() { - helpers.callCallback(this.options.afterCalculateTickRotation, [this]); - }, - - // - - beforeFit: function() { - helpers.callCallback(this.options.beforeFit, [this]); - }, - fit: function() { - - this.minSize = { - width: 0, - height: 0 - }; - - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); - var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - - var scaleLabelFontSize = helpers.getValueOrDefault(this.options.scaleLabel.fontSize, Chart.defaults.global.defaultFontSize); - var scaleLabelFontStyle = helpers.getValueOrDefault(this.options.scaleLabel.fontStyle, Chart.defaults.global.defaultFontStyle); - var scaleLabelFontFamily = helpers.getValueOrDefault(this.options.scaleLabel.fontFamily, Chart.defaults.global.defaultFontFamily); - var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily); - - // Width - if (this.isHorizontal()) { - // subtract the margins to line up with the chartArea if we are a full width scale - this.minSize.width = this.isFullWidth() ? this.maxWidth - this.margins.left - this.margins.right : this.maxWidth; - } else { - this.minSize.width = this.options.gridLines.display && this.options.display ? 10 : 0; - } - - // height - if (this.isHorizontal()) { - this.minSize.height = this.options.gridLines.display && this.options.display ? 10 : 0; - } else { - this.minSize.height = this.maxHeight; // fill all the height - } - - // Are we showing a title for the scale? - if (this.options.scaleLabel.display) { - if (this.isHorizontal()) { - this.minSize.height += (scaleLabelFontSize * 1.5); - } else { - this.minSize.width += (scaleLabelFontSize * 1.5); - } - } - - if (this.options.ticks.display && this.options.display) { - // Don't bother fitting the ticks if we are not showing them - if (!this.longestTextCache) { - this.longestTextCache = {}; - } - - var largestTextWidth = helpers.longestText(this.ctx, tickLabelFont, this.ticks, this.longestTextCache); - - if (this.isHorizontal()) { - // A horizontal axis is more constrained by the height. - this.longestLabelWidth = largestTextWidth; - - // TODO - improve this calculation - var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * this.longestLabelWidth) + 1.5 * tickFontSize; - - this.minSize.height = Math.min(this.maxHeight, this.minSize.height + labelHeight); - this.ctx.font = tickLabelFont; - - var firstLabelWidth = this.ctx.measureText(this.ticks[0]).width; - var lastLabelWidth = this.ctx.measureText(this.ticks[this.ticks.length - 1]).width; - - // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated - // by the font height - var cosRotation = Math.cos(helpers.toRadians(this.labelRotation)); - var sinRotation = Math.sin(helpers.toRadians(this.labelRotation)); - this.paddingLeft = this.labelRotation !== 0 ? (cosRotation * firstLabelWidth) + 3 : firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges - this.paddingRight = this.labelRotation !== 0 ? (sinRotation * (tickFontSize / 2)) + 3 : lastLabelWidth / 2 + 3; // when rotated - } else { - // A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first - var maxLabelWidth = this.maxWidth - this.minSize.width; - - // Account for padding - if (!this.options.ticks.mirror) { - largestTextWidth += this.options.ticks.padding; - } - - if (largestTextWidth < maxLabelWidth) { - // We don't need all the room - this.minSize.width += largestTextWidth; - } else { - // Expand to max size - this.minSize.width = this.maxWidth; - } - - this.paddingTop = tickFontSize / 2; - this.paddingBottom = tickFontSize / 2; - } - } - - if (this.margins) { - this.paddingLeft = Math.max(this.paddingLeft - this.margins.left, 0); - this.paddingTop = Math.max(this.paddingTop - this.margins.top, 0); - this.paddingRight = Math.max(this.paddingRight - this.margins.right, 0); - this.paddingBottom = Math.max(this.paddingBottom - this.margins.bottom, 0); - } - - this.width = this.minSize.width; - this.height = this.minSize.height; - - }, - afterFit: function() { - helpers.callCallback(this.options.afterFit, [this]); - }, - - // Shared Methods - isHorizontal: function() { - return this.options.position === "top" || this.options.position === "bottom"; - }, - isFullWidth: function() { - return (this.options.fullWidth); - }, - - // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not - getRightValue: function getRightValue(rawValue) { - // Null and undefined values first - if (rawValue === null || typeof(rawValue) === 'undefined') { - return NaN; - } - // isNaN(object) returns true, so make sure NaN is checking for a number - if (typeof(rawValue) === 'number' && isNaN(rawValue)) { - return NaN; - } - // If it is in fact an object, dive in one more level - if (typeof(rawValue) === "object") { - if (rawValue instanceof Date) { - return rawValue; - } else { - return getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y); - } - } - - // Value is good, return it - return rawValue; - }, - - // Used to get the value to display in the tooltip for the data at the given index - // function getLabelForIndex(index, datasetIndex) - getLabelForIndex: helpers.noop, - - // Used to get data value locations. Value can either be an index or a numerical value - getPixelForValue: helpers.noop, - - // Used for tick location, should - getPixelForTick: function(index, includeOffset) { - if (this.isHorizontal()) { - var innerWidth = this.width - (this.paddingLeft + this.paddingRight); - var tickWidth = innerWidth / Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1); - var pixel = (tickWidth * index) + this.paddingLeft; - - if (includeOffset) { - pixel += tickWidth / 2; - } - - var finalVal = this.left + Math.round(pixel); - finalVal += this.isFullWidth() ? this.margins.left : 0; - return finalVal; - } else { - var innerHeight = this.height - (this.paddingTop + this.paddingBottom); - return this.top + (index * (innerHeight / (this.ticks.length - 1))); - } - }, - - // Utility for getting the pixel location of a percentage of scale - getPixelForDecimal: function(decimal /*, includeOffset*/ ) { - if (this.isHorizontal()) { - var innerWidth = this.width - (this.paddingLeft + this.paddingRight); - var valueOffset = (innerWidth * decimal) + this.paddingLeft; - - var finalVal = this.left + Math.round(valueOffset); - finalVal += this.isFullWidth() ? this.margins.left : 0; - return finalVal; - } else { - return this.top + (decimal * this.height); - } - }, - - // Actualy draw the scale on the canvas - // @param {rectangle} chartArea : the area of the chart to draw full grid lines on - draw: function(chartArea) { - if (this.options.display) { - - var setContextLineSettings; - var isRotated = this.labelRotation !== 0; - var skipRatio; - var scaleLabelX; - var scaleLabelY; - var useAutoskipper = this.options.ticks.autoSkip; - - - // figure out the maximum number of gridlines to show - var maxTicks; - - if (this.options.ticks.maxTicksLimit) { - maxTicks = this.options.ticks.maxTicksLimit; - } - - var tickFontColor = helpers.getValueOrDefault(this.options.ticks.fontColor, Chart.defaults.global.defaultFontColor); - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); - var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - - var scaleLabelFontColor = helpers.getValueOrDefault(this.options.scaleLabel.fontColor, Chart.defaults.global.defaultFontColor); - var scaleLabelFontSize = helpers.getValueOrDefault(this.options.scaleLabel.fontSize, Chart.defaults.global.defaultFontSize); - var scaleLabelFontStyle = helpers.getValueOrDefault(this.options.scaleLabel.fontStyle, Chart.defaults.global.defaultFontStyle); - var scaleLabelFontFamily = helpers.getValueOrDefault(this.options.scaleLabel.fontFamily, Chart.defaults.global.defaultFontFamily); - var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily); - - var cosRotation = Math.cos(helpers.toRadians(this.labelRotation)); - var sinRotation = Math.sin(helpers.toRadians(this.labelRotation)); - var longestRotatedLabel = this.longestLabelWidth * cosRotation; - var rotatedLabelHeight = tickFontSize * sinRotation; - - // Make sure we draw text in the correct color and font - this.ctx.fillStyle = tickFontColor; - - if (this.isHorizontal()) { - setContextLineSettings = true; - var yTickStart = this.options.position === "bottom" ? this.top : this.bottom - 10; - var yTickEnd = this.options.position === "bottom" ? this.top + 10 : this.bottom; - skipRatio = false; - - if (((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) { - skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight))); - } - - // if they defined a max number of ticks, - // increase skipRatio until that number is met - if (maxTicks && this.ticks.length > maxTicks) { - while (!skipRatio || this.ticks.length / (skipRatio || 1) > maxTicks) { - if (!skipRatio) { - skipRatio = 1; - } - skipRatio += 1; - } - } - - if (!useAutoskipper) { - skipRatio = false; - } - - helpers.each(this.ticks, function(label, index) { - // Blank ticks - var isLastTick = this.ticks.length === index + 1; - - // Since we always show the last tick,we need may need to hide the last shown one before - var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio > this.ticks.length); - if (shouldSkip && !isLastTick || (label === undefined || label === null)) { - return; - } - var xLineValue = this.getPixelForTick(index); // xvalues for grid lines - var xLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) - - if (this.options.gridLines.display) { - if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { - // Draw the first index specially - this.ctx.lineWidth = this.options.gridLines.zeroLineWidth; - this.ctx.strokeStyle = this.options.gridLines.zeroLineColor; - setContextLineSettings = true; // reset next time - } else if (setContextLineSettings) { - this.ctx.lineWidth = this.options.gridLines.lineWidth; - this.ctx.strokeStyle = this.options.gridLines.color; - setContextLineSettings = false; - } - - xLineValue += helpers.aliasPixel(this.ctx.lineWidth); - - // Draw the label area - this.ctx.beginPath(); - - if (this.options.gridLines.drawTicks) { - this.ctx.moveTo(xLineValue, yTickStart); - this.ctx.lineTo(xLineValue, yTickEnd); - } - - // Draw the chart area - if (this.options.gridLines.drawOnChartArea) { - this.ctx.moveTo(xLineValue, chartArea.top); - this.ctx.lineTo(xLineValue, chartArea.bottom); - } - - // Need to stroke in the loop because we are potentially changing line widths & colours - this.ctx.stroke(); - } - - if (this.options.ticks.display) { - this.ctx.save(); - this.ctx.translate(xLabelValue, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - 10 : this.top + 10); - this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1); - this.ctx.font = tickLabelFont; - this.ctx.textAlign = (isRotated) ? "right" : "center"; - this.ctx.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top"; - this.ctx.fillText(label, 0, 0); - this.ctx.restore(); - } - }, this); - - if (this.options.scaleLabel.display) { - // Draw the scale label - this.ctx.textAlign = "center"; - this.ctx.textBaseline = 'middle'; - this.ctx.fillStyle = scaleLabelFontColor; // render in correct colour - this.ctx.font = scaleLabelFont; - - scaleLabelX = this.left + ((this.right - this.left) / 2); // midpoint of the width - scaleLabelY = this.options.position === 'bottom' ? this.bottom - (scaleLabelFontSize / 2) : this.top + (scaleLabelFontSize / 2); - - this.ctx.fillText(this.options.scaleLabel.labelString, scaleLabelX, scaleLabelY); - } - - } else { - setContextLineSettings = true; - var xTickStart = this.options.position === "right" ? this.left : this.right - 5; - var xTickEnd = this.options.position === "right" ? this.left + 5 : this.right; - - helpers.each(this.ticks, function(label, index) { - // If the callback returned a null or undefined value, do not draw this line - if (label === undefined || label === null) { - return; - } - - var yLineValue = this.getPixelForTick(index); // xvalues for grid lines - - if (this.options.gridLines.display) { - if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { - // Draw the first index specially - this.ctx.lineWidth = this.options.gridLines.zeroLineWidth; - this.ctx.strokeStyle = this.options.gridLines.zeroLineColor; - setContextLineSettings = true; // reset next time - } else if (setContextLineSettings) { - this.ctx.lineWidth = this.options.gridLines.lineWidth; - this.ctx.strokeStyle = this.options.gridLines.color; - setContextLineSettings = false; - } - - yLineValue += helpers.aliasPixel(this.ctx.lineWidth); - - // Draw the label area - this.ctx.beginPath(); - - if (this.options.gridLines.drawTicks) { - this.ctx.moveTo(xTickStart, yLineValue); - this.ctx.lineTo(xTickEnd, yLineValue); - } - - // Draw the chart area - if (this.options.gridLines.drawOnChartArea) { - this.ctx.moveTo(chartArea.left, yLineValue); - this.ctx.lineTo(chartArea.right, yLineValue); - } - - // Need to stroke in the loop because we are potentially changing line widths & colours - this.ctx.stroke(); - } - - if (this.options.ticks.display) { - var xLabelValue; - var yLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) - - this.ctx.save(); - - if (this.options.position === "left") { - if (this.options.ticks.mirror) { - xLabelValue = this.right + this.options.ticks.padding; - this.ctx.textAlign = "left"; - } else { - xLabelValue = this.right - this.options.ticks.padding; - this.ctx.textAlign = "right"; - } - } else { - // right side - if (this.options.ticks.mirror) { - xLabelValue = this.left - this.options.ticks.padding; - this.ctx.textAlign = "right"; - } else { - xLabelValue = this.left + this.options.ticks.padding; - this.ctx.textAlign = "left"; - } - } - - this.ctx.translate(xLabelValue, yLabelValue); - this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1); - this.ctx.font = tickLabelFont; - this.ctx.textBaseline = "middle"; - this.ctx.fillText(label, 0, 0); - this.ctx.restore(); - } - }, this); - - if (this.options.scaleLabel.display) { - // Draw the scale label - scaleLabelX = this.options.position === 'left' ? this.left + (scaleLabelFontSize / 2) : this.right - (scaleLabelFontSize / 2); - scaleLabelY = this.top + ((this.bottom - this.top) / 2); - var rotation = this.options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI; - - this.ctx.save(); - this.ctx.translate(scaleLabelX, scaleLabelY); - this.ctx.rotate(rotation); - this.ctx.textAlign = "center"; - this.ctx.fillStyle =scaleLabelFontColor; // render in correct colour - this.ctx.font = scaleLabelFont; - this.ctx.textBaseline = 'middle'; - this.ctx.fillText(this.options.scaleLabel.labelString, 0, 0); - this.ctx.restore(); - } - } - - // Draw the line at the edge of the axis - this.ctx.lineWidth = this.options.gridLines.lineWidth; - this.ctx.strokeStyle = this.options.gridLines.color; - var x1 = this.left, - x2 = this.right, - y1 = this.top, - y2 = this.bottom; - - if (this.isHorizontal()) { - y1 = y2 = this.options.position === 'top' ? this.bottom : this.top; - y1 += helpers.aliasPixel(this.ctx.lineWidth); - y2 += helpers.aliasPixel(this.ctx.lineWidth); - } else { - x1 = x2 = this.options.position === 'left' ? this.right : this.left; - x1 += helpers.aliasPixel(this.ctx.lineWidth); - x2 += helpers.aliasPixel(this.ctx.lineWidth); - } - - this.ctx.beginPath(); - this.ctx.moveTo(x1, y1); - this.ctx.lineTo(x2, y2); - this.ctx.stroke(); - } - } - }); -}; -},{}],30:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.scaleService = { - // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then - // use the new chart options to grab the correct scale - constructors: {}, - // Use a registration function so that we can move to an ES6 map when we no longer need to support - // old browsers - - // Scale config defaults - defaults: {}, - registerScaleType: function(type, scaleConstructor, defaults) { - this.constructors[type] = scaleConstructor; - this.defaults[type] = helpers.clone(defaults); - }, - getScaleConstructor: function(type) { - return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined; - }, - getScaleDefaults: function(type) { - // Return the scale defaults merged with the global settings so that we always use the latest ones - return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {}; - }, - addScalesToLayout: function(chartInstance) { - // Adds each scale to the chart.boxes array to be sized accordingly - helpers.each(chartInstance.scales, function(scale) { - Chart.layoutService.addBox(chartInstance, scale); - }); - } - }; -}; -},{}],31:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.title = { - display: false, - position: 'top', - fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes) - - fontStyle: 'bold', - padding: 10, - - // actual title - text: '' - }; - - Chart.Title = Chart.Element.extend({ - - initialize: function(config) { - helpers.extend(this, config); - this.options = helpers.configMerge(Chart.defaults.global.title, config.options); - - // Contains hit boxes for each dataset (in dataset order) - this.legendHitBoxes = []; - }, - - // These methods are ordered by lifecyle. Utilities then follow. - - beforeUpdate: helpers.noop, - update: function(maxWidth, maxHeight, margins) { - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - this.beforeUpdate(); - - // Absorb the master measurements - this.maxWidth = maxWidth; - this.maxHeight = maxHeight; - this.margins = margins; - - // Dimensions - this.beforeSetDimensions(); - this.setDimensions(); - this.afterSetDimensions(); - // Labels - this.beforeBuildLabels(); - this.buildLabels(); - this.afterBuildLabels(); - - // Fit - this.beforeFit(); - this.fit(); - this.afterFit(); - // - this.afterUpdate(); - - return this.minSize; - - }, - afterUpdate: helpers.noop, - - // - - beforeSetDimensions: helpers.noop, - setDimensions: function() { - // Set the unconstrained dimension before label rotation - if (this.isHorizontal()) { - // Reset position before calculating rotation - this.width = this.maxWidth; - this.left = 0; - this.right = this.width; - } else { - this.height = this.maxHeight; - - // Reset position before calculating rotation - this.top = 0; - this.bottom = this.height; - } - - // Reset padding - this.paddingLeft = 0; - this.paddingTop = 0; - this.paddingRight = 0; - this.paddingBottom = 0; - - // Reset minSize - this.minSize = { - width: 0, - height: 0 - }; - }, - afterSetDimensions: helpers.noop, - - // - - beforeBuildLabels: helpers.noop, - buildLabels: helpers.noop, - afterBuildLabels: helpers.noop, - - // - - beforeFit: helpers.noop, - fit: function() { - - var ctx = this.ctx; - var fontSize = helpers.getValueOrDefault(this.options.fontSize, Chart.defaults.global.defaultFontSize); - var fontStyle = helpers.getValueOrDefault(this.options.fontStyle, Chart.defaults.global.defaultFontStyle); - var fontFamily = helpers.getValueOrDefault(this.options.fontFamily, Chart.defaults.global.defaultFontFamily); - var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily); - - // Width - if (this.isHorizontal()) { - this.minSize.width = this.maxWidth; // fill all the width - } else { - this.minSize.width = 0; - } - - // height - if (this.isHorizontal()) { - this.minSize.height = 0; - } else { - this.minSize.height = this.maxHeight; // fill all the height - } - - // Increase sizes here - if (this.isHorizontal()) { - - // Title - if (this.options.display) { - this.minSize.height += fontSize + (this.options.padding * 2); - } - } else { - if (this.options.display) { - this.minSize.width += fontSize + (this.options.padding * 2); - } - } - - this.width = this.minSize.width; - this.height = this.minSize.height; - - }, - afterFit: helpers.noop, - - // Shared Methods - isHorizontal: function() { - return this.options.position === "top" || this.options.position === "bottom"; - }, - - // Actualy draw the title block on the canvas - draw: function() { - if (this.options.display) { - var ctx = this.ctx; - var titleX, titleY; - - var fontColor = helpers.getValueOrDefault(this.options.fontColor, Chart.defaults.global.defaultFontColor); - var fontSize = helpers.getValueOrDefault(this.options.fontSize, Chart.defaults.global.defaultFontSize); - var fontStyle = helpers.getValueOrDefault(this.options.fontStyle, Chart.defaults.global.defaultFontStyle); - var fontFamily = helpers.getValueOrDefault(this.options.fontFamily, Chart.defaults.global.defaultFontFamily); - var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily); - - ctx.fillStyle = fontColor; // render in correct colour - ctx.font = titleFont; - - // Horizontal - if (this.isHorizontal()) { - // Title - ctx.textAlign = "center"; - ctx.textBaseline = 'middle'; - - titleX = this.left + ((this.right - this.left) / 2); // midpoint of the width - titleY = this.top + ((this.bottom - this.top) / 2); // midpoint of the height - - ctx.fillText(this.options.text, titleX, titleY); - } else { - - // Title - titleX = this.options.position === 'left' ? this.left + (fontSize / 2) : this.right - (fontSize / 2); - titleY = this.top + ((this.bottom - this.top) / 2); - var rotation = this.options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI; - - ctx.save(); - ctx.translate(titleX, titleY); - ctx.rotate(rotation); - ctx.textAlign = "center"; - ctx.textBaseline = 'middle'; - ctx.fillText(this.options.text, 0, 0); - ctx.restore(); - } - } - } - }); -}; -},{}],32:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.tooltips = { - enabled: true, - custom: null, - mode: 'single', - backgroundColor: "rgba(0,0,0,0.8)", - titleFontStyle: "bold", - titleSpacing: 2, - titleMarginBottom: 6, - titleColor: "#fff", - titleAlign: "left", - bodySpacing: 2, - bodyColor: "#fff", - bodyAlign: "left", - footerFontStyle: "bold", - footerSpacing: 2, - footerMarginTop: 6, - footerColor: "#fff", - footerAlign: "left", - yPadding: 6, - xPadding: 6, - yAlign : 'center', - xAlign : 'center', - caretSize: 5, - cornerRadius: 6, - multiKeyBackground: '#fff', - callbacks: { - // Args are: (tooltipItems, data) - beforeTitle: helpers.noop, - title: function(tooltipItems, data) { - // Pick first xLabel for now - var title = ''; - - if (tooltipItems.length > 0) { - if (tooltipItems[0].xLabel) { - title = tooltipItems[0].xLabel; - } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) { - title = data.labels[tooltipItems[0].index]; - } - } - - return title; - }, - afterTitle: helpers.noop, - - // Args are: (tooltipItems, data) - beforeBody: helpers.noop, - - // Args are: (tooltipItem, data) - beforeLabel: helpers.noop, - label: function(tooltipItem, data) { - var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; - return datasetLabel + ': ' + tooltipItem.yLabel; - }, - afterLabel: helpers.noop, - - // Args are: (tooltipItems, data) - afterBody: helpers.noop, - - // Args are: (tooltipItems, data) - beforeFooter: helpers.noop, - footer: helpers.noop, - afterFooter: helpers.noop - } - }; - - // Helper to push or concat based on if the 2nd parameter is an array or not - function pushOrConcat(base, toPush) { - if (toPush) { - if (helpers.isArray(toPush)) { - base = base.concat(toPush); - } else { - base.push(toPush); - } - } - - return base; - } - - Chart.Tooltip = Chart.Element.extend({ - initialize: function() { - var options = this._options; - helpers.extend(this, { - _model: { - // Positioning - xPadding: options.tooltips.xPadding, - yPadding: options.tooltips.yPadding, - xAlign : options.tooltips.yAlign, - yAlign : options.tooltips.xAlign, - - // Body - bodyColor: options.tooltips.bodyColor, - _bodyFontFamily: helpers.getValueOrDefault(options.tooltips.bodyFontFamily, Chart.defaults.global.defaultFontFamily), - _bodyFontStyle: helpers.getValueOrDefault(options.tooltips.bodyFontStyle, Chart.defaults.global.defaultFontStyle), - _bodyAlign: options.tooltips.bodyAlign, - bodyFontSize: helpers.getValueOrDefault(options.tooltips.bodyFontSize, Chart.defaults.global.defaultFontSize), - bodySpacing: options.tooltips.bodySpacing, - - // Title - titleColor: options.tooltips.titleColor, - _titleFontFamily: helpers.getValueOrDefault(options.tooltips.titleFontFamily, Chart.defaults.global.defaultFontFamily), - _titleFontStyle: helpers.getValueOrDefault(options.tooltips.titleFontStyle, Chart.defaults.global.defaultFontStyle), - titleFontSize: helpers.getValueOrDefault(options.tooltips.titleFontSize, Chart.defaults.global.defaultFontSize), - _titleAlign: options.tooltips.titleAlign, - titleSpacing: options.tooltips.titleSpacing, - titleMarginBottom: options.tooltips.titleMarginBottom, - - // Footer - footerColor: options.tooltips.footerColor, - _footerFontFamily: helpers.getValueOrDefault(options.tooltips.footerFontFamily, Chart.defaults.global.defaultFontFamily), - _footerFontStyle: helpers.getValueOrDefault(options.tooltips.footerFontStyle, Chart.defaults.global.defaultFontStyle), - footerFontSize: helpers.getValueOrDefault(options.tooltips.footerFontSize, Chart.defaults.global.defaultFontSize), - _footerAlign: options.tooltips.footerAlign, - footerSpacing: options.tooltips.footerSpacing, - footerMarginTop: options.tooltips.footerMarginTop, - - // Appearance - caretSize: options.tooltips.caretSize, - cornerRadius: options.tooltips.cornerRadius, - backgroundColor: options.tooltips.backgroundColor, - opacity: 0, - legendColorBackground: options.tooltips.multiKeyBackground - } - }); - }, - - // Get the title - // Args are: (tooltipItem, data) - getTitle: function() { - var beforeTitle = this._options.tooltips.callbacks.beforeTitle.apply(this, arguments), - title = this._options.tooltips.callbacks.title.apply(this, arguments), - afterTitle = this._options.tooltips.callbacks.afterTitle.apply(this, arguments); - - var lines = []; - lines = pushOrConcat(lines, beforeTitle); - lines = pushOrConcat(lines, title); - lines = pushOrConcat(lines, afterTitle); - - return lines; - }, - - // Args are: (tooltipItem, data) - getBeforeBody: function() { - var lines = this._options.tooltips.callbacks.beforeBody.apply(this, arguments); - return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : []; - }, - - // Args are: (tooltipItem, data) - getBody: function(tooltipItems, data) { - var lines = []; - - helpers.each(tooltipItems, function(bodyItem) { - helpers.pushAllIfDefined(this._options.tooltips.callbacks.beforeLabel.call(this, bodyItem, data), lines); - helpers.pushAllIfDefined(this._options.tooltips.callbacks.label.call(this, bodyItem, data), lines); - helpers.pushAllIfDefined(this._options.tooltips.callbacks.afterLabel.call(this, bodyItem, data), lines); - }, this); - - return lines; - }, - - // Args are: (tooltipItem, data) - getAfterBody: function() { - var lines = this._options.tooltips.callbacks.afterBody.apply(this, arguments); - return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : []; - }, - - // Get the footer and beforeFooter and afterFooter lines - // Args are: (tooltipItem, data) - getFooter: function() { - var beforeFooter = this._options.tooltips.callbacks.beforeFooter.apply(this, arguments); - var footer = this._options.tooltips.callbacks.footer.apply(this, arguments); - var afterFooter = this._options.tooltips.callbacks.afterFooter.apply(this, arguments); - - var lines = []; - lines = pushOrConcat(lines, beforeFooter); - lines = pushOrConcat(lines, footer); - lines = pushOrConcat(lines, afterFooter); - - return lines; - }, - - getAveragePosition: function(elements) { - - if (!elements.length) { - return false; - } - - var xPositions = []; - var yPositions = []; - - helpers.each(elements, function(el) { - if (el) { - var pos = el.tooltipPosition(); - xPositions.push(pos.x); - yPositions.push(pos.y); - } - }); - - var x = 0, - y = 0; - for (var i = 0; i < xPositions.length; i++) { - x += xPositions[i]; - y += yPositions[i]; - } - - return { - x: Math.round(x / xPositions.length), - y: Math.round(y / xPositions.length) - }; - - }, - - update: function(changed) { - if (this._active.length) { - this._model.opacity = 1; - - var element = this._active[0], - labelColors = [], - tooltipPosition; - - var tooltipItems = []; - - if (this._options.tooltips.mode === 'single') { - var yScale = element._yScale || element._scale; // handle radar || polarArea charts - tooltipItems.push({ - xLabel: element._xScale ? element._xScale.getLabelForIndex(element._index, element._datasetIndex) : '', - yLabel: yScale ? yScale.getLabelForIndex(element._index, element._datasetIndex) : '', - index: element._index, - datasetIndex: element._datasetIndex - }); - tooltipPosition = this.getAveragePosition(this._active); - } else { - helpers.each(this._data.datasets, function(dataset, datasetIndex) { - if (!helpers.isDatasetVisible(dataset)) { - return; - } - var currentElement = dataset.metaData[element._index]; - if (currentElement) { - var yScale = element._yScale || element._scale; // handle radar || polarArea charts - - tooltipItems.push({ - xLabel: currentElement._xScale ? currentElement._xScale.getLabelForIndex(currentElement._index, currentElement._datasetIndex) : '', - yLabel: yScale ? yScale.getLabelForIndex(currentElement._index, currentElement._datasetIndex) : '', - index: element._index, - datasetIndex: datasetIndex - }); - } - }, null, element._yScale.options.stacked); - - helpers.each(this._active, function(active) { - if (active) { - labelColors.push({ - borderColor: active._view.borderColor, - backgroundColor: active._view.backgroundColor - }); - } - }, null, element._yScale.options.stacked); - - tooltipPosition = this.getAveragePosition(this._active); - tooltipPosition.y = this._active[0]._yScale.getPixelForDecimal(0.5); - } - - // Build the Text Lines - helpers.extend(this._model, { - title: this.getTitle(tooltipItems, this._data), - beforeBody: this.getBeforeBody(tooltipItems, this._data), - body: this.getBody(tooltipItems, this._data), - afterBody: this.getAfterBody(tooltipItems, this._data), - footer: this.getFooter(tooltipItems, this._data) - }); - - helpers.extend(this._model, { - x: Math.round(tooltipPosition.x), - y: Math.round(tooltipPosition.y), - caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2), - labelColors: labelColors - }); - - // We need to determine alignment of - var tooltipSize = this.getTooltipSize(this._model); - this.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas - - helpers.extend(this._model, this.getBackgroundPoint(this._model, tooltipSize)); - } else { - this._model.opacity = 0; - } - - if (changed && this._options.tooltips.custom) { - this._options.tooltips.custom.call(this, this._model); - } - - return this; - }, - getTooltipSize: function getTooltipSize(vm) { - var ctx = this._chart.ctx; - - var size = { - height: vm.yPadding * 2, // Tooltip Padding - width: 0 - }; - var combinedBodyLength = vm.body.length + vm.beforeBody.length + vm.afterBody.length; - - size.height += vm.title.length * vm.titleFontSize; // Title Lines - size.height += (vm.title.length - 1) * vm.titleSpacing; // Title Line Spacing - size.height += vm.title.length ? vm.titleMarginBottom : 0; // Title's bottom Margin - size.height += combinedBodyLength * vm.bodyFontSize; // Body Lines - size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing - size.height += vm.footer.length ? vm.footerMarginTop : 0; // Footer Margin - size.height += vm.footer.length * (vm.footerFontSize); // Footer Lines - size.height += vm.footer.length ? (vm.footer.length - 1) * vm.footerSpacing : 0; // Footer Line Spacing - - // Width - ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily); - helpers.each(vm.title, function(line) { - size.width = Math.max(size.width, ctx.measureText(line).width); - }); - - ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily); - helpers.each(vm.beforeBody.concat(vm.afterBody), function(line) { - size.width = Math.max(size.width, ctx.measureText(line).width); - }); - helpers.each(vm.body, function(line) { - size.width = Math.max(size.width, ctx.measureText(line).width + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0)); - }, this); - - ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily); - helpers.each(vm.footer, function(line) { - size.width = Math.max(size.width, ctx.measureText(line).width); - }); - size.width += 2 * vm.xPadding; - - return size; - }, - determineAlignment: function determineAlignment(size) { - if (this._model.y < size.height) { - this._model.yAlign = 'top'; - } else if (this._model.y > (this._chart.height - size.height)) { - this._model.yAlign = 'bottom'; - } - - var lf, rf; // functions to determine left, right alignment - var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart - var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges - var _this = this; - var midX = (this._chartInstance.chartArea.left + this._chartInstance.chartArea.right) / 2; - var midY = (this._chartInstance.chartArea.top + this._chartInstance.chartArea.bottom) / 2; - - if (this._model.yAlign === 'center') { - lf = function(x) { - return x <= midX; - }; - rf = function(x) { - return x > midX; - }; - } else { - lf = function(x) { - return x <= (size.width / 2); - }; - rf = function(x) { - return x >= (_this._chart.width - (size.width / 2)); - }; - } - - olf = function(x) { - return x + size.width > _this._chart.width; - }; - orf = function(x) { - return x - size.width < 0; - }; - yf = function(y) { - return y <= midY ? 'top' : 'bottom'; - }; - - if (lf(this._model.x)) { - this._model.xAlign = 'left'; - - // Is tooltip too wide and goes over the right side of the chart.? - if (olf(this._model.x)) { - this._model.xAlign = 'center'; - this._model.yAlign = yf(this._model.y); - } - } else if (rf(this._model.x)) { - this._model.xAlign = 'right'; - - // Is tooltip too wide and goes outside left edge of canvas? - if (orf(this._model.x)) { - this._model.xAlign = 'center'; - this._model.yAlign = yf(this._model.y); - } - } - }, - getBackgroundPoint: function getBackgroundPoint(vm, size) { - // Background Position - var pt = { - x: vm.x, - y: vm.y - }; - - if (vm.xAlign === 'right') { - pt.x -= size.width; - } else if (vm.xAlign === 'center') { - pt.x -= (size.width / 2); - } - - if (vm.yAlign === 'top') { - pt.y += vm.caretPadding + vm.caretSize; - } else if (vm.yAlign === 'bottom') { - pt.y -= size.height + vm.caretPadding + vm.caretSize; - } else { - pt.y -= (size.height / 2); - } - - if (vm.yAlign === 'center') { - if (vm.xAlign === 'left') { - pt.x += vm.caretPadding + vm.caretSize; - } else if (vm.xAlign === 'right') { - pt.x -= vm.caretPadding + vm.caretSize; - } - } else { - if (vm.xAlign === 'left') { - pt.x -= vm.cornerRadius + vm.caretPadding; - } else if (vm.xAlign === 'right') { - pt.x += vm.cornerRadius + vm.caretPadding; - } - } - - return pt; - }, - drawCaret: function drawCaret(tooltipPoint, size, opacity, caretPadding) { - var vm = this._view; - var ctx = this._chart.ctx; - var x1, x2, x3; - var y1, y2, y3; - - if (vm.yAlign === 'center') { - // Left or right side - if (vm.xAlign === 'left') { - x1 = tooltipPoint.x; - x2 = x1 - vm.caretSize; - x3 = x1; - } else { - x1 = tooltipPoint.x + size.width; - x2 = x1 + vm.caretSize; - x3 = x1; - } - - y2 = tooltipPoint.y + (size.height / 2); - y1 = y2 - vm.caretSize; - y3 = y2 + vm.caretSize; - } else { - if (vm.xAlign === 'left') { - x1 = tooltipPoint.x + vm.cornerRadius; - x2 = x1 + vm.caretSize; - x3 = x2 + vm.caretSize; - } else if (vm.xAlign === 'right') { - x1 = tooltipPoint.x + size.width - vm.cornerRadius; - x2 = x1 - vm.caretSize; - x3 = x2 - vm.caretSize; - } else { - x2 = tooltipPoint.x + (size.width / 2); - x1 = x2 - vm.caretSize; - x3 = x2 + vm.caretSize; - } - - if (vm.yAlign === 'top') { - y1 = tooltipPoint.y; - y2 = y1 - vm.caretSize; - y3 = y1; - } else { - y1 = tooltipPoint.y + size.height; - y2 = y1 + vm.caretSize; - y3 = y1; - } - } - - var bgColor = helpers.color(vm.backgroundColor); - ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString(); - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.lineTo(x3, y3); - ctx.closePath(); - ctx.fill(); - }, - drawTitle: function drawTitle(pt, vm, ctx, opacity) { - if (vm.title.length) { - ctx.textAlign = vm._titleAlign; - ctx.textBaseline = "top"; - - var titleColor = helpers.color(vm.titleColor); - ctx.fillStyle = titleColor.alpha(opacity * titleColor.alpha()).rgbString(); - ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily); - - helpers.each(vm.title, function(title, i) { - ctx.fillText(title, pt.x, pt.y); - pt.y += vm.titleFontSize + vm.titleSpacing; // Line Height and spacing - - if (i + 1 === vm.title.length) { - pt.y += vm.titleMarginBottom - vm.titleSpacing; // If Last, add margin, remove spacing - } - }); - } - }, - drawBody: function drawBody(pt, vm, ctx, opacity) { - ctx.textAlign = vm._bodyAlign; - ctx.textBaseline = "top"; - - var bodyColor = helpers.color(vm.bodyColor); - ctx.fillStyle = bodyColor.alpha(opacity * bodyColor.alpha()).rgbString(); - ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily); - - // Before Body - helpers.each(vm.beforeBody, function(beforeBody) { - ctx.fillText(beforeBody, pt.x, pt.y); - pt.y += vm.bodyFontSize + vm.bodySpacing; - }); - - helpers.each(vm.body, function(body, i) { - // Draw Legend-like boxes if needed - if (this._options.tooltips.mode !== 'single') { - // Fill a white rect so that colours merge nicely if the opacity is < 1 - ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString(); - ctx.fillRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize); - - // Border - ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString(); - ctx.strokeRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize); - - // Inner square - ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString(); - ctx.fillRect(pt.x + 1, pt.y + 1, vm.bodyFontSize - 2, vm.bodyFontSize - 2); - - ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbaString(); // Return fill style for text - } - - // Body Line - ctx.fillText(body, pt.x + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0), pt.y); - - pt.y += vm.bodyFontSize + vm.bodySpacing; - }, this); - - // After Body - helpers.each(vm.afterBody, function(afterBody) { - ctx.fillText(afterBody, pt.x, pt.y); - pt.y += vm.bodyFontSize; - }); - - pt.y -= vm.bodySpacing; // Remove last body spacing - }, - drawFooter: function drawFooter(pt, vm, ctx, opacity) { - if (vm.footer.length) { - pt.y += vm.footerMarginTop; - - ctx.textAlign = vm._footerAlign; - ctx.textBaseline = "top"; - - var footerColor = helpers.color(vm.footerColor); - ctx.fillStyle = footerColor.alpha(opacity * footerColor.alpha()).rgbString(); - ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily); - - helpers.each(vm.footer, function(footer) { - ctx.fillText(footer, pt.x, pt.y); - pt.y += vm.footerFontSize + vm.footerSpacing; - }); - } - }, - draw: function draw() { - var ctx = this._chart.ctx; - var vm = this._view; - - if (vm.opacity === 0) { - return; - } - - var caretPadding = vm.caretPadding; - var tooltipSize = this.getTooltipSize(vm); - var pt = { - x: vm.x, - y: vm.y - }; - - // IE11/Edge does not like very small opacities, so snap to 0 - var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity; - - if (this._options.tooltips.enabled) { - // Draw Background - var bgColor = helpers.color(vm.backgroundColor); - ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString(); - helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius); - ctx.fill(); - - // Draw Caret - this.drawCaret(pt, tooltipSize, opacity, caretPadding); - - // Draw Title, Body, and Footer - pt.x += vm.xPadding; - pt.y += vm.yPadding; - - // Titles - this.drawTitle(pt, vm, ctx, opacity); - - // Body - this.drawBody(pt, vm, ctx, opacity); - - // Footer - this.drawFooter(pt, vm, ctx, opacity); - } - } - }); -}; - -},{}],33:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart, moment) { - - var helpers = Chart.helpers; - - Chart.defaults.global.elements.arc = { - backgroundColor: Chart.defaults.global.defaultColor, - borderColor: "#fff", - borderWidth: 2 - }; - - Chart.elements.Arc = Chart.Element.extend({ - inLabelRange: function(mouseX) { - var vm = this._view; - - if (vm) { - return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); - } else { - return false; - } - }, - inRange: function(chartX, chartY) { - - var vm = this._view; - - if (vm) { - var pointRelativePosition = helpers.getAngleFromPoint(vm, { - x: chartX, - y: chartY - }); - - // Put into the range of (-PI/2, 3PI/2] - var startAngle = vm.startAngle < (-0.5 * Math.PI) ? vm.startAngle + (2.0 * Math.PI) : vm.startAngle > (1.5 * Math.PI) ? vm.startAngle - (2.0 * Math.PI) : vm.startAngle; - var endAngle = vm.endAngle < (-0.5 * Math.PI) ? vm.endAngle + (2.0 * Math.PI) : vm.endAngle > (1.5 * Math.PI) ? vm.endAngle - (2.0 * Math.PI) : vm.endAngle; - - //Check if within the range of the open/close angle - var betweenAngles = (pointRelativePosition.angle >= startAngle && pointRelativePosition.angle <= endAngle), - withinRadius = (pointRelativePosition.distance >= vm.innerRadius && pointRelativePosition.distance <= vm.outerRadius); - - return (betweenAngles && withinRadius); - } else { - return false; - } - }, - tooltipPosition: function() { - var vm = this._view; - - var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2), - rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; - return { - x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), - y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) - }; - }, - draw: function() { - - var ctx = this._chart.ctx; - var vm = this._view; - - ctx.beginPath(); - - ctx.arc(vm.x, vm.y, vm.outerRadius, vm.startAngle, vm.endAngle); - - ctx.arc(vm.x, vm.y, vm.innerRadius, vm.endAngle, vm.startAngle, true); - - ctx.closePath(); - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = vm.borderWidth; - - ctx.fillStyle = vm.backgroundColor; - - ctx.fill(); - ctx.lineJoin = 'bevel'; - - if (vm.borderWidth) { - ctx.stroke(); - } - } - }); -}; - -},{}],34:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.elements.line = { - tension: 0.4, - backgroundColor: Chart.defaults.global.defaultColor, - borderWidth: 3, - borderColor: Chart.defaults.global.defaultColor, - borderCapStyle: 'butt', - borderDash: [], - borderDashOffset: 0.0, - borderJoinStyle: 'miter', - fill: true // do we fill in the area between the line and its base axis - }; - - Chart.elements.Line = Chart.Element.extend({ - lineToNextPoint: function(previousPoint, point, nextPoint, skipHandler, previousSkipHandler) { - var ctx = this._chart.ctx; - - if (point._view.skip) { - skipHandler.call(this, previousPoint, point, nextPoint); - } else if (previousPoint._view.skip) { - previousSkipHandler.call(this, previousPoint, point, nextPoint); - } else if (point._view.tension === 0) { - ctx.lineTo(point._view.x, point._view.y); - } else { - // Line between points - ctx.bezierCurveTo( - previousPoint._view.controlPointNextX, - previousPoint._view.controlPointNextY, - point._view.controlPointPreviousX, - point._view.controlPointPreviousY, - point._view.x, - point._view.y - ); - } - }, - - draw: function() { - var _this = this; - - var vm = this._view; - var ctx = this._chart.ctx; - var first = this._children[0]; - var last = this._children[this._children.length - 1]; - - function loopBackToStart(drawLineToCenter) { - if (!first._view.skip && !last._view.skip) { - // Draw a bezier line from last to first - ctx.bezierCurveTo( - last._view.controlPointNextX, - last._view.controlPointNextY, - first._view.controlPointPreviousX, - first._view.controlPointPreviousY, - first._view.x, - first._view.y - ); - } else if (drawLineToCenter) { - // Go to center - ctx.lineTo(_this._view.scaleZero.x, _this._view.scaleZero.y); - } - } - - ctx.save(); - - // If we had points and want to fill this line, do so. - if (this._children.length > 0 && vm.fill) { - // Draw the background first (so the border is always on top) - ctx.beginPath(); - - helpers.each(this._children, function(point, index) { - var previous = helpers.previousItem(this._children, index); - var next = helpers.nextItem(this._children, index); - - // First point moves to it's starting position no matter what - if (index === 0) { - if (this._loop) { - ctx.moveTo(vm.scaleZero.x, vm.scaleZero.y); - } else { - ctx.moveTo(point._view.x, vm.scaleZero); - } - - if (point._view.skip) { - if (!this._loop) { - ctx.moveTo(next._view.x, this._view.scaleZero); - } - } else { - ctx.lineTo(point._view.x, point._view.y); - } - } else { - this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) { - if (this._loop) { - // Go to center - ctx.lineTo(this._view.scaleZero.x, this._view.scaleZero.y); - } else { - ctx.lineTo(previousPoint._view.x, this._view.scaleZero); - ctx.moveTo(nextPoint._view.x, this._view.scaleZero); - } - }, function(previousPoint, point) { - // If we skipped the last point, draw a line to ourselves so that the fill is nice - ctx.lineTo(point._view.x, point._view.y); - }); - } - }, this); - - // For radial scales, loop back around to the first point - if (this._loop) { - loopBackToStart(true); - } else { - //Round off the line by going to the base of the chart, back to the start, then fill. - ctx.lineTo(this._children[this._children.length - 1]._view.x, vm.scaleZero); - ctx.lineTo(this._children[0]._view.x, vm.scaleZero); - } - - ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor; - ctx.closePath(); - ctx.fill(); - } - - // Now draw the line between all the points with any borders - ctx.lineCap = vm.borderCapStyle || Chart.defaults.global.elements.line.borderCapStyle; - - // IE 9 and 10 do not support line dash - if (ctx.setLineDash) { - ctx.setLineDash(vm.borderDash || Chart.defaults.global.elements.line.borderDash); - } - - ctx.lineDashOffset = vm.borderDashOffset || Chart.defaults.global.elements.line.borderDashOffset; - ctx.lineJoin = vm.borderJoinStyle || Chart.defaults.global.elements.line.borderJoinStyle; - ctx.lineWidth = vm.borderWidth || Chart.defaults.global.elements.line.borderWidth; - ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor; - ctx.beginPath(); - - helpers.each(this._children, function(point, index) { - var previous = helpers.previousItem(this._children, index); - var next = helpers.nextItem(this._children, index); - - if (index === 0) { - ctx.moveTo(point._view.x, point._view.y); - } else { - this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) { - ctx.moveTo(nextPoint._view.x, nextPoint._view.y); - }, function(previousPoint, point) { - // If we skipped the last point, move up to our point preventing a line from being drawn - ctx.moveTo(point._view.x, point._view.y); - }); - } - }, this); - - if (this._loop && this._children.length > 0) { - loopBackToStart(); - } - - ctx.stroke(); - ctx.restore(); - } - }); -}; -},{}],35:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.elements.point = { - radius: 3, - pointStyle: 'circle', - backgroundColor: Chart.defaults.global.defaultColor, - borderWidth: 1, - borderColor: Chart.defaults.global.defaultColor, - // Hover - hitRadius: 1, - hoverRadius: 4, - hoverBorderWidth: 1 - }; - - - Chart.elements.Point = Chart.Element.extend({ - inRange: function(mouseX, mouseY) { - var vm = this._view; - - if (vm) { - var hoverRange = vm.hitRadius + vm.radius; - return ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(hoverRange, 2)); - } else { - return false; - } - }, - inLabelRange: function(mouseX) { - var vm = this._view; - - if (vm) { - return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)); - } else { - return false; - } - }, - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y, - padding: vm.radius + vm.borderWidth - }; - }, - draw: function() { - - var vm = this._view; - var ctx = this._chart.ctx; - - - if (vm.skip) { - return; - } - - if (typeof vm.pointStyle === 'object' && ((vm.pointStyle.toString() === '[object HTMLImageElement]') || (vm.pointStyle.toString() === '[object HTMLCanvasElement]'))) { - ctx.drawImage(vm.pointStyle, vm.x - vm.pointStyle.width / 2, vm.y - vm.pointStyle.height / 2); - return; - } - - if (!isNaN(vm.radius) && vm.radius > 0) { - - ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor; - ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, Chart.defaults.global.elements.point.borderWidth); - - ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor; - - var radius = vm.radius; - - var xOffset; - var yOffset; - - switch (vm.pointStyle) { - // Default includes circle - default: ctx.beginPath(); - ctx.arc(vm.x, vm.y, radius, 0, Math.PI * 2); - ctx.closePath(); - ctx.fill(); - break; - case 'triangle': - ctx.beginPath(); - var edgeLength = 3 * radius / Math.sqrt(3); - var height = edgeLength * Math.sqrt(3) / 2; - ctx.moveTo(vm.x - edgeLength / 2, vm.y + height / 3); - ctx.lineTo(vm.x + edgeLength / 2, vm.y + height / 3); - ctx.lineTo(vm.x, vm.y - 2 * height / 3); - ctx.closePath(); - ctx.fill(); - break; - case 'rect': - ctx.fillRect(vm.x - 1 / Math.SQRT2 * radius, vm.y - 1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius); - ctx.strokeRect(vm.x - 1 / Math.SQRT2 * radius, vm.y - 1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius); - break; - case 'rectRot': - ctx.translate(vm.x, vm.y); - ctx.rotate(Math.PI / 4); - ctx.fillRect(-1 / Math.SQRT2 * radius, -1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius); - ctx.strokeRect(-1 / Math.SQRT2 * radius, -1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius); - ctx.setTransform(1, 0, 0, 1, 0, 0); - break; - case 'cross': - ctx.beginPath(); - ctx.moveTo(vm.x, vm.y + radius); - ctx.lineTo(vm.x, vm.y - radius); - ctx.moveTo(vm.x - radius, vm.y); - ctx.lineTo(vm.x + radius, vm.y); - ctx.closePath(); - break; - case 'crossRot': - ctx.beginPath(); - xOffset = Math.cos(Math.PI / 4) * radius; - yOffset = Math.sin(Math.PI / 4) * radius; - ctx.moveTo(vm.x - xOffset, vm.y - yOffset); - ctx.lineTo(vm.x + xOffset, vm.y + yOffset); - ctx.moveTo(vm.x - xOffset, vm.y + yOffset); - ctx.lineTo(vm.x + xOffset, vm.y - yOffset); - ctx.closePath(); - break; - case 'star': - ctx.beginPath(); - ctx.moveTo(vm.x, vm.y + radius); - ctx.lineTo(vm.x, vm.y - radius); - ctx.moveTo(vm.x - radius, vm.y); - ctx.lineTo(vm.x + radius, vm.y); - xOffset = Math.cos(Math.PI / 4) * radius; - yOffset = Math.sin(Math.PI / 4) * radius; - ctx.moveTo(vm.x - xOffset, vm.y - yOffset); - ctx.lineTo(vm.x + xOffset, vm.y + yOffset); - ctx.moveTo(vm.x - xOffset, vm.y + yOffset); - ctx.lineTo(vm.x + xOffset, vm.y - yOffset); - ctx.closePath(); - break; - case 'line': - ctx.beginPath(); - ctx.moveTo(vm.x - radius, vm.y); - ctx.lineTo(vm.x + radius, vm.y); - ctx.closePath(); - break; - case 'dash': - ctx.beginPath(); - ctx.moveTo(vm.x, vm.y); - ctx.lineTo(vm.x + radius, vm.y); - ctx.closePath(); - break; - } - - ctx.stroke(); - } - } - }); -}; -},{}],36:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.elements.rectangle = { - backgroundColor: Chart.defaults.global.defaultColor, - borderWidth: 0, - borderColor: Chart.defaults.global.defaultColor, - borderSkipped: 'bottom' - }; - - Chart.elements.Rectangle = Chart.Element.extend({ - draw: function() { - - var ctx = this._chart.ctx; - var vm = this._view; - - var halfWidth = vm.width / 2, - leftX = vm.x - halfWidth, - rightX = vm.x + halfWidth, - top = vm.base - (vm.base - vm.y), - halfStroke = vm.borderWidth / 2; - - // Canvas doesn't allow us to stroke inside the width so we can - // adjust the sizes to fit if we're setting a stroke on the line - if (vm.borderWidth) { - leftX += halfStroke; - rightX -= halfStroke; - top += halfStroke; - } - - ctx.beginPath(); - - ctx.fillStyle = vm.backgroundColor; - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = vm.borderWidth; - - // Corner points, from bottom-left to bottom-right clockwise - // | 1 2 | - // | 0 3 | - var corners = [ - [leftX, vm.base], - [leftX, top], - [rightX, top], - [rightX, vm.base] - ]; - - // Find first (starting) corner with fallback to 'bottom' - var borders = ['bottom', 'left', 'top', 'right']; - var startCorner = borders.indexOf(vm.borderSkipped, 0); - if (startCorner === -1) - startCorner = 0; - - function cornerAt(index) { - return corners[(startCorner + index) % 4]; - } - - // Draw rectangle from 'startCorner' - ctx.moveTo.apply(ctx, cornerAt(0)); - for (var i = 1; i < 4; i++) - ctx.lineTo.apply(ctx, cornerAt(i)); - - ctx.fill(); - if (vm.borderWidth) { - ctx.stroke(); - } - }, - height: function() { - var vm = this._view; - return vm.base - vm.y; - }, - inRange: function(mouseX, mouseY) { - var vm = this._view; - var inRange = false; - - if (vm) { - if (vm.y < vm.base) { - inRange = (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.y && mouseY <= vm.base); - } else { - inRange = (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.base && mouseY <= vm.y); - } - } - - return inRange; - }, - inLabelRange: function(mouseX) { - var vm = this._view; - - if (vm) { - return (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2); - } else { - return false; - } - }, - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - } - }); - -}; -},{}],37:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - // Default config for a category scale - var defaultConfig = { - position: "bottom" - }; - - var DatasetScale = Chart.Scale.extend({ - buildTicks: function(index) { - this.startIndex = 0; - this.endIndex = this.chart.data.labels.length; - var findIndex; - - if (this.options.ticks.min !== undefined) { - // user specified min value - findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.min); - this.startIndex = findIndex !== -1 ? findIndex : this.startIndex; - } - - if (this.options.ticks.max !== undefined) { - // user specified max value - findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.max); - this.endIndex = findIndex !== -1 ? findIndex : this.endIndex; - } - - // If we are viewing some subset of labels, slice the original array - this.ticks = (this.startIndex === 0 && this.endIndex === this.chart.data.labels.length) ? this.chart.data.labels : this.chart.data.labels.slice(this.startIndex, this.endIndex + 1); - }, - - getLabelForIndex: function(index, datasetIndex) { - return this.ticks[index]; - }, - - // Used to get data value locations. Value can either be an index or a numerical value - getPixelForValue: function(value, index, datasetIndex, includeOffset) { - // 1 is added because we need the length but we have the indexes - var offsetAmt = Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1); - - if (this.isHorizontal()) { - var innerWidth = this.width - (this.paddingLeft + this.paddingRight); - var valueWidth = innerWidth / offsetAmt; - var widthOffset = (valueWidth * (index - this.startIndex)) + this.paddingLeft; - - if (this.options.gridLines.offsetGridLines && includeOffset) { - widthOffset += (valueWidth / 2); - } - - return this.left + Math.round(widthOffset); - } else { - var innerHeight = this.height - (this.paddingTop + this.paddingBottom); - var valueHeight = innerHeight / offsetAmt; - var heightOffset = (valueHeight * (index - this.startIndex)) + this.paddingTop; - - if (this.options.gridLines.offsetGridLines && includeOffset) { - heightOffset += (valueHeight / 2); - } - - return this.top + Math.round(heightOffset); - } - }, - getPixelForTick: function(index, includeOffset) { - return this.getPixelForValue(this.ticks[index], index + this.startIndex, null, includeOffset); - } - }); - - Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig); - -}; -},{}],38:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - var defaultConfig = { - position: "left", - ticks: { - callback: function(tickValue, index, ticks) { - var delta = ticks[1] - ticks[0]; - - // If we have a number like 2.5 as the delta, figure out how many decimal places we need - if (Math.abs(delta) > 1) { - if (tickValue !== Math.floor(tickValue)) { - // not an integer - delta = tickValue - Math.floor(tickValue); - } - } - - var logDelta = helpers.log10(Math.abs(delta)); - var tickString = ''; - - if (tickValue !== 0) { - var numDecimal = -1 * Math.floor(logDelta); - numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places - tickString = tickValue.toFixed(numDecimal); - } else { - tickString = '0'; // never show decimal places for 0 - } - - return tickString; - } - } - }; - - var LinearScale = Chart.Scale.extend({ - determineDataLimits: function() { - // First Calculate the range - this.min = null; - this.max = null; - - if (this.options.stacked) { - var valuesPerType = {}; - var hasPositiveValues = false; - var hasNegativeValues = false; - - helpers.each(this.chart.data.datasets, function(dataset) { - if (valuesPerType[dataset.type] === undefined) { - valuesPerType[dataset.type] = { - positiveValues: [], - negativeValues: [] - }; - } - - // Store these per type - var positiveValues = valuesPerType[dataset.type].positiveValues; - var negativeValues = valuesPerType[dataset.type].negativeValues; - - if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) { - helpers.each(dataset.data, function(rawValue, index) { - - var value = +this.getRightValue(rawValue); - if (isNaN(value)) { - return; - } - - positiveValues[index] = positiveValues[index] || 0; - negativeValues[index] = negativeValues[index] || 0; - - if (this.options.relativePoints) { - positiveValues[index] = 100; - } else { - if (value < 0) { - hasNegativeValues = true; - negativeValues[index] += value; - } else { - hasPositiveValues = true; - positiveValues[index] += value; - } - } - }, this); - } - }, this); - - helpers.each(valuesPerType, function(valuesForType) { - var values = valuesForType.positiveValues.concat(valuesForType.negativeValues); - var minVal = helpers.min(values); - var maxVal = helpers.max(values); - this.min = this.min === null ? minVal : Math.min(this.min, minVal); - this.max = this.max === null ? maxVal : Math.max(this.max, maxVal); - }, this); - - } else { - helpers.each(this.chart.data.datasets, function(dataset) { - if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) { - helpers.each(dataset.data, function(rawValue, index) { - var value = +this.getRightValue(rawValue); - if (isNaN(value)) { - return; - } - - if (this.min === null) { - this.min = value; - } else if (value < this.min) { - this.min = value; - } - - if (this.max === null) { - this.max = value; - } else if (value > this.max) { - this.max = value; - } - }, this); - } - }, this); - } - - // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, - // do nothing since that would make the chart weird. If the user really wants a weird chart - // axis, they can manually override it - if (this.options.ticks.beginAtZero) { - var minSign = helpers.sign(this.min); - var maxSign = helpers.sign(this.max); - - if (minSign < 0 && maxSign < 0) { - // move the top up to 0 - this.max = 0; - } else if (minSign > 0 && maxSign > 0) { - // move the botttom down to 0 - this.min = 0; - } - } - - if (this.options.ticks.min !== undefined) { - this.min = this.options.ticks.min; - } else if (this.options.ticks.suggestedMin !== undefined) { - this.min = Math.min(this.min, this.options.ticks.suggestedMin); - } - - if (this.options.ticks.max !== undefined) { - this.max = this.options.ticks.max; - } else if (this.options.ticks.suggestedMax !== undefined) { - this.max = Math.max(this.max, this.options.ticks.suggestedMax); - } - - if (this.min === this.max) { - this.min--; - this.max++; - } - }, - buildTicks: function() { - - // Then calulate the ticks - this.ticks = []; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph - - var maxTicks; - - if (this.isHorizontal()) { - maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11, Math.ceil(this.width / 50)); - } else { - // The factor of 2 used to scale the font size has been experimentally determined. - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11, Math.ceil(this.height / (2 * tickFontSize))); - } - - // Make sure we always have at least 2 ticks - maxTicks = Math.max(2, maxTicks); - - // To get a "nice" value for the tick spacing, we will use the appropriately named - // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - // for details. - - var spacing; - var fixedStepSizeSet = (this.options.ticks.fixedStepSize && this.options.ticks.fixedStepSize > 0) || (this.options.ticks.stepSize && this.options.ticks.stepSize > 0); - if (fixedStepSizeSet) { - spacing = helpers.getValueOrDefault(this.options.ticks.fixedStepSize, this.options.ticks.stepSize); - } else { - var niceRange = helpers.niceNum(this.max - this.min, false); - spacing = helpers.niceNum(niceRange / (maxTicks - 1), true); - } - var niceMin = Math.floor(this.min / spacing) * spacing; - var niceMax = Math.ceil(this.max / spacing) * spacing; - var numSpaces = (niceMax - niceMin) / spacing; - - // If very close to our rounded value, use it. - if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) { - numSpaces = Math.round(numSpaces); - } else { - numSpaces = Math.ceil(numSpaces); - } - - // Put the values into the ticks array - this.ticks.push(this.options.ticks.min !== undefined ? this.options.ticks.min : niceMin); - for (var j = 1; j < numSpaces; ++j) { - this.ticks.push(niceMin + (j * spacing)); - } - this.ticks.push(this.options.ticks.max !== undefined ? this.options.ticks.max : niceMax); - - if (this.options.position === "left" || this.options.position === "right") { - // We are in a vertical orientation. The top value is the highest. So reverse the array - this.ticks.reverse(); - } - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - this.max = helpers.max(this.ticks); - this.min = helpers.min(this.ticks); - - if (this.options.ticks.reverse) { - this.ticks.reverse(); - - this.start = this.max; - this.end = this.min; - } else { - this.start = this.min; - this.end = this.max; - } - }, - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - convertTicksToLabels: function() { - this.ticksAsNumbers = this.ticks.slice(); - this.zeroLineIndex = this.ticks.indexOf(0); - - Chart.Scale.prototype.convertTicksToLabels.call(this); - }, - // Utils - getPixelForValue: function(value, index, datasetIndex, includeOffset) { - // This must be called after fit has been run so that - // this.left, this.top, this.right, and this.bottom have been defined - var rightValue = +this.getRightValue(value); - var pixel; - var range = this.end - this.start; - - if (this.isHorizontal()) { - var innerWidth = this.width - (this.paddingLeft + this.paddingRight); - pixel = this.left + (innerWidth / range * (rightValue - this.start)); - return Math.round(pixel + this.paddingLeft); - } else { - var innerHeight = this.height - (this.paddingTop + this.paddingBottom); - pixel = (this.bottom - this.paddingBottom) - (innerHeight / range * (rightValue - this.start)); - return Math.round(pixel); - } - }, - getPixelForTick: function(index, includeOffset) { - return this.getPixelForValue(this.ticksAsNumbers[index], null, null, includeOffset); - } - }); - Chart.scaleService.registerScaleType("linear", LinearScale, defaultConfig); - -}; -},{}],39:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - var defaultConfig = { - position: "left", - - // label settings - ticks: { - callback: function(value, index, arr) { - var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value)))); - - if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) { - return value.toExponential(); - } else { - return ''; - } - } - } - }; - - var LogarithmicScale = Chart.Scale.extend({ - determineDataLimits: function() { - // Calculate Range - this.min = null; - this.max = null; - - if (this.options.stacked) { - var valuesPerType = {}; - - helpers.each(this.chart.data.datasets, function(dataset) { - if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) { - if (valuesPerType[dataset.type] === undefined) { - valuesPerType[dataset.type] = []; - } - - helpers.each(dataset.data, function(rawValue, index) { - var values = valuesPerType[dataset.type]; - var value = +this.getRightValue(rawValue); - if (isNaN(value)) { - return; - } - - values[index] = values[index] || 0; - - if (this.options.relativePoints) { - values[index] = 100; - } else { - // Don't need to split positive and negative since the log scale can't handle a 0 crossing - values[index] += value; - } - }, this); - } - }, this); - - helpers.each(valuesPerType, function(valuesForType) { - var minVal = helpers.min(valuesForType); - var maxVal = helpers.max(valuesForType); - this.min = this.min === null ? minVal : Math.min(this.min, minVal); - this.max = this.max === null ? maxVal : Math.max(this.max, maxVal); - }, this); - - } else { - helpers.each(this.chart.data.datasets, function(dataset) { - if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) { - helpers.each(dataset.data, function(rawValue, index) { - var value = +this.getRightValue(rawValue); - if (isNaN(value)) { - return; - } - - if (this.min === null) { - this.min = value; - } else if (value < this.min) { - this.min = value; - } - - if (this.max === null) { - this.max = value; - } else if (value > this.max) { - this.max = value; - } - }, this); - } - }, this); - } - - this.min = this.options.ticks.min !== undefined ? this.options.ticks.min : this.min; - this.max = this.options.ticks.max !== undefined ? this.options.ticks.max : this.max; - - if (this.min === this.max) { - if (this.min !== 0 && this.min !== null) { - this.min = Math.pow(10, Math.floor(helpers.log10(this.min)) - 1); - this.max = Math.pow(10, Math.floor(helpers.log10(this.max)) + 1); - } else { - this.min = 1; - this.max = 10; - } - } - }, - buildTicks: function() { - // Reset the ticks array. Later on, we will draw a grid line at these positions - // The array simply contains the numerical value of the spots where ticks will be - this.ticks = []; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph - - var tickVal = this.options.ticks.min !== undefined ? this.options.ticks.min : Math.pow(10, Math.floor(helpers.log10(this.min))); - - while (tickVal < this.max) { - this.ticks.push(tickVal); - - var exp = Math.floor(helpers.log10(tickVal)); - var significand = Math.floor(tickVal / Math.pow(10, exp)) + 1; - - if (significand === 10) { - significand = 1; - ++exp; - } - - tickVal = significand * Math.pow(10, exp); - } - - var lastTick = this.options.ticks.max !== undefined ? this.options.ticks.max : tickVal; - this.ticks.push(lastTick); - - if (this.options.position === "left" || this.options.position === "right") { - // We are in a vertical orientation. The top value is the highest. So reverse the array - this.ticks.reverse(); - } - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - this.max = helpers.max(this.ticks); - this.min = helpers.min(this.ticks); - - if (this.options.ticks.reverse) { - this.ticks.reverse(); - - this.start = this.max; - this.end = this.min; - } else { - this.start = this.min; - this.end = this.max; - } - }, - convertTicksToLabels: function() { - this.tickValues = this.ticks.slice(); - - Chart.Scale.prototype.convertTicksToLabels.call(this); - }, - // Get the correct tooltip label - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - getPixelForTick: function(index, includeOffset) { - return this.getPixelForValue(this.tickValues[index], null, null, includeOffset); - }, - getPixelForValue: function(value, index, datasetIndex, includeOffset) { - var pixel; - - var newVal = +this.getRightValue(value); - var range = helpers.log10(this.end) - helpers.log10(this.start); - - if (this.isHorizontal()) { - - if (newVal === 0) { - pixel = this.left + this.paddingLeft; - } else { - var innerWidth = this.width - (this.paddingLeft + this.paddingRight); - pixel = this.left + (innerWidth / range * (helpers.log10(newVal) - helpers.log10(this.start))); - pixel += this.paddingLeft; - } - } else { - // Bottom - top since pixels increase downard on a screen - if (newVal === 0) { - pixel = this.top + this.paddingTop; - } else { - var innerHeight = this.height - (this.paddingTop + this.paddingBottom); - pixel = (this.bottom - this.paddingBottom) - (innerHeight / range * (helpers.log10(newVal) - helpers.log10(this.start))); - } - } - - return pixel; - } - - }); - Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig); - -}; -},{}],40:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - var defaultConfig = { - display: true, - - //Boolean - Whether to animate scaling the chart from the centre - animate: true, - lineArc: false, - position: "chartArea", - - angleLines: { - display: true, - color: "rgba(0, 0, 0, 0.1)", - lineWidth: 1 - }, - - // label settings - ticks: { - //Boolean - Show a backdrop to the scale label - showLabelBackdrop: true, - - //String - The colour of the label backdrop - backdropColor: "rgba(255,255,255,0.75)", - - //Number - The backdrop padding above & below the label in pixels - backdropPaddingY: 2, - - //Number - The backdrop padding to the side of the label in pixels - backdropPaddingX: 2 - }, - - pointLabels: { - //Number - Point label font size in pixels - fontSize: 10, - - //Function - Used to convert point labels - callback: function(label) { - return label; - } - } - }; - - var LinearRadialScale = Chart.Scale.extend({ - getValueCount: function() { - return this.chart.data.labels.length; - }, - setDimensions: function() { - // Set the unconstrained dimension before label rotation - this.width = this.maxWidth; - this.height = this.maxHeight; - this.xCenter = Math.round(this.width / 2); - this.yCenter = Math.round(this.height / 2); - - var minSize = helpers.min([this.height, this.width]); - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - this.drawingArea = (this.options.display) ? (minSize / 2) - (tickFontSize / 2 + this.options.ticks.backdropPaddingY) : (minSize / 2); - }, - determineDataLimits: function() { - this.min = null; - this.max = null; - - helpers.each(this.chart.data.datasets, function(dataset) { - if (helpers.isDatasetVisible(dataset)) { - helpers.each(dataset.data, function(rawValue, index) { - var value = +this.getRightValue(rawValue); - if (isNaN(value)) { - return; - } - - if (this.min === null) { - this.min = value; - } else if (value < this.min) { - this.min = value; - } - - if (this.max === null) { - this.max = value; - } else if (value > this.max) { - this.max = value; - } - }, this); - } - }, this); - - // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, - // do nothing since that would make the chart weird. If the user really wants a weird chart - // axis, they can manually override it - if (this.options.ticks.beginAtZero) { - var minSign = helpers.sign(this.min); - var maxSign = helpers.sign(this.max); - - if (minSign < 0 && maxSign < 0) { - // move the top up to 0 - this.max = 0; - } else if (minSign > 0 && maxSign > 0) { - // move the botttom down to 0 - this.min = 0; - } - } - - if (this.options.ticks.min !== undefined) { - this.min = this.options.ticks.min; - } else if (this.options.ticks.suggestedMin !== undefined) { - this.min = Math.min(this.min, this.options.ticks.suggestedMin); - } - - if (this.options.ticks.max !== undefined) { - this.max = this.options.ticks.max; - } else if (this.options.ticks.suggestedMax !== undefined) { - this.max = Math.max(this.max, this.options.ticks.suggestedMax); - } - - if (this.min === this.max) { - this.min--; - this.max++; - } - }, - buildTicks: function() { - - - this.ticks = []; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize))); - maxTicks = Math.max(2, maxTicks); // Make sure we always have at least 2 ticks - - // To get a "nice" value for the tick spacing, we will use the appropriately named - // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - // for details. - - var niceRange = helpers.niceNum(this.max - this.min, false); - var spacing = helpers.niceNum(niceRange / (maxTicks - 1), true); - var niceMin = Math.floor(this.min / spacing) * spacing; - var niceMax = Math.ceil(this.max / spacing) * spacing; - - var numSpaces = Math.ceil((niceMax - niceMin) / spacing); - - // Put the values into the ticks array - this.ticks.push(this.options.ticks.min !== undefined ? this.options.ticks.min : niceMin); - for (var j = 1; j < numSpaces; ++j) { - this.ticks.push(niceMin + (j * spacing)); - } - this.ticks.push(this.options.ticks.max !== undefined ? this.options.ticks.max : niceMax); - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - this.max = helpers.max(this.ticks); - this.min = helpers.min(this.ticks); - - if (this.options.ticks.reverse) { - this.ticks.reverse(); - - this.start = this.max; - this.end = this.min; - } else { - this.start = this.min; - this.end = this.max; - } - - this.zeroLineIndex = this.ticks.indexOf(0); - }, - convertTicksToLabels: function() { - Chart.Scale.prototype.convertTicksToLabels.call(this); - - // Point labels - this.pointLabels = this.chart.data.labels.map(this.options.pointLabels.callback, this); - }, - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - fit: function() { - /* - * Right, this is really confusing and there is a lot of maths going on here - * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 - * - * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif - * - * Solution: - * - * We assume the radius of the polygon is half the size of the canvas at first - * at each index we check if the text overlaps. - * - * Where it does, we store that angle and that index. - * - * After finding the largest index and angle we calculate how much we need to remove - * from the shape radius to move the point inwards by that x. - * - * We average the left and right distances to get the maximum shape radius that can fit in the box - * along with labels. - * - * Once we have that, we can find the centre point for the chart, by taking the x text protrusion - * on each side, removing that from the size, halving it and adding the left x protrusion width. - * - * This will mean we have a shape fitted to the canvas, as large as it can be with the labels - * and position it in the most space efficient manner - * - * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif - */ - - var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize); - var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle); - var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, Chart.defaults.global.defaultFontFamily); - var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily); - - // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. - // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points - var largestPossibleRadius = helpers.min([(this.height / 2 - pointLabelFontSize - 5), this.width / 2]), - pointPosition, - i, - textWidth, - halfTextWidth, - furthestRight = this.width, - furthestRightIndex, - furthestRightAngle, - furthestLeft = 0, - furthestLeftIndex, - furthestLeftAngle, - xProtrusionLeft, - xProtrusionRight, - radiusReductionRight, - radiusReductionLeft, - maxWidthRadius; - this.ctx.font = pointLabeFont; - - for (i = 0; i < this.getValueCount(); i++) { - // 5px to space the text slightly out - similar to what we do in the draw function. - pointPosition = this.getPointPosition(i, largestPossibleRadius); - textWidth = this.ctx.measureText(this.pointLabels[i] ? this.pointLabels[i] : '').width + 5; - if (i === 0 || i === this.getValueCount() / 2) { - // If we're at index zero, or exactly the middle, we're at exactly the top/bottom - // of the radar chart, so text will be aligned centrally, so we'll half it and compare - // w/left and right text sizes - halfTextWidth = textWidth / 2; - if (pointPosition.x + halfTextWidth > furthestRight) { - furthestRight = pointPosition.x + halfTextWidth; - furthestRightIndex = i; - } - if (pointPosition.x - halfTextWidth < furthestLeft) { - furthestLeft = pointPosition.x - halfTextWidth; - furthestLeftIndex = i; - } - } else if (i < this.getValueCount() / 2) { - // Less than half the values means we'll left align the text - if (pointPosition.x + textWidth > furthestRight) { - furthestRight = pointPosition.x + textWidth; - furthestRightIndex = i; - } - } else if (i > this.getValueCount() / 2) { - // More than half the values means we'll right align the text - if (pointPosition.x - textWidth < furthestLeft) { - furthestLeft = pointPosition.x - textWidth; - furthestLeftIndex = i; - } - } - } - - xProtrusionLeft = furthestLeft; - xProtrusionRight = Math.ceil(furthestRight - this.width); - - furthestRightAngle = this.getIndexAngle(furthestRightIndex); - furthestLeftAngle = this.getIndexAngle(furthestLeftIndex); - - radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI / 2); - radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI / 2); - - // Ensure we actually need to reduce the size of the chart - radiusReductionRight = (helpers.isNumber(radiusReductionRight)) ? radiusReductionRight : 0; - radiusReductionLeft = (helpers.isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0; - - this.drawingArea = Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2); - this.setCenterPoint(radiusReductionLeft, radiusReductionRight); - }, - setCenterPoint: function(leftMovement, rightMovement) { - - var maxRight = this.width - rightMovement - this.drawingArea, - maxLeft = leftMovement + this.drawingArea; - - this.xCenter = Math.round(((maxLeft + maxRight) / 2) + this.left); - // Always vertically in the centre as the text height doesn't change - this.yCenter = Math.round((this.height / 2) + this.top); - }, - - getIndexAngle: function(index) { - var angleMultiplier = (Math.PI * 2) / this.getValueCount(); - // Start from the top instead of right, so remove a quarter of the circle - - return index * angleMultiplier - (Math.PI / 2); - }, - getDistanceFromCenterForValue: function(value) { - if (value === null) { - return 0; // null always in center - } - - // Take into account half font size + the yPadding of the top value - var scalingFactor = this.drawingArea / (this.max - this.min); - if (this.options.reverse) { - return (this.max - value) * scalingFactor; - } else { - return (value - this.min) * scalingFactor; - } - }, - getPointPosition: function(index, distanceFromCenter) { - var thisAngle = this.getIndexAngle(index); - return { - x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + this.xCenter, - y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + this.yCenter - }; - }, - getPointPositionForValue: function(index, value) { - return this.getPointPosition(index, this.getDistanceFromCenterForValue(value)); - }, - draw: function() { - if (this.options.display) { - var ctx = this.ctx; - helpers.each(this.ticks, function(label, index) { - // Don't draw a centre value (if it is minimum) - if (index > 0 || this.options.reverse) { - var yCenterOffset = this.getDistanceFromCenterForValue(this.ticks[index]); - var yHeight = this.yCenter - yCenterOffset; - - // Draw circular lines around the scale - if (this.options.gridLines.display) { - ctx.strokeStyle = this.options.gridLines.color; - ctx.lineWidth = this.options.gridLines.lineWidth; - - if (this.options.lineArc) { - // Draw circular arcs between the points - ctx.beginPath(); - ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI * 2); - ctx.closePath(); - ctx.stroke(); - } else { - // Draw straight lines connecting each index - ctx.beginPath(); - for (var i = 0; i < this.getValueCount(); i++) { - var pointPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.ticks[index])); - if (i === 0) { - ctx.moveTo(pointPosition.x, pointPosition.y); - } else { - ctx.lineTo(pointPosition.x, pointPosition.y); - } - } - ctx.closePath(); - ctx.stroke(); - } - } - - if (this.options.ticks.display) { - var tickFontColor = helpers.getValueOrDefault(this.options.ticks.fontColor, Chart.defaults.global.defaultFontColor); - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); - var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - ctx.font = tickLabelFont; - - if (this.options.ticks.showLabelBackdrop) { - var labelWidth = ctx.measureText(label).width; - ctx.fillStyle = this.options.ticks.backdropColor; - ctx.fillRect( - this.xCenter - labelWidth / 2 - this.options.ticks.backdropPaddingX, - yHeight - tickFontSize / 2 - this.options.ticks.backdropPaddingY, - labelWidth + this.options.ticks.backdropPaddingX * 2, - tickFontSize + this.options.ticks.backdropPaddingY * 2 - ); - } - - ctx.textAlign = 'center'; - ctx.textBaseline = "middle"; - ctx.fillStyle = tickFontColor; - ctx.fillText(label, this.xCenter, yHeight); - } - } - }, this); - - if (!this.options.lineArc) { - ctx.lineWidth = this.options.angleLines.lineWidth; - ctx.strokeStyle = this.options.angleLines.color; - - for (var i = this.getValueCount() - 1; i >= 0; i--) { - if (this.options.angleLines.display) { - var outerPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max)); - ctx.beginPath(); - ctx.moveTo(this.xCenter, this.yCenter); - ctx.lineTo(outerPosition.x, outerPosition.y); - ctx.stroke(); - ctx.closePath(); - } - // Extra 3px out for some label spacing - var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5); - - var pointLabelFontColor = helpers.getValueOrDefault(this.options.pointLabels.fontColor, Chart.defaults.global.defaultFontColor); - var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize); - var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle); - var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, Chart.defaults.global.defaultFontFamily); - var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily); - - ctx.font = pointLabeFont; - ctx.fillStyle = pointLabelFontColor; - - var labelsCount = this.pointLabels.length, - halfLabelsCount = this.pointLabels.length / 2, - quarterLabelsCount = halfLabelsCount / 2, - upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount), - exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount); - if (i === 0) { - ctx.textAlign = 'center'; - } else if (i === halfLabelsCount) { - ctx.textAlign = 'center'; - } else if (i < halfLabelsCount) { - ctx.textAlign = 'left'; - } else { - ctx.textAlign = 'right'; - } - - // Set the correct text baseline based on outer positioning - if (exactQuarter) { - ctx.textBaseline = 'middle'; - } else if (upperHalf) { - ctx.textBaseline = 'bottom'; - } else { - ctx.textBaseline = 'top'; - } - - ctx.fillText(this.pointLabels[i] ? this.pointLabels[i] : '', pointLabelPosition.x, pointLabelPosition.y); - } - } - } - } - }); - Chart.scaleService.registerScaleType("radialLinear", LinearRadialScale, defaultConfig); - -}; -},{}],41:[function(require,module,exports){ -/*global window: false */ -"use strict"; - -var moment = require('moment'); -moment = typeof(moment) === 'function' ? moment : window.moment; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - var time = { - units: [{ - name: 'millisecond', - steps: [1, 2, 5, 10, 20, 50, 100, 250, 500] - }, { - name: 'second', - steps: [1, 2, 5, 10, 30] - }, { - name: 'minute', - steps: [1, 2, 5, 10, 30] - }, { - name: 'hour', - steps: [1, 2, 3, 6, 12] - }, { - name: 'day', - steps: [1, 2, 5] - }, { - name: 'week', - maxStep: 4 - }, { - name: 'month', - maxStep: 3 - }, { - name: 'quarter', - maxStep: 4 - }, { - name: 'year', - maxStep: false - }] - }; - - var defaultConfig = { - position: "bottom", - - time: { - parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment - format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/ - unit: false, // false == automatic or override with week, month, year, etc. - round: false, // none, or override with week, month, year, etc. - displayFormat: false, // DEPRECATED - - // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/ - displayFormats: { - 'millisecond': 'h:mm:ss.SSS a', // 11:20:01.123 AM, - 'second': 'h:mm:ss a', // 11:20:01 AM - 'minute': 'h:mm:ss a', // 11:20:01 AM - 'hour': 'MMM D, hA', // Sept 4, 5PM - 'day': 'll', // Sep 4 2015 - 'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ? - 'month': 'MMM YYYY', // Sept 2015 - 'quarter': '[Q]Q - YYYY', // Q3 - 'year': 'YYYY' // 2015 - } - }, - ticks: { - autoSkip: false, - } - }; - - var TimeScale = Chart.Scale.extend({ - initialize: function() { - if (!moment) { - throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com'); - } - - Chart.Scale.prototype.initialize.call(this); - }, - getLabelMoment: function(datasetIndex, index) { - return this.labelMoments[datasetIndex][index]; - }, - determineDataLimits: function() { - this.labelMoments = []; - - // Only parse these once. If the dataset does not have data as x,y pairs, we will use - // these - var scaleLabelMoments = []; - if (this.chart.data.labels && this.chart.data.labels.length > 0) { - helpers.each(this.chart.data.labels, function(label, index) { - var labelMoment = this.parseTime(label); - if (this.options.time.round) { - labelMoment.startOf(this.options.time.round); - } - scaleLabelMoments.push(labelMoment); - }, this); - - this.firstTick = moment.min.call(this, scaleLabelMoments); - this.lastTick = moment.max.call(this, scaleLabelMoments); - } else { - this.firstTick = null; - this.lastTick = null; - } - - helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) { - var momentsForDataset = []; - - if (typeof dataset.data[0] === 'object') { - helpers.each(dataset.data, function(value, index) { - var labelMoment = this.parseTime(this.getRightValue(value)); - if (this.options.time.round) { - labelMoment.startOf(this.options.time.round); - } - momentsForDataset.push(labelMoment); - - // May have gone outside the scale ranges, make sure we keep the first and last ticks updated - this.firstTick = this.firstTick !== null ? moment.min(this.firstTick, labelMoment) : labelMoment; - this.lastTick = this.lastTick !== null ? moment.max(this.lastTick, labelMoment) : labelMoment; - }, this); - } else { - // We have no labels. Use the ones from the scale - momentsForDataset = scaleLabelMoments; - } - - this.labelMoments.push(momentsForDataset); - }, this); - - // Set these after we've done all the data - if (this.options.time.min) { - this.firstTick = this.parseTime(this.options.time.min); - } - - if (this.options.time.max) { - this.lastTick = this.parseTime(this.options.time.max); - } - - // We will modify these, so clone for later - this.firstTick = (this.firstTick || moment()).clone(); - this.lastTick = (this.lastTick || moment()).clone(); - }, - buildTicks: function(index) { - - this.ticks = []; - this.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step - this.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc) - - // Set unit override if applicable - if (this.options.time.unit) { - this.tickUnit = this.options.time.unit || 'day'; - this.displayFormat = this.options.time.displayFormats[this.tickUnit]; - this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true); - this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, 1); - } else { - // Determine the smallest needed unit of the time - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var innerWidth = this.isHorizontal() ? this.width - (this.paddingLeft + this.paddingRight) : this.height - (this.paddingTop + this.paddingBottom); - - // Crude approximation of what the label length might be - var tempFirstLabel = this.tickFormatFunction(this.firstTick, 0, []); - var tickLabelWidth = tempFirstLabel.length * tickFontSize; - var cosRotation = Math.cos(helpers.toRadians(this.options.ticks.maxRotation)); - var sinRotation = Math.sin(helpers.toRadians(this.options.ticks.maxRotation)); - tickLabelWidth = (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation); - var labelCapacity = innerWidth / (tickLabelWidth + 10); - - // Start as small as possible - this.tickUnit = 'millisecond'; - this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true); - this.displayFormat = this.options.time.displayFormats[this.tickUnit]; - - var unitDefinitionIndex = 0; - var unitDefinition = time.units[unitDefinitionIndex]; - - // While we aren't ideal and we don't have units left - while (unitDefinitionIndex < time.units.length) { - // Can we scale this unit. If `false` we can scale infinitely - this.unitScale = 1; - - if (helpers.isArray(unitDefinition.steps) && Math.ceil(this.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) { - // Use one of the prefedined steps - for (var idx = 0; idx < unitDefinition.steps.length; ++idx) { - if (unitDefinition.steps[idx] > Math.ceil(this.scaleSizeInUnits / labelCapacity)) { - this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, unitDefinition.steps[idx]); - break; - } - } - - break; - } else if ((unitDefinition.maxStep === false) || (Math.ceil(this.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep)) { - // We have a max step. Scale this unit - this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, Math.ceil(this.scaleSizeInUnits / labelCapacity)); - break; - } else { - // Move to the next unit up - ++unitDefinitionIndex; - unitDefinition = time.units[unitDefinitionIndex]; - - this.tickUnit = unitDefinition.name; - this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true); - this.displayFormat = this.options.time.displayFormats[unitDefinition.name]; - } - } - } - - var roundedStart; - - // Only round the first tick if we have no hard minimum - if (!this.options.time.min) { - this.firstTick.startOf(this.tickUnit); - roundedStart = this.firstTick; - } else { - roundedStart = this.firstTick.clone().startOf(this.tickUnit); - } - - // Only round the last tick if we have no hard maximum - if (!this.options.time.max) { - this.lastTick.endOf(this.tickUnit); - } - - this.smallestLabelSeparation = this.width; - - helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) { - for (var i = 1; i < this.labelMoments[datasetIndex].length; i++) { - this.smallestLabelSeparation = Math.min(this.smallestLabelSeparation, this.labelMoments[datasetIndex][i].diff(this.labelMoments[datasetIndex][i - 1], this.tickUnit, true)); - } - }, this); - - // Tick displayFormat override - if (this.options.time.displayFormat) { - this.displayFormat = this.options.time.displayFormat; - } - - // first tick. will have been rounded correctly if options.time.min is not specified - this.ticks.push(this.firstTick.clone()); - - // For every unit in between the first and last moment, create a moment and add it to the ticks tick - for (var i = 1; i < this.scaleSizeInUnits; ++i) { - var newTick = roundedStart.clone().add(i, this.tickUnit); - - // Are we greater than the max time - if (this.options.time.max && newTick.diff(this.lastTick, this.tickUnit, true) >= 0) { - break; - } - - if (i % this.unitScale === 0) { - this.ticks.push(newTick); - } - } - - // Always show the right tick - if (this.ticks[this.ticks.length - 1].diff(this.lastTick, this.tickUnit) !== 0 || this.scaleSizeInUnits === 0) { - // this is a weird case. If the option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart - // but the last tick was not rounded. - if (this.options.time.max) { - this.ticks.push(this.lastTick.clone()); - this.scaleSizeInUnits = this.lastTick.diff(this.ticks[0], this.tickUnit, true); - } else { - this.scaleSizeInUnits = Math.ceil(this.scaleSizeInUnits / this.unitScale) * this.unitScale; - this.ticks.push(this.firstTick.clone().add(this.scaleSizeInUnits, this.tickUnit)); - this.lastTick = this.ticks[this.ticks.length - 1].clone(); - } - } - }, - // Get tooltip label - getLabelForIndex: function(index, datasetIndex) { - var label = this.chart.data.labels && index < this.chart.data.labels.length ? this.chart.data.labels[index] : ''; - - if (typeof this.chart.data.datasets[datasetIndex].data[0] === 'object') { - label = this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - } - - // Format nicely - if (this.options.time.tooltipFormat) { - label = this.parseTime(label).format(this.options.time.tooltipFormat); - } - - return label; - }, - // Function to format an individual tick mark - tickFormatFunction: function tickFormatFunction(tick, index, ticks) { - var formattedTick = tick.format(this.displayFormat); - - if (this.options.ticks.userCallback) { - return this.options.ticks.userCallback(formattedTick, index, ticks); - } else { - return formattedTick; - } - }, - convertTicksToLabels: function() { - this.ticks = this.ticks.map(this.tickFormatFunction, this); - }, - getPixelForValue: function(value, index, datasetIndex, includeOffset) { - var labelMoment = this.getLabelMoment(datasetIndex, index); - - if (labelMoment) { - var offset = labelMoment.diff(this.firstTick, this.tickUnit, true); - - var decimal = offset / this.scaleSizeInUnits; - - if (this.isHorizontal()) { - var innerWidth = this.width - (this.paddingLeft + this.paddingRight); - var valueWidth = innerWidth / Math.max(this.ticks.length - 1, 1); - var valueOffset = (innerWidth * decimal) + this.paddingLeft; - - return this.left + Math.round(valueOffset); - } else { - var innerHeight = this.height - (this.paddingTop + this.paddingBottom); - var valueHeight = innerHeight / Math.max(this.ticks.length - 1, 1); - var heightOffset = (innerHeight * decimal) + this.paddingTop; - - return this.top + Math.round(heightOffset); - } - } - }, - parseTime: function(label) { - if (typeof this.options.time.parser === 'string') { - return moment(label, this.options.time.parser); - } - if (typeof this.options.time.parser === 'function') { - return this.options.time.parser(label); - } - // Date objects - if (typeof label.getMonth === 'function' || typeof label === 'number') { - return moment(label); - } - // Moment support - if (label.isValid && label.isValid()) { - return label; - } - // Custom parsing (return an instance of moment) - if (typeof this.options.time.format !== 'string' && this.options.time.format.call) { - console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"); - return this.options.time.format(label); - } - // Moment format parsing - return moment(label, this.options.time.format); - } - }); - Chart.scaleService.registerScaleType("time", TimeScale, defaultConfig); - -}; -},{"moment":1}]},{},[7]); diff --git a/js/lib/Chart.min.js b/js/lib/Chart.min.js deleted file mode 100644 index b8e77fe8bd2..00000000000 --- a/js/lib/Chart.min.js +++ /dev/null @@ -1,14 +0,0 @@ -!function t(e,i,a){function s(n,r){if(!i[n]){if(!e[n]){var l="function"==typeof require&&require;if(!r&&l)return l(n,!0);if(o)return o(n,!0);var h=new Error("Cannot find module '"+n+"'");throw h.code="MODULE_NOT_FOUND",h}var c=i[n]={exports:{}};e[n][0].call(c.exports,function(t){var i=e[n][1][t];return s(i?i:t)},c,c.exports,t,e,i,a)}return i[n].exports}for(var o="function"==typeof require&&require,n=0;ne&&(e+=360),a=(r+l)/2,i=l==r?0:.5>=a?h/(l+r):h/(2-l-r),[e,100*i,100*a]}function s(t){var e,i,a,s=t[0],o=t[1],n=t[2],r=Math.min(s,o,n),l=Math.max(s,o,n),h=l-r;return i=0==l?0:h/l*1e3/10,l==r?e=0:s==l?e=(o-n)/h:o==l?e=2+(n-s)/h:n==l&&(e=4+(s-o)/h),e=Math.min(60*e,360),0>e&&(e+=360),a=l/255*1e3/10,[e,i,a]}function o(t){var e=t[0],i=t[1],s=t[2],o=a(t)[0],n=1/255*Math.min(e,Math.min(i,s)),s=1-1/255*Math.max(e,Math.max(i,s));return[o,100*n,100*s]}function n(t){var e,i,a,s,o=t[0]/255,n=t[1]/255,r=t[2]/255;return s=Math.min(1-o,1-n,1-r),e=(1-o-s)/(1-s)||0,i=(1-n-s)/(1-s)||0,a=(1-r-s)/(1-s)||0,[100*e,100*i,100*a,100*s]}function l(t){return G[JSON.stringify(t)]}function h(t){var e=t[0]/255,i=t[1]/255,a=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92,a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92;var s=.4124*e+.3576*i+.1805*a,o=.2126*e+.7152*i+.0722*a,n=.0193*e+.1192*i+.9505*a;return[100*s,100*o,100*n]}function c(t){var e,i,a,s=h(t),o=s[0],n=s[1],r=s[2];return o/=95.047,n/=100,r/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*n-16,i=500*(o-n),a=200*(n-r),[e,i,a]}function d(t){return W(c(t))}function u(t){var e,i,a,s,o,n=t[0]/360,r=t[1]/100,l=t[2]/100;if(0==r)return o=255*l,[o,o,o];i=.5>l?l*(1+r):l+r-l*r,e=2*l-i,s=[0,0,0];for(var h=0;3>h;h++)a=n+1/3*-(h-1),0>a&&a++,a>1&&a--,o=1>6*a?e+6*(i-e)*a:1>2*a?i:2>3*a?e+(i-e)*(2/3-a)*6:e,s[h]=255*o;return s}function f(t){var e,i,a=t[0],s=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,s*=1>=o?o:2-o,i=(o+s)/2,e=2*s/(o+s),[a,100*e,100*i])}function m(t){return o(u(t))}function p(t){return n(u(t))}function x(t){return l(u(t))}function v(t){var e=t[0]/60,i=t[1]/100,a=t[2]/100,s=Math.floor(e)%6,o=e-Math.floor(e),n=255*a*(1-i),r=255*a*(1-i*o),l=255*a*(1-i*(1-o)),a=255*a;switch(s){case 0:return[a,l,n];case 1:return[r,a,n];case 2:return[n,a,l];case 3:return[n,r,a];case 4:return[l,n,a];case 5:return[a,n,r]}}function y(t){var e,i,a=t[0],s=t[1]/100,o=t[2]/100;return i=(2-s)*o,e=s*o,e/=1>=i?i:2-i,e=e||0,i/=2,[a,100*e,100*i]}function k(t){return o(v(t))}function D(t){return n(v(t))}function S(t){return l(v(t))}function C(t){var e,i,a,s,o=t[0]/360,n=t[1]/100,l=t[2]/100,h=n+l;switch(h>1&&(n/=h,l/=h),e=Math.floor(6*o),i=1-l,a=6*o-e,0!=(1&e)&&(a=1-a),s=n+a*(i-n),e){default:case 6:case 0:r=i,g=s,b=n;break;case 1:r=s,g=i,b=n;break;case 2:r=n,g=i,b=s;break;case 3:r=n,g=s,b=i;break;case 4:r=s,g=n,b=i;break;case 5:r=i,g=n,b=s}return[255*r,255*g,255*b]}function w(t){return a(C(t))}function _(t){return s(C(t))}function A(t){return n(C(t))}function I(t){return l(C(t))}function M(t){var e,i,a,s=t[0]/100,o=t[1]/100,n=t[2]/100,r=t[3]/100;return e=1-Math.min(1,s*(1-r)+r),i=1-Math.min(1,o*(1-r)+r),a=1-Math.min(1,n*(1-r)+r),[255*e,255*i,255*a]}function F(t){return a(M(t))}function P(t){return s(M(t))}function T(t){return o(M(t))}function V(t){return l(M(t))}function R(t){var e,i,a,s=t[0]/100,o=t[1]/100,n=t[2]/100;return e=3.2406*s+-1.5372*o+n*-.4986,i=s*-.9689+1.8758*o+.0415*n,a=.0557*s+o*-.204+1.057*n,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e=12.92*e,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i=12.92*i,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a=12.92*a,e=Math.min(Math.max(0,e),1),i=Math.min(Math.max(0,i),1),a=Math.min(Math.max(0,a),1),[255*e,255*i,255*a]}function O(t){var e,i,a,s=t[0],o=t[1],n=t[2];return s/=95.047,o/=100,n/=108.883,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,e=116*o-16,i=500*(s-o),a=200*(o-n),[e,i,a]}function L(t){return W(O(t))}function z(t){var e,i,a,s,o=t[0],n=t[1],r=t[2];return 8>=o?(i=100*o/903.3,s=7.787*(i/100)+16/116):(i=100*Math.pow((o+16)/116,3),s=Math.pow(i/100,1/3)),e=.008856>=e/95.047?e=95.047*(n/500+s-16/116)/7.787:95.047*Math.pow(n/500+s,3),a=.008859>=a/108.883?a=108.883*(s-r/200-16/116)/7.787:108.883*Math.pow(s-r/200,3),[e,i,a]}function W(t){var e,i,a,s=t[0],o=t[1],n=t[2];return e=Math.atan2(n,o),i=360*e/2/Math.PI,0>i&&(i+=360),a=Math.sqrt(o*o+n*n),[s,a,i]}function B(t){return R(z(t))}function N(t){var e,i,a,s=t[0],o=t[1],n=t[2];return a=n/360*2*Math.PI,e=o*Math.cos(a),i=o*Math.sin(a),[s,e,i]}function H(t){return z(N(t))}function E(t){return B(N(t))}function U(t){return X[t]}function j(t){return a(U(t))}function q(t){return s(U(t))}function Y(t){return o(U(t))}function Q(t){return n(U(t))}function J(t){return c(U(t))}function Z(t){return h(U(t))}e.exports={rgb2hsl:a,rgb2hsv:s,rgb2hwb:o,rgb2cmyk:n,rgb2keyword:l,rgb2xyz:h,rgb2lab:c,rgb2lch:d,hsl2rgb:u,hsl2hsv:f,hsl2hwb:m,hsl2cmyk:p,hsl2keyword:x,hsv2rgb:v,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:D,hsv2keyword:S,hwb2rgb:C,hwb2hsl:w,hwb2hsv:_,hwb2cmyk:A,hwb2keyword:I,cmyk2rgb:M,cmyk2hsl:F,cmyk2hsv:P,cmyk2hwb:T,cmyk2keyword:V,keyword2rgb:U,keyword2hsl:j,keyword2hsv:q,keyword2hwb:Y,keyword2cmyk:Q,keyword2lab:J,keyword2xyz:Z,xyz2rgb:R,xyz2lab:O,xyz2lch:L,lab2xyz:z,lab2rgb:B,lab2lch:W,lch2lab:N,lch2xyz:H,lch2rgb:E};var X={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},G={};for(var $ in X)G[JSON.stringify(X[$])]=$},{}],3:[function(t,e,i){var a=t("./conversions"),s=function(){return new h};for(var o in a){s[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),a[t](e)}}(o);var n=/(\w+)2(\w+)/.exec(o),r=n[1],l=n[2];s[r]=s[r]||{},s[r][l]=s[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var i=a[t](e);if("string"==typeof i||void 0===i)return i;for(var s=0;se||t[3]&&t[3]<1?d(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function d(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function u(t,e){if(1>e||t[3]&&t[3]<1)return g(t,e);var i=Math.round(t[0]/255*100),a=Math.round(t[1]/255*100),s=Math.round(t[2]/255*100);return"rgb("+i+"%, "+a+"%, "+s+"%)"}function g(t,e){var i=Math.round(t[0]/255*100),a=Math.round(t[1]/255*100),s=Math.round(t[2]/255*100);return"rgba("+i+"%, "+a+"%, "+s+"%, "+(e||t[3]||1)+")"}function f(t,e){return 1>e||t[3]&&t[3]<1?m(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function b(t){return k[t.slice(0,3)]}function x(t,e,i){return Math.min(Math.max(e,t),i)}function v(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y=t("color-name");e.exports={getRgba:a,getHsla:s,getRgb:n,getHsl:r,getHwb:o,getAlpha:l,hexString:h,rgbString:c,rgbaString:d,percentString:u,percentaString:g,hslString:f,hslaString:m,hwbString:p,keyword:b};var k={};for(var D in y)k[y[D]]=D},{"color-name":6}],5:[function(t,e,i){var a=t("color-convert"),s=t("color-string"),o=function(t){if(t instanceof o)return t;if(!(this instanceof o))return new o(t);if(this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},"string"==typeof t){var e=s.getRgba(t);if(e)this.setValues("rgb",e);else if(e=s.getHsla(t))this.setValues("hsl",e);else{if(!(e=s.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}}else if("object"==typeof t){var e=t;if(void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}}};o.prototype={rgb:function(t){return this.setSpace("rgb",arguments)},hsl:function(t){return this.setSpace("hsl",arguments)},hsv:function(t){return this.setSpace("hsv",arguments)},hwb:function(t){return this.setSpace("hwb",arguments)},cmyk:function(t){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){return 1!==this.values.alpha?this.values.hwb.concat([this.values.alpha]):this.values.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values.rgb;return t.concat([this.values.alpha])},hslaArray:function(){var t=this.values.hsl;return t.concat([this.values.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return s.hexString(this.values.rgb)},rgbString:function(){return s.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return s.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return s.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return s.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return s.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return s.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return s.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){return this.values.rgb[0]<<16|this.values.rgb[1]<<8|this.values.rgb[2]},luminosity:function(){for(var t=this.values.rgb,e=[],i=0;i=a?a/12.92:Math.pow((a+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),i=t.luminosity();return e>i?(e+.05)/(i+.05):(i+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return 128>e},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;3>e;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){return this.values.hsl[2]+=this.values.hsl[2]*t,this.setValues("hsl",this.values.hsl),this},darken:function(t){return this.values.hsl[2]-=this.values.hsl[2]*t,this.setValues("hsl",this.values.hsl),this},saturate:function(t){return this.values.hsl[1]+=this.values.hsl[1]*t,this.setValues("hsl",this.values.hsl),this},desaturate:function(t){return this.values.hsl[1]-=this.values.hsl[1]*t,this.setValues("hsl",this.values.hsl),this},whiten:function(t){return this.values.hwb[1]+=this.values.hwb[1]*t,this.setValues("hwb",this.values.hwb),this},blacken:function(t){return this.values.hwb[2]+=this.values.hwb[2]*t,this.setValues("hwb",this.values.hwb),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){return this.setValues("alpha",this.values.alpha-this.values.alpha*t),this},opaquer:function(t){return this.setValues("alpha",this.values.alpha+this.values.alpha*t),this},rotate:function(t){var e=this.values.hsl[0];return e=(e+t)%360,e=0>e?360+e:e,this.values.hsl[0]=e,this.setValues("hsl",this.values.hsl),this},mix:function(t,e){e=1-(null==e?.5:e);for(var i=2*e-1,a=this.alpha()-t.alpha(),s=((i*a==-1?i:(i+a)/(1+i*a))+1)/2,o=1-s,n=this.rgbArray(),r=t.rgbArray(),l=0;l0&&r.max>0?r.getPixelForValue(r.min):r.getPixelForValue(0),e.extend(t,{_chart:this.chart.chart,_xScale:n,_yScale:r,_datasetIndex:this.index,_index:i,_model:{x:this.calculateBarX(i,this.index),y:a?o:this.calculateBarY(i,this.index),label:this.chart.data.labels[i],datasetLabel:this.getDataset().label,base:a?o:this.calculateBarBase(this.index,i),width:this.calculateBarWidth(s),backgroundColor:t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.rectangle.backgroundColor),borderSkipped:t.custom&&t.custom.borderSkipped?t.custom.borderSkipped:this.chart.options.elements.rectangle.borderSkipped,borderColor:t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.rectangle.borderColor),borderWidth:t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.rectangle.borderWidth)}}),t.pivot()},calculateBarBase:function(t,i){var a=(this.getScaleForId(this.getDataset().xAxisID),this.getScaleForId(this.getDataset().yAxisID)),s=0;if(a.options.stacked){var o=this.chart.data.datasets[t].data[i];if(0>o)for(var n=0;t>n;n++){var r=this.chart.data.datasets[n];e.isDatasetVisible(r)&&r.yAxisID===a.id&&r.bar&&(s+=r.data[i]<0?r.data[i]:0)}else for(var l=0;t>l;l++){var h=this.chart.data.datasets[l];e.isDatasetVisible(h)&&h.yAxisID===a.id&&h.bar&&(s+=h.data[i]>0?h.data[i]:0)}return a.getPixelForValue(s)}return s=a.getPixelForValue(a.min),a.beginAtZero||a.min<=0&&a.max>=0||a.min>=0&&a.max<=0?s=a.getPixelForValue(0,0):a.min<0&&a.max<0&&(s=a.getPixelForValue(a.max)),s},getRuler:function(){var t=this.getScaleForId(this.getDataset().xAxisID),e=(this.getScaleForId(this.getDataset().yAxisID),this.getBarCount()),i=function(){for(var e=t.getPixelForTick(1)-t.getPixelForTick(0),i=2;ia;++a)e.isDatasetVisible(this.chart.data.datasets[a])&&this.chart.data.datasets[a].bar&&++i;return i},calculateBarX:function(t,e){var i=(this.getScaleForId(this.getDataset().yAxisID),this.getScaleForId(this.getDataset().xAxisID)),a=this.getBarIndex(e),s=this.getRuler(),o=i.getPixelForValue(null,t,e,this.chart.isCombo);return o-=this.chart.isCombo?s.tickWidth/2:0,i.options.stacked?o+s.categoryWidth/2+s.categorySpacing:o+s.barWidth/2+s.categorySpacing+s.barWidth*a+s.barSpacing/2+s.barSpacing*a},calculateBarY:function(t,i){var a=(this.getScaleForId(this.getDataset().xAxisID),this.getScaleForId(this.getDataset().yAxisID)),s=this.getDataset().data[t];if(a.options.stacked){for(var o=0,n=0,r=0;i>r;r++){var l=this.chart.data.datasets[r];e.isDatasetVisible(l)&&l.bar&&l.yAxisID===a.id&&(l.data[t]<0?n+=l.data[t]||0:o+=l.data[t]||0)}return 0>s?a.getPixelForValue(n+s):a.getPixelForValue(o+s)}return a.getPixelForValue(s)},draw:function(t){var i=t||1;e.each(this.getDataset().metaData,function(t,e){var a=this.getDataset().data[e];null===a||void 0===a||isNaN(a)||t.transition(i).draw()},this)},setHoverStyle:function(t){var i=this.chart.data.datasets[t._datasetIndex],a=t._index;t._model.backgroundColor=t.custom&&t.custom.hoverBackgroundColor?t.custom.hoverBackgroundColor:e.getValueAtIndexOrDefault(i.hoverBackgroundColor,a,e.color(t._model.backgroundColor).saturate(.5).darken(.1).rgbString()),t._model.borderColor=t.custom&&t.custom.hoverBorderColor?t.custom.hoverBorderColor:e.getValueAtIndexOrDefault(i.hoverBorderColor,a,e.color(t._model.borderColor).saturate(.5).darken(.1).rgbString()),t._model.borderWidth=t.custom&&t.custom.hoverBorderWidth?t.custom.hoverBorderWidth:e.getValueAtIndexOrDefault(i.hoverBorderWidth,a,t._model.borderWidth)},removeHoverStyle:function(t){var i=(this.chart.data.datasets[t._datasetIndex],t._index);t._model.backgroundColor=t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.rectangle.backgroundColor),t._model.borderColor=t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.rectangle.borderColor),t._model.borderWidth=t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.rectangle.borderWidth)}})}},{}],16:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(t,e){return""},label:function(t,e){var i=e.datasets[t.datasetIndex].label||"",a=e.datasets[t.datasetIndex].data[t.index];return i+": ("+a.x+", "+a.y+", "+a.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({addElements:function(){this.getDataset().metaData=this.getDataset().metaData||[],e.each(this.getDataset().data,function(e,i){this.getDataset().metaData[i]=this.getDataset().metaData[i]||new t.elements.Point({_chart:this.chart.chart,_datasetIndex:this.index,_index:i})},this)},addElementAndReset:function(e){this.getDataset().metaData=this.getDataset().metaData||[];var i=new t.elements.Point({_chart:this.chart.chart,_datasetIndex:this.index,_index:e});this.updateElement(i,e,!0),this.getDataset().metaData.splice(e,0,i)},update:function(t){var i,a=this.getDataset().metaData,s=this.getScaleForId(this.getDataset().yAxisID);this.getScaleForId(this.getDataset().xAxisID);i=s.min<0&&s.max<0?s.getPixelForValue(s.max):s.min>0&&s.max>0?s.getPixelForValue(s.min):s.getPixelForValue(0),e.each(a,function(e,i){this.updateElement(e,i,t)},this)},updateElement:function(t,i,a){var s,o=this.getScaleForId(this.getDataset().yAxisID),n=this.getScaleForId(this.getDataset().xAxisID);s=o.min<0&&o.max<0?o.getPixelForValue(o.max):o.min>0&&o.max>0?o.getPixelForValue(o.min):o.getPixelForValue(0),e.extend(t,{_chart:this.chart.chart,_xScale:n,_yScale:o,_datasetIndex:this.index,_index:i,_model:{x:a?n.getPixelForDecimal(.5):n.getPixelForValue(this.getDataset().data[i],i,this.index,this.chart.isCombo),y:a?s:o.getPixelForValue(this.getDataset().data[i],i,this.index),radius:a?0:t.custom&&t.custom.radius?t.custom.radius:this.getRadius(this.getDataset().data[i]),backgroundColor:t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.point.backgroundColor),borderColor:t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.point.borderColor),borderWidth:t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.point.borderWidth),hitRadius:t.custom&&t.custom.hitRadius?t.custom.hitRadius:e.getValueAtIndexOrDefault(this.getDataset().hitRadius,i,this.chart.options.elements.point.hitRadius)}}),t._model.skip=t.custom&&t.custom.skip?t.custom.skip:isNaN(t._model.x)||isNaN(t._model.y),t.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},draw:function(t){var i=t||1;e.each(this.getDataset().metaData,function(t,e){t.transition(i),t.draw()})},setHoverStyle:function(t){var i=this.chart.data.datasets[t._datasetIndex],a=t._index;t._model.radius=t.custom&&t.custom.hoverRadius?t.custom.hoverRadius:e.getValueAtIndexOrDefault(i.hoverRadius,a,this.chart.options.elements.point.hoverRadius)+this.getRadius(this.getDataset().data[t._index]),t._model.backgroundColor=t.custom&&t.custom.hoverBackgroundColor?t.custom.hoverBackgroundColor:e.getValueAtIndexOrDefault(i.hoverBackgroundColor,a,e.color(t._model.backgroundColor).saturate(.5).darken(.1).rgbString()),t._model.borderColor=t.custom&&t.custom.hoverBorderColor?t.custom.hoverBorderColor:e.getValueAtIndexOrDefault(i.hoverBorderColor,a,e.color(t._model.borderColor).saturate(.5).darken(.1).rgbString()),t._model.borderWidth=t.custom&&t.custom.hoverBorderWidth?t.custom.hoverBorderWidth:e.getValueAtIndexOrDefault(i.hoverBorderWidth,a,t._model.borderWidth)},removeHoverStyle:function(t){var i=(this.chart.data.datasets[t._datasetIndex],t._index);t._model.radius=t.custom&&t.custom.radius?t.custom.radius:this.getRadius(this.getDataset().data[t._index]),t._model.backgroundColor=t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.point.backgroundColor),t._model.borderColor=t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.point.borderColor),t._model.borderWidth=t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.point.borderWidth)}})}},{}],17:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];if(e.push('
    '),t.data.datasets.length)for(var i=0;i'),t.data.labels[i]&&e.push(t.data.labels[i]),e.push("");return e.push("
"),e.join("")},legend:{labels:{generateLabels:function(t){return t.labels.length&&t.datasets.length?t.labels.map(function(e,i){return{text:e,fillStyle:t.datasets[0].backgroundColor[i],hidden:isNaN(t.datasets[0].data[i]),index:i}}):[]}},onClick:function(t,i){e.each(this.chart.data.datasets,function(t){t.metaHiddenData=t.metaHiddenData||[];var e=i.index;isNaN(t.data[e])?isNaN(t.metaHiddenData[e])||(t.data[e]=t.metaHiddenData[e]):(t.metaHiddenData[e]=t.data[e],t.data[e]=NaN)}),this.chart.update()}},cutoutPercentage:50,tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+e.datasets[t.datasetIndex].data[t.index]}}}},t.defaults.pie=e.clone(t.defaults.doughnut),e.extend(t.defaults.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({linkScales:function(){},addElements:function(){this.getDataset().metaData=this.getDataset().metaData||[],e.each(this.getDataset().data,function(e,i){this.getDataset().metaData[i]=this.getDataset().metaData[i]||new t.elements.Arc({_chart:this.chart.chart,_datasetIndex:this.index,_index:i})},this)},addElementAndReset:function(i,a){this.getDataset().metaData=this.getDataset().metaData||[];var s=new t.elements.Arc({_chart:this.chart.chart,_datasetIndex:this.index,_index:i});a&&e.isArray(this.getDataset().backgroundColor)&&this.getDataset().backgroundColor.splice(i,0,a),this.updateElement(s,i,!0),this.getDataset().metaData.splice(i,0,s)},getVisibleDatasetCount:function(){return e.where(this.chart.data.datasets,function(t){return e.isDatasetVisible(t)}).length},getRingIndex:function(t){for(var i=0,a=0;t>a;++a)e.isDatasetVisible(this.chart.data.datasets[a])&&++i;return i},update:function(t){var i=Math.min(this.chart.chartArea.right-this.chart.chartArea.left,this.chart.chartArea.bottom-this.chart.chartArea.top);this.chart.outerRadius=Math.max(i/2-this.chart.options.elements.arc.borderWidth/2,0),this.chart.innerRadius=Math.max(this.chart.options.cutoutPercentage?this.chart.outerRadius/100*this.chart.options.cutoutPercentage:1,0),this.chart.radiusLength=(this.chart.outerRadius-this.chart.innerRadius)/this.getVisibleDatasetCount(),this.getDataset().total=0,e.each(this.getDataset().data,function(t){isNaN(t)||(this.getDataset().total+=Math.abs(t))},this),this.outerRadius=this.chart.outerRadius-this.chart.radiusLength*this.getRingIndex(this.index),this.innerRadius=this.outerRadius-this.chart.radiusLength,e.each(this.getDataset().metaData,function(e,i){this.updateElement(e,i,t)},this)},updateElement:function(t,i,a){var s=(this.chart.chartArea.left+this.chart.chartArea.right)/2,o=(this.chart.chartArea.top+this.chart.chartArea.bottom)/2,n=Math.PI*-.5,r=Math.PI*-.5,l=a&&this.chart.options.animation.animateRotate?0:this.calculateCircumference(this.getDataset().data[i]),h=a&&this.chart.options.animation.animateScale?0:this.innerRadius,c=a&&this.chart.options.animation.animateScale?0:this.outerRadius;e.extend(t,{_chart:this.chart.chart,_datasetIndex:this.index,_index:i,_model:{x:s,y:o,startAngle:n,endAngle:r,circumference:l,outerRadius:c,innerRadius:h,backgroundColor:t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.arc.backgroundColor),hoverBackgroundColor:t.custom&&t.custom.hoverBackgroundColor?t.custom.hoverBackgroundColor:e.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor,i,this.chart.options.elements.arc.hoverBackgroundColor),borderWidth:t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.arc.borderWidth),borderColor:t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.arc.borderColor),label:e.getValueAtIndexOrDefault(this.getDataset().label,i,this.chart.data.labels[i])}}),a||(0===i?t._model.startAngle=Math.PI*-.5:t._model.startAngle=this.getDataset().metaData[i-1]._model.endAngle,t._model.endAngle=t._model.startAngle+t._model.circumference),t.pivot()},draw:function(t){var i=t||1;e.each(this.getDataset().metaData,function(t,e){t.transition(i).draw()})},setHoverStyle:function(t){var i=this.chart.data.datasets[t._datasetIndex],a=t._index;t._model.backgroundColor=t.custom&&t.custom.hoverBackgroundColor?t.custom.hoverBackgroundColor:e.getValueAtIndexOrDefault(i.hoverBackgroundColor,a,e.color(t._model.backgroundColor).saturate(.5).darken(.1).rgbString()),t._model.borderColor=t.custom&&t.custom.hoverBorderColor?t.custom.hoverBorderColor:e.getValueAtIndexOrDefault(i.hoverBorderColor,a,e.color(t._model.borderColor).saturate(.5).darken(.1).rgbString()),t._model.borderWidth=t.custom&&t.custom.hoverBorderWidth?t.custom.hoverBorderWidth:e.getValueAtIndexOrDefault(i.hoverBorderWidth,a,t._model.borderWidth)},removeHoverStyle:function(t){var i=(this.chart.data.datasets[t._datasetIndex],t._index);t._model.backgroundColor=t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.arc.backgroundColor),t._model.borderColor=t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.arc.borderColor),t._model.borderWidth=t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.arc.borderWidth)},calculateCircumference:function(t){return this.getDataset().total>0&&!isNaN(t)?1.999999*Math.PI*(t/this.getDataset().total):0}})}},{}],18:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.line={showLines:!0,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({addElements:function(){this.getDataset().metaData=this.getDataset().metaData||[],this.getDataset().metaDataset=this.getDataset().metaDataset||new t.elements.Line({_chart:this.chart.chart,_datasetIndex:this.index,_points:this.getDataset().metaData}),e.each(this.getDataset().data,function(e,i){this.getDataset().metaData[i]=this.getDataset().metaData[i]||new t.elements.Point({_chart:this.chart.chart,_datasetIndex:this.index,_index:i})},this)},addElementAndReset:function(e){this.getDataset().metaData=this.getDataset().metaData||[];var i=new t.elements.Point({_chart:this.chart.chart,_datasetIndex:this.index,_index:e});this.updateElement(i,e,!0),this.getDataset().metaData.splice(e,0,i),this.chart.options.showLines&&0!==this.chart.options.elements.line.tension&&this.updateBezierControlPoints()},update:function(t){var i,a=this.getDataset().metaDataset,s=this.getDataset().metaData,o=this.getScaleForId(this.getDataset().yAxisID);this.getScaleForId(this.getDataset().xAxisID);i=o.min<0&&o.max<0?o.getPixelForValue(o.max):o.min>0&&o.max>0?o.getPixelForValue(o.min):o.getPixelForValue(0),this.chart.options.showLines&&(a._scale=o,a._datasetIndex=this.index,a._children=s,a._model={tension:a.custom&&a.custom.tension?a.custom.tension:e.getValueOrDefault(this.getDataset().tension,this.chart.options.elements.line.tension),backgroundColor:a.custom&&a.custom.backgroundColor?a.custom.backgroundColor:this.getDataset().backgroundColor||this.chart.options.elements.line.backgroundColor,borderWidth:a.custom&&a.custom.borderWidth?a.custom.borderWidth:this.getDataset().borderWidth||this.chart.options.elements.line.borderWidth,borderColor:a.custom&&a.custom.borderColor?a.custom.borderColor:this.getDataset().borderColor||this.chart.options.elements.line.borderColor,borderCapStyle:a.custom&&a.custom.borderCapStyle?a.custom.borderCapStyle:this.getDataset().borderCapStyle||this.chart.options.elements.line.borderCapStyle,borderDash:a.custom&&a.custom.borderDash?a.custom.borderDash:this.getDataset().borderDash||this.chart.options.elements.line.borderDash,borderDashOffset:a.custom&&a.custom.borderDashOffset?a.custom.borderDashOffset:this.getDataset().borderDashOffset||this.chart.options.elements.line.borderDashOffset,borderJoinStyle:a.custom&&a.custom.borderJoinStyle?a.custom.borderJoinStyle:this.getDataset().borderJoinStyle||this.chart.options.elements.line.borderJoinStyle,fill:a.custom&&a.custom.fill?a.custom.fill:void 0!==this.getDataset().fill?this.getDataset().fill:this.chart.options.elements.line.fill,scaleTop:o.top,scaleBottom:o.bottom,scaleZero:i},a.pivot()),e.each(s,function(e,i){this.updateElement(e,i,t)},this),this.chart.options.showLines&&0!==this.chart.options.elements.line.tension&&this.updateBezierControlPoints()},getPointBackgroundColor:function(t,i){var a=this.chart.options.elements.point.backgroundColor,s=this.getDataset();return t.custom&&t.custom.backgroundColor?a=t.custom.backgroundColor:s.pointBackgroundColor?a=e.getValueAtIndexOrDefault(s.pointBackgroundColor,i,a):s.backgroundColor&&(a=s.backgroundColor),a},getPointBorderColor:function(t,i){var a=this.chart.options.elements.point.borderColor,s=this.getDataset();return t.custom&&t.custom.borderColor?a=t.custom.borderColor:s.pointBorderColor?a=e.getValueAtIndexOrDefault(this.getDataset().pointBorderColor,i,a):s.borderColor&&(a=s.borderColor),a},getPointBorderWidth:function(t,i){var a=this.chart.options.elements.point.borderWidth,s=this.getDataset();return t.custom&&void 0!==t.custom.borderWidth?a=t.custom.borderWidth:void 0!==s.pointBorderWidth?a=e.getValueAtIndexOrDefault(s.pointBorderWidth,i,a):void 0!==s.borderWidth&&(a=s.borderWidth),a},updateElement:function(t,i,a){var s,o=this.getScaleForId(this.getDataset().yAxisID),n=this.getScaleForId(this.getDataset().xAxisID);s=o.min<0&&o.max<0?o.getPixelForValue(o.max):o.min>0&&o.max>0?o.getPixelForValue(o.min):o.getPixelForValue(0),t._chart=this.chart.chart,t._xScale=n,t._yScale=o,t._datasetIndex=this.index,t._index=i,t._model={x:n.getPixelForValue(this.getDataset().data[i],i,this.index,this.chart.isCombo),y:a?s:this.calculatePointY(this.getDataset().data[i],i,this.index,this.chart.isCombo),tension:t.custom&&t.custom.tension?t.custom.tension:e.getValueOrDefault(this.getDataset().tension,this.chart.options.elements.line.tension),radius:t.custom&&t.custom.radius?t.custom.radius:e.getValueAtIndexOrDefault(this.getDataset().radius,i,this.chart.options.elements.point.radius),pointStyle:t.custom&&t.custom.pointStyle?t.custom.pointStyle:e.getValueAtIndexOrDefault(this.getDataset().pointStyle,i,this.chart.options.elements.point.pointStyle),backgroundColor:this.getPointBackgroundColor(t,i),borderColor:this.getPointBorderColor(t,i),borderWidth:this.getPointBorderWidth(t,i),hitRadius:t.custom&&t.custom.hitRadius?t.custom.hitRadius:e.getValueAtIndexOrDefault(this.getDataset().hitRadius,i,this.chart.options.elements.point.hitRadius)},t._model.skip=t.custom&&t.custom.skip?t.custom.skip:isNaN(t._model.x)||isNaN(t._model.y)},calculatePointY:function(t,i,a,s){var o=(this.getScaleForId(this.getDataset().xAxisID),this.getScaleForId(this.getDataset().yAxisID));if(o.options.stacked){for(var n=0,r=0,l=0;a>l;l++){var h=this.chart.data.datasets[l];"line"===h.type&&e.isDatasetVisible(h)&&(h.data[i]<0?r+=h.data[i]||0:n+=h.data[i]||0)}return 0>t?o.getPixelForValue(r+t):o.getPixelForValue(n+t)}return o.getPixelForValue(t)},updateBezierControlPoints:function(){e.each(this.getDataset().metaData,function(t,i){var a=e.splineCurve(e.previousItem(this.getDataset().metaData,i)._model,t._model,e.nextItem(this.getDataset().metaData,i)._model,t._model.tension);t._model.controlPointPreviousX=Math.max(Math.min(a.previous.x,this.chart.chartArea.right),this.chart.chartArea.left),t._model.controlPointPreviousY=Math.max(Math.min(a.previous.y,this.chart.chartArea.bottom),this.chart.chartArea.top),t._model.controlPointNextX=Math.max(Math.min(a.next.x,this.chart.chartArea.right),this.chart.chartArea.left),t._model.controlPointNextY=Math.max(Math.min(a.next.y,this.chart.chartArea.bottom),this.chart.chartArea.top),t.pivot()},this)},draw:function(t){var i=t||1;e.each(this.getDataset().metaData,function(t){t.transition(i)}),this.chart.options.showLines&&this.getDataset().metaDataset.transition(i).draw(),e.each(this.getDataset().metaData,function(t){t.draw()})},setHoverStyle:function(t){var i=this.chart.data.datasets[t._datasetIndex],a=t._index;t._model.radius=t.custom&&t.custom.hoverRadius?t.custom.hoverRadius:e.getValueAtIndexOrDefault(i.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),t._model.backgroundColor=t.custom&&t.custom.hoverBackgroundColor?t.custom.hoverBackgroundColor:e.getValueAtIndexOrDefault(i.pointHoverBackgroundColor,a,e.color(t._model.backgroundColor).saturate(.5).darken(.1).rgbString()),t._model.borderColor=t.custom&&t.custom.hoverBorderColor?t.custom.hoverBorderColor:e.getValueAtIndexOrDefault(i.pointHoverBorderColor,a,e.color(t._model.borderColor).saturate(.5).darken(.1).rgbString()),t._model.borderWidth=t.custom&&t.custom.hoverBorderWidth?t.custom.hoverBorderWidth:e.getValueAtIndexOrDefault(i.pointHoverBorderWidth,a,t._model.borderWidth)},removeHoverStyle:function(t){var i=(this.chart.data.datasets[t._datasetIndex],t._index);t._model.radius=t.custom&&t.custom.radius?t.custom.radius:e.getValueAtIndexOrDefault(this.getDataset().radius,i,this.chart.options.elements.point.radius),t._model.backgroundColor=this.getPointBackgroundColor(t,i),t._model.borderColor=this.getPointBorderColor(t,i),t._model.borderWidth=this.getPointBorderWidth(t,i)}})}},{}],19:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0},animateRotate:!0,animateScale:!0,aspectRatio:1,legendCallback:function(t){var e=[];if(e.push('
    '),t.data.datasets.length)for(var i=0;i'),t.data.labels[i]&&e.push(t.data.labels[i]),e.push("");return e.push("
"),e.join("")},legend:{labels:{generateLabels:function(t){return t.labels.length&&t.datasets.length?t.labels.map(function(e,i){return{text:e,fillStyle:t.datasets[0].backgroundColor[i],hidden:isNaN(t.datasets[0].data[i]),index:i}}):[]}},onClick:function(t,i){e.each(this.chart.data.datasets,function(t){t.metaHiddenData=t.metaHiddenData||[];var e=i.index;isNaN(t.data[e])?isNaN(t.metaHiddenData[e])||(t.data[e]=t.metaHiddenData[e]):(t.metaHiddenData[e]=t.data[e],t.data[e]=NaN)}),this.chart.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({linkScales:function(){},addElements:function(){this.getDataset().metaData=this.getDataset().metaData||[],e.each(this.getDataset().data,function(e,i){this.getDataset().metaData[i]=this.getDataset().metaData[i]||new t.elements.Arc({_chart:this.chart.chart,_datasetIndex:this.index,_index:i})},this)},addElementAndReset:function(e){this.getDataset().metaData=this.getDataset().metaData||[];var i=new t.elements.Arc({_chart:this.chart.chart,_datasetIndex:this.index,_index:e});this.updateElement(i,e,!0),this.getDataset().metaData.splice(e,0,i)},getVisibleDatasetCount:function(){return e.where(this.chart.data.datasets,function(t){return e.isDatasetVisible(t)}).length},update:function(t){var i=Math.min(this.chart.chartArea.right-this.chart.chartArea.left,this.chart.chartArea.bottom-this.chart.chartArea.top);this.chart.outerRadius=Math.max((i-this.chart.options.elements.arc.borderWidth/2)/2,0),this.chart.innerRadius=Math.max(this.chart.options.cutoutPercentage?this.chart.outerRadius/100*this.chart.options.cutoutPercentage:1,0),this.chart.radiusLength=(this.chart.outerRadius-this.chart.innerRadius)/this.getVisibleDatasetCount(),this.getDataset().total=0,e.each(this.getDataset().data,function(t){this.getDataset().total+=Math.abs(t)},this),this.outerRadius=this.chart.outerRadius-this.chart.radiusLength*this.index,this.innerRadius=this.outerRadius-this.chart.radiusLength,e.each(this.getDataset().metaData,function(e,i){this.updateElement(e,i,t)},this)},updateElement:function(t,i,a){for(var s=this.calculateCircumference(this.getDataset().data[i]),o=(this.chart.chartArea.left+this.chart.chartArea.right)/2,n=(this.chart.chartArea.top+this.chart.chartArea.bottom)/2,r=0,l=0;i>l;++l)isNaN(this.getDataset().data[l])||++r;var h=-.5*Math.PI+s*r,c=h+s,d={x:o,y:n,innerRadius:0,outerRadius:this.chart.options.animateScale?0:this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[i]),startAngle:this.chart.options.animateRotate?Math.PI*-.5:h,endAngle:this.chart.options.animateRotate?Math.PI*-.5:c,backgroundColor:t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.arc.backgroundColor),borderWidth:t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.arc.borderWidth),borderColor:t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.arc.borderColor),label:e.getValueAtIndexOrDefault(this.chart.data.labels,i,this.chart.data.labels[i])};e.extend(t,{_chart:this.chart.chart,_datasetIndex:this.index,_index:i,_scale:this.chart.scale,_model:a?d:{x:o,y:n,innerRadius:0, -outerRadius:this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[i]),startAngle:h,endAngle:c,backgroundColor:t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.arc.backgroundColor),borderWidth:t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.arc.borderWidth),borderColor:t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.arc.borderColor),label:e.getValueAtIndexOrDefault(this.chart.data.labels,i,this.chart.data.labels[i])}}),t.pivot()},draw:function(t){var i=t||1;e.each(this.getDataset().metaData,function(t,e){t.transition(i).draw()})},setHoverStyle:function(t){var i=this.chart.data.datasets[t._datasetIndex],a=t._index;t._model.backgroundColor=t.custom&&t.custom.hoverBackgroundColor?t.custom.hoverBackgroundColor:e.getValueAtIndexOrDefault(i.hoverBackgroundColor,a,e.color(t._model.backgroundColor).saturate(.5).darken(.1).rgbString()),t._model.borderColor=t.custom&&t.custom.hoverBorderColor?t.custom.hoverBorderColor:e.getValueAtIndexOrDefault(i.hoverBorderColor,a,e.color(t._model.borderColor).saturate(.5).darken(.1).rgbString()),t._model.borderWidth=t.custom&&t.custom.hoverBorderWidth?t.custom.hoverBorderWidth:e.getValueAtIndexOrDefault(i.hoverBorderWidth,a,t._model.borderWidth)},removeHoverStyle:function(t){var i=(this.chart.data.datasets[t._datasetIndex],t._index);t._model.backgroundColor=t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().backgroundColor,i,this.chart.options.elements.arc.backgroundColor),t._model.borderColor=t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().borderColor,i,this.chart.options.elements.arc.borderColor),t._model.borderWidth=t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().borderWidth,i,this.chart.options.elements.arc.borderWidth)},calculateCircumference:function(t){if(isNaN(t))return 0;var i=e.where(this.getDataset().data,function(t){return isNaN(t)}).length;return 2*Math.PI/(this.getDataset().data.length-i)}})}},{}],20:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({linkScales:function(){},addElements:function(){this.getDataset().metaData=this.getDataset().metaData||[],this.getDataset().metaDataset=this.getDataset().metaDataset||new t.elements.Line({_chart:this.chart.chart,_datasetIndex:this.index,_points:this.getDataset().metaData,_loop:!0}),e.each(this.getDataset().data,function(e,i){this.getDataset().metaData[i]=this.getDataset().metaData[i]||new t.elements.Point({_chart:this.chart.chart,_datasetIndex:this.index,_index:i,_model:{x:0,y:0}})},this)},addElementAndReset:function(e){this.getDataset().metaData=this.getDataset().metaData||[];var i=new t.elements.Point({_chart:this.chart.chart,_datasetIndex:this.index,_index:e});this.updateElement(i,e,!0),this.getDataset().metaData.splice(e,0,i),this.updateBezierControlPoints()},update:function(t){var i,a=this.getDataset().metaDataset,s=this.getDataset().metaData,o=this.chart.scale;i=o.min<0&&o.max<0?o.getPointPositionForValue(0,o.max):o.min>0&&o.max>0?o.getPointPositionForValue(0,o.min):o.getPointPositionForValue(0,0),e.extend(this.getDataset().metaDataset,{_datasetIndex:this.index,_children:this.getDataset().metaData,_model:{tension:a.custom&&a.custom.tension?a.custom.tension:e.getValueOrDefault(this.getDataset().tension,this.chart.options.elements.line.tension),backgroundColor:a.custom&&a.custom.backgroundColor?a.custom.backgroundColor:this.getDataset().backgroundColor||this.chart.options.elements.line.backgroundColor,borderWidth:a.custom&&a.custom.borderWidth?a.custom.borderWidth:this.getDataset().borderWidth||this.chart.options.elements.line.borderWidth,borderColor:a.custom&&a.custom.borderColor?a.custom.borderColor:this.getDataset().borderColor||this.chart.options.elements.line.borderColor,fill:a.custom&&a.custom.fill?a.custom.fill:void 0!==this.getDataset().fill?this.getDataset().fill:this.chart.options.elements.line.fill,borderCapStyle:a.custom&&a.custom.borderCapStyle?a.custom.borderCapStyle:this.getDataset().borderCapStyle||this.chart.options.elements.line.borderCapStyle,borderDash:a.custom&&a.custom.borderDash?a.custom.borderDash:this.getDataset().borderDash||this.chart.options.elements.line.borderDash,borderDashOffset:a.custom&&a.custom.borderDashOffset?a.custom.borderDashOffset:this.getDataset().borderDashOffset||this.chart.options.elements.line.borderDashOffset,borderJoinStyle:a.custom&&a.custom.borderJoinStyle?a.custom.borderJoinStyle:this.getDataset().borderJoinStyle||this.chart.options.elements.line.borderJoinStyle,scaleTop:o.top,scaleBottom:o.bottom,scaleZero:i}}),this.getDataset().metaDataset.pivot(),e.each(s,function(e,i){this.updateElement(e,i,t)},this),this.updateBezierControlPoints()},updateElement:function(t,i,a){var s=this.chart.scale.getPointPositionForValue(i,this.getDataset().data[i]);e.extend(t,{_datasetIndex:this.index,_index:i,_scale:this.chart.scale,_model:{x:a?this.chart.scale.xCenter:s.x,y:a?this.chart.scale.yCenter:s.y,tension:t.custom&&t.custom.tension?t.custom.tension:e.getValueOrDefault(this.getDataset().tension,this.chart.options.elements.line.tension),radius:t.custom&&t.custom.radius?t.custom.radius:e.getValueAtIndexOrDefault(this.getDataset().pointRadius,i,this.chart.options.elements.point.radius),backgroundColor:t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor,i,this.chart.options.elements.point.backgroundColor),borderColor:t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().pointBorderColor,i,this.chart.options.elements.point.borderColor),borderWidth:t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth,i,this.chart.options.elements.point.borderWidth),pointStyle:t.custom&&t.custom.pointStyle?t.custom.pointStyle:e.getValueAtIndexOrDefault(this.getDataset().pointStyle,i,this.chart.options.elements.point.pointStyle),hitRadius:t.custom&&t.custom.hitRadius?t.custom.hitRadius:e.getValueAtIndexOrDefault(this.getDataset().hitRadius,i,this.chart.options.elements.point.hitRadius)}}),t._model.skip=t.custom&&t.custom.skip?t.custom.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){e.each(this.getDataset().metaData,function(t,i){var a=e.splineCurve(e.previousItem(this.getDataset().metaData,i,!0)._model,t._model,e.nextItem(this.getDataset().metaData,i,!0)._model,t._model.tension);t._model.controlPointPreviousX=Math.max(Math.min(a.previous.x,this.chart.chartArea.right),this.chart.chartArea.left),t._model.controlPointPreviousY=Math.max(Math.min(a.previous.y,this.chart.chartArea.bottom),this.chart.chartArea.top),t._model.controlPointNextX=Math.max(Math.min(a.next.x,this.chart.chartArea.right),this.chart.chartArea.left),t._model.controlPointNextY=Math.max(Math.min(a.next.y,this.chart.chartArea.bottom),this.chart.chartArea.top),t.pivot()},this)},draw:function(t){var i=t||1;e.each(this.getDataset().metaData,function(t,e){t.transition(i)}),this.getDataset().metaDataset.transition(i).draw(),e.each(this.getDataset().metaData,function(t){t.draw()})},setHoverStyle:function(t){var i=this.chart.data.datasets[t._datasetIndex],a=t._index;t._model.radius=t.custom&&t.custom.hoverRadius?t.custom.hoverRadius:e.getValueAtIndexOrDefault(i.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),t._model.backgroundColor=t.custom&&t.custom.hoverBackgroundColor?t.custom.hoverBackgroundColor:e.getValueAtIndexOrDefault(i.pointHoverBackgroundColor,a,e.color(t._model.backgroundColor).saturate(.5).darken(.1).rgbString()),t._model.borderColor=t.custom&&t.custom.hoverBorderColor?t.custom.hoverBorderColor:e.getValueAtIndexOrDefault(i.pointHoverBorderColor,a,e.color(t._model.borderColor).saturate(.5).darken(.1).rgbString()),t._model.borderWidth=t.custom&&t.custom.hoverBorderWidth?t.custom.hoverBorderWidth:e.getValueAtIndexOrDefault(i.pointHoverBorderWidth,a,t._model.borderWidth)},removeHoverStyle:function(t){var i=(this.chart.data.datasets[t._datasetIndex],t._index);t._model.radius=t.custom&&t.custom.radius?t.custom.radius:e.getValueAtIndexOrDefault(this.getDataset().radius,i,this.chart.options.elements.point.radius),t._model.backgroundColor=t.custom&&t.custom.backgroundColor?t.custom.backgroundColor:e.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor,i,this.chart.options.elements.point.backgroundColor),t._model.borderColor=t.custom&&t.custom.borderColor?t.custom.borderColor:e.getValueAtIndexOrDefault(this.getDataset().pointBorderColor,i,this.chart.options.elements.point.borderColor),t._model.borderWidth=t.custom&&t.custom.borderWidth?t.custom.borderWidth:e.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth,i,this.chart.options.elements.point.borderWidth)}})}},{}],21:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,i,a){a||(t.animating=!0);for(var s=0;s1&&(e=Math.floor(this.dropFrames),this.dropFrames=this.dropFrames%1);for(var i=0;ithis.animations[i].animationObject.numSteps&&(this.animations[i].animationObject.currentStep=this.animations[i].animationObject.numSteps),this.animations[i].animationObject.render(this.animations[i].chartInstance,this.animations[i].animationObject),this.animations[i].animationObject.onAnimationProgress&&this.animations[i].animationObject.onAnimationProgress.call&&this.animations[i].animationObject.onAnimationProgress.call(this.animations[i].chartInstance,this.animations[i]),this.animations[i].animationObject.currentStep===this.animations[i].animationObject.numSteps?(this.animations[i].animationObject.onAnimationComplete&&this.animations[i].animationObject.onAnimationComplete.call&&this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance,this.animations[i]),this.animations[i].chartInstance.animating=!1,this.animations.splice(i,1)):++i;var a=Date.now(),s=(a-t)/this.frameDuration;this.dropFrames+=s,this.animations.length>0&&this.requestAnimationFrame()}}}},{}],22:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.types={},t.instances={},t.controllers={},t.Controller=function(i){return this.chart=i,this.config=i.config,this.options=this.config.options=e.configMerge(t.defaults.global,t.defaults[this.config.type],this.config.options||{}),this.id=e.uid(),Object.defineProperty(this,"data",{get:function(){return this.config.data}}),t.instances[this.id]=this,this.options.responsive&&this.resize(!0),this.initialize(),this},e.extend(t.Controller.prototype,{initialize:function(){return this.bindEvents(),this.ensureScalesHaveIDs(),this.buildOrUpdateControllers(),this.buildScales(),this.buildSurroundingItems(),this.updateLayout(),this.resetElements(),this.initToolTip(),this.update(),this},clear:function(){return e.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var i=this.chart.canvas,a=e.getMaximumWidth(this.chart.canvas),s=this.options.maintainAspectRatio&&isNaN(this.chart.aspectRatio)===!1&&isFinite(this.chart.aspectRatio)&&0!==this.chart.aspectRatio?a/this.chart.aspectRatio:e.getMaximumHeight(this.chart.canvas),o=this.chart.width!==a||this.chart.height!==s;return o?(i.width=this.chart.width=a,i.height=this.chart.height=s,e.retinaScale(this.chart),t||(this.stop(),this.update(this.options.responsiveAnimationDuration)),this):this},ensureScalesHaveIDs:function(){var t="x-axis-",i="y-axis-";this.options.scales&&(this.options.scales.xAxes&&this.options.scales.xAxes.length&&e.each(this.options.scales.xAxes,function(e,i){e.id=e.id||t+i}),this.options.scales.yAxes&&this.options.scales.yAxes.length&&e.each(this.options.scales.yAxes,function(t,e){t.id=t.id||i+e}))},buildScales:function(){if(this.scales={},this.options.scales&&(this.options.scales.xAxes&&this.options.scales.xAxes.length&&e.each(this.options.scales.xAxes,function(i,a){var s=e.getValueOrDefault(i.type,"category"),o=t.scaleService.getScaleConstructor(s);if(o){var n=new o({ctx:this.chart.ctx,options:i,chart:this,id:i.id});this.scales[n.id]=n}},this),this.options.scales.yAxes&&this.options.scales.yAxes.length&&e.each(this.options.scales.yAxes,function(i,a){var s=e.getValueOrDefault(i.type,"linear"),o=t.scaleService.getScaleConstructor(s);if(o){var n=new o({ctx:this.chart.ctx,options:i,chart:this,id:i.id});this.scales[n.id]=n}},this)),this.options.scale){var i=t.scaleService.getScaleConstructor(this.options.scale.type);if(i){var a=new i({ctx:this.chart.ctx,options:this.options.scale,chart:this});this.scale=a,this.scales.radialScale=a}}t.scaleService.addScalesToLayout(this)},buildSurroundingItems:function(){this.options.title&&(this.titleBlock=new t.Title({ctx:this.chart.ctx,options:this.options.title,chart:this}),t.layoutService.addBox(this,this.titleBlock)),this.options.legend&&(this.legend=new t.Legend({ctx:this.chart.ctx,options:this.options.legend,chart:this}),t.layoutService.addBox(this,this.legend))},updateLayout:function(){t.layoutService.update(this,this.chart.width,this.chart.height)},buildOrUpdateControllers:function(){var i=[],a=[];if(e.each(this.data.datasets,function(e,s){e.type||(e.type=this.config.type);var o=e.type;i.push(o),e.controller?e.controller.updateIndex(s):(e.controller=new t.controllers[o](this,s),a.push(e.controller))},this),i.length>1)for(var s=1;s0&&(e=this.data.datasets[e[0]._datasetIndex].metaData),e},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){this.clear(),e.unbindEvents(this,this.events),e.removeResizeListener(this.chart.canvas.parentNode);var i=this.chart.canvas;i.width=this.chart.width,i.height=this.chart.height,void 0!==this.chart.originalDevicePixelRatio&&this.chart.ctx.scale(1/this.chart.originalDevicePixelRatio,1/this.chart.originalDevicePixelRatio),i.style.width=this.chart.originalCanvasStyleWidth,i.style.height=this.chart.originalCanvasStyleHeight,delete t.instances[this.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){this.tooltip=new t.Tooltip({_chart:this.chart,_chartInstance:this,_data:this.data,_options:this.options},this)},bindEvents:function(){e.bindEvents(this,this.options.events,function(t){this.eventHandler(t)})},eventHandler:function(t){if(this.lastActive=this.lastActive||[],this.lastTooltipActive=this.lastTooltipActive||[],"mouseout"===t.type)this.active=[],this.tooltipActive=[];else{var i=this,a=function(e){switch(e){case"single":return i.getElementAtEvent(t);case"label":return i.getElementsAtEvent(t);case"dataset":return i.getDatasetAtEvent(t);default:return t}};this.active=a(this.options.hover.mode),this.tooltipActive=a(this.options.tooltips.mode)}this.options.hover.onHover&&this.options.hover.onHover.call(this,this.active),("mouseup"===t.type||"click"===t.type)&&(this.options.onClick&&this.options.onClick.call(this,t,this.active),this.legend&&this.legend.handleEvent&&this.legend.handleEvent(t));if(this.lastActive.length)switch(this.options.hover.mode){case"single":this.data.datasets[this.lastActive[0]._datasetIndex].controller.removeHoverStyle(this.lastActive[0],this.lastActive[0]._datasetIndex,this.lastActive[0]._index);break;case"label":case"dataset":for(var s=0;st)this.getDataset().metaData.splice(t,e-t);else if(t>e)for(var i=e;t>i;++i)this.addElementAndReset(i)},addElements:e.noop,addElementAndReset:e.noop,draw:e.noop,removeHoverStyle:e.noop,setHoverStyle:e.noop,update:e.noop}),t.DatasetController.extend=e.inherits}},{}],24:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){},pivot:function(){return this._view||(this._view=e.clone(this._model)),this._start=e.clone(this._view),this},transition:function(t){return this._view||(this._view=e.clone(this._model)),1===t?(this._view=this._model,this._start=null,this):(this._start||this.pivot(),e.each(this._model,function(i,a){if("_"!==a[0]&&this._model.hasOwnProperty(a))if(this._view.hasOwnProperty(a))if(i===this._view[a]);else if("string"==typeof i)try{var s=e.color(this._start[a]).mix(e.color(this._model[a]),t);this._view[a]=s.rgbString()}catch(o){this._view[a]=i}else if("number"==typeof i){var n=void 0!==this._start[a]&&isNaN(this._start[a])===!1?this._start[a]:0;this._view[a]=(this._model[a]-n)*t+n}else this._view[a]=i;else"number"!=typeof i||isNaN(this._view[a])?this._view[a]=i:this._view[a]=i*t;else;},this),this)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],25:[function(t,e,i){"use strict";var a=t("chartjs-color");e.exports=function(t){function e(t,e,i){var a;return"string"==typeof t?(a=parseInt(t,10),-1!=t.indexOf("%")&&(a=a/100*e.parentNode[i])):a=t,a}function i(t,i,a){var s,o=document.defaultView.getComputedStyle(t)[i],n=document.defaultView.getComputedStyle(t.parentNode)[i],r=null!==o&&"none"!==o,l=null!==n&&"none"!==n;return(r||l)&&(s=Math.min(r?e(o,t,a):Number.POSITIVE_INFINITY,l?e(n,t.parentNode,a):Number.POSITIVE_INFINITY)),s}var s=t.helpers={};s.each=function(t,e,i,a){var o,n;if(s.isArray(t))if(n=t.length,a)for(o=n-1;o>=0;o--)e.call(i,t[o],o);else for(o=0;n>o;o++)e.call(i,t[o],o);else if("object"==typeof t){var r=Object.keys(t);for(n=r.length,o=0;n>o;o++)e.call(i,t[r[o]],r[o])}},s.clone=function(t){var e={};return s.each(t,function(i,a){t.hasOwnProperty(a)&&(s.isArray(i)?e[a]=i.slice(0):"object"==typeof i&&null!==i?e[a]=s.clone(i):e[a]=i)}),e},s.extend=function(t){for(var e=arguments.length,i=[],a=1;e>a;a++)i.push(arguments[a]);return s.each(i,function(e){s.each(e,function(i,a){e.hasOwnProperty(a)&&(t[a]=i)})}),t},s.configMerge=function(e){var i=s.clone(e);return s.each(Array.prototype.slice.call(arguments,1),function(e){s.each(e,function(a,o){if(e.hasOwnProperty(o))if("scales"===o)i[o]=s.scaleMerge(i.hasOwnProperty(o)?i[o]:{},a);else if("scale"===o)i[o]=s.configMerge(i.hasOwnProperty(o)?i[o]:{},t.scaleService.getScaleDefaults(a.type),a);else if(i.hasOwnProperty(o)&&s.isArray(i[o])&&s.isArray(a)){var n=i[o];s.each(a,function(t,e){e=a[o].length||!a[o][i].type?a[o].push(s.configMerge(r,e)):e.type&&e.type!==a[o][i].type?a[o][i]=s.configMerge(a[o][i],r,e):a[o][i]=s.configMerge(a[o][i],e)}):(a[o]=[],s.each(e,function(e){var i=s.getValueOrDefault(e.type,"xAxes"===o?"category":"linear");a[o].push(s.configMerge(t.scaleService.getScaleDefaults(i),e))})):a.hasOwnProperty(o)&&"object"==typeof a[o]&&null!==a[o]&&"object"==typeof e?a[o]=s.configMerge(a[o],e):a[o]=e)}),a},s.getValueAtIndexOrDefault=function(t,e,i){return void 0===t||null===t?i:s.isArray(t)?e=0;a--){var s=t[a];if(e(s))return s}},s.inherits=function(t){var e=this,i=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},a=function(){this.constructor=i};return a.prototype=e.prototype,i.prototype=new a,i.extend=s.inherits,t&&s.extend(i.prototype,t),i.__super__=e.prototype,i},s.noop=function(){},s.uid=function(){var t=0;return function(){return"chart-"+t++}}(),s.warn=function(t){console&&"function"==typeof console.warn&&console.warn(t)},s.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},s.almostEquals=function(t,e,i){return Math.abs(t-e)0?1:-1)},s.log10=function(t){return Math.log10?Math.log10(t):Math.log(t)/Math.LN10},s.toRadians=function(t){return t*(Math.PI/180)},s.toDegrees=function(t){return t*(180/Math.PI)},s.getAngleFromPoint=function(t,e){var i=e.x-t.x,a=e.y-t.y,s=Math.sqrt(i*i+a*a),o=Math.atan2(a,i);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:s}},s.aliasPixel=function(t){return t%2===0?0:.5},s.splineCurve=function(t,e,i,a){var s=t.skip?e:t,o=e,n=i.skip?e:i,r=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2)),l=Math.sqrt(Math.pow(n.x-o.x,2)+Math.pow(n.y-o.y,2)),h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;var d=a*h,u=a*c;return{previous:{x:o.x-d*(n.x-s.x),y:o.y-d*(n.y-s.y)},next:{x:o.x+u*(n.x-s.x),y:o.y+u*(n.y-s.y)}}},s.nextItem=function(t,e,i){return i?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},s.previousItem=function(t,e,i){return i?0>=e?t[t.length-1]:t[e-1]:0>=e?t[0]:t[e-1]},s.niceNum=function(t,e){var i,a=Math.floor(s.log10(t)),o=t/Math.pow(10,a);return i=e?1.5>o?1:3>o?2:7>o?5:10:1>=o?1:2>=o?2:5>=o?5:10,i*Math.pow(10,a)};var o=s.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,i=0,a=1;return 0===t?0:1===(t/=1)?1:(i||(i=.3),at?-.5*(a*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/i)):a*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/i)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-o.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*o.easeInBounce(2*t):.5*o.easeOutBounce(2*t-1)+.5}};s.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),s.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),s.getRelativePosition=function(t,e){var i,a,o=t.originalEvent||t,n=t.currentTarget||t.srcElement,r=n.getBoundingClientRect();o.touches&&o.touches.length>0?(i=o.touches[0].clientX,a=o.touches[0].clientY):(i=o.clientX,a=o.clientY);var l=parseFloat(s.getStyle(n,"padding-left")),h=parseFloat(s.getStyle(n,"padding-top")),c=parseFloat(s.getStyle(n,"padding-right")),d=parseFloat(s.getStyle(n,"padding-bottom")),u=r.right-r.left-l-c,g=r.bottom-r.top-h-d;return i=Math.round((i-r.left-l)/u*n.width/e.currentDevicePixelRatio),a=Math.round((a-r.top-h)/g*n.height/e.currentDevicePixelRatio),{x:i,y:a}},s.addEvent=function(t,e,i){t.addEventListener?t.addEventListener(e,i):t.attachEvent?t.attachEvent("on"+e,i):t["on"+e]=i; -},s.removeEvent=function(t,e,i){t.removeEventListener?t.removeEventListener(e,i,!1):t.detachEvent?t.detachEvent("on"+e,i):t["on"+e]=s.noop},s.bindEvents=function(t,e,i){t.events||(t.events={}),s.each(e,function(e){t.events[e]=function(){i.apply(t,arguments)},s.addEvent(t.chart.canvas,e,t.events[e])})},s.unbindEvents=function(t,e){s.each(e,function(e,i){s.removeEvent(t.chart.canvas,i,e)})},s.getConstraintWidth=function(t){return i(t,"max-width","clientWidth")},s.getConstraintHeight=function(t){return i(t,"max-height","clientHeight")},s.getMaximumWidth=function(t){var e=t.parentNode,i=parseInt(s.getStyle(e,"padding-left"))+parseInt(s.getStyle(e,"padding-right")),a=e.clientWidth-i,o=s.getConstraintWidth(t);return void 0!==o&&(a=Math.min(a,o)),a},s.getMaximumHeight=function(t){var e=t.parentNode,i=parseInt(s.getStyle(e,"padding-top"))+parseInt(s.getStyle(e,"padding-bottom")),a=e.clientHeight-i,o=s.getConstraintHeight(t);return void 0!==o&&(a=Math.min(a,o)),a},s.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},s.retinaScale=function(t){var e=t.ctx,i=t.canvas.width,a=t.canvas.height,s=t.currentDevicePixelRatio=window.devicePixelRatio||1;1!==s&&(e.canvas.height=a*s,e.canvas.width=i*s,e.scale(s,s),t.originalDevicePixelRatio=t.originalDevicePixelRatio||s),e.canvas.style.width=i+"px",e.canvas.style.height=a+"px"},s.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},s.fontString=function(t,e,i){return e+" "+t+"px "+i},s.longestText=function(t,e,i,a){a=a||{},a.data=a.data||{},a.garbageCollect=a.garbageCollect||[],a.font!==e&&(a.data={},a.garbageCollect=[],a.font=e),t.font=e;var o=0;s.each(i,function(e){if(void 0!==e&&null!==e){var i=a.data[e];i||(i=a.data[e]=t.measureText(e).width,a.garbageCollect.push(e)),i>o&&(o=i)}});var n=a.garbageCollect.length/2;if(n>i.length){for(var r=0;n>r;r++)delete a.data[a.garbageCollect[r]];a.garbageCollect.splice(0,n)}return o},s.drawRoundedRectangle=function(t,e,i,a,s,o){t.beginPath(),t.moveTo(e+o,i),t.lineTo(e+a-o,i),t.quadraticCurveTo(e+a,i,e+a,i+o),t.lineTo(e+a,i+s-o),t.quadraticCurveTo(e+a,i+s,e+a-o,i+s),t.lineTo(e+o,i+s),t.quadraticCurveTo(e,i+s,e,i+s-o),t.lineTo(e,i+o),t.quadraticCurveTo(e,i,e+o,i),t.closePath()},s.color=function(e){return a?a(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.log("Color.js not found!"),e)},s.addResizeListener=function(t,e){var i=document.createElement("iframe"),a="chartjs-hidden-iframe";i.classlist?i.classlist.add(a):i.setAttribute("class",a),i.style.width="100%",i.style.display="block",i.style.border=0,i.style.height=0,i.style.margin=0,i.style.position="absolute",i.style.left=0,i.style.right=0,i.style.top=0,i.style.bottom=0,t.insertBefore(i,t.firstChild),(i.contentWindow||i).onresize=function(){e&&e()}},s.removeResizeListener=function(t){var e=t.querySelector(".chartjs-hidden-iframe");e&&e.parentNode.removeChild(e)},s.isArray=function(t){return Array.isArray?Array.isArray(t):"[object Array]"===Object.prototype.toString.call(t)},s.pushAllIfDefined=function(t,e){"undefined"!=typeof t&&(s.isArray(t)?e.push.apply(e,t):e.push(t))},s.isDatasetVisible=function(t){return!t.hidden},s.callCallback=function(t,e,i){t&&"function"==typeof t.call&&t.apply(i,e)}}},{"chartjs-color":5}],26:[function(t,e,i){"use strict";e.exports=function(){var t=function(e,i){this.config=i,e.length&&e[0].getContext&&(e=e[0]),e.getContext&&(e=e.getContext("2d")),this.ctx=e,this.canvas=e.canvas,this.width=e.canvas.width||parseInt(t.helpers.getStyle(e.canvas,"width"))||t.helpers.getMaximumWidth(e.canvas),this.height=e.canvas.height||parseInt(t.helpers.getStyle(e.canvas,"height"))||t.helpers.getMaximumHeight(e.canvas),this.aspectRatio=this.width/this.height,(isNaN(this.aspectRatio)||isFinite(this.aspectRatio)===!1)&&(this.aspectRatio=void 0!==i.aspectRatio?i.aspectRatio:2),this.originalCanvasStyleWidth=e.canvas.style.width,this.originalCanvasStyleHeight=e.canvas.style.height,t.helpers.retinaScale(this),i&&(this.controller=new t.Controller(this));var a=this;return t.helpers.addResizeListener(e.canvas.parentNode,function(){a.controller&&a.controller.config.options.responsive&&a.controller.resize()}),this.controller?this.controller:this};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"single",animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('
    ');for(var i=0;i'),t.data.datasets[i].label&&e.push(t.data.datasets[i].label),e.push("");return e.push("
"),e.join("")}}},t}},{}],27:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,i,a){function s(t){var e,i=t.isHorizontal();i?(e=t.update(t.options.fullWidth?m:k,y),D-=e.height):(e=t.update(v,x),k-=e.width),S.push({horizontal:i,minSize:e,box:t})}function o(t){var i=e.findNextWhere(S,function(e){return e.box===t});if(i)if(t.isHorizontal()){var a={left:C,right:w,top:0,bottom:0};t.update(t.options.fullWidth?m:k,p/2,a)}else t.update(i.minSize.width,D)}function n(t){var i=e.findNextWhere(S,function(e){return e.box===t}),a={left:0,right:0,top:_,bottom:A};i&&t.update(i.minSize.width,D,a)}function r(t){t.isHorizontal()?(t.left=t.options.fullWidth?l:C,t.right=t.options.fullWidth?i-l:C+k,t.top=P,t.bottom=P+t.height,P=t.bottom):(t.left=F,t.right=F+t.width,t.top=_,t.bottom=_+D,F=t.right)}if(t){var l=0,h=0,c=e.where(t.boxes,function(t){return"left"===t.options.position}),d=e.where(t.boxes,function(t){return"right"===t.options.position}),u=e.where(t.boxes,function(t){return"top"===t.options.position}),g=e.where(t.boxes,function(t){return"bottom"===t.options.position}),f=e.where(t.boxes,function(t){return"chartArea"===t.options.position});u.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),g.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var m=i-2*l,p=a-2*h,b=m/2,x=p/2,v=(i-b)/(c.length+d.length),y=(a-x)/(u.length+g.length),k=m,D=p,S=[];e.each(c.concat(d,u,g),s);var C=l,w=l,_=h,A=h;e.each(c.concat(d),o),e.each(c,function(t){C+=t.width}),e.each(d,function(t){w+=t.width}),e.each(u.concat(g),o),e.each(u,function(t){_+=t.height}),e.each(g,function(t){A+=t.height}),e.each(c.concat(d),n),C=l,w=l,_=h,A=h,e.each(c,function(t){C+=t.width}),e.each(d,function(t){w+=t.width}),e.each(u,function(t){_+=t.height}),e.each(g,function(t){A+=t.height});var I=a-_-A,M=i-C-w;(M!==k||I!==D)&&(e.each(c,function(t){t.height=I}),e.each(d,function(t){t.height=I}),e.each(u,function(t){t.width=M}),e.each(g,function(t){t.width=M}),D=I,k=M);var F=l,P=h;e.each(c.concat(u),r),F+=k,P+=D,e.each(d,r),e.each(g,r),t.chartArea={left:C,top:_,right:C+k,bottom:_+D},e.each(f,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(k,D)})}}}}},{}],28:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var i=this.chart.data.datasets[e.datasetIndex];i.hidden=!i.hidden,this.chart.update()},labels:{boxWidth:40,padding:10,generateLabels:function(t){return e.isArray(t.datasets)?t.datasets.map(function(t,e){return{text:t.label,fillStyle:t.backgroundColor,hidden:t.hidden,lineCap:t.borderCapStyle,lineDash:t.borderDash,lineDashOffset:t.borderDashOffset,lineJoin:t.borderJoinStyle,lineWidth:t.borderWidth,strokeStyle:t.borderColor,datasetIndex:e}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){e.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:e.noop,update:function(t,e,i){return this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this.margins=i,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this.beforeBuildLabels(),this.buildLabels(),this.afterBuildLabels(),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate(),this.minSize},afterUpdate:e.noop,beforeSetDimensions:e.noop,setDimensions:function(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0,this.minSize={width:0,height:0}},afterSetDimensions:e.noop,beforeBuildLabels:e.noop,buildLabels:function(){this.legendItems=this.options.labels.generateLabels.call(this,this.chart.data),this.options.reverse&&this.legendItems.reverse()},afterBuildLabels:e.noop,beforeFit:e.noop,fit:function(){var i=this.ctx,a=e.getValueOrDefault(this.options.labels.fontSize,t.defaults.global.defaultFontSize),s=e.getValueOrDefault(this.options.labels.fontStyle,t.defaults.global.defaultFontStyle),o=e.getValueOrDefault(this.options.labels.fontFamily,t.defaults.global.defaultFontFamily),n=e.fontString(a,s,o);if(this.legendHitBoxes=[],this.isHorizontal()?this.minSize.width=this.maxWidth:this.minSize.width=this.options.display?10:0,this.isHorizontal()?this.minSize.height=this.options.display?10:0:this.minSize.height=this.maxHeight,this.options.display&&this.isHorizontal()){this.lineWidths=[0];var r=this.legendItems.length?a+this.options.labels.padding:0;i.textAlign="left",i.textBaseline="top",i.font=n,e.each(this.legendItems,function(t,e){var s=this.options.labels.boxWidth+a/2+i.measureText(t.text).width;this.lineWidths[this.lineWidths.length-1]+s+this.options.labels.padding>=this.width&&(r+=a+this.options.labels.padding,this.lineWidths[this.lineWidths.length]=this.left),this.legendHitBoxes[e]={left:0,top:0,width:s,height:a},this.lineWidths[this.lineWidths.length-1]+=s+this.options.labels.padding},this),this.minSize.height+=r}this.width=this.minSize.width,this.height=this.minSize.height},afterFit:e.noop,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){if(this.options.display){var i=this.ctx,a={x:this.left+(this.width-this.lineWidths[0])/2,y:this.top+this.options.labels.padding,line:0},s=e.getValueOrDefault(this.options.labels.fontColor,t.defaults.global.defaultFontColor),o=e.getValueOrDefault(this.options.labels.fontSize,t.defaults.global.defaultFontSize),n=e.getValueOrDefault(this.options.labels.fontStyle,t.defaults.global.defaultFontStyle),r=e.getValueOrDefault(this.options.labels.fontFamily,t.defaults.global.defaultFontFamily),l=e.fontString(o,n,r);this.isHorizontal()&&(i.textAlign="left",i.textBaseline="top",i.lineWidth=.5,i.strokeStyle=s,i.fillStyle=s,i.font=l,e.each(this.legendItems,function(e,s){var n=i.measureText(e.text).width,r=this.options.labels.boxWidth+o/2+n;a.x+r>=this.width&&(a.y+=o+this.options.labels.padding,a.line++,a.x=this.left+(this.width-this.lineWidths[a.line])/2),i.save();var l=function(t,e){return void 0!==t?t:e};i.fillStyle=l(e.fillStyle,t.defaults.global.defaultColor),i.lineCap=l(e.lineCap,t.defaults.global.elements.line.borderCapStyle),i.lineDashOffset=l(e.lineDashOffset,t.defaults.global.elements.line.borderDashOffset),i.lineJoin=l(e.lineJoin,t.defaults.global.elements.line.borderJoinStyle),i.lineWidth=l(e.lineWidth,t.defaults.global.elements.line.borderWidth),i.strokeStyle=l(e.strokeStyle,t.defaults.global.defaultColor),i.setLineDash&&i.setLineDash(l(e.lineDash,t.defaults.global.elements.line.borderDash)),i.strokeRect(a.x,a.y,this.options.labels.boxWidth,o),i.fillRect(a.x,a.y,this.options.labels.boxWidth,o),i.restore(),this.legendHitBoxes[s].left=a.x,this.legendHitBoxes[s].top=a.y,i.fillText(e.text,this.options.labels.boxWidth+o/2+a.x,a.y),e.hidden&&(i.beginPath(),i.lineWidth=2,i.moveTo(this.options.labels.boxWidth+o/2+a.x,a.y+o/2),i.lineTo(this.options.labels.boxWidth+o/2+a.x+n,a.y+o/2),i.stroke()),a.x+=r+this.options.labels.padding},this))}},handleEvent:function(t){var i=e.getRelativePosition(t,this.chart.chart);if(i.x>=this.left&&i.x<=this.right&&i.y>=this.top&&i.y<=this.bottom)for(var a=0;a=s.left&&i.x<=s.left+s.width&&i.y>=s.top&&i.y<=s.top+s.height){this.options.onClick&&this.options.onClick.call(this,t,this.legendItems[a]);break}}}})}},{}],29:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.scale={display:!0,gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawOnChartArea:!0,drawTicks:!0,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,maxRotation:90,mirror:!1,padding:10,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:20,callback:function(t){return""+t}}},t.Scale=t.Element.extend({beforeUpdate:function(){e.callCallback(this.options.beforeUpdate,[this])},update:function(t,i,a){return this.beforeUpdate(),this.maxWidth=t,this.maxHeight=i,this.margins=e.extend({left:0,right:0,top:0,bottom:0},a),this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this.beforeBuildTicks(),this.buildTicks(),this.afterBuildTicks(),this.beforeTickToLabelConversion(),this.convertTicksToLabels(),this.afterTickToLabelConversion(),this.beforeCalculateTickRotation(),this.calculateTickRotation(),this.afterCalculateTickRotation(),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate(),this.minSize},afterUpdate:function(){e.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){e.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0},afterSetDimensions:function(){e.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){e.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:e.noop,afterDataLimits:function(){e.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){e.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:e.noop,afterBuildTicks:function(){e.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){e.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){this.ticks=this.ticks.map(function(t,e,i){return this.options.ticks.userCallback?this.options.ticks.userCallback(t,e,i):this.options.ticks.callback(t,e,i)},this)},afterTickToLabelConversion:function(){e.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){e.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var i=e.getValueOrDefault(this.options.ticks.fontSize,t.defaults.global.defaultFontSize),a=e.getValueOrDefault(this.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),s=e.getValueOrDefault(this.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),o=e.fontString(i,a,s);this.ctx.font=o;var n,r=this.ctx.measureText(this.ticks[0]).width,l=this.ctx.measureText(this.ticks[this.ticks.length-1]).width;if(this.labelRotation=0,this.paddingRight=0,this.paddingLeft=0,this.options.display&&this.isHorizontal()){this.paddingRight=l/2+3,this.paddingLeft=r/2+3,this.longestTextCache||(this.longestTextCache={});for(var h,c,d=e.longestText(this.ctx,o,this.ticks,this.longestTextCache),u=d,g=this.getPixelForTick(1)-this.getPixelForTick(0)-6;u>g&&this.labelRotationthis.yLabelWidth&&(this.paddingLeft=n+i/2),this.paddingRight=i/2,c*d>this.maxHeight){this.labelRotation--;break}this.labelRotation++,u=h*d}}this.margins&&(this.paddingLeft=Math.max(this.paddingLeft-this.margins.left,0),this.paddingRight=Math.max(this.paddingRight-this.margins.right,0))},afterCalculateTickRotation:function(){e.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){e.callCallback(this.options.beforeFit,[this])},fit:function(){this.minSize={width:0,height:0};var i=e.getValueOrDefault(this.options.ticks.fontSize,t.defaults.global.defaultFontSize),a=e.getValueOrDefault(this.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),s=e.getValueOrDefault(this.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),o=e.fontString(i,a,s),n=e.getValueOrDefault(this.options.scaleLabel.fontSize,t.defaults.global.defaultFontSize),r=e.getValueOrDefault(this.options.scaleLabel.fontStyle,t.defaults.global.defaultFontStyle),l=e.getValueOrDefault(this.options.scaleLabel.fontFamily,t.defaults.global.defaultFontFamily);e.fontString(n,r,l);if(this.isHorizontal()?this.minSize.width=this.isFullWidth()?this.maxWidth-this.margins.left-this.margins.right:this.maxWidth:this.minSize.width=this.options.gridLines.display&&this.options.display?10:0,this.isHorizontal()?this.minSize.height=this.options.gridLines.display&&this.options.display?10:0:this.minSize.height=this.maxHeight,this.options.scaleLabel.display&&(this.isHorizontal()?this.minSize.height+=1.5*n:this.minSize.width+=1.5*n),this.options.ticks.display&&this.options.display){this.longestTextCache||(this.longestTextCache={});var h=e.longestText(this.ctx,o,this.ticks,this.longestTextCache);if(this.isHorizontal()){this.longestLabelWidth=h;var c=Math.sin(e.toRadians(this.labelRotation))*this.longestLabelWidth+1.5*i;this.minSize.height=Math.min(this.maxHeight,this.minSize.height+c),this.ctx.font=o;var d=this.ctx.measureText(this.ticks[0]).width,u=this.ctx.measureText(this.ticks[this.ticks.length-1]).width,g=Math.cos(e.toRadians(this.labelRotation)),f=Math.sin(e.toRadians(this.labelRotation));this.paddingLeft=0!==this.labelRotation?g*d+3:d/2+3,this.paddingRight=0!==this.labelRotation?f*(i/2)+3:u/2+3}else{var m=this.maxWidth-this.minSize.width;this.options.ticks.mirror||(h+=this.options.ticks.padding),m>h?this.minSize.width+=h:this.minSize.width=this.maxWidth,this.paddingTop=i/2,this.paddingBottom=i/2}}this.margins&&(this.paddingLeft=Math.max(this.paddingLeft-this.margins.left,0),this.paddingTop=Math.max(this.paddingTop-this.margins.top,0),this.paddingRight=Math.max(this.paddingRight-this.margins.right,0),this.paddingBottom=Math.max(this.paddingBottom-this.margins.bottom,0)),this.width=this.minSize.width,this.height=this.minSize.height},afterFit:function(){e.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function i(t){return null===t||"undefined"==typeof t?NaN:"number"==typeof t&&isNaN(t)?NaN:"object"==typeof t?t instanceof Date?t:i(this.isHorizontal()?t.x:t.y):t},getLabelForIndex:e.noop,getPixelForValue:e.noop,getPixelForTick:function(t,e){if(this.isHorizontal()){var i=this.width-(this.paddingLeft+this.paddingRight),a=i/Math.max(this.ticks.length-(this.options.gridLines.offsetGridLines?0:1),1),s=a*t+this.paddingLeft;e&&(s+=a/2);var o=this.left+Math.round(s);return o+=this.isFullWidth()?this.margins.left:0}var n=this.height-(this.paddingTop+this.paddingBottom);return this.top+t*(n/(this.ticks.length-1))},getPixelForDecimal:function(t){if(this.isHorizontal()){var e=this.width-(this.paddingLeft+this.paddingRight),i=e*t+this.paddingLeft,a=this.left+Math.round(i);return a+=this.isFullWidth()?this.margins.left:0}return this.top+t*this.height},draw:function(i){if(this.options.display){var a,s,o,n,r,l=0!==this.labelRotation,h=this.options.ticks.autoSkip;this.options.ticks.maxTicksLimit&&(r=this.options.ticks.maxTicksLimit);var c=e.getValueOrDefault(this.options.ticks.fontColor,t.defaults.global.defaultFontColor),d=e.getValueOrDefault(this.options.ticks.fontSize,t.defaults.global.defaultFontSize),u=e.getValueOrDefault(this.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),g=e.getValueOrDefault(this.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),f=e.fontString(d,u,g),m=e.getValueOrDefault(this.options.scaleLabel.fontColor,t.defaults.global.defaultFontColor),p=e.getValueOrDefault(this.options.scaleLabel.fontSize,t.defaults.global.defaultFontSize),b=e.getValueOrDefault(this.options.scaleLabel.fontStyle,t.defaults.global.defaultFontStyle),x=e.getValueOrDefault(this.options.scaleLabel.fontFamily,t.defaults.global.defaultFontFamily),v=e.fontString(p,b,x),y=Math.cos(e.toRadians(this.labelRotation)),k=(Math.sin(e.toRadians(this.labelRotation)),this.longestLabelWidth*y);if(this.ctx.fillStyle=c,this.isHorizontal()){a=!0;var D="bottom"===this.options.position?this.top:this.bottom-10,S="bottom"===this.options.position?this.top+10:this.bottom;if(s=!1,(k/2+this.options.ticks.autoSkipPadding)*this.ticks.length>this.width-(this.paddingLeft+this.paddingRight)&&(s=1+Math.floor((k/2+this.options.ticks.autoSkipPadding)*this.ticks.length/(this.width-(this.paddingLeft+this.paddingRight)))),r&&this.ticks.length>r)for(;!s||this.ticks.length/(s||1)>r;)s||(s=1),s+=1;h||(s=!1),e.each(this.ticks,function(t,o){var n=this.ticks.length===o+1,r=s>1&&o%s>0||o%s===0&&o+s>this.ticks.length;if((!r||n)&&void 0!==t&&null!==t){var h=this.getPixelForTick(o),c=this.getPixelForTick(o,this.options.gridLines.offsetGridLines);this.options.gridLines.display&&(o===("undefined"!=typeof this.zeroLineIndex?this.zeroLineIndex:0)?(this.ctx.lineWidth=this.options.gridLines.zeroLineWidth,this.ctx.strokeStyle=this.options.gridLines.zeroLineColor,a=!0):a&&(this.ctx.lineWidth=this.options.gridLines.lineWidth,this.ctx.strokeStyle=this.options.gridLines.color,a=!1),h+=e.aliasPixel(this.ctx.lineWidth),this.ctx.beginPath(),this.options.gridLines.drawTicks&&(this.ctx.moveTo(h,D),this.ctx.lineTo(h,S)),this.options.gridLines.drawOnChartArea&&(this.ctx.moveTo(h,i.top),this.ctx.lineTo(h,i.bottom)),this.ctx.stroke()),this.options.ticks.display&&(this.ctx.save(),this.ctx.translate(c,l?this.top+12:"top"===this.options.position?this.bottom-10:this.top+10),this.ctx.rotate(-1*e.toRadians(this.labelRotation)),this.ctx.font=f,this.ctx.textAlign=l?"right":"center",this.ctx.textBaseline=l?"middle":"top"===this.options.position?"bottom":"top",this.ctx.fillText(t,0,0),this.ctx.restore())}},this),this.options.scaleLabel.display&&(this.ctx.textAlign="center",this.ctx.textBaseline="middle",this.ctx.fillStyle=m,this.ctx.font=v,o=this.left+(this.right-this.left)/2,n="bottom"===this.options.position?this.bottom-p/2:this.top+p/2,this.ctx.fillText(this.options.scaleLabel.labelString,o,n))}else{a=!0;var C="right"===this.options.position?this.left:this.right-5,w="right"===this.options.position?this.left+5:this.right;if(e.each(this.ticks,function(t,s){if(void 0!==t&&null!==t){var o=this.getPixelForTick(s);if(this.options.gridLines.display&&(s===("undefined"!=typeof this.zeroLineIndex?this.zeroLineIndex:0)?(this.ctx.lineWidth=this.options.gridLines.zeroLineWidth,this.ctx.strokeStyle=this.options.gridLines.zeroLineColor,a=!0):a&&(this.ctx.lineWidth=this.options.gridLines.lineWidth,this.ctx.strokeStyle=this.options.gridLines.color,a=!1),o+=e.aliasPixel(this.ctx.lineWidth),this.ctx.beginPath(),this.options.gridLines.drawTicks&&(this.ctx.moveTo(C,o),this.ctx.lineTo(w,o)),this.options.gridLines.drawOnChartArea&&(this.ctx.moveTo(i.left,o),this.ctx.lineTo(i.right,o)),this.ctx.stroke()),this.options.ticks.display){var n,r=this.getPixelForTick(s,this.options.gridLines.offsetGridLines);this.ctx.save(),"left"===this.options.position?this.options.ticks.mirror?(n=this.right+this.options.ticks.padding,this.ctx.textAlign="left"):(n=this.right-this.options.ticks.padding,this.ctx.textAlign="right"):this.options.ticks.mirror?(n=this.left-this.options.ticks.padding,this.ctx.textAlign="right"):(n=this.left+this.options.ticks.padding,this.ctx.textAlign="left"),this.ctx.translate(n,r),this.ctx.rotate(-1*e.toRadians(this.labelRotation)),this.ctx.font=f,this.ctx.textBaseline="middle",this.ctx.fillText(t,0,0),this.ctx.restore()}}},this),this.options.scaleLabel.display){o="left"===this.options.position?this.left+p/2:this.right-p/2,n=this.top+(this.bottom-this.top)/2;var _="left"===this.options.position?-.5*Math.PI:.5*Math.PI;this.ctx.save(),this.ctx.translate(o,n),this.ctx.rotate(_),this.ctx.textAlign="center",this.ctx.fillStyle=m,this.ctx.font=v,this.ctx.textBaseline="middle",this.ctx.fillText(this.options.scaleLabel.labelString,0,0),this.ctx.restore()}}this.ctx.lineWidth=this.options.gridLines.lineWidth,this.ctx.strokeStyle=this.options.gridLines.color;var A=this.left,I=this.right,M=this.top,F=this.bottom;this.isHorizontal()?(M=F="top"===this.options.position?this.bottom:this.top,M+=e.aliasPixel(this.ctx.lineWidth),F+=e.aliasPixel(this.ctx.lineWidth)):(A=I="left"===this.options.position?this.right:this.left,A+=e.aliasPixel(this.ctx.lineWidth),I+=e.aliasPixel(this.ctx.lineWidth)),this.ctx.beginPath(),this.ctx.moveTo(A,M),this.ctx.lineTo(I,F),this.ctx.stroke()}}})}},{}],30:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,i,a){this.constructors[t]=i,this.defaults[t]=e.clone(a)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(i){return this.defaults.hasOwnProperty(i)?e.scaleMerge(t.defaults.scale,this.defaults[i]):{}},addScalesToLayout:function(i){e.each(i.scales,function(e){t.layoutService.addBox(i,e)})}}}},{}],31:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""},t.Title=t.Element.extend({initialize:function(i){e.extend(this,i),this.options=e.configMerge(t.defaults.global.title,i.options),this.legendHitBoxes=[]},beforeUpdate:e.noop,update:function(t,e,i){return this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this.margins=i,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this.beforeBuildLabels(),this.buildLabels(),this.afterBuildLabels(),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate(),this.minSize},afterUpdate:e.noop,beforeSetDimensions:e.noop,setDimensions:function(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0,this.minSize={width:0,height:0}},afterSetDimensions:e.noop,beforeBuildLabels:e.noop,buildLabels:e.noop,afterBuildLabels:e.noop,beforeFit:e.noop,fit:function(){var i=(this.ctx,e.getValueOrDefault(this.options.fontSize,t.defaults.global.defaultFontSize)),a=e.getValueOrDefault(this.options.fontStyle,t.defaults.global.defaultFontStyle),s=e.getValueOrDefault(this.options.fontFamily,t.defaults.global.defaultFontFamily);e.fontString(i,a,s);this.isHorizontal()?this.minSize.width=this.maxWidth:this.minSize.width=0,this.isHorizontal()?this.minSize.height=0:this.minSize.height=this.maxHeight,this.isHorizontal()?this.options.display&&(this.minSize.height+=i+2*this.options.padding):this.options.display&&(this.minSize.width+=i+2*this.options.padding),this.width=this.minSize.width,this.height=this.minSize.height},afterFit:e.noop,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){if(this.options.display){var i,a,s=this.ctx,o=e.getValueOrDefault(this.options.fontColor,t.defaults.global.defaultFontColor),n=e.getValueOrDefault(this.options.fontSize,t.defaults.global.defaultFontSize),r=e.getValueOrDefault(this.options.fontStyle,t.defaults.global.defaultFontStyle),l=e.getValueOrDefault(this.options.fontFamily,t.defaults.global.defaultFontFamily),h=e.fontString(n,r,l);if(s.fillStyle=o,s.font=h,this.isHorizontal())s.textAlign="center",s.textBaseline="middle",i=this.left+(this.right-this.left)/2,a=this.top+(this.bottom-this.top)/2,s.fillText(this.options.text,i,a);else{i="left"===this.options.position?this.left+n/2:this.right-n/2,a=this.top+(this.bottom-this.top)/2;var c="left"===this.options.position?-.5*Math.PI:.5*Math.PI;s.save(),s.translate(i,a),s.rotate(c),s.textAlign="center",s.textBaseline="middle",s.fillText(this.options.text,0,0),s.restore()}}}})}},{}],32:[function(t,e,i){"use strict";e.exports=function(t){function e(t,e){return e&&(i.isArray(e)?t=t.concat(e):t.push(e)),t}var i=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"single",backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleColor:"#fff",titleAlign:"left",bodySpacing:2,bodyColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,yAlign:"center",xAlign:"center",caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",callbacks:{beforeTitle:i.noop,title:function(t,e){var i="";return t.length>0&&(t[0].xLabel?i=t[0].xLabel:e.labels.length>0&&t[0].indexthis._chart.height-t.height&&(this._model.yAlign="bottom");var e,i,a,s,o,n=this,r=(this._chartInstance.chartArea.left+this._chartInstance.chartArea.right)/2,l=(this._chartInstance.chartArea.top+this._chartInstance.chartArea.bottom)/2;"center"===this._model.yAlign?(e=function(t){return r>=t},i=function(t){return t>r}):(e=function(e){return e<=t.width/2},i=function(e){return e>=n._chart.width-t.width/2}),a=function(e){return e+t.width>n._chart.width},s=function(e){return e-t.width<0},o=function(t){return l>=t?"top":"bottom"},e(this._model.x)?(this._model.xAlign="left",a(this._model.x)&&(this._model.xAlign="center",this._model.yAlign=o(this._model.y))):i(this._model.x)&&(this._model.xAlign="right",s(this._model.x)&&(this._model.xAlign="center",this._model.yAlign=o(this._model.y)))},getBackgroundPoint:function(t,e){var i={x:t.x,y:t.y};return"right"===t.xAlign?i.x-=e.width:"center"===t.xAlign&&(i.x-=e.width/2),"top"===t.yAlign?i.y+=t.caretPadding+t.caretSize:"bottom"===t.yAlign?i.y-=e.height+t.caretPadding+t.caretSize:i.y-=e.height/2,"center"===t.yAlign?"left"===t.xAlign?i.x+=t.caretPadding+t.caretSize:"right"===t.xAlign&&(i.x-=t.caretPadding+t.caretSize):"left"===t.xAlign?i.x-=t.cornerRadius+t.caretPadding:"right"===t.xAlign&&(i.x+=t.cornerRadius+t.caretPadding),i},drawCaret:function(t,e,a,s){var o,n,r,l,h,c,d=this._view,u=this._chart.ctx;"center"===d.yAlign?("left"===d.xAlign?(o=t.x,n=o-d.caretSize,r=o):(o=t.x+e.width,n=o+d.caretSize,r=o),h=t.y+e.height/2,l=h-d.caretSize,c=h+d.caretSize):("left"===d.xAlign?(o=t.x+d.cornerRadius,n=o+d.caretSize,r=n+d.caretSize):"right"===d.xAlign?(o=t.x+e.width-d.cornerRadius,n=o-d.caretSize,r=n-d.caretSize):(n=t.x+e.width/2,o=n-d.caretSize,r=n+d.caretSize),"top"===d.yAlign?(l=t.y,h=l-d.caretSize,c=l):(l=t.y+e.height,h=l+d.caretSize,c=l));var g=i.color(d.backgroundColor);u.fillStyle=g.alpha(a*g.alpha()).rgbString(),u.beginPath(),u.moveTo(o,l),u.lineTo(n,h),u.lineTo(r,c),u.closePath(),u.fill()},drawTitle:function(t,e,a,s){if(e.title.length){a.textAlign=e._titleAlign,a.textBaseline="top";var o=i.color(e.titleColor);a.fillStyle=o.alpha(s*o.alpha()).rgbString(),a.font=i.fontString(e.titleFontSize,e._titleFontStyle,e._titleFontFamily),i.each(e.title,function(i,s){a.fillText(i,t.x,t.y),t.y+=e.titleFontSize+e.titleSpacing,s+1===e.title.length&&(t.y+=e.titleMarginBottom-e.titleSpacing)})}},drawBody:function(t,e,a,s){a.textAlign=e._bodyAlign,a.textBaseline="top";var o=i.color(e.bodyColor);a.fillStyle=o.alpha(s*o.alpha()).rgbString(),a.font=i.fontString(e.bodyFontSize,e._bodyFontStyle,e._bodyFontFamily),i.each(e.beforeBody,function(i){a.fillText(i,t.x,t.y),t.y+=e.bodyFontSize+e.bodySpacing}),i.each(e.body,function(o,n){"single"!==this._options.tooltips.mode&&(a.fillStyle=i.color(e.legendColorBackground).alpha(s).rgbaString(),a.fillRect(t.x,t.y,e.bodyFontSize,e.bodyFontSize),a.strokeStyle=i.color(e.labelColors[n].borderColor).alpha(s).rgbaString(),a.strokeRect(t.x,t.y,e.bodyFontSize,e.bodyFontSize),a.fillStyle=i.color(e.labelColors[n].backgroundColor).alpha(s).rgbaString(),a.fillRect(t.x+1,t.y+1,e.bodyFontSize-2,e.bodyFontSize-2),a.fillStyle=i.color(e.bodyColor).alpha(s).rgbaString()),a.fillText(o,t.x+("single"!==this._options.tooltips.mode?e.bodyFontSize+2:0),t.y),t.y+=e.bodyFontSize+e.bodySpacing},this),i.each(e.afterBody,function(i){a.fillText(i,t.x,t.y),t.y+=e.bodyFontSize}),t.y-=e.bodySpacing},drawFooter:function(t,e,a,s){if(e.footer.length){t.y+=e.footerMarginTop,a.textAlign=e._footerAlign,a.textBaseline="top";var o=i.color(e.footerColor);a.fillStyle=o.alpha(s*o.alpha()).rgbString(),a.font=i.fontString(e.footerFontSize,e._footerFontStyle,e._footerFontFamily),i.each(e.footer,function(i){a.fillText(i,t.x,t.y),t.y+=e.footerFontSize+e.footerSpacing})}},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var a=e.caretPadding,s=this.getTooltipSize(e),o={x:e.x,y:e.y},n=Math.abs(e.opacity<.001)?0:e.opacity;if(this._options.tooltips.enabled){var r=i.color(e.backgroundColor);t.fillStyle=r.alpha(n*r.alpha()).rgbString(),i.drawRoundedRectangle(t,o.x,o.y,s.width,s.height,e.cornerRadius),t.fill(),this.drawCaret(o,s,n,a),o.x+=e.xPadding,o.y+=e.yPadding,this.drawTitle(o,e,t,n),this.drawBody(o,e,t,n),this.drawFooter(o,e,t,n)}}}})}},{}],33:[function(t,e,i){"use strict";e.exports=function(t,e){var i=t.helpers;t.defaults.global.elements.arc={backgroundColor:t.defaults.global.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)1.5*Math.PI?a.startAngle-2*Math.PI:a.startAngle,n=a.endAngle<-.5*Math.PI?a.endAngle+2*Math.PI:a.endAngle>1.5*Math.PI?a.endAngle-2*Math.PI:a.endAngle,r=s.angle>=o&&s.angle<=n,l=s.distance>=a.innerRadius&&s.distance<=a.outerRadius;return r&&l}return!1},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t=this._chart.ctx,e=this._view;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,e.startAngle,e.endAngle),t.arc(e.x,e.y,e.innerRadius,e.endAngle,e.startAngle,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],34:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.elements.line={tension:.4,backgroundColor:t.defaults.global.defaultColor,borderWidth:3,borderColor:t.defaults.global.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",fill:!0},t.elements.Line=t.Element.extend({lineToNextPoint:function(t,e,i,a,s){var o=this._chart.ctx;e._view.skip?a.call(this,t,e,i):t._view.skip?s.call(this,t,e,i):0===e._view.tension?o.lineTo(e._view.x,e._view.y):o.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,e._view.controlPointPreviousX,e._view.controlPointPreviousY,e._view.x,e._view.y)},draw:function(){function i(t){n._view.skip||r._view.skip?t&&o.lineTo(a._view.scaleZero.x,a._view.scaleZero.y):o.bezierCurveTo(r._view.controlPointNextX,r._view.controlPointNextY,n._view.controlPointPreviousX,n._view.controlPointPreviousY,n._view.x,n._view.y)}var a=this,s=this._view,o=this._chart.ctx,n=this._children[0],r=this._children[this._children.length-1];o.save(),this._children.length>0&&s.fill&&(o.beginPath(),e.each(this._children,function(t,i){var a=e.previousItem(this._children,i),n=e.nextItem(this._children,i);0===i?(this._loop?o.moveTo(s.scaleZero.x,s.scaleZero.y):o.moveTo(t._view.x,s.scaleZero),t._view.skip?this._loop||o.moveTo(n._view.x,this._view.scaleZero):o.lineTo(t._view.x,t._view.y)):this.lineToNextPoint(a,t,n,function(t,e,i){this._loop?o.lineTo(this._view.scaleZero.x,this._view.scaleZero.y):(o.lineTo(t._view.x,this._view.scaleZero),o.moveTo(i._view.x,this._view.scaleZero))},function(t,e){o.lineTo(e._view.x,e._view.y)})},this),this._loop?i(!0):(o.lineTo(this._children[this._children.length-1]._view.x,s.scaleZero),o.lineTo(this._children[0]._view.x,s.scaleZero)),o.fillStyle=s.backgroundColor||t.defaults.global.defaultColor,o.closePath(),o.fill()),o.lineCap=s.borderCapStyle||t.defaults.global.elements.line.borderCapStyle,o.setLineDash&&o.setLineDash(s.borderDash||t.defaults.global.elements.line.borderDash),o.lineDashOffset=s.borderDashOffset||t.defaults.global.elements.line.borderDashOffset,o.lineJoin=s.borderJoinStyle||t.defaults.global.elements.line.borderJoinStyle,o.lineWidth=s.borderWidth||t.defaults.global.elements.line.borderWidth,o.strokeStyle=s.borderColor||t.defaults.global.defaultColor,o.beginPath(),e.each(this._children,function(t,i){var a=e.previousItem(this._children,i),s=e.nextItem(this._children,i);0===i?o.moveTo(t._view.x,t._view.y):this.lineToNextPoint(a,t,s,function(t,e,i){o.moveTo(i._view.x,i._view.y)},function(t,e){o.moveTo(e._view.x,e._view.y)})},this),this._loop&&this._children.length>0&&i(),o.stroke(),o.restore()}})}},{}],35:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.elements.point={radius:3,pointStyle:"circle",backgroundColor:t.defaults.global.defaultColor,borderWidth:1,borderColor:t.defaults.global.defaultColor,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var i=this._view;if(i){var a=i.hitRadius+i.radius;return Math.pow(t-i.x,2)+Math.pow(e-i.y,2)0){a.strokeStyle=i.borderColor||t.defaults.global.defaultColor,a.lineWidth=e.getValueOrDefault(i.borderWidth,t.defaults.global.elements.point.borderWidth),a.fillStyle=i.backgroundColor||t.defaults.global.defaultColor;var s,o,n=i.radius;switch(i.pointStyle){default:a.beginPath(),a.arc(i.x,i.y,n,0,2*Math.PI),a.closePath(),a.fill();break;case"triangle":a.beginPath();var r=3*n/Math.sqrt(3),l=r*Math.sqrt(3)/2;a.moveTo(i.x-r/2,i.y+l/3),a.lineTo(i.x+r/2,i.y+l/3),a.lineTo(i.x,i.y-2*l/3),a.closePath(),a.fill();break;case"rect":a.fillRect(i.x-1/Math.SQRT2*n,i.y-1/Math.SQRT2*n,2/Math.SQRT2*n,2/Math.SQRT2*n),a.strokeRect(i.x-1/Math.SQRT2*n,i.y-1/Math.SQRT2*n,2/Math.SQRT2*n,2/Math.SQRT2*n);break;case"rectRot":a.translate(i.x,i.y),a.rotate(Math.PI/4),a.fillRect(-1/Math.SQRT2*n,-1/Math.SQRT2*n,2/Math.SQRT2*n,2/Math.SQRT2*n),a.strokeRect(-1/Math.SQRT2*n,-1/Math.SQRT2*n,2/Math.SQRT2*n,2/Math.SQRT2*n),a.setTransform(1,0,0,1,0,0);break;case"cross":a.beginPath(),a.moveTo(i.x,i.y+n),a.lineTo(i.x,i.y-n),a.moveTo(i.x-n,i.y),a.lineTo(i.x+n,i.y),a.closePath();break;case"crossRot":a.beginPath(),s=Math.cos(Math.PI/4)*n,o=Math.sin(Math.PI/4)*n,a.moveTo(i.x-s,i.y-o),a.lineTo(i.x+s,i.y+o),a.moveTo(i.x-s,i.y+o),a.lineTo(i.x+s,i.y-o),a.closePath();break;case"star":a.beginPath(),a.moveTo(i.x,i.y+n),a.lineTo(i.x,i.y-n),a.moveTo(i.x-n,i.y),a.lineTo(i.x+n,i.y),s=Math.cos(Math.PI/4)*n,o=Math.sin(Math.PI/4)*n,a.moveTo(i.x-s,i.y-o),a.lineTo(i.x+s,i.y+o),a.moveTo(i.x-s,i.y+o),a.lineTo(i.x+s,i.y-o),a.closePath();break;case"line":a.beginPath(),a.moveTo(i.x-n,i.y),a.lineTo(i.x+n,i.y),a.closePath();break;case"dash":a.beginPath(),a.moveTo(i.x,i.y),a.lineTo(i.x+n,i.y),a.closePath()}a.stroke()}}}})}},{}],36:[function(t,e,i){"use strict";e.exports=function(t){t.helpers;t.defaults.global.elements.rectangle={backgroundColor:t.defaults.global.defaultColor,borderWidth:0,borderColor:t.defaults.global.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return l[(c+t)%4]}var e=this._chart.ctx,i=this._view,a=i.width/2,s=i.x-a,o=i.x+a,n=i.base-(i.base-i.y),r=i.borderWidth/2;i.borderWidth&&(s+=r,o-=r,n+=r),e.beginPath(),e.fillStyle=i.backgroundColor,e.strokeStyle=i.borderColor,e.lineWidth=i.borderWidth;var l=[[s,i.base],[s,n],[o,n],[o,i.base]],h=["bottom","left","top","right"],c=h.indexOf(i.borderSkipped,0);-1===c&&(c=0),e.moveTo.apply(e,t(0));for(var d=1;4>d;d++)e.lineTo.apply(e,t(d));e.fill(),i.borderWidth&&e.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=this._view,a=!1;return i&&(a=i.y=i.x-i.width/2&&t<=i.x+i.width/2&&e>=i.y&&e<=i.base:t>=i.x-i.width/2&&t<=i.x+i.width/2&&e>=i.base&&e<=i.y),a},inLabelRange:function(t){var e=this._view;return e?t>=e.x-e.width/2&&t<=e.x+e.width/2:!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],37:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers,i={position:"bottom"},a=t.Scale.extend({buildTicks:function(t){this.startIndex=0,this.endIndex=this.chart.data.labels.length;var i;void 0!==this.options.ticks.min&&(i=e.indexOf(this.chart.data.labels,this.options.ticks.min),this.startIndex=-1!==i?i:this.startIndex),void 0!==this.options.ticks.max&&(i=e.indexOf(this.chart.data.labels,this.options.ticks.max),this.endIndex=-1!==i?i:this.endIndex),this.ticks=0===this.startIndex&&this.endIndex===this.chart.data.labels.length?this.chart.data.labels:this.chart.data.labels.slice(this.startIndex,this.endIndex+1)},getLabelForIndex:function(t,e){return this.ticks[t]},getPixelForValue:function(t,e,i,a){var s=Math.max(this.ticks.length-(this.options.gridLines.offsetGridLines?0:1),1);if(this.isHorizontal()){var o=this.width-(this.paddingLeft+this.paddingRight),n=o/s,r=n*(e-this.startIndex)+this.paddingLeft;return this.options.gridLines.offsetGridLines&&a&&(r+=n/2),this.left+Math.round(r)}var l=this.height-(this.paddingTop+this.paddingBottom),h=l/s,c=h*(e-this.startIndex)+this.paddingTop;return this.options.gridLines.offsetGridLines&&a&&(c+=h/2),this.top+Math.round(c)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.startIndex,null,e)}});t.scaleService.registerScaleType("category",a,i)}},{}],38:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers,i={position:"left",ticks:{callback:function(t,i,a){var s=a[1]-a[0];Math.abs(s)>1&&t!==Math.floor(t)&&(s=t-Math.floor(t));var o=e.log10(Math.abs(s)),n="";if(0!==t){var r=-1*Math.floor(o);r=Math.max(Math.min(r,20),0),n=t.toFixed(r)}else n="0";return n}}},a=t.Scale.extend({determineDataLimits:function(){if(this.min=null,this.max=null,this.options.stacked){var t={},i=!1,a=!1;e.each(this.chart.data.datasets,function(s){void 0===t[s.type]&&(t[s.type]={positiveValues:[],negativeValues:[]});var o=t[s.type].positiveValues,n=t[s.type].negativeValues;e.isDatasetVisible(s)&&(this.isHorizontal()?s.xAxisID===this.id:s.yAxisID===this.id)&&e.each(s.data,function(t,e){var s=+this.getRightValue(t);isNaN(s)||(o[e]=o[e]||0,n[e]=n[e]||0,this.options.relativePoints?o[e]=100:0>s?(a=!0,n[e]+=s):(i=!0,o[e]+=s))},this)},this),e.each(t,function(t){var i=t.positiveValues.concat(t.negativeValues),a=e.min(i),s=e.max(i);this.min=null===this.min?a:Math.min(this.min,a),this.max=null===this.max?s:Math.max(this.max,s)},this)}else e.each(this.chart.data.datasets,function(t){e.isDatasetVisible(t)&&(this.isHorizontal()?t.xAxisID===this.id:t.yAxisID===this.id)&&e.each(t.data,function(t,e){var i=+this.getRightValue(t);isNaN(i)||(null===this.min?this.min=i:ithis.max&&(this.max=i))},this)},this);if(this.options.ticks.beginAtZero){var s=e.sign(this.min),o=e.sign(this.max);0>s&&0>o?this.max=0:s>0&&o>0&&(this.min=0)}void 0!==this.options.ticks.min?this.min=this.options.ticks.min:void 0!==this.options.ticks.suggestedMin&&(this.min=Math.min(this.min,this.options.ticks.suggestedMin)),void 0!==this.options.ticks.max?this.max=this.options.ticks.max:void 0!==this.options.ticks.suggestedMax&&(this.max=Math.max(this.max,this.options.ticks.suggestedMax)),this.min===this.max&&(this.min--,this.max++)},buildTicks:function(){this.ticks=[];var i;if(this.isHorizontal())i=Math.min(this.options.ticks.maxTicksLimit?this.options.ticks.maxTicksLimit:11,Math.ceil(this.width/50));else{var a=e.getValueOrDefault(this.options.ticks.fontSize,t.defaults.global.defaultFontSize);i=Math.min(this.options.ticks.maxTicksLimit?this.options.ticks.maxTicksLimit:11,Math.ceil(this.height/(2*a)))}i=Math.max(2,i);var s,o=this.options.ticks.fixedStepSize&&this.options.ticks.fixedStepSize>0||this.options.ticks.stepSize&&this.options.ticks.stepSize>0;if(o)s=e.getValueOrDefault(this.options.ticks.fixedStepSize,this.options.ticks.stepSize);else{var n=e.niceNum(this.max-this.min,!1);s=e.niceNum(n/(i-1),!0)}var r=Math.floor(this.min/s)*s,l=Math.ceil(this.max/s)*s,h=(l-r)/s;h=e.almostEquals(h,Math.round(h),s/1e3)?Math.round(h):Math.ceil(h),this.ticks.push(void 0!==this.options.ticks.min?this.options.ticks.min:r);for(var c=1;h>c;++c)this.ticks.push(r+c*s);this.ticks.push(void 0!==this.options.ticks.max?this.options.ticks.max:l),("left"===this.options.position||"right"===this.options.position)&&this.ticks.reverse(),this.max=e.max(this.ticks),this.min=e.min(this.ticks),this.options.ticks.reverse?(this.ticks.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},convertTicksToLabels:function(){this.ticksAsNumbers=this.ticks.slice(),this.zeroLineIndex=this.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(this)},getPixelForValue:function(t,e,i,a){var s,o=+this.getRightValue(t),n=this.end-this.start;if(this.isHorizontal()){var r=this.width-(this.paddingLeft+this.paddingRight);return s=this.left+r/n*(o-this.start),Math.round(s+this.paddingLeft)}var l=this.height-(this.paddingTop+this.paddingBottom);return s=this.bottom-this.paddingBottom-l/n*(o-this.start),Math.round(s)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticksAsNumbers[t],null,null,e)}});t.scaleService.registerScaleType("linear",a,i)}},{}],39:[function(t,e,i){"use strict";e.exports=function(t){var e=t.helpers,i={position:"left",ticks:{callback:function(e,i,a){var s=e/Math.pow(10,Math.floor(t.helpers.log10(e)));return 1===s||2===s||5===s||0===i||i===a.length-1?e.toExponential():""}}},a=t.Scale.extend({determineDataLimits:function(){if(this.min=null,this.max=null,this.options.stacked){var t={};e.each(this.chart.data.datasets,function(i){e.isDatasetVisible(i)&&(this.isHorizontal()?i.xAxisID===this.id:i.yAxisID===this.id)&&(void 0===t[i.type]&&(t[i.type]=[]),e.each(i.data,function(e,a){var s=t[i.type],o=+this.getRightValue(e);isNaN(o)||(s[a]=s[a]||0,this.options.relativePoints?s[a]=100:s[a]+=o)},this))},this),e.each(t,function(t){var i=e.min(t),a=e.max(t);this.min=null===this.min?i:Math.min(this.min,i),this.max=null===this.max?a:Math.max(this.max,a)},this)}else e.each(this.chart.data.datasets,function(t){e.isDatasetVisible(t)&&(this.isHorizontal()?t.xAxisID===this.id:t.yAxisID===this.id)&&e.each(t.data,function(t,e){var i=+this.getRightValue(t);isNaN(i)||(null===this.min?this.min=i:ithis.max&&(this.max=i))},this)},this);this.min=void 0!==this.options.ticks.min?this.options.ticks.min:this.min,this.max=void 0!==this.options.ticks.max?this.options.ticks.max:this.max,this.min===this.max&&(0!==this.min&&null!==this.min?(this.min=Math.pow(10,Math.floor(e.log10(this.min))-1),this.max=Math.pow(10,Math.floor(e.log10(this.max))+1)):(this.min=1,this.max=10))},buildTicks:function(){this.ticks=[];for(var t=void 0!==this.options.ticks.min?this.options.ticks.min:Math.pow(10,Math.floor(e.log10(this.min)));tthis.max&&(this.max=i))},this)},this),this.options.ticks.beginAtZero){var t=e.sign(this.min),i=e.sign(this.max);0>t&&0>i?this.max=0:t>0&&i>0&&(this.min=0)}void 0!==this.options.ticks.min?this.min=this.options.ticks.min:void 0!==this.options.ticks.suggestedMin&&(this.min=Math.min(this.min,this.options.ticks.suggestedMin)),void 0!==this.options.ticks.max?this.max=this.options.ticks.max:void 0!==this.options.ticks.suggestedMax&&(this.max=Math.max(this.max,this.options.ticks.suggestedMax)),this.min===this.max&&(this.min--,this.max++)},buildTicks:function(){this.ticks=[];var i=e.getValueOrDefault(this.options.ticks.fontSize,t.defaults.global.defaultFontSize),a=Math.min(this.options.ticks.maxTicksLimit?this.options.ticks.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)));a=Math.max(2,a);var s=e.niceNum(this.max-this.min,!1),o=e.niceNum(s/(a-1),!0),n=Math.floor(this.min/o)*o,r=Math.ceil(this.max/o)*o,l=Math.ceil((r-n)/o);this.ticks.push(void 0!==this.options.ticks.min?this.options.ticks.min:n);for(var h=1;l>h;++h)this.ticks.push(n+h*o);this.ticks.push(void 0!==this.options.ticks.max?this.options.ticks.max:r),this.max=e.max(this.ticks),this.min=e.min(this.ticks),this.options.ticks.reverse?(this.ticks.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),this.zeroLineIndex=this.ticks.indexOf(0)},convertTicksToLabels:function(){t.Scale.prototype.convertTicksToLabels.call(this),this.pointLabels=this.chart.data.labels.map(this.options.pointLabels.callback,this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var i,a,s,o,n,r,l,h,c,d,u,g,f=e.getValueOrDefault(this.options.pointLabels.fontSize,t.defaults.global.defaultFontSize),m=e.getValueOrDefault(this.options.pointLabels.fontStyle,t.defaults.global.defaultFontStyle),p=e.getValueOrDefault(this.options.pointLabels.fontFamily,t.defaults.global.defaultFontFamily),b=e.fontString(f,m,p),x=e.min([this.height/2-f-5,this.width/2]),v=this.width,y=0;for(this.ctx.font=b,a=0;av&&(v=i.x+o,n=a),i.x-ov&&(v=i.x+s,n=a):a>this.getValueCount()/2&&i.x-s0||this.options.reverse){var o=this.getDistanceFromCenterForValue(this.ticks[s]),n=this.yCenter-o;if(this.options.gridLines.display)if(i.strokeStyle=this.options.gridLines.color,i.lineWidth=this.options.gridLines.lineWidth,this.options.lineArc)i.beginPath(),i.arc(this.xCenter,this.yCenter,o,0,2*Math.PI),i.closePath(),i.stroke();else{i.beginPath();for(var r=0;r=0;a--){if(this.options.angleLines.display){var s=this.getPointPosition(a,this.getDistanceFromCenterForValue(this.options.reverse?this.min:this.max));i.beginPath(),i.moveTo(this.xCenter,this.yCenter),i.lineTo(s.x,s.y),i.stroke(),i.closePath()}var o=this.getPointPosition(a,this.getDistanceFromCenterForValue(this.options.reverse?this.min:this.max)+5),n=e.getValueOrDefault(this.options.pointLabels.fontColor,t.defaults.global.defaultFontColor),r=e.getValueOrDefault(this.options.pointLabels.fontSize,t.defaults.global.defaultFontSize),l=e.getValueOrDefault(this.options.pointLabels.fontStyle,t.defaults.global.defaultFontStyle),h=e.getValueOrDefault(this.options.pointLabels.fontFamily,t.defaults.global.defaultFontFamily),c=e.fontString(r,l,h);i.font=c,i.fillStyle=n;var d=this.pointLabels.length,u=this.pointLabels.length/2,g=u/2,f=g>a||a>d-g,m=a===g||a===d-g;0===a?i.textAlign="center":a===u?i.textAlign="center":u>a?i.textAlign="left":i.textAlign="right",m?i.textBaseline="middle":f?i.textBaseline="bottom":i.textBaseline="top",i.fillText(this.pointLabels[a]?this.pointLabels[a]:"",o.x,o.y)}}}}});t.scaleService.registerScaleType("radialLinear",a,i)}},{}],41:[function(t,e,i){"use strict";var a=t("moment");a="function"==typeof a?a:window.moment,e.exports=function(t){var e=t.helpers,i={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},s={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},o=t.Scale.extend({initialize:function(){if(!a)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return this.labelMoments[t][e]},determineDataLimits:function(){this.labelMoments=[];var t=[];this.chart.data.labels&&this.chart.data.labels.length>0?(e.each(this.chart.data.labels,function(e,i){var a=this.parseTime(e);this.options.time.round&&a.startOf(this.options.time.round), -t.push(a)},this),this.firstTick=a.min.call(this,t),this.lastTick=a.max.call(this,t)):(this.firstTick=null,this.lastTick=null),e.each(this.chart.data.datasets,function(i,s){var o=[];"object"==typeof i.data[0]?e.each(i.data,function(t,e){var i=this.parseTime(this.getRightValue(t));this.options.time.round&&i.startOf(this.options.time.round),o.push(i),this.firstTick=null!==this.firstTick?a.min(this.firstTick,i):i,this.lastTick=null!==this.lastTick?a.max(this.lastTick,i):i},this):o=t,this.labelMoments.push(o)},this),this.options.time.min&&(this.firstTick=this.parseTime(this.options.time.min)),this.options.time.max&&(this.lastTick=this.parseTime(this.options.time.max)),this.firstTick=(this.firstTick||a()).clone(),this.lastTick=(this.lastTick||a()).clone()},buildTicks:function(a){if(this.ticks=[],this.unitScale=1,this.scaleSizeInUnits=0,this.options.time.unit)this.tickUnit=this.options.time.unit||"day",this.displayFormat=this.options.time.displayFormats[this.tickUnit],this.scaleSizeInUnits=this.lastTick.diff(this.firstTick,this.tickUnit,!0),this.unitScale=e.getValueOrDefault(this.options.time.unitStepSize,1);else{var s=e.getValueOrDefault(this.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=this.isHorizontal()?this.width-(this.paddingLeft+this.paddingRight):this.height-(this.paddingTop+this.paddingBottom),n=this.tickFormatFunction(this.firstTick,0,[]),r=n.length*s,l=Math.cos(e.toRadians(this.options.ticks.maxRotation)),h=Math.sin(e.toRadians(this.options.ticks.maxRotation));r=r*l+s*h;var c=o/(r+10);this.tickUnit="millisecond",this.scaleSizeInUnits=this.lastTick.diff(this.firstTick,this.tickUnit,!0),this.displayFormat=this.options.time.displayFormats[this.tickUnit];for(var d=0,u=i.units[d];dMath.ceil(this.scaleSizeInUnits/c)){this.unitScale=e.getValueOrDefault(this.options.time.unitStepSize,u.steps[g]);break}break}if(u.maxStep===!1||Math.ceil(this.scaleSizeInUnits/c)=0)break;m%this.unitScale===0&&this.ticks.push(p)}(0!==this.ticks[this.ticks.length-1].diff(this.lastTick,this.tickUnit)||0===this.scaleSizeInUnits)&&(this.options.time.max?(this.ticks.push(this.lastTick.clone()),this.scaleSizeInUnits=this.lastTick.diff(this.ticks[0],this.tickUnit,!0)):(this.scaleSizeInUnits=Math.ceil(this.scaleSizeInUnits/this.unitScale)*this.unitScale,this.ticks.push(this.firstTick.clone().add(this.scaleSizeInUnits,this.tickUnit)),this.lastTick=this.ticks[this.ticks.length-1].clone()))},getLabelForIndex:function(t,e){var i=this.chart.data.labels&&t]*?>/g, ' ').replace(/ | /gi, ' ') - // remove punctuation - .replace(/[.(),;:!?%#$'"_+=\/\-]*/g,''); - } - jQuery.validator.addMethod("maxWords", function(value, element, params) { - return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length <= params; - }, jQuery.validator.format("Please enter {0} words or less.")); - - jQuery.validator.addMethod("minWords", function(value, element, params) { - return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params; - }, jQuery.validator.format("Please enter at least {0} words.")); - - jQuery.validator.addMethod("rangeWords", function(value, element, params) { - var valueStripped = stripHtml(value); - var regex = /\b\w+\b/g; - return this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1]; - }, jQuery.validator.format("Please enter between {0} and {1} words.")); - -}()); - -jQuery.validator.addMethod("letterswithbasicpunc", function(value, element) { - return this.optional(element) || /^[a-z\-.,()'"\s]+$/i.test(value); -}, "Letters or punctuation only please"); - -jQuery.validator.addMethod("alphanumeric", function(value, element) { - return this.optional(element) || /^\w+$/i.test(value); -}, "Letters, numbers, and underscores only please"); - -jQuery.validator.addMethod("lettersonly", function(value, element) { - return this.optional(element) || /^[a-z]+$/i.test(value); -}, "Letters only please"); - -jQuery.validator.addMethod("nowhitespace", function(value, element) { - return this.optional(element) || /^\S+$/i.test(value); -}, "No white space please"); - -jQuery.validator.addMethod("ziprange", function(value, element) { - return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value); -}, "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx"); - -jQuery.validator.addMethod("zipcodeUS", function(value, element) { - return this.optional(element) || /\d{5}-\d{4}$|^\d{5}$/.test(value); -}, "The specified US ZIP Code is invalid"); - -jQuery.validator.addMethod("integer", function(value, element) { - return this.optional(element) || /^-?\d+$/.test(value); -}, "A positive or negative non-decimal number please"); - -/** - * Return true, if the value is a valid vehicle identification number (VIN). - * - * Works with all kind of text inputs. - * - * @example - * @desc Declares a required input element whose value must be a valid vehicle identification number. - * - * @name jQuery.validator.methods.vinUS - * @type Boolean - * @cat Plugins/Validate/Methods - */ -jQuery.validator.addMethod("vinUS", function(v) { - if (v.length !== 17) { - return false; - } - var i, n, d, f, cd, cdv; - var LL = ["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"]; - var VL = [1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9]; - var FL = [8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2]; - var rs = 0; - for(i = 0; i < 17; i++){ - f = FL[i]; - d = v.slice(i,i+1); - if (i === 8) { - cdv = d; - } - if (!isNaN(d)) { - d *= f; - } else { - for (n = 0; n < LL.length; n++) { - if (d.toUpperCase() === LL[n]) { - d = VL[n]; - d *= f; - if (isNaN(cdv) && n === 8) { - cdv = LL[n]; - } - break; - } - } - } - rs += d; - } - cd = rs % 11; - if (cd === 10) { - cd = "X"; - } - if (cd === cdv) { - return true; - } - return false; -}, "The specified vehicle identification number (VIN) is invalid."); - -/** - * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy. - * - * @example jQuery.validator.methods.date("01/01/1900") - * @result true - * - * @example jQuery.validator.methods.date("01/13/1990") - * @result false - * - * @example jQuery.validator.methods.date("01.01.1900") - * @result false - * - * @example - * @desc Declares an optional input element whose value must be a valid date. - * - * @name jQuery.validator.methods.dateITA - * @type Boolean - * @cat Plugins/Validate/Methods - */ -jQuery.validator.addMethod("dateITA", function(value, element) { - var check = false; - var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/; - if( re.test(value)) { - var adata = value.split('/'); - var gg = parseInt(adata[0],10); - var mm = parseInt(adata[1],10); - var aaaa = parseInt(adata[2],10); - var xdata = new Date(aaaa,mm-1,gg); - if ( ( xdata.getFullYear() === aaaa ) && ( xdata.getMonth() === mm - 1 ) && ( xdata.getDate() === gg ) ){ - check = true; - } else { - check = false; - } - } else { - check = false; - } - return this.optional(element) || check; -}, "Please enter a correct date"); - -/** - * IBAN is the international bank account number. - * It has a country - specific format, that is checked here too - */ -jQuery.validator.addMethod("iban", function(value, element) { - // some quick simple tests to prevent needless work - if (this.optional(element)) { - return true; - } - if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(value))) { - return false; - } - - // check the country code and find the country specific format - var iban = value.replace(/ /g,'').toUpperCase(); // remove spaces and to upper case - var countrycode = iban.substring(0,2); - var bbancountrypatterns = { - 'AL': "\\d{8}[\\dA-Z]{16}", - 'AD': "\\d{8}[\\dA-Z]{12}", - 'AT': "\\d{16}", - 'AZ': "[\\dA-Z]{4}\\d{20}", - 'BE': "\\d{12}", - 'BH': "[A-Z]{4}[\\dA-Z]{14}", - 'BA': "\\d{16}", - 'BR': "\\d{23}[A-Z][\\dA-Z]", - 'BG': "[A-Z]{4}\\d{6}[\\dA-Z]{8}", - 'CR': "\\d{17}", - 'HR': "\\d{17}", - 'CY': "\\d{8}[\\dA-Z]{16}", - 'CZ': "\\d{20}", - 'DK': "\\d{14}", - 'DO': "[A-Z]{4}\\d{20}", - 'EE': "\\d{16}", - 'FO': "\\d{14}", - 'FI': "\\d{14}", - 'FR': "\\d{10}[\\dA-Z]{11}\\d{2}", - 'GE': "[\\dA-Z]{2}\\d{16}", - 'DE': "\\d{18}", - 'GI': "[A-Z]{4}[\\dA-Z]{15}", - 'GR': "\\d{7}[\\dA-Z]{16}", - 'GL': "\\d{14}", - 'GT': "[\\dA-Z]{4}[\\dA-Z]{20}", - 'HU': "\\d{24}", - 'IS': "\\d{22}", - 'IE': "[\\dA-Z]{4}\\d{14}", - 'IL': "\\d{19}", - 'IT': "[A-Z]\\d{10}[\\dA-Z]{12}", - 'KZ': "\\d{3}[\\dA-Z]{13}", - 'KW': "[A-Z]{4}[\\dA-Z]{22}", - 'LV': "[A-Z]{4}[\\dA-Z]{13}", - 'LB': "\\d{4}[\\dA-Z]{20}", - 'LI': "\\d{5}[\\dA-Z]{12}", - 'LT': "\\d{16}", - 'LU': "\\d{3}[\\dA-Z]{13}", - 'MK': "\\d{3}[\\dA-Z]{10}\\d{2}", - 'MT': "[A-Z]{4}\\d{5}[\\dA-Z]{18}", - 'MR': "\\d{23}", - 'MU': "[A-Z]{4}\\d{19}[A-Z]{3}", - 'MC': "\\d{10}[\\dA-Z]{11}\\d{2}", - 'MD': "[\\dA-Z]{2}\\d{18}", - 'ME': "\\d{18}", - 'NL': "[A-Z]{4}\\d{10}", - 'NO': "\\d{11}", - 'PK': "[\\dA-Z]{4}\\d{16}", - 'PS': "[\\dA-Z]{4}\\d{21}", - 'PL': "\\d{24}", - 'PT': "\\d{21}", - 'RO': "[A-Z]{4}[\\dA-Z]{16}", - 'SM': "[A-Z]\\d{10}[\\dA-Z]{12}", - 'SA': "\\d{2}[\\dA-Z]{18}", - 'RS': "\\d{18}", - 'SK': "\\d{20}", - 'SI': "\\d{15}", - 'ES': "\\d{20}", - 'SE': "\\d{20}", - 'CH': "\\d{5}[\\dA-Z]{12}", - 'TN': "\\d{20}", - 'TR': "\\d{5}[\\dA-Z]{17}", - 'AE': "\\d{3}\\d{16}", - 'GB': "[A-Z]{4}\\d{14}", - 'VG': "[\\dA-Z]{4}\\d{16}" - }; - var bbanpattern = bbancountrypatterns[countrycode]; - // As new countries will start using IBAN in the - // future, we only check if the countrycode is known. - // This prevents false negatives, while almost all - // false positives introduced by this, will be caught - // by the checksum validation below anyway. - // Strict checking should return FALSE for unknown - // countries. - if (typeof bbanpattern !== 'undefined') { - var ibanregexp = new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern + "$", ""); - if (!(ibanregexp.test(iban))) { - return false; // invalid country specific format - } - } - - // now check the checksum, first convert to digits - var ibancheck = iban.substring(4,iban.length) + iban.substring(0,4); - var ibancheckdigits = ""; - var leadingZeroes = true; - var charAt; - for (var i =0; i 9 && - phone_number.match(/^(\+?1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/); -}, "Please specify a valid phone number"); - -jQuery.validator.addMethod('phoneUK', function(phone_number, element) { - phone_number = phone_number.replace(/\(|\)|\s+|-/g,''); - return this.optional(element) || phone_number.length > 9 && - phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/); -}, 'Please specify a valid phone number'); - -jQuery.validator.addMethod('mobileUK', function(phone_number, element) { - phone_number = phone_number.replace(/\(|\)|\s+|-/g,''); - return this.optional(element) || phone_number.length > 9 && - phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[45789]\d{2}|624)\s?\d{3}\s?\d{3})$/); -}, 'Please specify a valid mobile number'); - -//Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers -jQuery.validator.addMethod('phonesUK', function(phone_number, element) { - phone_number = phone_number.replace(/\(|\)|\s+|-/g,''); - return this.optional(element) || phone_number.length > 9 && - phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[45789]\d{8}|624\d{6})))$/); -}, 'Please specify a valid uk phone number'); -// On the above three UK functions, do the following server side processing: -// Compare original input with this RegEx pattern: -// ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ -// Extract $1 and set $prefix to '+44' if $1 is '44', otherwise set $prefix to '0' -// Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. -// A number of very detailed GB telephone number RegEx patterns can also be found at: -// http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers - -// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK) -jQuery.validator.addMethod('postcodeUK', function(value, element) { - return this.optional(element) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(value); -}, 'Please specify a valid UK postcode'); - -// TODO check if value starts with <, otherwise don't try stripping anything -jQuery.validator.addMethod("strippedminlength", function(value, element, param) { - return jQuery(value).text().length >= param; -}, jQuery.validator.format("Please enter at least {0} characters")); - -// same as email, but TLD is optional -jQuery.validator.addMethod("email2", function(value, element, param) { - return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value); -}, jQuery.validator.messages.email); - -// same as url, but TLD is optional -jQuery.validator.addMethod("url2", function(value, element, param) { - return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); -}, jQuery.validator.messages.url); - -// NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator -// Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0 -// Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings) -jQuery.validator.addMethod("creditcardtypes", function(value, element, param) { - if (/[^0-9\-]+/.test(value)) { - return false; - } - - value = value.replace(/\D/g, ""); - - var validTypes = 0x0000; - - if (param.mastercard) { - validTypes |= 0x0001; - } - if (param.visa) { - validTypes |= 0x0002; - } - if (param.amex) { - validTypes |= 0x0004; - } - if (param.dinersclub) { - validTypes |= 0x0008; - } - if (param.enroute) { - validTypes |= 0x0010; - } - if (param.discover) { - validTypes |= 0x0020; - } - if (param.jcb) { - validTypes |= 0x0040; - } - if (param.unknown) { - validTypes |= 0x0080; - } - if (param.all) { - validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080; - } - if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard - return value.length === 16; - } - if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa - return value.length === 16; - } - if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex - return value.length === 15; - } - if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub - return value.length === 14; - } - if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute - return value.length === 15; - } - if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover - return value.length === 16; - } - if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb - return value.length === 16; - } - if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb - return value.length === 15; - } - if (validTypes & 0x0080) { //unknown - return true; - } - return false; -}, "Please enter a valid credit card number."); - -jQuery.validator.addMethod("ipv4", function(value, element, param) { - return this.optional(element) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(value); -}, "Please enter a valid IP v4 address."); - -jQuery.validator.addMethod("ipv6", function(value, element, param) { - return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value); -}, "Please enter a valid IP v6 address."); - -/** -* Return true if the field value matches the given format RegExp -* -* @example jQuery.validator.methods.pattern("AR1004",element,/^AR\d{4}$/) -* @result true -* -* @example jQuery.validator.methods.pattern("BR1004",element,/^AR\d{4}$/) -* @result false -* -* @name jQuery.validator.methods.pattern -* @type Boolean -* @cat Plugins/Validate/Methods -*/ -jQuery.validator.addMethod("pattern", function(value, element, param) { - if (this.optional(element)) { - return true; - } - if (typeof param === 'string') { - param = new RegExp('^(?:' + param + ')$'); - } - return param.test(value); -}, "Invalid format."); - - -/* - * Lets you say "at least X inputs that match selector Y must be filled." - * - * The end result is that neither of these inputs: - * - * - * - * - * ...will validate unless at least one of them is filled. - * - * partnumber: {require_from_group: [1,".productinfo"]}, - * description: {require_from_group: [1,".productinfo"]} - * - */ -jQuery.validator.addMethod("require_from_group", function(value, element, options) { - var validator = this; - var selector = options[1]; - var validOrNot = $(selector, element.form).filter(function() { - return validator.elementValue(this); - }).length >= options[0]; - - if(!$(element).data('being_validated')) { - var fields = $(selector, element.form); - fields.data('being_validated', true); - fields.valid(); - fields.data('being_validated', false); - } - return validOrNot; -}, jQuery.format("Please fill at least {0} of these fields.")); - -/* - * Lets you say "either at least X inputs that match selector Y must be filled, - * OR they must all be skipped (left blank)." - * - * The end result, is that none of these inputs: - * - * - * - * - * - * ...will validate unless either at least two of them are filled, - * OR none of them are. - * - * partnumber: {skip_or_fill_minimum: [2,".productinfo"]}, - * description: {skip_or_fill_minimum: [2,".productinfo"]}, - * color: {skip_or_fill_minimum: [2,".productinfo"]} - * - */ -jQuery.validator.addMethod("skip_or_fill_minimum", function(value, element, options) { - var validator = this, - numberRequired = options[0], - selector = options[1]; - var numberFilled = $(selector, element.form).filter(function() { - return validator.elementValue(this); - }).length; - var valid = numberFilled >= numberRequired || numberFilled === 0; - - if(!$(element).data('being_validated')) { - var fields = $(selector, element.form); - fields.data('being_validated', true); - fields.valid(); - fields.data('being_validated', false); - } - return valid; -}, jQuery.format("Please either skip these fields or fill at least {0} of them.")); - -// Accept a value from a file input based on a required mimetype -jQuery.validator.addMethod("accept", function(value, element, param) { - // Split mime on commas in case we have multiple types we can accept - var typeParam = typeof param === "string" ? param.replace(/\s/g, '').replace(/,/g, '|') : "image/*", - optionalValue = this.optional(element), - i, file; - - // Element is optional - if (optionalValue) { - return optionalValue; - } - - if ($(element).attr("type") === "file") { - // If we are using a wildcard, make it regex friendly - typeParam = typeParam.replace(/\*/g, ".*"); - - // Check if the element has a FileList before checking each file - if (element.files && element.files.length) { - for (i = 0; i < element.files.length; i++) { - file = element.files[i]; - - // Grab the mimetype from the loaded file, verify it matches - if (!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) { - return false; - } - } - } - } - - // Either return true because we've validated each file, or because the - // browser does not support element.files and the FileList feature - return true; -}, jQuery.format("Please enter a value with a valid mimetype.")); - -// Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept -jQuery.validator.addMethod("extension", function(value, element, param) { - param = typeof param === "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif"; - return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); -}, jQuery.format("Please enter a value with a valid extension.")); diff --git a/js/lib/jquery/plugins/validate/additional-methods.min.js b/js/lib/jquery/plugins/validate/additional-methods.min.js deleted file mode 100644 index 0c5539ad56e..00000000000 --- a/js/lib/jquery/plugins/validate/additional-methods.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery Validation Plugin - v1.11.1 - 3/22/2013\n* https://github.com/jzaefferer/jquery-validation -* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */(function(){function t(t){return t.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'"_+=\/\-]*/g,"")}jQuery.validator.addMethod("maxWords",function(e,i,a){return this.optional(i)||a>=t(e).match(/\b\w+\b/g).length},jQuery.validator.format("Please enter {0} words or less.")),jQuery.validator.addMethod("minWords",function(e,i,a){return this.optional(i)||t(e).match(/\b\w+\b/g).length>=a},jQuery.validator.format("Please enter at least {0} words.")),jQuery.validator.addMethod("rangeWords",function(e,i,a){var r=t(e),n=/\b\w+\b/g;return this.optional(i)||r.match(n).length>=a[0]&&r.match(n).length<=a[1]},jQuery.validator.format("Please enter between {0} and {1} words."))})(),jQuery.validator.addMethod("letterswithbasicpunc",function(t,e){return this.optional(e)||/^[a-z\-.,()'"\s]+$/i.test(t)},"Letters or punctuation only please"),jQuery.validator.addMethod("alphanumeric",function(t,e){return this.optional(e)||/^\w+$/i.test(t)},"Letters, numbers, and underscores only please"),jQuery.validator.addMethod("lettersonly",function(t,e){return this.optional(e)||/^[a-z]+$/i.test(t)},"Letters only please"),jQuery.validator.addMethod("nowhitespace",function(t,e){return this.optional(e)||/^\S+$/i.test(t)},"No white space please"),jQuery.validator.addMethod("ziprange",function(t,e){return this.optional(e)||/^90[2-5]\d\{2\}-\d{4}$/.test(t)},"Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx"),jQuery.validator.addMethod("zipcodeUS",function(t,e){return this.optional(e)||/\d{5}-\d{4}$|^\d{5}$/.test(t)},"The specified US ZIP Code is invalid"),jQuery.validator.addMethod("integer",function(t,e){return this.optional(e)||/^-?\d+$/.test(t)},"A positive or negative non-decimal number please"),jQuery.validator.addMethod("vinUS",function(t){if(17!==t.length)return!1;var e,i,a,r,n,s,u=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],d=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],o=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],l=0;for(e=0;17>e;e++){if(r=o[e],a=t.slice(e,e+1),8===e&&(s=a),isNaN(a)){for(i=0;u.length>i;i++)if(a.toUpperCase()===u[i]){a=d[i],a*=r,isNaN(s)&&8===i&&(s=u[i]);break}}else a*=r;l+=a}return n=l%11,10===n&&(n="X"),n===s?!0:!1},"The specified vehicle identification number (VIN) is invalid."),jQuery.validator.addMethod("dateITA",function(t,e){var i=!1,a=/^\d{1,2}\/\d{1,2}\/\d{4}$/;if(a.test(t)){var r=t.split("/"),n=parseInt(r[0],10),s=parseInt(r[1],10),u=parseInt(r[2],10),d=new Date(u,s-1,n);i=d.getFullYear()===u&&d.getMonth()===s-1&&d.getDate()===n?!0:!1}else i=!1;return this.optional(e)||i},"Please enter a correct date"),jQuery.validator.addMethod("iban",function(t,e){if(this.optional(e))return!0;if(!/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(t))return!1;var i=t.replace(/ /g,"").toUpperCase(),a=i.substring(0,2),r={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},n=r[a];if(n!==void 0){var s=RegExp("^[A-Z]{2}\\d{2}"+n+"$","");if(!s.test(i))return!1}for(var u,d=i.substring(4,i.length)+i.substring(0,4),o="",l=!0,h=0;d.length>h;h++)u=d.charAt(h),"0"!==u&&(l=!1),l||(o+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(u));for(var F="",c="",m=0;o.length>m;m++){var f=o.charAt(m);c=""+F+f,F=c%97}return 1===F},"Please specify a valid IBAN"),jQuery.validator.addMethod("dateNL",function(t,e){return this.optional(e)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(t)},"Please enter a correct date"),jQuery.validator.addMethod("phoneNL",function(t,e){return this.optional(e)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(t)},"Please specify a valid phone number."),jQuery.validator.addMethod("mobileNL",function(t,e){return this.optional(e)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(t)},"Please specify a valid mobile number"),jQuery.validator.addMethod("postalcodeNL",function(t,e){return this.optional(e)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(t)},"Please specify a valid postal code"),jQuery.validator.addMethod("bankaccountNL",function(t,e){if(this.optional(e))return!0;if(!/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(t))return!1;for(var i=t.replace(/ /g,""),a=0,r=i.length,n=0;r>n;n++){var s=r-n,u=i.substring(n,n+1);a+=s*u}return 0===a%11},"Please specify a valid bank account number"),jQuery.validator.addMethod("giroaccountNL",function(t,e){return this.optional(e)||/^[0-9]{1,7}$/.test(t)},"Please specify a valid giro account number"),jQuery.validator.addMethod("bankorgiroaccountNL",function(t,e){return this.optional(e)||$.validator.methods.bankaccountNL.call(this,t,e)||$.validator.methods.giroaccountNL.call(this,t,e)},"Please specify a valid bank or giro account number"),jQuery.validator.addMethod("time",function(t,e){return this.optional(e)||/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(t)},"Please enter a valid time, between 00:00 and 23:59"),jQuery.validator.addMethod("time12h",function(t,e){return this.optional(e)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(t)},"Please enter a valid time in 12-hour am/pm format"),jQuery.validator.addMethod("phoneUS",function(t,e){return t=t.replace(/\s+/g,""),this.optional(e)||t.length>9&&t.match(/^(\+?1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/)},"Please specify a valid phone number"),jQuery.validator.addMethod("phoneUK",function(t,e){return t=t.replace(/\(|\)|\s+|-/g,""),this.optional(e)||t.length>9&&t.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),jQuery.validator.addMethod("mobileUK",function(t,e){return t=t.replace(/\(|\)|\s+|-/g,""),this.optional(e)||t.length>9&&t.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[45789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),jQuery.validator.addMethod("phonesUK",function(t,e){return t=t.replace(/\(|\)|\s+|-/g,""),this.optional(e)||t.length>9&&t.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[45789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),jQuery.validator.addMethod("postcodeUK",function(t,e){return this.optional(e)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(t)},"Please specify a valid UK postcode"),jQuery.validator.addMethod("strippedminlength",function(t,e,i){return jQuery(t).text().length>=i},jQuery.validator.format("Please enter at least {0} characters")),jQuery.validator.addMethod("email2",function(t,e){return this.optional(e)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(t)},jQuery.validator.messages.email),jQuery.validator.addMethod("url2",function(t,e){return this.optional(e)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(t)},jQuery.validator.messages.url),jQuery.validator.addMethod("creditcardtypes",function(t,e,i){if(/[^0-9\-]+/.test(t))return!1;t=t.replace(/\D/g,"");var a=0;return i.mastercard&&(a|=1),i.visa&&(a|=2),i.amex&&(a|=4),i.dinersclub&&(a|=8),i.enroute&&(a|=16),i.discover&&(a|=32),i.jcb&&(a|=64),i.unknown&&(a|=128),i.all&&(a=255),1&a&&/^(5[12345])/.test(t)?16===t.length:2&a&&/^(4)/.test(t)?16===t.length:4&a&&/^(3[47])/.test(t)?15===t.length:8&a&&/^(3(0[012345]|[68]))/.test(t)?14===t.length:16&a&&/^(2(014|149))/.test(t)?15===t.length:32&a&&/^(6011)/.test(t)?16===t.length:64&a&&/^(3)/.test(t)?16===t.length:64&a&&/^(2131|1800)/.test(t)?15===t.length:128&a?!0:!1},"Please enter a valid credit card number."),jQuery.validator.addMethod("ipv4",function(t,e){return this.optional(e)||/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(t)},"Please enter a valid IP v4 address."),jQuery.validator.addMethod("ipv6",function(t,e){return this.optional(e)||/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(t)},"Please enter a valid IP v6 address."),jQuery.validator.addMethod("pattern",function(t,e,i){return this.optional(e)?!0:("string"==typeof i&&(i=RegExp("^(?:"+i+")$")),i.test(t))},"Invalid format."),jQuery.validator.addMethod("require_from_group",function(t,e,i){var a=this,r=i[1],n=$(r,e.form).filter(function(){return a.elementValue(this)}).length>=i[0];if(!$(e).data("being_validated")){var s=$(r,e.form);s.data("being_validated",!0),s.valid(),s.data("being_validated",!1)}return n},jQuery.format("Please fill at least {0} of these fields.")),jQuery.validator.addMethod("skip_or_fill_minimum",function(t,e,i){var a=this,r=i[0],n=i[1],s=$(n,e.form).filter(function(){return a.elementValue(this)}).length,u=s>=r||0===s;if(!$(e).data("being_validated")){var d=$(n,e.form);d.data("being_validated",!0),d.valid(),d.data("being_validated",!1)}return u},jQuery.format("Please either skip these fields or fill at least {0} of them.")),jQuery.validator.addMethod("accept",function(t,e,i){var a,r,n="string"==typeof i?i.replace(/\s/g,"").replace(/,/g,"|"):"image/*",s=this.optional(e);if(s)return s;if("file"===$(e).attr("type")&&(n=n.replace(/\*/g,".*"),e.files&&e.files.length))for(a=0;e.files.length>a;a++)if(r=e.files[a],!r.type.match(RegExp(".?("+n+")$","i")))return!1;return!0},jQuery.format("Please enter a value with a valid mimetype.")),jQuery.validator.addMethod("extension",function(t,e,i){return i="string"==typeof i?i.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(e)||t.match(RegExp(".("+i+")$","i"))},jQuery.format("Please enter a value with a valid extension.")); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/jquery.validate.js b/js/lib/jquery/plugins/validate/jquery.validate.js deleted file mode 100644 index 88ba300ea9c..00000000000 --- a/js/lib/jquery/plugins/validate/jquery.validate.js +++ /dev/null @@ -1,1231 +0,0 @@ -/*! - * jQuery Validation Plugin 1.11.1 - * - * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ - * http://docs.jquery.com/Plugins/Validation - * - * Copyright 2013 Jörn Zaefferer - * Released under the MIT license: - * http://www.opensource.org/licenses/mit-license.php - */ - -(function($) { - -$.extend($.fn, { - // http://docs.jquery.com/Plugins/Validation/validate - validate: function( options ) { - - // if nothing is selected, return nothing; can't chain anyway - if ( !this.length ) { - if ( options && options.debug && window.console ) { - console.warn( "Nothing selected, can't validate, returning nothing." ); - } - return; - } - - // check if a validator for this form was already created - var validator = $.data( this[0], "validator" ); - if ( validator ) { - return validator; - } - - // Add novalidate tag if HTML5. - this.attr( "novalidate", "novalidate" ); - - validator = new $.validator( options, this[0] ); - $.data( this[0], "validator", validator ); - - if ( validator.settings.onsubmit ) { - - this.validateDelegate( ":submit", "click", function( event ) { - if ( validator.settings.submitHandler ) { - validator.submitButton = event.target; - } - // allow suppressing validation by adding a cancel class to the submit button - if ( $(event.target).hasClass("cancel") ) { - validator.cancelSubmit = true; - } - - // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button - if ( $(event.target).attr("formnovalidate") !== undefined ) { - validator.cancelSubmit = true; - } - }); - - // validate the form on submit - this.submit( function( event ) { - if ( validator.settings.debug ) { - // prevent form submit to be able to see console output - event.preventDefault(); - } - function handle() { - var hidden; - if ( validator.settings.submitHandler ) { - if ( validator.submitButton ) { - // insert a hidden input as a replacement for the missing submit button - hidden = $("").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm); - } - validator.settings.submitHandler.call( validator, validator.currentForm, event ); - if ( validator.submitButton ) { - // and clean up afterwards; thanks to no-block-scope, hidden can be referenced - hidden.remove(); - } - return false; - } - return true; - } - - // prevent submit for invalid forms or custom submit handlers - if ( validator.cancelSubmit ) { - validator.cancelSubmit = false; - return handle(); - } - if ( validator.form() ) { - if ( validator.pendingRequest ) { - validator.formSubmitted = true; - return false; - } - return handle(); - } else { - validator.focusInvalid(); - return false; - } - }); - } - - return validator; - }, - // http://docs.jquery.com/Plugins/Validation/valid - valid: function() { - if ( $(this[0]).is("form")) { - return this.validate().form(); - } else { - var valid = true; - var validator = $(this[0].form).validate(); - this.each(function() { - valid = valid && validator.element(this); - }); - return valid; - } - }, - // attributes: space seperated list of attributes to retrieve and remove - removeAttrs: function( attributes ) { - var result = {}, - $element = this; - $.each(attributes.split(/\s/), function( index, value ) { - result[value] = $element.attr(value); - $element.removeAttr(value); - }); - return result; - }, - // http://docs.jquery.com/Plugins/Validation/rules - rules: function( command, argument ) { - var element = this[0]; - - if ( command ) { - var settings = $.data(element.form, "validator").settings; - var staticRules = settings.rules; - var existingRules = $.validator.staticRules(element); - switch(command) { - case "add": - $.extend(existingRules, $.validator.normalizeRule(argument)); - // remove messages from rules, but allow them to be set separetely - delete existingRules.messages; - staticRules[element.name] = existingRules; - if ( argument.messages ) { - settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); - } - break; - case "remove": - if ( !argument ) { - delete staticRules[element.name]; - return existingRules; - } - var filtered = {}; - $.each(argument.split(/\s/), function( index, method ) { - filtered[method] = existingRules[method]; - delete existingRules[method]; - }); - return filtered; - } - } - - var data = $.validator.normalizeRules( - $.extend( - {}, - $.validator.classRules(element), - $.validator.attributeRules(element), - $.validator.dataRules(element), - $.validator.staticRules(element) - ), element); - - // make sure required is at front - if ( data.required ) { - var param = data.required; - delete data.required; - data = $.extend({required: param}, data); - } - - return data; - } -}); - -// Custom selectors -$.extend($.expr[":"], { - // http://docs.jquery.com/Plugins/Validation/blank - blank: function( a ) { return !$.trim("" + $(a).val()); }, - // http://docs.jquery.com/Plugins/Validation/filled - filled: function( a ) { return !!$.trim("" + $(a).val()); }, - // http://docs.jquery.com/Plugins/Validation/unchecked - unchecked: function( a ) { return !$(a).prop("checked"); } -}); - -// constructor for validator -$.validator = function( options, form ) { - this.settings = $.extend( true, {}, $.validator.defaults, options ); - this.currentForm = form; - this.init(); -}; - -$.validator.format = function( source, params ) { - if ( arguments.length === 1 ) { - return function() { - var args = $.makeArray(arguments); - args.unshift(source); - return $.validator.format.apply( this, args ); - }; - } - if ( arguments.length > 2 && params.constructor !== Array ) { - params = $.makeArray(arguments).slice(1); - } - if ( params.constructor !== Array ) { - params = [ params ]; - } - $.each(params, function( i, n ) { - source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() { - return n; - }); - }); - return source; -}; - -$.extend($.validator, { - - defaults: { - messages: {}, - groups: {}, - rules: {}, - errorClass: "error", - validClass: "valid", - errorElement: "label", - focusInvalid: true, - errorContainer: $([]), - errorLabelContainer: $([]), - onsubmit: true, - ignore: ":hidden", - ignoreTitle: false, - onfocusin: function( element, event ) { - this.lastActive = element; - - // hide error label and remove error class on focus if enabled - if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { - if ( this.settings.unhighlight ) { - this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); - } - this.addWrapper(this.errorsFor(element)).hide(); - } - }, - onfocusout: function( element, event ) { - if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { - this.element(element); - } - }, - onkeyup: function( element, event ) { - if ( event.which === 9 && this.elementValue(element) === "" ) { - return; - } else if ( element.name in this.submitted || element === this.lastElement ) { - this.element(element); - } - }, - onclick: function( element, event ) { - // click on selects, radiobuttons and checkboxes - if ( element.name in this.submitted ) { - this.element(element); - } - // or option elements, check parent select in that case - else if ( element.parentNode.name in this.submitted ) { - this.element(element.parentNode); - } - }, - highlight: function( element, errorClass, validClass ) { - if ( element.type === "radio" ) { - this.findByName(element.name).addClass(errorClass).removeClass(validClass); - } else { - $(element).addClass(errorClass).removeClass(validClass); - } - }, - unhighlight: function( element, errorClass, validClass ) { - if ( element.type === "radio" ) { - this.findByName(element.name).removeClass(errorClass).addClass(validClass); - } else { - $(element).removeClass(errorClass).addClass(validClass); - } - } - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults - setDefaults: function( settings ) { - $.extend( $.validator.defaults, settings ); - }, - - messages: { - required: "This field is required.", - remote: "Please fix this field.", - email: "Please enter a valid email address.", - url: "Please enter a valid URL.", - date: "Please enter a valid date.", - dateISO: "Please enter a valid date (ISO).", - number: "Please enter a valid number.", - digits: "Please enter only digits.", - creditcard: "Please enter a valid credit card number.", - equalTo: "Please enter the same value again.", - maxlength: $.validator.format("Please enter no more than {0} characters."), - minlength: $.validator.format("Please enter at least {0} characters."), - rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), - range: $.validator.format("Please enter a value between {0} and {1}."), - max: $.validator.format("Please enter a value less than or equal to {0}."), - min: $.validator.format("Please enter a value greater than or equal to {0}.") - }, - - autoCreateRanges: false, - - prototype: { - - init: function() { - this.labelContainer = $(this.settings.errorLabelContainer); - this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); - this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); - this.submitted = {}; - this.valueCache = {}; - this.pendingRequest = 0; - this.pending = {}; - this.invalid = {}; - this.reset(); - - var groups = (this.groups = {}); - $.each(this.settings.groups, function( key, value ) { - if ( typeof value === "string" ) { - value = value.split(/\s/); - } - $.each(value, function( index, name ) { - groups[name] = key; - }); - }); - var rules = this.settings.rules; - $.each(rules, function( key, value ) { - rules[key] = $.validator.normalizeRule(value); - }); - - function delegate(event) { - var validator = $.data(this[0].form, "validator"), - eventType = "on" + event.type.replace(/^validate/, ""); - if ( validator.settings[eventType] ) { - validator.settings[eventType].call(validator, this[0], event); - } - } - $(this.currentForm) - .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " + - "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + - "[type='email'], [type='datetime'], [type='date'], [type='month'], " + - "[type='week'], [type='time'], [type='datetime-local'], " + - "[type='range'], [type='color'] ", - "focusin focusout keyup", delegate) - .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); - - if ( this.settings.invalidHandler ) { - $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); - } - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/form - form: function() { - this.checkForm(); - $.extend(this.submitted, this.errorMap); - this.invalid = $.extend({}, this.errorMap); - if ( !this.valid() ) { - $(this.currentForm).triggerHandler("invalid-form", [this]); - } - this.showErrors(); - return this.valid(); - }, - - checkForm: function() { - this.prepareForm(); - for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { - this.check( elements[i] ); - } - return this.valid(); - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/element - element: function( element ) { - element = this.validationTargetFor( this.clean( element ) ); - this.lastElement = element; - this.prepareElement( element ); - this.currentElements = $(element); - var result = this.check( element ) !== false; - if ( result ) { - delete this.invalid[element.name]; - } else { - this.invalid[element.name] = true; - } - if ( !this.numberOfInvalids() ) { - // Hide error containers on last error - this.toHide = this.toHide.add( this.containers ); - } - this.showErrors(); - return result; - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/showErrors - showErrors: function( errors ) { - if ( errors ) { - // add items to error list and map - $.extend( this.errorMap, errors ); - this.errorList = []; - for ( var name in errors ) { - this.errorList.push({ - message: errors[name], - element: this.findByName(name)[0] - }); - } - // remove items from success list - this.successList = $.grep( this.successList, function( element ) { - return !(element.name in errors); - }); - } - if ( this.settings.showErrors ) { - this.settings.showErrors.call( this, this.errorMap, this.errorList ); - } else { - this.defaultShowErrors(); - } - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/resetForm - resetForm: function() { - if ( $.fn.resetForm ) { - $(this.currentForm).resetForm(); - } - this.submitted = {}; - this.lastElement = null; - this.prepareForm(); - this.hideErrors(); - this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" ); - }, - - numberOfInvalids: function() { - return this.objectLength(this.invalid); - }, - - objectLength: function( obj ) { - var count = 0; - for ( var i in obj ) { - count++; - } - return count; - }, - - hideErrors: function() { - this.addWrapper( this.toHide ).hide(); - }, - - valid: function() { - return this.size() === 0; - }, - - size: function() { - return this.errorList.length; - }, - - focusInvalid: function() { - if ( this.settings.focusInvalid ) { - try { - $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) - .filter(":visible") - .focus() - // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find - .trigger("focusin"); - } catch(e) { - // ignore IE throwing errors when focusing hidden elements - } - } - }, - - findLastActive: function() { - var lastActive = this.lastActive; - return lastActive && $.grep(this.errorList, function( n ) { - return n.element.name === lastActive.name; - }).length === 1 && lastActive; - }, - - elements: function() { - var validator = this, - rulesCache = {}; - - // select all valid inputs inside the form (no submit or reset buttons) - return $(this.currentForm) - .find("input, select, textarea") - .not(":submit, :reset, :image, [disabled]") - .not( this.settings.ignore ) - .filter(function() { - if ( !this.name && validator.settings.debug && window.console ) { - console.error( "%o has no name assigned", this); - } - - // select only the first element for each name, and only those with rules specified - if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) { - return false; - } - - rulesCache[this.name] = true; - return true; - }); - }, - - clean: function( selector ) { - return $(selector)[0]; - }, - - errors: function() { - var errorClass = this.settings.errorClass.replace(" ", "."); - return $(this.settings.errorElement + "." + errorClass, this.errorContext); - }, - - reset: function() { - this.successList = []; - this.errorList = []; - this.errorMap = {}; - this.toShow = $([]); - this.toHide = $([]); - this.currentElements = $([]); - }, - - prepareForm: function() { - this.reset(); - this.toHide = this.errors().add( this.containers ); - }, - - prepareElement: function( element ) { - this.reset(); - this.toHide = this.errorsFor(element); - }, - - elementValue: function( element ) { - var type = $(element).attr("type"), - val = $(element).val(); - - if ( type === "radio" || type === "checkbox" ) { - return $("input[name='" + $(element).attr("name") + "']:checked").val(); - } - - if ( typeof val === "string" ) { - return val.replace(/\r/g, ""); - } - return val; - }, - - check: function( element ) { - element = this.validationTargetFor( this.clean( element ) ); - - var rules = $(element).rules(); - var dependencyMismatch = false; - var val = this.elementValue(element); - var result; - - for (var method in rules ) { - var rule = { method: method, parameters: rules[method] }; - try { - - result = $.validator.methods[method].call( this, val, element, rule.parameters ); - - // if a method indicates that the field is optional and therefore valid, - // don't mark it as valid when there are no other rules - if ( result === "dependency-mismatch" ) { - dependencyMismatch = true; - continue; - } - dependencyMismatch = false; - - if ( result === "pending" ) { - this.toHide = this.toHide.not( this.errorsFor(element) ); - return; - } - - if ( !result ) { - this.formatAndAdd( element, rule ); - return false; - } - } catch(e) { - if ( this.settings.debug && window.console ) { - console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); - } - throw e; - } - } - if ( dependencyMismatch ) { - return; - } - if ( this.objectLength(rules) ) { - this.successList.push(element); - } - return true; - }, - - // return the custom message for the given element and validation method - // specified in the element's HTML5 data attribute - customDataMessage: function( element, method ) { - return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase())); - }, - - // return the custom message for the given element name and validation method - customMessage: function( name, method ) { - var m = this.settings.messages[name]; - return m && (m.constructor === String ? m : m[method]); - }, - - // return the first defined argument, allowing empty strings - findDefined: function() { - for(var i = 0; i < arguments.length; i++) { - if ( arguments[i] !== undefined ) { - return arguments[i]; - } - } - return undefined; - }, - - defaultMessage: function( element, method ) { - return this.findDefined( - this.customMessage( element.name, method ), - this.customDataMessage( element, method ), - // title is never undefined, so handle empty string as undefined - !this.settings.ignoreTitle && element.title || undefined, - $.validator.messages[method], - "Warning: No message defined for " + element.name + "" - ); - }, - - formatAndAdd: function( element, rule ) { - var message = this.defaultMessage( element, rule.method ), - theregex = /\$?\{(\d+)\}/g; - if ( typeof message === "function" ) { - message = message.call(this, rule.parameters, element); - } else if (theregex.test(message)) { - message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); - } - this.errorList.push({ - message: message, - element: element - }); - - this.errorMap[element.name] = message; - this.submitted[element.name] = message; - }, - - addWrapper: function( toToggle ) { - if ( this.settings.wrapper ) { - toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); - } - return toToggle; - }, - - defaultShowErrors: function() { - var i, elements; - for ( i = 0; this.errorList[i]; i++ ) { - var error = this.errorList[i]; - if ( this.settings.highlight ) { - this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); - } - this.showLabel( error.element, error.message ); - } - if ( this.errorList.length ) { - this.toShow = this.toShow.add( this.containers ); - } - if ( this.settings.success ) { - for ( i = 0; this.successList[i]; i++ ) { - this.showLabel( this.successList[i] ); - } - } - if ( this.settings.unhighlight ) { - for ( i = 0, elements = this.validElements(); elements[i]; i++ ) { - this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass ); - } - } - this.toHide = this.toHide.not( this.toShow ); - this.hideErrors(); - this.addWrapper( this.toShow ).show(); - }, - - validElements: function() { - return this.currentElements.not(this.invalidElements()); - }, - - invalidElements: function() { - return $(this.errorList).map(function() { - return this.element; - }); - }, - - showLabel: function( element, message ) { - var label = this.errorsFor( element ); - if ( label.length ) { - // refresh error/success class - label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); - // replace message on existing label - label.html(message); - } else { - // create label - label = $("<" + this.settings.errorElement + ">") - .attr("for", this.idOrName(element)) - .addClass(this.settings.errorClass) - .html(message || ""); - if ( this.settings.wrapper ) { - // make sure the element is visible, even in IE - // actually showing the wrapped element is handled elsewhere - label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); - } - if ( !this.labelContainer.append(label).length ) { - if ( this.settings.errorPlacement ) { - this.settings.errorPlacement(label, $(element) ); - } else { - label.insertAfter(element); - } - } - } - if ( !message && this.settings.success ) { - label.text(""); - if ( typeof this.settings.success === "string" ) { - label.addClass( this.settings.success ); - } else { - this.settings.success( label, element ); - } - } - this.toShow = this.toShow.add(label); - }, - - errorsFor: function( element ) { - var name = this.idOrName(element); - return this.errors().filter(function() { - return $(this).attr("for") === name; - }); - }, - - idOrName: function( element ) { - return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); - }, - - validationTargetFor: function( element ) { - // if radio/checkbox, validate first element in group instead - if ( this.checkable(element) ) { - element = this.findByName( element.name ).not(this.settings.ignore)[0]; - } - return element; - }, - - checkable: function( element ) { - return (/radio|checkbox/i).test(element.type); - }, - - findByName: function( name ) { - return $(this.currentForm).find("[name='" + name + "']"); - }, - - getLength: function( value, element ) { - switch( element.nodeName.toLowerCase() ) { - case "select": - return $("option:selected", element).length; - case "input": - if ( this.checkable( element) ) { - return this.findByName(element.name).filter(":checked").length; - } - } - return value.length; - }, - - depend: function( param, element ) { - return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; - }, - - dependTypes: { - "boolean": function( param, element ) { - return param; - }, - "string": function( param, element ) { - return !!$(param, element.form).length; - }, - "function": function( param, element ) { - return param(element); - } - }, - - optional: function( element ) { - var val = this.elementValue(element); - return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; - }, - - startRequest: function( element ) { - if ( !this.pending[element.name] ) { - this.pendingRequest++; - this.pending[element.name] = true; - } - }, - - stopRequest: function( element, valid ) { - this.pendingRequest--; - // sometimes synchronization fails, make sure pendingRequest is never < 0 - if ( this.pendingRequest < 0 ) { - this.pendingRequest = 0; - } - delete this.pending[element.name]; - if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { - $(this.currentForm).submit(); - this.formSubmitted = false; - } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { - $(this.currentForm).triggerHandler("invalid-form", [this]); - this.formSubmitted = false; - } - }, - - previousValue: function( element ) { - return $.data(element, "previousValue") || $.data(element, "previousValue", { - old: null, - valid: true, - message: this.defaultMessage( element, "remote" ) - }); - } - - }, - - classRuleSettings: { - required: {required: true}, - email: {email: true}, - url: {url: true}, - date: {date: true}, - dateISO: {dateISO: true}, - number: {number: true}, - digits: {digits: true}, - creditcard: {creditcard: true} - }, - - addClassRules: function( className, rules ) { - if ( className.constructor === String ) { - this.classRuleSettings[className] = rules; - } else { - $.extend(this.classRuleSettings, className); - } - }, - - classRules: function( element ) { - var rules = {}; - var classes = $(element).attr("class"); - if ( classes ) { - $.each(classes.split(" "), function() { - if ( this in $.validator.classRuleSettings ) { - $.extend(rules, $.validator.classRuleSettings[this]); - } - }); - } - return rules; - }, - - attributeRules: function( element ) { - var rules = {}; - var $element = $(element); - var type = $element[0].getAttribute("type"); - - for (var method in $.validator.methods) { - var value; - - // support for in both html5 and older browsers - if ( method === "required" ) { - value = $element.get(0).getAttribute(method); - // Some browsers return an empty string for the required attribute - // and non-HTML5 browsers might have required="" markup - if ( value === "" ) { - value = true; - } - // force non-HTML5 browsers to return bool - value = !!value; - } else { - value = $element.attr(method); - } - - // convert the value to a number for number inputs, and for text for backwards compability - // allows type="date" and others to be compared as strings - if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { - value = Number(value); - } - - if ( value ) { - rules[method] = value; - } else if ( type === method && type !== 'range' ) { - // exception: the jquery validate 'range' method - // does not test for the html5 'range' type - rules[method] = true; - } - } - - // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs - if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) { - delete rules.maxlength; - } - - return rules; - }, - - dataRules: function( element ) { - var method, value, - rules = {}, $element = $(element); - for (method in $.validator.methods) { - value = $element.data("rule-" + method.toLowerCase()); - if ( value !== undefined ) { - rules[method] = value; - } - } - return rules; - }, - - staticRules: function( element ) { - var rules = {}; - var validator = $.data(element.form, "validator"); - if ( validator.settings.rules ) { - rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; - } - return rules; - }, - - normalizeRules: function( rules, element ) { - // handle dependency check - $.each(rules, function( prop, val ) { - // ignore rule when param is explicitly false, eg. required:false - if ( val === false ) { - delete rules[prop]; - return; - } - if ( val.param || val.depends ) { - var keepRule = true; - switch (typeof val.depends) { - case "string": - keepRule = !!$(val.depends, element.form).length; - break; - case "function": - keepRule = val.depends.call(element, element); - break; - } - if ( keepRule ) { - rules[prop] = val.param !== undefined ? val.param : true; - } else { - delete rules[prop]; - } - } - }); - - // evaluate parameters - $.each(rules, function( rule, parameter ) { - rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; - }); - - // clean number parameters - $.each(['minlength', 'maxlength'], function() { - if ( rules[this] ) { - rules[this] = Number(rules[this]); - } - }); - $.each(['rangelength', 'range'], function() { - var parts; - if ( rules[this] ) { - if ( $.isArray(rules[this]) ) { - rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; - } else if ( typeof rules[this] === "string" ) { - parts = rules[this].split(/[\s,]+/); - rules[this] = [Number(parts[0]), Number(parts[1])]; - } - } - }); - - if ( $.validator.autoCreateRanges ) { - // auto-create ranges - if ( rules.min && rules.max ) { - rules.range = [rules.min, rules.max]; - delete rules.min; - delete rules.max; - } - if ( rules.minlength && rules.maxlength ) { - rules.rangelength = [rules.minlength, rules.maxlength]; - delete rules.minlength; - delete rules.maxlength; - } - } - - return rules; - }, - - // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} - normalizeRule: function( data ) { - if ( typeof data === "string" ) { - var transformed = {}; - $.each(data.split(/\s/), function() { - transformed[this] = true; - }); - data = transformed; - } - return data; - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/addMethod - addMethod: function( name, method, message ) { - $.validator.methods[name] = method; - $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; - if ( method.length < 3 ) { - $.validator.addClassRules(name, $.validator.normalizeRule(name)); - } - }, - - methods: { - - // http://docs.jquery.com/Plugins/Validation/Methods/required - required: function( value, element, param ) { - // check if dependency is met - if ( !this.depend(param, element) ) { - return "dependency-mismatch"; - } - if ( element.nodeName.toLowerCase() === "select" ) { - // could be an array for select-multiple or a string, both are fine this way - var val = $(element).val(); - return val && val.length > 0; - } - if ( this.checkable(element) ) { - return this.getLength(value, element) > 0; - } - return $.trim(value).length > 0; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/email - email: function( value, element ) { - // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ - return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/url - url: function( value, element ) { - // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ - return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/date - date: function( value, element ) { - return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/dateISO - dateISO: function( value, element ) { - return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/number - number: function( value, element ) { - return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/digits - digits: function( value, element ) { - return this.optional(element) || /^\d+$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/creditcard - // based on http://en.wikipedia.org/wiki/Luhn - creditcard: function( value, element ) { - if ( this.optional(element) ) { - return "dependency-mismatch"; - } - // accept only spaces, digits and dashes - if ( /[^0-9 \-]+/.test(value) ) { - return false; - } - var nCheck = 0, - nDigit = 0, - bEven = false; - - value = value.replace(/\D/g, ""); - - for (var n = value.length - 1; n >= 0; n--) { - var cDigit = value.charAt(n); - nDigit = parseInt(cDigit, 10); - if ( bEven ) { - if ( (nDigit *= 2) > 9 ) { - nDigit -= 9; - } - } - nCheck += nDigit; - bEven = !bEven; - } - - return (nCheck % 10) === 0; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/minlength - minlength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); - return this.optional(element) || length >= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/maxlength - maxlength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); - return this.optional(element) || length <= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/rangelength - rangelength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); - return this.optional(element) || ( length >= param[0] && length <= param[1] ); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/min - min: function( value, element, param ) { - return this.optional(element) || value >= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/max - max: function( value, element, param ) { - return this.optional(element) || value <= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/range - range: function( value, element, param ) { - return this.optional(element) || ( value >= param[0] && value <= param[1] ); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/equalTo - equalTo: function( value, element, param ) { - // bind to the blur event of the target in order to revalidate whenever the target field is updated - // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead - var target = $(param); - if ( this.settings.onfocusout ) { - target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { - $(element).valid(); - }); - } - return value === target.val(); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/remote - remote: function( value, element, param ) { - if ( this.optional(element) ) { - return "dependency-mismatch"; - } - - var previous = this.previousValue(element); - if (!this.settings.messages[element.name] ) { - this.settings.messages[element.name] = {}; - } - previous.originalMessage = this.settings.messages[element.name].remote; - this.settings.messages[element.name].remote = previous.message; - - param = typeof param === "string" && {url:param} || param; - - if ( previous.old === value ) { - return previous.valid; - } - - previous.old = value; - var validator = this; - this.startRequest(element); - var data = {}; - data[element.name] = value; - $.ajax($.extend(true, { - url: param, - mode: "abort", - port: "validate" + element.name, - dataType: "json", - data: data, - success: function( response ) { - validator.settings.messages[element.name].remote = previous.originalMessage; - var valid = response === true || response === "true"; - if ( valid ) { - var submitted = validator.formSubmitted; - validator.prepareElement(element); - validator.formSubmitted = submitted; - validator.successList.push(element); - delete validator.invalid[element.name]; - validator.showErrors(); - } else { - var errors = {}; - var message = response || validator.defaultMessage( element, "remote" ); - errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; - validator.invalid[element.name] = true; - validator.showErrors(errors); - } - previous.valid = valid; - validator.stopRequest(element, valid); - } - }, param)); - return "pending"; - } - - } - -}); - -// deprecated, use $.validator.format instead -$.format = $.validator.format; - -}(jQuery)); - -// ajax mode: abort -// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); -// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() -(function($) { - var pendingRequests = {}; - // Use a prefilter if available (1.5+) - if ( $.ajaxPrefilter ) { - $.ajaxPrefilter(function( settings, _, xhr ) { - var port = settings.port; - if ( settings.mode === "abort" ) { - if ( pendingRequests[port] ) { - pendingRequests[port].abort(); - } - pendingRequests[port] = xhr; - } - }); - } else { - // Proxy ajax - var ajax = $.ajax; - $.ajax = function( settings ) { - var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, - port = ( "port" in settings ? settings : $.ajaxSettings ).port; - if ( mode === "abort" ) { - if ( pendingRequests[port] ) { - pendingRequests[port].abort(); - } - pendingRequests[port] = ajax.apply(this, arguments); - return pendingRequests[port]; - } - return ajax.apply(this, arguments); - }; - } -}(jQuery)); - -// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation -// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target -(function($) { - $.extend($.fn, { - validateDelegate: function( delegate, type, handler ) { - return this.bind(type, function( event ) { - var target = $(event.target); - if ( target.is(delegate) ) { - return handler.apply(target, arguments); - } - }); - } - }); -}(jQuery)); diff --git a/js/lib/jquery/plugins/validate/jquery.validate.min.js b/js/lib/jquery/plugins/validate/jquery.validate.min.js deleted file mode 100644 index cbaf5109a43..00000000000 --- a/js/lib/jquery/plugins/validate/jquery.validate.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery Validation Plugin - v1.11.1 - 3/22/2013\n* https://github.com/jzaefferer/jquery-validation -* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */(function(t){t.extend(t.fn,{validate:function(e){if(!this.length)return e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."),void 0;var i=t.data(this[0],"validator");return i?i:(this.attr("novalidate","novalidate"),i=new t.validator(e,this[0]),t.data(this[0],"validator",i),i.settings.onsubmit&&(this.validateDelegate(":submit","click",function(e){i.settings.submitHandler&&(i.submitButton=e.target),t(e.target).hasClass("cancel")&&(i.cancelSubmit=!0),void 0!==t(e.target).attr("formnovalidate")&&(i.cancelSubmit=!0)}),this.submit(function(e){function s(){var s;return i.settings.submitHandler?(i.submitButton&&(s=t("").attr("name",i.submitButton.name).val(t(i.submitButton).val()).appendTo(i.currentForm)),i.settings.submitHandler.call(i,i.currentForm,e),i.submitButton&&s.remove(),!1):!0}return i.settings.debug&&e.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,s()):i.form()?i.pendingRequest?(i.formSubmitted=!0,!1):s():(i.focusInvalid(),!1)})),i)},valid:function(){if(t(this[0]).is("form"))return this.validate().form();var e=!0,i=t(this[0].form).validate();return this.each(function(){e=e&&i.element(this)}),e},removeAttrs:function(e){var i={},s=this;return t.each(e.split(/\s/),function(t,e){i[e]=s.attr(e),s.removeAttr(e)}),i},rules:function(e,i){var s=this[0];if(e){var r=t.data(s.form,"validator").settings,n=r.rules,a=t.validator.staticRules(s);switch(e){case"add":t.extend(a,t.validator.normalizeRule(i)),delete a.messages,n[s.name]=a,i.messages&&(r.messages[s.name]=t.extend(r.messages[s.name],i.messages));break;case"remove":if(!i)return delete n[s.name],a;var u={};return t.each(i.split(/\s/),function(t,e){u[e]=a[e],delete a[e]}),u}}var o=t.validator.normalizeRules(t.extend({},t.validator.classRules(s),t.validator.attributeRules(s),t.validator.dataRules(s),t.validator.staticRules(s)),s);if(o.required){var l=o.required;delete o.required,o=t.extend({required:l},o)}return o}}),t.extend(t.expr[":"],{blank:function(e){return!t.trim(""+t(e).val())},filled:function(e){return!!t.trim(""+t(e).val())},unchecked:function(e){return!t(e).prop("checked")}}),t.validator=function(e,i){this.settings=t.extend(!0,{},t.validator.defaults,e),this.currentForm=i,this.init()},t.validator.format=function(e,i){return 1===arguments.length?function(){var i=t.makeArray(arguments);return i.unshift(e),t.validator.format.apply(this,i)}:(arguments.length>2&&i.constructor!==Array&&(i=t.makeArray(arguments).slice(1)),i.constructor!==Array&&(i=[i]),t.each(i,function(t,i){e=e.replace(RegExp("\\{"+t+"\\}","g"),function(){return i})}),e)},t.extend(t.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:t([]),errorLabelContainer:t([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(t){this.lastActive=t,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,t,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(t)).hide())},onfocusout:function(t){this.checkable(t)||!(t.name in this.submitted)&&this.optional(t)||this.element(t)},onkeyup:function(t,e){(9!==e.which||""!==this.elementValue(t))&&(t.name in this.submitted||t===this.lastElement)&&this.element(t)},onclick:function(t){t.name in this.submitted?this.element(t):t.parentNode.name in this.submitted&&this.element(t.parentNode)},highlight:function(e,i,s){"radio"===e.type?this.findByName(e.name).addClass(i).removeClass(s):t(e).addClass(i).removeClass(s)},unhighlight:function(e,i,s){"radio"===e.type?this.findByName(e.name).removeClass(i).addClass(s):t(e).removeClass(i).addClass(s)}},setDefaults:function(e){t.extend(t.validator.defaults,e)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:t.validator.format("Please enter no more than {0} characters."),minlength:t.validator.format("Please enter at least {0} characters."),rangelength:t.validator.format("Please enter a value between {0} and {1} characters long."),range:t.validator.format("Please enter a value between {0} and {1}."),max:t.validator.format("Please enter a value less than or equal to {0}."),min:t.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function e(e){var i=t.data(this[0].form,"validator"),s="on"+e.type.replace(/^validate/,"");i.settings[s]&&i.settings[s].call(i,this[0],e)}this.labelContainer=t(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||t(this.currentForm),this.containers=t(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var i=this.groups={};t.each(this.settings.groups,function(e,s){"string"==typeof s&&(s=s.split(/\s/)),t.each(s,function(t,s){i[s]=e})});var s=this.settings.rules;t.each(s,function(e,i){s[e]=t.validator.normalizeRule(i)}),t(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",e).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",e),this.settings.invalidHandler&&t(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),t.extend(this.submitted,this.errorMap),this.invalid=t.extend({},this.errorMap),this.valid()||t(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var t=0,e=this.currentElements=this.elements();e[t];t++)this.check(e[t]);return this.valid()},element:function(e){e=this.validationTargetFor(this.clean(e)),this.lastElement=e,this.prepareElement(e),this.currentElements=t(e);var i=this.check(e)!==!1;return i?delete this.invalid[e.name]:this.invalid[e.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),i},showErrors:function(e){if(e){t.extend(this.errorMap,e),this.errorList=[];for(var i in e)this.errorList.push({message:e[i],element:this.findByName(i)[0]});this.successList=t.grep(this.successList,function(t){return!(t.name in e)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){t.fn.resetForm&&t(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(t){var e=0;for(var i in t)e++;return e},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{t(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(e){}},findLastActive:function(){var e=this.lastActive;return e&&1===t.grep(this.errorList,function(t){return t.element.name===e.name}).length&&e},elements:function(){var e=this,i={};return t(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&e.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in i||!e.objectLength(t(this).rules())?!1:(i[this.name]=!0,!0)})},clean:function(e){return t(e)[0]},errors:function(){var e=this.settings.errorClass.replace(" ",".");return t(this.settings.errorElement+"."+e,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=t([]),this.toHide=t([]),this.currentElements=t([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(t){this.reset(),this.toHide=this.errorsFor(t)},elementValue:function(e){var i=t(e).attr("type"),s=t(e).val();return"radio"===i||"checkbox"===i?t("input[name='"+t(e).attr("name")+"']:checked").val():"string"==typeof s?s.replace(/\r/g,""):s},check:function(e){e=this.validationTargetFor(this.clean(e));var i,s=t(e).rules(),r=!1,n=this.elementValue(e);for(var a in s){var u={method:a,parameters:s[a]};try{if(i=t.validator.methods[a].call(this,n,e,u.parameters),"dependency-mismatch"===i){r=!0;continue}if(r=!1,"pending"===i)return this.toHide=this.toHide.not(this.errorsFor(e)),void 0;if(!i)return this.formatAndAdd(e,u),!1}catch(o){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+e.id+", check the '"+u.method+"' method.",o),o}}return r?void 0:(this.objectLength(s)&&this.successList.push(e),!0)},customDataMessage:function(e,i){return t(e).data("msg-"+i.toLowerCase())||e.attributes&&t(e).attr("data-msg-"+i.toLowerCase())},customMessage:function(t,e){var i=this.settings.messages[t];return i&&(i.constructor===String?i:i[e])},findDefined:function(){for(var t=0;arguments.length>t;t++)if(void 0!==arguments[t])return arguments[t];return void 0},defaultMessage:function(e,i){return this.findDefined(this.customMessage(e.name,i),this.customDataMessage(e,i),!this.settings.ignoreTitle&&e.title||void 0,t.validator.messages[i],"Warning: No message defined for "+e.name+"")},formatAndAdd:function(e,i){var s=this.defaultMessage(e,i.method),r=/\$?\{(\d+)\}/g;"function"==typeof s?s=s.call(this,i.parameters,e):r.test(s)&&(s=t.validator.format(s.replace(r,"{$1}"),i.parameters)),this.errorList.push({message:s,element:e}),this.errorMap[e.name]=s,this.submitted[e.name]=s},addWrapper:function(t){return this.settings.wrapper&&(t=t.add(t.parent(this.settings.wrapper))),t},defaultShowErrors:function(){var t,e;for(t=0;this.errorList[t];t++){var i=this.errorList[t];this.settings.highlight&&this.settings.highlight.call(this,i.element,this.settings.errorClass,this.settings.validClass),this.showLabel(i.element,i.message)}if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(t=0;this.successList[t];t++)this.showLabel(this.successList[t]);if(this.settings.unhighlight)for(t=0,e=this.validElements();e[t];t++)this.settings.unhighlight.call(this,e[t],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return t(this.errorList).map(function(){return this.element})},showLabel:function(e,i){var s=this.errorsFor(e);s.length?(s.removeClass(this.settings.validClass).addClass(this.settings.errorClass),s.html(i)):(s=t("<"+this.settings.errorElement+">").attr("for",this.idOrName(e)).addClass(this.settings.errorClass).html(i||""),this.settings.wrapper&&(s=s.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.append(s).length||(this.settings.errorPlacement?this.settings.errorPlacement(s,t(e)):s.insertAfter(e))),!i&&this.settings.success&&(s.text(""),"string"==typeof this.settings.success?s.addClass(this.settings.success):this.settings.success(s,e)),this.toShow=this.toShow.add(s)},errorsFor:function(e){var i=this.idOrName(e);return this.errors().filter(function(){return t(this).attr("for")===i})},idOrName:function(t){return this.groups[t.name]||(this.checkable(t)?t.name:t.id||t.name)},validationTargetFor:function(t){return this.checkable(t)&&(t=this.findByName(t.name).not(this.settings.ignore)[0]),t},checkable:function(t){return/radio|checkbox/i.test(t.type)},findByName:function(e){return t(this.currentForm).find("[name='"+e+"']")},getLength:function(e,i){switch(i.nodeName.toLowerCase()){case"select":return t("option:selected",i).length;case"input":if(this.checkable(i))return this.findByName(i.name).filter(":checked").length}return e.length},depend:function(t,e){return this.dependTypes[typeof t]?this.dependTypes[typeof t](t,e):!0},dependTypes:{"boolean":function(t){return t},string:function(e,i){return!!t(e,i.form).length},"function":function(t,e){return t(e)}},optional:function(e){var i=this.elementValue(e);return!t.validator.methods.required.call(this,i,e)&&"dependency-mismatch"},startRequest:function(t){this.pending[t.name]||(this.pendingRequest++,this.pending[t.name]=!0)},stopRequest:function(e,i){this.pendingRequest--,0>this.pendingRequest&&(this.pendingRequest=0),delete this.pending[e.name],i&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(t(this.currentForm).submit(),this.formSubmitted=!1):!i&&0===this.pendingRequest&&this.formSubmitted&&(t(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e){return t.data(e,"previousValue")||t.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(e,i){e.constructor===String?this.classRuleSettings[e]=i:t.extend(this.classRuleSettings,e)},classRules:function(e){var i={},s=t(e).attr("class");return s&&t.each(s.split(" "),function(){this in t.validator.classRuleSettings&&t.extend(i,t.validator.classRuleSettings[this])}),i},attributeRules:function(e){var i={},s=t(e),r=s[0].getAttribute("type");for(var n in t.validator.methods){var a;"required"===n?(a=s.get(0).getAttribute(n),""===a&&(a=!0),a=!!a):a=s.attr(n),/min|max/.test(n)&&(null===r||/number|range|text/.test(r))&&(a=Number(a)),a?i[n]=a:r===n&&"range"!==r&&(i[n]=!0)}return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var i,s,r={},n=t(e);for(i in t.validator.methods)s=n.data("rule-"+i.toLowerCase()),void 0!==s&&(r[i]=s);return r},staticRules:function(e){var i={},s=t.data(e.form,"validator");return s.settings.rules&&(i=t.validator.normalizeRule(s.settings.rules[e.name])||{}),i},normalizeRules:function(e,i){return t.each(e,function(s,r){if(r===!1)return delete e[s],void 0;if(r.param||r.depends){var n=!0;switch(typeof r.depends){case"string":n=!!t(r.depends,i.form).length;break;case"function":n=r.depends.call(i,i)}n?e[s]=void 0!==r.param?r.param:!0:delete e[s]}}),t.each(e,function(s,r){e[s]=t.isFunction(r)?r(i):r}),t.each(["minlength","maxlength"],function(){e[this]&&(e[this]=Number(e[this]))}),t.each(["rangelength","range"],function(){var i;e[this]&&(t.isArray(e[this])?e[this]=[Number(e[this][0]),Number(e[this][1])]:"string"==typeof e[this]&&(i=e[this].split(/[\s,]+/),e[this]=[Number(i[0]),Number(i[1])]))}),t.validator.autoCreateRanges&&(e.min&&e.max&&(e.range=[e.min,e.max],delete e.min,delete e.max),e.minlength&&e.maxlength&&(e.rangelength=[e.minlength,e.maxlength],delete e.minlength,delete e.maxlength)),e},normalizeRule:function(e){if("string"==typeof e){var i={};t.each(e.split(/\s/),function(){i[this]=!0}),e=i}return e},addMethod:function(e,i,s){t.validator.methods[e]=i,t.validator.messages[e]=void 0!==s?s:t.validator.messages[e],3>i.length&&t.validator.addClassRules(e,t.validator.normalizeRule(e))},methods:{required:function(e,i,s){if(!this.depend(s,i))return"dependency-mismatch";if("select"===i.nodeName.toLowerCase()){var r=t(i).val();return r&&r.length>0}return this.checkable(i)?this.getLength(e,i)>0:t.trim(e).length>0},email:function(t,e){return this.optional(e)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(t)},url:function(t,e){return this.optional(e)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(t)},date:function(t,e){return this.optional(e)||!/Invalid|NaN/.test(""+new Date(t))},dateISO:function(t,e){return this.optional(e)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(t)},number:function(t,e){return this.optional(e)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(t)},digits:function(t,e){return this.optional(e)||/^\d+$/.test(t)},creditcard:function(t,e){if(this.optional(e))return"dependency-mismatch";if(/[^0-9 \-]+/.test(t))return!1;var i=0,s=0,r=!1;t=t.replace(/\D/g,"");for(var n=t.length-1;n>=0;n--){var a=t.charAt(n);s=parseInt(a,10),r&&(s*=2)>9&&(s-=9),i+=s,r=!r}return 0===i%10},minlength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||r>=s},maxlength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||s>=r},rangelength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||r>=s[0]&&s[1]>=r},min:function(t,e,i){return this.optional(e)||t>=i},max:function(t,e,i){return this.optional(e)||i>=t},range:function(t,e,i){return this.optional(e)||t>=i[0]&&i[1]>=t},equalTo:function(e,i,s){var r=t(s);return this.settings.onfocusout&&r.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){t(i).valid()}),e===r.val()},remote:function(e,i,s){if(this.optional(i))return"dependency-mismatch";var r=this.previousValue(i);if(this.settings.messages[i.name]||(this.settings.messages[i.name]={}),r.originalMessage=this.settings.messages[i.name].remote,this.settings.messages[i.name].remote=r.message,s="string"==typeof s&&{url:s}||s,r.old===e)return r.valid;r.old=e;var n=this;this.startRequest(i);var a={};return a[i.name]=e,t.ajax(t.extend(!0,{url:s,mode:"abort",port:"validate"+i.name,dataType:"json",data:a,success:function(s){n.settings.messages[i.name].remote=r.originalMessage;var a=s===!0||"true"===s;if(a){var u=n.formSubmitted;n.prepareElement(i),n.formSubmitted=u,n.successList.push(i),delete n.invalid[i.name],n.showErrors()}else{var o={},l=s||n.defaultMessage(i,"remote");o[i.name]=r.message=t.isFunction(l)?l(e):l,n.invalid[i.name]=!0,n.showErrors(o)}r.valid=a,n.stopRequest(i,a)}},s)),"pending"}}}),t.format=t.validator.format})(jQuery),function(t){var e={};if(t.ajaxPrefilter)t.ajaxPrefilter(function(t,i,s){var r=t.port;"abort"===t.mode&&(e[r]&&e[r].abort(),e[r]=s)});else{var i=t.ajax;t.ajax=function(s){var r=("mode"in s?s:t.ajaxSettings).mode,n=("port"in s?s:t.ajaxSettings).port;return"abort"===r?(e[n]&&e[n].abort(),e[n]=i.apply(this,arguments),e[n]):i.apply(this,arguments)}}}(jQuery),function(t){t.extend(t.fn,{validateDelegate:function(e,i,s){return this.bind(i,function(i){var r=t(i.target);return r.is(e)?s.apply(r,arguments):void 0})}})}(jQuery); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_ar.js b/js/lib/jquery/plugins/validate/localization/messages_ar.js deleted file mode 100644 index 6df9495f53e..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_ar.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: AR (Arabic; العربية) - */ -(function ($) { - $.extend($.validator.messages, { - required: "هذا الحقل إلزامي", - remote: "يرجى تصحيح هذا الحقل للمتابعة", - email: "رجاء إدخال عنوان بريد إلكتروني صحيح", - url: "رجاء إدخال عنوان موقع إلكتروني صحيح", - date: "رجاء إدخال تاريخ صحيح", - dateISO: "رجاء إدخال تاريخ صحيح (ISO)", - number: "رجاء إدخال عدد بطريقة صحيحة", - digits: "رجاء إدخال أرقام فقط", - creditcard: "رجاء إدخال رقم بطاقة ائتمان صحيح", - equalTo: "رجاء إدخال نفس القيمة", - accept: "رجاء إدخال ملف بامتداد موافق عليه", - maxlength: $.validator.format("الحد الأقصى لعدد الحروف هو {0}"), - minlength: $.validator.format("الحد الأدنى لعدد الحروف هو {0}"), - rangelength: $.validator.format("عدد الحروف يجب أن يكون بين {0} و {1}"), - range: $.validator.format("رجاء إدخال عدد قيمته بين {0} و {1}"), - max: $.validator.format("رجاء إدخال عدد أقل من أو يساوي (0}"), - min: $.validator.format("رجاء إدخال عدد أكبر من أو يساوي (0}") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_bg.js b/js/lib/jquery/plugins/validate/localization/messages_bg.js deleted file mode 100644 index 10ba1d32295..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_bg.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: BG (Bulgarian; български език) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Полето е задължително.", - remote: "Моля, въведете правилната стойност.", - email: "Моля, въведете валиден email.", - url: "Моля, въведете валидно URL.", - date: "Моля, въведете валидна дата.", - dateISO: "Моля, въведете валидна дата (ISO).", - number: "Моля, въведете валиден номер.", - digits: "Моля, въведете само цифри", - creditcard: "Моля, въведете валиден номер на кредитна карта.", - equalTo: "Моля, въведете същата стойност отново.", - accept: "Моля, въведете стойност с валидно разширение.", - maxlength: $.validator.format("Моля, въведете повече от {0} символа."), - minlength: $.validator.format("Моля, въведете поне {0} символа."), - rangelength: $.validator.format("Моля, въведете стойност с дължина между {0} и {1} символа."), - range: $.validator.format("Моля, въведете стойност между {0} и {1}."), - max: $.validator.format("Моля, въведете стойност по-малка или равна на {0}."), - min: $.validator.format("Моля, въведете стойност по-голяма или равна на {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_ca.js b/js/lib/jquery/plugins/validate/localization/messages_ca.js deleted file mode 100644 index 940c37f5475..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_ca.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: CA (Catalan; català) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Aquest camp és obligatori.", - remote: "Si us plau, omple aquest camp.", - email: "Si us plau, escriu una adreça de correu-e vàlida", - url: "Si us plau, escriu una URL vàlida.", - date: "Si us plau, escriu una data vàlida.", - dateISO: "Si us plau, escriu una data (ISO) vàlida.", - number: "Si us plau, escriu un número enter vàlid.", - digits: "Si us plau, escriu només dígits.", - creditcard: "Si us plau, escriu un número de tarjeta vàlid.", - equalTo: "Si us plau, escriu el maateix valor de nou.", - accept: "Si us plau, escriu un valor amb una extensió acceptada.", - maxlength: $.validator.format("Si us plau, no escriguis més de {0} caracters."), - minlength: $.validator.format("Si us plau, no escriguis menys de {0} caracters."), - rangelength: $.validator.format("Si us plau, escriu un valor entre {0} i {1} caracters."), - range: $.validator.format("Si us plau, escriu un valor entre {0} i {1}."), - max: $.validator.format("Si us plau, escriu un valor menor o igual a {0}."), - min: $.validator.format("Si us plau, escriu un valor major o igual a {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_cs.js b/js/lib/jquery/plugins/validate/localization/messages_cs.js deleted file mode 100644 index 43cc3ad1b04..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_cs.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: CS (Czech; čeština, český jazyk) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Tento údaj je povinný.", - remote: "Prosím, opravte tento údaj.", - email: "Prosím, zadejte platný e-mail.", - url: "Prosím, zadejte platné URL.", - date: "Prosím, zadejte platné datum.", - dateISO: "Prosím, zadejte platné datum (ISO).", - number: "Prosím, zadejte číslo.", - digits: "Prosím, zadávejte pouze číslice.", - creditcard: "Prosím, zadejte číslo kreditní karty.", - equalTo: "Prosím, zadejte znovu stejnou hodnotu.", - accept: "Prosím, zadejte soubor se správnou příponou.", - maxlength: $.validator.format("Prosím, zadejte nejvíce {0} znaků."), - minlength: $.validator.format("Prosím, zadejte nejméně {0} znaků."), - rangelength: $.validator.format("Prosím, zadejte od {0} do {1} znaků."), - range: $.validator.format("Prosím, zadejte hodnotu od {0} do {1}."), - max: $.validator.format("Prosím, zadejte hodnotu menší nebo rovnu {0}."), - min: $.validator.format("Prosím, zadejte hodnotu větší nebo rovnu {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_da.js b/js/lib/jquery/plugins/validate/localization/messages_da.js deleted file mode 100644 index bcceb202e19..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_da.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: DA (Danish; dansk) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Dette felt er påkrævet.", - maxlength: $.validator.format("Indtast højst {0} tegn."), - minlength: $.validator.format("Indtast mindst {0} tegn."), - rangelength: $.validator.format("Indtast mindst {0} og højst {1} tegn."), - email: "Indtast en gyldig email-adresse.", - url: "Indtast en gyldig URL.", - date: "Indtast en gyldig dato.", - number: "Indtast et tal.", - digits: "Indtast kun cifre.", - equalTo: "Indtast den samme værdi igen.", - range: $.validator.format("Angiv en værdi mellem {0} og {1}."), - max: $.validator.format("Angiv en værdi der højst er {0}."), - min: $.validator.format("Angiv en værdi der mindst er {0}."), - creditcard: "Indtast et gyldigt kreditkortnummer." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_de.js b/js/lib/jquery/plugins/validate/localization/messages_de.js deleted file mode 100644 index 073853e97b3..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_de.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: DE (German, Deutsch) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Dieses Feld ist ein Pflichtfeld.", - maxlength: $.validator.format("Geben Sie bitte maximal {0} Zeichen ein."), - minlength: $.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."), - rangelength: $.validator.format("Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein."), - email: "Geben Sie bitte eine gültige E-Mail Adresse ein.", - url: "Geben Sie bitte eine gültige URL ein.", - date: "Bitte geben Sie ein gültiges Datum ein.", - number: "Geben Sie bitte eine Nummer ein.", - digits: "Geben Sie bitte nur Ziffern ein.", - equalTo: "Bitte denselben Wert wiederholen.", - range: $.validator.format("Geben Sie bitte einen Wert zwischen {0} und {1} ein."), - max: $.validator.format("Geben Sie bitte einen Wert kleiner oder gleich {0} ein."), - min: $.validator.format("Geben Sie bitte einen Wert größer oder gleich {0} ein."), - creditcard: "Geben Sie bitte eine gültige Kreditkarten-Nummer ein." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_el.js b/js/lib/jquery/plugins/validate/localization/messages_el.js deleted file mode 100644 index 6cd5a1de4ef..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_el.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: EL (Greek; ελληνικά) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Αυτό το πεδίο είναι υποχρεωτικό.", - remote: "Παρακαλώ διορθώστε αυτό το πεδίο.", - email: "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email.", - url: "Παρακαλώ εισάγετε ένα έγκυρο URL.", - date: "Παρακαλώ εισάγετε μια έγκυρη ημερομηνία.", - dateISO: "Παρακαλώ εισάγετε μια έγκυρη ημερομηνία (ISO).", - number: "Παρακαλώ εισάγετε έναν έγκυρο αριθμό.", - digits: "Παρακαλώ εισάγετε μόνο αριθμητικά ψηφία.", - creditcard: "Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας.", - equalTo: "Παρακαλώ εισάγετε την ίδια τιμή ξανά.", - accept: "Παρακαλώ εισάγετε μια τιμή με έγκυρη επέκταση αρχείου.", - maxlength: $.validator.format("Παρακαλώ εισάγετε μέχρι και {0} χαρακτήρες."), - minlength: $.validator.format("Παρακαλώ εισάγετε τουλάχιστον {0} χαρακτήρες."), - rangelength: $.validator.format("Παρακαλώ εισάγετε μια τιμή με μήκος μεταξύ {0} και {1} χαρακτήρων."), - range: $.validator.format("Παρακαλώ εισάγετε μια τιμή μεταξύ {0} και {1}."), - max: $.validator.format("Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση του {0}."), - min: $.validator.format("Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση του {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_es.js b/js/lib/jquery/plugins/validate/localization/messages_es.js deleted file mode 100644 index 3a30eee8f35..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_es.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: ES (Spanish; Español) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Este campo es obligatorio.", - remote: "Por favor, rellena este campo.", - email: "Por favor, escribe una dirección de correo válida", - url: "Por favor, escribe una URL válida.", - date: "Por favor, escribe una fecha válida.", - dateISO: "Por favor, escribe una fecha (ISO) válida.", - number: "Por favor, escribe un número entero válido.", - digits: "Por favor, escribe sólo dígitos.", - creditcard: "Por favor, escribe un número de tarjeta válido.", - equalTo: "Por favor, escribe el mismo valor de nuevo.", - accept: "Por favor, escribe un valor con una extensión aceptada.", - maxlength: $.validator.format("Por favor, no escribas más de {0} caracteres."), - minlength: $.validator.format("Por favor, no escribas menos de {0} caracteres."), - rangelength: $.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."), - range: $.validator.format("Por favor, escribe un valor entre {0} y {1}."), - max: $.validator.format("Por favor, escribe un valor menor o igual a {0}."), - min: $.validator.format("Por favor, escribe un valor mayor o igual a {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_et.js b/js/lib/jquery/plugins/validate/localization/messages_et.js deleted file mode 100644 index aaa26777f57..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_et.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: ET (Estonian; eesti, eesti keel) - */ -(function ($) { - $.extend($.validator.messages, { - required: "See väli peab olema täidetud.", - maxlength: $.validator.format("Palun sisestage vähem kui {0} tähemärki."), - minlength: $.validator.format("Palun sisestage vähemalt {0} tähemärki."), - rangelength: $.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1} tähemärki."), - email: "Palun sisestage korrektne e-maili aadress.", - url: "Palun sisestage korrektne URL.", - date: "Palun sisestage korrektne kuupäev.", - dateISO: "Palun sisestage korrektne kuupäev (YYYY-MM-DD).", - number: "Palun sisestage korrektne number.", - digits: "Palun sisestage ainult numbreid.", - equalTo: "Palun sisestage sama väärtus uuesti.", - range: $.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1}."), - max: $.validator.format("Palun sisestage väärtus, mis on väiksem või võrdne arvuga {0}."), - min: $.validator.format("Palun sisestage väärtus, mis on suurem või võrdne arvuga {0}."), - creditcard: "Palun sisestage korrektne krediitkaardi number." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_eu.js b/js/lib/jquery/plugins/validate/localization/messages_eu.js deleted file mode 100644 index 8f02f1b229e..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_eu.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: EU (Basque; euskara, euskera) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Eremu hau beharrezkoa da.", - remote: "Mesedez, bete eremu hau.", - email: "Mesedez, idatzi baliozko posta helbide bat.", - url: "Mesedez, idatzi baliozko URL bat.", - date: "Mesedez, idatzi baliozko data bat.", - dateISO: "Mesedez, idatzi baliozko (ISO) data bat.", - number: "Mesedez, idatzi baliozko zenbaki oso bat.", - digits: "Mesedez, idatzi digituak soilik.", - creditcard: "Mesedez, idatzi baliozko txartel zenbaki bat.", - equalTo: "Mesedez, idatzi berdina berriro ere.", - accept: "Mesedez, idatzi onartutako luzapena duen balio bat.", - maxlength: $.validator.format("Mesedez, ez idatzi {0} karaktere baino gehiago."), - minlength: $.validator.format("Mesedez, ez idatzi {0} karaktere baino gutxiago."), - rangelength: $.validator.format("Mesedez, idatzi {0} eta {1} karaktere arteko balio bat."), - range: $.validator.format("Mesedez, idatzi {0} eta {1} arteko balio bat."), - max: $.validator.format("Mesedez, idatzi {0} edo txikiagoa den balio bat."), - min: $.validator.format("Mesedez, idatzi {0} edo handiagoa den balio bat.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_fa.js b/js/lib/jquery/plugins/validate/localization/messages_fa.js deleted file mode 100644 index 38163525cb9..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_fa.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: FA (Persian; فارسی) - */ -(function ($) { - $.extend($.validator.messages, { - required: "تکمیل این فیلد اجباری است.", - remote: "لطفا این فیلد را تصحیح کنید.", - email: ".لطفا یک ایمیل صحیح وارد کنید", - url: "لطفا آدرس صحیح وارد کنید.", - date: "لطفا یک تاریخ صحیح وارد کنید", - dateISO: "لطفا تاریخ صحیح وارد کنید (ISO).", - number: "لطفا عدد صحیح وارد کنید.", - digits: "لطفا تنها رقم وارد کنید", - creditcard: "لطفا کریدیت کارت صحیح وارد کنید.", - equalTo: "لطفا مقدار برابری وارد کنید", - accept: "لطفا مقداری وارد کنید که ", - maxlength: $.validator.format("لطفا بیشتر از {0} حرف وارد نکنید."), - minlength: $.validator.format("لطفا کمتر از {0} حرف وارد نکنید."), - rangelength: $.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."), - range: $.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."), - max: $.validator.format("لطفا مقداری کمتر از {0} حرف وارد کنید."), - min: $.validator.format("لطفا مقداری بیشتر از {0} حرف وارد کنید.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_fi.js b/js/lib/jquery/plugins/validate/localization/messages_fi.js deleted file mode 100644 index a1fc03c5b98..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_fi.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: FI (Finnish; suomi, suomen kieli) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Tämä kenttä on pakollinen.", - email: "Syötä oikea sähköpostiosoite.", - url: "Syötä oikea URL osoite.", - date: "Syötä oike päivämäärä.", - dateISO: "Syötä oike päivämäärä (VVVV-MM-DD).", - number: "Syötä numero.", - creditcard: "Syötä voimassa oleva luottokorttinumero.", - digits: "Syötä pelkästään numeroita.", - equalTo: "Syötä sama arvo uudestaan.", - maxlength: $.validator.format("Voit syöttää enintään {0} merkkiä."), - minlength: $.validator.format("Vähintään {0} merkkiä."), - rangelength: $.validator.format("Syötä vähintään {0} ja enintään {1} merkkiä."), - range: $.validator.format("Syötä arvo {0} ja {1} väliltä."), - max: $.validator.format("Syötä arvo joka on pienempi tai yhtä suuri kuin {0}."), - min: $.validator.format("Syötä arvo joka on yhtä suuri tai suurempi kuin {0}.") - }); -}(jQuery)); diff --git a/js/lib/jquery/plugins/validate/localization/messages_fr.js b/js/lib/jquery/plugins/validate/localization/messages_fr.js deleted file mode 100644 index c976ff460e6..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_fr.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: FR (French; français) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Ce champ est obligatoire.", - remote: "Veuillez corriger ce champ.", - email: "Veuillez fournir une adresse électronique valide.", - url: "Veuillez fournir une adresse URL valide.", - date: "Veuillez fournir une date valide.", - dateISO: "Veuillez fournir une date valide (ISO).", - number: "Veuillez fournir un numéro valide.", - digits: "Veuillez fournir seulement des chiffres.", - creditcard: "Veuillez fournir un numéro de carte de crédit valide.", - equalTo: "Veuillez fournir encore la même valeur.", - accept: "Veuillez fournir une valeur avec une extension valide.", - maxlength: $.validator.format("Veuillez fournir au plus {0} caractères."), - minlength: $.validator.format("Veuillez fournir au moins {0} caractères."), - rangelength: $.validator.format("Veuillez fournir une valeur qui contient entre {0} et {1} caractères."), - range: $.validator.format("Veuillez fournir une valeur entre {0} et {1}."), - max: $.validator.format("Veuillez fournir une valeur inférieur ou égal à {0}."), - min: $.validator.format("Veuillez fournir une valeur supérieur ou égal à {0}."), - maxWords: $.validator.format("Veuillez fournir au plus {0} mots."), - minWords: $.validator.format("Veuillez fournir au moins {0} mots."), - rangeWords: $.validator.format("Veuillez fournir entre {0} et {1} mots."), - letterswithbasicpunc: "Veuillez fournir seulement des lettres et des signes de ponctuation.", - alphanumeric: "Veuillez fournir seulement des lettres, nombres, espaces et soulignages", - lettersonly: "Veuillez fournir seulement des lettres.", - nowhitespace: "Veuillez ne pas inscrire d'espaces blancs.", - ziprange: "Veuillez fournir un code postal entre 902xx-xxxx et 905-xx-xxxx.", - integer: "Veuillez fournir un nombre non décimal qui est positif ou négatif.", - vinUS: "Veuillez fournir un numéro d'identification du véhicule (VIN).", - dateITA: "Veuillez fournir une date valide.", - time: "Veuillez fournir une heure valide entre 00:00 et 23:59.", - phoneUS: "Veuillez fournir un numéro de téléphone valide.", - phoneUK: "Veuillez fournir un numéro de téléphone valide.", - mobileUK: "Veuillez fournir un numéro de téléphone mobile valide.", - strippedminlength: $.validator.format("Veuillez fournir au moins {0} caractères."), - email2: "Veuillez fournir une adresse électronique valide.", - url2: "Veuillez fournir une adresse URL valide.", - creditcardtypes: "Veuillez fournir un numéro de carte de crédit valide.", - ipv4: "Veuillez fournir une adresse IP v4 valide.", - ipv6: "Veuillez fournir une adresse IP v6 valide.", - require_from_group: "Veuillez fournir au moins {0} de ces champs." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_he.js b/js/lib/jquery/plugins/validate/localization/messages_he.js deleted file mode 100644 index 373feee7fcc..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_he.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: HE (Hebrew; עברית) - */ -(function ($) { - $.extend($.validator.messages, { - required: "השדה הזה הינו שדה חובה", - remote: "נא לתקן שדה זה", - email: "נא למלא כתובת דוא\"ל חוקית", - url: "נא למלא כתובת אינטרנט חוקית", - date: "נא למלא תאריך חוקי", - dateISO: "נא למלא תאריך חוקי (ISO)", - number: "נא למלא מספר", - digits: "נא למלא רק מספרים", - creditcard: "נא למלא מספר כרטיס אשראי חוקי", - equalTo: "נא למלא את אותו ערך שוב", - accept: "נא למלא ערך עם סיומת חוקית", - maxlength: $.validator.format(".נא לא למלא יותר מ- {0} תווים"), - minlength: $.validator.format("נא למלא לפחות {0} תווים"), - rangelength: $.validator.format("נא למלא ערך בין {0} ל- {1} תווים"), - range: $.validator.format("נא למלא ערך בין {0} ל- {1}"), - max: $.validator.format("נא למלא ערך קטן או שווה ל- {0}"), - min: $.validator.format("נא למלא ערך גדול או שווה ל- {0}") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_hr.js b/js/lib/jquery/plugins/validate/localization/messages_hr.js deleted file mode 100644 index 895ae2dca97..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_hr.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: HR (Croatia; hrvatski jezik) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Ovo polje je obavezno.", - remote: "Ovo polje treba popraviti.", - email: "Unesite ispravnu e-mail adresu.", - url: "Unesite ispravan URL.", - date: "Unesite ispravan datum.", - dateISO: "Unesite ispravan datum (ISO).", - number: "Unesite ispravan broj.", - digits: "Unesite samo brojeve.", - creditcard: "Unesite ispravan broj kreditne kartice.", - equalTo: "Unesite ponovo istu vrijednost.", - accept: "Unesite vrijednost sa ispravnom ekstenzijom.", - maxlength: $.validator.format("Maksimalni broj znakova je {0} ."), - minlength: $.validator.format("Minimalni broj znakova je {0} ."), - rangelength: $.validator.format("Unesite vrijednost između {0} i {1} znakova."), - range: $.validator.format("Unesite vrijednost između {0} i {1}."), - max: $.validator.format("Unesite vrijednost manju ili jednaku {0}."), - min: $.validator.format("Unesite vrijednost veću ili jednaku {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_hu.js b/js/lib/jquery/plugins/validate/localization/messages_hu.js deleted file mode 100644 index cd73fc3eefe..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_hu.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: HU (Hungarian; Magyar) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Kötelező megadni.", - maxlength: $.validator.format("Legfeljebb {0} karakter hosszú legyen."), - minlength: $.validator.format("Legalább {0} karakter hosszú legyen."), - rangelength: $.validator.format("Legalább {0} és legfeljebb {1} karakter hosszú legyen."), - email: "Érvényes e-mail címnek kell lennie.", - url: "Érvényes URL-nek kell lennie.", - date: "Dátumnak kell lennie.", - number: "Számnak kell lennie.", - digits: "Csak számjegyek lehetnek.", - equalTo: "Meg kell egyeznie a két értéknek.", - range: $.validator.format("{0} és {1} közé kell esnie."), - max: $.validator.format("Nem lehet nagyobb, mint {0}."), - min: $.validator.format("Nem lehet kisebb, mint {0}."), - creditcard: "Érvényes hitelkártyaszámnak kell lennie.", - remote: "Kérem javítsa ki ezt a mezőt.", - dateISO: "Kérem írjon be egy érvényes dátumot (ISO)." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_it.js b/js/lib/jquery/plugins/validate/localization/messages_it.js deleted file mode 100644 index 19323b0f560..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_it.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: IT (Italian; Italiano) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Campo obbligatorio.", - remote: "Controlla questo campo.", - email: "Inserisci un indirizzo email valido.", - url: "Inserisci un indirizzo web valido.", - date: "Inserisci una data valida.", - dateISO: "Inserisci una data valida (ISO).", - number: "Inserisci un numero valido.", - digits: "Inserisci solo numeri.", - creditcard: "Inserisci un numero di carta di credito valido.", - equalTo: "Il valore non corrisponde.", - accept: "Inserisci un valore con un'estensione valida.", - maxlength: $.validator.format("Non inserire più di {0} caratteri."), - minlength: $.validator.format("Inserisci almeno {0} caratteri."), - rangelength: $.validator.format("Inserisci un valore compreso tra {0} e {1} caratteri."), - range: $.validator.format("Inserisci un valore compreso tra {0} e {1}."), - max: $.validator.format("Inserisci un valore minore o uguale a {0}."), - min: $.validator.format("Inserisci un valore maggiore o uguale a {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_ja.js b/js/lib/jquery/plugins/validate/localization/messages_ja.js deleted file mode 100644 index cb060c9c129..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_ja.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: JA (Japanese; 日本語) - */ -(function ($) { - $.extend($.validator.messages, { - required: "このフィールドは必須です。", - remote: "このフィールドを修正してください。", - email: "有効なEメールアドレスを入力してください。", - url: "有効なURLを入力してください。", - date: "有効な日付を入力してください。", - dateISO: "有効な日付(ISO)を入力してください。", - number: "有効な数字を入力してください。", - digits: "数字のみを入力してください。", - creditcard: "有効なクレジットカード番号を入力してください。", - equalTo: "同じ値をもう一度入力してください。", - accept: "有効な拡張子を含む値を入力してください。", - maxlength: $.format("{0} 文字以内で入力してください。"), - minlength: $.format("{0} 文字以上で入力してください。"), - rangelength: $.format("{0} 文字から {1} 文字までの値を入力してください。"), - range: $.format("{0} から {1} までの値を入力してください。"), - max: $.format("{0} 以下の値を入力してください。"), - min: $.format("{0} 以上の値を入力してください。") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_ka.js b/js/lib/jquery/plugins/validate/localization/messages_ka.js deleted file mode 100644 index 319363e4df3..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_ka.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: KA (Georgian; ქართული) - */ -(function ($) { - $.extend($.validator.messages, { - required: "ამ ველის შევსება აუცილებელია.", - remote: "გთხოვთ მიუთითოთ სწორი მნიშვნელობა.", - email: "გთხოვთ მიუთითოთ ელ-ფოსტის კორექტული მისამართი.", - url: "გთხოვთ მიუთითოთ კორექტული URL.", - date: "გთხოვთ მიუთითოთ კორექტული თარიღი.", - dateISO: "გთხოვთ მიუთითოთ კორექტული თარიღი ISO ფორმატში.", - number: "გთხოვთ მიუთითოთ ციფრი.", - digits: "გთხოვთ მიუთითოთ მხოლოდ ციფრები.", - creditcard: "გთხოვთ მიუთითოთ საკრედიტო ბარათის კორექტული ნომერი.", - equalTo: "გთხოვთ მიუთითოთ ასეთივე მნიშვნელობა კიდევ ერთხელ.", - accept: "გთხოვთ აირჩიოთ ფაილი კორექტული გაფართოებით.", - maxlength: $.validator.format("დასაშვებია არაუმეტეს {0} სიმბოლო."), - minlength: $.validator.format("აუცილებელია შეიყვანოთ მინიმუმ {0} სიმბოლო."), - rangelength: $.validator.format("ტექსტში სიმბოლოების რაოდენობა უნდა იყოს {0}-დან {1}-მდე."), - range: $.validator.format("გთხოვთ შეიყვანოთ ციფრი {0}-დან {1}-მდე."), - max: $.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც ნაკლებია ან უდრის {0}-ს."), - min: $.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც მეტია ან უდრის {0}-ს.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_kk.js b/js/lib/jquery/plugins/validate/localization/messages_kk.js deleted file mode 100644 index dd9276fb5c1..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_kk.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: KK (Kazakh; қазақ тілі) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Бұл өрісті міндетті түрде толтырыңыз.", - remote: "Дұрыс мағына енгізуіңізді сұраймыз.", - email: "Нақты электронды поштаңызды енгізуіңізді сұраймыз.", - url: "Нақты URL-ды енгізуіңізді сұраймыз.", - date: "Нақты URL-ды енгізуіңізді сұраймыз.", - dateISO: "Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.", - number: "Күнді енгізуіңізді сұраймыз.", - digits: "Тек қана сандарды енгізуіңізді сұраймыз.", - creditcard: "Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.", - equalTo: "Осы мәнді қайта енгізуіңізді сұраймыз.", - accept: "Файлдың кеңейтуін дұрыс таңдаңыз.", - maxlength: $.format("Ұзындығы {0} символдан көр болмасын."), - minlength: $.format("Ұзындығы {0} символдан аз болмасын."), - rangelength: $.format("Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз."), - range: $.format("Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз."), - max: $.format("{0} аз немесе тең санын енгізуіңіді сұраймыз."), - min: $.format("{0} көп немесе тең санын енгізуіңізді сұраймыз.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_ko.js b/js/lib/jquery/plugins/validate/localization/messages_ko.js deleted file mode 100644 index 1e6bba91669..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_ko.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: KO (Korean; 한국어) - */ -(function ($) { - $.extend($.validator.messages, { - required: "필수 항목입니다.", - remote: "항목을 수정하세요.", - email: "유효하지 않은 E-Mail주소입니다.", - url: "유효하지 않은 주소입니다.", - date: "옳바른 날짜를 입력하세요.", - dateISO: "옳바른 날짜(ISO)를 입력하세요.", - number: "유효한 숫자가 아닙니다.", - digits: "숫자만 입력 가능합니다.", - creditcard: "신용카드번호가 바르지 않습니다.", - equalTo: "같은값을 다시 입력하세요.", - accept: "옳바른 확장자가 아닙니다.", - maxlength: $.format("{0}자를 넘을 수 없습니다. "), - minlength: $.format("{0}자 이하로 입력하세요."), - rangelength: $.format("문자 길이를 {0} 에서 {1} 사이의로 입력하세요."), - range: $.format("{0} 에서 {1} 값을 입력하세요."), - max: $.format("{0} 이하의 값을 입력하세요."), - min: $.format("{0} 이상의 값을 입력하세요.") - }); -}(jQuery)); diff --git a/js/lib/jquery/plugins/validate/localization/messages_lt.js b/js/lib/jquery/plugins/validate/localization/messages_lt.js deleted file mode 100644 index 856aaeb8b1a..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_lt.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: LT (Lithuanian; lietuvių kalba) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Šis laukas yra privalomas.", - remote: "Prašau pataisyti šį lauką.", - email: "Prašau įvesti teisingą elektroninio pašto adresą.", - url: "Prašau įvesti teisingą URL.", - date: "Prašau įvesti teisingą datą.", - dateISO: "Prašau įvesti teisingą datą (ISO).", - number: "Prašau įvesti teisingą skaičių.", - digits: "Prašau naudoti tik skaitmenis.", - creditcard: "Prašau įvesti teisingą kreditinės kortelės numerį.", - equalTo: "Prašau įvestį tą pačią reikšmę dar kartą.", - accept: "Prašau įvesti reikšmę su teisingu plėtiniu.", - maxlength: $.format("Prašau įvesti ne daugiau kaip {0} simbolių."), - minlength: $.format("Prašau įvesti bent {0} simbolius."), - rangelength: $.format("Prašau įvesti reikšmes, kurių ilgis nuo {0} iki {1} simbolių."), - range: $.format("Prašau įvesti reikšmę intervale nuo {0} iki {1}."), - max: $.format("Prašau įvesti reikšmę mažesnę arba lygią {0}."), - min: $.format("Prašau įvesti reikšmę didesnę arba lygią {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_lv.js b/js/lib/jquery/plugins/validate/localization/messages_lv.js deleted file mode 100644 index 959a9759c2e..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_lv.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: LV (Latvian; latviešu valoda) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Šis lauks ir obligāts.", - remote: "Lūdzu, pārbaudiet šo lauku.", - email: "Lūdzu, ievadiet derīgu e-pasta adresi.", - url: "Lūdzu, ievadiet derīgu URL adresi.", - date: "Lūdzu, ievadiet derīgu datumu.", - dateISO: "Lūdzu, ievadiet derīgu datumu (ISO).", - number: "Lūdzu, ievadiet derīgu numuru.", - digits: "Lūdzu, ievadiet tikai ciparus.", - creditcard: "Lūdzu, ievadiet derīgu kredītkartes numuru.", - equalTo: "Lūdzu, ievadiet to pašu vēlreiz.", - accept: "Lūdzu, ievadiet vērtību ar derīgu paplašinājumu.", - maxlength: $.validator.format("Lūdzu, ievadiet ne vairāk kā {0} rakstzīmes."), - minlength: $.validator.format("Lūdzu, ievadiet vismaz {0} rakstzīmes."), - rangelength: $.validator.format("Lūdzu ievadiet {0} līdz {1} rakstzīmes."), - range: $.validator.format("Lūdzu, ievadiet skaitli no {0} līdz {1}."), - max: $.validator.format("Lūdzu, ievadiet skaitli, kurš ir mazāks vai vienāds ar {0}."), - min: $.validator.format("Lūdzu, ievadiet skaitli, kurš ir lielāks vai vienāds ar {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_my.js b/js/lib/jquery/plugins/validate/localization/messages_my.js deleted file mode 100644 index 95fe7270f73..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_my.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: MY (Malay; Melayu) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Medan ini diperlukan.", - remote: "Sila betulkan medan ini.", - email: "Sila masukkan alamat emel yang betul.", - url: "Sila masukkan URL yang betul.", - date: "Sila masukkan tarikh yang betul.", - dateISO: "Sila masukkan tarikh(ISO) yang betul.", - number: "Sila masukkan nombor yang betul.", - digits: "Sila masukkan nilai digit sahaja.", - creditcard: "Sila masukkan nombor kredit kad yang betul.", - equalTo: "Sila masukkan nilai yang sama semula.", - accept: "Sila masukkan nilai yang telah diterima.", - maxlength: $.validator.format("Sila masukkan nilai tidak lebih dari {0} aksara."), - minlength: $.validator.format("Sila masukkan nilai sekurang-kurangnya {0} aksara."), - rangelength: $.validator.format("Sila masukkan panjang nilai antara {0} dan {1} aksara."), - range: $.validator.format("Sila masukkan nilai antara {0} dan {1} aksara."), - max: $.validator.format("Sila masukkan nilai yang kurang atau sama dengan {0}."), - min: $.validator.format("Sila masukkan nilai yang lebih atau sama dengan {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_nl.js b/js/lib/jquery/plugins/validate/localization/messages_nl.js deleted file mode 100644 index 39f335d7a4d..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_nl.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: NL (Dutch; Nederlands, Vlaams) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Dit is een verplicht veld.", - remote: "Controleer dit veld.", - email: "Vul hier een geldig e-mailadres in.", - url: "Vul hier een geldige URL in.", - date: "Vul hier een geldige datum in.", - dateISO: "Vul hier een geldige datum in (ISO-formaat).", - number: "Vul hier een geldig getal in.", - digits: "Vul hier alleen getallen in.", - creditcard: "Vul hier een geldig creditcardnummer in.", - equalTo: "Vul hier dezelfde waarde in.", - accept: "Vul hier een waarde in met een geldige extensie.", - maxlength: $.validator.format("Vul hier maximaal {0} tekens in."), - minlength: $.validator.format("Vul hier minimaal {0} tekens in."), - rangelength: $.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1} tekens."), - range: $.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1}."), - max: $.validator.format("Vul hier een waarde in kleiner dan of gelijk aan {0}."), - min: $.validator.format("Vul hier een waarde in groter dan of gelijk aan {0}."), - - // for validations in additional-methods.js - iban: "Vul hier een geldig IBAN in.", - dateNL: "Vul hier een geldige datum in.", - phoneNL: "Vul hier een geldig Nederlands telefoonnummer in.", - mobileNL: "Vul hier een geldig Nederlands mobiel telefoonnummer in.", - postalcodeNL: "Vul hier een geldige postcode in.", - bankaccountNL: "Vul hier een geldig bankrekeningnummer in.", - giroaccountNL: "Vul hier een geldig gironummer in.", - bankorgiroaccountNL: "Vul hier een geldig bank- of gironummer in." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_no.js b/js/lib/jquery/plugins/validate/localization/messages_no.js deleted file mode 100644 index 9ba6d2f5b5d..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_no.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: NO (Norwegian; Norsk) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Dette feltet er obligatorisk.", - maxlength: $.validator.format("Maksimalt {0} tegn."), - minlength: $.validator.format("Minimum {0} tegn."), - rangelength: $.validator.format("Angi minimum {0} og maksimum {1} tegn."), - email: "Oppgi en gyldig epostadresse.", - url: "Angi en gyldig URL.", - date: "Angi en gyldig dato.", - dateISO: "Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).", - dateSE: "Angi en gyldig dato.", - number: "Angi et gyldig nummer.", - numberSE: "Angi et gyldig nummer.", - digits: "Skriv kun tall.", - equalTo: "Skriv samme verdi igjen.", - range: $.validator.format("Angi en verdi mellom {0} og {1}."), - max: $.validator.format("Angi en verdi som er mindre eller lik {0}."), - min: $.validator.format("Angi en verdi som er større eller lik {0}."), - creditcard: "Angi et gyldig kredittkortnummer." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_pl.js b/js/lib/jquery/plugins/validate/localization/messages_pl.js deleted file mode 100644 index fcf2f6df867..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_pl.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: PL (Polish; język polski, polszczyzna) - */ -(function ($) { - $.extend($.validator.messages, { - required: "To pole jest wymagane.", - remote: "Proszę o wypełnienie tego pola.", - email: "Proszę o podanie prawidłowego adresu email.", - url: "Proszę o podanie prawidłowego URL.", - date: "Proszę o podanie prawidłowej daty.", - dateISO: "Proszę o podanie prawidłowej daty (ISO).", - number: "Proszę o podanie prawidłowej liczby.", - digits: "Proszę o podanie samych cyfr.", - creditcard: "Proszę o podanie prawidłowej karty kredytowej.", - equalTo: "Proszę o podanie tej samej wartości ponownie.", - accept: "Proszę o podanie wartości z prawidłowym rozszerzeniem.", - maxlength: $.validator.format("Proszę o podanie nie więcej niż {0} znaków."), - minlength: $.validator.format("Proszę o podanie przynajmniej {0} znaków."), - rangelength: $.validator.format("Proszę o podanie wartości o długości od {0} do {1} znaków."), - range: $.validator.format("Proszę o podanie wartości z przedziału od {0} do {1}."), - max: $.validator.format("Proszę o podanie wartości mniejszej bądź równej {0}."), - min: $.validator.format("Proszę o podanie wartości większej bądź równej {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_pt_BR.js b/js/lib/jquery/plugins/validate/localization/messages_pt_BR.js deleted file mode 100644 index dd9434802c3..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_pt_BR.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: PT (Portuguese; português) - * Region: BR (Brazil) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Este campo é requerido.", - remote: "Por favor, corrija este campo.", - email: "Por favor, forneça um endereço eletrônico válido.", - url: "Por favor, forneça uma URL válida.", - date: "Por favor, forneça uma data válida.", - dateISO: "Por favor, forneça uma data válida (ISO).", - number: "Por favor, forneça um número válido.", - digits: "Por favor, forneça somente dígitos.", - creditcard: "Por favor, forneça um cartão de crédito válido.", - equalTo: "Por favor, forneça o mesmo valor novamente.", - accept: "Por favor, forneça um valor com uma extensão válida.", - maxlength: $.validator.format("Por favor, forneça não mais que {0} caracteres."), - minlength: $.validator.format("Por favor, forneça ao menos {0} caracteres."), - rangelength: $.validator.format("Por favor, forneça um valor entre {0} e {1} caracteres de comprimento."), - range: $.validator.format("Por favor, forneça um valor entre {0} e {1}."), - max: $.validator.format("Por favor, forneça um valor menor ou igual a {0}."), - min: $.validator.format("Por favor, forneça um valor maior ou igual a {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_pt_PT.js b/js/lib/jquery/plugins/validate/localization/messages_pt_PT.js deleted file mode 100644 index 41b239e3345..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_pt_PT.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: PT (Portuguese; português) - * Region: PT (Portugal) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Campo de preenchimento obrigatório.", - remote: "Por favor, corrija este campo.", - email: "Por favor, introduza um endereço eletrónico válido.", - url: "Por favor, introduza um URL válido.", - date: "Por favor, introduza uma data válida.", - dateISO: "Por favor, introduza uma data válida (ISO).", - number: "Por favor, introduza um número válido.", - digits: "Por favor, introduza apenas dígitos.", - creditcard: "Por favor, introduza um número de cartão de crédito válido.", - equalTo: "Por favor, introduza de novo o mesmo valor.", - accept: "Por favor, introduza um ficheiro com uma extensão válida.", - maxlength: $.validator.format("Por favor, não introduza mais do que {0} caracteres."), - minlength: $.validator.format("Por favor, introduza pelo menos {0} caracteres."), - rangelength: $.validator.format("Por favor, introduza entre {0} e {1} caracteres."), - range: $.validator.format("Por favor, introduza um valor entre {0} e {1}."), - max: $.validator.format("Por favor, introduza um valor menor ou igual a {0}."), - min: $.validator.format("Por favor, introduza um valor maior ou igual a {0}.") - }); -}(jQuery)); diff --git a/js/lib/jquery/plugins/validate/localization/messages_ro.js b/js/lib/jquery/plugins/validate/localization/messages_ro.js deleted file mode 100644 index 6286f80f767..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_ro.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: RO (Romanian, limba română) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Acest câmp este obligatoriu.", - remote: "Te rugăm să completezi acest câmp.", - email: "Te rugăm să introduci o adresă de email validă", - url: "Te rugăm sa introduci o adresă URL validă.", - date: "Te rugăm să introduci o dată corectă.", - dateISO: "Te rugăm să introduci o dată (ISO) corectă.", - number: "Te rugăm să introduci un număr întreg valid.", - digits: "Te rugăm să introduci doar cifre.", - creditcard: "Te rugăm să introduci un numar de carte de credit valid.", - equalTo: "Te rugăm să reintroduci valoarea.", - accept: "Te rugăm să introduci o valoare cu o extensie validă.", - maxlength: $.validator.format("Te rugăm să nu introduci mai mult de {0} caractere."), - minlength: $.validator.format("Te rugăm să introduci cel puțin {0} caractere."), - rangelength: $.validator.format("Te rugăm să introduci o valoare între {0} și {1} caractere."), - range: $.validator.format("Te rugăm să introduci o valoare între {0} și {1}."), - max: $.validator.format("Te rugăm să introduci o valoare egal sau mai mică decât {0}."), - min: $.validator.format("Te rugăm să introduci o valoare egal sau mai mare decât {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_ru.js b/js/lib/jquery/plugins/validate/localization/messages_ru.js deleted file mode 100644 index 46dc78168e3..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_ru.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: RU (Russian; русский язык) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Это поле необходимо заполнить.", - remote: "Пожалуйста, введите правильное значение.", - email: "Пожалуйста, введите корректный адрес электронной почты.", - url: "Пожалуйста, введите корректный URL.", - date: "Пожалуйста, введите корректную дату.", - dateISO: "Пожалуйста, введите корректную дату в формате ISO.", - number: "Пожалуйста, введите число.", - digits: "Пожалуйста, вводите только цифры.", - creditcard: "Пожалуйста, введите правильный номер кредитной карты.", - equalTo: "Пожалуйста, введите такое же значение ещё раз.", - accept: "Пожалуйста, выберите файл с правильным расширением.", - maxlength: $.validator.format("Пожалуйста, введите не больше {0} символов."), - minlength: $.validator.format("Пожалуйста, введите не меньше {0} символов."), - rangelength: $.validator.format("Пожалуйста, введите значение длиной от {0} до {1} символов."), - range: $.validator.format("Пожалуйста, введите число от {0} до {1}."), - max: $.validator.format("Пожалуйста, введите число, меньшее или равное {0}."), - min: $.validator.format("Пожалуйста, введите число, большее или равное {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_si.js b/js/lib/jquery/plugins/validate/localization/messages_si.js deleted file mode 100644 index 0c280e80db9..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_si.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: SI (Slovenian) - */ -(function ($) { - $.extend($.validator.messages, { - required: "To polje je obvezno.", - remote: "Vpis v tem polju ni v pravi obliki.", - email: "Prosimo, vnesite pravi email naslov.", - url: "Prosimo, vnesite pravi URL.", - date: "Prosimo, vnesite pravi datum.", - dateISO: "Prosimo, vnesite pravi datum (ISO).", - number: "Prosimo, vnesite pravo številko.", - digits: "Prosimo, vnesite samo številke.", - creditcard: "Prosimo, vnesite pravo številko kreditne kartice.", - equalTo: "Prosimo, ponovno vnesite enako vsebino.", - accept: "Prosimo, vnesite vsebino z pravo končnico.", - maxlength: $.validator.format("Prosimo, da ne vnašate več kot {0} znakov."), - minlength: $.validator.format("Prosimo, vnesite vsaj {0} znakov."), - rangelength: $.validator.format("Prosimo, vnesite od {0} do {1} znakov."), - range: $.validator.format("Prosimo, vnesite vrednost med {0} in {1}."), - max: $.validator.format("Prosimo, vnesite vrednost manjšo ali enako {0}."), - min: $.validator.format("Prosimo, vnesite vrednost večjo ali enako {0}.") - }); -}(jQuery)); diff --git a/js/lib/jquery/plugins/validate/localization/messages_sk.js b/js/lib/jquery/plugins/validate/localization/messages_sk.js deleted file mode 100644 index bc6340abfcd..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_sk.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: SK (Slovak; slovenčina, slovenský jazyk) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Povinné zadať.", - maxlength: $.validator.format("Maximálne {0} znakov."), - minlength: $.validator.format("Minimálne {0} znakov."), - rangelength: $.validator.format("Minimálne {0} a Maximálne {0} znakov."), - email: "E-mailová adresa musí byť platná.", - url: "URL musí byť platný.", - date: "Musí byť dátum.", - number: "Musí byť číslo.", - digits: "Môže obsahovať iba číslice.", - equalTo: "Dva hodnoty sa musia rovnať.", - range: $.validator.format("Musí byť medzi {0} a {1}."), - max: $.validator.format("Nemôže byť viac ako{0}."), - min: $.validator.format("Nemôže byť menej ako{0}."), - creditcard: "Číslo platobnej karty musí byť platné." - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_sl.js b/js/lib/jquery/plugins/validate/localization/messages_sl.js deleted file mode 100644 index fa53d6d721c..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_sl.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Language: SL (Slovenian; slovenski jezik) - */ -(function ($) { - $.extend($.validator.messages, { - required: "To polje je obvezno.", - remote: "Prosimo popravite to polje.", - email: "Prosimo vnesite veljaven email naslov.", - url: "Prosimo vnesite veljaven URL naslov.", - date: "Prosimo vnesite veljaven datum.", - dateISO: "Prosimo vnesite veljaven ISO datum.", - number: "Prosimo vnesite veljavno število.", - digits: "Prosimo vnesite samo števila.", - creditcard: "Prosimo vnesite veljavno številko kreditne kartice.", - equalTo: "Prosimo ponovno vnesite vrednost.", - accept: "Prosimo vnesite vrednost z veljavno končnico.", - maxlength: $.validator.format("Prosimo vnesite največ {0} znakov."), - minlength: $.validator.format("Prosimo vnesite najmanj {0} znakov."), - rangelength: $.validator.format("Prosimo vnesite najmanj {0} in največ {1} znakov."), - range: $.validator.format("Prosimo vnesite vrednost med {0} in {1}."), - max: $.validator.format("Prosimo vnesite vrednost manjše ali enako {0}."), - min: $.validator.format("Prosimo vnesite vrednost večje ali enako {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_sr.js b/js/lib/jquery/plugins/validate/localization/messages_sr.js deleted file mode 100644 index 73b5ec7ae1a..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_sr.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: SR (Serbian; српски језик) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Поље је обавезно.", - remote: "Средите ово поље.", - email: "Унесите исправну и-мејл адресу", - url: "Унесите исправан URL.", - date: "Унесите исправан датум.", - dateISO: "Унесите исправан датум (ISO).", - number: "Унесите исправан број.", - digits: "Унесите само цифе.", - creditcard: "Унесите исправан број кредитне картице.", - equalTo: "Унесите исту вредност поново.", - accept: "Унесите вредност са одговарајућом екстензијом.", - maxlength: $.validator.format("Унесите мање од {0}карактера."), - minlength: $.validator.format("Унесите барем {0} карактера."), - rangelength: $.validator.format("Унесите вредност дугачку између {0} и {1} карактера."), - range: $.validator.format("Унесите вредност између {0} и {1}."), - max: $.validator.format("Унесите вредност мању или једнаку {0}."), - min: $.validator.format("Унесите вредност већу или једнаку {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_sv.js b/js/lib/jquery/plugins/validate/localization/messages_sv.js deleted file mode 100644 index 26db0913a3e..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_sv.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: SV (Swedish; Svenska) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Detta fält är obligatoriskt.", - maxlength: $.validator.format("Du får ange högst {0} tecken."), - minlength: $.validator.format("Du måste ange minst {0} tecken."), - rangelength: $.validator.format("Ange minst {0} och max {1} tecken."), - email: "Ange en korrekt e-postadress.", - url: "Ange en korrekt URL.", - date: "Ange ett korrekt datum.", - dateISO: "Ange ett korrekt datum (ÅÅÅÅ-MM-DD).", - number: "Ange ett korrekt nummer.", - digits: "Ange endast siffror.", - equalTo: "Ange samma värde igen.", - range: $.validator.format("Ange ett värde mellan {0} och {1}."), - max: $.validator.format("Ange ett värde som är mindre eller lika med {0}."), - min: $.validator.format("Ange ett värde som är större eller lika med {0}."), - creditcard: "Ange ett korrekt kreditkortsnummer." - }); -}(jQuery)); diff --git a/js/lib/jquery/plugins/validate/localization/messages_th.js b/js/lib/jquery/plugins/validate/localization/messages_th.js deleted file mode 100644 index f3b02355674..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_th.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: TH (Thai; ไทย) - */ -(function ($) { - $.extend($.validator.messages, { - required: "โปรดระบุ", - remote: "โปรดแก้ไขให้ถูกต้อง", - email: "โปรดระบุที่อยู่อีเมล์ที่ถูกต้อง", - url: "โปรดระบุ URL ที่ถูกต้อง", - date: "โปรดระบุวันที่ ที่ถูกต้อง", - dateISO: "โปรดระบุวันที่ ที่ถูกต้อง (ระบบ ISO).", - number: "โปรดระบุทศนิยมที่ถูกต้อง", - digits: "โปรดระบุจำนวนเต็มที่ถูกต้อง", - creditcard: "โปรดระบุรหัสบัตรเครดิตที่ถูกต้อง", - equalTo: "โปรดระบุค่าเดิมอีกครั้ง", - accept: "โปรดระบุค่าที่มีส่วนขยายที่ถูกต้อง", - maxlength: $.validator.format("โปรดอย่าระบุค่าที่ยาวกว่า {0} อักขระ"), - minlength: $.validator.format("โปรดอย่าระบุค่าที่สั้นกว่า {0} อักขระ"), - rangelength: $.validator.format("โปรดอย่าระบุค่าความยาวระหว่าง {0} ถึง {1} อักขระ"), - range: $.validator.format("โปรดระบุค่าระหว่าง {0} และ {1}"), - max: $.validator.format("โปรดระบุค่าน้อยกว่าหรือเท่ากับ {0}"), - min: $.validator.format("โปรดระบุค่ามากกว่าหรือเท่ากับ {0}") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_tr.js b/js/lib/jquery/plugins/validate/localization/messages_tr.js deleted file mode 100644 index 1c412180a21..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_tr.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: TR (Turkish; Türkçe) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Bu alanın doldurulması zorunludur.", - remote: "Lütfen bu alanı düzeltin.", - email: "Lütfen geçerli bir e-posta adresi giriniz.", - url: "Lütfen geçerli bir web adresi (URL) giriniz.", - date: "Lütfen geçerli bir tarih giriniz.", - dateISO: "Lütfen geçerli bir tarih giriniz(ISO formatında)", - number: "Lütfen geçerli bir sayı giriniz.", - digits: "Lütfen sadece sayısal karakterler giriniz.", - creditcard: "Lütfen geçerli bir kredi kartı giriniz.", - equalTo: "Lütfen aynı değeri tekrar giriniz.", - accept: "Lütfen geçerli uzantıya sahip bir değer giriniz.", - maxlength: $.validator.format("Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz."), - minlength: $.validator.format("Lütfen en az {0} karakter uzunluğunda bir değer giriniz."), - rangelength: $.validator.format("Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz."), - range: $.validator.format("Lütfen {0} ile {1} arasında bir değer giriniz."), - max: $.validator.format("Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz."), - min: $.validator.format("Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_uk.js b/js/lib/jquery/plugins/validate/localization/messages_uk.js deleted file mode 100644 index cdea494b1d7..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_uk.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: UK (Ukrainian; українська мова) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Це поле необхідно заповнити.", - remote: "Будь ласка, введіть правильне значення.", - email: "Будь ласка, введіть коректну адресу електронної пошти.", - url: "Будь ласка, введіть коректний URL.", - date: "Будь ласка, введіть коректну дату.", - dateISO: "Будь ласка, введіть коректну дату у форматі ISO.", - number: "Будь ласка, введіть число.", - digits: "Вводите потрібно лише цифри.", - creditcard: "Будь ласка, введіть правильний номер кредитної карти.", - equalTo: "Будь ласка, введіть таке ж значення ще раз.", - accept: "Будь ласка, виберіть файл з правильним розширенням.", - maxlength: $.validator.format("Будь ласка, введіть не більше {0} символів."), - minlength: $.validator.format("Будь ласка, введіть не менше {0} символів."), - rangelength: $.validator.format("Будь ласка, введіть значення довжиною від {0} до {1} символів."), - range: $.validator.format("Будь ласка, введіть число від {0} до {1}."), - max: $.validator.format("Будь ласка, введіть число, менше або рівно {0}."), - min: $.validator.format("Будь ласка, введіть число, більше або рівно {0}.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_vi.js b/js/lib/jquery/plugins/validate/localization/messages_vi.js deleted file mode 100644 index fd5f2b5d5e1..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_vi.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: VI (Vietnamese; Tiếng Việt) - */ -(function ($) { - $.extend($.validator.messages, { - required: "Hãy nhập.", - remote: "Hãy sửa cho đúng.", - email: "Hãy nhập email.", - url: "Hãy nhập URL.", - date: "Hãy nhập ngày.", - dateISO: "Hãy nhập ngày (ISO).", - number: "Hãy nhập số.", - digits: "Hãy nhập chữ số.", - creditcard: "Hãy nhập số thẻ tín dụng.", - equalTo: "Hãy nhập thêm lần nữa.", - accept: "Phần mở rộng không đúng.", - maxlength: $.format("Hãy nhập từ {0} kí tự trở xuống."), - minlength: $.format("Hãy nhập từ {0} kí tự trở lên."), - rangelength: $.format("Hãy nhập từ {0} đến {1} kí tự."), - range: $.format("Hãy nhập từ {0} đến {1}."), - max: $.format("Hãy nhập từ {0} trở xuống."), - min: $.format("Hãy nhập từ {1} trở lên.") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_zh.js b/js/lib/jquery/plugins/validate/localization/messages_zh.js deleted file mode 100644 index 2c4d5c30843..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_zh.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: ZH (Chinese, 中文 (Zhōngwén), 汉语, 漢語) - */ -(function ($) { - $.extend($.validator.messages, { - required: "必选字段", - remote: "请修正该字段", - email: "请输入正确格式的电子邮件", - url: "请输入合法的网址", - date: "请输入合法的日期", - dateISO: "请输入合法的日期 (ISO).", - number: "请输入合法的数字", - digits: "只能输入整数", - creditcard: "请输入合法的信用卡号", - equalTo: "请再次输入相同的值", - accept: "请输入拥有合法后缀名的字符串", - maxlength: $.validator.format("请输入一个长度最多是 {0} 的字符串"), - minlength: $.validator.format("请输入一个长度最少是 {0} 的字符串"), - rangelength: $.validator.format("请输入一个长度介于 {0} 和 {1} 之间的字符串"), - range: $.validator.format("请输入一个介于 {0} 和 {1} 之间的值"), - max: $.validator.format("请输入一个最大为 {0} 的值"), - min: $.validator.format("请输入一个最小为 {0} 的值") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/messages_zh_TW.js b/js/lib/jquery/plugins/validate/localization/messages_zh_TW.js deleted file mode 100644 index ec0a2ffbc55..00000000000 --- a/js/lib/jquery/plugins/validate/localization/messages_zh_TW.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Translated default messages for the jQuery validation plugin. - * Locale: ZH (Chinese; 中文 (Zhōngwén), 汉语, 漢語) - * Region: TW (Taiwan) - */ -(function ($) { - $.extend($.validator.messages, { - required: "必填", - remote: "請修正此欄位", - email: "請輸入正確的電子信箱", - url: "請輸入合法的URL", - date: "請輸入合法的日期", - dateISO: "請輸入合法的日期 (ISO).", - number: "請輸入數字", - digits: "請輸入整數", - creditcard: "請輸入合法的信用卡號碼", - equalTo: "請重複輸入一次", - accept: "請輸入有效的後缀字串", - maxlength: $.validator.format("請輸入長度不大於{0} 的字串"), - minlength: $.validator.format("請輸入長度不小於 {0} 的字串"), - rangelength: $.validator.format("請輸入長度介於 {0} 和 {1} 之間的字串"), - range: $.validator.format("請輸入介於 {0} 和 {1} 之間的數值"), - max: $.validator.format("請輸入不大於 {0} 的數值"), - min: $.validator.format("請輸入不小於 {0} 的數值") - }); -}(jQuery)); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/methods_de.js b/js/lib/jquery/plugins/validate/localization/methods_de.js deleted file mode 100644 index 3e8ac8437e0..00000000000 --- a/js/lib/jquery/plugins/validate/localization/methods_de.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Localized default methods for the jQuery validation plugin. - * Locale: DE - */ -jQuery.extend(jQuery.validator.methods, { - date: function(value, element) { - return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value); - }, - number: function(value, element) { - return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value); - } -}); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/methods_nl.js b/js/lib/jquery/plugins/validate/localization/methods_nl.js deleted file mode 100644 index 450041b14e9..00000000000 --- a/js/lib/jquery/plugins/validate/localization/methods_nl.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Localized default methods for the jQuery validation plugin. - * Locale: NL - */ -jQuery.extend(jQuery.validator.methods, { - date: function(value, element) { - return this.optional(element) || /^\d\d?[\.\/\-]\d\d?[\.\/\-]\d\d\d?\d?$/.test(value); - } -}); \ No newline at end of file diff --git a/js/lib/jquery/plugins/validate/localization/methods_pt.js b/js/lib/jquery/plugins/validate/localization/methods_pt.js deleted file mode 100644 index 21879d3bb66..00000000000 --- a/js/lib/jquery/plugins/validate/localization/methods_pt.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Localized default methods for the jQuery validation plugin. - * Locale: PT_BR - */ -jQuery.extend(jQuery.validator.methods, { - date: function(value, element) { - return this.optional(element) || /^\d\d?\/\d\d?\/\d\d\d?\d?$/.test(value); - } -}); \ No newline at end of file diff --git a/js/usage-stats-chart.js b/js/usage-stats-chart.js index 7e04ef53cfa..f7493665d23 100644 --- a/js/usage-stats-chart.js +++ b/js/usage-stats-chart.js @@ -43,63 +43,56 @@ // Define default chart options var chartOptions = { - legend: { - display: false, + plugins: { + legend: { + display: false, + }, }, - tooltips: { - titleColor: '#333', - bodyColor: '#333', - footerColor: '#333', + tooltip: { + titleFontColor: '#333', + bodyFontColor: '#333', + footerFontColor: '#333', backgroundColor: '#ddd', cornerRadius: 2, }, elements: { line: { - borderColor: 'rgba(0,0,0,0.3)', - borderWidth: 1, + borderColor: 'rgba(0,0,0,0.4)', + borderWidth: 2, borderJoinStyle: 'round', backgroundColor: 'rgba(0,0,0,0.3)', + tension: 0.5, + fill: true, }, - rectangle: { + bar: { backgroundColor: 'rgba(0,0,0,0.3)', }, point: { radius: 2, hoverRadius: 6, - borderWidth: 0, + borderWidth: 2, hitRadius: 5, }, }, scales: { - xAxes: [ - { - gridLines: { - color: 'rgba(0,0,0,0.05)', - drawTicks: false, - }, + x: { + grid: { + color: + pkpUsageStats.config.chartType === 'bar' + ? 'transparent' + : 'rgba(0,0,0,0.05)', + drawTicks: false, }, - ], - yAxes: [ - { - gridLines: { - color: 'rgba(0,0,0,0.05)', - drawTicks: false, - }, + }, + y: { + grid: { + color: 'rgba(0,0,0,0.05)', + drawTicks: false, }, - ], + }, }, }; - if (pkpUsageStats.config.chartType === 'bar') { - chartOptions.scales.xAxes = [ - { - gridLines: { - color: 'transparent', - }, - }, - ]; - } - // Fire an event to allow third-party customization of the options var optionsEvent = document.createEvent('Event'); optionsEvent.initEvent('usageStatsChartOptions.pkp', true, true);