From 343c08dad2a88b38536a3548571a82be80087190 Mon Sep 17 00:00:00 2001 From: mrholek Date: Mon, 11 Nov 2019 15:52:32 +0100 Subject: [PATCH 01/37] Ship v2.0.0-beta.0 --- custom-tooltips/.babelrc.js => .babelrc.js | 0 .../.editorconfig => .editorconfig | 0 .../.eslintignore => .eslintignore | 0 .../.eslintrc.json => .eslintrc.json | 0 .../.gitattributes => .gitattributes | 0 CHANGELOG.md | 40 +- {custom-tooltips/build => build}/banner.js | 0 .../build => build}/postcss.config.js | 0 .../build => build}/rollup.config.js | 2 +- custom-tooltips/.gitignore | 3 - custom-tooltips/CHANGELOG.md | 41 - .../dist/css/coreui-chartjs.css.map | 1 - .../dist/css/coreui-chartjs.min.css.map | 1 - .../dist/js/coreui-chartjs.bundle.js | 163 - .../dist/js/coreui-chartjs.bundle.js.map | 1 - .../dist/js/coreui-chartjs.bundle.min.js | 7 - .../dist/js/coreui-chartjs.bundle.min.js.map | 1 - .../dist/js/coreui-chartjs.esm.js.map | 1 - .../dist/js/coreui-chartjs.esm.min.js | 7 - .../dist/js/coreui-chartjs.esm.min.js.map | 1 - custom-tooltips/dist/js/coreui-chartjs.js.map | 1 - custom-tooltips/dist/js/coreui-chartjs.min.js | 7 - .../dist/js/coreui-chartjs.min.js.map | 1 - custom-tooltips/package-lock.json | 5 - custom-tooltips/package.json | 79 - .../dist => dist}/css/coreui-chartjs.css | 4 +- dist/css/coreui-chartjs.css.map | 1 + .../dist => dist}/css/coreui-chartjs.min.css | 4 +- dist/css/coreui-chartjs.min.css.map | 1 + dist/js/coreui-chartjs.bundle.js | 16312 +++++++ dist/js/coreui-chartjs.bundle.js.map | 1 + dist/js/coreui-chartjs.bundle.min.js | 13 + dist/js/coreui-chartjs.bundle.min.js.map | 1 + .../dist => dist}/js/coreui-chartjs.esm.js | 32 +- dist/js/coreui-chartjs.esm.js.map | 1 + dist/js/coreui-chartjs.esm.min.js | 7 + dist/js/coreui-chartjs.esm.min.js.map | 1 + .../dist => dist}/js/coreui-chartjs.js | 44 +- dist/js/coreui-chartjs.js.map | 1 + dist/js/coreui-chartjs.min.js | 7 + dist/js/coreui-chartjs.min.js.map | 1 + {custom-tooltips/js => js}/index.esm.js | 4 +- {custom-tooltips/js => js}/index.umd.js | 4 +- .../js => js}/src/custom-tooltips.js | 27 +- package-lock.json | 1604 +- package.json | 55 +- {custom-tooltips/scss => scss}/_tooltips.scss | 0 .../scss => scss}/_variables.scss | 0 {custom-tooltips/scss => scss}/style.scss | 2 +- vue/.gitignore | 20 - vue/LICENSE | 21 - vue/README.md | 2 - vue/babel.config.js | 7 - vue/dist/coreui-vue-chartjs.common.js | 36334 --------------- vue/dist/coreui-vue-chartjs.common.js.map | 1 - vue/dist/coreui-vue-chartjs.umd.js | 36344 ---------------- vue/dist/coreui-vue-chartjs.umd.js.map | 1 - vue/dist/coreui-vue-chartjs.umd.min.js | 15 - vue/dist/coreui-vue-chartjs.umd.min.js.map | 1 - vue/dist/demo.html | 10 - vue/package-lock.json | 12447 ------ vue/package.json | 46 - vue/src/generateChartComponent.js | 134 - vue/src/index.js | 31 - 64 files changed, 17099 insertions(+), 86804 deletions(-) rename custom-tooltips/.babelrc.js => .babelrc.js (100%) rename custom-tooltips/.editorconfig => .editorconfig (100%) rename custom-tooltips/.eslintignore => .eslintignore (100%) rename custom-tooltips/.eslintrc.json => .eslintrc.json (100%) rename custom-tooltips/.gitattributes => .gitattributes (100%) rename {custom-tooltips/build => build}/banner.js (100%) rename {custom-tooltips/build => build}/postcss.config.js (100%) rename {custom-tooltips/build => build}/rollup.config.js (98%) delete mode 100644 custom-tooltips/.gitignore delete mode 100644 custom-tooltips/CHANGELOG.md delete mode 100644 custom-tooltips/dist/css/coreui-chartjs.css.map delete mode 100644 custom-tooltips/dist/css/coreui-chartjs.min.css.map delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.bundle.js delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.bundle.js.map delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.bundle.min.js delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.bundle.min.js.map delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.esm.js.map delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.esm.min.js delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.esm.min.js.map delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.js.map delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.min.js delete mode 100644 custom-tooltips/dist/js/coreui-chartjs.min.js.map delete mode 100644 custom-tooltips/package-lock.json delete mode 100644 custom-tooltips/package.json rename {custom-tooltips/dist => dist}/css/coreui-chartjs.css (94%) create mode 100644 dist/css/coreui-chartjs.css.map rename {custom-tooltips/dist => dist}/css/coreui-chartjs.min.css (93%) create mode 100644 dist/css/coreui-chartjs.min.css.map create mode 100644 dist/js/coreui-chartjs.bundle.js create mode 100644 dist/js/coreui-chartjs.bundle.js.map create mode 100644 dist/js/coreui-chartjs.bundle.min.js create mode 100644 dist/js/coreui-chartjs.bundle.min.js.map rename {custom-tooltips/dist => dist}/js/coreui-chartjs.esm.js (83%) create mode 100644 dist/js/coreui-chartjs.esm.js.map create mode 100644 dist/js/coreui-chartjs.esm.min.js create mode 100644 dist/js/coreui-chartjs.esm.min.js.map rename {custom-tooltips/dist => dist}/js/coreui-chartjs.js (82%) create mode 100644 dist/js/coreui-chartjs.js.map create mode 100644 dist/js/coreui-chartjs.min.js create mode 100644 dist/js/coreui-chartjs.min.js.map rename {custom-tooltips/js => js}/index.esm.js (70%) rename {custom-tooltips/js => js}/index.umd.js (70%) rename {custom-tooltips/js => js}/src/custom-tooltips.js (83%) rename {custom-tooltips/scss => scss}/_tooltips.scss (100%) rename {custom-tooltips/scss => scss}/_variables.scss (100%) rename {custom-tooltips/scss => scss}/style.scss (89%) delete mode 100644 vue/.gitignore delete mode 100644 vue/LICENSE delete mode 100644 vue/README.md delete mode 100644 vue/babel.config.js delete mode 100644 vue/dist/coreui-vue-chartjs.common.js delete mode 100644 vue/dist/coreui-vue-chartjs.common.js.map delete mode 100644 vue/dist/coreui-vue-chartjs.umd.js delete mode 100644 vue/dist/coreui-vue-chartjs.umd.js.map delete mode 100644 vue/dist/coreui-vue-chartjs.umd.min.js delete mode 100644 vue/dist/coreui-vue-chartjs.umd.min.js.map delete mode 100644 vue/dist/demo.html delete mode 100644 vue/package-lock.json delete mode 100644 vue/package.json delete mode 100644 vue/src/generateChartComponent.js delete mode 100644 vue/src/index.js diff --git a/custom-tooltips/.babelrc.js b/.babelrc.js similarity index 100% rename from custom-tooltips/.babelrc.js rename to .babelrc.js diff --git a/custom-tooltips/.editorconfig b/.editorconfig similarity index 100% rename from custom-tooltips/.editorconfig rename to .editorconfig diff --git a/custom-tooltips/.eslintignore b/.eslintignore similarity index 100% rename from custom-tooltips/.eslintignore rename to .eslintignore diff --git a/custom-tooltips/.eslintrc.json b/.eslintrc.json similarity index 100% rename from custom-tooltips/.eslintrc.json rename to .eslintrc.json diff --git a/custom-tooltips/.gitattributes b/.gitattributes similarity index 100% rename from custom-tooltips/.gitattributes rename to .gitattributes diff --git a/CHANGELOG.md b/CHANGELOG.md index beef575..bccaaac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,41 @@ -## [CoreUI](https:/coreui.io) Chart.js utities +## [CoreUI](https:/coreui.io) Chart.js CustomTooltips plugin +### v1.3.1 +- fix: tooltip position out of view area +##### dependencies update +- update `@babel/core` to `^7.4.5` +- update `@babel/plugin-proposal-object-rest-spread` to `^7.4.4` +- update `@babel/cli` to `^7.4.4` +- update `@babel/preset-env` to `^7.4.5` +- update `babel-eslint` to `^10.0.1` +- update `babel-plugin-istanbul` to `^5.1.4` +- update `babel-preset-minify` to `^0.5.0` +- update `eslint` to `^5.16.0` +- update `eslint-plugin-compat` to `^3.1.0` +- update `nodemon` to `^1.19.1` +- update `rollup` to `^1.12.5` +- update `rollup-plugin-babel-minify` to `^8.0.0` +- update `rollup-plugin-commonjs` to `^10.0.0` +- update `rollup-plugin-node-resolve` to `^5.0.0` +- update `rollup-plugin-uglify` to `^6.0.2` +- update `uglify-js` to `^3.5.1` +- chore(rollup.config): update `uglify` plugin call + +### v1.3.0 +- fix: named exports + +##### dependencies update +- update `@babel/cli` to `^7.4.3` +- update `@babel/core` to `^7.4.3` +- update `@babel/plugin-proposal-object-rest-spread` to `^7.4.3` +- update `@babel/preset-env` to `^7.4.3` +- update `babel-eslint` to `^10.0.1` +- update `rollup-plugin-babel` to `^4.3.2` + +### v1.2.0 +- chore: add `rollup.js` module bundler +- chore: adjust linebreak-style eslint rule +- refactor: extract _setCanvasId function +- refactor: generate and set random _chart.canvas.id if none +- chore: dependencies update diff --git a/custom-tooltips/build/banner.js b/build/banner.js similarity index 100% rename from custom-tooltips/build/banner.js rename to build/banner.js diff --git a/custom-tooltips/build/postcss.config.js b/build/postcss.config.js similarity index 100% rename from custom-tooltips/build/postcss.config.js rename to build/postcss.config.js diff --git a/custom-tooltips/build/rollup.config.js b/build/rollup.config.js similarity index 98% rename from custom-tooltips/build/rollup.config.js rename to build/rollup.config.js index 81c893d..6e63e90 100644 --- a/custom-tooltips/build/rollup.config.js +++ b/build/rollup.config.js @@ -48,7 +48,7 @@ const plugins = [ }) ] const globals = { - 'chart.js': 'Chart.js' + 'chart.js': 'Chart' } if (BUNDLE) { diff --git a/custom-tooltips/.gitignore b/custom-tooltips/.gitignore deleted file mode 100644 index f598023..0000000 --- a/custom-tooltips/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -.idea -node_modules diff --git a/custom-tooltips/CHANGELOG.md b/custom-tooltips/CHANGELOG.md deleted file mode 100644 index bccaaac..0000000 --- a/custom-tooltips/CHANGELOG.md +++ /dev/null @@ -1,41 +0,0 @@ -## [CoreUI](https:/coreui.io) Chart.js CustomTooltips plugin - -### v1.3.1 -- fix: tooltip position out of view area - -##### dependencies update -- update `@babel/core` to `^7.4.5` -- update `@babel/plugin-proposal-object-rest-spread` to `^7.4.4` -- update `@babel/cli` to `^7.4.4` -- update `@babel/preset-env` to `^7.4.5` -- update `babel-eslint` to `^10.0.1` -- update `babel-plugin-istanbul` to `^5.1.4` -- update `babel-preset-minify` to `^0.5.0` -- update `eslint` to `^5.16.0` -- update `eslint-plugin-compat` to `^3.1.0` -- update `nodemon` to `^1.19.1` -- update `rollup` to `^1.12.5` -- update `rollup-plugin-babel-minify` to `^8.0.0` -- update `rollup-plugin-commonjs` to `^10.0.0` -- update `rollup-plugin-node-resolve` to `^5.0.0` -- update `rollup-plugin-uglify` to `^6.0.2` -- update `uglify-js` to `^3.5.1` -- chore(rollup.config): update `uglify` plugin call - -### v1.3.0 -- fix: named exports - -##### dependencies update -- update `@babel/cli` to `^7.4.3` -- update `@babel/core` to `^7.4.3` -- update `@babel/plugin-proposal-object-rest-spread` to `^7.4.3` -- update `@babel/preset-env` to `^7.4.3` -- update `babel-eslint` to `^10.0.1` -- update `rollup-plugin-babel` to `^4.3.2` - -### v1.2.0 -- chore: add `rollup.js` module bundler -- chore: adjust linebreak-style eslint rule -- refactor: extract _setCanvasId function -- refactor: generate and set random _chart.canvas.id if none -- chore: dependencies update diff --git a/custom-tooltips/dist/css/coreui-chartjs.css.map b/custom-tooltips/dist/css/coreui-chartjs.css.map deleted file mode 100644 index a8c158f..0000000 --- a/custom-tooltips/dist/css/coreui-chartjs.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["coreui-chartjs.css","../../scss/style.scss","../../scss/_tooltips.scss","../../node_modules/@coreui/coreui/scss/_variables.scss","../../node_modules/@coreui/coreui/scss/mixins/_border-radius.scss"],"names":[],"mappings":"AAAA,gBAAgB;ACAhB;;;;;;EDOE;AELF;EACE,kBAAkB;EAClB,aCo3BsC;EDn3BtC,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,uBAAuC;EACvC,WAAW;EACX,oBAAoB;EACpB,8BAA6B;EAC7B,UAAU;EACV,0BAA6C;EAC7C,qCAA6B;EAA7B,6BAA6B;EER3B,sBDwVgC;AHxUpC;;AEnBA;EAeI,qBAA6B;AFQjC;;AEvBA;EAmBI,sBCiZgD;EDhZhD,gBCqZ6B;AH7YjC;;AE5BA;EAwBI,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,sBC0YgD;EDzYhD,mBAAmB;AFQvB;;AEnCA;EA+BI,qBAAqB;EACrB,eCkYiC;EDjYjC,gBCiYiC;EDhYjC,sBCgYiC;AHxXrC;;AE1CA;EAsCI,kBCqKS;EDpKT,iBAAiB;EACjB,gBCiY6B;AHzXjC","file":"coreui-chartjs.css","sourcesContent":["@charset \"UTF-8\";\n/*!\n * CoreUI Plugins - Chart.js for CoreUI 3\n * @version v2.0.0-alpha.0\n * @link https://coreui.io\n * Copyright (c) 2019 creativeLabs Łukasz Holeczek\n * Licensed under MIT (https://coreui.io/license/plugins/chart.js)\n */\n.c-chartjs-tooltip {\n position: absolute;\n z-index: 1021;\n display: flex;\n flex-direction: column;\n padding: 0.25rem 0.5rem;\n color: #fff;\n pointer-events: none;\n background: rgba(0, 0, 0, 0.7);\n opacity: 0;\n transition: all 0.25s ease;\n transform: translate(-50%, 0);\n border-radius: 0.25rem;\n}\n\n.c-chartjs-tooltip .c-tooltip-header {\n margin-bottom: 0.5rem;\n}\n\n.c-chartjs-tooltip .c-tooltip-header-item {\n font-size: 0.765625rem;\n font-weight: 700;\n}\n\n.c-chartjs-tooltip .c-tooltip-body-item {\n display: flex;\n align-items: center;\n font-size: 0.765625rem;\n white-space: nowrap;\n}\n\n.c-chartjs-tooltip .c-tooltip-body-item-color {\n display: inline-block;\n width: 0.875rem;\n height: 0.875rem;\n margin-right: 0.875rem;\n}\n\n.c-chartjs-tooltip .c-tooltip-body-item-value {\n padding-left: 1rem;\n margin-left: auto;\n font-weight: 700;\n}\n\n/*# sourceMappingURL=coreui-chartjs.css.map */","/*!\n * CoreUI Plugins - Chart.js for CoreUI 3\n * @version v2.0.0-alpha.0\n * @link https://coreui.io\n * Copyright (c) 2019 creativeLabs Łukasz Holeczek\n * Licensed under MIT (https://coreui.io/license/plugins/chart.js)\n */\n\n@import \"variables\";\n@import \"tooltips\";\n","// Custom tooltips\n\n.#{$prefix}chartjs-tooltip {\n position: absolute;\n z-index: $zindex-sticky + 1;\n display: flex;\n flex-direction: column;\n padding: ($spacer * .25) ($spacer * .5);\n color: #fff;\n pointer-events: none;\n background: rgba(0, 0, 0, .7);\n opacity: 0;\n transition: all $layout-transition-speed ease;\n transform: translate(-50%, 0);\n @include border-radius($border-radius);\n\n .#{$prefix}tooltip-header {\n margin-bottom: ($spacer * .5);\n }\n\n .#{$prefix}tooltip-header-item {\n font-size: $font-size-sm;\n font-weight: $font-weight-bold;\n }\n\n .#{$prefix}tooltip-body-item {\n display: flex;\n align-items: center;\n font-size: $font-size-sm;\n white-space: nowrap;\n }\n\n .#{$prefix}tooltip-body-item-color {\n display: inline-block;\n width: $font-size-base;\n height: $font-size-base;\n margin-right: $font-size-base;\n }\n\n .#{$prefix}tooltip-body-item-value {\n padding-left: $spacer;\n margin-left: auto;\n font-weight: $font-weight-bold;\n }\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n@import \"variables/colors\";\n\n$white: #fff !default;\n$gray-base: #181b1e !default;\n$gray-100: #f0f3f5 !default; // lighten($gray-base, 85%);\n$gray-200: #e4e7ea !default; // lighten($gray-base, 80%);\n$gray-300: #c8ced3 !default; // lighten($gray-base, 70%);\n$gray-400: #acb4bc !default; // lighten($gray-base, 60%);\n$gray-500: #8f9ba6 !default; // lighten($gray-base, 50%);\n$gray-600: #73818f !default; // lighten($gray-base, 40%);\n$gray-700: #5c6873 !default; // lighten($gray-base, 30%);\n$gray-800: #2f353a !default; // lighten($gray-base, 10%);\n$gray-900: #23282c !default; // lighten($gray-base, 5%);\n$black: #000 !default;\n\n$grays: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #20a8d8 !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #f86c6b !default;\n$orange: #f8cb00 !default;\n$yellow: #ffc107 !default;\n$green: #4dbd74 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n$light-blue: #63c2de !default;\n\n$colors: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"light-blue\": $light-blue,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-300 !default;\n$success: $green !default;\n$info: $light-blue !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Brand Colors\n\n$facebook: #3b5998 !default;\n$twitter: #00aced !default;\n$linkedin: #4875b4 !default;\n// $google-plus: #d34836 !default;\n$flickr: #ff0084 !default;\n$tumblr: #32506d !default;\n$xing: #026466 !default;\n$github: #4183c4 !default;\n// $html5: #e34f26 !default;\n// $openid: #f78c40 !default;\n$stack-overflow: #fe7a15 !default;\n$youtube: #b00 !default;\n// $css3: #0170ba !default;\n$dribbble: #ea4c89 !default;\n// $google-plus: #bb4b39 !default;\n$instagram: #517fa4 !default;\n$pinterest: #cb2027 !default;\n$vk: #45668e !default;\n$yahoo: #400191 !default;\n$behance: #1769ff !default;\n// $dropbox: #007ee5 !default;\n$reddit: #ff4500 !default;\n// $spotify: #7ab800 !default;\n// $vine: #00bf8f !default;\n// $foursquare: #1073af !default;\n$vimeo: #aad450 !default;\n\n$brands-colors: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$brands-colors: map-merge(\n (\n \"facebook\": $facebook,\n \"twitter\": $twitter,\n \"linkedin\": $linkedin,\n // \"google-plus\": $google-plus,\n \"flickr\": $flickr,\n \"tumblr\": $tumblr,\n \"xing\": $xing,\n \"github\": $github,\n // \"html5\": $html5,\n // \"openid\": $openid,\n \"stack-overflow\": $stack-overflow,\n \"youtube\": $youtube,\n // \"css3\": $css3,\n \"dribbble\": $dribbble,\n \"instagram\": $instagram,\n \"pinterest\": $pinterest,\n \"vk\": $vk,\n \"yahoo\": $yahoo,\n \"behance\": $behance,\n // \"dropbox\": $dropbox,\n \"reddit\": $reddit,\n // \"spotify\": $spotify,\n // \"vine\": $vine,\n // \"foursquare\": $foursquare,\n \"vimeo\": $vimeo\n ),\n $brands-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$prefix: c- !default; // CoreUI\n$bs-prefix: c- !default; // CoreUI\n$enable-rtl: true !default; // CoreUI\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n// CoreUI\n$enable-sidebar-nav-rounded: false !default;\n$layout-transition-speed: .25s !default;\n$default-themes: light, dark !default;\n$default-theme: light !default;\n$enable-elevation: false !default;\n$enable-prefers-color-scheme: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `` element.\n\n$body-bg: #e4e5e6 !default; // was: $white\n$body-color: $gray-900 !default;\n\n$body-dark-theme-bg: $gray-dark-theme-base !default;\n$body-dark-theme-color: #e1e1e1 !default;\n\n$body-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$body-theme-map: map-merge(\n (\n light: (\n \"body-bg\": #e4e5e6,\n \"body-color\": $gray-900\n ),\n dark: (\n \"body-bg\": $body-dark-theme-bg,\n \"body-color\": $body-dark-theme-color\n )\n ),\n $body-theme-map\n);\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n$link-dark-theme-color: $primary-50 !default;\n$link-dark-theme-hover-color: darken($link-dark-theme-color, 15%) !default;\n\n$link-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$link-theme-map: map-merge(\n (\n light: (\n \"link-color\": $link-color,\n \"link-hover-color\": $link-hover-color\n ),\n dark: (\n \"link-color\": $link-dark-theme-color,\n \"link-hover-color\": $link-dark-theme-hover-color\n )\n ),\n $link-theme-map\n);\n\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n$border-dark-theme-color: $gray-dark-theme-900 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-color: $body-color !default;\n$component-bg: $white !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$component-dark-theme-color: $body-dark-theme-color !default;\n$component-dark-theme-bg: $gray-dark-theme-800 !default;\n\n$component-dark-theme-active-color: $black !default;\n$component-dark-theme-active-bg: $primary-50 !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// TODO: Add elevation system\n// Elevation\n//\n// Define common box shadows.\n\n$elevations: (\n 0: none,\n 1: \"0 1px 1px 0 rgba(0, 0, 0, .14), 0 2px 1px -1px rgba(0, 0, 0, .12), 0 1px 3px 0 rgba(0, 0, 0, .20)\",\n 2: \"0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .12), 0 1px 5px 0 rgba(0, 0, 0, .20)\",\n 3: \"0 3px 4px 0 rgba(0, 0, 0, .14), 0 3px 3px -2px rgba(0, 0, 0, .12), 0 1px 8px 0 rgba(0, 0, 0, .20)\",\n 4: \"0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .20)\",\n 6: \"0 6px 10px 0 rgba(0, 0, 0, .14), 0 1px 18px 0 rgba(0, 0, 0, .12), 0 3px 5px -1px rgba(0, 0, 0, .20)\",\n 8: \"0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .20)\",\n 9: \"0 9px 12px 1px rgba(0, 0, 0, .14), 0 3px 16px 2px rgba(0, 0, 0, .12), 0 5px 6px -3px rgba(0, 0, 0, .20)\",\n 12: \"0 12px 17px 2px rgba(0, 0, 0, .14), 0 5px 22px 4px rgba(0, 0, 0, .12), 0 7px 8px -4px rgba(0, 0, 0, .20)\",\n 16: \"0 16px 24px 2px rgba(0, 0, 0, .14), 0 6px 30px 5px rgba(0, 0, 0, .12), 0 8px 10px -5px rgba(0, 0, 0, .20)\",\n 24: \"0 24px 38px 3px rgba(0, 0, 0, .14), 0 9px 46px 8px rgba(0, 0, 0, .12), 0 11px 15px -7px rgba(0, 0, 0, .20)\"\n) !default;\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: .875rem !default; // was: 1rem\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-700 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .2) !default;\n$hr-border-width: $border-width !default;\n\n$vr-color-bg: rgba($black, .2) !default;\n$vr-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n$table-dark-color: $white !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n$table-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$table-theme-map: map-merge(\n (\n \"light\": (\n \"table-color\": $gray-900,\n \"table-bg\": transparent,\n \"table-accent-bg\": rgba($black, .05),\n \"table-hover-color\": $gray-900,\n \"table-hover-bg\": rgba($black, .075),\n \"table-active-bg\": rgba($black, .075),\n \"table-border-color\": $border-color,\n \"table-head-bg\": $gray-200,\n \"table-head-color\": $gray-700\n ),\n \"dark\": (\n \"table-color\": $body-dark-theme-color,\n \"table-bg\": transparent,\n \"table-accent-bg\": rgba($white, .05),\n \"table-hover-color\": $body-dark-theme-color,\n \"table-hover-bg\": rgba($white, .075),\n \"table-active-bg\": rgba($white, .075),\n \"table-border-color\": $gray-900,\n \"table-head-bg\": $gray-800,\n \"table-head-color\": $body-dark-theme-color,\n )\n ),\n $table-theme-map\n);\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-200 !default; //was: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: calc(#{$input-line-height * 1em} + #{$input-padding-y * 2}) !default;\n$input-height-inner-half: calc(#{$input-line-height * .5em} + #{$input-padding-y}) !default;\n$input-height-inner-quarter: calc(#{$input-line-height * .25em} + #{$input-padding-y / 2}) !default;\n\n$input-height: calc(#{$input-line-height * 1em} + #{$input-padding-y * 2} + #{$input-height-border}) !default;\n$input-height-sm: calc(#{$input-line-height-sm * 1em} + #{$input-btn-padding-y-sm * 2} + #{$input-height-border}) !default;\n$input-height-lg: calc(#{$input-line-height-lg * 1em} + #{$input-btn-padding-y-lg * 2} + #{$input-height-border}) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-100 !default; // was: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: none !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: none !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: none !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: calc(#{$custom-control-indicator-size} - #{$custom-control-indicator-border-width * 4}) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$custom-select-background: $custom-select-indicator no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: calc((1em + #{2 * $custom-select-padding-y}) * 3 / 4 + #{$custom-select-padding-x + $custom-select-indicator-padding}) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n$form-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$form-theme-map: map-merge(\n (\n light: (\n \"input-bg\": $white,\n \"input-disabled-bg\": $gray-200,\n \"input-color\": $gray-700,\n \"input-border-color\": $gray-200,\n \"input-focus-bg\": $input-bg,\n \"input-focus-border-color\": lighten($component-active-bg, 25%),\n \"input-focus-color\": $input-color,\n \"input-placeholder-color\": $gray-600,\n \"input-plaintext-color\": $body-color,\n \"input-group-addon-color\": $input-color,\n \"input-group-addon-bg\": $gray-100,\n \"input-group-addon-border-color\": $input-border-color\n ),\n dark: (\n \"input-bg\": $gray-dark-theme-400,\n \"input-disabled-bg\": rgba($white, .12),\n \"input-color\": $gray-100,\n \"input-border-color\": $gray-dark-theme-400,\n \"input-focus-bg\": lighten($gray-dark-theme-400, 12%),\n \"input-focus-border-color\": lighten($gray-dark-theme-400, 12%),\n \"input-focus-color\": $gray-100,\n \"input-placeholder-color\": $gray-500,\n \"input-plaintext-color\": $body-dark-theme-color,\n \"input-group-addon-color\": $gray-100,\n \"input-group-addon-bg\": $gray-800,\n \"input-group-addon-border-color\": $gray-900\n )\n ),\n $form-theme-map\n);\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-feedback-icon-invalid-color}' viewBox='-2 -2 7 7'%3e%3cpath stroke='#{$form-feedback-icon-invalid-color}' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\"), \"#\", \"%23\") !default;\n\n$form-validation-states: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n$nav-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$nav-theme-map: map-merge(\n (\n light: (\n \"nav-link-disabled-color\": $gray-600,\n \"nav-tabs-border-color\": $gray-300,\n \"nav-tabs-link-hover-border-color\": $gray-200 $gray-200 $nav-tabs-border-color,\n \"nav-tabs-link-active-color\": $gray-700,\n \"nav-tabs-link-active-bg\": $body-bg,\n \"nav-tabs-link-active-border-color\": $gray-300 $gray-300 $nav-tabs-link-active-bg,\n \"nav-pills-link-active-color\": $component-active-color,\n \"nav-pills-link-active-bg\": $component-active-bg,\n \"nav-divider-color\": $gray-200\n ),\n dark: (\n \"nav-link-disabled-color\": $gray-900,\n \"nav-tabs-border-color\": $gray-900,\n \"nav-tabs-link-hover-border-color\": $gray-900 $gray-900 $gray-900,\n \"nav-tabs-link-active-color\": $body-dark-theme-color,\n \"nav-tabs-link-active-bg\": $gray-800,\n \"nav-tabs-link-active-border-color\": $gray-900 $gray-900 $gray-800,\n \"nav-pills-link-active-color\": $component-active-color,\n \"nav-pills-link-active-bg\": $component-active-bg,\n \"nav-divider-color\": $gray-200\n )\n ),\n $nav-theme-map\n);\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n// CoreUI specific changes start\n@import \"variables/header\";\n// Header\n// TODO: clean-up\n\n// $header-height: 55px !default;\n// // $header-bg: $white !default;\n// // $header-border: (\n// // bottom: 1px solid $border-color\n// // ) !default;\n// $header-brand-width: 205px !default;\n// $header-brand-minimized-width: 50px !default;\n\n// $header-padding-y: $spacer / 2 !default;\n// $header-padding-x: $spacer !default;\n\n// $header-nav-link-padding-x: .5rem !default;\n\n// $header-brand-font-size: $font-size-lg !default;\n// $header-brand-height: $header-brand-font-size * $line-height-base !default;\n// $header-brand-padding-y: ($nav-link-height - $header-brand-height) / 2 !default;\n\n// $header-toggler-bg: transparent !default;\n// $header-toggler-padding-y: .25rem !default;\n// $header-toggler-padding-x: .75rem !default;\n// $header-toggler-font-size: $font-size-lg !default;\n// $header-toggler-border: 0 !default;\n// $header-toggler-border-radius: $btn-border-radius !default;\n\n// $header-dark-bg: $gray-800 !default;\n// $header-dark-color: rgba($white, .75) !default;\n// $header-dark-border: (\n// bottom: 1px solid $gray-800\n// ) !default;\n// $header-dark-hover-color: rgba($white, .9) !default;\n// $header-dark-active-color: $white !default;\n// $header-dark-disabled-color: rgba($white, .25) !default;\n// $header-dark-toggler-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$header-dark-color}' stroke-width='2.25' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $header-dark-toggler-hover-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$header-dark-hover-color}' stroke-width='2.25' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $header-dark-toggler-border-color: rgba($white, .1) !default;\n\n// $header-light-bg: $white !default;\n// $header-light-color: rgba($black, .5) !default;\n// $header-light-border: (\n// bottom: 1px solid $border-color\n// ) !default;\n// $header-light-hover-color: rgba($black, .7) !default;\n// $header-light-active-color: rgba($black, .9) !default;\n// $header-light-disabled-color: rgba($black, .3) !default;\n// $header-light-toggler-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$header-light-color}' stroke-width='2.25' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $header-light-toggler-hover-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$header-light-hover-color}' stroke-width='2.25' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $header-light-toggler-border-color: rgba($black, .1) !default;\n\n// $header-light-brand-bg: transparent !default;\n// $header-light-brand-border: 0 !default;\n// $header-light-brand-color: $header-light-active-color !default;\n// $header-light-brand-hover-color: $header-light-active-color !default;\n// $header-light-brand-minimized-bg: transparent !default;\n// $header-light-brand-minimized-border: 0 !default;\n\n// $header-dark-brand-bg: transparent !default;\n// $header-dark-brand-border: 0 !default;\n// $header-dark-brand-color: $header-dark-active-color !default;\n// $header-dark-brand-hover-color: $header-dark-active-color !default;\n// $header-dark-brand-minimized-bg: transparent !default;\n// $header-dark-brand-minimized-border: 0 !default;\n\n// $header-variants-map: () !default;\n// // stylelint-disable-next-line scss/dollar-variable-default\n// $header-variants-map: map-merge(\n// (\n// dark: (\n// \"header-bg\": $header-dark-bg,\n// \"header-color\": $header-dark-color,\n// \"header-border\": $header-dark-border,\n// \"dark-theme-header-border\": 0,\n// \"header-hover-color\": $header-dark-hover-color,\n// \"header-active-color\": $header-dark-active-color,\n// \"header-disabled-color\": $header-dark-disabled-color,\n// \"header-toggler-icon-bg\": $header-dark-toggler-icon-bg,\n// \"header-toggler-hover-icon-bg\": $header-dark-toggler-hover-icon-bg,\n// \"header-toggler-border-color\": $header-dark-toggler-border-color,\n// \"header-brand-bg\": $header-dark-brand-bg,\n// \"header-brand-border\": $header-dark-brand-border,\n// \"header-brand-color\": $header-dark-brand-color,\n// \"header-brand-hover-color\": $header-dark-brand-hover-color,\n// \"header-brand-minimized-bg\": $header-dark-brand-minimized-bg,\n// \"header-brand-minimized-border\": $header-dark-brand-minimized-border\n// ),\n// light: (\n// \"header-bg\": $header-light-bg,\n// \"header-color\": $header-light-color,\n// \"header-border\": $header-light-border,\n// \"dark-theme-header-border\": 0,\n// \"header-hover-color\": $header-light-hover-color,\n// \"header-active-color\": $header-light-active-color,\n// \"header-disabled-color\": $header-light-disabled-color,\n// \"header-toggler-icon-bg\": $header-light-toggler-icon-bg,\n// \"header-toggler-hover-icon-bg\": $header-light-toggler-hover-icon-bg,\n// \"header-toggler-border-color\": $header-light-toggler-border-color,\n// \"header-brand-bg\": $header-light-brand-bg,\n// \"header-brand-border\": $header-light-brand-border,\n// \"header-brand-color\": $header-light-brand-color,\n// \"header-brand-hover-color\": $header-light-brand-hover-color,\n// \"header-brand-minimized-bg\": $header-light-brand-minimized-bg,\n// \"header-brand-minimized-border\": $header-light-brand-minimized-border\n// )\n// ),\n// $header-variants-map\n// );\n\n// $header-default-variant: \"light\" !default;\n// $header-variants: (\n// default: $header-default-variant,\n// map: $header-variants-map\n// ) !default;\n\n\n// // $header-color: $gray-600 !default;\n// // $header-hover-color: $gray-800 !default;\n// // $header-active-color: $gray-800 !default;\n// // TODO: Variable is not being used!\n// // $header-disabled-color: $gray-300 !default;\n\n\n// CoreUI specific changes end\n\n@import \"variables/sidebar\";\n// // Sidebar\n\n// $sidebar-width: 250px !default;\n// $sidebar-padding: 0 !default;\n// $sidebar-minimized-width: 50px !default;\n// $sidebar-minimized-height: $sidebar-minimized-width !default;\n// $sidebar-compact-width: 150px !default;\n\n// $sidebar-dark-color: $white !default;\n// $sidebar-dark-bg: $gray-800 !default;\n// $sidebar-dark-borders: none !default;\n\n// $sidebar-light-color: $body-color !default;\n// $sidebar-light-bg: $white !default;\n// $sidebar-light-borders: (\n// right: 1px solid rgba(darken($border-color, 20%), .5)\n// ) !default;\n\n// // Sidebar Brand\n\n// $sidebar-brand-height: 55px !default;\n\n// $sidebar-dark-brand-bg: rgba($black, .2) !default;\n// $sidebar-light-brand-bg: rgba($black, .2) !default;\n\n// // Sidebar Header\n\n// $sidebar-header-height: auto !default;\n// $sidebar-header-padding-y: .75rem !default;\n// $sidebar-header-padding-x: 1rem !default;\n\n// $sidebar-dark-header-bg: rgba($black, .2) !default;\n// $sidebar-light-header-bg: rgba($black, .2) !default;\n\n// // Sidebar Form\n\n// $sidebar-dark-form-border: 0 !default;\n// $sidebar-dark-form-bg: rgba($black, .1) !default;\n// $sidebar-dark-form-color: $white !default;\n// $sidebar-dark-form-placeholder-color: rgba($white, .7) !default;\n\n// $sidebar-light-form-border: 0 !default;\n// $sidebar-light-form-bg: rgba($black, .1) !default;\n// $sidebar-light-form-color: $white !default;\n// $sidebar-light-form-placeholder-color: rgba($white, .7) !default;\n\n\n// // Sidebar Navigation\n\n// $sidebar-nav-title-padding-y: .75rem !default;\n// $sidebar-nav-title-padding-x: 1rem !default;\n// $sidebar-nav-link-padding-y: .75rem !default;\n// $sidebar-nav-link-padding-x: 1rem !default;\n// $sidebar-nav-icon-width: 50px !default;\n\n// $sidebar-dark-nav-title-color: rgba($white, .6) !default;\n// $sidebar-dark-nav-link-color: rgba($white, .8) !default;\n// $sidebar-dark-nav-link-bg: transparent !default;\n// $sidebar-dark-nav-link-icon-color: $gray-600 !default;\n// $sidebar-dark-nav-link-borders: 0 !default;\n\n// $sidebar-light-nav-title-color: rgba($black, .4) !default;\n// $sidebar-light-nav-link-color: rgba($black, .8) !default;\n// $sidebar-light-nav-link-bg: transparent !default;\n// $sidebar-light-nav-link-icon-color: $gray-600 !default;\n// $sidebar-light-nav-link-borders: 0 !default;\n\n\n// $sidebar-dark-nav-link-hover-color: $white !default;\n// $sidebar-dark-nav-link-hover-bg: theme-color(\"primary\") !default;\n// $sidebar-dark-nav-link-hover-icon-color: $white !default;\n// $sidebar-dark-nav-link-hover-borders: 0 !default;\n\n// $sidebar-light-nav-link-hover-color: $white !default;\n// $sidebar-light-nav-link-hover-bg: theme-color(\"primary\") !default;\n// $sidebar-light-nav-link-hover-icon-color: $white !default;\n// $sidebar-light-nav-link-hover-borders: 0 !default;\n\n\n// $sidebar-dark-nav-link-active-color: $white !default;\n// $sidebar-dark-nav-link-active-bg: rgba($white, .05) !default;\n// $sidebar-dark-nav-link-active-icon-color: theme-color(\"primary\") !default;\n// $sidebar-dark-nav-link-active-borders: 0 !default;\n\n// $sidebar-light-nav-link-active-color: $white !default;\n// $sidebar-light-nav-link-active-bg: rgba($black, .05) !default;\n// $sidebar-light-nav-link-active-icon-color: theme-color(\"primary\") !default;\n// $sidebar-light-nav-link-active-borders: 0 !default;\n\n\n// $sidebar-dark-nav-link-disabled-color: darken($white, 30%) !default;\n// $sidebar-dark-nav-link-disabled-bg: $sidebar-dark-bg !default;\n// $sidebar-dark-nav-link-disabled-icon-color: $sidebar-dark-nav-link-icon-color !default;\n// $sidebar-dark-nav-link-disabled-borders: 0 !default;\n\n// $sidebar-light-nav-link-disabled-color: darken($white, 30%) !default;\n// $sidebar-light-nav-link-disabled-bg: $sidebar-light-bg !default;\n// $sidebar-light-nav-link-disabled-icon-color: $sidebar-light-nav-link-icon-color !default;\n// $sidebar-light-nav-link-disabled-borders: 0 !default;\n\n// $sidebar-dark-nav-dropdown-color: $white !default;\n// $sidebar-dark-nav-dropdown-bg: rgba(0, 0, 0, .2) !default;\n// $sidebar-dark-nav-dropdown-borders: 0 !default;\n// $sidebar-dark-nav-dropdown-indicator-color: $gray-600 !default;\n// $sidebar-dark-nav-dropdown-indicator: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-dark-nav-dropdown-indicator-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $sidebar-dark-nav-dropdown-indicator-hover-color: $sidebar-dark-nav-link-hover-color !default;\n// $sidebar-dark-nav-dropdown-indicator-hover: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-dark-nav-dropdown-indicator-hover-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n\n// $sidebar-light-nav-dropdown-color: $white !default;\n// $sidebar-light-nav-dropdown-bg: rgba(0, 0, 0, .2) !default;\n// $sidebar-light-nav-dropdown-borders: 0 !default;\n// $sidebar-light-nav-dropdown-indicator-color: $gray-600 !default;\n// $sidebar-light-nav-dropdown-indicator: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-light-nav-dropdown-indicator-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $sidebar-light-nav-dropdown-indicator-hover-color: $sidebar-dark-nav-link-hover-color !default;\n// $sidebar-light-nav-dropdown-indicator-hover: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-light-nav-dropdown-indicator-hover-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n\n// // Sidebar Tabs\n\n// $sidebar-nav-tabs-link-padding-y: .75rem !default;\n// $sidebar-nav-tabs-link-padding-x: 1rem !default;\n\n// $sidebar-dark-nav-tabs-border-color: rgba($black, .2) !default;\n// $sidebar-dark-nav-tabs-link-active-bg: rgba($white, .05) !default;\n// $sidebar-dark-nav-tabs-link-active-border-color: rgba($black, .2) rgba($black, .2) theme-color(\"primary\") !default;\n// $sidebar-dark-nav-tabs-link-hover-bg: rgba($black, .2) !default;\n// $sidebar-dark-nav-tabs-link-hover-border-color: rgba($black, .2) rgba($black, .2) $gray-200 !default;\n// $sidebar-dark-tab-content-borders: (\n// top: 1px solid rgba($black, .2)\n// ) !default;\n\n// $sidebar-light-nav-tabs-border-color: rgba(darken($border-color, 20%), .5) !default;\n// $sidebar-light-nav-tabs-link-active-bg: $white !default;\n// $sidebar-light-nav-tabs-link-active-border-color: rgba(darken($border-color, 20%), .5) rgba(darken($border-color, 20%), .5) $white !default;\n// $sidebar-light-nav-tabs-link-hover-bg: $white !default;\n// $sidebar-light-nav-tabs-link-hover-border-color: rgba(darken($border-color, 20%), .5) rgba(darken($border-color, 20%), .5) $white !default;\n// $sidebar-light-tab-content-borders: (\n// top: 1px solid rgba(darken($border-color, 20%), .5)\n// ) !default;\n\n// // Sidebar Footer\n\n// $sidebar-footer-height: auto !default;\n// $sidebar-footer-padding-y: .75rem !default;\n// $sidebar-footer-padding-x: 1rem !default;\n\n// $sidebar-dark-footer-bg: rgba($black, .2) !default;\n// $sidebar-dark-footer-borders: 0 !default;\n// $sidebar-light-footer-bg: rgba($black, .2) !default;\n// $sidebar-light-footer-borders: 0 !default;\n\n// // Sidebar Minimizer\n\n// $sidebar-minimizer-height: 50px !default;\n\n// $sidebar-dark-minimizer-borders: 0 !default;\n// $sidebar-dark-minimizer-bg: rgba($black, .2) !default;\n// $sidebar-dark-minimizer-indicator-color: $gray-600 !default;\n// $sidebar-dark-minimizer-indicator: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-dark-minimizer-indicator-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $sidebar-dark-minimizer-hover-bg: rgba(0, 0, 0, .3) !default;\n// $sidebar-dark-minimizer-hover-indicator-color: $sidebar-dark-nav-link-hover-color !default;\n// $sidebar-dark-minimizer-hover-indicator: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-dark-minimizer-hover-indicator-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n\n// $sidebar-light-minimizer-borders: 0 !default;\n// $sidebar-light-minimizer-bg: rgba($black, .2) !default;\n// $sidebar-light-minimizer-indicator-color: $gray-600 !default;\n// $sidebar-light-minimizer-indicator: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-light-minimizer-indicator-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n// $sidebar-light-minimizer-hover-bg: rgba(0, 0, 0, .3) !default;\n// $sidebar-light-minimizer-hover-indicator-color: $sidebar-dark-nav-link-hover-color !default;\n// $sidebar-light-minimizer-hover-indicator: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-light-minimizer-hover-indicator-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n\n// $sidebar-variants-map: () !default;\n// // stylelint-disable-next-line scss/dollar-variable-default\n// $sidebar-variants-map: map-merge(\n// (\n// dark: (\n// \"sidebar-color\": $sidebar-dark-color,\n// \"sidebar-bg\": $sidebar-dark-bg,\n// \"dark-theme-sidebar-bg\": 0,\n// \"sidebar-borders\": $sidebar-dark-borders,\n// \"dark-theme-sidebar-borders\": 0,\n// \"sidebar-brand-bg\": $sidebar-dark-brand-bg,\n// \"sidebar-header-bg\": $sidebar-dark-header-bg,\n// \"sidebar-form-border\": $sidebar-dark-form-border,\n// \"sidebar-form-bg\": $sidebar-dark-form-bg,\n// \"sidebar-form-color\": $sidebar-dark-form-color,\n// \"sidebar-form-placeholder-color\": $sidebar-dark-form-placeholder-color,\n// \"sidebar-nav-title-color\": $sidebar-dark-nav-title-color,\n// \"sidebar-nav-link-color\": $sidebar-dark-nav-link-color,\n// \"sidebar-nav-link-bg\": $sidebar-dark-nav-link-bg,\n// \"sidebar-nav-link-icon-color\": $sidebar-dark-nav-link-icon-color,\n// \"sidebar-nav-link-borders\": $sidebar-dark-nav-link-borders,\n// \"sidebar-nav-link-hover-color\": $sidebar-dark-nav-link-hover-color,\n// \"sidebar-nav-link-hover-bg\": $sidebar-dark-nav-link-hover-bg,\n// \"sidebar-nav-link-hover-icon-color\": $sidebar-dark-nav-link-hover-icon-color,\n// \"sidebar-nav-link-hover-borders\": $sidebar-dark-nav-link-hover-borders,\n// \"sidebar-nav-link-active-color\": $sidebar-dark-nav-link-active-color,\n// \"sidebar-nav-link-active-bg\": $sidebar-dark-nav-link-active-bg,\n// \"sidebar-nav-link-active-icon-color\": $sidebar-dark-nav-link-active-icon-color,\n// \"sidebar-nav-link-active-borders\": $sidebar-dark-nav-link-active-borders,\n// \"sidebar-nav-link-disabled-color\": $sidebar-dark-nav-link-disabled-color,\n// \"sidebar-nav-link-disabled-bg\": $sidebar-dark-nav-link-disabled-bg,\n// \"sidebar-nav-link-disabled-icon-color\": $sidebar-dark-nav-link-disabled-icon-color,\n// \"sidebar-nav-link-disabled-borders\": $sidebar-dark-nav-link-disabled-borders,\n// \"sidebar-nav-dropdown-color\": $sidebar-dark-nav-dropdown-color,\n// \"sidebar-nav-dropdown-bg\": $sidebar-dark-nav-dropdown-bg,\n// \"sidebar-nav-dropdown-borders\": $sidebar-dark-nav-dropdown-borders,\n// \"sidebar-nav-dropdown-indicator-color\": $sidebar-dark-nav-dropdown-indicator-color,\n// \"sidebar-nav-dropdown-indicator\": $sidebar-dark-nav-dropdown-indicator,\n// \"sidebar-nav-dropdown-indicator-hover-color\": $sidebar-dark-nav-dropdown-indicator-hover-color,\n// \"sidebar-nav-dropdown-indicator-hover\": $sidebar-dark-nav-dropdown-indicator-hover,\n// \"sidebar-nav-tabs-border-color\": $sidebar-dark-nav-tabs-border-color,\n// \"sidebar-nav-tabs-link-active-bg\": $sidebar-dark-nav-tabs-link-active-bg,\n// \"sidebar-nav-tabs-link-active-border-color\": $sidebar-dark-nav-tabs-link-active-border-color,\n// \"sidebar-nav-tabs-link-hover-bg\": $sidebar-dark-nav-tabs-link-hover-bg,\n// \"sidebar-nav-tabs-link-hover-border-color\": $sidebar-dark-nav-tabs-link-hover-border-color,\n// \"sidebar-tab-content-borders\": $sidebar-dark-tab-content-borders,\n// \"sidebar-footer-bg\": $sidebar-dark-footer-bg,\n// \"sidebar-footer-borders\": $sidebar-dark-footer-borders,\n// \"sidebar-minimizer-borders\": $sidebar-dark-minimizer-borders,\n// \"sidebar-minimizer-bg\": $sidebar-dark-minimizer-bg,\n// \"sidebar-minimizer-indicator-color\": $sidebar-dark-minimizer-indicator-color,\n// \"sidebar-minimizer-indicator\": $sidebar-dark-minimizer-indicator,\n// \"sidebar-minimizer-hover-bg\": $sidebar-dark-minimizer-hover-bg,\n// \"sidebar-minimizer-hover-indicator-color\": $sidebar-dark-minimizer-hover-indicator-color,\n// \"sidebar-minimizer-hover-indicator\": $sidebar-dark-minimizer-hover-indicator\n// ),\n// light: (\n// \"sidebar-color\": $sidebar-light-color,\n// \"sidebar-bg\": $sidebar-light-bg,\n// \"dark-theme-sidebar-bg\": 0,\n// \"sidebar-borders\": $sidebar-light-borders,\n// \"dark-theme-sidebar-borders\": 0,\n// \"sidebar-brand-bg\": $sidebar-light-brand-bg,\n// \"sidebar-header-bg\": $sidebar-light-header-bg,\n// \"sidebar-form-border\": $sidebar-light-form-border,\n// \"sidebar-form-bg\": $sidebar-light-form-bg,\n// \"sidebar-form-color\": $sidebar-light-form-color,\n// \"sidebar-form-placeholder-color\": $sidebar-light-form-placeholder-color,\n// \"sidebar-nav-title-color\": $sidebar-light-nav-title-color,\n// \"sidebar-nav-link-color\": $sidebar-light-nav-link-color,\n// \"sidebar-nav-link-bg\": $sidebar-light-nav-link-bg,\n// \"sidebar-nav-link-icon-color\": $sidebar-light-nav-link-icon-color,\n// \"sidebar-nav-link-borders\": $sidebar-light-nav-link-borders,\n// \"sidebar-nav-link-hover-color\": $sidebar-light-nav-link-hover-color,\n// \"sidebar-nav-link-hover-bg\": $sidebar-light-nav-link-hover-bg,\n// \"sidebar-nav-link-hover-icon-color\": $sidebar-light-nav-link-hover-icon-color,\n// \"sidebar-nav-link-hover-borders\": $sidebar-light-nav-link-hover-borders,\n// \"sidebar-nav-link-active-color\": $sidebar-light-nav-link-active-color,\n// \"sidebar-nav-link-active-bg\": $sidebar-light-nav-link-active-bg,\n// \"sidebar-nav-link-active-icon-color\": $sidebar-light-nav-link-active-icon-color,\n// \"sidebar-nav-link-active-borders\": $sidebar-light-nav-link-active-borders,\n// \"sidebar-nav-link-disabled-color\": $sidebar-light-nav-link-disabled-color,\n// \"sidebar-nav-link-disabled-bg\": $sidebar-light-nav-link-disabled-bg,\n// \"sidebar-nav-link-disabled-icon-color\": $sidebar-light-nav-link-disabled-icon-color,\n// \"sidebar-nav-link-disabled-borders\": $sidebar-light-nav-link-disabled-borders,\n// \"sidebar-nav-dropdown-color\": $sidebar-light-nav-dropdown-color,\n// \"sidebar-nav-dropdown-bg\": $sidebar-light-nav-dropdown-bg,\n// \"sidebar-nav-dropdown-borders\": $sidebar-light-nav-dropdown-borders,\n// \"sidebar-nav-dropdown-indicator-color\": $sidebar-light-nav-dropdown-indicator-color,\n// \"sidebar-nav-dropdown-indicator\": $sidebar-light-nav-dropdown-indicator,\n// \"sidebar-nav-dropdown-indicator-hover-color\": $sidebar-light-nav-dropdown-indicator-hover-color,\n// \"sidebar-nav-dropdown-indicator-hover\": $sidebar-light-nav-dropdown-indicator-hover,\n// \"sidebar-nav-tabs-border-color\": $sidebar-light-nav-tabs-border-color,\n// \"sidebar-nav-tabs-link-active-bg\": $sidebar-light-nav-tabs-link-active-bg,\n// \"sidebar-nav-tabs-link-active-border-color\": $sidebar-light-nav-tabs-link-active-border-color,\n// \"sidebar-nav-tabs-link-hover-bg\": $sidebar-light-nav-tabs-link-hover-bg,\n// \"sidebar-nav-tabs-link-hover-border-color\": $sidebar-light-nav-tabs-link-hover-border-color,\n// \"sidebar-tab-content-borders\": $sidebar-light-tab-content-borders,\n// \"sidebar-footer-bg\": $sidebar-light-footer-bg,\n// \"sidebar-footer-borders\": $sidebar-light-footer-borders,\n// \"sidebar-minimizer-borders\": $sidebar-light-minimizer-borders,\n// \"sidebar-minimizer-bg\": $sidebar-light-minimizer-bg,\n// \"sidebar-minimizer-indicator-color\": $sidebar-light-minimizer-indicator-color,\n// \"sidebar-minimizer-indicator\": $sidebar-light-minimizer-indicator,\n// \"sidebar-minimizer-hover-bg\": $sidebar-light-minimizer-hover-bg,\n// \"sidebar-minimizer-hover-indicator-color\": $sidebar-light-minimizer-hover-indicator-color,\n// \"sidebar-minimizer-hover-indicator\": $sidebar-light-minimizer-hover-indicator,\n// )\n// ),\n// $sidebar-variants-map\n// );\n\n// $sidebar-default-variant: \"dark\" !default;\n// $sidebar-variants: (\n// map: $sidebar-variants-map,\n// default: $sidebar-default-variant\n// ) !default;\n\n\n@import \"variables/footer\";\n// Footer\n\n// $footer-height: 50px !default;\n\n// $footer-dark-bg: $gray-800 !default;\n// $footer-dark-color: $dark-theme-body-color !default;\n// $footer-dark-borders: ( top: 1px solid $border-dark-theme-color ) !default;\n\n// $footer-light-bg: $gray-100 !default;\n// $footer-light-color: $body-color !default;\n// $footer-light-borders: ( top: 1px solid $border-color ) !default;\n\n// $footer-variants-map: () !default;\n// // stylelint-disable-next-line scss/dollar-variable-default\n// $footer-variants-map: map-merge(\n// (\n// dark: (\n// \"footer-bg\": $footer-dark-bg,\n// \"footer-color\": $footer-dark-color,\n// \"footer-borders\": $footer-dark-borders\n// ),\n// light: (\n// \"footer-bg\": $footer-light-bg,\n// \"footer-color\": $footer-light-color,\n// \"footer-borders\": $footer-light-borders\n// )\n// ),\n// $footer-variants-map\n// );\n\n// $footer-default-variant: \"light\" !default;\n// $footer-variants: (\n// \"default\": $footer-default-variant,\n// \"map\": $footer-variants-map\n// ) !default;\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-y: .5rem !default; // was: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: calc(#{$dropdown-border-radius} - #{$dropdown-border-width}) !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n$dropdown-item-padding-y: .5rem !default;\n$dropdown-item-padding-x: 1.25rem !default;\n\n// Default theme\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: $border-color !default; // was: rgba($black, .15) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-100 !default;\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n$dropdown-link-disabled-color: $gray-600 !default;\n$dropdown-header-color: $gray-600 !default;\n\n// Dark theme\n$dropdown-dark-color: $body-dark-theme-color !default;\n$dropdown-dark-bg: $gray-dark-theme-200 !default;\n$dropdown-dark-border-color: $border-dark-theme-color !default; // was: rgba($black, .15) !default;\n$dropdown-dark-divider-bg: $gray-800 !default;\n$dropdown-dark-link-color: $body-dark-theme-color !default;\n$dropdown-dark-link-hover-color: $body-dark-theme-color !default;\n$dropdown-dark-link-hover-bg: $gray-900 !default;\n$dropdown-dark-link-active-color: $component-active-color !default;\n$dropdown-dark-link-active-bg: $component-active-bg !default;\n$dropdown-dark-link-disabled-color: $gray-600 !default;\n$dropdown-dark-header-color: $gray-200 !default;\n\n$dropdown-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$dropdown-theme-map: map-merge(\n (\n light: (\n \"dropdown-color\": $dropdown-color,\n \"dropdown-border-color\": $dropdown-border-color,\n \"dropdown-bg\": $dropdown-bg,\n \"dropdown-divider-bg\": $dropdown-divider-bg,\n \"dropdown-link-color\": $dropdown-link-color,\n \"dropdown-link-hover-color\": $dropdown-link-hover-color,\n \"dropdown-link-hover-bg\": $dropdown-link-hover-bg,\n \"dropdown-link-active-color\": $dropdown-link-active-color,\n \"dropdown-link-active-bg\": $dropdown-link-active-bg,\n \"dropdown-link-disabled-color\": $dropdown-link-disabled-color,\n \"dropdown-header-color\": $dropdown-header-color\n ),\n dark: (\n \"dropdown-color\": $dropdown-dark-color,\n \"dropdown-border-color\": $dropdown-dark-border-color,\n \"dropdown-bg\": $dropdown-dark-bg,\n \"dropdown-divider-bg\": $dropdown-dark-divider-bg,\n \"dropdown-link-color\": $dropdown-dark-link-color,\n \"dropdown-link-hover-color\": $dropdown-dark-link-hover-color,\n \"dropdown-link-hover-bg\": $dropdown-dark-link-hover-bg,\n \"dropdown-link-active-color\": $dropdown-dark-link-active-color,\n \"dropdown-link-active-bg\": $dropdown-dark-link-active-bg,\n \"dropdown-link-disabled-color\": $dropdown-dark-link-disabled-color,\n \"dropdown-header-color\": $dropdown-header-color\n )\n ),\n $dropdown-theme-map\n);\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n$pagination-border-width: $border-width !default;\n\n// Default theme\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-color: $border-color !default;\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n// Dark theme\n$pagination-dark-color: $link-color !default;\n$pagination-dark-bg: $gray-800 !default;\n$pagination-dark-border-color: $border-dark-theme-color !default;\n$pagination-dark-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-dark-focus-outline: 0 !default;\n$pagination-dark-hover-color: $link-hover-color !default;\n$pagination-dark-hover-bg: $gray-900 !default;\n$pagination-dark-hover-border-color: $gray-900 !default;\n$pagination-dark-active-color: $component-dark-theme-active-color !default;\n$pagination-dark-active-bg: $component-dark-theme-active-bg !default;\n$pagination-dark-active-border-color: $pagination-active-bg !default;\n$pagination-dark-disabled-color: $gray-600 !default;\n$pagination-dark-disabled-bg: $gray-900 !default;\n$pagination-dark-disabled-border-color: $gray-900 !default;\n\n$pagination-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$pagination-theme-map: map-merge(\n (\n light: (\n \"pagination-color\": $link-color,\n \"pagination-bg\": $white,\n \"pagination-border-color\": $gray-300,\n \"pagination-focus-box-shadow\": $input-btn-focus-box-shadow,\n \"pagination-focus-outline\": 0,\n \"pagination-hover-color\": $link-hover-color,\n \"pagination-hover-bg\": $gray-200,\n \"pagination-hover-border-color\": $gray-300,\n \"pagination-active-color\": $component-active-color,\n \"pagination-active-bg\": $component-active-bg,\n \"pagination-active-border-color\": $pagination-active-bg,\n \"pagination-disabled-color\": $gray-600,\n \"pagination-disabled-bg\": $white,\n \"pagination-disabled-border-color\": $gray-300\n ),\n dark: (\n \"pagination-color\": $link-dark-theme-color,\n \"pagination-bg\": $gray-800,\n \"pagination-border-color\": $gray-900,\n \"pagination-focus-box-shadow\": $input-btn-focus-box-shadow,\n \"pagination-focus-outline\": 0,\n \"pagination-hover-color\": $link-hover-color,\n \"pagination-hover-bg\": $gray-900,\n \"pagination-hover-border-color\": $gray-900,\n \"pagination-active-color\": $component-active-color,\n \"pagination-active-bg\": $component-active-bg,\n \"pagination-active-border-color\": $pagination-active-bg,\n \"pagination-disabled-color\": $gray-600,\n \"pagination-disabled-bg\": $gray-900,\n \"pagination-disabled-border-color\": $gray-900\n )\n ),\n $pagination-theme-map\n);\n\n\n//\n// Cards\n//\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width}) !default;\n$card-margin-bottom: $spacer * 1.5 !default; // CoreUI\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n$card-icon-bg: transparent !default;\n$card-icon-color: $body-color !default;\n\n// Default theme\n$card-border-color: $border-color !default; // was: rgba($black, .125) !default;\n$card-cap-bg: $gray-100 !default; // was: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n// Dark theme\n$card-dark-border-color: $border-dark-theme-color !default;\n$card-dark-cap-bg: $gray-dark-theme-700 !default;\n$card-dark-cap-color: null !default;\n$card-dark-color: null !default;\n$card-dark-bg: $gray-dark-theme-600 !default;\n\n$card-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$card-theme-map: map-merge(\n (\n light: (\n \"card-border-color\": $card-border-color,\n \"card-cap-bg\": $card-cap-bg,\n \"card-cap-color\": $card-cap-color,\n \"card-color\": $card-color,\n \"card-bg\": $card-bg\n ),\n dark: (\n \"card-border-color\": $card-dark-border-color,\n \"card-cap-bg\": $card-dark-cap-bg,\n \"card-cap-color\": $card-dark-cap-color,\n \"card-color\": $card-dark-color,\n \"card-bg\": $card-dark-bg\n )\n ),\n $card-theme-map\n);\n\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n\n// Default theme\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n// Dark theme\n$jumbotron-dark-color: null !default;\n$jumbotron-dark-bg: $gray-900 !default;\n\n$jumbotron-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$jumbotron-theme-map: map-merge(\n (\n light: (\n \"jumbotron-color\": $jumbotron-color,\n \"jumbotron-bg\": $jumbotron-bg\n ),\n dark: (\n \"jumbotron-color\": $jumbotron-dark-color,\n \"jumbotron-bg\": $jumbotron-dark-bg\n )\n ),\n $jumbotron-theme-map\n);\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n\n// Default theme\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n\n// Dark theme\n$modal-dark-theme-content-color: null !default;\n$modal-dark-theme-content-bg: $gray-dark-theme-400 !default;\n$modal-dark-theme-content-border-color: $gray-dark-theme-400 !default;\n$modal-dark-theme-header-border-color: $gray-dark-theme-400 !default;\n$modal-dark-theme-footer-border-color: $gray-dark-theme-400 !default;\n\n\n$modal-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$modal-theme-map: map-merge(\n (\n light: (\n \"modal-content-color\": $modal-content-color,\n \"modal-content-bg\": $modal-content-bg,\n \"modal-content-border-color\": $modal-content-border-color,\n \"modal-header-border-color\": $modal-header-border-color,\n \"modal-footer-border-color\": $modal-footer-border-color,\n ),\n dark: (\n \"modal-content-color\": $modal-dark-theme-content-color,\n \"modal-content-bg\": $modal-dark-theme-content-bg,\n \"modal-content-border-color\": $modal-dark-theme-content-border-color,\n \"modal-header-border-color\": $modal-dark-theme-header-border-color,\n \"modal-footer-border-color\": $modal-dark-theme-footer-border-color\n )\n ),\n $modal-theme-map\n);\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n// Default theme\n$progress-bg: $gray-100 !default; // was: $gray-200 !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n\n// Dark theme\n$progress-dark-bg: $gray-700 !default;\n$progress-dark-bar-color: $white !default;\n$progress-dark-bar-bg: theme-color(\"primary\") !default;\n\n$progress-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$progress-theme-map: map-merge(\n (\n light: (\n \"progress-bg\": $progress-bg,\n \"progress-bar-color\": $progress-bar-color,\n \"progress-bar-bg\": $progress-bar-bg\n ),\n dark: (\n \"progress-bg\": $progress-dark-bg,\n \"progress-bar-color\": $progress-dark-bar-color,\n \"progress-bar-bg\": $progress-dark-bar-bg\n )\n ),\n $progress-theme-map\n);\n\n\n// List group\n\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n// Default theme\n$list-group-color: null !default;\n$list-group-bg: inherit !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n// Dark theme\n$list-group-dark-color: $body-dark-theme-color !default;\n$list-group-dark-bg: inherit !default;\n$list-group-dark-border-color: $border-dark-theme-color !default;\n$list-group-dark-hover-bg: $gray-800 !default;\n$list-group-dark-active-color: $component-active-color !default;\n$list-group-dark-active-bg: $component-active-bg !default;\n$list-group-dark-active-border-color: $list-group-dark-active-bg !default;\n$list-group-dark-disabled-color: $gray-600 !default;\n$list-group-dark-disabled-bg: $gray-800 !default;\n$list-group-dark-action-color: $body-dark-theme-color !default;\n$list-group-dark-action-hover-color: $body-dark-theme-color !default;\n$list-group-dark-action-active-color: $body-dark-theme-color !default;\n$list-group-dark-action-active-bg: $gray-900 !default;\n\n$list-group-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$list-group-theme-map: map-merge(\n (\n light: (\n \"list-group-color\": $list-group-color,\n \"list-group-bg\": $list-group-bg,\n \"list-group-border-color\": $list-group-border-color,\n \"list-group-hover-bg\": $list-group-hover-bg,\n \"list-group-active-color\": $list-group-active-color,\n \"list-group-active-bg\": $list-group-active-bg,\n \"list-group-active-border-color\": $list-group-active-border-color,\n \"list-group-disabled-color\": $list-group-disabled-color,\n \"list-group-disabled-bg\": $list-group-disabled-bg,\n \"list-group-action-color\": $list-group-action-color,\n \"list-group-action-hover-color\": $list-group-action-hover-color,\n \"list-group-action-active-color\": $list-group-action-active-color,\n \"list-group-action-active-bg\": $list-group-action-active-bg,\n ),\n dark: (\n \"list-group-color\": $list-group-dark-color,\n \"list-group-bg\": $list-group-dark-bg,\n \"list-group-border-color\": $list-group-dark-border-color,\n \"list-group-hover-bg\": $list-group-dark-hover-bg,\n \"list-group-active-color\": $list-group-dark-active-color,\n \"list-group-active-bg\": $list-group-dark-active-bg,\n \"list-group-active-border-color\": $list-group-dark-active-border-color,\n \"list-group-disabled-color\": $list-group-dark-disabled-color,\n \"list-group-disabled-bg\": $list-group-dark-disabled-bg,\n \"list-group-action-color\": $list-group-dark-action-color,\n \"list-group-action-hover-color\": $list-group-dark-action-hover-color,\n \"list-group-action-active-color\": $list-group-dark-action-active-color,\n \"list-group-action-active-bg\": $list-group-dark-action-active-bg\n )\n ),\n $list-group-theme-map\n);\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1.5rem !default; // was: 1rem\n\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: 0 !default; // was: $border-radius\n\n$breadcrumb-borders: (\n bottom: 1px solid\n) !default;\n\n// Default theme\n$breadcrumb-bg: $white !default; // was: $gray-200\n$breadcrumb-border-color: $border-color !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n\n// Dark theme\n$breadcrumb-dark-bg: $component-dark-theme-bg !default;\n$breadcrumb-dark-border-color: $component-dark-theme-bg !default;\n$breadcrumb-dark-divider-color: $body-dark-theme-color !default;\n$breadcrumb-dark-active-color: $gray-600 !default;\n\n$breadcrumb-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$breadcrumb-theme-map: map-merge(\n (\n light: (\n \"breadcrumb-bg\": $breadcrumb-bg,\n \"breadcrumb-border-color\": $breadcrumb-border-color,\n \"breadcrumb-divider-color\": $breadcrumb-divider-color,\n \"breadcrumb-active-color\": $breadcrumb-active-color\n ),\n dark: (\n \"breadcrumb-bg\": $breadcrumb-dark-bg,\n \"breadcrumb-border-color\": $breadcrumb-dark-border-color,\n \"breadcrumb-divider-color\": $breadcrumb-dark-divider-color,\n \"breadcrumb-active-color\": $breadcrumb-dark-active-color\n )\n ),\n $breadcrumb-theme-map\n);\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$carousel-control-next-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// CoreUI specific changes start\n// Avatars\n\n$avatar-width: 36px !default;\n$avatar-status-width: 10px !default;\n\n$avatar-lg-width: 72px !default;\n$avatar-lg-status-width: 12px !default;\n\n$avatar-sm-width: 24px !default;\n$avatar-sm-status-width: 8px !default;\n\n$avatar-xs-width: 20px !default;\n$avatar-xs-status-width: 8px !default;\n\n\n// Switches\n\n$switch-width: 40px !default;\n$switch-height: 26px !default;\n$switch-font-size: 10px !default;\n\n$switch-lg-width: 48px !default;\n$switch-lg-height: 30px !default;\n$switch-lg-font-size: 12px !default;\n\n$switch-sm-width: 32px !default;\n$switch-sm-height: 22px !default;\n$switch-sm-font-size: 8px !default;\n\n$switch-label-width: 48px !default;\n$switch-label-lg-width: 56px !default;\n$switch-label-sm-width: 40px !default;\n\n$switch-handle-margin: 2px !default;\n// CoreUI specific changes end\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n\n// Cursor\n$cursor-disabled: default !default;\n","// stylelint-disable property-blacklist\n// Single side border-radius\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: $radius;\n }\n}\n"]} \ No newline at end of file diff --git a/custom-tooltips/dist/css/coreui-chartjs.min.css.map b/custom-tooltips/dist/css/coreui-chartjs.min.css.map deleted file mode 100644 index 845c7db..0000000 --- a/custom-tooltips/dist/css/coreui-chartjs.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["../../scss/style.scss","../../scss/_tooltips.scss","../../node_modules/@coreui/coreui/scss/mixins/_border-radius.scss"],"names":[],"mappings":"iBAAA;;;;;;ACEA,mBACE,SAAA,SACA,QAAA,KACA,QAAA,YAAA,QAAA,KACA,mBAAA,OAAA,eAAA,OACA,QAAA,OAAA,MACA,MAAA,KACA,eAAA,KACA,WAAA,eACA,QAAA,EACA,WAAA,IAAA,KAAA,KACA,kBAAA,kBAAA,UAAA,kBCRE,cAAA,ODHJ,qCAeI,cAAA,MAfJ,0CAmBI,UAAA,WACA,YAAA,IApBJ,wCAwBI,QAAA,YAAA,QAAA,KACA,eAAA,OAAA,YAAA,OACA,UAAA,WACA,YAAA,OA3BJ,8CA+BI,QAAA,aACA,MAAA,QACA,OAAA,QACA,aAAA,QAlCJ,8CAsCI,aAAA,KACA,YAAA,KACA,YAAA","sourcesContent":["/*!\n * CoreUI Plugins - Chart.js for CoreUI 3\n * @version v2.0.0-alpha.0\n * @link https://coreui.io\n * Copyright (c) 2019 creativeLabs Łukasz Holeczek\n * Licensed under MIT (https://coreui.io/license/plugins/chart.js)\n */\n\n@import \"variables\";\n@import \"tooltips\";\n","// Custom tooltips\n\n.#{$prefix}chartjs-tooltip {\n position: absolute;\n z-index: $zindex-sticky + 1;\n display: flex;\n flex-direction: column;\n padding: ($spacer * .25) ($spacer * .5);\n color: #fff;\n pointer-events: none;\n background: rgba(0, 0, 0, .7);\n opacity: 0;\n transition: all $layout-transition-speed ease;\n transform: translate(-50%, 0);\n @include border-radius($border-radius);\n\n .#{$prefix}tooltip-header {\n margin-bottom: ($spacer * .5);\n }\n\n .#{$prefix}tooltip-header-item {\n font-size: $font-size-sm;\n font-weight: $font-weight-bold;\n }\n\n .#{$prefix}tooltip-body-item {\n display: flex;\n align-items: center;\n font-size: $font-size-sm;\n white-space: nowrap;\n }\n\n .#{$prefix}tooltip-body-item-color {\n display: inline-block;\n width: $font-size-base;\n height: $font-size-base;\n margin-right: $font-size-base;\n }\n\n .#{$prefix}tooltip-body-item-value {\n padding-left: $spacer;\n margin-left: auto;\n font-weight: $font-weight-bold;\n }\n}\n","// stylelint-disable property-blacklist\n// Single side border-radius\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: $radius;\n }\n}\n"]} \ No newline at end of file diff --git a/custom-tooltips/dist/js/coreui-chartjs.bundle.js b/custom-tooltips/dist/js/coreui-chartjs.bundle.js deleted file mode 100644 index d7822b9..0000000 --- a/custom-tooltips/dist/js/coreui-chartjs.bundle.js +++ /dev/null @@ -1,163 +0,0 @@ -/*! - * CoreUI Plugins - Chart.js for CoreUI 3 v2.0.0-alpha.1 (https://coreui.io) - * Copyright 2019 Łukasz Holeczek - * Licensed under MIT (https://coreui.io/plugins/chart.js) - */ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = global || self, (global.coreui = global.coreui || {}, global.coreui.ChartJS = factory())); -}(this, function () { 'use strict'; - - /** - * -------------------------------------------------------------------------- - * Custom Tooltips for Chart.js (v2.0.0-alpha.0): custom-tooltips.js - * Licensed under MIT (https://coreui.io/plugins/chart.js) - * -------------------------------------------------------------------------- - */ - function customTooltips(tooltipModel) { - var _this = this; - - // Add unique id if not exist - var _setCanvasId = function _setCanvasId() { - var _idMaker = function _idMaker() { - var _hex = 16; - var _multiplier = 0x10000; - return ((1 + Math.random()) * _multiplier | 0).toString(_hex); - }; - - var _canvasId = "_canvas-" + (_idMaker() + _idMaker()); - - _this._chart.canvas.id = _canvasId; - return _canvasId; - }; // eslint-disable-next-line no-nested-ternary - - - var PREFIX = window.CoreUIDefaults ? window.CoreUIDefaults.prefix ? window.CoreUIDefaults.prefix : 'c-' : 'c-'; - var ClassName = { - ABOVE: PREFIX + "above", - BELOW: PREFIX + "below", - CHARTJS_TOOLTIP: PREFIX + "chartjs-tooltip", - NO_TRANSFORM: PREFIX + "no-transform", - TOOLTIP_BODY: PREFIX + "tooltip-body", - TOOLTIP_BODY_ITEM: PREFIX + "tooltip-body-item", - TOOLTIP_BODY_ITEM_COLOR: PREFIX + "tooltip-body-item-color", - TOOLTIP_BODY_ITEM_LABEL: PREFIX + "tooltip-body-item-label", - TOOLTIP_BODY_ITEM_VALUE: PREFIX + "tooltip-body-item-value", - TOOLTIP_HEADER: PREFIX + "tooltip-header", - TOOLTIP_HEADER_ITEM: PREFIX + "tooltip-header-item" - }; - var Selector = { - DIV: 'div', - SPAN: 'span', - TOOLTIP: (this._chart.canvas.id || _setCanvasId()) + "-tooltip" - }; - var tooltip = document.getElementById(Selector.TOOLTIP); - - if (!tooltip) { - tooltip = document.createElement('div'); - tooltip.id = Selector.TOOLTIP; - tooltip.className = ClassName.CHARTJS_TOOLTIP; - - this._chart.canvas.parentNode.appendChild(tooltip); - } // Hide if no tooltip - - - if (tooltipModel.opacity === 0) { - tooltip.style.opacity = 0; - return; - } // Set caret Position - - - tooltip.classList.remove(ClassName.ABOVE, ClassName.BELOW, ClassName.NO_TRANSFORM); - - if (tooltipModel.yAlign) { - tooltip.classList.add(tooltipModel.yAlign); - } else { - tooltip.classList.add(ClassName.NO_TRANSFORM); - } // Set Text - - - if (tooltipModel.body) { - var titleLines = tooltipModel.title || []; - var tooltipHeader = document.createElement(Selector.DIV); - tooltipHeader.className = ClassName.TOOLTIP_HEADER; - titleLines.forEach(function (title) { - var tooltipHeaderTitle = document.createElement(Selector.DIV); - tooltipHeaderTitle.className = ClassName.TOOLTIP_HEADER_ITEM; - tooltipHeaderTitle.innerHTML = title; - tooltipHeader.appendChild(tooltipHeaderTitle); - }); - var tooltipBody = document.createElement(Selector.DIV); - tooltipBody.className = ClassName.TOOLTIP_BODY; - var tooltipBodyItems = tooltipModel.body.map(function (item) { - return item.lines; - }); - tooltipBodyItems.forEach(function (item, i) { - var tooltipBodyItem = document.createElement(Selector.DIV); - tooltipBodyItem.className = ClassName.TOOLTIP_BODY_ITEM; - var colors = tooltipModel.labelColors[i]; - var tooltipBodyItemColor = document.createElement(Selector.SPAN); - tooltipBodyItemColor.className = ClassName.TOOLTIP_BODY_ITEM_COLOR; - tooltipBodyItemColor.style.backgroundColor = colors.backgroundColor; - tooltipBodyItem.appendChild(tooltipBodyItemColor); - - if (item[0].split(':').length > 1) { - var tooltipBodyItemLabel = document.createElement(Selector.SPAN); - tooltipBodyItemLabel.className = ClassName.TOOLTIP_BODY_ITEM_LABEL; - tooltipBodyItemLabel.innerHTML = item[0].split(': ')[0]; - tooltipBodyItem.appendChild(tooltipBodyItemLabel); - var tooltipBodyItemValue = document.createElement(Selector.SPAN); - tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE; - tooltipBodyItemValue.innerHTML = item[0].split(': ').pop(); - tooltipBodyItem.appendChild(tooltipBodyItemValue); - } else { - var _tooltipBodyItemValue = document.createElement(Selector.SPAN); - - _tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE; - _tooltipBodyItemValue.innerHTML = item[0]; - tooltipBodyItem.appendChild(_tooltipBodyItemValue); - } - - tooltipBody.appendChild(tooltipBodyItem); - }); - tooltip.innerHTML = ''; - tooltip.appendChild(tooltipHeader); - tooltip.appendChild(tooltipBody); - } - - var position = this._chart.canvas.getBoundingClientRect(); - - var positionY = this._chart.canvas.offsetTop; - var positionX = this._chart.canvas.offsetLeft; - var positionLeft = positionX + tooltipModel.caretX; - var positionTop = positionY + tooltipModel.caretY; // eslint-disable-next-line - - var halfWidth = tooltipModel.width / 2; - - if (positionLeft + halfWidth > position.width) { - positionLeft -= halfWidth; - } else if (positionLeft < halfWidth) { - positionLeft += halfWidth; - } // Display, position, and set styles for font - - - tooltip.style.opacity = 1; - tooltip.style.left = positionLeft + "px"; - tooltip.style.top = positionTop + "px"; - } - - /** - * -------------------------------------------------------------------------- - * Custom Tooltips for Chart.js (v2.0.0-alpha.0): index.umd.js - * Licensed under MIT (https://github.com/@coreui/coreui-chartjs/LICENSE) - * -------------------------------------------------------------------------- - */ - var index_umd = { - customTooltips: customTooltips - }; - - return index_umd; - -})); -//# sourceMappingURL=coreui-chartjs.bundle.js.map diff --git a/custom-tooltips/dist/js/coreui-chartjs.bundle.js.map b/custom-tooltips/dist/js/coreui-chartjs.bundle.js.map deleted file mode 100644 index 60394cc..0000000 --- a/custom-tooltips/dist/js/coreui-chartjs.bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"coreui-chartjs.bundle.js","sources":["../../js/src/custom-tooltips.js","../../js/index.umd.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Custom Tooltips for Chart.js (v2.0.0-alpha.0): custom-tooltips.js\n * Licensed under MIT (https://coreui.io/plugins/chart.js)\n * --------------------------------------------------------------------------\n */\n\nfunction customTooltips(tooltipModel) {\n // Add unique id if not exist\n const _setCanvasId = () => {\n const _idMaker = () => {\n const _hex = 16\n const _multiplier = 0x10000\n return ((1 + Math.random()) * _multiplier | 0).toString(_hex)\n }\n const _canvasId = `_canvas-${_idMaker() + _idMaker()}`\n this._chart.canvas.id = _canvasId\n return _canvasId\n }\n\n // eslint-disable-next-line no-nested-ternary\n const PREFIX = window.CoreUIDefaults ? window.CoreUIDefaults.prefix ? window.CoreUIDefaults.prefix : 'c-' : 'c-'\n\n const ClassName = {\n ABOVE : `${PREFIX}above`,\n BELOW : `${PREFIX}below`,\n CHARTJS_TOOLTIP : `${PREFIX}chartjs-tooltip`,\n NO_TRANSFORM : `${PREFIX}no-transform`,\n TOOLTIP_BODY : `${PREFIX}tooltip-body`,\n TOOLTIP_BODY_ITEM : `${PREFIX}tooltip-body-item`,\n TOOLTIP_BODY_ITEM_COLOR : `${PREFIX}tooltip-body-item-color`,\n TOOLTIP_BODY_ITEM_LABEL : `${PREFIX}tooltip-body-item-label`,\n TOOLTIP_BODY_ITEM_VALUE : `${PREFIX}tooltip-body-item-value`,\n TOOLTIP_HEADER : `${PREFIX}tooltip-header`,\n TOOLTIP_HEADER_ITEM : `${PREFIX}tooltip-header-item`\n }\n\n const Selector = {\n DIV : 'div',\n SPAN : 'span',\n TOOLTIP : `${this._chart.canvas.id || _setCanvasId()}-tooltip`\n }\n\n let tooltip = document.getElementById(Selector.TOOLTIP)\n\n if (!tooltip) {\n tooltip = document.createElement('div')\n tooltip.id = Selector.TOOLTIP\n tooltip.className = ClassName.CHARTJS_TOOLTIP\n this._chart.canvas.parentNode.appendChild(tooltip)\n }\n\n // Hide if no tooltip\n if (tooltipModel.opacity === 0) {\n tooltip.style.opacity = 0\n return\n }\n\n // Set caret Position\n tooltip.classList.remove(ClassName.ABOVE, ClassName.BELOW, ClassName.NO_TRANSFORM)\n if (tooltipModel.yAlign) {\n tooltip.classList.add(tooltipModel.yAlign)\n } else {\n tooltip.classList.add(ClassName.NO_TRANSFORM)\n }\n\n // Set Text\n if (tooltipModel.body) {\n const titleLines = tooltipModel.title || []\n\n const tooltipHeader = document.createElement(Selector.DIV)\n tooltipHeader.className = ClassName.TOOLTIP_HEADER\n\n titleLines.forEach((title) => {\n const tooltipHeaderTitle = document.createElement(Selector.DIV)\n tooltipHeaderTitle.className = ClassName.TOOLTIP_HEADER_ITEM\n tooltipHeaderTitle.innerHTML = title\n tooltipHeader.appendChild(tooltipHeaderTitle)\n })\n\n const tooltipBody = document.createElement(Selector.DIV)\n tooltipBody.className = ClassName.TOOLTIP_BODY\n\n const tooltipBodyItems = tooltipModel.body.map((item) => item.lines)\n tooltipBodyItems.forEach((item, i) => {\n const tooltipBodyItem = document.createElement(Selector.DIV)\n tooltipBodyItem.className = ClassName.TOOLTIP_BODY_ITEM\n\n const colors = tooltipModel.labelColors[i]\n\n const tooltipBodyItemColor = document.createElement(Selector.SPAN)\n tooltipBodyItemColor.className = ClassName.TOOLTIP_BODY_ITEM_COLOR\n tooltipBodyItemColor.style.backgroundColor = colors.backgroundColor\n\n tooltipBodyItem.appendChild(tooltipBodyItemColor)\n\n if (item[0].split(':').length > 1) {\n const tooltipBodyItemLabel = document.createElement(Selector.SPAN)\n tooltipBodyItemLabel.className = ClassName.TOOLTIP_BODY_ITEM_LABEL\n tooltipBodyItemLabel.innerHTML = item[0].split(': ')[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemLabel)\n\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0].split(': ').pop()\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n } else {\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n }\n\n tooltipBody.appendChild(tooltipBodyItem)\n })\n\n tooltip.innerHTML = ''\n\n tooltip.appendChild(tooltipHeader)\n tooltip.appendChild(tooltipBody)\n }\n\n const position = this._chart.canvas.getBoundingClientRect()\n\n const positionY = this._chart.canvas.offsetTop\n const positionX = this._chart.canvas.offsetLeft\n\n let positionLeft = positionX + tooltipModel.caretX\n const positionTop = positionY + tooltipModel.caretY\n // eslint-disable-next-line\n const halfWidth = tooltipModel.width / 2\n\n if (positionLeft + halfWidth > position.width) {\n positionLeft -= halfWidth\n } else if (positionLeft < halfWidth) {\n positionLeft += halfWidth\n }\n\n // Display, position, and set styles for font\n tooltip.style.opacity = 1\n tooltip.style.left = `${positionLeft}px`\n tooltip.style.top = `${positionTop}px`\n}\n\nexport default customTooltips\n","/**\n * --------------------------------------------------------------------------\n * Custom Tooltips for Chart.js (v2.0.0-alpha.0): index.umd.js\n * Licensed under MIT (https://github.com/@coreui/coreui-chartjs/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport customTooltips from './src/custom-tooltips'\n\nexport default {\n customTooltips\n}\n"],"names":["customTooltips","tooltipModel","_setCanvasId","_idMaker","_hex","_multiplier","Math","random","toString","_canvasId","_chart","canvas","id","PREFIX","window","CoreUIDefaults","prefix","ClassName","ABOVE","BELOW","CHARTJS_TOOLTIP","NO_TRANSFORM","TOOLTIP_BODY","TOOLTIP_BODY_ITEM","TOOLTIP_BODY_ITEM_COLOR","TOOLTIP_BODY_ITEM_LABEL","TOOLTIP_BODY_ITEM_VALUE","TOOLTIP_HEADER","TOOLTIP_HEADER_ITEM","Selector","DIV","SPAN","TOOLTIP","tooltip","document","getElementById","createElement","className","parentNode","appendChild","opacity","style","classList","remove","yAlign","add","body","titleLines","title","tooltipHeader","forEach","tooltipHeaderTitle","innerHTML","tooltipBody","tooltipBodyItems","map","item","lines","i","tooltipBodyItem","colors","labelColors","tooltipBodyItemColor","backgroundColor","split","length","tooltipBodyItemLabel","tooltipBodyItemValue","pop","position","getBoundingClientRect","positionY","offsetTop","positionX","offsetLeft","positionLeft","caretX","positionTop","caretY","halfWidth","width","left","top"],"mappings":";;;;;;;;;;;EAAA;;;;;;EAOA,SAASA,cAAT,CAAwBC,YAAxB,EAAsC;EAAA;;EACpC;EACA,MAAMC,YAAY,GAAG,SAAfA,YAAe,GAAM;EACzB,QAAMC,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,UAAMC,IAAI,GAAG,EAAb;EACA,UAAMC,WAAW,GAAG,OAApB;EACA,aAAO,CAAC,CAAC,IAAIC,IAAI,CAACC,MAAL,EAAL,IAAsBF,WAAtB,GAAoC,CAArC,EAAwCG,QAAxC,CAAiDJ,IAAjD,CAAP;EACD,KAJD;;EAKA,QAAMK,SAAS,iBAAcN,QAAQ,KAAKA,QAAQ,EAAnC,CAAf;;EACA,IAAA,KAAI,CAACO,MAAL,CAAYC,MAAZ,CAAmBC,EAAnB,GAAwBH,SAAxB;EACA,WAAOA,SAAP;EACD,GATD,CAFoC;;;EAcpC,MAAMI,MAAM,GAAGC,MAAM,CAACC,cAAP,GAAwBD,MAAM,CAACC,cAAP,CAAsBC,MAAtB,GAA+BF,MAAM,CAACC,cAAP,CAAsBC,MAArD,GAA8D,IAAtF,GAA6F,IAA5G;EAEA,MAAMC,SAAS,GAAG;EAChBC,IAAAA,KAAK,EAAwBL,MAAxB,UADW;EAEhBM,IAAAA,KAAK,EAAwBN,MAAxB,UAFW;EAGhBO,IAAAA,eAAe,EAAcP,MAAd,oBAHC;EAIhBQ,IAAAA,YAAY,EAAiBR,MAAjB,iBAJI;EAKhBS,IAAAA,YAAY,EAAiBT,MAAjB,iBALI;EAMhBU,IAAAA,iBAAiB,EAAYV,MAAZ,sBAND;EAOhBW,IAAAA,uBAAuB,EAAMX,MAAN,4BAPP;EAQhBY,IAAAA,uBAAuB,EAAMZ,MAAN,4BARP;EAShBa,IAAAA,uBAAuB,EAAMb,MAAN,4BATP;EAUhBc,IAAAA,cAAc,EAAed,MAAf,mBAVE;EAWhBe,IAAAA,mBAAmB,EAAUf,MAAV;EAXH,GAAlB;EAcA,MAAMgB,QAAQ,GAAG;EACfC,IAAAA,GAAG,EAAO,KADK;EAEfC,IAAAA,IAAI,EAAM,MAFK;EAGfC,IAAAA,OAAO,GAAM,KAAKtB,MAAL,CAAYC,MAAZ,CAAmBC,EAAnB,IAAyBV,YAAY,EAA3C;EAHQ,GAAjB;EAMA,MAAI+B,OAAO,GAAGC,QAAQ,CAACC,cAAT,CAAwBN,QAAQ,CAACG,OAAjC,CAAd;;EAEA,MAAI,CAACC,OAAL,EAAc;EACZA,IAAAA,OAAO,GAAGC,QAAQ,CAACE,aAAT,CAAuB,KAAvB,CAAV;EACAH,IAAAA,OAAO,CAACrB,EAAR,GAAaiB,QAAQ,CAACG,OAAtB;EACAC,IAAAA,OAAO,CAACI,SAAR,GAAoBpB,SAAS,CAACG,eAA9B;;EACA,SAAKV,MAAL,CAAYC,MAAZ,CAAmB2B,UAAnB,CAA8BC,WAA9B,CAA0CN,OAA1C;EACD,GA3CmC;;;EA8CpC,MAAIhC,YAAY,CAACuC,OAAb,KAAyB,CAA7B,EAAgC;EAC9BP,IAAAA,OAAO,CAACQ,KAAR,CAAcD,OAAd,GAAwB,CAAxB;EACA;EACD,GAjDmC;;;EAoDpCP,EAAAA,OAAO,CAACS,SAAR,CAAkBC,MAAlB,CAAyB1B,SAAS,CAACC,KAAnC,EAA0CD,SAAS,CAACE,KAApD,EAA2DF,SAAS,CAACI,YAArE;;EACA,MAAIpB,YAAY,CAAC2C,MAAjB,EAAyB;EACvBX,IAAAA,OAAO,CAACS,SAAR,CAAkBG,GAAlB,CAAsB5C,YAAY,CAAC2C,MAAnC;EACD,GAFD,MAEO;EACLX,IAAAA,OAAO,CAACS,SAAR,CAAkBG,GAAlB,CAAsB5B,SAAS,CAACI,YAAhC;EACD,GAzDmC;;;EA4DpC,MAAIpB,YAAY,CAAC6C,IAAjB,EAAuB;EACrB,QAAMC,UAAU,GAAG9C,YAAY,CAAC+C,KAAb,IAAsB,EAAzC;EAEA,QAAMC,aAAa,GAAGf,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAAtB;EACAmB,IAAAA,aAAa,CAACZ,SAAd,GAA0BpB,SAAS,CAACU,cAApC;EAEAoB,IAAAA,UAAU,CAACG,OAAX,CAAmB,UAACF,KAAD,EAAW;EAC5B,UAAMG,kBAAkB,GAAGjB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAA3B;EACAqB,MAAAA,kBAAkB,CAACd,SAAnB,GAA+BpB,SAAS,CAACW,mBAAzC;EACAuB,MAAAA,kBAAkB,CAACC,SAAnB,GAA+BJ,KAA/B;EACAC,MAAAA,aAAa,CAACV,WAAd,CAA0BY,kBAA1B;EACD,KALD;EAOA,QAAME,WAAW,GAAGnB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAApB;EACAuB,IAAAA,WAAW,CAAChB,SAAZ,GAAwBpB,SAAS,CAACK,YAAlC;EAEA,QAAMgC,gBAAgB,GAAGrD,YAAY,CAAC6C,IAAb,CAAkBS,GAAlB,CAAsB,UAACC,IAAD;EAAA,aAAUA,IAAI,CAACC,KAAf;EAAA,KAAtB,CAAzB;EACAH,IAAAA,gBAAgB,CAACJ,OAAjB,CAAyB,UAACM,IAAD,EAAOE,CAAP,EAAa;EACpC,UAAMC,eAAe,GAAGzB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAAxB;EACA6B,MAAAA,eAAe,CAACtB,SAAhB,GAA4BpB,SAAS,CAACM,iBAAtC;EAEA,UAAMqC,MAAM,GAAG3D,YAAY,CAAC4D,WAAb,CAAyBH,CAAzB,CAAf;EAEA,UAAMI,oBAAoB,GAAG5B,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;EACA+B,MAAAA,oBAAoB,CAACzB,SAArB,GAAiCpB,SAAS,CAACO,uBAA3C;EACAsC,MAAAA,oBAAoB,CAACrB,KAArB,CAA2BsB,eAA3B,GAA6CH,MAAM,CAACG,eAApD;EAEAJ,MAAAA,eAAe,CAACpB,WAAhB,CAA4BuB,oBAA5B;;EAEA,UAAIN,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,GAAd,EAAmBC,MAAnB,GAA4B,CAAhC,EAAmC;EACjC,YAAMC,oBAAoB,GAAGhC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;EACAmC,QAAAA,oBAAoB,CAAC7B,SAArB,GAAiCpB,SAAS,CAACQ,uBAA3C;EACAyC,QAAAA,oBAAoB,CAACd,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,IAAd,EAAoB,CAApB,CAAjC;EAEAL,QAAAA,eAAe,CAACpB,WAAhB,CAA4B2B,oBAA5B;EAEA,YAAMC,oBAAoB,GAAGjC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;EACAoC,QAAAA,oBAAoB,CAAC9B,SAArB,GAAiCpB,SAAS,CAACS,uBAA3C;EACAyC,QAAAA,oBAAoB,CAACf,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,IAAd,EAAoBI,GAApB,EAAjC;EAEAT,QAAAA,eAAe,CAACpB,WAAhB,CAA4B4B,oBAA5B;EACD,OAZD,MAYO;EACL,YAAMA,qBAAoB,GAAGjC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;;EACAoC,QAAAA,qBAAoB,CAAC9B,SAArB,GAAiCpB,SAAS,CAACS,uBAA3C;EACAyC,QAAAA,qBAAoB,CAACf,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAArC;EAEAG,QAAAA,eAAe,CAACpB,WAAhB,CAA4B4B,qBAA5B;EACD;;EAEDd,MAAAA,WAAW,CAACd,WAAZ,CAAwBoB,eAAxB;EACD,KAjCD;EAmCA1B,IAAAA,OAAO,CAACmB,SAAR,GAAoB,EAApB;EAEAnB,IAAAA,OAAO,CAACM,WAAR,CAAoBU,aAApB;EACAhB,IAAAA,OAAO,CAACM,WAAR,CAAoBc,WAApB;EACD;;EAED,MAAMgB,QAAQ,GAAG,KAAK3D,MAAL,CAAYC,MAAZ,CAAmB2D,qBAAnB,EAAjB;;EAEA,MAAMC,SAAS,GAAG,KAAK7D,MAAL,CAAYC,MAAZ,CAAmB6D,SAArC;EACA,MAAMC,SAAS,GAAG,KAAK/D,MAAL,CAAYC,MAAZ,CAAmB+D,UAArC;EAEA,MAAIC,YAAY,GAAGF,SAAS,GAAGxE,YAAY,CAAC2E,MAA5C;EACA,MAAMC,WAAW,GAAGN,SAAS,GAAGtE,YAAY,CAAC6E,MAA7C,CA5HoC;;EA8HpC,MAAMC,SAAS,GAAG9E,YAAY,CAAC+E,KAAb,GAAqB,CAAvC;;EAEA,MAAIL,YAAY,GAAGI,SAAf,GAA2BV,QAAQ,CAACW,KAAxC,EAA+C;EAC7CL,IAAAA,YAAY,IAAII,SAAhB;EACD,GAFD,MAEO,IAAIJ,YAAY,GAAGI,SAAnB,EAA8B;EACnCJ,IAAAA,YAAY,IAAII,SAAhB;EACD,GApImC;;;EAuIpC9C,EAAAA,OAAO,CAACQ,KAAR,CAAcD,OAAd,GAAwB,CAAxB;EACAP,EAAAA,OAAO,CAACQ,KAAR,CAAcwC,IAAd,GAAwBN,YAAxB;EACA1C,EAAAA,OAAO,CAACQ,KAAR,CAAcyC,GAAd,GAAuBL,WAAvB;EACD;;ECjJD;;;;;;AAOA,AAEA,kBAAe;EACb7E,EAAAA,cAAc,EAAdA;EADa,CAAf;;;;;;;;"} \ No newline at end of file diff --git a/custom-tooltips/dist/js/coreui-chartjs.bundle.min.js b/custom-tooltips/dist/js/coreui-chartjs.bundle.min.js deleted file mode 100644 index 0bc8258..0000000 --- a/custom-tooltips/dist/js/coreui-chartjs.bundle.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * CoreUI Plugins - Chart.js for CoreUI 3 v2.0.0-alpha.1 (https://coreui.io) - * Copyright 2019 Łukasz Holeczek - * Licensed under MIT (https://coreui.io/plugins/chart.js) - */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e=e||self).coreui=e.coreui||{},e.coreui.ChartJS=t())}(this,(function(){"use strict";return{customTooltips:function(e){var t,a,o=this,n=window.CoreUIDefaults&&window.CoreUIDefaults.prefix?window.CoreUIDefaults.prefix:"c-",i={ABOVE:n+"above",BELOW:n+"below",CHARTJS_TOOLTIP:n+"chartjs-tooltip",NO_TRANSFORM:n+"no-transform",TOOLTIP_BODY:n+"tooltip-body",TOOLTIP_BODY_ITEM:n+"tooltip-body-item",TOOLTIP_BODY_ITEM_COLOR:n+"tooltip-body-item-color",TOOLTIP_BODY_ITEM_LABEL:n+"tooltip-body-item-label",TOOLTIP_BODY_ITEM_VALUE:n+"tooltip-body-item-value",TOOLTIP_HEADER:n+"tooltip-header",TOOLTIP_HEADER_ITEM:n+"tooltip-header-item"},l={DIV:"div",SPAN:"span",TOOLTIP:(this._chart.canvas.id||(t=function(){return(65536*(1+Math.random())|0).toString(16)},a="_canvas-"+(t()+t()),o._chart.canvas.id=a,a))+"-tooltip"},c=document.getElementById(l.TOOLTIP);if(c||((c=document.createElement("div")).id=l.TOOLTIP,c.className=i.CHARTJS_TOOLTIP,this._chart.canvas.parentNode.appendChild(c)),0!==e.opacity){if(c.classList.remove(i.ABOVE,i.BELOW,i.NO_TRANSFORM),e.yAlign?c.classList.add(e.yAlign):c.classList.add(i.NO_TRANSFORM),e.body){var s=e.title||[],r=document.createElement(l.DIV);r.className=i.TOOLTIP_HEADER,s.forEach((function(e){var t=document.createElement(l.DIV);t.className=i.TOOLTIP_HEADER_ITEM,t.innerHTML=e,r.appendChild(t)}));var d=document.createElement(l.DIV);d.className=i.TOOLTIP_BODY,e.body.map((function(e){return e.lines})).forEach((function(t,a){var o=document.createElement(l.DIV);o.className=i.TOOLTIP_BODY_ITEM;var n=e.labelColors[a],c=document.createElement(l.SPAN);if(c.className=i.TOOLTIP_BODY_ITEM_COLOR,c.style.backgroundColor=n.backgroundColor,o.appendChild(c),t[0].split(":").length>1){var s=document.createElement(l.SPAN);s.className=i.TOOLTIP_BODY_ITEM_LABEL,s.innerHTML=t[0].split(": ")[0],o.appendChild(s);var r=document.createElement(l.SPAN);r.className=i.TOOLTIP_BODY_ITEM_VALUE,r.innerHTML=t[0].split(": ").pop(),o.appendChild(r)}else{var O=document.createElement(l.SPAN);O.className=i.TOOLTIP_BODY_ITEM_VALUE,O.innerHTML=t[0],o.appendChild(O)}d.appendChild(o)})),c.innerHTML="",c.appendChild(r),c.appendChild(d)}var O=this._chart.canvas.getBoundingClientRect(),T=this._chart.canvas.offsetTop,p=this._chart.canvas.offsetLeft+e.caretX,_=T+e.caretY,m=e.width/2;p+m>O.width?p-=m:p {\n const _idMaker = () => {\n const _hex = 16\n const _multiplier = 0x10000\n return ((1 + Math.random()) * _multiplier | 0).toString(_hex)\n }\n const _canvasId = `_canvas-${_idMaker() + _idMaker()}`\n this._chart.canvas.id = _canvasId\n return _canvasId\n }\n\n // eslint-disable-next-line no-nested-ternary\n const PREFIX = window.CoreUIDefaults ? window.CoreUIDefaults.prefix ? window.CoreUIDefaults.prefix : 'c-' : 'c-'\n\n const ClassName = {\n ABOVE : `${PREFIX}above`,\n BELOW : `${PREFIX}below`,\n CHARTJS_TOOLTIP : `${PREFIX}chartjs-tooltip`,\n NO_TRANSFORM : `${PREFIX}no-transform`,\n TOOLTIP_BODY : `${PREFIX}tooltip-body`,\n TOOLTIP_BODY_ITEM : `${PREFIX}tooltip-body-item`,\n TOOLTIP_BODY_ITEM_COLOR : `${PREFIX}tooltip-body-item-color`,\n TOOLTIP_BODY_ITEM_LABEL : `${PREFIX}tooltip-body-item-label`,\n TOOLTIP_BODY_ITEM_VALUE : `${PREFIX}tooltip-body-item-value`,\n TOOLTIP_HEADER : `${PREFIX}tooltip-header`,\n TOOLTIP_HEADER_ITEM : `${PREFIX}tooltip-header-item`\n }\n\n const Selector = {\n DIV : 'div',\n SPAN : 'span',\n TOOLTIP : `${this._chart.canvas.id || _setCanvasId()}-tooltip`\n }\n\n let tooltip = document.getElementById(Selector.TOOLTIP)\n\n if (!tooltip) {\n tooltip = document.createElement('div')\n tooltip.id = Selector.TOOLTIP\n tooltip.className = ClassName.CHARTJS_TOOLTIP\n this._chart.canvas.parentNode.appendChild(tooltip)\n }\n\n // Hide if no tooltip\n if (tooltipModel.opacity === 0) {\n tooltip.style.opacity = 0\n return\n }\n\n // Set caret Position\n tooltip.classList.remove(ClassName.ABOVE, ClassName.BELOW, ClassName.NO_TRANSFORM)\n if (tooltipModel.yAlign) {\n tooltip.classList.add(tooltipModel.yAlign)\n } else {\n tooltip.classList.add(ClassName.NO_TRANSFORM)\n }\n\n // Set Text\n if (tooltipModel.body) {\n const titleLines = tooltipModel.title || []\n\n const tooltipHeader = document.createElement(Selector.DIV)\n tooltipHeader.className = ClassName.TOOLTIP_HEADER\n\n titleLines.forEach((title) => {\n const tooltipHeaderTitle = document.createElement(Selector.DIV)\n tooltipHeaderTitle.className = ClassName.TOOLTIP_HEADER_ITEM\n tooltipHeaderTitle.innerHTML = title\n tooltipHeader.appendChild(tooltipHeaderTitle)\n })\n\n const tooltipBody = document.createElement(Selector.DIV)\n tooltipBody.className = ClassName.TOOLTIP_BODY\n\n const tooltipBodyItems = tooltipModel.body.map((item) => item.lines)\n tooltipBodyItems.forEach((item, i) => {\n const tooltipBodyItem = document.createElement(Selector.DIV)\n tooltipBodyItem.className = ClassName.TOOLTIP_BODY_ITEM\n\n const colors = tooltipModel.labelColors[i]\n\n const tooltipBodyItemColor = document.createElement(Selector.SPAN)\n tooltipBodyItemColor.className = ClassName.TOOLTIP_BODY_ITEM_COLOR\n tooltipBodyItemColor.style.backgroundColor = colors.backgroundColor\n\n tooltipBodyItem.appendChild(tooltipBodyItemColor)\n\n if (item[0].split(':').length > 1) {\n const tooltipBodyItemLabel = document.createElement(Selector.SPAN)\n tooltipBodyItemLabel.className = ClassName.TOOLTIP_BODY_ITEM_LABEL\n tooltipBodyItemLabel.innerHTML = item[0].split(': ')[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemLabel)\n\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0].split(': ').pop()\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n } else {\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n }\n\n tooltipBody.appendChild(tooltipBodyItem)\n })\n\n tooltip.innerHTML = ''\n\n tooltip.appendChild(tooltipHeader)\n tooltip.appendChild(tooltipBody)\n }\n\n const position = this._chart.canvas.getBoundingClientRect()\n\n const positionY = this._chart.canvas.offsetTop\n const positionX = this._chart.canvas.offsetLeft\n\n let positionLeft = positionX + tooltipModel.caretX\n const positionTop = positionY + tooltipModel.caretY\n // eslint-disable-next-line\n const halfWidth = tooltipModel.width / 2\n\n if (positionLeft + halfWidth > position.width) {\n positionLeft -= halfWidth\n } else if (positionLeft < halfWidth) {\n positionLeft += halfWidth\n }\n\n // Display, position, and set styles for font\n tooltip.style.opacity = 1\n tooltip.style.left = `${positionLeft}px`\n tooltip.style.top = `${positionTop}px`\n}\n\nexport default customTooltips\n"]} \ No newline at end of file diff --git a/custom-tooltips/dist/js/coreui-chartjs.esm.js.map b/custom-tooltips/dist/js/coreui-chartjs.esm.js.map deleted file mode 100644 index e9af893..0000000 --- a/custom-tooltips/dist/js/coreui-chartjs.esm.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"coreui-chartjs.esm.js","sources":["../../js/src/custom-tooltips.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Custom Tooltips for Chart.js (v2.0.0-alpha.0): custom-tooltips.js\n * Licensed under MIT (https://coreui.io/plugins/chart.js)\n * --------------------------------------------------------------------------\n */\n\nfunction customTooltips(tooltipModel) {\n // Add unique id if not exist\n const _setCanvasId = () => {\n const _idMaker = () => {\n const _hex = 16\n const _multiplier = 0x10000\n return ((1 + Math.random()) * _multiplier | 0).toString(_hex)\n }\n const _canvasId = `_canvas-${_idMaker() + _idMaker()}`\n this._chart.canvas.id = _canvasId\n return _canvasId\n }\n\n // eslint-disable-next-line no-nested-ternary\n const PREFIX = window.CoreUIDefaults ? window.CoreUIDefaults.prefix ? window.CoreUIDefaults.prefix : 'c-' : 'c-'\n\n const ClassName = {\n ABOVE : `${PREFIX}above`,\n BELOW : `${PREFIX}below`,\n CHARTJS_TOOLTIP : `${PREFIX}chartjs-tooltip`,\n NO_TRANSFORM : `${PREFIX}no-transform`,\n TOOLTIP_BODY : `${PREFIX}tooltip-body`,\n TOOLTIP_BODY_ITEM : `${PREFIX}tooltip-body-item`,\n TOOLTIP_BODY_ITEM_COLOR : `${PREFIX}tooltip-body-item-color`,\n TOOLTIP_BODY_ITEM_LABEL : `${PREFIX}tooltip-body-item-label`,\n TOOLTIP_BODY_ITEM_VALUE : `${PREFIX}tooltip-body-item-value`,\n TOOLTIP_HEADER : `${PREFIX}tooltip-header`,\n TOOLTIP_HEADER_ITEM : `${PREFIX}tooltip-header-item`\n }\n\n const Selector = {\n DIV : 'div',\n SPAN : 'span',\n TOOLTIP : `${this._chart.canvas.id || _setCanvasId()}-tooltip`\n }\n\n let tooltip = document.getElementById(Selector.TOOLTIP)\n\n if (!tooltip) {\n tooltip = document.createElement('div')\n tooltip.id = Selector.TOOLTIP\n tooltip.className = ClassName.CHARTJS_TOOLTIP\n this._chart.canvas.parentNode.appendChild(tooltip)\n }\n\n // Hide if no tooltip\n if (tooltipModel.opacity === 0) {\n tooltip.style.opacity = 0\n return\n }\n\n // Set caret Position\n tooltip.classList.remove(ClassName.ABOVE, ClassName.BELOW, ClassName.NO_TRANSFORM)\n if (tooltipModel.yAlign) {\n tooltip.classList.add(tooltipModel.yAlign)\n } else {\n tooltip.classList.add(ClassName.NO_TRANSFORM)\n }\n\n // Set Text\n if (tooltipModel.body) {\n const titleLines = tooltipModel.title || []\n\n const tooltipHeader = document.createElement(Selector.DIV)\n tooltipHeader.className = ClassName.TOOLTIP_HEADER\n\n titleLines.forEach((title) => {\n const tooltipHeaderTitle = document.createElement(Selector.DIV)\n tooltipHeaderTitle.className = ClassName.TOOLTIP_HEADER_ITEM\n tooltipHeaderTitle.innerHTML = title\n tooltipHeader.appendChild(tooltipHeaderTitle)\n })\n\n const tooltipBody = document.createElement(Selector.DIV)\n tooltipBody.className = ClassName.TOOLTIP_BODY\n\n const tooltipBodyItems = tooltipModel.body.map((item) => item.lines)\n tooltipBodyItems.forEach((item, i) => {\n const tooltipBodyItem = document.createElement(Selector.DIV)\n tooltipBodyItem.className = ClassName.TOOLTIP_BODY_ITEM\n\n const colors = tooltipModel.labelColors[i]\n\n const tooltipBodyItemColor = document.createElement(Selector.SPAN)\n tooltipBodyItemColor.className = ClassName.TOOLTIP_BODY_ITEM_COLOR\n tooltipBodyItemColor.style.backgroundColor = colors.backgroundColor\n\n tooltipBodyItem.appendChild(tooltipBodyItemColor)\n\n if (item[0].split(':').length > 1) {\n const tooltipBodyItemLabel = document.createElement(Selector.SPAN)\n tooltipBodyItemLabel.className = ClassName.TOOLTIP_BODY_ITEM_LABEL\n tooltipBodyItemLabel.innerHTML = item[0].split(': ')[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemLabel)\n\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0].split(': ').pop()\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n } else {\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n }\n\n tooltipBody.appendChild(tooltipBodyItem)\n })\n\n tooltip.innerHTML = ''\n\n tooltip.appendChild(tooltipHeader)\n tooltip.appendChild(tooltipBody)\n }\n\n const position = this._chart.canvas.getBoundingClientRect()\n\n const positionY = this._chart.canvas.offsetTop\n const positionX = this._chart.canvas.offsetLeft\n\n let positionLeft = positionX + tooltipModel.caretX\n const positionTop = positionY + tooltipModel.caretY\n // eslint-disable-next-line\n const halfWidth = tooltipModel.width / 2\n\n if (positionLeft + halfWidth > position.width) {\n positionLeft -= halfWidth\n } else if (positionLeft < halfWidth) {\n positionLeft += halfWidth\n }\n\n // Display, position, and set styles for font\n tooltip.style.opacity = 1\n tooltip.style.left = `${positionLeft}px`\n tooltip.style.top = `${positionTop}px`\n}\n\nexport default customTooltips\n"],"names":["customTooltips","tooltipModel","_setCanvasId","_idMaker","_hex","_multiplier","Math","random","toString","_canvasId","_chart","canvas","id","PREFIX","window","CoreUIDefaults","prefix","ClassName","ABOVE","BELOW","CHARTJS_TOOLTIP","NO_TRANSFORM","TOOLTIP_BODY","TOOLTIP_BODY_ITEM","TOOLTIP_BODY_ITEM_COLOR","TOOLTIP_BODY_ITEM_LABEL","TOOLTIP_BODY_ITEM_VALUE","TOOLTIP_HEADER","TOOLTIP_HEADER_ITEM","Selector","DIV","SPAN","TOOLTIP","tooltip","document","getElementById","createElement","className","parentNode","appendChild","opacity","style","classList","remove","yAlign","add","body","titleLines","title","tooltipHeader","forEach","tooltipHeaderTitle","innerHTML","tooltipBody","tooltipBodyItems","map","item","lines","i","tooltipBodyItem","colors","labelColors","tooltipBodyItemColor","backgroundColor","split","length","tooltipBodyItemLabel","tooltipBodyItemValue","pop","position","getBoundingClientRect","positionY","offsetTop","positionX","offsetLeft","positionLeft","caretX","positionTop","caretY","halfWidth","width","left","top"],"mappings":";;;;;AAAA;;;;;;AAOA,SAASA,cAAT,CAAwBC,YAAxB,EAAsC;;MAE9BC,YAAY,GAAG,MAAM;QACnBC,QAAQ,GAAG,MAAM;UACfC,IAAI,GAAG,EAAb;UACMC,WAAW,GAAG,OAApB;aACO,CAAC,CAAC,IAAIC,IAAI,CAACC,MAAL,EAAL,IAAsBF,WAAtB,GAAoC,CAArC,EAAwCG,QAAxC,CAAiDJ,IAAjD,CAAP;KAHF;;QAKMK,SAAS,iBAAcN,QAAQ,KAAKA,QAAQ,EAAnC,CAAf;;SACKO,MAAL,CAAYC,MAAZ,CAAmBC,EAAnB,GAAwBH,SAAxB;WACOA,SAAP;GARF,CAFoC;;;MAc9BI,MAAM,GAAGC,MAAM,CAACC,cAAP,GAAwBD,MAAM,CAACC,cAAP,CAAsBC,MAAtB,GAA+BF,MAAM,CAACC,cAAP,CAAsBC,MAArD,GAA8D,IAAtF,GAA6F,IAA5G;MAEMC,SAAS,GAAG;IAChBC,KAAK,EAAwBL,MAAxB,UADW;IAEhBM,KAAK,EAAwBN,MAAxB,UAFW;IAGhBO,eAAe,EAAcP,MAAd,oBAHC;IAIhBQ,YAAY,EAAiBR,MAAjB,iBAJI;IAKhBS,YAAY,EAAiBT,MAAjB,iBALI;IAMhBU,iBAAiB,EAAYV,MAAZ,sBAND;IAOhBW,uBAAuB,EAAMX,MAAN,4BAPP;IAQhBY,uBAAuB,EAAMZ,MAAN,4BARP;IAShBa,uBAAuB,EAAMb,MAAN,4BATP;IAUhBc,cAAc,EAAed,MAAf,mBAVE;IAWhBe,mBAAmB,EAAUf,MAAV;GAXrB;MAcMgB,QAAQ,GAAG;IACfC,GAAG,EAAO,KADK;IAEfC,IAAI,EAAM,MAFK;IAGfC,OAAO,GAAM,KAAKtB,MAAL,CAAYC,MAAZ,CAAmBC,EAAnB,IAAyBV,YAAY,EAA3C;GAHT;MAMI+B,OAAO,GAAGC,QAAQ,CAACC,cAAT,CAAwBN,QAAQ,CAACG,OAAjC,CAAd;;MAEI,CAACC,OAAL,EAAc;IACZA,OAAO,GAAGC,QAAQ,CAACE,aAAT,CAAuB,KAAvB,CAAV;IACAH,OAAO,CAACrB,EAAR,GAAaiB,QAAQ,CAACG,OAAtB;IACAC,OAAO,CAACI,SAAR,GAAoBpB,SAAS,CAACG,eAA9B;;SACKV,MAAL,CAAYC,MAAZ,CAAmB2B,UAAnB,CAA8BC,WAA9B,CAA0CN,OAA1C;GA1CkC;;;MA8ChChC,YAAY,CAACuC,OAAb,KAAyB,CAA7B,EAAgC;IAC9BP,OAAO,CAACQ,KAAR,CAAcD,OAAd,GAAwB,CAAxB;;GA/CkC;;;EAoDpCP,OAAO,CAACS,SAAR,CAAkBC,MAAlB,CAAyB1B,SAAS,CAACC,KAAnC,EAA0CD,SAAS,CAACE,KAApD,EAA2DF,SAAS,CAACI,YAArE;;MACIpB,YAAY,CAAC2C,MAAjB,EAAyB;IACvBX,OAAO,CAACS,SAAR,CAAkBG,GAAlB,CAAsB5C,YAAY,CAAC2C,MAAnC;GADF,MAEO;IACLX,OAAO,CAACS,SAAR,CAAkBG,GAAlB,CAAsB5B,SAAS,CAACI,YAAhC;GAxDkC;;;MA4DhCpB,YAAY,CAAC6C,IAAjB,EAAuB;QACfC,UAAU,GAAG9C,YAAY,CAAC+C,KAAb,IAAsB,EAAzC;QAEMC,aAAa,GAAGf,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAAtB;IACAmB,aAAa,CAACZ,SAAd,GAA0BpB,SAAS,CAACU,cAApC;IAEAoB,UAAU,CAACG,OAAX,CAAoBF,KAAD,IAAW;UACtBG,kBAAkB,GAAGjB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAA3B;MACAqB,kBAAkB,CAACd,SAAnB,GAA+BpB,SAAS,CAACW,mBAAzC;MACAuB,kBAAkB,CAACC,SAAnB,GAA+BJ,KAA/B;MACAC,aAAa,CAACV,WAAd,CAA0BY,kBAA1B;KAJF;QAOME,WAAW,GAAGnB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAApB;IACAuB,WAAW,CAAChB,SAAZ,GAAwBpB,SAAS,CAACK,YAAlC;QAEMgC,gBAAgB,GAAGrD,YAAY,CAAC6C,IAAb,CAAkBS,GAAlB,CAAuBC,IAAD,IAAUA,IAAI,CAACC,KAArC,CAAzB;IACAH,gBAAgB,CAACJ,OAAjB,CAAyB,CAACM,IAAD,EAAOE,CAAP,KAAa;UAC9BC,eAAe,GAAGzB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAAxB;MACA6B,eAAe,CAACtB,SAAhB,GAA4BpB,SAAS,CAACM,iBAAtC;UAEMqC,MAAM,GAAG3D,YAAY,CAAC4D,WAAb,CAAyBH,CAAzB,CAAf;UAEMI,oBAAoB,GAAG5B,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;MACA+B,oBAAoB,CAACzB,SAArB,GAAiCpB,SAAS,CAACO,uBAA3C;MACAsC,oBAAoB,CAACrB,KAArB,CAA2BsB,eAA3B,GAA6CH,MAAM,CAACG,eAApD;MAEAJ,eAAe,CAACpB,WAAhB,CAA4BuB,oBAA5B;;UAEIN,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,GAAd,EAAmBC,MAAnB,GAA4B,CAAhC,EAAmC;YAC3BC,oBAAoB,GAAGhC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;QACAmC,oBAAoB,CAAC7B,SAArB,GAAiCpB,SAAS,CAACQ,uBAA3C;QACAyC,oBAAoB,CAACd,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,IAAd,EAAoB,CAApB,CAAjC;QAEAL,eAAe,CAACpB,WAAhB,CAA4B2B,oBAA5B;YAEMC,oBAAoB,GAAGjC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;QACAoC,oBAAoB,CAAC9B,SAArB,GAAiCpB,SAAS,CAACS,uBAA3C;QACAyC,oBAAoB,CAACf,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,IAAd,EAAoBI,GAApB,EAAjC;QAEAT,eAAe,CAACpB,WAAhB,CAA4B4B,oBAA5B;OAXF,MAYO;YACCA,qBAAoB,GAAGjC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;;QACAoC,qBAAoB,CAAC9B,SAArB,GAAiCpB,SAAS,CAACS,uBAA3C;QACAyC,qBAAoB,CAACf,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAArC;QAEAG,eAAe,CAACpB,WAAhB,CAA4B4B,qBAA5B;;;MAGFd,WAAW,CAACd,WAAZ,CAAwBoB,eAAxB;KAhCF;IAmCA1B,OAAO,CAACmB,SAAR,GAAoB,EAApB;IAEAnB,OAAO,CAACM,WAAR,CAAoBU,aAApB;IACAhB,OAAO,CAACM,WAAR,CAAoBc,WAApB;;;MAGIgB,QAAQ,GAAG,KAAK3D,MAAL,CAAYC,MAAZ,CAAmB2D,qBAAnB,EAAjB;;MAEMC,SAAS,GAAG,KAAK7D,MAAL,CAAYC,MAAZ,CAAmB6D,SAArC;MACMC,SAAS,GAAG,KAAK/D,MAAL,CAAYC,MAAZ,CAAmB+D,UAArC;MAEIC,YAAY,GAAGF,SAAS,GAAGxE,YAAY,CAAC2E,MAA5C;MACMC,WAAW,GAAGN,SAAS,GAAGtE,YAAY,CAAC6E,MAA7C,CA5HoC;;MA8H9BC,SAAS,GAAG9E,YAAY,CAAC+E,KAAb,GAAqB,CAAvC;;MAEIL,YAAY,GAAGI,SAAf,GAA2BV,QAAQ,CAACW,KAAxC,EAA+C;IAC7CL,YAAY,IAAII,SAAhB;GADF,MAEO,IAAIJ,YAAY,GAAGI,SAAnB,EAA8B;IACnCJ,YAAY,IAAII,SAAhB;GAnIkC;;;EAuIpC9C,OAAO,CAACQ,KAAR,CAAcD,OAAd,GAAwB,CAAxB;EACAP,OAAO,CAACQ,KAAR,CAAcwC,IAAd,GAAwBN,YAAxB;EACA1C,OAAO,CAACQ,KAAR,CAAcyC,GAAd,GAAuBL,WAAvB;;;;;"} \ No newline at end of file diff --git a/custom-tooltips/dist/js/coreui-chartjs.esm.min.js b/custom-tooltips/dist/js/coreui-chartjs.esm.min.js deleted file mode 100644 index bda5627..0000000 --- a/custom-tooltips/dist/js/coreui-chartjs.esm.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * CoreUI Plugins - Chart.js for CoreUI 3 v2.0.0-alpha.1 (https://coreui.io) - * Copyright 2019 Łukasz Holeczek - * Licensed under MIT (https://coreui.io/plugins/chart.js) - */ -function customTooltips(e){var t=window.CoreUIDefaults&&window.CoreUIDefaults.prefix?window.CoreUIDefaults.prefix:"c-",a={ABOVE:t+"above",BELOW:t+"below",CHARTJS_TOOLTIP:t+"chartjs-tooltip",NO_TRANSFORM:t+"no-transform",TOOLTIP_BODY:t+"tooltip-body",TOOLTIP_BODY_ITEM:t+"tooltip-body-item",TOOLTIP_BODY_ITEM_COLOR:t+"tooltip-body-item-color",TOOLTIP_BODY_ITEM_LABEL:t+"tooltip-body-item-label",TOOLTIP_BODY_ITEM_VALUE:t+"tooltip-body-item-value",TOOLTIP_HEADER:t+"tooltip-header",TOOLTIP_HEADER_ITEM:t+"tooltip-header-item"},o={DIV:"div",SPAN:"span",TOOLTIP:(this._chart.canvas.id||(()=>{var e=()=>{return(65536*(1+Math.random())|0).toString(16)},t="_canvas-"+(e()+e());return this._chart.canvas.id=t,t})())+"-tooltip"},l=document.getElementById(o.TOOLTIP);if(l||((l=document.createElement("div")).id=o.TOOLTIP,l.className=a.CHARTJS_TOOLTIP,this._chart.canvas.parentNode.appendChild(l)),0!==e.opacity){if(l.classList.remove(a.ABOVE,a.BELOW,a.NO_TRANSFORM),e.yAlign?l.classList.add(e.yAlign):l.classList.add(a.NO_TRANSFORM),e.body){var i=e.title||[],n=document.createElement(o.DIV);n.className=a.TOOLTIP_HEADER,i.forEach(e=>{var t=document.createElement(o.DIV);t.className=a.TOOLTIP_HEADER_ITEM,t.innerHTML=e,n.appendChild(t)});var O=document.createElement(o.DIV);O.className=a.TOOLTIP_BODY,e.body.map(e=>e.lines).forEach((t,l)=>{var i=document.createElement(o.DIV);i.className=a.TOOLTIP_BODY_ITEM;var n=e.labelColors[l],s=document.createElement(o.SPAN);if(s.className=a.TOOLTIP_BODY_ITEM_COLOR,s.style.backgroundColor=n.backgroundColor,i.appendChild(s),t[0].split(":").length>1){var T=document.createElement(o.SPAN);T.className=a.TOOLTIP_BODY_ITEM_LABEL,T.innerHTML=t[0].split(": ")[0],i.appendChild(T);var c=document.createElement(o.SPAN);c.className=a.TOOLTIP_BODY_ITEM_VALUE,c.innerHTML=t[0].split(": ").pop(),i.appendChild(c)}else{var r=document.createElement(o.SPAN);r.className=a.TOOLTIP_BODY_ITEM_VALUE,r.innerHTML=t[0],i.appendChild(r)}O.appendChild(i)}),l.innerHTML="",l.appendChild(n),l.appendChild(O)}var s=this._chart.canvas.getBoundingClientRect(),T=this._chart.canvas.offsetTop,c=this._chart.canvas.offsetLeft+e.caretX,r=T+e.caretY,d=e.width/2;c+d>s.width?c-=d:c {\n const _idMaker = () => {\n const _hex = 16\n const _multiplier = 0x10000\n return ((1 + Math.random()) * _multiplier | 0).toString(_hex)\n }\n const _canvasId = `_canvas-${_idMaker() + _idMaker()}`\n this._chart.canvas.id = _canvasId\n return _canvasId\n }\n\n // eslint-disable-next-line no-nested-ternary\n const PREFIX = window.CoreUIDefaults ? window.CoreUIDefaults.prefix ? window.CoreUIDefaults.prefix : 'c-' : 'c-'\n\n const ClassName = {\n ABOVE : `${PREFIX}above`,\n BELOW : `${PREFIX}below`,\n CHARTJS_TOOLTIP : `${PREFIX}chartjs-tooltip`,\n NO_TRANSFORM : `${PREFIX}no-transform`,\n TOOLTIP_BODY : `${PREFIX}tooltip-body`,\n TOOLTIP_BODY_ITEM : `${PREFIX}tooltip-body-item`,\n TOOLTIP_BODY_ITEM_COLOR : `${PREFIX}tooltip-body-item-color`,\n TOOLTIP_BODY_ITEM_LABEL : `${PREFIX}tooltip-body-item-label`,\n TOOLTIP_BODY_ITEM_VALUE : `${PREFIX}tooltip-body-item-value`,\n TOOLTIP_HEADER : `${PREFIX}tooltip-header`,\n TOOLTIP_HEADER_ITEM : `${PREFIX}tooltip-header-item`\n }\n\n const Selector = {\n DIV : 'div',\n SPAN : 'span',\n TOOLTIP : `${this._chart.canvas.id || _setCanvasId()}-tooltip`\n }\n\n let tooltip = document.getElementById(Selector.TOOLTIP)\n\n if (!tooltip) {\n tooltip = document.createElement('div')\n tooltip.id = Selector.TOOLTIP\n tooltip.className = ClassName.CHARTJS_TOOLTIP\n this._chart.canvas.parentNode.appendChild(tooltip)\n }\n\n // Hide if no tooltip\n if (tooltipModel.opacity === 0) {\n tooltip.style.opacity = 0\n return\n }\n\n // Set caret Position\n tooltip.classList.remove(ClassName.ABOVE, ClassName.BELOW, ClassName.NO_TRANSFORM)\n if (tooltipModel.yAlign) {\n tooltip.classList.add(tooltipModel.yAlign)\n } else {\n tooltip.classList.add(ClassName.NO_TRANSFORM)\n }\n\n // Set Text\n if (tooltipModel.body) {\n const titleLines = tooltipModel.title || []\n\n const tooltipHeader = document.createElement(Selector.DIV)\n tooltipHeader.className = ClassName.TOOLTIP_HEADER\n\n titleLines.forEach((title) => {\n const tooltipHeaderTitle = document.createElement(Selector.DIV)\n tooltipHeaderTitle.className = ClassName.TOOLTIP_HEADER_ITEM\n tooltipHeaderTitle.innerHTML = title\n tooltipHeader.appendChild(tooltipHeaderTitle)\n })\n\n const tooltipBody = document.createElement(Selector.DIV)\n tooltipBody.className = ClassName.TOOLTIP_BODY\n\n const tooltipBodyItems = tooltipModel.body.map((item) => item.lines)\n tooltipBodyItems.forEach((item, i) => {\n const tooltipBodyItem = document.createElement(Selector.DIV)\n tooltipBodyItem.className = ClassName.TOOLTIP_BODY_ITEM\n\n const colors = tooltipModel.labelColors[i]\n\n const tooltipBodyItemColor = document.createElement(Selector.SPAN)\n tooltipBodyItemColor.className = ClassName.TOOLTIP_BODY_ITEM_COLOR\n tooltipBodyItemColor.style.backgroundColor = colors.backgroundColor\n\n tooltipBodyItem.appendChild(tooltipBodyItemColor)\n\n if (item[0].split(':').length > 1) {\n const tooltipBodyItemLabel = document.createElement(Selector.SPAN)\n tooltipBodyItemLabel.className = ClassName.TOOLTIP_BODY_ITEM_LABEL\n tooltipBodyItemLabel.innerHTML = item[0].split(': ')[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemLabel)\n\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0].split(': ').pop()\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n } else {\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n }\n\n tooltipBody.appendChild(tooltipBodyItem)\n })\n\n tooltip.innerHTML = ''\n\n tooltip.appendChild(tooltipHeader)\n tooltip.appendChild(tooltipBody)\n }\n\n const position = this._chart.canvas.getBoundingClientRect()\n\n const positionY = this._chart.canvas.offsetTop\n const positionX = this._chart.canvas.offsetLeft\n\n let positionLeft = positionX + tooltipModel.caretX\n const positionTop = positionY + tooltipModel.caretY\n // eslint-disable-next-line\n const halfWidth = tooltipModel.width / 2\n\n if (positionLeft + halfWidth > position.width) {\n positionLeft -= halfWidth\n } else if (positionLeft < halfWidth) {\n positionLeft += halfWidth\n }\n\n // Display, position, and set styles for font\n tooltip.style.opacity = 1\n tooltip.style.left = `${positionLeft}px`\n tooltip.style.top = `${positionTop}px`\n}\n\nexport default customTooltips\n"]} \ No newline at end of file diff --git a/custom-tooltips/dist/js/coreui-chartjs.js.map b/custom-tooltips/dist/js/coreui-chartjs.js.map deleted file mode 100644 index 22fd9cf..0000000 --- a/custom-tooltips/dist/js/coreui-chartjs.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"coreui-chartjs.js","sources":["../../js/src/custom-tooltips.js","../../js/index.umd.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Custom Tooltips for Chart.js (v2.0.0-alpha.0): custom-tooltips.js\n * Licensed under MIT (https://coreui.io/plugins/chart.js)\n * --------------------------------------------------------------------------\n */\n\nfunction customTooltips(tooltipModel) {\n // Add unique id if not exist\n const _setCanvasId = () => {\n const _idMaker = () => {\n const _hex = 16\n const _multiplier = 0x10000\n return ((1 + Math.random()) * _multiplier | 0).toString(_hex)\n }\n const _canvasId = `_canvas-${_idMaker() + _idMaker()}`\n this._chart.canvas.id = _canvasId\n return _canvasId\n }\n\n // eslint-disable-next-line no-nested-ternary\n const PREFIX = window.CoreUIDefaults ? window.CoreUIDefaults.prefix ? window.CoreUIDefaults.prefix : 'c-' : 'c-'\n\n const ClassName = {\n ABOVE : `${PREFIX}above`,\n BELOW : `${PREFIX}below`,\n CHARTJS_TOOLTIP : `${PREFIX}chartjs-tooltip`,\n NO_TRANSFORM : `${PREFIX}no-transform`,\n TOOLTIP_BODY : `${PREFIX}tooltip-body`,\n TOOLTIP_BODY_ITEM : `${PREFIX}tooltip-body-item`,\n TOOLTIP_BODY_ITEM_COLOR : `${PREFIX}tooltip-body-item-color`,\n TOOLTIP_BODY_ITEM_LABEL : `${PREFIX}tooltip-body-item-label`,\n TOOLTIP_BODY_ITEM_VALUE : `${PREFIX}tooltip-body-item-value`,\n TOOLTIP_HEADER : `${PREFIX}tooltip-header`,\n TOOLTIP_HEADER_ITEM : `${PREFIX}tooltip-header-item`\n }\n\n const Selector = {\n DIV : 'div',\n SPAN : 'span',\n TOOLTIP : `${this._chart.canvas.id || _setCanvasId()}-tooltip`\n }\n\n let tooltip = document.getElementById(Selector.TOOLTIP)\n\n if (!tooltip) {\n tooltip = document.createElement('div')\n tooltip.id = Selector.TOOLTIP\n tooltip.className = ClassName.CHARTJS_TOOLTIP\n this._chart.canvas.parentNode.appendChild(tooltip)\n }\n\n // Hide if no tooltip\n if (tooltipModel.opacity === 0) {\n tooltip.style.opacity = 0\n return\n }\n\n // Set caret Position\n tooltip.classList.remove(ClassName.ABOVE, ClassName.BELOW, ClassName.NO_TRANSFORM)\n if (tooltipModel.yAlign) {\n tooltip.classList.add(tooltipModel.yAlign)\n } else {\n tooltip.classList.add(ClassName.NO_TRANSFORM)\n }\n\n // Set Text\n if (tooltipModel.body) {\n const titleLines = tooltipModel.title || []\n\n const tooltipHeader = document.createElement(Selector.DIV)\n tooltipHeader.className = ClassName.TOOLTIP_HEADER\n\n titleLines.forEach((title) => {\n const tooltipHeaderTitle = document.createElement(Selector.DIV)\n tooltipHeaderTitle.className = ClassName.TOOLTIP_HEADER_ITEM\n tooltipHeaderTitle.innerHTML = title\n tooltipHeader.appendChild(tooltipHeaderTitle)\n })\n\n const tooltipBody = document.createElement(Selector.DIV)\n tooltipBody.className = ClassName.TOOLTIP_BODY\n\n const tooltipBodyItems = tooltipModel.body.map((item) => item.lines)\n tooltipBodyItems.forEach((item, i) => {\n const tooltipBodyItem = document.createElement(Selector.DIV)\n tooltipBodyItem.className = ClassName.TOOLTIP_BODY_ITEM\n\n const colors = tooltipModel.labelColors[i]\n\n const tooltipBodyItemColor = document.createElement(Selector.SPAN)\n tooltipBodyItemColor.className = ClassName.TOOLTIP_BODY_ITEM_COLOR\n tooltipBodyItemColor.style.backgroundColor = colors.backgroundColor\n\n tooltipBodyItem.appendChild(tooltipBodyItemColor)\n\n if (item[0].split(':').length > 1) {\n const tooltipBodyItemLabel = document.createElement(Selector.SPAN)\n tooltipBodyItemLabel.className = ClassName.TOOLTIP_BODY_ITEM_LABEL\n tooltipBodyItemLabel.innerHTML = item[0].split(': ')[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemLabel)\n\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0].split(': ').pop()\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n } else {\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n }\n\n tooltipBody.appendChild(tooltipBodyItem)\n })\n\n tooltip.innerHTML = ''\n\n tooltip.appendChild(tooltipHeader)\n tooltip.appendChild(tooltipBody)\n }\n\n const position = this._chart.canvas.getBoundingClientRect()\n\n const positionY = this._chart.canvas.offsetTop\n const positionX = this._chart.canvas.offsetLeft\n\n let positionLeft = positionX + tooltipModel.caretX\n const positionTop = positionY + tooltipModel.caretY\n // eslint-disable-next-line\n const halfWidth = tooltipModel.width / 2\n\n if (positionLeft + halfWidth > position.width) {\n positionLeft -= halfWidth\n } else if (positionLeft < halfWidth) {\n positionLeft += halfWidth\n }\n\n // Display, position, and set styles for font\n tooltip.style.opacity = 1\n tooltip.style.left = `${positionLeft}px`\n tooltip.style.top = `${positionTop}px`\n}\n\nexport default customTooltips\n","/**\n * --------------------------------------------------------------------------\n * Custom Tooltips for Chart.js (v2.0.0-alpha.0): index.umd.js\n * Licensed under MIT (https://github.com/@coreui/coreui-chartjs/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport customTooltips from './src/custom-tooltips'\n\nexport default {\n customTooltips\n}\n"],"names":["customTooltips","tooltipModel","_setCanvasId","_idMaker","_hex","_multiplier","Math","random","toString","_canvasId","_chart","canvas","id","PREFIX","window","CoreUIDefaults","prefix","ClassName","ABOVE","BELOW","CHARTJS_TOOLTIP","NO_TRANSFORM","TOOLTIP_BODY","TOOLTIP_BODY_ITEM","TOOLTIP_BODY_ITEM_COLOR","TOOLTIP_BODY_ITEM_LABEL","TOOLTIP_BODY_ITEM_VALUE","TOOLTIP_HEADER","TOOLTIP_HEADER_ITEM","Selector","DIV","SPAN","TOOLTIP","tooltip","document","getElementById","createElement","className","parentNode","appendChild","opacity","style","classList","remove","yAlign","add","body","titleLines","title","tooltipHeader","forEach","tooltipHeaderTitle","innerHTML","tooltipBody","tooltipBodyItems","map","item","lines","i","tooltipBodyItem","colors","labelColors","tooltipBodyItemColor","backgroundColor","split","length","tooltipBodyItemLabel","tooltipBodyItemValue","pop","position","getBoundingClientRect","positionY","offsetTop","positionX","offsetLeft","positionLeft","caretX","positionTop","caretY","halfWidth","width","left","top"],"mappings":";;;;;;;;;;;EAAA;;;;;;EAOA,SAASA,cAAT,CAAwBC,YAAxB,EAAsC;EAAA;;EACpC;EACA,MAAMC,YAAY,GAAG,SAAfA,YAAe,GAAM;EACzB,QAAMC,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,UAAMC,IAAI,GAAG,EAAb;EACA,UAAMC,WAAW,GAAG,OAApB;EACA,aAAO,CAAC,CAAC,IAAIC,IAAI,CAACC,MAAL,EAAL,IAAsBF,WAAtB,GAAoC,CAArC,EAAwCG,QAAxC,CAAiDJ,IAAjD,CAAP;EACD,KAJD;;EAKA,QAAMK,SAAS,iBAAcN,QAAQ,KAAKA,QAAQ,EAAnC,CAAf;;EACA,IAAA,KAAI,CAACO,MAAL,CAAYC,MAAZ,CAAmBC,EAAnB,GAAwBH,SAAxB;EACA,WAAOA,SAAP;EACD,GATD,CAFoC;;;EAcpC,MAAMI,MAAM,GAAGC,MAAM,CAACC,cAAP,GAAwBD,MAAM,CAACC,cAAP,CAAsBC,MAAtB,GAA+BF,MAAM,CAACC,cAAP,CAAsBC,MAArD,GAA8D,IAAtF,GAA6F,IAA5G;EAEA,MAAMC,SAAS,GAAG;EAChBC,IAAAA,KAAK,EAAwBL,MAAxB,UADW;EAEhBM,IAAAA,KAAK,EAAwBN,MAAxB,UAFW;EAGhBO,IAAAA,eAAe,EAAcP,MAAd,oBAHC;EAIhBQ,IAAAA,YAAY,EAAiBR,MAAjB,iBAJI;EAKhBS,IAAAA,YAAY,EAAiBT,MAAjB,iBALI;EAMhBU,IAAAA,iBAAiB,EAAYV,MAAZ,sBAND;EAOhBW,IAAAA,uBAAuB,EAAMX,MAAN,4BAPP;EAQhBY,IAAAA,uBAAuB,EAAMZ,MAAN,4BARP;EAShBa,IAAAA,uBAAuB,EAAMb,MAAN,4BATP;EAUhBc,IAAAA,cAAc,EAAed,MAAf,mBAVE;EAWhBe,IAAAA,mBAAmB,EAAUf,MAAV;EAXH,GAAlB;EAcA,MAAMgB,QAAQ,GAAG;EACfC,IAAAA,GAAG,EAAO,KADK;EAEfC,IAAAA,IAAI,EAAM,MAFK;EAGfC,IAAAA,OAAO,GAAM,KAAKtB,MAAL,CAAYC,MAAZ,CAAmBC,EAAnB,IAAyBV,YAAY,EAA3C;EAHQ,GAAjB;EAMA,MAAI+B,OAAO,GAAGC,QAAQ,CAACC,cAAT,CAAwBN,QAAQ,CAACG,OAAjC,CAAd;;EAEA,MAAI,CAACC,OAAL,EAAc;EACZA,IAAAA,OAAO,GAAGC,QAAQ,CAACE,aAAT,CAAuB,KAAvB,CAAV;EACAH,IAAAA,OAAO,CAACrB,EAAR,GAAaiB,QAAQ,CAACG,OAAtB;EACAC,IAAAA,OAAO,CAACI,SAAR,GAAoBpB,SAAS,CAACG,eAA9B;;EACA,SAAKV,MAAL,CAAYC,MAAZ,CAAmB2B,UAAnB,CAA8BC,WAA9B,CAA0CN,OAA1C;EACD,GA3CmC;;;EA8CpC,MAAIhC,YAAY,CAACuC,OAAb,KAAyB,CAA7B,EAAgC;EAC9BP,IAAAA,OAAO,CAACQ,KAAR,CAAcD,OAAd,GAAwB,CAAxB;EACA;EACD,GAjDmC;;;EAoDpCP,EAAAA,OAAO,CAACS,SAAR,CAAkBC,MAAlB,CAAyB1B,SAAS,CAACC,KAAnC,EAA0CD,SAAS,CAACE,KAApD,EAA2DF,SAAS,CAACI,YAArE;;EACA,MAAIpB,YAAY,CAAC2C,MAAjB,EAAyB;EACvBX,IAAAA,OAAO,CAACS,SAAR,CAAkBG,GAAlB,CAAsB5C,YAAY,CAAC2C,MAAnC;EACD,GAFD,MAEO;EACLX,IAAAA,OAAO,CAACS,SAAR,CAAkBG,GAAlB,CAAsB5B,SAAS,CAACI,YAAhC;EACD,GAzDmC;;;EA4DpC,MAAIpB,YAAY,CAAC6C,IAAjB,EAAuB;EACrB,QAAMC,UAAU,GAAG9C,YAAY,CAAC+C,KAAb,IAAsB,EAAzC;EAEA,QAAMC,aAAa,GAAGf,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAAtB;EACAmB,IAAAA,aAAa,CAACZ,SAAd,GAA0BpB,SAAS,CAACU,cAApC;EAEAoB,IAAAA,UAAU,CAACG,OAAX,CAAmB,UAACF,KAAD,EAAW;EAC5B,UAAMG,kBAAkB,GAAGjB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAA3B;EACAqB,MAAAA,kBAAkB,CAACd,SAAnB,GAA+BpB,SAAS,CAACW,mBAAzC;EACAuB,MAAAA,kBAAkB,CAACC,SAAnB,GAA+BJ,KAA/B;EACAC,MAAAA,aAAa,CAACV,WAAd,CAA0BY,kBAA1B;EACD,KALD;EAOA,QAAME,WAAW,GAAGnB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAApB;EACAuB,IAAAA,WAAW,CAAChB,SAAZ,GAAwBpB,SAAS,CAACK,YAAlC;EAEA,QAAMgC,gBAAgB,GAAGrD,YAAY,CAAC6C,IAAb,CAAkBS,GAAlB,CAAsB,UAACC,IAAD;EAAA,aAAUA,IAAI,CAACC,KAAf;EAAA,KAAtB,CAAzB;EACAH,IAAAA,gBAAgB,CAACJ,OAAjB,CAAyB,UAACM,IAAD,EAAOE,CAAP,EAAa;EACpC,UAAMC,eAAe,GAAGzB,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACC,GAAhC,CAAxB;EACA6B,MAAAA,eAAe,CAACtB,SAAhB,GAA4BpB,SAAS,CAACM,iBAAtC;EAEA,UAAMqC,MAAM,GAAG3D,YAAY,CAAC4D,WAAb,CAAyBH,CAAzB,CAAf;EAEA,UAAMI,oBAAoB,GAAG5B,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;EACA+B,MAAAA,oBAAoB,CAACzB,SAArB,GAAiCpB,SAAS,CAACO,uBAA3C;EACAsC,MAAAA,oBAAoB,CAACrB,KAArB,CAA2BsB,eAA3B,GAA6CH,MAAM,CAACG,eAApD;EAEAJ,MAAAA,eAAe,CAACpB,WAAhB,CAA4BuB,oBAA5B;;EAEA,UAAIN,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,GAAd,EAAmBC,MAAnB,GAA4B,CAAhC,EAAmC;EACjC,YAAMC,oBAAoB,GAAGhC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;EACAmC,QAAAA,oBAAoB,CAAC7B,SAArB,GAAiCpB,SAAS,CAACQ,uBAA3C;EACAyC,QAAAA,oBAAoB,CAACd,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,IAAd,EAAoB,CAApB,CAAjC;EAEAL,QAAAA,eAAe,CAACpB,WAAhB,CAA4B2B,oBAA5B;EAEA,YAAMC,oBAAoB,GAAGjC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;EACAoC,QAAAA,oBAAoB,CAAC9B,SAArB,GAAiCpB,SAAS,CAACS,uBAA3C;EACAyC,QAAAA,oBAAoB,CAACf,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAAJ,CAAQQ,KAAR,CAAc,IAAd,EAAoBI,GAApB,EAAjC;EAEAT,QAAAA,eAAe,CAACpB,WAAhB,CAA4B4B,oBAA5B;EACD,OAZD,MAYO;EACL,YAAMA,qBAAoB,GAAGjC,QAAQ,CAACE,aAAT,CAAuBP,QAAQ,CAACE,IAAhC,CAA7B;;EACAoC,QAAAA,qBAAoB,CAAC9B,SAArB,GAAiCpB,SAAS,CAACS,uBAA3C;EACAyC,QAAAA,qBAAoB,CAACf,SAArB,GAAiCI,IAAI,CAAC,CAAD,CAArC;EAEAG,QAAAA,eAAe,CAACpB,WAAhB,CAA4B4B,qBAA5B;EACD;;EAEDd,MAAAA,WAAW,CAACd,WAAZ,CAAwBoB,eAAxB;EACD,KAjCD;EAmCA1B,IAAAA,OAAO,CAACmB,SAAR,GAAoB,EAApB;EAEAnB,IAAAA,OAAO,CAACM,WAAR,CAAoBU,aAApB;EACAhB,IAAAA,OAAO,CAACM,WAAR,CAAoBc,WAApB;EACD;;EAED,MAAMgB,QAAQ,GAAG,KAAK3D,MAAL,CAAYC,MAAZ,CAAmB2D,qBAAnB,EAAjB;;EAEA,MAAMC,SAAS,GAAG,KAAK7D,MAAL,CAAYC,MAAZ,CAAmB6D,SAArC;EACA,MAAMC,SAAS,GAAG,KAAK/D,MAAL,CAAYC,MAAZ,CAAmB+D,UAArC;EAEA,MAAIC,YAAY,GAAGF,SAAS,GAAGxE,YAAY,CAAC2E,MAA5C;EACA,MAAMC,WAAW,GAAGN,SAAS,GAAGtE,YAAY,CAAC6E,MAA7C,CA5HoC;;EA8HpC,MAAMC,SAAS,GAAG9E,YAAY,CAAC+E,KAAb,GAAqB,CAAvC;;EAEA,MAAIL,YAAY,GAAGI,SAAf,GAA2BV,QAAQ,CAACW,KAAxC,EAA+C;EAC7CL,IAAAA,YAAY,IAAII,SAAhB;EACD,GAFD,MAEO,IAAIJ,YAAY,GAAGI,SAAnB,EAA8B;EACnCJ,IAAAA,YAAY,IAAII,SAAhB;EACD,GApImC;;;EAuIpC9C,EAAAA,OAAO,CAACQ,KAAR,CAAcD,OAAd,GAAwB,CAAxB;EACAP,EAAAA,OAAO,CAACQ,KAAR,CAAcwC,IAAd,GAAwBN,YAAxB;EACA1C,EAAAA,OAAO,CAACQ,KAAR,CAAcyC,GAAd,GAAuBL,WAAvB;EACD;;ECjJD;;;;;;AAOA,AAEA,kBAAe;EACb7E,EAAAA,cAAc,EAAdA;EADa,CAAf;;;;;;;;"} \ No newline at end of file diff --git a/custom-tooltips/dist/js/coreui-chartjs.min.js b/custom-tooltips/dist/js/coreui-chartjs.min.js deleted file mode 100644 index a587feb..0000000 --- a/custom-tooltips/dist/js/coreui-chartjs.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * CoreUI Plugins - Chart.js for CoreUI 3 v2.0.0-alpha.1 (https://coreui.io) - * Copyright 2019 Łukasz Holeczek - * Licensed under MIT (https://coreui.io/plugins/chart.js) - */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e=e||self).coreui=e.coreui||{},e.coreui.ChartJS=t())}(this,(function(){"use strict";return{customTooltips:function(e){var t,a,o=this,n=window.CoreUIDefaults&&window.CoreUIDefaults.prefix?window.CoreUIDefaults.prefix:"c-",i={ABOVE:n+"above",BELOW:n+"below",CHARTJS_TOOLTIP:n+"chartjs-tooltip",NO_TRANSFORM:n+"no-transform",TOOLTIP_BODY:n+"tooltip-body",TOOLTIP_BODY_ITEM:n+"tooltip-body-item",TOOLTIP_BODY_ITEM_COLOR:n+"tooltip-body-item-color",TOOLTIP_BODY_ITEM_LABEL:n+"tooltip-body-item-label",TOOLTIP_BODY_ITEM_VALUE:n+"tooltip-body-item-value",TOOLTIP_HEADER:n+"tooltip-header",TOOLTIP_HEADER_ITEM:n+"tooltip-header-item"},l={DIV:"div",SPAN:"span",TOOLTIP:(this._chart.canvas.id||(t=function(){return(65536*(1+Math.random())|0).toString(16)},a="_canvas-"+(t()+t()),o._chart.canvas.id=a,a))+"-tooltip"},c=document.getElementById(l.TOOLTIP);if(c||((c=document.createElement("div")).id=l.TOOLTIP,c.className=i.CHARTJS_TOOLTIP,this._chart.canvas.parentNode.appendChild(c)),0!==e.opacity){if(c.classList.remove(i.ABOVE,i.BELOW,i.NO_TRANSFORM),e.yAlign?c.classList.add(e.yAlign):c.classList.add(i.NO_TRANSFORM),e.body){var s=e.title||[],r=document.createElement(l.DIV);r.className=i.TOOLTIP_HEADER,s.forEach((function(e){var t=document.createElement(l.DIV);t.className=i.TOOLTIP_HEADER_ITEM,t.innerHTML=e,r.appendChild(t)}));var d=document.createElement(l.DIV);d.className=i.TOOLTIP_BODY,e.body.map((function(e){return e.lines})).forEach((function(t,a){var o=document.createElement(l.DIV);o.className=i.TOOLTIP_BODY_ITEM;var n=e.labelColors[a],c=document.createElement(l.SPAN);if(c.className=i.TOOLTIP_BODY_ITEM_COLOR,c.style.backgroundColor=n.backgroundColor,o.appendChild(c),t[0].split(":").length>1){var s=document.createElement(l.SPAN);s.className=i.TOOLTIP_BODY_ITEM_LABEL,s.innerHTML=t[0].split(": ")[0],o.appendChild(s);var r=document.createElement(l.SPAN);r.className=i.TOOLTIP_BODY_ITEM_VALUE,r.innerHTML=t[0].split(": ").pop(),o.appendChild(r)}else{var O=document.createElement(l.SPAN);O.className=i.TOOLTIP_BODY_ITEM_VALUE,O.innerHTML=t[0],o.appendChild(O)}d.appendChild(o)})),c.innerHTML="",c.appendChild(r),c.appendChild(d)}var O=this._chart.canvas.getBoundingClientRect(),T=this._chart.canvas.offsetTop,p=this._chart.canvas.offsetLeft+e.caretX,_=T+e.caretY,m=e.width/2;p+m>O.width?p-=m:p {\n const _idMaker = () => {\n const _hex = 16\n const _multiplier = 0x10000\n return ((1 + Math.random()) * _multiplier | 0).toString(_hex)\n }\n const _canvasId = `_canvas-${_idMaker() + _idMaker()}`\n this._chart.canvas.id = _canvasId\n return _canvasId\n }\n\n // eslint-disable-next-line no-nested-ternary\n const PREFIX = window.CoreUIDefaults ? window.CoreUIDefaults.prefix ? window.CoreUIDefaults.prefix : 'c-' : 'c-'\n\n const ClassName = {\n ABOVE : `${PREFIX}above`,\n BELOW : `${PREFIX}below`,\n CHARTJS_TOOLTIP : `${PREFIX}chartjs-tooltip`,\n NO_TRANSFORM : `${PREFIX}no-transform`,\n TOOLTIP_BODY : `${PREFIX}tooltip-body`,\n TOOLTIP_BODY_ITEM : `${PREFIX}tooltip-body-item`,\n TOOLTIP_BODY_ITEM_COLOR : `${PREFIX}tooltip-body-item-color`,\n TOOLTIP_BODY_ITEM_LABEL : `${PREFIX}tooltip-body-item-label`,\n TOOLTIP_BODY_ITEM_VALUE : `${PREFIX}tooltip-body-item-value`,\n TOOLTIP_HEADER : `${PREFIX}tooltip-header`,\n TOOLTIP_HEADER_ITEM : `${PREFIX}tooltip-header-item`\n }\n\n const Selector = {\n DIV : 'div',\n SPAN : 'span',\n TOOLTIP : `${this._chart.canvas.id || _setCanvasId()}-tooltip`\n }\n\n let tooltip = document.getElementById(Selector.TOOLTIP)\n\n if (!tooltip) {\n tooltip = document.createElement('div')\n tooltip.id = Selector.TOOLTIP\n tooltip.className = ClassName.CHARTJS_TOOLTIP\n this._chart.canvas.parentNode.appendChild(tooltip)\n }\n\n // Hide if no tooltip\n if (tooltipModel.opacity === 0) {\n tooltip.style.opacity = 0\n return\n }\n\n // Set caret Position\n tooltip.classList.remove(ClassName.ABOVE, ClassName.BELOW, ClassName.NO_TRANSFORM)\n if (tooltipModel.yAlign) {\n tooltip.classList.add(tooltipModel.yAlign)\n } else {\n tooltip.classList.add(ClassName.NO_TRANSFORM)\n }\n\n // Set Text\n if (tooltipModel.body) {\n const titleLines = tooltipModel.title || []\n\n const tooltipHeader = document.createElement(Selector.DIV)\n tooltipHeader.className = ClassName.TOOLTIP_HEADER\n\n titleLines.forEach((title) => {\n const tooltipHeaderTitle = document.createElement(Selector.DIV)\n tooltipHeaderTitle.className = ClassName.TOOLTIP_HEADER_ITEM\n tooltipHeaderTitle.innerHTML = title\n tooltipHeader.appendChild(tooltipHeaderTitle)\n })\n\n const tooltipBody = document.createElement(Selector.DIV)\n tooltipBody.className = ClassName.TOOLTIP_BODY\n\n const tooltipBodyItems = tooltipModel.body.map((item) => item.lines)\n tooltipBodyItems.forEach((item, i) => {\n const tooltipBodyItem = document.createElement(Selector.DIV)\n tooltipBodyItem.className = ClassName.TOOLTIP_BODY_ITEM\n\n const colors = tooltipModel.labelColors[i]\n\n const tooltipBodyItemColor = document.createElement(Selector.SPAN)\n tooltipBodyItemColor.className = ClassName.TOOLTIP_BODY_ITEM_COLOR\n tooltipBodyItemColor.style.backgroundColor = colors.backgroundColor\n\n tooltipBodyItem.appendChild(tooltipBodyItemColor)\n\n if (item[0].split(':').length > 1) {\n const tooltipBodyItemLabel = document.createElement(Selector.SPAN)\n tooltipBodyItemLabel.className = ClassName.TOOLTIP_BODY_ITEM_LABEL\n tooltipBodyItemLabel.innerHTML = item[0].split(': ')[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemLabel)\n\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0].split(': ').pop()\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n } else {\n const tooltipBodyItemValue = document.createElement(Selector.SPAN)\n tooltipBodyItemValue.className = ClassName.TOOLTIP_BODY_ITEM_VALUE\n tooltipBodyItemValue.innerHTML = item[0]\n\n tooltipBodyItem.appendChild(tooltipBodyItemValue)\n }\n\n tooltipBody.appendChild(tooltipBodyItem)\n })\n\n tooltip.innerHTML = ''\n\n tooltip.appendChild(tooltipHeader)\n tooltip.appendChild(tooltipBody)\n }\n\n const position = this._chart.canvas.getBoundingClientRect()\n\n const positionY = this._chart.canvas.offsetTop\n const positionX = this._chart.canvas.offsetLeft\n\n let positionLeft = positionX + tooltipModel.caretX\n const positionTop = positionY + tooltipModel.caretY\n // eslint-disable-next-line\n const halfWidth = tooltipModel.width / 2\n\n if (positionLeft + halfWidth > position.width) {\n positionLeft -= halfWidth\n } else if (positionLeft < halfWidth) {\n positionLeft += halfWidth\n }\n\n // Display, position, and set styles for font\n tooltip.style.opacity = 1\n tooltip.style.left = `${positionLeft}px`\n tooltip.style.top = `${positionTop}px`\n}\n\nexport default customTooltips\n"]} \ No newline at end of file diff --git a/custom-tooltips/package-lock.json b/custom-tooltips/package-lock.json deleted file mode 100644 index 9558a50..0000000 --- a/custom-tooltips/package-lock.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "@coreui/coreui-chartjs", - "version": "2.0.0-alpha.1", - "lockfileVersion": 1 -} diff --git a/custom-tooltips/package.json b/custom-tooltips/package.json deleted file mode 100644 index b046def..0000000 --- a/custom-tooltips/package.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "name": "@coreui/coreui-chartjs", - "version": "2.0.0-alpha.1", - "description": "CoreUI custom tooltips", - "keywords": [ - "chart", - "chart.js", - "coreui", - "tooltips" - ], - "homepage": "https://coreui.io", - "bugs": { - "url": "https://github.com/coreui/coreui-plugin-chartjs-custom-tooltips/issues", - "email": "support@coreui.io" - }, - "license": "MIT", - "author": { - "name": "Łukasz Holeczek", - "url": "https://github.com/mrholek" - }, - "contributors": [ - { - "name": "Andrzej Kopański", - "url": "https://github.com/xidedix" - } - ], - "files": [ - "dist/", - "js/", - "scss/" - ], - "style": "dist/css/coreui-chartjs.css", - "sass": "scss/coreui-chartjs.scss", - "main": "dist/js/coreui-chartjs.js", - "module": "dist/js/coreui-chartjs.esm.js", - "repository": { - "type": "git", - "url": "https://githubom/coreui/coreui-plugin-chartjs-custom-tooltips.git" - }, - "scripts": { - "css": "npm-run-all --sequential css-compile* css-prefix* css-minify*", - "css-compile": "node-sass --output-style expanded --source-map true --source-map-contents true --precision 8 scss/style.scss dist/css/coreui-chartjs.css", - "css-minify": "cleancss --level 2 --format breaksWith=lf --source-map --source-map-inline-sources --output dist/css/coreui-chartjs.min.css dist/css/coreui-chartjs.css", - "css-prefix": "postcss --config build/postcss.config.js --replace \"dist/css/*.css\" \"!dist/css/*.min.css\"", - "clean": "rimraf dist", - "dist": "npm-run-all clean css js", - "increment-version": "node build/increment-version.js", - "js": "npm-run-all js-compile* js-minify* js-lint", - "js-lint": "eslint js/", - "js-compile": "npm-run-all --parallel js-compile-*", - "js-compile-standalone": "rollup --environment BUNDLE:false --config build/rollup.config.js --sourcemap", - "js-compile-standalone-esm": "rollup --environment ESM:true,BUNDLE:false --config build/rollup.config.js --sourcemap", - "js-compile-bundle": "rollup --environment BUNDLE:true --config build/rollup.config.js --sourcemap", - "js-minify-main": "npm-run-all js-minify-standalone* js-minify-bundle", - "js-minify-standalone": "terser --compress typeofs=false --mangle --comments \"/^!/\" --source-map \"content=dist/js/coreui-chartjs.js.map,includeSources,url=coreui-chartjs.min.js.map\" --output dist/js/coreui-chartjs.min.js dist/js/coreui-chartjs.js", - "js-minify-standalone-esm": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/coreui-chartjs.esm.js.map,includeSources,url=coreui-chartjs.esm.min.js.map\" --output dist/js/coreui-chartjs.esm.min.js dist/js/coreui-chartjs.esm.js", - "js-minify-bundle": "terser --compress typeofs=false --mangle --comments \"/^!/\" --source-map \"content=dist/js/coreui-chartjs.bundle.js.map,includeSources,url=coreui-chartjs.bundle.min.js.map\" --output dist/js/coreui-chartjs.bundle.min.js dist/js/coreui-chartjs.bundle.js", - "release-version": "node build/change-version.js", - "watch-js": "nodemon --ignore dist/ -e js -x npm run js", - "build": "npm-run-all build:roll js", - "build:roll": "rollup --config build/rollup.config.js", - "dev": "rollup --config build/rollup.config.js --watch" - }, - "engines": { - "node": ">=6" - }, - "browserslist": [ - "last 1 major version", - ">= 1%", - "Chrome >= 45", - "Firefox >= 38", - "Edge >= 12", - "Explorer >= 10", - "iOS >= 9", - "Safari >= 9", - "Android >= 4.4", - "Opera >= 30" - ] -} diff --git a/custom-tooltips/dist/css/coreui-chartjs.css b/dist/css/coreui-chartjs.css similarity index 94% rename from custom-tooltips/dist/css/coreui-chartjs.css rename to dist/css/coreui-chartjs.css index 3c1929a..b04a4aa 100644 --- a/custom-tooltips/dist/css/coreui-chartjs.css +++ b/dist/css/coreui-chartjs.css @@ -1,7 +1,7 @@ @charset "UTF-8"; /*! * CoreUI Plugins - Chart.js for CoreUI 3 - * @version v2.0.0-alpha.0 + * @version vv2.0.0-beta.0 * @link https://coreui.io * Copyright (c) 2019 creativeLabs Łukasz Holeczek * Licensed under MIT (https://coreui.io/license/plugins/chart.js) @@ -54,4 +54,4 @@ margin-left: auto; font-weight: 700; } -/*# sourceMappingURL=coreui-chartjs.css.map */ \ No newline at end of file +/*# sourceMappingURL=coreui-chartjs.css.map */ diff --git a/dist/css/coreui-chartjs.css.map b/dist/css/coreui-chartjs.css.map new file mode 100644 index 0000000..38dab34 --- /dev/null +++ b/dist/css/coreui-chartjs.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["coreui-chartjs.css","../../scss/style.scss","../../scss/_tooltips.scss","../../node_modules/@coreui/coreui/scss/variables/_z-index.scss","../../node_modules/@coreui/coreui/scss/mixins/_border-radius.scss","../../node_modules/@coreui/coreui/scss/variables/components/_shared.scss","../../node_modules/@coreui/coreui/scss/variables/_typography.scss","../../node_modules/@coreui/coreui/scss/variables/_spacing.scss"],"names":[],"mappings":"AAAA,gBAAgB;ACAhB;;;;;;EDOE;AELF;EACE,kBAAkB;EAClB,aCE0B;EDD1B,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,uBAAuC;EACvC,WAAW;EACX,oBAAoB;EACpB,8BAA6B;EAC7B,UAAU;EACV,0BAA6C;EAC7C,qCAA6B;EAA7B,6BAA6B;EER3B,sBCkBgC;ALFpC;;AEnBA;EAeI,qBAA6B;AFQjC;;AEvBA;EAmBI,sBITgD;EJUhD,gBIL6B;ANajC;;AE5BA;EAwBI,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,sBIhBgD;EJiBhD,mBAAmB;AFQvB;;AEnCA;EA+BI,qBAAqB;EACrB,eIxBiC;EJyBjC,gBIzBiC;EJ0BjC,sBI1BiC;ANkCrC;;AE1CA;EAsCI,kBKhCS;ELiCT,iBAAiB;EACjB,gBIzB6B;ANiCjC","file":"coreui-chartjs.css","sourcesContent":["@charset \"UTF-8\";\n/*!\n * CoreUI Plugins - Chart.js for CoreUI 3\n * @version vv2.0.0-beta.0\n * @link https://coreui.io\n * Copyright (c) 2019 creativeLabs Łukasz Holeczek\n * Licensed under MIT (https://coreui.io/license/plugins/chart.js)\n */\n.c-chartjs-tooltip {\n position: absolute;\n z-index: 1021;\n display: flex;\n flex-direction: column;\n padding: 0.25rem 0.5rem;\n color: #fff;\n pointer-events: none;\n background: rgba(0, 0, 0, 0.7);\n opacity: 0;\n transition: all 0.25s ease;\n transform: translate(-50%, 0);\n border-radius: 0.25rem;\n}\n\n.c-chartjs-tooltip .c-tooltip-header {\n margin-bottom: 0.5rem;\n}\n\n.c-chartjs-tooltip .c-tooltip-header-item {\n font-size: 0.765625rem;\n font-weight: 700;\n}\n\n.c-chartjs-tooltip .c-tooltip-body-item {\n display: flex;\n align-items: center;\n font-size: 0.765625rem;\n white-space: nowrap;\n}\n\n.c-chartjs-tooltip .c-tooltip-body-item-color {\n display: inline-block;\n width: 0.875rem;\n height: 0.875rem;\n margin-right: 0.875rem;\n}\n\n.c-chartjs-tooltip .c-tooltip-body-item-value {\n padding-left: 1rem;\n margin-left: auto;\n font-weight: 700;\n}\n\n/*# sourceMappingURL=coreui-chartjs.css.map */","/*!\n * CoreUI Plugins - Chart.js for CoreUI 3\n * @version vv2.0.0-beta.0\n * @link https://coreui.io\n * Copyright (c) 2019 creativeLabs Łukasz Holeczek\n * Licensed under MIT (https://coreui.io/license/plugins/chart.js)\n */\n\n@import \"variables\";\n@import \"tooltips\";\n","// Custom tooltips\n\n.c-chartjs-tooltip {\n position: absolute;\n z-index: $zindex-sticky + 1;\n display: flex;\n flex-direction: column;\n padding: ($spacer * .25) ($spacer * .5);\n color: #fff;\n pointer-events: none;\n background: rgba(0, 0, 0, .7);\n opacity: 0;\n transition: all $layout-transition-speed ease;\n transform: translate(-50%, 0);\n @include border-radius($border-radius);\n\n .c-tooltip-header {\n margin-bottom: ($spacer * .5);\n }\n\n .c-tooltip-header-item {\n font-size: $font-size-sm;\n font-weight: $font-weight-bold;\n }\n\n .c-tooltip-body-item {\n display: flex;\n align-items: center;\n font-size: $font-size-sm;\n white-space: nowrap;\n }\n\n .c-tooltip-body-item-color {\n display: inline-block;\n width: $font-size-base;\n height: $font-size-base;\n margin-right: $font-size-base;\n }\n\n .c-tooltip-body-item-value {\n padding-left: $spacer;\n margin-left: auto;\n font-weight: $font-weight-bold;\n }\n}\n","// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n","// stylelint-disable property-blacklist\n// Single side border-radius\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: $radius;\n }\n}\n","\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-200 !default;\n\n$border-theme-map: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$border-theme-map: map-merge(\n (\n light: (\n \"border-color\": $border-color\n )\n ),\n $border-theme-map\n);\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-color: $body-color !default;\n$component-bg: $white !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n","// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: .875rem !default; // was: 1rem\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-700 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .2) !default;\n$hr-border-width: $border-width !default;\n\n$vr-color-bg: rgba($black, .2) !default;\n$vr-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n// Icons\n//\n// Style .c-icon element.\n\n$icon-size-base: 1rem !default; // was: 1rem\n$icon-size-sm: $icon-size-base * .875 !default;\n$icon-size-lg: $icon-size-base * 1.25 !default;\n$icon-size-xl: $icon-size-base * 1.5 !default;\n","\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n"]} diff --git a/custom-tooltips/dist/css/coreui-chartjs.min.css b/dist/css/coreui-chartjs.min.css similarity index 93% rename from custom-tooltips/dist/css/coreui-chartjs.min.css rename to dist/css/coreui-chartjs.min.css index 402f70b..56ce497 100644 --- a/custom-tooltips/dist/css/coreui-chartjs.min.css +++ b/dist/css/coreui-chartjs.min.css @@ -1,8 +1,8 @@ @charset "UTF-8";/*! * CoreUI Plugins - Chart.js for CoreUI 3 - * @version v2.0.0-alpha.0 + * @version vv2.0.0-beta.0 * @link https://coreui.io * Copyright (c) 2019 creativeLabs Łukasz Holeczek * Licensed under MIT (https://coreui.io/license/plugins/chart.js) */.c-chartjs-tooltip{position:absolute;z-index:1021;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:.25rem .5rem;color:#fff;pointer-events:none;background:rgba(0,0,0,.7);opacity:0;transition:all .25s ease;-webkit-transform:translate(-50%,0);transform:translate(-50%,0);border-radius:.25rem}.c-chartjs-tooltip .c-tooltip-header{margin-bottom:.5rem}.c-chartjs-tooltip .c-tooltip-header-item{font-size:.765625rem;font-weight:700}.c-chartjs-tooltip .c-tooltip-body-item{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;font-size:.765625rem;white-space:nowrap}.c-chartjs-tooltip .c-tooltip-body-item-color{display:inline-block;width:.875rem;height:.875rem;margin-right:.875rem}.c-chartjs-tooltip .c-tooltip-body-item-value{padding-left:1rem;margin-left:auto;font-weight:700} -/*# sourceMappingURL=coreui-chartjs.min.css.map */ \ No newline at end of file +/*# sourceMappingURL=coreui-chartjs.min.css.map */ diff --git a/dist/css/coreui-chartjs.min.css.map b/dist/css/coreui-chartjs.min.css.map new file mode 100644 index 0000000..ab25193 --- /dev/null +++ b/dist/css/coreui-chartjs.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/style.scss","../../scss/_tooltips.scss","../../node_modules/@coreui/coreui/scss/mixins/_border-radius.scss"],"names":[],"mappings":"iBAAA;;;;;;ACEA,mBACE,SAAA,SACA,QAAA,KACA,QAAA,YAAA,QAAA,KACA,mBAAA,OAAA,eAAA,OACA,QAAA,OAAA,MACA,MAAA,KACA,eAAA,KACA,WAAA,eACA,QAAA,EACA,WAAA,IAAA,KAAA,KACA,kBAAA,kBAAA,UAAA,kBCRE,cAAA,ODHJ,qCAeI,cAAA,MAfJ,0CAmBI,UAAA,WACA,YAAA,IApBJ,wCAwBI,QAAA,YAAA,QAAA,KACA,eAAA,OAAA,YAAA,OACA,UAAA,WACA,YAAA,OA3BJ,8CA+BI,QAAA,aACA,MAAA,QACA,OAAA,QACA,aAAA,QAlCJ,8CAsCI,aAAA,KACA,YAAA,KACA,YAAA","sourcesContent":["/*!\n * CoreUI Plugins - Chart.js for CoreUI 3\n * @version vv2.0.0-beta.0\n * @link https://coreui.io\n * Copyright (c) 2019 creativeLabs Łukasz Holeczek\n * Licensed under MIT (https://coreui.io/license/plugins/chart.js)\n */\n\n@import \"variables\";\n@import \"tooltips\";\n","// Custom tooltips\n\n.c-chartjs-tooltip {\n position: absolute;\n z-index: $zindex-sticky + 1;\n display: flex;\n flex-direction: column;\n padding: ($spacer * .25) ($spacer * .5);\n color: #fff;\n pointer-events: none;\n background: rgba(0, 0, 0, .7);\n opacity: 0;\n transition: all $layout-transition-speed ease;\n transform: translate(-50%, 0);\n @include border-radius($border-radius);\n\n .c-tooltip-header {\n margin-bottom: ($spacer * .5);\n }\n\n .c-tooltip-header-item {\n font-size: $font-size-sm;\n font-weight: $font-weight-bold;\n }\n\n .c-tooltip-body-item {\n display: flex;\n align-items: center;\n font-size: $font-size-sm;\n white-space: nowrap;\n }\n\n .c-tooltip-body-item-color {\n display: inline-block;\n width: $font-size-base;\n height: $font-size-base;\n margin-right: $font-size-base;\n }\n\n .c-tooltip-body-item-value {\n padding-left: $spacer;\n margin-left: auto;\n font-weight: $font-weight-bold;\n }\n}\n","// stylelint-disable property-blacklist\n// Single side border-radius\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: $radius;\n }\n}\n"]} diff --git a/dist/js/coreui-chartjs.bundle.js b/dist/js/coreui-chartjs.bundle.js new file mode 100644 index 0000000..e67b73e --- /dev/null +++ b/dist/js/coreui-chartjs.bundle.js @@ -0,0 +1,16312 @@ +/*! + * CoreUI Plugins - Chart.js for CoreUI 3 v2.0.0-beta.0 (https://coreui.io) + * Copyright 2019 Łukasz Holeczek + * Licensed under MIT (https://coreui.io/plugins/chart.js) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, (global.coreui = global.coreui || {}, global.coreui.ChartJS = factory())); +}(this, (function () { 'use strict'; + + /*! + * Chart.js v2.9.2 + * https://www.chartjs.org + * (c) 2019 Chart.js Contributors + * Released under the MIT License + */ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(function() { try { return require('moment'); } catch(e) { } }()) : + typeof define === 'function' && define.amd ? define(['require'], function(require) { return factory(function() { try { return require('moment'); } catch(e) { } }()); }) : + (global = global || self, global.Chart = factory(global.moment)); + }(undefined, (function (moment) { + moment = moment && moment.hasOwnProperty('default') ? moment['default'] : moment; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } + + var colorName = { + "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 conversions = createCommonjsModule(function (module) { + /* MIT license */ + + + // NOTE: conversions should only return primitive values (i.e. arrays, or + // values that give correct `typeof` results). + // do not use box values types (i.e. Number(), String(), etc.) + + var reverseKeywords = {}; + for (var key in colorName) { + if (colorName.hasOwnProperty(key)) { + reverseKeywords[colorName[key]] = key; + } + } + + var convert = module.exports = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} + }; + + // hide .channels and .labels properties + for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } + + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } + + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } + + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); + } + } + + convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; + + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } + + h = Math.min(h * 60, 360); + + if (h < 0) { + h += 360; + } + + l = (min + max) / 2; + + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } + + return [h, s * 100, l * 100]; + }; + + convert.rgb.hsv = function (rgb) { + var rdif; + var gdif; + var bdif; + var h; + var s; + + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var v = Math.max(r, g, b); + var diff = v - Math.min(r, g, b); + var diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; + + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + + return [ + h * 360, + s * 100, + v * 100 + ]; + }; + + convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); + + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); + + return [h, w * 100, b * 100]; + }; + + convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; + + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; + + return [c * 100, m * 100, y * 100, k * 100]; + }; + + /** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ + function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); + } + + convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } + + var currentClosestDistance = Infinity; + var currentClosestKeyword; + + for (var keyword in colorName) { + if (colorName.hasOwnProperty(keyword)) { + var value = colorName[keyword]; + + // Compute comparative distance + var distance = comparativeDistance(rgb, value); + + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + } + + return currentClosestKeyword; + }; + + convert.keyword.rgb = function (keyword) { + return colorName[keyword]; + }; + + convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); + + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + + return [x * 100, y * 100, z * 100]; + }; + + convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var 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]; + }; + + convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var 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); + if (t3 < 0) { + t3++; + } + if (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; + }; + + convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; + + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); + + return [h, sv * 100, v * 100]; + }; + + convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; + + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; + + 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]; + } + }; + + convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; + + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; + + return [h, sl * 100, l * 100]; + }; + + // http://dev.w3.org/csswg/css-color/#hwb-to-rgb + convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var 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 + + var r; + var g; + var b; + 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]; + }; + + convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var 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]; + }; + + convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var 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 * 12.92; + + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; + + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : 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]; + }; + + convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var 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]; + }; + + convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; + + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; + + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(z, 3); + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; + + x *= 95.047; + y *= 100; + z *= 108.883; + + return [x, y, z]; + }; + + convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var 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]; + }; + + convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; + + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); + + return [l, a, b]; + }; + + convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization + + value = Math.round(value / 50); + + if (value === 0) { + return 30; + } + + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); + + if (value === 2) { + ansi += 60; + } + + return ansi; + }; + + convert.hsv.ansi16 = function (args) { + // optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); + }; + + convert.rgb.ansi256 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + + // we use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } + + if (r > 248) { + return 231; + } + + return Math.round(((r - 8) / 247) * 24) + 232; + } + + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); + + return ansi; + }; + + convert.ansi16.rgb = function (args) { + var color = args % 10; + + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } + + color = color / 10.5 * 255; + + return [color, color, color]; + } + + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; + + return [r, g, b]; + }; + + convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; + } + + args -= 16; + + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; + + return [r, g, b]; + }; + + convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; + }; + + convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } + + var colorString = match[0]; + + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); + } + + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; + + return [r, g, b]; + }; + + convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; + + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } + + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma + 4; + } + + hue /= 6; + hue %= 1; + + return [hue * 360, chroma * 100, grayscale * 100]; + }; + + convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; + + if (l < 0.5) { + c = 2.0 * s * l; + } else { + c = 2.0 * s * (1.0 - l); + } + + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } + + return [hsl[0], c * 100, f * 100]; + }; + + convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; + + var c = s * v; + var f = 0; + + if (c < 1.0) { + f = (v - c) / (1 - c); + } + + return [hsv[0], c * 100, f * 100]; + }; + + convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } + + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; + + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } + + mg = (1.0 - c) * g; + + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; + }; + + convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var v = c + g * (1.0 - c); + var f = 0; + + if (v > 0.0) { + f = c / v; + } + + return [hcg[0], f * 100, v * 100]; + }; + + convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; + + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } + + return [hcg[0], s * 100, l * 100]; + }; + + convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; + }; + + convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; + + if (c < 1) { + g = (v - c) / (1 - c); + } + + return [hwb[0], c * 100, g * 100]; + }; + + convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; + }; + + convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; + }; + + convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; + }; + + convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; + }; + + convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; + }; + + convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; + }; + + convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; + }; + + convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; + }; + + convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; + }; + }); + var conversions_1 = conversions.rgb; + var conversions_2 = conversions.hsl; + var conversions_3 = conversions.hsv; + var conversions_4 = conversions.hwb; + var conversions_5 = conversions.cmyk; + var conversions_6 = conversions.xyz; + var conversions_7 = conversions.lab; + var conversions_8 = conversions.lch; + var conversions_9 = conversions.hex; + var conversions_10 = conversions.keyword; + var conversions_11 = conversions.ansi16; + var conversions_12 = conversions.ansi256; + var conversions_13 = conversions.hcg; + var conversions_14 = conversions.apple; + var conversions_15 = conversions.gray; + + /* + this function routes a model to all other models. + + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). + + conversions that are not possible simply are not included. + */ + + function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); + + for (var len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } + + return graph; + } + + // https://en.wikipedia.org/wiki/Breadth-first_search + function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop + + graph[fromModel].distance = 0; + + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); + + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } + + return graph; + } + + function link(from, to) { + return function (args) { + return to(from(args)); + }; + } + + function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; + + var cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } + + fn.conversion = path; + return fn; + } + + var route = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; + + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; + + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } + + conversion[toModel] = wrapConversion(toModel, graph); + } + + return conversion; + }; + + var convert = {}; + + var models = Object.keys(conversions); + + function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + + return fn(args); + }; + + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + + return wrappedFn; + } + + function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + + var result = fn(args); + + // we're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } + + return result; + }; + + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + + return wrappedFn; + } + + models.forEach(function (fromModel) { + convert[fromModel] = {}; + + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); + + var routes = route(fromModel); + var routeModels = Object.keys(routes); + + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; + + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); + }); + + var colorConvert = convert; + + var colorName$1 = { + "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] + }; + + /* MIT license */ + + + var colorString = { + 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,4})$/i, + hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i, + rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, + per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, + keyword = /(\w+)/; + + var rgb = [0, 0, 0], + a = 1, + match = string.match(abbr), + hexAlpha = ""; + if (match) { + match = match[1]; + hexAlpha = match[3]; + for (var i = 0; i < rgb.length; i++) { + rgb[i] = parseInt(match[i] + match[i], 16); + } + if (hexAlpha) { + a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100; + } + } + else if (match = string.match(hex)) { + hexAlpha = match[2]; + match = match[1]; + for (var i = 0; i < rgb.length; i++) { + rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); + } + if (hexAlpha) { + a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100; + } + } + 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 = colorName$1[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(rgba, a) { + var a = (a !== undefined && rgba.length === 3) ? a : rgba[3]; + return "#" + hexDouble(rgba[0]) + + hexDouble(rgba[1]) + + hexDouble(rgba[2]) + + ( + (a >= 0 && a < 1) + ? hexDouble(Math.round(a * 255)) + : "" + ); + } + + 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 colorName$1) { + reverseNames[colorName$1[name]] = name; + } + + /* MIT license */ + + + + var Color = function (obj) { + if (obj instanceof Color) { + return obj; + } + if (!(this instanceof Color)) { + return new Color(obj); + } + + this.valid = false; + this.values = { + rgb: [0, 0, 0], + hsl: [0, 0, 0], + hsv: [0, 0, 0], + hwb: [0, 0, 0], + cmyk: [0, 0, 0, 0], + alpha: 1 + }; + + // parse Color() argument + var vals; + if (typeof obj === 'string') { + vals = colorString.getRgba(obj); + if (vals) { + this.setValues('rgb', vals); + } else if (vals = colorString.getHsla(obj)) { + this.setValues('hsl', vals); + } else if (vals = colorString.getHwb(obj)) { + this.setValues('hwb', vals); + } + } else if (typeof obj === 'object') { + vals = obj; + if (vals.r !== undefined || vals.red !== undefined) { + this.setValues('rgb', vals); + } else if (vals.l !== undefined || vals.lightness !== undefined) { + this.setValues('hsl', vals); + } else if (vals.v !== undefined || vals.value !== undefined) { + this.setValues('hsv', vals); + } else if (vals.w !== undefined || vals.whiteness !== undefined) { + this.setValues('hwb', vals); + } else if (vals.c !== undefined || vals.cyan !== undefined) { + this.setValues('cmyk', vals); + } + } + }; + + Color.prototype = { + isValid: function () { + return this.valid; + }, + rgb: function () { + return this.setSpace('rgb', arguments); + }, + hsl: function () { + return this.setSpace('hsl', arguments); + }, + hsv: function () { + return this.setSpace('hsv', arguments); + }, + hwb: function () { + return this.setSpace('hwb', arguments); + }, + cmyk: function () { + return this.setSpace('cmyk', arguments); + }, + + rgbArray: function () { + return this.values.rgb; + }, + hslArray: function () { + return this.values.hsl; + }, + hsvArray: function () { + return this.values.hsv; + }, + hwbArray: function () { + var values = this.values; + if (values.alpha !== 1) { + return values.hwb.concat([values.alpha]); + } + return values.hwb; + }, + cmykArray: function () { + return this.values.cmyk; + }, + rgbaArray: function () { + var values = this.values; + return values.rgb.concat([values.alpha]); + }, + hslaArray: function () { + var values = this.values; + return values.hsl.concat([values.alpha]); + }, + alpha: function (val) { + if (val === undefined) { + return this.values.alpha; + } + this.setValues('alpha', val); + return this; + }, + + red: function (val) { + return this.setChannel('rgb', 0, val); + }, + green: function (val) { + return this.setChannel('rgb', 1, val); + }, + blue: function (val) { + return this.setChannel('rgb', 2, val); + }, + hue: function (val) { + if (val) { + val %= 360; + val = val < 0 ? 360 + val : val; + } + return this.setChannel('hsl', 0, val); + }, + saturation: function (val) { + return this.setChannel('hsl', 1, val); + }, + lightness: function (val) { + return this.setChannel('hsl', 2, val); + }, + saturationv: function (val) { + return this.setChannel('hsv', 1, val); + }, + whiteness: function (val) { + return this.setChannel('hwb', 1, val); + }, + blackness: function (val) { + return this.setChannel('hwb', 2, val); + }, + value: function (val) { + return this.setChannel('hsv', 2, val); + }, + cyan: function (val) { + return this.setChannel('cmyk', 0, val); + }, + magenta: function (val) { + return this.setChannel('cmyk', 1, val); + }, + yellow: function (val) { + return this.setChannel('cmyk', 2, val); + }, + black: function (val) { + return this.setChannel('cmyk', 3, val); + }, + + hexString: function () { + return colorString.hexString(this.values.rgb); + }, + rgbString: function () { + return colorString.rgbString(this.values.rgb, this.values.alpha); + }, + rgbaString: function () { + return colorString.rgbaString(this.values.rgb, this.values.alpha); + }, + percentString: function () { + return colorString.percentString(this.values.rgb, this.values.alpha); + }, + hslString: function () { + return colorString.hslString(this.values.hsl, this.values.alpha); + }, + hslaString: function () { + return colorString.hslaString(this.values.hsl, this.values.alpha); + }, + hwbString: function () { + return colorString.hwbString(this.values.hwb, this.values.alpha); + }, + keyword: function () { + return colorString.keyword(this.values.rgb, this.values.alpha); + }, + + rgbNumber: function () { + var rgb = this.values.rgb; + return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; + }, + + luminosity: function () { + // http://www.w3.org/TR/WCAG20/#relativeluminancedef + var rgb = this.values.rgb; + var lum = []; + for (var i = 0; i < rgb.length; i++) { + var chan = rgb[i] / 255; + lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); + } + return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + }, + + contrast: function (color2) { + // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + var lum1 = this.luminosity(); + var lum2 = color2.luminosity(); + if (lum1 > lum2) { + return (lum1 + 0.05) / (lum2 + 0.05); + } + return (lum2 + 0.05) / (lum1 + 0.05); + }, + + level: function (color2) { + var contrastRatio = this.contrast(color2); + if (contrastRatio >= 7.1) { + return 'AAA'; + } + + return (contrastRatio >= 4.5) ? 'AA' : ''; + }, + + dark: function () { + // YIQ equation from http://24ways.org/2010/calculating-color-contrast + var rgb = this.values.rgb; + var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; + return yiq < 128; + }, + + light: function () { + return !this.dark(); + }, + + negate: function () { + var rgb = []; + for (var i = 0; i < 3; i++) { + rgb[i] = 255 - this.values.rgb[i]; + } + this.setValues('rgb', rgb); + return this; + }, + + lighten: function (ratio) { + var hsl = this.values.hsl; + hsl[2] += hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + darken: function (ratio) { + var hsl = this.values.hsl; + hsl[2] -= hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + saturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] += hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + desaturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] -= hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + whiten: function (ratio) { + var hwb = this.values.hwb; + hwb[1] += hwb[1] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + blacken: function (ratio) { + var hwb = this.values.hwb; + hwb[2] += hwb[2] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + greyscale: function () { + var rgb = this.values.rgb; + // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + this.setValues('rgb', [val, val, val]); + return this; + }, + + clearer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha - (alpha * ratio)); + return this; + }, + + opaquer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha + (alpha * ratio)); + return this; + }, + + rotate: function (degrees) { + var hsl = this.values.hsl; + var hue = (hsl[0] + degrees) % 360; + hsl[0] = hue < 0 ? 360 + hue : hue; + this.setValues('hsl', hsl); + return this; + }, + + /** + * Ported from sass implementation in C + * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 + */ + mix: function (mixinColor, weight) { + var color1 = this; + var color2 = mixinColor; + var p = weight === undefined ? 0.5 : weight; + + var w = 2 * p - 1; + var a = color1.alpha() - color2.alpha(); + + var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + return this + .rgb( + w1 * color1.red() + w2 * color2.red(), + w1 * color1.green() + w2 * color2.green(), + w1 * color1.blue() + w2 * color2.blue() + ) + .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); + }, + + toJSON: function () { + return this.rgb(); + }, + + clone: function () { + // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, + // making the final build way to big to embed in Chart.js. So let's do it manually, + // assuming that values to clone are 1 dimension arrays containing only numbers, + // except 'alpha' which is a number. + var result = new Color(); + var source = this.values; + var target = result.values; + var value, type; + + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + value = source[prop]; + type = ({}).toString.call(value); + if (type === '[object Array]') { + target[prop] = value.slice(0); + } else if (type === '[object Number]') { + target[prop] = value; + } else { + console.error('unexpected color value:', value); + } + } + } + + return result; + } + }; + + Color.prototype.spaces = { + rgb: ['red', 'green', 'blue'], + hsl: ['hue', 'saturation', 'lightness'], + hsv: ['hue', 'saturation', 'value'], + hwb: ['hue', 'whiteness', 'blackness'], + cmyk: ['cyan', 'magenta', 'yellow', 'black'] + }; + + Color.prototype.maxes = { + rgb: [255, 255, 255], + hsl: [360, 100, 100], + hsv: [360, 100, 100], + hwb: [360, 100, 100], + cmyk: [100, 100, 100, 100] + }; + + Color.prototype.getValues = function (space) { + var values = this.values; + var vals = {}; + + for (var i = 0; i < space.length; i++) { + vals[space.charAt(i)] = values[space][i]; + } + + if (values.alpha !== 1) { + vals.a = values.alpha; + } + + // {r: 255, g: 255, b: 255, a: 0.4} + return vals; + }; + + Color.prototype.setValues = function (space, vals) { + var values = this.values; + var spaces = this.spaces; + var maxes = this.maxes; + var alpha = 1; + var i; + + this.valid = true; + + if (space === 'alpha') { + alpha = vals; + } else if (vals.length) { + // [10, 10, 10] + values[space] = vals.slice(0, space.length); + alpha = vals[space.length]; + } else if (vals[space.charAt(0)] !== undefined) { + // {r: 10, g: 10, b: 10} + for (i = 0; i < space.length; i++) { + values[space][i] = vals[space.charAt(i)]; + } + + alpha = vals.a; + } else if (vals[spaces[space][0]] !== undefined) { + // {red: 10, green: 10, blue: 10} + var chans = spaces[space]; + + for (i = 0; i < space.length; i++) { + values[space][i] = vals[chans[i]]; + } + + alpha = vals.alpha; + } + + values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); + + if (space === 'alpha') { + return false; + } + + var capped; + + // cap values of the space prior converting all values + for (i = 0; i < space.length; i++) { + capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); + values[space][i] = Math.round(capped); + } + + // convert to all the other color spaces + for (var sname in spaces) { + if (sname !== space) { + values[sname] = colorConvert[space][sname](values[space]); + } + } + + return true; + }; + + Color.prototype.setSpace = function (space, args) { + var vals = args[0]; + + if (vals === undefined) { + // color.rgb() + return this.getValues(space); + } + + // color.rgb(10, 10, 10) + if (typeof vals === 'number') { + vals = Array.prototype.slice.call(args); + } + + this.setValues(space, vals); + return this; + }; + + Color.prototype.setChannel = function (space, index, val) { + var svalues = this.values[space]; + if (val === undefined) { + // color.red() + return svalues[index]; + } else if (val === svalues[index]) { + // color.red(color.red()) + return this; + } + + // color.red(100) + svalues[index] = val; + this.setValues(space, svalues); + + return this; + }; + + if (typeof window !== 'undefined') { + window.Color = Color; + } + + var chartjsColor = Color; + + /** + * @namespace Chart.helpers + */ + var helpers = { + /** + * An empty function that can be used, for example, for optional callback. + */ + noop: function() {}, + + /** + * Returns a unique id, sequentially generated from a global variable. + * @returns {number} + * @function + */ + uid: (function() { + var id = 0; + return function() { + return id++; + }; + }()), + + /** + * Returns true if `value` is neither null nor undefined, else returns false. + * @param {*} value - The value to test. + * @returns {boolean} + * @since 2.7.0 + */ + isNullOrUndef: function(value) { + return value === null || typeof value === 'undefined'; + }, + + /** + * Returns true if `value` is an array (including typed arrays), else returns false. + * @param {*} value - The value to test. + * @returns {boolean} + * @function + */ + isArray: function(value) { + if (Array.isArray && Array.isArray(value)) { + return true; + } + var type = Object.prototype.toString.call(value); + if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') { + return true; + } + return false; + }, + + /** + * Returns true if `value` is an object (excluding null), else returns false. + * @param {*} value - The value to test. + * @returns {boolean} + * @since 2.7.0 + */ + isObject: function(value) { + return value !== null && Object.prototype.toString.call(value) === '[object Object]'; + }, + + /** + * Returns true if `value` is a finite number, else returns false + * @param {*} value - The value to test. + * @returns {boolean} + */ + isFinite: function(value) { + return (typeof value === 'number' || value instanceof Number) && isFinite(value); + }, + + /** + * Returns `value` if defined, else returns `defaultValue`. + * @param {*} value - The value to return if defined. + * @param {*} defaultValue - The value to return if `value` is undefined. + * @returns {*} + */ + valueOrDefault: function(value, defaultValue) { + return typeof value === 'undefined' ? defaultValue : value; + }, + + /** + * Returns value at the given `index` in array if defined, else returns `defaultValue`. + * @param {Array} value - The array to lookup for value at `index`. + * @param {number} index - The index in `value` to lookup for value. + * @param {*} defaultValue - The value to return if `value[index]` is undefined. + * @returns {*} + */ + valueAtIndexOrDefault: function(value, index, defaultValue) { + return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue); + }, + + /** + * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the + * value returned by `fn`. If `fn` is not a function, this method returns undefined. + * @param {function} fn - The function to call. + * @param {Array|undefined|null} args - The arguments with which `fn` should be called. + * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. + * @returns {*} + */ + callback: function(fn, args, thisArg) { + if (fn && typeof fn.call === 'function') { + return fn.apply(thisArg, args); + } + }, + + /** + * Note(SB) for performance sake, this method should only be used when loopable type + * is unknown or in none intensive code (not called often and small loopable). Else + * it's preferable to use a regular for() loop and save extra function calls. + * @param {object|Array} loopable - The object or array to be iterated. + * @param {function} fn - The function to call for each item. + * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. + * @param {boolean} [reverse] - If true, iterates backward on the loopable. + */ + each: function(loopable, fn, thisArg, reverse) { + var i, len, keys; + if (helpers.isArray(loopable)) { + len = loopable.length; + if (reverse) { + for (i = len - 1; i >= 0; i--) { + fn.call(thisArg, loopable[i], i); + } + } else { + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[i], i); + } + } + } else if (helpers.isObject(loopable)) { + keys = Object.keys(loopable); + len = keys.length; + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[keys[i]], keys[i]); + } + } + }, + + /** + * Returns true if the `a0` and `a1` arrays have the same content, else returns false. + * @see https://stackoverflow.com/a/14853974 + * @param {Array} a0 - The array to compare + * @param {Array} a1 - The array to compare + * @returns {boolean} + */ + arrayEquals: function(a0, a1) { + var i, ilen, v0, v1; + + if (!a0 || !a1 || a0.length !== a1.length) { + return false; + } + + for (i = 0, ilen = a0.length; i < ilen; ++i) { + v0 = a0[i]; + v1 = a1[i]; + + if (v0 instanceof Array && v1 instanceof Array) { + if (!helpers.arrayEquals(v0, v1)) { + return false; + } + } else if (v0 !== v1) { + // NOTE: two different object instances will never be equal: {x:20} != {x:20} + return false; + } + } + + return true; + }, + + /** + * Returns a deep copy of `source` without keeping references on objects and arrays. + * @param {*} source - The value to clone. + * @returns {*} + */ + clone: function(source) { + if (helpers.isArray(source)) { + return source.map(helpers.clone); + } + + if (helpers.isObject(source)) { + var target = {}; + var keys = Object.keys(source); + var klen = keys.length; + var k = 0; + + for (; k < klen; ++k) { + target[keys[k]] = helpers.clone(source[keys[k]]); + } + + return target; + } + + return source; + }, + + /** + * The default merger when Chart.helpers.merge is called without merger option. + * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback. + * @private + */ + _merger: function(key, target, source, options) { + var tval = target[key]; + var sval = source[key]; + + if (helpers.isObject(tval) && helpers.isObject(sval)) { + helpers.merge(tval, sval, options); + } else { + target[key] = helpers.clone(sval); + } + }, + + /** + * Merges source[key] in target[key] only if target[key] is undefined. + * @private + */ + _mergerIf: function(key, target, source) { + var tval = target[key]; + var sval = source[key]; + + if (helpers.isObject(tval) && helpers.isObject(sval)) { + helpers.mergeIf(tval, sval); + } else if (!target.hasOwnProperty(key)) { + target[key] = helpers.clone(sval); + } + }, + + /** + * Recursively deep copies `source` properties into `target` with the given `options`. + * IMPORTANT: `target` is not cloned and will be updated with `source` properties. + * @param {object} target - The target object in which all sources are merged into. + * @param {object|object[]} source - Object(s) to merge into `target`. + * @param {object} [options] - Merging options: + * @param {function} [options.merger] - The merge method (key, target, source, options) + * @returns {object} The `target` object. + */ + merge: function(target, source, options) { + var sources = helpers.isArray(source) ? source : [source]; + var ilen = sources.length; + var merge, i, keys, klen, k; + + if (!helpers.isObject(target)) { + return target; + } + + options = options || {}; + merge = options.merger || helpers._merger; + + for (i = 0; i < ilen; ++i) { + source = sources[i]; + if (!helpers.isObject(source)) { + continue; + } + + keys = Object.keys(source); + for (k = 0, klen = keys.length; k < klen; ++k) { + merge(keys[k], target, source, options); + } + } + + return target; + }, + + /** + * Recursively deep copies `source` properties into `target` *only* if not defined in target. + * IMPORTANT: `target` is not cloned and will be updated with `source` properties. + * @param {object} target - The target object in which all sources are merged into. + * @param {object|object[]} source - Object(s) to merge into `target`. + * @returns {object} The `target` object. + */ + mergeIf: function(target, source) { + return helpers.merge(target, source, {merger: helpers._mergerIf}); + }, + + /** + * Applies the contents of two or more objects together into the first object. + * @param {object} target - The target object in which all objects are merged into. + * @param {object} arg1 - Object containing additional properties to merge in target. + * @param {object} argN - Additional objects containing properties to merge in target. + * @returns {object} The `target` object. + */ + extend: Object.assign || function(target) { + return helpers.merge(target, [].slice.call(arguments, 1), { + merger: function(key, dst, src) { + dst[key] = src[key]; + } + }); + }, + + /** + * Basic javascript inheritance based on the model created in Backbone.js + */ + inherits: function(extensions) { + var me = this; + var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() { + return me.apply(this, arguments); + }; + + var Surrogate = function() { + this.constructor = ChartElement; + }; + + Surrogate.prototype = me.prototype; + ChartElement.prototype = new Surrogate(); + ChartElement.extend = helpers.inherits; + + if (extensions) { + helpers.extend(ChartElement.prototype, extensions); + } + + ChartElement.__super__ = me.prototype; + return ChartElement; + }, + + _deprecated: function(scope, value, previous, current) { + if (value !== undefined) { + console.warn(scope + ': "' + previous + + '" is deprecated. Please use "' + current + '" instead'); + } + } + }; + + var helpers_core = helpers; + + // DEPRECATIONS + + /** + * Provided for backward compatibility, use Chart.helpers.callback instead. + * @function Chart.helpers.callCallback + * @deprecated since version 2.6.0 + * @todo remove at version 3 + * @private + */ + helpers.callCallback = helpers.callback; + + /** + * Provided for backward compatibility, use Array.prototype.indexOf instead. + * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+ + * @function Chart.helpers.indexOf + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ + helpers.indexOf = function(array, item, fromIndex) { + return Array.prototype.indexOf.call(array, item, fromIndex); + }; + + /** + * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead. + * @function Chart.helpers.getValueOrDefault + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ + helpers.getValueOrDefault = helpers.valueOrDefault; + + /** + * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead. + * @function Chart.helpers.getValueAtIndexOrDefault + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ + helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault; + + /** + * Easing functions adapted from Robert Penner's easing equations. + * @namespace Chart.helpers.easingEffects + * @see http://www.robertpenner.com/easing/ + */ + var effects = { + linear: function(t) { + return t; + }, + + easeInQuad: function(t) { + return t * t; + }, + + easeOutQuad: function(t) { + return -t * (t - 2); + }, + + easeInOutQuad: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t; + } + return -0.5 * ((--t) * (t - 2) - 1); + }, + + easeInCubic: function(t) { + return t * t * t; + }, + + easeOutCubic: function(t) { + return (t = t - 1) * t * t + 1; + }, + + easeInOutCubic: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t; + } + return 0.5 * ((t -= 2) * t * t + 2); + }, + + easeInQuart: function(t) { + return t * t * t * t; + }, + + easeOutQuart: function(t) { + return -((t = t - 1) * t * t * t - 1); + }, + + easeInOutQuart: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t * t; + } + return -0.5 * ((t -= 2) * t * t * t - 2); + }, + + easeInQuint: function(t) { + return t * t * t * t * t; + }, + + easeOutQuint: function(t) { + return (t = t - 1) * t * t * t * t + 1; + }, + + easeInOutQuint: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t * t * t; + } + return 0.5 * ((t -= 2) * t * t * t * t + 2); + }, + + easeInSine: function(t) { + return -Math.cos(t * (Math.PI / 2)) + 1; + }, + + easeOutSine: function(t) { + return Math.sin(t * (Math.PI / 2)); + }, + + easeInOutSine: function(t) { + return -0.5 * (Math.cos(Math.PI * t) - 1); + }, + + easeInExpo: function(t) { + return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); + }, + + easeOutExpo: function(t) { + return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; + }, + + easeInOutExpo: function(t) { + if (t === 0) { + return 0; + } + if (t === 1) { + return 1; + } + if ((t /= 0.5) < 1) { + return 0.5 * Math.pow(2, 10 * (t - 1)); + } + return 0.5 * (-Math.pow(2, -10 * --t) + 2); + }, + + easeInCirc: function(t) { + if (t >= 1) { + return t; + } + return -(Math.sqrt(1 - t * t) - 1); + }, + + easeOutCirc: function(t) { + return Math.sqrt(1 - (t = t - 1) * t); + }, + + easeInOutCirc: function(t) { + if ((t /= 0.5) < 1) { + return -0.5 * (Math.sqrt(1 - t * t) - 1); + } + return 0.5 * (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) { + return 1; + } + if (!p) { + p = 0.3; + } + if (a < 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 - 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) { + return 1; + } + if (!p) { + p = 0.3; + } + if (a < 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 - 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 /= 0.5) === 2) { + return 1; + } + if (!p) { + p = 0.45; + } + if (a < 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 - s) * (2 * Math.PI) / p)); + } + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, + easeInBack: function(t) { + var s = 1.70158; + return t * t * ((s + 1) * t - s); + }, + + easeOutBack: function(t) { + var s = 1.70158; + return (t = t - 1) * t * ((s + 1) * t + s) + 1; + }, + + easeInOutBack: function(t) { + var s = 1.70158; + if ((t /= 0.5) < 1) { + return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); + } + return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + }, + + easeInBounce: function(t) { + return 1 - effects.easeOutBounce(1 - t); + }, + + easeOutBounce: function(t) { + if (t < (1 / 2.75)) { + return 7.5625 * t * t; + } + if (t < (2 / 2.75)) { + return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75; + } + if (t < (2.5 / 2.75)) { + return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375; + } + return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375; + }, + + easeInOutBounce: function(t) { + if (t < 0.5) { + return effects.easeInBounce(t * 2) * 0.5; + } + return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; + } + }; + + var helpers_easing = { + effects: effects + }; + + // DEPRECATIONS + + /** + * Provided for backward compatibility, use Chart.helpers.easing.effects instead. + * @function Chart.helpers.easingEffects + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ + helpers_core.easingEffects = effects; + + var PI = Math.PI; + var RAD_PER_DEG = PI / 180; + var DOUBLE_PI = PI * 2; + var HALF_PI = PI / 2; + var QUARTER_PI = PI / 4; + var TWO_THIRDS_PI = PI * 2 / 3; + + /** + * @namespace Chart.helpers.canvas + */ + var exports$1 = { + /** + * Clears the entire canvas associated to the given `chart`. + * @param {Chart} chart - The chart for which to clear the canvas. + */ + clear: function(chart) { + chart.ctx.clearRect(0, 0, chart.width, chart.height); + }, + + /** + * Creates a "path" for a rectangle with rounded corners at position (x, y) with a + * given size (width, height) and the same `radius` for all corners. + * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context. + * @param {number} x - The x axis of the coordinate for the rectangle starting point. + * @param {number} y - The y axis of the coordinate for the rectangle starting point. + * @param {number} width - The rectangle's width. + * @param {number} height - The rectangle's height. + * @param {number} radius - The rounded amount (in pixels) for the four corners. + * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object? + */ + roundedRect: function(ctx, x, y, width, height, radius) { + if (radius) { + var r = Math.min(radius, height / 2, width / 2); + var left = x + r; + var top = y + r; + var right = x + width - r; + var bottom = y + height - r; + + ctx.moveTo(x, top); + if (left < right && top < bottom) { + ctx.arc(left, top, r, -PI, -HALF_PI); + ctx.arc(right, top, r, -HALF_PI, 0); + ctx.arc(right, bottom, r, 0, HALF_PI); + ctx.arc(left, bottom, r, HALF_PI, PI); + } else if (left < right) { + ctx.moveTo(left, y); + ctx.arc(right, top, r, -HALF_PI, HALF_PI); + ctx.arc(left, top, r, HALF_PI, PI + HALF_PI); + } else if (top < bottom) { + ctx.arc(left, top, r, -PI, 0); + ctx.arc(left, bottom, r, 0, PI); + } else { + ctx.arc(left, top, r, -PI, PI); + } + ctx.closePath(); + ctx.moveTo(x, y); + } else { + ctx.rect(x, y, width, height); + } + }, + + drawPoint: function(ctx, style, radius, x, y, rotation) { + var type, xOffset, yOffset, size, cornerRadius; + var rad = (rotation || 0) * RAD_PER_DEG; + + if (style && typeof style === 'object') { + type = style.toString(); + if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { + ctx.save(); + ctx.translate(x, y); + ctx.rotate(rad); + ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height); + ctx.restore(); + return; + } + } + + if (isNaN(radius) || radius <= 0) { + return; + } + + ctx.beginPath(); + + switch (style) { + // Default includes circle + default: + ctx.arc(x, y, radius, 0, DOUBLE_PI); + ctx.closePath(); + break; + case 'triangle': + ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); + rad += TWO_THIRDS_PI; + ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); + rad += TWO_THIRDS_PI; + ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); + ctx.closePath(); + break; + case 'rectRounded': + // NOTE: the rounded rect implementation changed to use `arc` instead of + // `quadraticCurveTo` since it generates better results when rect is + // almost a circle. 0.516 (instead of 0.5) produces results with visually + // closer proportion to the previous impl and it is inscribed in the + // circle with `radius`. For more details, see the following PRs: + // https://github.com/chartjs/Chart.js/issues/5597 + // https://github.com/chartjs/Chart.js/issues/5858 + cornerRadius = radius * 0.516; + size = radius - cornerRadius; + xOffset = Math.cos(rad + QUARTER_PI) * size; + yOffset = Math.sin(rad + QUARTER_PI) * size; + ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI); + ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad); + ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI); + ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI); + ctx.closePath(); + break; + case 'rect': + if (!rotation) { + size = Math.SQRT1_2 * radius; + ctx.rect(x - size, y - size, 2 * size, 2 * size); + break; + } + rad += QUARTER_PI; + /* falls through */ + case 'rectRot': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + yOffset, y - xOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.lineTo(x - yOffset, y + xOffset); + ctx.closePath(); + break; + case 'crossRot': + rad += QUARTER_PI; + /* falls through */ + case 'cross': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.moveTo(x + yOffset, y - xOffset); + ctx.lineTo(x - yOffset, y + xOffset); + break; + case 'star': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.moveTo(x + yOffset, y - xOffset); + ctx.lineTo(x - yOffset, y + xOffset); + rad += QUARTER_PI; + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.moveTo(x + yOffset, y - xOffset); + ctx.lineTo(x - yOffset, y + xOffset); + break; + case 'line': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + break; + case 'dash': + ctx.moveTo(x, y); + ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius); + break; + } + + ctx.fill(); + ctx.stroke(); + }, + + /** + * Returns true if the point is inside the rectangle + * @param {object} point - The point to test + * @param {object} area - The rectangle + * @returns {boolean} + * @private + */ + _isPointInArea: function(point, area) { + var epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error. + + return point.x > area.left - epsilon && point.x < area.right + epsilon && + point.y > area.top - epsilon && point.y < area.bottom + epsilon; + }, + + clipArea: function(ctx, area) { + ctx.save(); + ctx.beginPath(); + ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); + ctx.clip(); + }, + + unclipArea: function(ctx) { + ctx.restore(); + }, + + lineTo: function(ctx, previous, target, flip) { + var stepped = target.steppedLine; + if (stepped) { + if (stepped === 'middle') { + var midpoint = (previous.x + target.x) / 2.0; + ctx.lineTo(midpoint, flip ? target.y : previous.y); + ctx.lineTo(midpoint, flip ? previous.y : target.y); + } else if ((stepped === 'after' && !flip) || (stepped !== 'after' && flip)) { + ctx.lineTo(previous.x, target.y); + } else { + ctx.lineTo(target.x, previous.y); + } + ctx.lineTo(target.x, target.y); + return; + } + + if (!target.tension) { + ctx.lineTo(target.x, target.y); + return; + } + + ctx.bezierCurveTo( + flip ? previous.controlPointPreviousX : previous.controlPointNextX, + flip ? previous.controlPointPreviousY : previous.controlPointNextY, + flip ? target.controlPointNextX : target.controlPointPreviousX, + flip ? target.controlPointNextY : target.controlPointPreviousY, + target.x, + target.y); + } + }; + + var helpers_canvas = exports$1; + + // DEPRECATIONS + + /** + * Provided for backward compatibility, use Chart.helpers.canvas.clear instead. + * @namespace Chart.helpers.clear + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ + helpers_core.clear = exports$1.clear; + + /** + * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead. + * @namespace Chart.helpers.drawRoundedRectangle + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ + helpers_core.drawRoundedRectangle = function(ctx) { + ctx.beginPath(); + exports$1.roundedRect.apply(exports$1, arguments); + }; + + var defaults = { + /** + * @private + */ + _set: function(scope, values) { + return helpers_core.merge(this[scope] || (this[scope] = {}), values); + } + }; + + // TODO(v3): remove 'global' from namespace. all default are global and + // there's inconsistency around which options are under 'global' + defaults._set('global', { + defaultColor: 'rgba(0,0,0,0.1)', + defaultFontColor: '#666', + defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + defaultFontSize: 12, + defaultFontStyle: 'normal', + defaultLineHeight: 1.2, + showLines: true + }); + + var core_defaults = defaults; + + var valueOrDefault = helpers_core.valueOrDefault; + + /** + * Converts the given font object into a CSS font string. + * @param {object} font - A font object. + * @return {string} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font + * @private + */ + function toFontString(font) { + if (!font || helpers_core.isNullOrUndef(font.size) || helpers_core.isNullOrUndef(font.family)) { + return null; + } + + return (font.style ? font.style + ' ' : '') + + (font.weight ? font.weight + ' ' : '') + + font.size + 'px ' + + font.family; + } + + /** + * @alias Chart.helpers.options + * @namespace + */ + var helpers_options = { + /** + * Converts the given line height `value` in pixels for a specific font `size`. + * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). + * @param {number} size - The font size (in pixels) used to resolve relative `value`. + * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid). + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height + * @since 2.7.0 + */ + toLineHeight: function(value, size) { + var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); + if (!matches || matches[1] === 'normal') { + return size * 1.2; + } + + value = +matches[2]; + + switch (matches[3]) { + case 'px': + return value; + case '%': + value /= 100; + break; + } + + return size * value; + }, + + /** + * Converts the given value into a padding object with pre-computed width/height. + * @param {number|object} value - If a number, set the value to all TRBL component, + * else, if and object, use defined properties and sets undefined ones to 0. + * @returns {object} The padding values (top, right, bottom, left, width, height) + * @since 2.7.0 + */ + toPadding: function(value) { + var t, r, b, l; + + if (helpers_core.isObject(value)) { + t = +value.top || 0; + r = +value.right || 0; + b = +value.bottom || 0; + l = +value.left || 0; + } else { + t = r = b = l = +value || 0; + } + + return { + top: t, + right: r, + bottom: b, + left: l, + height: t + b, + width: l + r + }; + }, + + /** + * Parses font options and returns the font object. + * @param {object} options - A object that contains font options to be parsed. + * @return {object} The font object. + * @todo Support font.* options and renamed to toFont(). + * @private + */ + _parseFont: function(options) { + var globalDefaults = core_defaults.global; + var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize); + var font = { + family: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily), + lineHeight: helpers_core.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size), + size: size, + style: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle), + weight: null, + string: '' + }; + + font.string = toFontString(font); + return font; + }, + + /** + * Evaluates the given `inputs` sequentially and returns the first defined value. + * @param {Array} inputs - An array of values, falling back to the last value. + * @param {object} [context] - If defined and the current value is a function, the value + * is called with `context` as first argument and the result becomes the new input. + * @param {number} [index] - If defined and the current value is an array, the value + * at `index` become the new input. + * @param {object} [info] - object to return information about resolution in + * @param {boolean} [info.cacheable] - Will be set to `false` if option is not cacheable. + * @since 2.7.0 + */ + resolve: function(inputs, context, index, info) { + var cacheable = true; + var i, ilen, value; + + for (i = 0, ilen = inputs.length; i < ilen; ++i) { + value = inputs[i]; + if (value === undefined) { + continue; + } + if (context !== undefined && typeof value === 'function') { + value = value(context); + cacheable = false; + } + if (index !== undefined && helpers_core.isArray(value)) { + value = value[index]; + cacheable = false; + } + if (value !== undefined) { + if (info && !cacheable) { + info.cacheable = false; + } + return value; + } + } + } + }; + + /** + * @alias Chart.helpers.math + * @namespace + */ + var exports$2 = { + /** + * Returns an array of factors sorted from 1 to sqrt(value) + * @private + */ + _factorize: function(value) { + var result = []; + var sqrt = Math.sqrt(value); + var i; + + for (i = 1; i < sqrt; i++) { + if (value % i === 0) { + result.push(i); + result.push(value / i); + } + } + if (sqrt === (sqrt | 0)) { // if value is a square number + result.push(sqrt); + } + + result.sort(function(a, b) { + return a - b; + }).pop(); + return result; + }, + + log10: Math.log10 || function(x) { + var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10. + // Check for whole powers of 10, + // which due to floating point rounding error should be corrected. + var powerOf10 = Math.round(exponent); + var isPowerOf10 = x === Math.pow(10, powerOf10); + + return isPowerOf10 ? powerOf10 : exponent; + } + }; + + var helpers_math = exports$2; + + // DEPRECATIONS + + /** + * Provided for backward compatibility, use Chart.helpers.math.log10 instead. + * @namespace Chart.helpers.log10 + * @deprecated since version 2.9.0 + * @todo remove at version 3 + * @private + */ + helpers_core.log10 = exports$2.log10; + + var getRtlAdapter = function(rectX, width) { + return { + x: function(x) { + return rectX + rectX + width - x; + }, + setWidth: function(w) { + width = w; + }, + textAlign: function(align) { + if (align === 'center') { + return align; + } + return align === 'right' ? 'left' : 'right'; + }, + xPlus: function(x, value) { + return x - value; + }, + leftForLtr: function(x, itemWidth) { + return x - itemWidth; + }, + }; + }; + + var getLtrAdapter = function() { + return { + x: function(x) { + return x; + }, + setWidth: function(w) { // eslint-disable-line no-unused-vars + }, + textAlign: function(align) { + return align; + }, + xPlus: function(x, value) { + return x + value; + }, + leftForLtr: function(x, _itemWidth) { // eslint-disable-line no-unused-vars + return x; + }, + }; + }; + + var getAdapter = function(rtl, rectX, width) { + return rtl ? getRtlAdapter(rectX, width) : getLtrAdapter(); + }; + + var overrideTextDirection = function(ctx, direction) { + var style, original; + if (direction === 'ltr' || direction === 'rtl') { + style = ctx.canvas.style; + original = [ + style.getPropertyValue('direction'), + style.getPropertyPriority('direction'), + ]; + + style.setProperty('direction', direction, 'important'); + ctx.prevTextDirection = original; + } + }; + + var restoreTextDirection = function(ctx) { + var original = ctx.prevTextDirection; + if (original !== undefined) { + delete ctx.prevTextDirection; + ctx.canvas.style.setProperty('direction', original[0], original[1]); + } + }; + + var helpers_rtl = { + getRtlAdapter: getAdapter, + overrideTextDirection: overrideTextDirection, + restoreTextDirection: restoreTextDirection, + }; + + var helpers$1 = helpers_core; + var easing = helpers_easing; + var canvas = helpers_canvas; + var options = helpers_options; + var math = helpers_math; + var rtl = helpers_rtl; + helpers$1.easing = easing; + helpers$1.canvas = canvas; + helpers$1.options = options; + helpers$1.math = math; + helpers$1.rtl = rtl; + + function interpolate(start, view, model, ease) { + var keys = Object.keys(model); + var i, ilen, key, actual, origin, target, type, c0, c1; + + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + + target = model[key]; + + // if a value is added to the model after pivot() has been called, the view + // doesn't contain it, so let's initialize the view to the target value. + if (!view.hasOwnProperty(key)) { + view[key] = target; + } + + actual = view[key]; + + if (actual === target || key[0] === '_') { + continue; + } + + if (!start.hasOwnProperty(key)) { + start[key] = actual; + } + + origin = start[key]; + + type = typeof target; + + if (type === typeof origin) { + if (type === 'string') { + c0 = chartjsColor(origin); + if (c0.valid) { + c1 = chartjsColor(target); + if (c1.valid) { + view[key] = c1.mix(c0, ease).rgbString(); + continue; + } + } + } else if (helpers$1.isFinite(origin) && helpers$1.isFinite(target)) { + view[key] = origin + (target - origin) * ease; + continue; + } + } + + view[key] = target; + } + } + + var Element = function(configuration) { + helpers$1.extend(this, configuration); + this.initialize.apply(this, arguments); + }; + + helpers$1.extend(Element.prototype, { + _type: undefined, + + initialize: function() { + this.hidden = false; + }, + + pivot: function() { + var me = this; + if (!me._view) { + me._view = helpers$1.extend({}, me._model); + } + me._start = {}; + return me; + }, + + transition: function(ease) { + var me = this; + var model = me._model; + var start = me._start; + var view = me._view; + + // No animation -> No Transition + if (!model || ease === 1) { + me._view = helpers$1.extend({}, model); + me._start = null; + return me; + } + + if (!view) { + view = me._view = {}; + } + + if (!start) { + start = me._start = {}; + } + + interpolate(start, view, model, ease); + + return me; + }, + + tooltipPosition: function() { + return { + x: this._model.x, + y: this._model.y + }; + }, + + hasValue: function() { + return helpers$1.isNumber(this._model.x) && helpers$1.isNumber(this._model.y); + } + }); + + Element.extend = helpers$1.inherits; + + var core_element = Element; + + var exports$3 = core_element.extend({ + chart: null, // the animation associated chart instance + currentStep: 0, // the current animation step + numSteps: 60, // default number of steps + easing: '', // the easing to use for this animation + render: null, // render function used by the animation service + + onAnimationProgress: null, // user specified callback to fire on each step of the animation + onAnimationComplete: null, // user specified callback to fire when the animation finishes + }); + + var core_animation = exports$3; + + // DEPRECATIONS + + /** + * Provided for backward compatibility, use Chart.Animation instead + * @prop Chart.Animation#animationObject + * @deprecated since version 2.6.0 + * @todo remove at version 3 + */ + Object.defineProperty(exports$3.prototype, 'animationObject', { + get: function() { + return this; + } + }); + + /** + * Provided for backward compatibility, use Chart.Animation#chart instead + * @prop Chart.Animation#chartInstance + * @deprecated since version 2.6.0 + * @todo remove at version 3 + */ + Object.defineProperty(exports$3.prototype, 'chartInstance', { + get: function() { + return this.chart; + }, + set: function(value) { + this.chart = value; + } + }); + + core_defaults._set('global', { + animation: { + duration: 1000, + easing: 'easeOutQuart', + onProgress: helpers$1.noop, + onComplete: helpers$1.noop + } + }); + + var core_animations = { + animations: [], + request: null, + + /** + * @param {Chart} chart - The chart to animate. + * @param {Chart.Animation} animation - The animation that we will animate. + * @param {number} duration - The animation duration in ms. + * @param {boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions + */ + addAnimation: function(chart, animation, duration, lazy) { + var animations = this.animations; + var i, ilen; + + animation.chart = chart; + animation.startTime = Date.now(); + animation.duration = duration; + + if (!lazy) { + chart.animating = true; + } + + for (i = 0, ilen = animations.length; i < ilen; ++i) { + if (animations[i].chart === chart) { + animations[i] = animation; + return; + } + } + + animations.push(animation); + + // If there are no animations queued, manually kickstart a digest, for lack of a better word + if (animations.length === 1) { + this.requestAnimationFrame(); + } + }, + + cancelAnimation: function(chart) { + var index = helpers$1.findIndex(this.animations, function(animation) { + return animation.chart === chart; + }); + + if (index !== -1) { + this.animations.splice(index, 1); + chart.animating = false; + } + }, + + requestAnimationFrame: function() { + var me = this; + if (me.request === null) { + // Skip animation frame requests until the active one is executed. + // This can happen when processing mouse events, e.g. 'mousemove' + // and 'mouseout' events will trigger multiple renders. + me.request = helpers$1.requestAnimFrame.call(window, function() { + me.request = null; + me.startDigest(); + }); + } + }, + + /** + * @private + */ + startDigest: function() { + var me = this; + + me.advance(); + + // Do we have more stuff to animate? + if (me.animations.length > 0) { + me.requestAnimationFrame(); + } + }, + + /** + * @private + */ + advance: function() { + var animations = this.animations; + var animation, chart, numSteps, nextStep; + var i = 0; + + // 1 animation per chart, so we are looping charts here + while (i < animations.length) { + animation = animations[i]; + chart = animation.chart; + numSteps = animation.numSteps; + + // Make sure that currentStep starts at 1 + // https://github.com/chartjs/Chart.js/issues/6104 + nextStep = Math.floor((Date.now() - animation.startTime) / animation.duration * numSteps) + 1; + animation.currentStep = Math.min(nextStep, numSteps); + + helpers$1.callback(animation.render, [chart, animation], chart); + helpers$1.callback(animation.onAnimationProgress, [animation], chart); + + if (animation.currentStep >= numSteps) { + helpers$1.callback(animation.onAnimationComplete, [animation], chart); + chart.animating = false; + animations.splice(i, 1); + } else { + ++i; + } + } + } + }; + + var resolve = helpers$1.options.resolve; + + var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift']; + + /** + * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', + * 'unshift') and notify the listener AFTER the array has been altered. Listeners are + * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments. + */ + function listenArrayEvents(array, listener) { + if (array._chartjs) { + array._chartjs.listeners.push(listener); + return; + } + + Object.defineProperty(array, '_chartjs', { + configurable: true, + enumerable: false, + value: { + listeners: [listener] + } + }); + + arrayEvents.forEach(function(key) { + var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1); + var base = array[key]; + + Object.defineProperty(array, key, { + configurable: true, + enumerable: false, + value: function() { + var args = Array.prototype.slice.call(arguments); + var res = base.apply(this, args); + + helpers$1.each(array._chartjs.listeners, function(object) { + if (typeof object[method] === 'function') { + object[method].apply(object, args); + } + }); + + return res; + } + }); + }); + } + + /** + * Removes the given array event listener and cleanup extra attached properties (such as + * the _chartjs stub and overridden methods) if array doesn't have any more listeners. + */ + function unlistenArrayEvents(array, listener) { + var stub = array._chartjs; + if (!stub) { + return; + } + + var listeners = stub.listeners; + var index = listeners.indexOf(listener); + if (index !== -1) { + listeners.splice(index, 1); + } + + if (listeners.length > 0) { + return; + } + + arrayEvents.forEach(function(key) { + delete array[key]; + }); + + delete array._chartjs; + } + + // Base class for all dataset controllers (line, bar, etc) + var DatasetController = function(chart, datasetIndex) { + this.initialize(chart, datasetIndex); + }; + + helpers$1.extend(DatasetController.prototype, { + + /** + * Element type used to generate a meta dataset (e.g. Chart.element.Line). + * @type {Chart.core.element} + */ + datasetElementType: null, + + /** + * Element type used to generate a meta data (e.g. Chart.element.Point). + * @type {Chart.core.element} + */ + dataElementType: null, + + /** + * Dataset element option keys to be resolved in _resolveDatasetElementOptions. + * A derived controller may override this to resolve controller-specific options. + * The keys defined here are for backward compatibility for legend styles. + * @private + */ + _datasetElementOptions: [ + 'backgroundColor', + 'borderCapStyle', + 'borderColor', + 'borderDash', + 'borderDashOffset', + 'borderJoinStyle', + 'borderWidth' + ], + + /** + * Data element option keys to be resolved in _resolveDataElementOptions. + * A derived controller may override this to resolve controller-specific options. + * The keys defined here are for backward compatibility for legend styles. + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'pointStyle' + ], + + initialize: function(chart, datasetIndex) { + var me = this; + me.chart = chart; + me.index = datasetIndex; + me.linkScales(); + me.addElements(); + me._type = me.getMeta().type; + }, + + updateIndex: function(datasetIndex) { + this.index = datasetIndex; + }, + + linkScales: function() { + var me = this; + var meta = me.getMeta(); + var chart = me.chart; + var scales = chart.scales; + var dataset = me.getDataset(); + var scalesOpts = chart.options.scales; + + if (meta.xAxisID === null || !(meta.xAxisID in scales) || dataset.xAxisID) { + meta.xAxisID = dataset.xAxisID || scalesOpts.xAxes[0].id; + } + if (meta.yAxisID === null || !(meta.yAxisID in scales) || dataset.yAxisID) { + meta.yAxisID = dataset.yAxisID || scalesOpts.yAxes[0].id; + } + }, + + getDataset: function() { + return this.chart.data.datasets[this.index]; + }, + + getMeta: function() { + return this.chart.getDatasetMeta(this.index); + }, + + getScaleForId: function(scaleID) { + return this.chart.scales[scaleID]; + }, + + /** + * @private + */ + _getValueScaleId: function() { + return this.getMeta().yAxisID; + }, + + /** + * @private + */ + _getIndexScaleId: function() { + return this.getMeta().xAxisID; + }, + + /** + * @private + */ + _getValueScale: function() { + return this.getScaleForId(this._getValueScaleId()); + }, + + /** + * @private + */ + _getIndexScale: function() { + return this.getScaleForId(this._getIndexScaleId()); + }, + + reset: function() { + this._update(true); + }, + + /** + * @private + */ + destroy: function() { + if (this._data) { + unlistenArrayEvents(this._data, this); + } + }, + + createMetaDataset: function() { + var me = this; + var type = me.datasetElementType; + return type && new type({ + _chart: me.chart, + _datasetIndex: me.index + }); + }, + + createMetaData: function(index) { + var me = this; + var type = me.dataElementType; + return type && new type({ + _chart: me.chart, + _datasetIndex: me.index, + _index: index + }); + }, + + addElements: function() { + var me = this; + var meta = me.getMeta(); + var data = me.getDataset().data || []; + var metaData = meta.data; + var i, ilen; + + for (i = 0, ilen = data.length; i < ilen; ++i) { + metaData[i] = metaData[i] || me.createMetaData(i); + } + + meta.dataset = meta.dataset || me.createMetaDataset(); + }, + + addElementAndReset: function(index) { + var element = this.createMetaData(index); + this.getMeta().data.splice(index, 0, element); + this.updateElement(element, index, true); + }, + + buildOrUpdateElements: function() { + var me = this; + var dataset = me.getDataset(); + var data = dataset.data || (dataset.data = []); + + // In order to correctly handle data addition/deletion animation (an thus simulate + // real-time charts), we need to monitor these data modifications and synchronize + // the internal meta data accordingly. + if (me._data !== data) { + if (me._data) { + // This case happens when the user replaced the data array instance. + unlistenArrayEvents(me._data, me); + } + + if (data && Object.isExtensible(data)) { + listenArrayEvents(data, me); + } + me._data = data; + } + + // Re-sync meta data in case the user replaced the data array or if we missed + // any updates and so make sure that we handle number of datapoints changing. + me.resyncElements(); + }, + + /** + * Returns the merged user-supplied and default dataset-level options + * @private + */ + _configure: function() { + var me = this; + me._config = helpers$1.merge({}, [ + me.chart.options.datasets[me._type], + me.getDataset(), + ], { + merger: function(key, target, source) { + if (key !== '_meta' && key !== 'data') { + helpers$1._merger(key, target, source); + } + } + }); + }, + + _update: function(reset) { + var me = this; + me._configure(); + me._cachedDataOpts = null; + me.update(reset); + }, + + update: helpers$1.noop, + + transition: function(easingValue) { + var meta = this.getMeta(); + var elements = meta.data || []; + var ilen = elements.length; + var i = 0; + + for (; i < ilen; ++i) { + elements[i].transition(easingValue); + } + + if (meta.dataset) { + meta.dataset.transition(easingValue); + } + }, + + draw: function() { + var meta = this.getMeta(); + var elements = meta.data || []; + var ilen = elements.length; + var i = 0; + + if (meta.dataset) { + meta.dataset.draw(); + } + + for (; i < ilen; ++i) { + elements[i].draw(); + } + }, + + /** + * Returns a set of predefined style properties that should be used to represent the dataset + * or the data if the index is specified + * @param {number} index - data index + * @return {IStyleInterface} style object + */ + getStyle: function(index) { + var me = this; + var meta = me.getMeta(); + var dataset = meta.dataset; + var style; + + me._configure(); + if (dataset && index === undefined) { + style = me._resolveDatasetElementOptions(dataset || {}); + } else { + index = index || 0; + style = me._resolveDataElementOptions(meta.data[index] || {}, index); + } + + if (style.fill === false || style.fill === null) { + style.backgroundColor = 'rgba(0,0,0,0)'; + } + + return style; + }, + + /** + * @private + */ + _resolveDatasetElementOptions: function(element, hover) { + var me = this; + var chart = me.chart; + var datasetOpts = me._config; + var custom = element.custom || {}; + var options = chart.options.elements[me.datasetElementType.prototype._type] || {}; + var elementOptions = me._datasetElementOptions; + var values = {}; + var i, ilen, key, readKey; + + // Scriptable options + var context = { + chart: chart, + dataset: me.getDataset(), + datasetIndex: me.index, + hover: hover + }; + + for (i = 0, ilen = elementOptions.length; i < ilen; ++i) { + key = elementOptions[i]; + readKey = hover ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key; + values[key] = resolve([ + custom[readKey], + datasetOpts[readKey], + options[readKey] + ], context); + } + + return values; + }, + + /** + * @private + */ + _resolveDataElementOptions: function(element, index) { + var me = this; + var custom = element && element.custom; + var cached = me._cachedDataOpts; + if (cached && !custom) { + return cached; + } + var chart = me.chart; + var datasetOpts = me._config; + var options = chart.options.elements[me.dataElementType.prototype._type] || {}; + var elementOptions = me._dataElementOptions; + var values = {}; + + // Scriptable options + var context = { + chart: chart, + dataIndex: index, + dataset: me.getDataset(), + datasetIndex: me.index + }; + + // `resolve` sets cacheable to `false` if any option is indexed or scripted + var info = {cacheable: !custom}; + + var keys, i, ilen, key; + + custom = custom || {}; + + if (helpers$1.isArray(elementOptions)) { + for (i = 0, ilen = elementOptions.length; i < ilen; ++i) { + key = elementOptions[i]; + values[key] = resolve([ + custom[key], + datasetOpts[key], + options[key] + ], context, index, info); + } + } else { + keys = Object.keys(elementOptions); + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + values[key] = resolve([ + custom[key], + datasetOpts[elementOptions[key]], + datasetOpts[key], + options[key] + ], context, index, info); + } + } + + if (info.cacheable) { + me._cachedDataOpts = Object.freeze(values); + } + + return values; + }, + + removeHoverStyle: function(element) { + helpers$1.merge(element._model, element.$previousStyle || {}); + delete element.$previousStyle; + }, + + setHoverStyle: function(element) { + var dataset = this.chart.data.datasets[element._datasetIndex]; + var index = element._index; + var custom = element.custom || {}; + var model = element._model; + var getHoverColor = helpers$1.getHoverColor; + + element.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth + }; + + model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index); + model.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index); + model.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index); + }, + + /** + * @private + */ + _removeDatasetHoverStyle: function() { + var element = this.getMeta().dataset; + + if (element) { + this.removeHoverStyle(element); + } + }, + + /** + * @private + */ + _setDatasetHoverStyle: function() { + var element = this.getMeta().dataset; + var prev = {}; + var i, ilen, key, keys, hoverOptions, model; + + if (!element) { + return; + } + + model = element._model; + hoverOptions = this._resolveDatasetElementOptions(element, true); + + keys = Object.keys(hoverOptions); + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + prev[key] = model[key]; + model[key] = hoverOptions[key]; + } + + element.$previousStyle = prev; + }, + + /** + * @private + */ + resyncElements: function() { + var me = this; + var meta = me.getMeta(); + var data = me.getDataset().data; + var numMeta = meta.data.length; + var numData = data.length; + + if (numData < numMeta) { + meta.data.splice(numData, numMeta - numData); + } else if (numData > numMeta) { + me.insertElements(numMeta, numData - numMeta); + } + }, + + /** + * @private + */ + insertElements: function(start, count) { + for (var i = 0; i < count; ++i) { + this.addElementAndReset(start + i); + } + }, + + /** + * @private + */ + onDataPush: function() { + var count = arguments.length; + this.insertElements(this.getDataset().data.length - count, count); + }, + + /** + * @private + */ + onDataPop: function() { + this.getMeta().data.pop(); + }, + + /** + * @private + */ + onDataShift: function() { + this.getMeta().data.shift(); + }, + + /** + * @private + */ + onDataSplice: function(start, count) { + this.getMeta().data.splice(start, count); + this.insertElements(start, arguments.length - 2); + }, + + /** + * @private + */ + onDataUnshift: function() { + this.insertElements(0, arguments.length); + } + }); + + DatasetController.extend = helpers$1.inherits; + + var core_datasetController = DatasetController; + + var TAU = Math.PI * 2; + + core_defaults._set('global', { + elements: { + arc: { + backgroundColor: core_defaults.global.defaultColor, + borderColor: '#fff', + borderWidth: 2, + borderAlign: 'center' + } + } + }); + + function clipArc(ctx, arc) { + var startAngle = arc.startAngle; + var endAngle = arc.endAngle; + var pixelMargin = arc.pixelMargin; + var angleMargin = pixelMargin / arc.outerRadius; + var x = arc.x; + var y = arc.y; + + // Draw an inner border by cliping the arc and drawing a double-width border + // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders + ctx.beginPath(); + ctx.arc(x, y, arc.outerRadius, startAngle - angleMargin, endAngle + angleMargin); + if (arc.innerRadius > pixelMargin) { + angleMargin = pixelMargin / arc.innerRadius; + ctx.arc(x, y, arc.innerRadius - pixelMargin, endAngle + angleMargin, startAngle - angleMargin, true); + } else { + ctx.arc(x, y, pixelMargin, endAngle + Math.PI / 2, startAngle - Math.PI / 2); + } + ctx.closePath(); + ctx.clip(); + } + + function drawFullCircleBorders(ctx, vm, arc, inner) { + var endAngle = arc.endAngle; + var i; + + if (inner) { + arc.endAngle = arc.startAngle + TAU; + clipArc(ctx, arc); + arc.endAngle = endAngle; + if (arc.endAngle === arc.startAngle && arc.fullCircles) { + arc.endAngle += TAU; + arc.fullCircles--; + } + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.startAngle + TAU, arc.startAngle, true); + for (i = 0; i < arc.fullCircles; ++i) { + ctx.stroke(); + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.startAngle + TAU); + for (i = 0; i < arc.fullCircles; ++i) { + ctx.stroke(); + } + } + + function drawBorder(ctx, vm, arc) { + var inner = vm.borderAlign === 'inner'; + + if (inner) { + ctx.lineWidth = vm.borderWidth * 2; + ctx.lineJoin = 'round'; + } else { + ctx.lineWidth = vm.borderWidth; + ctx.lineJoin = 'bevel'; + } + + if (arc.fullCircles) { + drawFullCircleBorders(ctx, vm, arc, inner); + } + + if (inner) { + clipArc(ctx, arc); + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.endAngle); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); + ctx.closePath(); + ctx.stroke(); + } + + var element_arc = core_element.extend({ + _type: 'arc', + + inLabelRange: function(mouseX) { + var vm = this._view; + + if (vm) { + return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); + } + return false; + }, + + inRange: function(chartX, chartY) { + var vm = this._view; + + if (vm) { + var pointRelativePosition = helpers$1.getAngleFromPoint(vm, {x: chartX, y: chartY}); + var angle = pointRelativePosition.angle; + var distance = pointRelativePosition.distance; + + // Sanitise angle range + var startAngle = vm.startAngle; + var endAngle = vm.endAngle; + while (endAngle < startAngle) { + endAngle += TAU; + } + while (angle > endAngle) { + angle -= TAU; + } + while (angle < startAngle) { + angle += TAU; + } + + // Check if within the range of the open/close angle + var betweenAngles = (angle >= startAngle && angle <= endAngle); + var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); + + return (betweenAngles && withinRadius); + } + return false; + }, + + getCenterPoint: function() { + var vm = this._view; + var halfAngle = (vm.startAngle + vm.endAngle) / 2; + var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; + return { + x: vm.x + Math.cos(halfAngle) * halfRadius, + y: vm.y + Math.sin(halfAngle) * halfRadius + }; + }, + + getArea: function() { + var vm = this._view; + return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); + }, + + tooltipPosition: function() { + var vm = this._view; + var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2); + var 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; + var pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0; + var arc = { + x: vm.x, + y: vm.y, + innerRadius: vm.innerRadius, + outerRadius: Math.max(vm.outerRadius - pixelMargin, 0), + pixelMargin: pixelMargin, + startAngle: vm.startAngle, + endAngle: vm.endAngle, + fullCircles: Math.floor(vm.circumference / TAU) + }; + var i; + + ctx.save(); + + ctx.fillStyle = vm.backgroundColor; + ctx.strokeStyle = vm.borderColor; + + if (arc.fullCircles) { + arc.endAngle = arc.startAngle + TAU; + ctx.beginPath(); + ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); + ctx.closePath(); + for (i = 0; i < arc.fullCircles; ++i) { + ctx.fill(); + } + arc.endAngle = arc.startAngle + vm.circumference % TAU; + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); + ctx.closePath(); + ctx.fill(); + + if (vm.borderWidth) { + drawBorder(ctx, vm, arc); + } + + ctx.restore(); + } + }); + + var valueOrDefault$1 = helpers$1.valueOrDefault; + + var defaultColor = core_defaults.global.defaultColor; + + core_defaults._set('global', { + elements: { + line: { + tension: 0.4, + backgroundColor: defaultColor, + borderWidth: 3, + borderColor: defaultColor, + borderCapStyle: 'butt', + borderDash: [], + borderDashOffset: 0.0, + borderJoinStyle: 'miter', + capBezierPoints: true, + fill: true, // do we fill in the area between the line and its base axis + } + } + }); + + var element_line = core_element.extend({ + _type: 'line', + + draw: function() { + var me = this; + var vm = me._view; + var ctx = me._chart.ctx; + var spanGaps = vm.spanGaps; + var points = me._children.slice(); // clone array + var globalDefaults = core_defaults.global; + var globalOptionLineElements = globalDefaults.elements.line; + var lastDrawnIndex = -1; + var closePath = me._loop; + var index, previous, currentVM; + + if (!points.length) { + return; + } + + if (me._loop) { + for (index = 0; index < points.length; ++index) { + previous = helpers$1.previousItem(points, index); + // If the line has an open path, shift the point array + if (!points[index]._view.skip && previous._view.skip) { + points = points.slice(index).concat(points.slice(0, index)); + closePath = spanGaps; + break; + } + } + // If the line has a close path, add the first point again + if (closePath) { + points.push(points[0]); + } + } + + ctx.save(); + + // Stroke Line Options + ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; + + // IE 9 and 10 do not support line dash + if (ctx.setLineDash) { + ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); + } + + ctx.lineDashOffset = valueOrDefault$1(vm.borderDashOffset, globalOptionLineElements.borderDashOffset); + ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; + ctx.lineWidth = valueOrDefault$1(vm.borderWidth, globalOptionLineElements.borderWidth); + ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; + + // Stroke Line + ctx.beginPath(); + + // First point moves to it's starting position no matter what + currentVM = points[0]._view; + if (!currentVM.skip) { + ctx.moveTo(currentVM.x, currentVM.y); + lastDrawnIndex = 0; + } + + for (index = 1; index < points.length; ++index) { + currentVM = points[index]._view; + previous = lastDrawnIndex === -1 ? helpers$1.previousItem(points, index) : points[lastDrawnIndex]; + + if (!currentVM.skip) { + if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { + // There was a gap and this is the first point after the gap + ctx.moveTo(currentVM.x, currentVM.y); + } else { + // Line to next point + helpers$1.canvas.lineTo(ctx, previous._view, currentVM); + } + lastDrawnIndex = index; + } + } + + if (closePath) { + ctx.closePath(); + } + + ctx.stroke(); + ctx.restore(); + } + }); + + var valueOrDefault$2 = helpers$1.valueOrDefault; + + var defaultColor$1 = core_defaults.global.defaultColor; + + core_defaults._set('global', { + elements: { + point: { + radius: 3, + pointStyle: 'circle', + backgroundColor: defaultColor$1, + borderColor: defaultColor$1, + borderWidth: 1, + // Hover + hitRadius: 1, + hoverRadius: 4, + hoverBorderWidth: 1 + } + } + }); + + function xRange(mouseX) { + var vm = this._view; + return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false; + } + + function yRange(mouseY) { + var vm = this._view; + return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false; + } + + var element_point = core_element.extend({ + _type: 'point', + + inRange: function(mouseX, mouseY) { + var vm = this._view; + return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; + }, + + inLabelRange: xRange, + inXRange: xRange, + inYRange: yRange, + + getCenterPoint: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y + }; + }, + + getArea: function() { + return Math.PI * Math.pow(this._view.radius, 2); + }, + + tooltipPosition: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y, + padding: vm.radius + vm.borderWidth + }; + }, + + draw: function(chartArea) { + var vm = this._view; + var ctx = this._chart.ctx; + var pointStyle = vm.pointStyle; + var rotation = vm.rotation; + var radius = vm.radius; + var x = vm.x; + var y = vm.y; + var globalDefaults = core_defaults.global; + var defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow + + if (vm.skip) { + return; + } + + // Clipping for Points. + if (chartArea === undefined || helpers$1.canvas._isPointInArea(vm, chartArea)) { + ctx.strokeStyle = vm.borderColor || defaultColor; + ctx.lineWidth = valueOrDefault$2(vm.borderWidth, globalDefaults.elements.point.borderWidth); + ctx.fillStyle = vm.backgroundColor || defaultColor; + helpers$1.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation); + } + } + }); + + var defaultColor$2 = core_defaults.global.defaultColor; + + core_defaults._set('global', { + elements: { + rectangle: { + backgroundColor: defaultColor$2, + borderColor: defaultColor$2, + borderSkipped: 'bottom', + borderWidth: 0 + } + } + }); + + function isVertical(vm) { + return vm && vm.width !== undefined; + } + + /** + * Helper function to get the bounds of the bar regardless of the orientation + * @param bar {Chart.Element.Rectangle} the bar + * @return {Bounds} bounds of the bar + * @private + */ + function getBarBounds(vm) { + var x1, x2, y1, y2, half; + + if (isVertical(vm)) { + half = vm.width / 2; + x1 = vm.x - half; + x2 = vm.x + half; + y1 = Math.min(vm.y, vm.base); + y2 = Math.max(vm.y, vm.base); + } else { + half = vm.height / 2; + x1 = Math.min(vm.x, vm.base); + x2 = Math.max(vm.x, vm.base); + y1 = vm.y - half; + y2 = vm.y + half; + } + + return { + left: x1, + top: y1, + right: x2, + bottom: y2 + }; + } + + function swap(orig, v1, v2) { + return orig === v1 ? v2 : orig === v2 ? v1 : orig; + } + + function parseBorderSkipped(vm) { + var edge = vm.borderSkipped; + var res = {}; + + if (!edge) { + return res; + } + + if (vm.horizontal) { + if (vm.base > vm.x) { + edge = swap(edge, 'left', 'right'); + } + } else if (vm.base < vm.y) { + edge = swap(edge, 'bottom', 'top'); + } + + res[edge] = true; + return res; + } + + function parseBorderWidth(vm, maxW, maxH) { + var value = vm.borderWidth; + var skip = parseBorderSkipped(vm); + var t, r, b, l; + + if (helpers$1.isObject(value)) { + t = +value.top || 0; + r = +value.right || 0; + b = +value.bottom || 0; + l = +value.left || 0; + } else { + t = r = b = l = +value || 0; + } + + return { + t: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t, + r: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r, + b: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b, + l: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l + }; + } + + function boundingRects(vm) { + var bounds = getBarBounds(vm); + var width = bounds.right - bounds.left; + var height = bounds.bottom - bounds.top; + var border = parseBorderWidth(vm, width / 2, height / 2); + + return { + outer: { + x: bounds.left, + y: bounds.top, + w: width, + h: height + }, + inner: { + x: bounds.left + border.l, + y: bounds.top + border.t, + w: width - border.l - border.r, + h: height - border.t - border.b + } + }; + } + + function inRange(vm, x, y) { + var skipX = x === null; + var skipY = y === null; + var bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm); + + return bounds + && (skipX || x >= bounds.left && x <= bounds.right) + && (skipY || y >= bounds.top && y <= bounds.bottom); + } + + var element_rectangle = core_element.extend({ + _type: 'rectangle', + + draw: function() { + var ctx = this._chart.ctx; + var vm = this._view; + var rects = boundingRects(vm); + var outer = rects.outer; + var inner = rects.inner; + + ctx.fillStyle = vm.backgroundColor; + ctx.fillRect(outer.x, outer.y, outer.w, outer.h); + + if (outer.w === inner.w && outer.h === inner.h) { + return; + } + + ctx.save(); + ctx.beginPath(); + ctx.rect(outer.x, outer.y, outer.w, outer.h); + ctx.clip(); + ctx.fillStyle = vm.borderColor; + ctx.rect(inner.x, inner.y, inner.w, inner.h); + ctx.fill('evenodd'); + ctx.restore(); + }, + + height: function() { + var vm = this._view; + return vm.base - vm.y; + }, + + inRange: function(mouseX, mouseY) { + return inRange(this._view, mouseX, mouseY); + }, + + inLabelRange: function(mouseX, mouseY) { + var vm = this._view; + return isVertical(vm) + ? inRange(vm, mouseX, null) + : inRange(vm, null, mouseY); + }, + + inXRange: function(mouseX) { + return inRange(this._view, mouseX, null); + }, + + inYRange: function(mouseY) { + return inRange(this._view, null, mouseY); + }, + + getCenterPoint: function() { + var vm = this._view; + var x, y; + if (isVertical(vm)) { + x = vm.x; + y = (vm.y + vm.base) / 2; + } else { + x = (vm.x + vm.base) / 2; + y = vm.y; + } + + return {x: x, y: y}; + }, + + getArea: function() { + var vm = this._view; + + return isVertical(vm) + ? vm.width * Math.abs(vm.y - vm.base) + : vm.height * Math.abs(vm.x - vm.base); + }, + + tooltipPosition: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y + }; + } + }); + + var elements = {}; + var Arc = element_arc; + var Line = element_line; + var Point = element_point; + var Rectangle = element_rectangle; + elements.Arc = Arc; + elements.Line = Line; + elements.Point = Point; + elements.Rectangle = Rectangle; + + var deprecated = helpers$1._deprecated; + var valueOrDefault$3 = helpers$1.valueOrDefault; + + core_defaults._set('bar', { + hover: { + mode: 'label' + }, + + scales: { + xAxes: [{ + type: 'category', + offset: true, + gridLines: { + offsetGridLines: true + } + }], + + yAxes: [{ + type: 'linear' + }] + } + }); + + core_defaults._set('global', { + datasets: { + bar: { + categoryPercentage: 0.8, + barPercentage: 0.9 + } + } + }); + + /** + * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap. + * @private + */ + function computeMinSampleSize(scale, pixels) { + var min = scale._length; + var prev, curr, i, ilen; + + for (i = 1, ilen = pixels.length; i < ilen; ++i) { + min = Math.min(min, Math.abs(pixels[i] - pixels[i - 1])); + } + + for (i = 0, ilen = scale.getTicks().length; i < ilen; ++i) { + curr = scale.getPixelForTick(i); + min = i > 0 ? Math.min(min, Math.abs(curr - prev)) : min; + prev = curr; + } + + return min; + } + + /** + * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null, + * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This + * mode currently always generates bars equally sized (until we introduce scriptable options?). + * @private + */ + function computeFitCategoryTraits(index, ruler, options) { + var thickness = options.barThickness; + var count = ruler.stackCount; + var curr = ruler.pixels[index]; + var min = helpers$1.isNullOrUndef(thickness) + ? computeMinSampleSize(ruler.scale, ruler.pixels) + : -1; + var size, ratio; + + if (helpers$1.isNullOrUndef(thickness)) { + size = min * options.categoryPercentage; + ratio = options.barPercentage; + } else { + // When bar thickness is enforced, category and bar percentages are ignored. + // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%') + // and deprecate barPercentage since this value is ignored when thickness is absolute. + size = thickness * count; + ratio = 1; + } + + return { + chunk: size / count, + ratio: ratio, + start: curr - (size / 2) + }; + } + + /** + * Computes an "optimal" category that globally arranges bars side by side (no gap when + * percentage options are 1), based on the previous and following categories. This mode + * generates bars with different widths when data are not evenly spaced. + * @private + */ + function computeFlexCategoryTraits(index, ruler, options) { + var pixels = ruler.pixels; + var curr = pixels[index]; + var prev = index > 0 ? pixels[index - 1] : null; + var next = index < pixels.length - 1 ? pixels[index + 1] : null; + var percent = options.categoryPercentage; + var start, size; + + if (prev === null) { + // first data: its size is double based on the next point or, + // if it's also the last data, we use the scale size. + prev = curr - (next === null ? ruler.end - ruler.start : next - curr); + } + + if (next === null) { + // last data: its size is also double based on the previous point. + next = curr + curr - prev; + } + + start = curr - (curr - Math.min(prev, next)) / 2 * percent; + size = Math.abs(next - prev) / 2 * percent; + + return { + chunk: size / ruler.stackCount, + ratio: options.barPercentage, + start: start + }; + } + + var controller_bar = core_datasetController.extend({ + + dataElementType: elements.Rectangle, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderSkipped', + 'borderWidth', + 'barPercentage', + 'barThickness', + 'categoryPercentage', + 'maxBarThickness', + 'minBarLength' + ], + + initialize: function() { + var me = this; + var meta, scaleOpts; + + core_datasetController.prototype.initialize.apply(me, arguments); + + meta = me.getMeta(); + meta.stack = me.getDataset().stack; + meta.bar = true; + + scaleOpts = me._getIndexScale().options; + deprecated('bar chart', scaleOpts.barPercentage, 'scales.[x/y]Axes.barPercentage', 'dataset.barPercentage'); + deprecated('bar chart', scaleOpts.barThickness, 'scales.[x/y]Axes.barThickness', 'dataset.barThickness'); + deprecated('bar chart', scaleOpts.categoryPercentage, 'scales.[x/y]Axes.categoryPercentage', 'dataset.categoryPercentage'); + deprecated('bar chart', me._getValueScale().options.minBarLength, 'scales.[x/y]Axes.minBarLength', 'dataset.minBarLength'); + deprecated('bar chart', scaleOpts.maxBarThickness, 'scales.[x/y]Axes.maxBarThickness', 'dataset.maxBarThickness'); + }, + + update: function(reset) { + var me = this; + var rects = me.getMeta().data; + var i, ilen; + + me._ruler = me.getRuler(); + + for (i = 0, ilen = rects.length; i < ilen; ++i) { + me.updateElement(rects[i], i, reset); + } + }, + + updateElement: function(rectangle, index, reset) { + var me = this; + var meta = me.getMeta(); + var dataset = me.getDataset(); + var options = me._resolveDataElementOptions(rectangle, index); + + rectangle._xScale = me.getScaleForId(meta.xAxisID); + rectangle._yScale = me.getScaleForId(meta.yAxisID); + rectangle._datasetIndex = me.index; + rectangle._index = index; + rectangle._model = { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderSkipped: options.borderSkipped, + borderWidth: options.borderWidth, + datasetLabel: dataset.label, + label: me.chart.data.labels[index] + }; + + if (helpers$1.isArray(dataset.data[index])) { + rectangle._model.borderSkipped = null; + } + + me._updateElementGeometry(rectangle, index, reset, options); + + rectangle.pivot(); + }, + + /** + * @private + */ + _updateElementGeometry: function(rectangle, index, reset, options) { + var me = this; + var model = rectangle._model; + var vscale = me._getValueScale(); + var base = vscale.getBasePixel(); + var horizontal = vscale.isHorizontal(); + var ruler = me._ruler || me.getRuler(); + var vpixels = me.calculateBarValuePixels(me.index, index, options); + var ipixels = me.calculateBarIndexPixels(me.index, index, ruler, options); + + model.horizontal = horizontal; + model.base = reset ? base : vpixels.base; + model.x = horizontal ? reset ? base : vpixels.head : ipixels.center; + model.y = horizontal ? ipixels.center : reset ? base : vpixels.head; + model.height = horizontal ? ipixels.size : undefined; + model.width = horizontal ? undefined : ipixels.size; + }, + + /** + * Returns the stacks based on groups and bar visibility. + * @param {number} [last] - The dataset index + * @returns {string[]} The list of stack IDs + * @private + */ + _getStacks: function(last) { + var me = this; + var scale = me._getIndexScale(); + var metasets = scale._getMatchingVisibleMetas(me._type); + var stacked = scale.options.stacked; + var ilen = metasets.length; + var stacks = []; + var i, meta; + + for (i = 0; i < ilen; ++i) { + meta = metasets[i]; + // stacked | meta.stack + // | found | not found | undefined + // false | x | x | x + // true | | x | + // undefined | | x | x + if (stacked === false || stacks.indexOf(meta.stack) === -1 || + (stacked === undefined && meta.stack === undefined)) { + stacks.push(meta.stack); + } + if (meta.index === last) { + break; + } + } + + return stacks; + }, + + /** + * Returns the effective number of stacks based on groups and bar visibility. + * @private + */ + getStackCount: function() { + return this._getStacks().length; + }, + + /** + * Returns the stack index for the given dataset based on groups and bar visibility. + * @param {number} [datasetIndex] - The dataset index + * @param {string} [name] - The stack name to find + * @returns {number} The stack index + * @private + */ + getStackIndex: function(datasetIndex, name) { + var stacks = this._getStacks(datasetIndex); + var index = (name !== undefined) + ? stacks.indexOf(name) + : -1; // indexOf returns -1 if element is not present + + return (index === -1) + ? stacks.length - 1 + : index; + }, + + /** + * @private + */ + getRuler: function() { + var me = this; + var scale = me._getIndexScale(); + var pixels = []; + var i, ilen; + + for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) { + pixels.push(scale.getPixelForValue(null, i, me.index)); + } + + return { + pixels: pixels, + start: scale._startPixel, + end: scale._endPixel, + stackCount: me.getStackCount(), + scale: scale + }; + }, + + /** + * Note: pixel values are not clamped to the scale area. + * @private + */ + calculateBarValuePixels: function(datasetIndex, index, options) { + var me = this; + var chart = me.chart; + var scale = me._getValueScale(); + var isHorizontal = scale.isHorizontal(); + var datasets = chart.data.datasets; + var metasets = scale._getMatchingVisibleMetas(me._type); + var value = scale._parseValue(datasets[datasetIndex].data[index]); + var minBarLength = options.minBarLength; + var stacked = scale.options.stacked; + var stack = me.getMeta().stack; + var start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max; + var length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max; + var ilen = metasets.length; + var i, imeta, ivalue, base, head, size, stackLength; + + if (stacked || (stacked === undefined && stack !== undefined)) { + for (i = 0; i < ilen; ++i) { + imeta = metasets[i]; + + if (imeta.index === datasetIndex) { + break; + } + + if (imeta.stack === stack) { + stackLength = scale._parseValue(datasets[imeta.index].data[index]); + ivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min; + + if ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) { + start += ivalue; + } + } + } + } + + base = scale.getPixelForValue(start); + head = scale.getPixelForValue(start + length); + size = head - base; + + if (minBarLength !== undefined && Math.abs(size) < minBarLength) { + size = minBarLength; + if (length >= 0 && !isHorizontal || length < 0 && isHorizontal) { + head = base - minBarLength; + } else { + head = base + minBarLength; + } + } + + return { + size: size, + base: base, + head: head, + center: head + size / 2 + }; + }, + + /** + * @private + */ + calculateBarIndexPixels: function(datasetIndex, index, ruler, options) { + var me = this; + var range = options.barThickness === 'flex' + ? computeFlexCategoryTraits(index, ruler, options) + : computeFitCategoryTraits(index, ruler, options); + + var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack); + var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); + var size = Math.min( + valueOrDefault$3(options.maxBarThickness, Infinity), + range.chunk * range.ratio); + + return { + base: center - size / 2, + head: center + size / 2, + center: center, + size: size + }; + }, + + draw: function() { + var me = this; + var chart = me.chart; + var scale = me._getValueScale(); + var rects = me.getMeta().data; + var dataset = me.getDataset(); + var ilen = rects.length; + var i = 0; + + helpers$1.canvas.clipArea(chart.ctx, chart.chartArea); + + for (; i < ilen; ++i) { + var val = scale._parseValue(dataset.data[i]); + if (!isNaN(val.min) && !isNaN(val.max)) { + rects[i].draw(); + } + } + + helpers$1.canvas.unclipArea(chart.ctx); + }, + + /** + * @private + */ + _resolveDataElementOptions: function() { + var me = this; + var values = helpers$1.extend({}, core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments)); + var indexOpts = me._getIndexScale().options; + var valueOpts = me._getValueScale().options; + + values.barPercentage = valueOrDefault$3(indexOpts.barPercentage, values.barPercentage); + values.barThickness = valueOrDefault$3(indexOpts.barThickness, values.barThickness); + values.categoryPercentage = valueOrDefault$3(indexOpts.categoryPercentage, values.categoryPercentage); + values.maxBarThickness = valueOrDefault$3(indexOpts.maxBarThickness, values.maxBarThickness); + values.minBarLength = valueOrDefault$3(valueOpts.minBarLength, values.minBarLength); + + return values; + } + + }); + + var valueOrDefault$4 = helpers$1.valueOrDefault; + var resolve$1 = helpers$1.options.resolve; + + core_defaults._set('bubble', { + hover: { + mode: 'single' + }, + + scales: { + xAxes: [{ + type: 'linear', // bubble should probably use a linear scale by default + position: 'bottom', + id: 'x-axis-0' // need an ID so datasets can reference the scale + }], + yAxes: [{ + type: 'linear', + position: 'left', + id: 'y-axis-0' + }] + }, + + tooltips: { + callbacks: { + title: function() { + // Title doesn't make sense for scatter since we format the data as a point + return ''; + }, + label: function(item, data) { + var datasetLabel = data.datasets[item.datasetIndex].label || ''; + var dataPoint = data.datasets[item.datasetIndex].data[item.index]; + return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')'; + } + } + } + }); + + var controller_bubble = core_datasetController.extend({ + /** + * @protected + */ + dataElementType: elements.Point, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'hoverBackgroundColor', + 'hoverBorderColor', + 'hoverBorderWidth', + 'hoverRadius', + 'hitRadius', + 'pointStyle', + 'rotation' + ], + + /** + * @protected + */ + update: function(reset) { + var me = this; + var meta = me.getMeta(); + var points = meta.data; + + // Update Points + helpers$1.each(points, function(point, index) { + me.updateElement(point, index, reset); + }); + }, + + /** + * @protected + */ + updateElement: function(point, index, reset) { + var me = this; + var meta = me.getMeta(); + var custom = point.custom || {}; + var xScale = me.getScaleForId(meta.xAxisID); + var yScale = me.getScaleForId(meta.yAxisID); + var options = me._resolveDataElementOptions(point, index); + var data = me.getDataset().data[index]; + var dsIndex = me.index; + + var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex); + var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex); + + point._xScale = xScale; + point._yScale = yScale; + point._options = options; + point._datasetIndex = dsIndex; + point._index = index; + point._model = { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + hitRadius: options.hitRadius, + pointStyle: options.pointStyle, + rotation: options.rotation, + radius: reset ? 0 : options.radius, + skip: custom.skip || isNaN(x) || isNaN(y), + x: x, + y: y, + }; + + point.pivot(); + }, + + /** + * @protected + */ + setHoverStyle: function(point) { + var model = point._model; + var options = point._options; + var getHoverColor = helpers$1.getHoverColor; + + point.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + radius: model.radius + }; + + model.backgroundColor = valueOrDefault$4(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$4(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$4(options.hoverBorderWidth, options.borderWidth); + model.radius = options.radius + options.hoverRadius; + }, + + /** + * @private + */ + _resolveDataElementOptions: function(point, index) { + var me = this; + var chart = me.chart; + var dataset = me.getDataset(); + var custom = point.custom || {}; + var data = dataset.data[index] || {}; + var values = core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments); + + // Scriptable options + var context = { + chart: chart, + dataIndex: index, + dataset: dataset, + datasetIndex: me.index + }; + + // In case values were cached (and thus frozen), we need to clone the values + if (me._cachedDataOpts === values) { + values = helpers$1.extend({}, values); + } + + // Custom radius resolution + values.radius = resolve$1([ + custom.radius, + data.r, + me._config.radius, + chart.options.elements.point.radius + ], context, index); + + return values; + } + }); + + var valueOrDefault$5 = helpers$1.valueOrDefault; + + var PI$1 = Math.PI; + var DOUBLE_PI$1 = PI$1 * 2; + var HALF_PI$1 = PI$1 / 2; + + core_defaults._set('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 + }, + hover: { + mode: 'single' + }, + legendCallback: function(chart) { + var list = document.createElement('ul'); + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + var i, ilen, listItem, listItemSpan; + + list.setAttribute('class', chart.id + '-legend'); + if (datasets.length) { + for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) { + listItem = list.appendChild(document.createElement('li')); + listItemSpan = listItem.appendChild(document.createElement('span')); + listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i]; + if (labels[i]) { + listItem.appendChild(document.createTextNode(labels[i])); + } + } + } + + return list.outerHTML; + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var style = meta.controller.getStyle(i); + + return { + text: label, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + lineWidth: style.borderWidth, + hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } + return []; + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + // toggle visibility of index if exists + if (meta.data[index]) { + meta.data[index].hidden = !meta.data[index].hidden; + } + } + + chart.update(); + } + }, + + // The percentage of the chart that we cut out of the middle. + cutoutPercentage: 50, + + // The rotation of the chart, where the first data arc begins. + rotation: -HALF_PI$1, + + // The total circumference of the chart. + circumference: DOUBLE_PI$1, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(tooltipItem, data) { + var dataLabel = data.labels[tooltipItem.index]; + var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; + + if (helpers$1.isArray(dataLabel)) { + // show value on first line of multiline label + // need to clone because we are changing the value + dataLabel = dataLabel.slice(); + dataLabel[0] += value; + } else { + dataLabel += value; + } + + return dataLabel; + } + } + } + }); + + var controller_doughnut = core_datasetController.extend({ + + dataElementType: elements.Arc, + + linkScales: helpers$1.noop, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'borderAlign', + 'hoverBackgroundColor', + 'hoverBorderColor', + 'hoverBorderWidth', + ], + + // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly + getRingIndex: function(datasetIndex) { + var ringIndex = 0; + + for (var j = 0; j < datasetIndex; ++j) { + if (this.chart.isDatasetVisible(j)) { + ++ringIndex; + } + } + + return ringIndex; + }, + + update: function(reset) { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var opts = chart.options; + var ratioX = 1; + var ratioY = 1; + var offsetX = 0; + var offsetY = 0; + var meta = me.getMeta(); + var arcs = meta.data; + var cutout = opts.cutoutPercentage / 100 || 0; + var circumference = opts.circumference; + var chartWeight = me._getRingWeight(me.index); + var maxWidth, maxHeight, i, ilen; + + // If the chart's circumference isn't a full circle, calculate size as a ratio of the width/height of the arc + if (circumference < DOUBLE_PI$1) { + var startAngle = opts.rotation % DOUBLE_PI$1; + startAngle += startAngle >= PI$1 ? -DOUBLE_PI$1 : startAngle < -PI$1 ? DOUBLE_PI$1 : 0; + var endAngle = startAngle + circumference; + var startX = Math.cos(startAngle); + var startY = Math.sin(startAngle); + var endX = Math.cos(endAngle); + var endY = Math.sin(endAngle); + var contains0 = (startAngle <= 0 && endAngle >= 0) || endAngle >= DOUBLE_PI$1; + var contains90 = (startAngle <= HALF_PI$1 && endAngle >= HALF_PI$1) || endAngle >= DOUBLE_PI$1 + HALF_PI$1; + var contains180 = startAngle === -PI$1 || endAngle >= PI$1; + var contains270 = (startAngle <= -HALF_PI$1 && endAngle >= -HALF_PI$1) || endAngle >= PI$1 + HALF_PI$1; + var minX = contains180 ? -1 : Math.min(startX, startX * cutout, endX, endX * cutout); + var minY = contains270 ? -1 : Math.min(startY, startY * cutout, endY, endY * cutout); + var maxX = contains0 ? 1 : Math.max(startX, startX * cutout, endX, endX * cutout); + var maxY = contains90 ? 1 : Math.max(startY, startY * cutout, endY, endY * cutout); + ratioX = (maxX - minX) / 2; + ratioY = (maxY - minY) / 2; + offsetX = -(maxX + minX) / 2; + offsetY = -(maxY + minY) / 2; + } + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + arcs[i]._options = me._resolveDataElementOptions(arcs[i], i); + } + + chart.borderWidth = me.getMaxBorderWidth(); + maxWidth = (chartArea.right - chartArea.left - chart.borderWidth) / ratioX; + maxHeight = (chartArea.bottom - chartArea.top - chart.borderWidth) / ratioY; + chart.outerRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0); + chart.innerRadius = Math.max(chart.outerRadius * cutout, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1); + chart.offsetX = offsetX * chart.outerRadius; + chart.offsetY = offsetY * chart.outerRadius; + + meta.total = me.calculateTotal(); + + me.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index); + me.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0); + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + me.updateElement(arcs[i], i, reset); + } + }, + + updateElement: function(arc, index, reset) { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var opts = chart.options; + var animationOpts = opts.animation; + var centerX = (chartArea.left + chartArea.right) / 2; + var centerY = (chartArea.top + chartArea.bottom) / 2; + var startAngle = opts.rotation; // non reset case handled later + var endAngle = opts.rotation; // non reset case handled later + var dataset = me.getDataset(); + var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / DOUBLE_PI$1); + var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius; + var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius; + var options = arc._options || {}; + + helpers$1.extend(arc, { + // Utility + _datasetIndex: me.index, + _index: index, + + // Desired view properties + _model: { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + borderAlign: options.borderAlign, + x: centerX + chart.offsetX, + y: centerY + chart.offsetY, + startAngle: startAngle, + endAngle: endAngle, + circumference: circumference, + outerRadius: outerRadius, + innerRadius: innerRadius, + label: helpers$1.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) + } + }); + + var model = arc._model; + + // Set correct angles if not resetting + if (!reset || !animationOpts.animateRotate) { + if (index === 0) { + model.startAngle = opts.rotation; + } else { + model.startAngle = me.getMeta().data[index - 1]._model.endAngle; + } + + model.endAngle = model.startAngle + model.circumference; + } + + arc.pivot(); + }, + + calculateTotal: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var total = 0; + var value; + + helpers$1.each(meta.data, function(element, index) { + value = dataset.data[index]; + if (!isNaN(value) && !element.hidden) { + total += Math.abs(value); + } + }); + + /* if (total === 0) { + total = NaN; + }*/ + + return total; + }, + + calculateCircumference: function(value) { + var total = this.getMeta().total; + if (total > 0 && !isNaN(value)) { + return DOUBLE_PI$1 * (Math.abs(value) / total); + } + return 0; + }, + + // gets the max border or hover width to properly scale pie charts + getMaxBorderWidth: function(arcs) { + var me = this; + var max = 0; + var chart = me.chart; + var i, ilen, meta, arc, controller, options, borderWidth, hoverWidth; + + if (!arcs) { + // Find the outmost visible dataset + for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) { + if (chart.isDatasetVisible(i)) { + meta = chart.getDatasetMeta(i); + arcs = meta.data; + if (i !== me.index) { + controller = meta.controller; + } + break; + } + } + } + + if (!arcs) { + return 0; + } + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + arc = arcs[i]; + if (controller) { + controller._configure(); + options = controller._resolveDataElementOptions(arc, i); + } else { + options = arc._options; + } + if (options.borderAlign !== 'inner') { + borderWidth = options.borderWidth; + hoverWidth = options.hoverBorderWidth; + + max = borderWidth > max ? borderWidth : max; + max = hoverWidth > max ? hoverWidth : max; + } + } + return max; + }, + + /** + * @protected + */ + setHoverStyle: function(arc) { + var model = arc._model; + var options = arc._options; + var getHoverColor = helpers$1.getHoverColor; + + arc.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + }; + + model.backgroundColor = valueOrDefault$5(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$5(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$5(options.hoverBorderWidth, options.borderWidth); + }, + + /** + * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly + * @private + */ + _getRingWeightOffset: function(datasetIndex) { + var ringWeightOffset = 0; + + for (var i = 0; i < datasetIndex; ++i) { + if (this.chart.isDatasetVisible(i)) { + ringWeightOffset += this._getRingWeight(i); + } + } + + return ringWeightOffset; + }, + + /** + * @private + */ + _getRingWeight: function(dataSetIndex) { + return Math.max(valueOrDefault$5(this.chart.data.datasets[dataSetIndex].weight, 1), 0); + }, + + /** + * Returns the sum of all visibile data set weights. This value can be 0. + * @private + */ + _getVisibleDatasetWeightTotal: function() { + return this._getRingWeightOffset(this.chart.data.datasets.length); + } + }); + + core_defaults._set('horizontalBar', { + hover: { + mode: 'index', + axis: 'y' + }, + + scales: { + xAxes: [{ + type: 'linear', + position: 'bottom' + }], + + yAxes: [{ + type: 'category', + position: 'left', + offset: true, + gridLines: { + offsetGridLines: true + } + }] + }, + + elements: { + rectangle: { + borderSkipped: 'left' + } + }, + + tooltips: { + mode: 'index', + axis: 'y' + } + }); + + core_defaults._set('global', { + datasets: { + horizontalBar: { + categoryPercentage: 0.8, + barPercentage: 0.9 + } + } + }); + + var controller_horizontalBar = controller_bar.extend({ + /** + * @private + */ + _getValueScaleId: function() { + return this.getMeta().xAxisID; + }, + + /** + * @private + */ + _getIndexScaleId: function() { + return this.getMeta().yAxisID; + } + }); + + var valueOrDefault$6 = helpers$1.valueOrDefault; + var resolve$2 = helpers$1.options.resolve; + var isPointInArea = helpers$1.canvas._isPointInArea; + + core_defaults._set('line', { + showLines: true, + spanGaps: false, + + hover: { + mode: 'label' + }, + + scales: { + xAxes: [{ + type: 'category', + id: 'x-axis-0' + }], + yAxes: [{ + type: 'linear', + id: 'y-axis-0' + }] + } + }); + + function scaleClip(scale, halfBorderWidth) { + var tickOpts = scale && scale.options.ticks || {}; + var reverse = tickOpts.reverse; + var min = tickOpts.min === undefined ? halfBorderWidth : 0; + var max = tickOpts.max === undefined ? halfBorderWidth : 0; + return { + start: reverse ? max : min, + end: reverse ? min : max + }; + } + + function defaultClip(xScale, yScale, borderWidth) { + var halfBorderWidth = borderWidth / 2; + var x = scaleClip(xScale, halfBorderWidth); + var y = scaleClip(yScale, halfBorderWidth); + + return { + top: y.end, + right: x.end, + bottom: y.start, + left: x.start + }; + } + + function toClip(value) { + var t, r, b, l; + + if (helpers$1.isObject(value)) { + t = value.top; + r = value.right; + b = value.bottom; + l = value.left; + } else { + t = r = b = l = value; + } + + return { + top: t, + right: r, + bottom: b, + left: l + }; + } + + + var controller_line = core_datasetController.extend({ + + datasetElementType: elements.Line, + + dataElementType: elements.Point, + + /** + * @private + */ + _datasetElementOptions: [ + 'backgroundColor', + 'borderCapStyle', + 'borderColor', + 'borderDash', + 'borderDashOffset', + 'borderJoinStyle', + 'borderWidth', + 'cubicInterpolationMode', + 'fill' + ], + + /** + * @private + */ + _dataElementOptions: { + backgroundColor: 'pointBackgroundColor', + borderColor: 'pointBorderColor', + borderWidth: 'pointBorderWidth', + hitRadius: 'pointHitRadius', + hoverBackgroundColor: 'pointHoverBackgroundColor', + hoverBorderColor: 'pointHoverBorderColor', + hoverBorderWidth: 'pointHoverBorderWidth', + hoverRadius: 'pointHoverRadius', + pointStyle: 'pointStyle', + radius: 'pointRadius', + rotation: 'pointRotation' + }, + + update: function(reset) { + var me = this; + var meta = me.getMeta(); + var line = meta.dataset; + var points = meta.data || []; + var options = me.chart.options; + var config = me._config; + var showLine = me._showLine = valueOrDefault$6(config.showLine, options.showLines); + var i, ilen; + + me._xScale = me.getScaleForId(meta.xAxisID); + me._yScale = me.getScaleForId(meta.yAxisID); + + // Update Line + if (showLine) { + // Compatibility: If the properties are defined with only the old name, use those values + if (config.tension !== undefined && config.lineTension === undefined) { + config.lineTension = config.tension; + } + + // Utility + line._scale = me._yScale; + line._datasetIndex = me.index; + // Data + line._children = points; + // Model + line._model = me._resolveDatasetElementOptions(line); + + line.pivot(); + } + + // Update Points + for (i = 0, ilen = points.length; i < ilen; ++i) { + me.updateElement(points[i], i, reset); + } + + if (showLine && line._model.tension !== 0) { + me.updateBezierControlPoints(); + } + + // Now pivot the point for animation + for (i = 0, ilen = points.length; i < ilen; ++i) { + points[i].pivot(); + } + }, + + updateElement: function(point, index, reset) { + var me = this; + var meta = me.getMeta(); + var custom = point.custom || {}; + var dataset = me.getDataset(); + var datasetIndex = me.index; + var value = dataset.data[index]; + var xScale = me._xScale; + var yScale = me._yScale; + var lineModel = meta.dataset._model; + var x, y; + + var options = me._resolveDataElementOptions(point, index); + + x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex); + y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); + + // Utility + point._xScale = xScale; + point._yScale = yScale; + point._options = options; + point._datasetIndex = datasetIndex; + point._index = index; + + // Desired view properties + point._model = { + x: x, + y: y, + skip: custom.skip || isNaN(x) || isNaN(y), + // Appearance + radius: options.radius, + pointStyle: options.pointStyle, + rotation: options.rotation, + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + tension: valueOrDefault$6(custom.tension, lineModel ? lineModel.tension : 0), + steppedLine: lineModel ? lineModel.steppedLine : false, + // Tooltip + hitRadius: options.hitRadius + }; + }, + + /** + * @private + */ + _resolveDatasetElementOptions: function(element) { + var me = this; + var config = me._config; + var custom = element.custom || {}; + var options = me.chart.options; + var lineOptions = options.elements.line; + var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments); + + // The default behavior of lines is to break at null values, according + // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158 + // This option gives lines the ability to span gaps + values.spanGaps = valueOrDefault$6(config.spanGaps, options.spanGaps); + values.tension = valueOrDefault$6(config.lineTension, lineOptions.tension); + values.steppedLine = resolve$2([custom.steppedLine, config.steppedLine, lineOptions.stepped]); + values.clip = toClip(valueOrDefault$6(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth))); + + return values; + }, + + calculatePointY: function(value, index, datasetIndex) { + var me = this; + var chart = me.chart; + var yScale = me._yScale; + var sumPos = 0; + var sumNeg = 0; + var i, ds, dsMeta, stackedRightValue, rightValue, metasets, ilen; + + if (yScale.options.stacked) { + rightValue = +yScale.getRightValue(value); + metasets = chart._getSortedVisibleDatasetMetas(); + ilen = metasets.length; + + for (i = 0; i < ilen; ++i) { + dsMeta = metasets[i]; + if (dsMeta.index === datasetIndex) { + break; + } + + ds = chart.data.datasets[dsMeta.index]; + if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) { + stackedRightValue = +yScale.getRightValue(ds.data[index]); + if (stackedRightValue < 0) { + sumNeg += stackedRightValue || 0; + } else { + sumPos += stackedRightValue || 0; + } + } + } + + if (rightValue < 0) { + return yScale.getPixelForValue(sumNeg + rightValue); + } + return yScale.getPixelForValue(sumPos + rightValue); + } + return yScale.getPixelForValue(value); + }, + + updateBezierControlPoints: function() { + var me = this; + var chart = me.chart; + var meta = me.getMeta(); + var lineModel = meta.dataset._model; + var area = chart.chartArea; + var points = meta.data || []; + var i, ilen, model, controlPoints; + + // Only consider points that are drawn in case the spanGaps option is used + if (lineModel.spanGaps) { + points = points.filter(function(pt) { + return !pt._model.skip; + }); + } + + function capControlPoint(pt, min, max) { + return Math.max(Math.min(pt, max), min); + } + + if (lineModel.cubicInterpolationMode === 'monotone') { + helpers$1.splineCurveMonotone(points); + } else { + for (i = 0, ilen = points.length; i < ilen; ++i) { + model = points[i]._model; + controlPoints = helpers$1.splineCurve( + helpers$1.previousItem(points, i)._model, + model, + helpers$1.nextItem(points, i)._model, + lineModel.tension + ); + model.controlPointPreviousX = controlPoints.previous.x; + model.controlPointPreviousY = controlPoints.previous.y; + model.controlPointNextX = controlPoints.next.x; + model.controlPointNextY = controlPoints.next.y; + } + } + + if (chart.options.elements.line.capBezierPoints) { + for (i = 0, ilen = points.length; i < ilen; ++i) { + model = points[i]._model; + if (isPointInArea(model, area)) { + if (i > 0 && isPointInArea(points[i - 1]._model, area)) { + model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right); + model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom); + } + if (i < points.length - 1 && isPointInArea(points[i + 1]._model, area)) { + model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right); + model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom); + } + } + } + } + }, + + draw: function() { + var me = this; + var chart = me.chart; + var meta = me.getMeta(); + var points = meta.data || []; + var area = chart.chartArea; + var canvas = chart.canvas; + var i = 0; + var ilen = points.length; + var clip; + + if (me._showLine) { + clip = meta.dataset._model.clip; + + helpers$1.canvas.clipArea(chart.ctx, { + left: clip.left === false ? 0 : area.left - clip.left, + right: clip.right === false ? canvas.width : area.right + clip.right, + top: clip.top === false ? 0 : area.top - clip.top, + bottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom + }); + + meta.dataset.draw(); + + helpers$1.canvas.unclipArea(chart.ctx); + } + + // Draw the points + for (; i < ilen; ++i) { + points[i].draw(area); + } + }, + + /** + * @protected + */ + setHoverStyle: function(point) { + var model = point._model; + var options = point._options; + var getHoverColor = helpers$1.getHoverColor; + + point.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + radius: model.radius + }; + + model.backgroundColor = valueOrDefault$6(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$6(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$6(options.hoverBorderWidth, options.borderWidth); + model.radius = valueOrDefault$6(options.hoverRadius, options.radius); + }, + }); + + var resolve$3 = helpers$1.options.resolve; + + core_defaults._set('polarArea', { + scale: { + type: 'radialLinear', + angleLines: { + display: false + }, + gridLines: { + circular: true + }, + pointLabels: { + display: false + }, + ticks: { + beginAtZero: true + } + }, + + // Boolean - Whether to animate the rotation of the chart + animation: { + animateRotate: true, + animateScale: true + }, + + startAngle: -0.5 * Math.PI, + legendCallback: function(chart) { + var list = document.createElement('ul'); + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + var i, ilen, listItem, listItemSpan; + + list.setAttribute('class', chart.id + '-legend'); + if (datasets.length) { + for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) { + listItem = list.appendChild(document.createElement('li')); + listItemSpan = listItem.appendChild(document.createElement('span')); + listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i]; + if (labels[i]) { + listItem.appendChild(document.createTextNode(labels[i])); + } + } + } + + return list.outerHTML; + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var style = meta.controller.getStyle(i); + + return { + text: label, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + lineWidth: style.borderWidth, + hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } + return []; + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + meta.data[index].hidden = !meta.data[index].hidden; + } + + chart.update(); + } + }, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(item, data) { + return data.labels[item.index] + ': ' + item.yLabel; + } + } + } + }); + + var controller_polarArea = core_datasetController.extend({ + + dataElementType: elements.Arc, + + linkScales: helpers$1.noop, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'borderAlign', + 'hoverBackgroundColor', + 'hoverBorderColor', + 'hoverBorderWidth', + ], + + /** + * @private + */ + _getIndexScaleId: function() { + return this.chart.scale.id; + }, + + /** + * @private + */ + _getValueScaleId: function() { + return this.chart.scale.id; + }, + + update: function(reset) { + var me = this; + var dataset = me.getDataset(); + var meta = me.getMeta(); + var start = me.chart.options.startAngle || 0; + var starts = me._starts = []; + var angles = me._angles = []; + var arcs = meta.data; + var i, ilen, angle; + + me._updateRadius(); + + meta.count = me.countVisibleElements(); + + for (i = 0, ilen = dataset.data.length; i < ilen; i++) { + starts[i] = start; + angle = me._computeAngle(i); + angles[i] = angle; + start += angle; + } + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + arcs[i]._options = me._resolveDataElementOptions(arcs[i], i); + me.updateElement(arcs[i], i, reset); + } + }, + + /** + * @private + */ + _updateRadius: function() { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var opts = chart.options; + var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); + + chart.outerRadius = Math.max(minSize / 2, 0); + chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); + + me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index); + me.innerRadius = me.outerRadius - chart.radiusLength; + }, + + updateElement: function(arc, index, reset) { + var me = this; + var chart = me.chart; + var dataset = me.getDataset(); + var opts = chart.options; + var animationOpts = opts.animation; + var scale = chart.scale; + var labels = chart.data.labels; + + var centerX = scale.xCenter; + var centerY = scale.yCenter; + + // var negHalfPI = -0.5 * Math.PI; + var datasetStartAngle = opts.startAngle; + var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); + var startAngle = me._starts[index]; + var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]); + + var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); + var options = arc._options || {}; + + helpers$1.extend(arc, { + // Utility + _datasetIndex: me.index, + _index: index, + _scale: scale, + + // Desired view properties + _model: { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + borderAlign: options.borderAlign, + x: centerX, + y: centerY, + innerRadius: 0, + outerRadius: reset ? resetRadius : distance, + startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle, + endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle, + label: helpers$1.valueAtIndexOrDefault(labels, index, labels[index]) + } + }); + + arc.pivot(); + }, + + countVisibleElements: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var count = 0; + + helpers$1.each(meta.data, function(element, index) { + if (!isNaN(dataset.data[index]) && !element.hidden) { + count++; + } + }); + + return count; + }, + + /** + * @protected + */ + setHoverStyle: function(arc) { + var model = arc._model; + var options = arc._options; + var getHoverColor = helpers$1.getHoverColor; + var valueOrDefault = helpers$1.valueOrDefault; + + arc.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + }; + + model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth); + }, + + /** + * @private + */ + _computeAngle: function(index) { + var me = this; + var count = this.getMeta().count; + var dataset = me.getDataset(); + var meta = me.getMeta(); + + if (isNaN(dataset.data[index]) || meta.data[index].hidden) { + return 0; + } + + // Scriptable options + var context = { + chart: me.chart, + dataIndex: index, + dataset: dataset, + datasetIndex: me.index + }; + + return resolve$3([ + me.chart.options.elements.arc.angle, + (2 * Math.PI) / count + ], context, index); + } + }); + + core_defaults._set('pie', helpers$1.clone(core_defaults.doughnut)); + core_defaults._set('pie', { + cutoutPercentage: 0 + }); + + // Pie charts are Doughnut chart with different defaults + var controller_pie = controller_doughnut; + + var valueOrDefault$7 = helpers$1.valueOrDefault; + + core_defaults._set('radar', { + spanGaps: false, + scale: { + type: 'radialLinear' + }, + elements: { + line: { + fill: 'start', + tension: 0 // no bezier in radar + } + } + }); + + var controller_radar = core_datasetController.extend({ + datasetElementType: elements.Line, + + dataElementType: elements.Point, + + linkScales: helpers$1.noop, + + /** + * @private + */ + _datasetElementOptions: [ + 'backgroundColor', + 'borderWidth', + 'borderColor', + 'borderCapStyle', + 'borderDash', + 'borderDashOffset', + 'borderJoinStyle', + 'fill' + ], + + /** + * @private + */ + _dataElementOptions: { + backgroundColor: 'pointBackgroundColor', + borderColor: 'pointBorderColor', + borderWidth: 'pointBorderWidth', + hitRadius: 'pointHitRadius', + hoverBackgroundColor: 'pointHoverBackgroundColor', + hoverBorderColor: 'pointHoverBorderColor', + hoverBorderWidth: 'pointHoverBorderWidth', + hoverRadius: 'pointHoverRadius', + pointStyle: 'pointStyle', + radius: 'pointRadius', + rotation: 'pointRotation' + }, + + /** + * @private + */ + _getIndexScaleId: function() { + return this.chart.scale.id; + }, + + /** + * @private + */ + _getValueScaleId: function() { + return this.chart.scale.id; + }, + + update: function(reset) { + var me = this; + var meta = me.getMeta(); + var line = meta.dataset; + var points = meta.data || []; + var scale = me.chart.scale; + var config = me._config; + var i, ilen; + + // Compatibility: If the properties are defined with only the old name, use those values + if (config.tension !== undefined && config.lineTension === undefined) { + config.lineTension = config.tension; + } + + // Utility + line._scale = scale; + line._datasetIndex = me.index; + // Data + line._children = points; + line._loop = true; + // Model + line._model = me._resolveDatasetElementOptions(line); + + line.pivot(); + + // Update Points + for (i = 0, ilen = points.length; i < ilen; ++i) { + me.updateElement(points[i], i, reset); + } + + // Update bezier control points + me.updateBezierControlPoints(); + + // Now pivot the point for animation + for (i = 0, ilen = points.length; i < ilen; ++i) { + points[i].pivot(); + } + }, + + updateElement: function(point, index, reset) { + var me = this; + var custom = point.custom || {}; + var dataset = me.getDataset(); + var scale = me.chart.scale; + var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); + var options = me._resolveDataElementOptions(point, index); + var lineModel = me.getMeta().dataset._model; + var x = reset ? scale.xCenter : pointPosition.x; + var y = reset ? scale.yCenter : pointPosition.y; + + // Utility + point._scale = scale; + point._options = options; + point._datasetIndex = me.index; + point._index = index; + + // Desired view properties + point._model = { + x: x, // value not used in dataset scale, but we want a consistent API between scales + y: y, + skip: custom.skip || isNaN(x) || isNaN(y), + // Appearance + radius: options.radius, + pointStyle: options.pointStyle, + rotation: options.rotation, + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + tension: valueOrDefault$7(custom.tension, lineModel ? lineModel.tension : 0), + + // Tooltip + hitRadius: options.hitRadius + }; + }, + + /** + * @private + */ + _resolveDatasetElementOptions: function() { + var me = this; + var config = me._config; + var options = me.chart.options; + var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments); + + values.spanGaps = valueOrDefault$7(config.spanGaps, options.spanGaps); + values.tension = valueOrDefault$7(config.lineTension, options.elements.line.tension); + + return values; + }, + + updateBezierControlPoints: function() { + var me = this; + var meta = me.getMeta(); + var area = me.chart.chartArea; + var points = meta.data || []; + var i, ilen, model, controlPoints; + + // Only consider points that are drawn in case the spanGaps option is used + if (meta.dataset._model.spanGaps) { + points = points.filter(function(pt) { + return !pt._model.skip; + }); + } + + function capControlPoint(pt, min, max) { + return Math.max(Math.min(pt, max), min); + } + + for (i = 0, ilen = points.length; i < ilen; ++i) { + model = points[i]._model; + controlPoints = helpers$1.splineCurve( + helpers$1.previousItem(points, i, true)._model, + model, + helpers$1.nextItem(points, i, true)._model, + model.tension + ); + + // Prevent the bezier going outside of the bounds of the graph + model.controlPointPreviousX = capControlPoint(controlPoints.previous.x, area.left, area.right); + model.controlPointPreviousY = capControlPoint(controlPoints.previous.y, area.top, area.bottom); + model.controlPointNextX = capControlPoint(controlPoints.next.x, area.left, area.right); + model.controlPointNextY = capControlPoint(controlPoints.next.y, area.top, area.bottom); + } + }, + + setHoverStyle: function(point) { + var model = point._model; + var options = point._options; + var getHoverColor = helpers$1.getHoverColor; + + point.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + radius: model.radius + }; + + model.backgroundColor = valueOrDefault$7(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$7(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$7(options.hoverBorderWidth, options.borderWidth); + model.radius = valueOrDefault$7(options.hoverRadius, options.radius); + } + }); + + core_defaults._set('scatter', { + hover: { + mode: 'single' + }, + + scales: { + xAxes: [{ + id: 'x-axis-1', // need an ID so datasets can reference the scale + type: 'linear', // scatter should not use a category axis + position: 'bottom' + }], + yAxes: [{ + id: 'y-axis-1', + type: 'linear', + position: 'left' + }] + }, + + tooltips: { + callbacks: { + title: function() { + return ''; // doesn't make sense for scatter since data are formatted as a point + }, + label: function(item) { + return '(' + item.xLabel + ', ' + item.yLabel + ')'; + } + } + } + }); + + core_defaults._set('global', { + datasets: { + scatter: { + showLine: false + } + } + }); + + // Scatter charts use line controllers + var controller_scatter = controller_line; + + // NOTE export a map in which the key represents the controller type, not + // the class, and so must be CamelCase in order to be correctly retrieved + // by the controller in core.controller.js (`controllers[meta.type]`). + + var controllers = { + bar: controller_bar, + bubble: controller_bubble, + doughnut: controller_doughnut, + horizontalBar: controller_horizontalBar, + line: controller_line, + polarArea: controller_polarArea, + pie: controller_pie, + radar: controller_radar, + scatter: controller_scatter + }; + + /** + * Helper function to get relative position for an event + * @param {Event|IEvent} event - The event to get the position for + * @param {Chart} chart - The chart + * @returns {object} the event position + */ + function getRelativePosition(e, chart) { + if (e.native) { + return { + x: e.x, + y: e.y + }; + } + + return helpers$1.getRelativePosition(e, chart); + } + + /** + * Helper function to traverse all of the visible elements in the chart + * @param {Chart} chart - the chart + * @param {function} handler - the callback to execute for each visible item + */ + function parseVisibleItems(chart, handler) { + var metasets = chart._getSortedVisibleDatasetMetas(); + var metadata, i, j, ilen, jlen, element; + + for (i = 0, ilen = metasets.length; i < ilen; ++i) { + metadata = metasets[i].data; + for (j = 0, jlen = metadata.length; j < jlen; ++j) { + element = metadata[j]; + if (!element._view.skip) { + handler(element); + } + } + } + } + + /** + * Helper function to get the items that intersect the event position + * @param {ChartElement[]} items - elements to filter + * @param {object} position - the point to be nearest to + * @return {ChartElement[]} the nearest items + */ + function getIntersectItems(chart, position) { + var elements = []; + + parseVisibleItems(chart, function(element) { + if (element.inRange(position.x, position.y)) { + elements.push(element); + } + }); + + return elements; + } + + /** + * Helper function to get the items nearest to the event position considering all visible items in teh chart + * @param {Chart} chart - the chart to look at elements from + * @param {object} position - the point to be nearest to + * @param {boolean} intersect - if true, only consider items that intersect the position + * @param {function} distanceMetric - function to provide the distance between points + * @return {ChartElement[]} the nearest items + */ + function getNearestItems(chart, position, intersect, distanceMetric) { + var minDistance = Number.POSITIVE_INFINITY; + var nearestItems = []; + + parseVisibleItems(chart, function(element) { + if (intersect && !element.inRange(position.x, position.y)) { + return; + } + + var center = element.getCenterPoint(); + var distance = distanceMetric(position, center); + if (distance < minDistance) { + nearestItems = [element]; + minDistance = distance; + } else if (distance === minDistance) { + // Can have multiple items at the same distance in which case we sort by size + nearestItems.push(element); + } + }); + + return nearestItems; + } + + /** + * Get a distance metric function for two points based on the + * axis mode setting + * @param {string} axis - the axis mode. x|y|xy + */ + function getDistanceMetricForAxis(axis) { + var useX = axis.indexOf('x') !== -1; + var useY = axis.indexOf('y') !== -1; + + return function(pt1, pt2) { + var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; + var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; + return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); + }; + } + + function indexMode(chart, e, options) { + var position = getRelativePosition(e, chart); + // Default axis for index mode is 'x' to match old behaviour + options.axis = options.axis || 'x'; + var distanceMetric = getDistanceMetricForAxis(options.axis); + var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); + var elements = []; + + if (!items.length) { + return []; + } + + chart._getSortedVisibleDatasetMetas().forEach(function(meta) { + var element = meta.data[items[0]._index]; + + // don't count items that are skipped (null data) + if (element && !element._view.skip) { + elements.push(element); + } + }); + + return elements; + } + + /** + * @interface IInteractionOptions + */ + /** + * If true, only consider items that intersect the point + * @name IInterfaceOptions#boolean + * @type Boolean + */ + + /** + * Contains interaction related functions + * @namespace Chart.Interaction + */ + var core_interaction = { + // Helper function for different modes + modes: { + single: function(chart, e) { + var position = getRelativePosition(e, chart); + var elements = []; + + parseVisibleItems(chart, function(element) { + if (element.inRange(position.x, position.y)) { + elements.push(element); + return elements; + } + }); + + return elements.slice(0, 1); + }, + + /** + * @function Chart.Interaction.modes.label + * @deprecated since version 2.4.0 + * @todo remove at version 3 + * @private + */ + label: indexMode, + + /** + * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something + * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item + * @function Chart.Interaction.modes.index + * @since v2.4.0 + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use during interaction + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + index: indexMode, + + /** + * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something + * If the options.intersect is false, we find the nearest item and return the items in that dataset + * @function Chart.Interaction.modes.dataset + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use during interaction + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + dataset: function(chart, e, options) { + var position = getRelativePosition(e, chart); + options.axis = options.axis || 'xy'; + var distanceMetric = getDistanceMetricForAxis(options.axis); + var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); + + if (items.length > 0) { + items = chart.getDatasetMeta(items[0]._datasetIndex).data; + } + + return items; + }, + + /** + * @function Chart.Interaction.modes.x-axis + * @deprecated since version 2.4.0. Use index mode and intersect == true + * @todo remove at version 3 + * @private + */ + 'x-axis': function(chart, e) { + return indexMode(chart, e, {intersect: false}); + }, + + /** + * Point mode returns all elements that hit test based on the event position + * of the event + * @function Chart.Interaction.modes.intersect + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + point: function(chart, e) { + var position = getRelativePosition(e, chart); + return getIntersectItems(chart, position); + }, + + /** + * nearest mode returns the element closest to the point + * @function Chart.Interaction.modes.intersect + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + nearest: function(chart, e, options) { + var position = getRelativePosition(e, chart); + options.axis = options.axis || 'xy'; + var distanceMetric = getDistanceMetricForAxis(options.axis); + return getNearestItems(chart, position, options.intersect, distanceMetric); + }, + + /** + * x mode returns the elements that hit-test at the current x coordinate + * @function Chart.Interaction.modes.x + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + x: function(chart, e, options) { + var position = getRelativePosition(e, chart); + var items = []; + var intersectsItem = false; + + parseVisibleItems(chart, function(element) { + if (element.inXRange(position.x)) { + items.push(element); + } + + if (element.inRange(position.x, position.y)) { + intersectsItem = true; + } + }); + + // If we want to trigger on an intersect and we don't have any items + // that intersect the position, return nothing + if (options.intersect && !intersectsItem) { + items = []; + } + return items; + }, + + /** + * y mode returns the elements that hit-test at the current y coordinate + * @function Chart.Interaction.modes.y + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + y: function(chart, e, options) { + var position = getRelativePosition(e, chart); + var items = []; + var intersectsItem = false; + + parseVisibleItems(chart, function(element) { + if (element.inYRange(position.y)) { + items.push(element); + } + + if (element.inRange(position.x, position.y)) { + intersectsItem = true; + } + }); + + // If we want to trigger on an intersect and we don't have any items + // that intersect the position, return nothing + if (options.intersect && !intersectsItem) { + items = []; + } + return items; + } + } + }; + + var extend = helpers$1.extend; + + function filterByPosition(array, position) { + return helpers$1.where(array, function(v) { + return v.pos === position; + }); + } + + function sortByWeight(array, reverse) { + return array.sort(function(a, b) { + var v0 = reverse ? b : a; + var v1 = reverse ? a : b; + return v0.weight === v1.weight ? + v0.index - v1.index : + v0.weight - v1.weight; + }); + } + + function wrapBoxes(boxes) { + var layoutBoxes = []; + var i, ilen, box; + + for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) { + box = boxes[i]; + layoutBoxes.push({ + index: i, + box: box, + pos: box.position, + horizontal: box.isHorizontal(), + weight: box.weight + }); + } + return layoutBoxes; + } + + function setLayoutDims(layouts, params) { + var i, ilen, layout; + for (i = 0, ilen = layouts.length; i < ilen; ++i) { + layout = layouts[i]; + // store width used instead of chartArea.w in fitBoxes + layout.width = layout.horizontal + ? layout.box.fullWidth && params.availableWidth + : params.vBoxMaxWidth; + // store height used instead of chartArea.h in fitBoxes + layout.height = layout.horizontal && params.hBoxMaxHeight; + } + } + + function buildLayoutBoxes(boxes) { + var layoutBoxes = wrapBoxes(boxes); + var left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true); + var right = sortByWeight(filterByPosition(layoutBoxes, 'right')); + var top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true); + var bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom')); + + return { + leftAndTop: left.concat(top), + rightAndBottom: right.concat(bottom), + chartArea: filterByPosition(layoutBoxes, 'chartArea'), + vertical: left.concat(right), + horizontal: top.concat(bottom) + }; + } + + function getCombinedMax(maxPadding, chartArea, a, b) { + return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]); + } + + function updateDims(chartArea, params, layout) { + var box = layout.box; + var maxPadding = chartArea.maxPadding; + var newWidth, newHeight; + + if (layout.size) { + // this layout was already counted for, lets first reduce old size + chartArea[layout.pos] -= layout.size; + } + layout.size = layout.horizontal ? box.height : box.width; + chartArea[layout.pos] += layout.size; + + if (box.getPadding) { + var boxPadding = box.getPadding(); + maxPadding.top = Math.max(maxPadding.top, boxPadding.top); + maxPadding.left = Math.max(maxPadding.left, boxPadding.left); + maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom); + maxPadding.right = Math.max(maxPadding.right, boxPadding.right); + } + + newWidth = params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'); + newHeight = params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'); + + if (newWidth !== chartArea.w || newHeight !== chartArea.h) { + chartArea.w = newWidth; + chartArea.h = newHeight; + + // return true if chart area changed in layout's direction + return layout.horizontal ? newWidth !== chartArea.w : newHeight !== chartArea.h; + } + } + + function handleMaxPadding(chartArea) { + var maxPadding = chartArea.maxPadding; + + function updatePos(pos) { + var change = Math.max(maxPadding[pos] - chartArea[pos], 0); + chartArea[pos] += change; + return change; + } + chartArea.y += updatePos('top'); + chartArea.x += updatePos('left'); + updatePos('right'); + updatePos('bottom'); + } + + function getMargins(horizontal, chartArea) { + var maxPadding = chartArea.maxPadding; + + function marginForPositions(positions) { + var margin = {left: 0, top: 0, right: 0, bottom: 0}; + positions.forEach(function(pos) { + margin[pos] = Math.max(chartArea[pos], maxPadding[pos]); + }); + return margin; + } + + return horizontal + ? marginForPositions(['left', 'right']) + : marginForPositions(['top', 'bottom']); + } + + function fitBoxes(boxes, chartArea, params) { + var refitBoxes = []; + var i, ilen, layout, box, refit, changed; + + for (i = 0, ilen = boxes.length; i < ilen; ++i) { + layout = boxes[i]; + box = layout.box; + + box.update( + layout.width || chartArea.w, + layout.height || chartArea.h, + getMargins(layout.horizontal, chartArea) + ); + if (updateDims(chartArea, params, layout)) { + changed = true; + if (refitBoxes.length) { + // Dimensions changed and there were non full width boxes before this + // -> we have to refit those + refit = true; + } + } + if (!box.fullWidth) { // fullWidth boxes don't need to be re-fitted in any case + refitBoxes.push(layout); + } + } + + return refit ? fitBoxes(refitBoxes, chartArea, params) || changed : changed; + } + + function placeBoxes(boxes, chartArea, params) { + var userPadding = params.padding; + var x = chartArea.x; + var y = chartArea.y; + var i, ilen, layout, box; + + for (i = 0, ilen = boxes.length; i < ilen; ++i) { + layout = boxes[i]; + box = layout.box; + if (layout.horizontal) { + box.left = box.fullWidth ? userPadding.left : chartArea.left; + box.right = box.fullWidth ? params.outerWidth - userPadding.right : chartArea.left + chartArea.w; + box.top = y; + box.bottom = y + box.height; + box.width = box.right - box.left; + y = box.bottom; + } else { + box.left = x; + box.right = x + box.width; + box.top = chartArea.top; + box.bottom = chartArea.top + chartArea.h; + box.height = box.bottom - box.top; + x = box.right; + } + } + + chartArea.x = x; + chartArea.y = y; + } + + core_defaults._set('global', { + layout: { + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + } + } + }); + + /** + * @interface ILayoutItem + * @prop {string} position - The position of the item in the chart layout. Possible values are + * 'left', 'top', 'right', 'bottom', and 'chartArea' + * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area + * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down + * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom) + * @prop {function} update - Takes two parameters: width and height. Returns size of item + * @prop {function} getPadding - Returns an object with padding on the edges + * @prop {number} width - Width of item. Must be valid after update() + * @prop {number} height - Height of item. Must be valid after update() + * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update + * @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update + * @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update + * @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update + */ + + // The layout service is very self explanatory. It's responsible for the layout within a chart. + // Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need + // It is this service's responsibility of carrying out that layout. + var core_layouts = { + defaults: {}, + + /** + * Register a box to a chart. + * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title. + * @param {Chart} chart - the chart to use + * @param {ILayoutItem} item - the item to add to be layed out + */ + addBox: function(chart, item) { + if (!chart.boxes) { + chart.boxes = []; + } + + // initialize item with default values + item.fullWidth = item.fullWidth || false; + item.position = item.position || 'top'; + item.weight = item.weight || 0; + item._layers = item._layers || function() { + return [{ + z: 0, + draw: function() { + item.draw.apply(item, arguments); + } + }]; + }; + + chart.boxes.push(item); + }, + + /** + * Remove a layoutItem from a chart + * @param {Chart} chart - the chart to remove the box from + * @param {ILayoutItem} layoutItem - the item to remove from the layout + */ + removeBox: function(chart, layoutItem) { + var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; + if (index !== -1) { + chart.boxes.splice(index, 1); + } + }, + + /** + * Sets (or updates) options on the given `item`. + * @param {Chart} chart - the chart in which the item lives (or will be added to) + * @param {ILayoutItem} item - the item to configure with the given options + * @param {object} options - the new item options. + */ + configure: function(chart, item, options) { + var props = ['fullWidth', 'position', 'weight']; + var ilen = props.length; + var i = 0; + var prop; + + for (; i < ilen; ++i) { + prop = props[i]; + if (options.hasOwnProperty(prop)) { + item[prop] = options[prop]; + } + } + }, + + /** + * Fits boxes of the given chart into the given size by having each box measure itself + * then running a fitting algorithm + * @param {Chart} chart - the chart + * @param {number} width - the width to fit into + * @param {number} height - the height to fit into + */ + update: function(chart, width, height) { + if (!chart) { + return; + } + + var layoutOptions = chart.options.layout || {}; + var padding = helpers$1.options.toPadding(layoutOptions.padding); + + var availableWidth = width - padding.width; + var availableHeight = height - padding.height; + var boxes = buildLayoutBoxes(chart.boxes); + var verticalBoxes = boxes.vertical; + var horizontalBoxes = boxes.horizontal; + + // 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) | + // |----------------------------------------------------| + // + + var params = Object.freeze({ + outerWidth: width, + outerHeight: height, + padding: padding, + availableWidth: availableWidth, + vBoxMaxWidth: availableWidth / 2 / verticalBoxes.length, + hBoxMaxHeight: availableHeight / 2 + }); + var chartArea = extend({ + maxPadding: extend({}, padding), + w: availableWidth, + h: availableHeight, + x: padding.left, + y: padding.top + }, padding); + + setLayoutDims(verticalBoxes.concat(horizontalBoxes), params); + + // First fit vertical boxes + fitBoxes(verticalBoxes, chartArea, params); + + // Then fit horizontal boxes + if (fitBoxes(horizontalBoxes, chartArea, params)) { + // if the area changed, re-fit vertical boxes + fitBoxes(verticalBoxes, chartArea, params); + } + + handleMaxPadding(chartArea); + + // Finally place the boxes to correct coordinates + placeBoxes(boxes.leftAndTop, chartArea, params); + + // Move to opposite side of chart + chartArea.x += chartArea.w; + chartArea.y += chartArea.h; + + placeBoxes(boxes.rightAndBottom, chartArea, params); + + chart.chartArea = { + left: chartArea.left, + top: chartArea.top, + right: chartArea.left + chartArea.w, + bottom: chartArea.top + chartArea.h + }; + + // Finally update boxes in chartArea (radial scale for example) + helpers$1.each(boxes.chartArea, function(layout) { + var box = layout.box; + extend(box, chart.chartArea); + box.update(chartArea.w, chartArea.h); + }); + } + }; + + /** + * Platform fallback implementation (minimal). + * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939 + */ + + var platform_basic = { + acquireContext: function(item) { + if (item && item.canvas) { + // Support for any object associated to a canvas (including a context2d) + item = item.canvas; + } + + return item && item.getContext('2d') || null; + } + }; + + var platform_dom = "/*\n * DOM element rendering detection\n * https://davidwalsh.name/detect-node-insertion\n */\n@keyframes chartjs-render-animation {\n\tfrom { opacity: 0.99; }\n\tto { opacity: 1; }\n}\n\n.chartjs-render-monitor {\n\tanimation: chartjs-render-animation 0.001s;\n}\n\n/*\n * DOM element resizing detection\n * https://github.com/marcj/css-element-queries\n */\n.chartjs-size-monitor,\n.chartjs-size-monitor-expand,\n.chartjs-size-monitor-shrink {\n\tposition: absolute;\n\tdirection: ltr;\n\tleft: 0;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\toverflow: hidden;\n\tpointer-events: none;\n\tvisibility: hidden;\n\tz-index: -1;\n}\n\n.chartjs-size-monitor-expand > div {\n\tposition: absolute;\n\twidth: 1000000px;\n\theight: 1000000px;\n\tleft: 0;\n\ttop: 0;\n}\n\n.chartjs-size-monitor-shrink > div {\n\tposition: absolute;\n\twidth: 200%;\n\theight: 200%;\n\tleft: 0;\n\ttop: 0;\n}\n"; + + var platform_dom$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + 'default': platform_dom + }); + + var stylesheet = getCjsExportFromNamespace(platform_dom$1); + + var EXPANDO_KEY = '$chartjs'; + var CSS_PREFIX = 'chartjs-'; + var CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor'; + var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor'; + var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation'; + var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart']; + + /** + * DOM event types -> Chart.js event types. + * Note: only events with different types are mapped. + * @see https://developer.mozilla.org/en-US/docs/Web/Events + */ + var EVENT_TYPES = { + touchstart: 'mousedown', + touchmove: 'mousemove', + touchend: 'mouseup', + pointerenter: 'mouseenter', + pointerdown: 'mousedown', + pointermove: 'mousemove', + pointerup: 'mouseup', + pointerleave: 'mouseout', + pointerout: 'mouseout' + }; + + /** + * The "used" size is the final value of a dimension property after all calculations have + * been performed. This method uses the computed style of `element` but returns undefined + * if the computed style is not expressed in pixels. That can happen in some cases where + * `element` has a size relative to its parent and this last one is not yet displayed, + * for example because of `display: none` on a parent node. + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value + * @returns {number} Size in pixels or undefined if unknown. + */ + function readUsedSize(element, property) { + var value = helpers$1.getStyle(element, property); + var matches = value && value.match(/^(\d+)(\.\d+)?px$/); + return matches ? Number(matches[1]) : undefined; + } + + /** + * Initializes the canvas style and render size without modifying the canvas display size, + * since responsiveness is handled by the controller.resize() method. The config is used + * to determine the aspect ratio to apply in case no explicit height has been specified. + */ + function initCanvas(canvas, config) { + var style = canvas.style; + + // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it + // returns null or '' if no explicit value has been set to the canvas attribute. + var renderHeight = canvas.getAttribute('height'); + var renderWidth = canvas.getAttribute('width'); + + // Chart.js modifies some canvas values that we want to restore on destroy + canvas[EXPANDO_KEY] = { + initial: { + height: renderHeight, + width: renderWidth, + style: { + display: style.display, + height: style.height, + width: style.width + } + } + }; + + // Force canvas to display as block to avoid extra space caused by inline + // elements, which would interfere with the responsive resize process. + // https://github.com/chartjs/Chart.js/issues/2538 + style.display = style.display || 'block'; + + if (renderWidth === null || renderWidth === '') { + var displayWidth = readUsedSize(canvas, 'width'); + if (displayWidth !== undefined) { + canvas.width = displayWidth; + } + } + + if (renderHeight === null || renderHeight === '') { + if (canvas.style.height === '') { + // If no explicit render height and style height, let's apply the aspect ratio, + // which one can be specified by the user but also by charts as default option + // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2. + canvas.height = canvas.width / (config.options.aspectRatio || 2); + } else { + var displayHeight = readUsedSize(canvas, 'height'); + if (displayWidth !== undefined) { + canvas.height = displayHeight; + } + } + } + + return canvas; + } + + /** + * Detects support for options object argument in addEventListener. + * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support + * @private + */ + var supportsEventListenerOptions = (function() { + var supports = false; + try { + var options = Object.defineProperty({}, 'passive', { + // eslint-disable-next-line getter-return + get: function() { + supports = true; + } + }); + window.addEventListener('e', null, options); + } catch (e) { + // continue regardless of error + } + return supports; + }()); + + // Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events. + // https://github.com/chartjs/Chart.js/issues/4287 + var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false; + + function addListener(node, type, listener) { + node.addEventListener(type, listener, eventListenerOptions); + } + + function removeListener(node, type, listener) { + node.removeEventListener(type, listener, eventListenerOptions); + } + + function createEvent(type, chart, x, y, nativeEvent) { + return { + type: type, + chart: chart, + native: nativeEvent || null, + x: x !== undefined ? x : null, + y: y !== undefined ? y : null, + }; + } + + function fromNativeEvent(event, chart) { + var type = EVENT_TYPES[event.type] || event.type; + var pos = helpers$1.getRelativePosition(event, chart); + return createEvent(type, chart, pos.x, pos.y, event); + } + + function throttled(fn, thisArg) { + var ticking = false; + var args = []; + + return function() { + args = Array.prototype.slice.call(arguments); + thisArg = thisArg || this; + + if (!ticking) { + ticking = true; + helpers$1.requestAnimFrame.call(window, function() { + ticking = false; + fn.apply(thisArg, args); + }); + } + }; + } + + function createDiv(cls) { + var el = document.createElement('div'); + el.className = cls || ''; + return el; + } + + // Implementation based on https://github.com/marcj/css-element-queries + function createResizer(handler) { + var maxSize = 1000000; + + // NOTE(SB) Don't use innerHTML because it could be considered unsafe. + // https://github.com/chartjs/Chart.js/issues/5902 + var resizer = createDiv(CSS_SIZE_MONITOR); + var expand = createDiv(CSS_SIZE_MONITOR + '-expand'); + var shrink = createDiv(CSS_SIZE_MONITOR + '-shrink'); + + expand.appendChild(createDiv()); + shrink.appendChild(createDiv()); + + resizer.appendChild(expand); + resizer.appendChild(shrink); + resizer._reset = function() { + expand.scrollLeft = maxSize; + expand.scrollTop = maxSize; + shrink.scrollLeft = maxSize; + shrink.scrollTop = maxSize; + }; + + var onScroll = function() { + resizer._reset(); + handler(); + }; + + addListener(expand, 'scroll', onScroll.bind(expand, 'expand')); + addListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink')); + + return resizer; + } + + // https://davidwalsh.name/detect-node-insertion + function watchForRender(node, handler) { + var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); + var proxy = expando.renderProxy = function(e) { + if (e.animationName === CSS_RENDER_ANIMATION) { + handler(); + } + }; + + helpers$1.each(ANIMATION_START_EVENTS, function(type) { + addListener(node, type, proxy); + }); + + // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class + // is removed then added back immediately (same animation frame?). Accessing the + // `offsetParent` property will force a reflow and re-evaluate the CSS animation. + // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics + // https://github.com/chartjs/Chart.js/issues/4737 + expando.reflow = !!node.offsetParent; + + node.classList.add(CSS_RENDER_MONITOR); + } + + function unwatchForRender(node) { + var expando = node[EXPANDO_KEY] || {}; + var proxy = expando.renderProxy; + + if (proxy) { + helpers$1.each(ANIMATION_START_EVENTS, function(type) { + removeListener(node, type, proxy); + }); + + delete expando.renderProxy; + } + + node.classList.remove(CSS_RENDER_MONITOR); + } + + function addResizeListener(node, listener, chart) { + var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); + + // Let's keep track of this added resizer and thus avoid DOM query when removing it. + var resizer = expando.resizer = createResizer(throttled(function() { + if (expando.resizer) { + var container = chart.options.maintainAspectRatio && node.parentNode; + var w = container ? container.clientWidth : 0; + listener(createEvent('resize', chart)); + if (container && container.clientWidth < w && chart.canvas) { + // If the container size shrank during chart resize, let's assume + // scrollbar appeared. So we resize again with the scrollbar visible - + // effectively making chart smaller and the scrollbar hidden again. + // Because we are inside `throttled`, and currently `ticking`, scroll + // events are ignored during this whole 2 resize process. + // If we assumed wrong and something else happened, we are resizing + // twice in a frame (potential performance issue) + listener(createEvent('resize', chart)); + } + } + })); + + // The resizer needs to be attached to the node parent, so we first need to be + // sure that `node` is attached to the DOM before injecting the resizer element. + watchForRender(node, function() { + if (expando.resizer) { + var container = node.parentNode; + if (container && container !== resizer.parentNode) { + container.insertBefore(resizer, container.firstChild); + } + + // The container size might have changed, let's reset the resizer state. + resizer._reset(); + } + }); + } + + function removeResizeListener(node) { + var expando = node[EXPANDO_KEY] || {}; + var resizer = expando.resizer; + + delete expando.resizer; + unwatchForRender(node); + + if (resizer && resizer.parentNode) { + resizer.parentNode.removeChild(resizer); + } + } + + /** + * Injects CSS styles inline if the styles are not already present. + * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the