You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
605 lines
561 KiB
605 lines
561 KiB
define(["angular","app/core/config","app/core/core","app/core/core_module","app/core/time_series2","app/core/utils/kbn","app/core/utils/ticks","app/plugins/sdk","jquery","lodash","moment"], function(__WEBPACK_EXTERNAL_MODULE_angular__, __WEBPACK_EXTERNAL_MODULE_grafana_app_core_config__, __WEBPACK_EXTERNAL_MODULE_grafana_app_core_core__, __WEBPACK_EXTERNAL_MODULE_grafana_app_core_core_module__, __WEBPACK_EXTERNAL_MODULE_grafana_app_core_time_series2__, __WEBPACK_EXTERNAL_MODULE_grafana_app_core_utils_kbn__, __WEBPACK_EXTERNAL_MODULE_grafana_app_core_utils_ticks__, __WEBPACK_EXTERNAL_MODULE_grafana_app_plugins_sdk__, __WEBPACK_EXTERNAL_MODULE_jquery__, __WEBPACK_EXTERNAL_MODULE_lodash__, __WEBPACK_EXTERNAL_MODULE_moment__) { return /******/ (function(modules) { // webpackBootstrap |
|
/******/ // The module cache |
|
/******/ var installedModules = {}; |
|
/******/ |
|
/******/ // object to store loaded and loading wasm modules |
|
/******/ var installedWasmModules = {}; |
|
/******/ |
|
/******/ // The require function |
|
/******/ function __webpack_require__(moduleId) { |
|
/******/ |
|
/******/ // Check if module is in cache |
|
/******/ if(installedModules[moduleId]) { |
|
/******/ return installedModules[moduleId].exports; |
|
/******/ } |
|
/******/ // Create a new module (and put it into the cache) |
|
/******/ var module = installedModules[moduleId] = { |
|
/******/ i: moduleId, |
|
/******/ l: false, |
|
/******/ exports: {} |
|
/******/ }; |
|
/******/ |
|
/******/ // Execute the module function |
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); |
|
/******/ |
|
/******/ // Flag the module as loaded |
|
/******/ module.l = true; |
|
/******/ |
|
/******/ // Return the exports of the module |
|
/******/ return module.exports; |
|
/******/ } |
|
/******/ |
|
/******/ |
|
/******/ // expose the modules object (__webpack_modules__) |
|
/******/ __webpack_require__.m = modules; |
|
/******/ |
|
/******/ // expose the module cache |
|
/******/ __webpack_require__.c = installedModules; |
|
/******/ |
|
/******/ // define getter function for harmony exports |
|
/******/ __webpack_require__.d = function(exports, name, getter) { |
|
/******/ if(!__webpack_require__.o(exports, name)) { |
|
/******/ Object.defineProperty(exports, name, { |
|
/******/ configurable: false, |
|
/******/ enumerable: true, |
|
/******/ get: getter |
|
/******/ }); |
|
/******/ } |
|
/******/ }; |
|
/******/ |
|
/******/ // define __esModule on exports |
|
/******/ __webpack_require__.r = function(exports) { |
|
/******/ Object.defineProperty(exports, '__esModule', { value: true }); |
|
/******/ }; |
|
/******/ |
|
/******/ // getDefaultExport function for compatibility with non-harmony modules |
|
/******/ __webpack_require__.n = function(module) { |
|
/******/ var getter = module && module.__esModule ? |
|
/******/ function getDefault() { return module['default']; } : |
|
/******/ function getModuleExports() { return module; }; |
|
/******/ __webpack_require__.d(getter, 'a', getter); |
|
/******/ return getter; |
|
/******/ }; |
|
/******/ |
|
/******/ // Object.prototype.hasOwnProperty.call |
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; |
|
/******/ |
|
/******/ // __webpack_public_path__ |
|
/******/ __webpack_require__.p = ""; |
|
/******/ |
|
/******/ // object with all compiled WebAssembly.Modules |
|
/******/ __webpack_require__.w = {}; |
|
/******/ |
|
/******/ |
|
/******/ // Load entry module and return exports |
|
/******/ return __webpack_require__(__webpack_require__.s = "./module.ts"); |
|
/******/ }) |
|
/************************************************************************/ |
|
/******/ ({ |
|
|
|
/***/ "../node_modules/charenc/charenc.js": |
|
/*!******************************************!*\ |
|
!*** ../node_modules/charenc/charenc.js ***! |
|
\******************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("var charenc = {\n // UTF-8 encoding\n utf8: {\n // Convert a string to a byte array\n stringToBytes: function(str) {\n return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));\n },\n\n // Convert a byte array to a string\n bytesToString: function(bytes) {\n return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));\n }\n },\n\n // Binary encoding\n bin: {\n // Convert a string to a byte array\n stringToBytes: function(str) {\n for (var bytes = [], i = 0; i < str.length; i++)\n bytes.push(str.charCodeAt(i) & 0xFF);\n return bytes;\n },\n\n // Convert a byte array to a string\n bytesToString: function(bytes) {\n for (var str = [], i = 0; i < bytes.length; i++)\n str.push(String.fromCharCode(bytes[i]));\n return str.join('');\n }\n }\n};\n\nmodule.exports = charenc;\n\n\n//# sourceURL=webpack:///../node_modules/charenc/charenc.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "../node_modules/crypt/crypt.js": |
|
/*!**************************************!*\ |
|
!*** ../node_modules/crypt/crypt.js ***! |
|
\**************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("(function() {\n var base64map\n = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n\n crypt = {\n // Bit-wise rotation left\n rotl: function(n, b) {\n return (n << b) | (n >>> (32 - b));\n },\n\n // Bit-wise rotation right\n rotr: function(n, b) {\n return (n << (32 - b)) | (n >>> b);\n },\n\n // Swap big-endian to little-endian and vice versa\n endian: function(n) {\n // If number given, swap endian\n if (n.constructor == Number) {\n return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;\n }\n\n // Else, assume array and swap all items\n for (var i = 0; i < n.length; i++)\n n[i] = crypt.endian(n[i]);\n return n;\n },\n\n // Generate an array of any length of random bytes\n randomBytes: function(n) {\n for (var bytes = []; n > 0; n--)\n bytes.push(Math.floor(Math.random() * 256));\n return bytes;\n },\n\n // Convert a byte array to big-endian 32-bit words\n bytesToWords: function(bytes) {\n for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)\n words[b >>> 5] |= bytes[i] << (24 - b % 32);\n return words;\n },\n\n // Convert big-endian 32-bit words to a byte array\n wordsToBytes: function(words) {\n for (var bytes = [], b = 0; b < words.length * 32; b += 8)\n bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);\n return bytes;\n },\n\n // Convert a byte array to a hex string\n bytesToHex: function(bytes) {\n for (var hex = [], i = 0; i < bytes.length; i++) {\n hex.push((bytes[i] >>> 4).toString(16));\n hex.push((bytes[i] & 0xF).toString(16));\n }\n return hex.join('');\n },\n\n // Convert a hex string to a byte array\n hexToBytes: function(hex) {\n for (var bytes = [], c = 0; c < hex.length; c += 2)\n bytes.push(parseInt(hex.substr(c, 2), 16));\n return bytes;\n },\n\n // Convert a byte array to a base-64 string\n bytesToBase64: function(bytes) {\n for (var base64 = [], i = 0; i < bytes.length; i += 3) {\n var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];\n for (var j = 0; j < 4; j++)\n if (i * 8 + j * 6 <= bytes.length * 8)\n base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));\n else\n base64.push('=');\n }\n return base64.join('');\n },\n\n // Convert a base-64 string to a byte array\n base64ToBytes: function(base64) {\n // Remove non-base-64 characters\n base64 = base64.replace(/[^A-Z0-9+\\/]/ig, '');\n\n for (var bytes = [], i = 0, imod4 = 0; i < base64.length;\n imod4 = ++i % 4) {\n if (imod4 == 0) continue;\n bytes.push(((base64map.indexOf(base64.charAt(i - 1))\n & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))\n | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));\n }\n return bytes;\n }\n };\n\n module.exports = crypt;\n})();\n\n\n//# sourceURL=webpack:///../node_modules/crypt/crypt.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "../node_modules/is-buffer/index.js": |
|
/*!******************************************!*\ |
|
!*** ../node_modules/is-buffer/index.js ***! |
|
\******************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("/*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh <https://feross.org>\n * @license MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n\n//# sourceURL=webpack:///../node_modules/is-buffer/index.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "../node_modules/md5/md5.js": |
|
/*!**********************************!*\ |
|
!*** ../node_modules/md5/md5.js ***! |
|
\**********************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
eval("(function(){\r\n var crypt = __webpack_require__(/*! crypt */ \"../node_modules/crypt/crypt.js\"),\r\n utf8 = __webpack_require__(/*! charenc */ \"../node_modules/charenc/charenc.js\").utf8,\r\n isBuffer = __webpack_require__(/*! is-buffer */ \"../node_modules/is-buffer/index.js\"),\r\n bin = __webpack_require__(/*! charenc */ \"../node_modules/charenc/charenc.js\").bin,\r\n\r\n // The core\r\n md5 = function (message, options) {\r\n // Convert to byte array\r\n if (message.constructor == String)\r\n if (options && options.encoding === 'binary')\r\n message = bin.stringToBytes(message);\r\n else\r\n message = utf8.stringToBytes(message);\r\n else if (isBuffer(message))\r\n message = Array.prototype.slice.call(message, 0);\r\n else if (!Array.isArray(message))\r\n message = message.toString();\r\n // else, assume byte array already\r\n\r\n var m = crypt.bytesToWords(message),\r\n l = message.length * 8,\r\n a = 1732584193,\r\n b = -271733879,\r\n c = -1732584194,\r\n d = 271733878;\r\n\r\n // Swap endian\r\n for (var i = 0; i < m.length; i++) {\r\n m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |\r\n ((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;\r\n }\r\n\r\n // Padding\r\n m[l >>> 5] |= 0x80 << (l % 32);\r\n m[(((l + 64) >>> 9) << 4) + 14] = l;\r\n\r\n // Method shortcuts\r\n var FF = md5._ff,\r\n GG = md5._gg,\r\n HH = md5._hh,\r\n II = md5._ii;\r\n\r\n for (var i = 0; i < m.length; i += 16) {\r\n\r\n var aa = a,\r\n bb = b,\r\n cc = c,\r\n dd = d;\r\n\r\n a = FF(a, b, c, d, m[i+ 0], 7, -680876936);\r\n d = FF(d, a, b, c, m[i+ 1], 12, -389564586);\r\n c = FF(c, d, a, b, m[i+ 2], 17, 606105819);\r\n b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);\r\n a = FF(a, b, c, d, m[i+ 4], 7, -176418897);\r\n d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);\r\n c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);\r\n b = FF(b, c, d, a, m[i+ 7], 22, -45705983);\r\n a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);\r\n d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);\r\n c = FF(c, d, a, b, m[i+10], 17, -42063);\r\n b = FF(b, c, d, a, m[i+11], 22, -1990404162);\r\n a = FF(a, b, c, d, m[i+12], 7, 1804603682);\r\n d = FF(d, a, b, c, m[i+13], 12, -40341101);\r\n c = FF(c, d, a, b, m[i+14], 17, -1502002290);\r\n b = FF(b, c, d, a, m[i+15], 22, 1236535329);\r\n\r\n a = GG(a, b, c, d, m[i+ 1], 5, -165796510);\r\n d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);\r\n c = GG(c, d, a, b, m[i+11], 14, 643717713);\r\n b = GG(b, c, d, a, m[i+ 0], 20, -373897302);\r\n a = GG(a, b, c, d, m[i+ 5], 5, -701558691);\r\n d = GG(d, a, b, c, m[i+10], 9, 38016083);\r\n c = GG(c, d, a, b, m[i+15], 14, -660478335);\r\n b = GG(b, c, d, a, m[i+ 4], 20, -405537848);\r\n a = GG(a, b, c, d, m[i+ 9], 5, 568446438);\r\n d = GG(d, a, b, c, m[i+14], 9, -1019803690);\r\n c = GG(c, d, a, b, m[i+ 3], 14, -187363961);\r\n b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);\r\n a = GG(a, b, c, d, m[i+13], 5, -1444681467);\r\n d = GG(d, a, b, c, m[i+ 2], 9, -51403784);\r\n c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);\r\n b = GG(b, c, d, a, m[i+12], 20, -1926607734);\r\n\r\n a = HH(a, b, c, d, m[i+ 5], 4, -378558);\r\n d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);\r\n c = HH(c, d, a, b, m[i+11], 16, 1839030562);\r\n b = HH(b, c, d, a, m[i+14], 23, -35309556);\r\n a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);\r\n d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);\r\n c = HH(c, d, a, b, m[i+ 7], 16, -155497632);\r\n b = HH(b, c, d, a, m[i+10], 23, -1094730640);\r\n a = HH(a, b, c, d, m[i+13], 4, 681279174);\r\n d = HH(d, a, b, c, m[i+ 0], 11, -358537222);\r\n c = HH(c, d, a, b, m[i+ 3], 16, -722521979);\r\n b = HH(b, c, d, a, m[i+ 6], 23, 76029189);\r\n a = HH(a, b, c, d, m[i+ 9], 4, -640364487);\r\n d = HH(d, a, b, c, m[i+12], 11, -421815835);\r\n c = HH(c, d, a, b, m[i+15], 16, 530742520);\r\n b = HH(b, c, d, a, m[i+ 2], 23, -995338651);\r\n\r\n a = II(a, b, c, d, m[i+ 0], 6, -198630844);\r\n d = II(d, a, b, c, m[i+ 7], 10, 1126891415);\r\n c = II(c, d, a, b, m[i+14], 15, -1416354905);\r\n b = II(b, c, d, a, m[i+ 5], 21, -57434055);\r\n a = II(a, b, c, d, m[i+12], 6, 1700485571);\r\n d = II(d, a, b, c, m[i+ 3], 10, -1894986606);\r\n c = II(c, d, a, b, m[i+10], 15, -1051523);\r\n b = II(b, c, d, a, m[i+ 1], 21, -2054922799);\r\n a = II(a, b, c, d, m[i+ 8], 6, 1873313359);\r\n d = II(d, a, b, c, m[i+15], 10, -30611744);\r\n c = II(c, d, a, b, m[i+ 6], 15, -1560198380);\r\n b = II(b, c, d, a, m[i+13], 21, 1309151649);\r\n a = II(a, b, c, d, m[i+ 4], 6, -145523070);\r\n d = II(d, a, b, c, m[i+11], 10, -1120210379);\r\n c = II(c, d, a, b, m[i+ 2], 15, 718787259);\r\n b = II(b, c, d, a, m[i+ 9], 21, -343485551);\r\n\r\n a = (a + aa) >>> 0;\r\n b = (b + bb) >>> 0;\r\n c = (c + cc) >>> 0;\r\n d = (d + dd) >>> 0;\r\n }\r\n\r\n return crypt.endian([a, b, c, d]);\r\n };\r\n\r\n // Auxiliary functions\r\n md5._ff = function (a, b, c, d, x, s, t) {\r\n var n = a + (b & c | ~b & d) + (x >>> 0) + t;\r\n return ((n << s) | (n >>> (32 - s))) + b;\r\n };\r\n md5._gg = function (a, b, c, d, x, s, t) {\r\n var n = a + (b & d | c & ~d) + (x >>> 0) + t;\r\n return ((n << s) | (n >>> (32 - s))) + b;\r\n };\r\n md5._hh = function (a, b, c, d, x, s, t) {\r\n var n = a + (b ^ c ^ d) + (x >>> 0) + t;\r\n return ((n << s) | (n >>> (32 - s))) + b;\r\n };\r\n md5._ii = function (a, b, c, d, x, s, t) {\r\n var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;\r\n return ((n << s) | (n >>> (32 - s))) + b;\r\n };\r\n\r\n // Package private blocksize\r\n md5._blocksize = 16;\r\n md5._digestsize = 16;\r\n\r\n module.exports = function (message, options) {\r\n if (message === undefined || message === null)\r\n throw new Error('Illegal argument ' + message);\r\n\r\n var digestbytes = crypt.wordsToBytes(md5(message, options));\r\n return options && options.asBytes ? digestbytes :\r\n options && options.asString ? bin.bytesToString(digestbytes) :\r\n crypt.bytesToHex(digestbytes);\r\n };\r\n\r\n})();\r\n\n\n//# sourceURL=webpack:///../node_modules/md5/md5.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "../node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js": |
|
/*!***********************************************************************!*\ |
|
!*** ../node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js ***! |
|
\***********************************************************************/ |
|
/*! exports provided: default */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/*!\n * perfect-scrollbar v1.3.0\n * (c) 2017 Hyunje Jun\n * @license MIT\n */\nfunction get(element) {\n return getComputedStyle(element);\n}\n\nfunction set(element, obj) {\n for (var key in obj) {\n var val = obj[key];\n if (typeof val === 'number') {\n val = val + \"px\";\n }\n element.style[key] = val;\n }\n return element;\n}\n\nfunction div(className) {\n var div = document.createElement('div');\n div.className = className;\n return div;\n}\n\nvar elMatches =\n typeof Element !== 'undefined' &&\n (Element.prototype.matches ||\n Element.prototype.webkitMatchesSelector ||\n Element.prototype.msMatchesSelector);\n\nfunction matches(element, query) {\n if (!elMatches) {\n throw new Error('No element matching method supported');\n }\n\n return elMatches.call(element, query);\n}\n\nfunction remove(element) {\n if (element.remove) {\n element.remove();\n } else {\n if (element.parentNode) {\n element.parentNode.removeChild(element);\n }\n }\n}\n\nfunction queryChildren(element, selector) {\n return Array.prototype.filter.call(element.children, function (child) { return matches(child, selector); }\n );\n}\n\nvar cls = {\n main: 'ps',\n element: {\n thumb: function (x) { return (\"ps__thumb-\" + x); },\n rail: function (x) { return (\"ps__rail-\" + x); },\n consuming: 'ps__child--consume',\n },\n state: {\n focus: 'ps--focus',\n active: function (x) { return (\"ps--active-\" + x); },\n scrolling: function (x) { return (\"ps--scrolling-\" + x); },\n },\n};\n\n/*\n * Helper methods\n */\nvar scrollingClassTimeout = { x: null, y: null };\n\nfunction addScrollingClass(i, x) {\n var classList = i.element.classList;\n var className = cls.state.scrolling(x);\n\n if (classList.contains(className)) {\n clearTimeout(scrollingClassTimeout[x]);\n } else {\n classList.add(className);\n }\n}\n\nfunction removeScrollingClass(i, x) {\n scrollingClassTimeout[x] = setTimeout(\n function () { return i.isAlive && i.element.classList.remove(cls.state.scrolling(x)); },\n i.settings.scrollingThreshold\n );\n}\n\nfunction setScrollingClassInstantly(i, x) {\n addScrollingClass(i, x);\n removeScrollingClass(i, x);\n}\n\nvar EventElement = function EventElement(element) {\n this.element = element;\n this.handlers = {};\n};\n\nvar prototypeAccessors = { isEmpty: { configurable: true } };\n\nEventElement.prototype.bind = function bind (eventName, handler) {\n if (typeof this.handlers[eventName] === 'undefined') {\n this.handlers[eventName] = [];\n }\n this.handlers[eventName].push(handler);\n this.element.addEventListener(eventName, handler, false);\n};\n\nEventElement.prototype.unbind = function unbind (eventName, target) {\n var this$1 = this;\n\n this.handlers[eventName] = this.handlers[eventName].filter(function (handler) {\n if (target && handler !== target) {\n return true;\n }\n this$1.element.removeEventListener(eventName, handler, false);\n return false;\n });\n};\n\nEventElement.prototype.unbindAll = function unbindAll () {\n var this$1 = this;\n\n for (var name in this$1.handlers) {\n this$1.unbind(name);\n }\n};\n\nprototypeAccessors.isEmpty.get = function () {\n var this$1 = this;\n\n return Object.keys(this.handlers).every(\n function (key) { return this$1.handlers[key].length === 0; }\n );\n};\n\nObject.defineProperties( EventElement.prototype, prototypeAccessors );\n\nvar EventManager = function EventManager() {\n this.eventElements = [];\n};\n\nEventManager.prototype.eventElement = function eventElement (element) {\n var ee = this.eventElements.filter(function (ee) { return ee.element === element; })[0];\n if (!ee) {\n ee = new EventElement(element);\n this.eventElements.push(ee);\n }\n return ee;\n};\n\nEventManager.prototype.bind = function bind (element, eventName, handler) {\n this.eventElement(element).bind(eventName, handler);\n};\n\nEventManager.prototype.unbind = function unbind (element, eventName, handler) {\n var ee = this.eventElement(element);\n ee.unbind(eventName, handler);\n\n if (ee.isEmpty) {\n // remove\n this.eventElements.splice(this.eventElements.indexOf(ee), 1);\n }\n};\n\nEventManager.prototype.unbindAll = function unbindAll () {\n this.eventElements.forEach(function (e) { return e.unbindAll(); });\n this.eventElements = [];\n};\n\nEventManager.prototype.once = function once (element, eventName, handler) {\n var ee = this.eventElement(element);\n var onceHandler = function (evt) {\n ee.unbind(eventName, onceHandler);\n handler(evt);\n };\n ee.bind(eventName, onceHandler);\n};\n\nfunction createEvent(name) {\n if (typeof window.CustomEvent === 'function') {\n return new CustomEvent(name);\n } else {\n var evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(name, false, false, undefined);\n return evt;\n }\n}\n\nvar processScrollDiff = function(\n i,\n axis,\n diff,\n useScrollingClass,\n forceFireReachEvent\n) {\n if ( useScrollingClass === void 0 ) useScrollingClass = true;\n if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false;\n\n var fields;\n if (axis === 'top') {\n fields = [\n 'contentHeight',\n 'containerHeight',\n 'scrollTop',\n 'y',\n 'up',\n 'down' ];\n } else if (axis === 'left') {\n fields = [\n 'contentWidth',\n 'containerWidth',\n 'scrollLeft',\n 'x',\n 'left',\n 'right' ];\n } else {\n throw new Error('A proper axis should be provided');\n }\n\n processScrollDiff$1(i, diff, fields, useScrollingClass, forceFireReachEvent);\n};\n\nfunction processScrollDiff$1(\n i,\n diff,\n ref,\n useScrollingClass,\n forceFireReachEvent\n) {\n var contentHeight = ref[0];\n var containerHeight = ref[1];\n var scrollTop = ref[2];\n var y = ref[3];\n var up = ref[4];\n var down = ref[5];\n if ( useScrollingClass === void 0 ) useScrollingClass = true;\n if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false;\n\n var element = i.element;\n\n // reset reach\n i.reach[y] = null;\n\n // 1 for subpixel rounding\n if (element[scrollTop] < 1) {\n i.reach[y] = 'start';\n }\n\n // 1 for subpixel rounding\n if (element[scrollTop] > i[contentHeight] - i[containerHeight] - 1) {\n i.reach[y] = 'end';\n }\n\n if (diff) {\n element.dispatchEvent(createEvent((\"ps-scroll-\" + y)));\n\n if (diff < 0) {\n element.dispatchEvent(createEvent((\"ps-scroll-\" + up)));\n } else if (diff > 0) {\n element.dispatchEvent(createEvent((\"ps-scroll-\" + down)));\n }\n\n if (useScrollingClass) {\n setScrollingClassInstantly(i, y);\n }\n }\n\n if (i.reach[y] && (diff || forceFireReachEvent)) {\n element.dispatchEvent(createEvent((\"ps-\" + y + \"-reach-\" + (i.reach[y]))));\n }\n}\n\nfunction toInt(x) {\n return parseInt(x, 10) || 0;\n}\n\nfunction isEditable(el) {\n return (\n matches(el, 'input,[contenteditable]') ||\n matches(el, 'select,[contenteditable]') ||\n matches(el, 'textarea,[contenteditable]') ||\n matches(el, 'button,[contenteditable]')\n );\n}\n\nfunction outerWidth(element) {\n var styles = get(element);\n return (\n toInt(styles.width) +\n toInt(styles.paddingLeft) +\n toInt(styles.paddingRight) +\n toInt(styles.borderLeftWidth) +\n toInt(styles.borderRightWidth)\n );\n}\n\nvar env = {\n isWebKit:\n typeof document !== 'undefined' &&\n 'WebkitAppearance' in document.documentElement.style,\n supportsTouch:\n typeof window !== 'undefined' &&\n ('ontouchstart' in window ||\n (window.DocumentTouch && document instanceof window.DocumentTouch)),\n supportsIePointer:\n typeof navigator !== 'undefined' && navigator.msMaxTouchPoints,\n isChrome:\n typeof navigator !== 'undefined' &&\n /Chrome/i.test(navigator && navigator.userAgent),\n};\n\nvar updateGeometry = function(i) {\n var element = i.element;\n\n i.containerWidth = element.clientWidth;\n i.containerHeight = element.clientHeight;\n i.contentWidth = element.scrollWidth;\n i.contentHeight = element.scrollHeight;\n\n if (!element.contains(i.scrollbarXRail)) {\n // clean up and append\n queryChildren(element, cls.element.rail('x')).forEach(function (el) { return remove(el); }\n );\n element.appendChild(i.scrollbarXRail);\n }\n if (!element.contains(i.scrollbarYRail)) {\n // clean up and append\n queryChildren(element, cls.element.rail('y')).forEach(function (el) { return remove(el); }\n );\n element.appendChild(i.scrollbarYRail);\n }\n\n if (\n !i.settings.suppressScrollX &&\n i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth\n ) {\n i.scrollbarXActive = true;\n i.railXWidth = i.containerWidth - i.railXMarginWidth;\n i.railXRatio = i.containerWidth / i.railXWidth;\n i.scrollbarXWidth = getThumbSize(\n i,\n toInt(i.railXWidth * i.containerWidth / i.contentWidth)\n );\n i.scrollbarXLeft = toInt(\n (i.negativeScrollAdjustment + element.scrollLeft) *\n (i.railXWidth - i.scrollbarXWidth) /\n (i.contentWidth - i.containerWidth)\n );\n } else {\n i.scrollbarXActive = false;\n }\n\n if (\n !i.settings.suppressScrollY &&\n i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight\n ) {\n i.scrollbarYActive = true;\n i.railYHeight = i.containerHeight - i.railYMarginHeight;\n i.railYRatio = i.containerHeight / i.railYHeight;\n i.scrollbarYHeight = getThumbSize(\n i,\n toInt(i.railYHeight * i.containerHeight / i.contentHeight)\n );\n i.scrollbarYTop = toInt(\n element.scrollTop *\n (i.railYHeight - i.scrollbarYHeight) /\n (i.contentHeight - i.containerHeight)\n );\n } else {\n i.scrollbarYActive = false;\n }\n\n if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {\n i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;\n }\n if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {\n i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;\n }\n\n updateCss(element, i);\n\n if (i.scrollbarXActive) {\n element.classList.add(cls.state.active('x'));\n } else {\n element.classList.remove(cls.state.active('x'));\n i.scrollbarXWidth = 0;\n i.scrollbarXLeft = 0;\n element.scrollLeft = 0;\n }\n if (i.scrollbarYActive) {\n element.classList.add(cls.state.active('y'));\n } else {\n element.classList.remove(cls.state.active('y'));\n i.scrollbarYHeight = 0;\n i.scrollbarYTop = 0;\n element.scrollTop = 0;\n }\n};\n\nfunction getThumbSize(i, thumbSize) {\n if (i.settings.minScrollbarLength) {\n thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);\n }\n if (i.settings.maxScrollbarLength) {\n thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);\n }\n return thumbSize;\n}\n\nfunction updateCss(element, i) {\n var xRailOffset = { width: i.railXWidth };\n if (i.isRtl) {\n xRailOffset.left =\n i.negativeScrollAdjustment +\n element.scrollLeft +\n i.containerWidth -\n i.contentWidth;\n } else {\n xRailOffset.left = element.scrollLeft;\n }\n if (i.isScrollbarXUsingBottom) {\n xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;\n } else {\n xRailOffset.top = i.scrollbarXTop + element.scrollTop;\n }\n set(i.scrollbarXRail, xRailOffset);\n\n var yRailOffset = { top: element.scrollTop, height: i.railYHeight };\n if (i.isScrollbarYUsingRight) {\n if (i.isRtl) {\n yRailOffset.right =\n i.contentWidth -\n (i.negativeScrollAdjustment + element.scrollLeft) -\n i.scrollbarYRight -\n i.scrollbarYOuterWidth;\n } else {\n yRailOffset.right = i.scrollbarYRight - element.scrollLeft;\n }\n } else {\n if (i.isRtl) {\n yRailOffset.left =\n i.negativeScrollAdjustment +\n element.scrollLeft +\n i.containerWidth * 2 -\n i.contentWidth -\n i.scrollbarYLeft -\n i.scrollbarYOuterWidth;\n } else {\n yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;\n }\n }\n set(i.scrollbarYRail, yRailOffset);\n\n set(i.scrollbarX, {\n left: i.scrollbarXLeft,\n width: i.scrollbarXWidth - i.railBorderXWidth,\n });\n set(i.scrollbarY, {\n top: i.scrollbarYTop,\n height: i.scrollbarYHeight - i.railBorderYWidth,\n });\n}\n\nvar clickRail = function(i) {\n i.event.bind(i.scrollbarY, 'mousedown', function (e) { return e.stopPropagation(); });\n i.event.bind(i.scrollbarYRail, 'mousedown', function (e) {\n var positionTop =\n e.pageY -\n window.pageYOffset -\n i.scrollbarYRail.getBoundingClientRect().top;\n var direction = positionTop > i.scrollbarYTop ? 1 : -1;\n\n i.element.scrollTop += direction * i.containerHeight;\n updateGeometry(i);\n\n e.stopPropagation();\n });\n\n i.event.bind(i.scrollbarX, 'mousedown', function (e) { return e.stopPropagation(); });\n i.event.bind(i.scrollbarXRail, 'mousedown', function (e) {\n var positionLeft =\n e.pageX -\n window.pageXOffset -\n i.scrollbarXRail.getBoundingClientRect().left;\n var direction = positionLeft > i.scrollbarXLeft ? 1 : -1;\n\n i.element.scrollLeft += direction * i.containerWidth;\n updateGeometry(i);\n\n e.stopPropagation();\n });\n};\n\nvar dragThumb = function(i) {\n bindMouseScrollHandler(i, [\n 'containerWidth',\n 'contentWidth',\n 'pageX',\n 'railXWidth',\n 'scrollbarX',\n 'scrollbarXWidth',\n 'scrollLeft',\n 'x' ]);\n bindMouseScrollHandler(i, [\n 'containerHeight',\n 'contentHeight',\n 'pageY',\n 'railYHeight',\n 'scrollbarY',\n 'scrollbarYHeight',\n 'scrollTop',\n 'y' ]);\n};\n\nfunction bindMouseScrollHandler(\n i,\n ref\n) {\n var containerHeight = ref[0];\n var contentHeight = ref[1];\n var pageY = ref[2];\n var railYHeight = ref[3];\n var scrollbarY = ref[4];\n var scrollbarYHeight = ref[5];\n var scrollTop = ref[6];\n var y = ref[7];\n\n var element = i.element;\n\n var startingScrollTop = null;\n var startingMousePageY = null;\n var scrollBy = null;\n\n function mouseMoveHandler(e) {\n element[scrollTop] =\n startingScrollTop + scrollBy * (e[pageY] - startingMousePageY);\n addScrollingClass(i, y);\n updateGeometry(i);\n\n e.stopPropagation();\n e.preventDefault();\n }\n\n function mouseUpHandler() {\n removeScrollingClass(i, y);\n i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n }\n\n i.event.bind(i[scrollbarY], 'mousedown', function (e) {\n startingScrollTop = element[scrollTop];\n startingMousePageY = e[pageY];\n scrollBy =\n (i[contentHeight] - i[containerHeight]) /\n (i[railYHeight] - i[scrollbarYHeight]);\n\n i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);\n\n e.stopPropagation();\n e.preventDefault();\n });\n}\n\nvar keyboard = function(i) {\n var element = i.element;\n\n var elementHovered = function () { return matches(element, ':hover'); };\n var scrollbarFocused = function () { return matches(i.scrollbarX, ':focus') || matches(i.scrollbarY, ':focus'); };\n\n function shouldPreventDefault(deltaX, deltaY) {\n var scrollTop = element.scrollTop;\n if (deltaX === 0) {\n if (!i.scrollbarYActive) {\n return false;\n }\n if (\n (scrollTop === 0 && deltaY > 0) ||\n (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)\n ) {\n return !i.settings.wheelPropagation;\n }\n }\n\n var scrollLeft = element.scrollLeft;\n if (deltaY === 0) {\n if (!i.scrollbarXActive) {\n return false;\n }\n if (\n (scrollLeft === 0 && deltaX < 0) ||\n (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)\n ) {\n return !i.settings.wheelPropagation;\n }\n }\n return true;\n }\n\n i.event.bind(i.ownerDocument, 'keydown', function (e) {\n if (\n (e.isDefaultPrevented && e.isDefaultPrevented()) ||\n e.defaultPrevented\n ) {\n return;\n }\n\n if (!elementHovered() && !scrollbarFocused()) {\n return;\n }\n\n var activeElement = document.activeElement\n ? document.activeElement\n : i.ownerDocument.activeElement;\n if (activeElement) {\n if (activeElement.tagName === 'IFRAME') {\n activeElement = activeElement.contentDocument.activeElement;\n } else {\n // go deeper if element is a webcomponent\n while (activeElement.shadowRoot) {\n activeElement = activeElement.shadowRoot.activeElement;\n }\n }\n if (isEditable(activeElement)) {\n return;\n }\n }\n\n var deltaX = 0;\n var deltaY = 0;\n\n switch (e.which) {\n case 37: // left\n if (e.metaKey) {\n deltaX = -i.contentWidth;\n } else if (e.altKey) {\n deltaX = -i.containerWidth;\n } else {\n deltaX = -30;\n }\n break;\n case 38: // up\n if (e.metaKey) {\n deltaY = i.contentHeight;\n } else if (e.altKey) {\n deltaY = i.containerHeight;\n } else {\n deltaY = 30;\n }\n break;\n case 39: // right\n if (e.metaKey) {\n deltaX = i.contentWidth;\n } else if (e.altKey) {\n deltaX = i.containerWidth;\n } else {\n deltaX = 30;\n }\n break;\n case 40: // down\n if (e.metaKey) {\n deltaY = -i.contentHeight;\n } else if (e.altKey) {\n deltaY = -i.containerHeight;\n } else {\n deltaY = -30;\n }\n break;\n case 32: // space bar\n if (e.shiftKey) {\n deltaY = i.containerHeight;\n } else {\n deltaY = -i.containerHeight;\n }\n break;\n case 33: // page up\n deltaY = i.containerHeight;\n break;\n case 34: // page down\n deltaY = -i.containerHeight;\n break;\n case 36: // home\n deltaY = i.contentHeight;\n break;\n case 35: // end\n deltaY = -i.contentHeight;\n break;\n default:\n return;\n }\n\n if (i.settings.suppressScrollX && deltaX !== 0) {\n return;\n }\n if (i.settings.suppressScrollY && deltaY !== 0) {\n return;\n }\n\n element.scrollTop -= deltaY;\n element.scrollLeft += deltaX;\n updateGeometry(i);\n\n if (shouldPreventDefault(deltaX, deltaY)) {\n e.preventDefault();\n }\n });\n};\n\nvar wheel = function(i) {\n var element = i.element;\n\n function shouldPreventDefault(deltaX, deltaY) {\n var isTop = element.scrollTop === 0;\n var isBottom =\n element.scrollTop + element.offsetHeight === element.scrollHeight;\n var isLeft = element.scrollLeft === 0;\n var isRight =\n element.scrollLeft + element.offsetWidth === element.offsetWidth;\n\n var hitsBound;\n\n // pick axis with primary direction\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n hitsBound = isTop || isBottom;\n } else {\n hitsBound = isLeft || isRight;\n }\n\n return hitsBound ? !i.settings.wheelPropagation : true;\n }\n\n function getDeltaFromEvent(e) {\n var deltaX = e.deltaX;\n var deltaY = -1 * e.deltaY;\n\n if (typeof deltaX === 'undefined' || typeof deltaY === 'undefined') {\n // OS X Safari\n deltaX = -1 * e.wheelDeltaX / 6;\n deltaY = e.wheelDeltaY / 6;\n }\n\n if (e.deltaMode && e.deltaMode === 1) {\n // Firefox in deltaMode 1: Line scrolling\n deltaX *= 10;\n deltaY *= 10;\n }\n\n if (deltaX !== deltaX && deltaY !== deltaY /* NaN checks */) {\n // IE in some mouse drivers\n deltaX = 0;\n deltaY = e.wheelDelta;\n }\n\n if (e.shiftKey) {\n // reverse axis with shift key\n return [-deltaY, -deltaX];\n }\n return [deltaX, deltaY];\n }\n\n function shouldBeConsumedByChild(target, deltaX, deltaY) {\n // FIXME: this is a workaround for <select> issue in FF and IE #571\n if (!env.isWebKit && element.querySelector('select:focus')) {\n return true;\n }\n\n if (!element.contains(target)) {\n return false;\n }\n\n var cursor = target;\n\n while (cursor && cursor !== element) {\n if (cursor.classList.contains(cls.element.consuming)) {\n return true;\n }\n\n var style = get(cursor);\n var overflow = [style.overflow, style.overflowX, style.overflowY].join(\n ''\n );\n\n // if scrollable\n if (overflow.match(/(scroll|auto)/)) {\n var maxScrollTop = cursor.scrollHeight - cursor.clientHeight;\n if (maxScrollTop > 0) {\n if (\n !(cursor.scrollTop === 0 && deltaY > 0) &&\n !(cursor.scrollTop === maxScrollTop && deltaY < 0)\n ) {\n return true;\n }\n }\n var maxScrollLeft = cursor.scrollLeft - cursor.clientWidth;\n if (maxScrollLeft > 0) {\n if (\n !(cursor.scrollLeft === 0 && deltaX < 0) &&\n !(cursor.scrollLeft === maxScrollLeft && deltaX > 0)\n ) {\n return true;\n }\n }\n }\n\n cursor = cursor.parentNode;\n }\n\n return false;\n }\n\n function mousewheelHandler(e) {\n var ref = getDeltaFromEvent(e);\n var deltaX = ref[0];\n var deltaY = ref[1];\n\n if (shouldBeConsumedByChild(e.target, deltaX, deltaY)) {\n return;\n }\n\n var shouldPrevent = false;\n if (!i.settings.useBothWheelAxes) {\n // deltaX will only be used for horizontal scrolling and deltaY will\n // only be used for vertical scrolling - this is the default\n element.scrollTop -= deltaY * i.settings.wheelSpeed;\n element.scrollLeft += deltaX * i.settings.wheelSpeed;\n } else if (i.scrollbarYActive && !i.scrollbarXActive) {\n // only vertical scrollbar is active and useBothWheelAxes option is\n // active, so let's scroll vertical bar using both mouse wheel axes\n if (deltaY) {\n element.scrollTop -= deltaY * i.settings.wheelSpeed;\n } else {\n element.scrollTop += deltaX * i.settings.wheelSpeed;\n }\n shouldPrevent = true;\n } else if (i.scrollbarXActive && !i.scrollbarYActive) {\n // useBothWheelAxes and only horizontal bar is active, so use both\n // wheel axes for horizontal bar\n if (deltaX) {\n element.scrollLeft += deltaX * i.settings.wheelSpeed;\n } else {\n element.scrollLeft -= deltaY * i.settings.wheelSpeed;\n }\n shouldPrevent = true;\n }\n\n updateGeometry(i);\n\n shouldPrevent = shouldPrevent || shouldPreventDefault(deltaX, deltaY);\n if (shouldPrevent && !e.ctrlKey) {\n e.stopPropagation();\n e.preventDefault();\n }\n }\n\n if (typeof window.onwheel !== 'undefined') {\n i.event.bind(element, 'wheel', mousewheelHandler);\n } else if (typeof window.onmousewheel !== 'undefined') {\n i.event.bind(element, 'mousewheel', mousewheelHandler);\n }\n};\n\nvar touch = function(i) {\n if (!env.supportsTouch && !env.supportsIePointer) {\n return;\n }\n\n var element = i.element;\n\n function shouldPrevent(deltaX, deltaY) {\n var scrollTop = element.scrollTop;\n var scrollLeft = element.scrollLeft;\n var magnitudeX = Math.abs(deltaX);\n var magnitudeY = Math.abs(deltaY);\n\n if (magnitudeY > magnitudeX) {\n // user is perhaps trying to swipe up/down the page\n\n if (\n (deltaY < 0 && scrollTop === i.contentHeight - i.containerHeight) ||\n (deltaY > 0 && scrollTop === 0)\n ) {\n // set prevent for mobile Chrome refresh\n return window.scrollY === 0 && deltaY > 0 && env.isChrome;\n }\n } else if (magnitudeX > magnitudeY) {\n // user is perhaps trying to swipe left/right across the page\n\n if (\n (deltaX < 0 && scrollLeft === i.contentWidth - i.containerWidth) ||\n (deltaX > 0 && scrollLeft === 0)\n ) {\n return true;\n }\n }\n\n return true;\n }\n\n function applyTouchMove(differenceX, differenceY) {\n element.scrollTop -= differenceY;\n element.scrollLeft -= differenceX;\n\n updateGeometry(i);\n }\n\n var startOffset = {};\n var startTime = 0;\n var speed = {};\n var easingLoop = null;\n\n function getTouch(e) {\n if (e.targetTouches) {\n return e.targetTouches[0];\n } else {\n // Maybe IE pointer\n return e;\n }\n }\n\n function shouldHandle(e) {\n if (e.pointerType && e.pointerType === 'pen' && e.buttons === 0) {\n return false;\n }\n if (e.targetTouches && e.targetTouches.length === 1) {\n return true;\n }\n if (\n e.pointerType &&\n e.pointerType !== 'mouse' &&\n e.pointerType !== e.MSPOINTER_TYPE_MOUSE\n ) {\n return true;\n }\n return false;\n }\n\n function touchStart(e) {\n if (!shouldHandle(e)) {\n return;\n }\n\n var touch = getTouch(e);\n\n startOffset.pageX = touch.pageX;\n startOffset.pageY = touch.pageY;\n\n startTime = new Date().getTime();\n\n if (easingLoop !== null) {\n clearInterval(easingLoop);\n }\n }\n\n function shouldBeConsumedByChild(target, deltaX, deltaY) {\n if (!element.contains(target)) {\n return false;\n }\n\n var cursor = target;\n\n while (cursor && cursor !== element) {\n if (cursor.classList.contains(cls.element.consuming)) {\n return true;\n }\n\n var style = get(cursor);\n var overflow = [style.overflow, style.overflowX, style.overflowY].join(\n ''\n );\n\n // if scrollable\n if (overflow.match(/(scroll|auto)/)) {\n var maxScrollTop = cursor.scrollHeight - cursor.clientHeight;\n if (maxScrollTop > 0) {\n if (\n !(cursor.scrollTop === 0 && deltaY > 0) &&\n !(cursor.scrollTop === maxScrollTop && deltaY < 0)\n ) {\n return true;\n }\n }\n var maxScrollLeft = cursor.scrollLeft - cursor.clientWidth;\n if (maxScrollLeft > 0) {\n if (\n !(cursor.scrollLeft === 0 && deltaX < 0) &&\n !(cursor.scrollLeft === maxScrollLeft && deltaX > 0)\n ) {\n return true;\n }\n }\n }\n\n cursor = cursor.parentNode;\n }\n\n return false;\n }\n\n function touchMove(e) {\n if (shouldHandle(e)) {\n var touch = getTouch(e);\n\n var currentOffset = { pageX: touch.pageX, pageY: touch.pageY };\n\n var differenceX = currentOffset.pageX - startOffset.pageX;\n var differenceY = currentOffset.pageY - startOffset.pageY;\n\n if (shouldBeConsumedByChild(e.target, differenceX, differenceY)) {\n return;\n }\n\n applyTouchMove(differenceX, differenceY);\n startOffset = currentOffset;\n\n var currentTime = new Date().getTime();\n\n var timeGap = currentTime - startTime;\n if (timeGap > 0) {\n speed.x = differenceX / timeGap;\n speed.y = differenceY / timeGap;\n startTime = currentTime;\n }\n\n if (shouldPrevent(differenceX, differenceY)) {\n e.preventDefault();\n }\n }\n }\n function touchEnd() {\n if (i.settings.swipeEasing) {\n clearInterval(easingLoop);\n easingLoop = setInterval(function() {\n if (i.isInitialized) {\n clearInterval(easingLoop);\n return;\n }\n\n if (!speed.x && !speed.y) {\n clearInterval(easingLoop);\n return;\n }\n\n if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {\n clearInterval(easingLoop);\n return;\n }\n\n applyTouchMove(speed.x * 30, speed.y * 30);\n\n speed.x *= 0.8;\n speed.y *= 0.8;\n }, 10);\n }\n }\n\n if (env.supportsTouch) {\n i.event.bind(element, 'touchstart', touchStart);\n i.event.bind(element, 'touchmove', touchMove);\n i.event.bind(element, 'touchend', touchEnd);\n } else if (env.supportsIePointer) {\n if (window.PointerEvent) {\n i.event.bind(element, 'pointerdown', touchStart);\n i.event.bind(element, 'pointermove', touchMove);\n i.event.bind(element, 'pointerup', touchEnd);\n } else if (window.MSPointerEvent) {\n i.event.bind(element, 'MSPointerDown', touchStart);\n i.event.bind(element, 'MSPointerMove', touchMove);\n i.event.bind(element, 'MSPointerUp', touchEnd);\n }\n }\n};\n\nvar defaultSettings = function () { return ({\n handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'],\n maxScrollbarLength: null,\n minScrollbarLength: null,\n scrollingThreshold: 1000,\n scrollXMarginOffset: 0,\n scrollYMarginOffset: 0,\n suppressScrollX: false,\n suppressScrollY: false,\n swipeEasing: true,\n useBothWheelAxes: false,\n wheelPropagation: false,\n wheelSpeed: 1,\n}); };\n\nvar handlers = {\n 'click-rail': clickRail,\n 'drag-thumb': dragThumb,\n keyboard: keyboard,\n wheel: wheel,\n touch: touch,\n};\n\nvar PerfectScrollbar = function PerfectScrollbar(element, userSettings) {\n var this$1 = this;\n if ( userSettings === void 0 ) userSettings = {};\n\n if (typeof element === 'string') {\n element = document.querySelector(element);\n }\n\n if (!element || !element.nodeName) {\n throw new Error('no element is specified to initialize PerfectScrollbar');\n }\n\n this.element = element;\n\n element.classList.add(cls.main);\n\n this.settings = defaultSettings();\n for (var key in userSettings) {\n this$1.settings[key] = userSettings[key];\n }\n\n this.containerWidth = null;\n this.containerHeight = null;\n this.contentWidth = null;\n this.contentHeight = null;\n\n var focus = function () { return element.classList.add(cls.state.focus); };\n var blur = function () { return element.classList.remove(cls.state.focus); };\n\n this.isRtl = get(element).direction === 'rtl';\n this.isNegativeScroll = (function () {\n var originalScrollLeft = element.scrollLeft;\n var result = null;\n element.scrollLeft = -1;\n result = element.scrollLeft < 0;\n element.scrollLeft = originalScrollLeft;\n return result;\n })();\n this.negativeScrollAdjustment = this.isNegativeScroll\n ? element.scrollWidth - element.clientWidth\n : 0;\n this.event = new EventManager();\n this.ownerDocument = element.ownerDocument || document;\n\n this.scrollbarXRail = div(cls.element.rail('x'));\n element.appendChild(this.scrollbarXRail);\n this.scrollbarX = div(cls.element.thumb('x'));\n this.scrollbarXRail.appendChild(this.scrollbarX);\n this.scrollbarX.setAttribute('tabindex', 0);\n this.event.bind(this.scrollbarX, 'focus', focus);\n this.event.bind(this.scrollbarX, 'blur', blur);\n this.scrollbarXActive = null;\n this.scrollbarXWidth = null;\n this.scrollbarXLeft = null;\n var railXStyle = get(this.scrollbarXRail);\n this.scrollbarXBottom = parseInt(railXStyle.bottom, 10);\n if (isNaN(this.scrollbarXBottom)) {\n this.isScrollbarXUsingBottom = false;\n this.scrollbarXTop = toInt(railXStyle.top);\n } else {\n this.isScrollbarXUsingBottom = true;\n }\n this.railBorderXWidth =\n toInt(railXStyle.borderLeftWidth) + toInt(railXStyle.borderRightWidth);\n // Set rail to display:block to calculate margins\n set(this.scrollbarXRail, { display: 'block' });\n this.railXMarginWidth =\n toInt(railXStyle.marginLeft) + toInt(railXStyle.marginRight);\n set(this.scrollbarXRail, { display: '' });\n this.railXWidth = null;\n this.railXRatio = null;\n\n this.scrollbarYRail = div(cls.element.rail('y'));\n element.appendChild(this.scrollbarYRail);\n this.scrollbarY = div(cls.element.thumb('y'));\n this.scrollbarYRail.appendChild(this.scrollbarY);\n this.scrollbarY.setAttribute('tabindex', 0);\n this.event.bind(this.scrollbarY, 'focus', focus);\n this.event.bind(this.scrollbarY, 'blur', blur);\n this.scrollbarYActive = null;\n this.scrollbarYHeight = null;\n this.scrollbarYTop = null;\n var railYStyle = get(this.scrollbarYRail);\n this.scrollbarYRight = parseInt(railYStyle.right, 10);\n if (isNaN(this.scrollbarYRight)) {\n this.isScrollbarYUsingRight = false;\n this.scrollbarYLeft = toInt(railYStyle.left);\n } else {\n this.isScrollbarYUsingRight = true;\n }\n this.scrollbarYOuterWidth = this.isRtl ? outerWidth(this.scrollbarY) : null;\n this.railBorderYWidth =\n toInt(railYStyle.borderTopWidth) + toInt(railYStyle.borderBottomWidth);\n set(this.scrollbarYRail, { display: 'block' });\n this.railYMarginHeight =\n toInt(railYStyle.marginTop) + toInt(railYStyle.marginBottom);\n set(this.scrollbarYRail, { display: '' });\n this.railYHeight = null;\n this.railYRatio = null;\n\n this.reach = {\n x:\n element.scrollLeft <= 0\n ? 'start'\n : element.scrollLeft >= this.contentWidth - this.containerWidth\n ? 'end'\n : null,\n y:\n element.scrollTop <= 0\n ? 'start'\n : element.scrollTop >= this.contentHeight - this.containerHeight\n ? 'end'\n : null,\n };\n\n this.isAlive = true;\n\n this.settings.handlers.forEach(function (handlerName) { return handlers[handlerName](this$1); });\n\n this.lastScrollTop = element.scrollTop; // for onScroll only\n this.lastScrollLeft = element.scrollLeft; // for onScroll only\n this.event.bind(this.element, 'scroll', function (e) { return this$1.onScroll(e); });\n updateGeometry(this);\n};\n\nPerfectScrollbar.prototype.update = function update () {\n if (!this.isAlive) {\n return;\n }\n\n // Recalcuate negative scrollLeft adjustment\n this.negativeScrollAdjustment = this.isNegativeScroll\n ? this.element.scrollWidth - this.element.clientWidth\n : 0;\n\n // Recalculate rail margins\n set(this.scrollbarXRail, { display: 'block' });\n set(this.scrollbarYRail, { display: 'block' });\n this.railXMarginWidth =\n toInt(get(this.scrollbarXRail).marginLeft) +\n toInt(get(this.scrollbarXRail).marginRight);\n this.railYMarginHeight =\n toInt(get(this.scrollbarYRail).marginTop) +\n toInt(get(this.scrollbarYRail).marginBottom);\n\n // Hide scrollbars not to affect scrollWidth and scrollHeight\n set(this.scrollbarXRail, { display: 'none' });\n set(this.scrollbarYRail, { display: 'none' });\n\n updateGeometry(this);\n\n processScrollDiff(this, 'top', 0, false, true);\n processScrollDiff(this, 'left', 0, false, true);\n\n set(this.scrollbarXRail, { display: '' });\n set(this.scrollbarYRail, { display: '' });\n};\n\nPerfectScrollbar.prototype.onScroll = function onScroll (e) {\n if (!this.isAlive) {\n return;\n }\n\n updateGeometry(this);\n processScrollDiff(this, 'top', this.element.scrollTop - this.lastScrollTop);\n processScrollDiff(\n this,\n 'left',\n this.element.scrollLeft - this.lastScrollLeft\n );\n\n this.lastScrollTop = this.element.scrollTop;\n this.lastScrollLeft = this.element.scrollLeft;\n};\n\nPerfectScrollbar.prototype.destroy = function destroy () {\n if (!this.isAlive) {\n return;\n }\n\n this.event.unbindAll();\n remove(this.scrollbarX);\n remove(this.scrollbarY);\n remove(this.scrollbarXRail);\n remove(this.scrollbarYRail);\n this.removePsClasses();\n\n // unset elements\n this.element = null;\n this.scrollbarX = null;\n this.scrollbarY = null;\n this.scrollbarXRail = null;\n this.scrollbarYRail = null;\n\n this.isAlive = false;\n};\n\nPerfectScrollbar.prototype.removePsClasses = function removePsClasses () {\n this.element.className = this.element.className\n .split(' ')\n .filter(function (name) { return !name.match(/^ps([-_].+|)$/); })\n .join(' ');\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (PerfectScrollbar);\n\n\n//# sourceURL=webpack:///../node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "../node_modules/tether-drop/dist/js/drop.js": |
|
/*!***************************************************!*\ |
|
!*** ../node_modules/tether-drop/dist/js/drop.js ***! |
|
\***************************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! tether-drop 1.4.1 */\n\n(function(root, factory) {\n if (true) {\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! tether */ \"../node_modules/tether/dist/js/tether.js\")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n}(this, function(Tether) {\n\n/* global Tether */\n'use strict';\n\nvar _bind = Function.prototype.bind;\n\nvar _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\nvar _get = function get(_x2, _x3, _x4) { var _again = true; _function: while (_again) { var object = _x2, property = _x3, receiver = _x4; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x2 = parent; _x3 = property; _x4 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar _Tether$Utils = Tether.Utils;\nvar extend = _Tether$Utils.extend;\nvar addClass = _Tether$Utils.addClass;\nvar removeClass = _Tether$Utils.removeClass;\nvar hasClass = _Tether$Utils.hasClass;\nvar Evented = _Tether$Utils.Evented;\n\nfunction sortAttach(str) {\n var _str$split = str.split(' ');\n\n var _str$split2 = _slicedToArray(_str$split, 2);\n\n var first = _str$split2[0];\n var second = _str$split2[1];\n\n if (['left', 'right'].indexOf(first) >= 0) {\n var _ref = [second, first];\n first = _ref[0];\n second = _ref[1];\n }\n return [first, second].join(' ');\n}\n\nfunction removeFromArray(arr, item) {\n var index = undefined;\n var results = [];\n while ((index = arr.indexOf(item)) !== -1) {\n results.push(arr.splice(index, 1));\n }\n return results;\n}\n\nvar clickEvents = ['click'];\nif ('ontouchstart' in document.documentElement) {\n clickEvents.push('touchstart');\n}\n\nvar transitionEndEvents = {\n 'WebkitTransition': 'webkitTransitionEnd',\n 'MozTransition': 'transitionend',\n 'OTransition': 'otransitionend',\n 'transition': 'transitionend'\n};\n\nvar transitionEndEvent = '';\nfor (var _name in transitionEndEvents) {\n if (({}).hasOwnProperty.call(transitionEndEvents, _name)) {\n var tempEl = document.createElement('p');\n if (typeof tempEl.style[_name] !== 'undefined') {\n transitionEndEvent = transitionEndEvents[_name];\n }\n }\n}\n\nvar MIRROR_ATTACH = {\n left: 'right',\n right: 'left',\n top: 'bottom',\n bottom: 'top',\n middle: 'middle',\n center: 'center'\n};\n\nvar allDrops = {};\n\n// Drop can be included in external libraries. Calling createContext gives you a fresh\n// copy of drop which won't interact with other copies on the page (beyond calling the document events).\n\nfunction createContext() {\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var drop = function drop() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return new (_bind.apply(DropInstance, [null].concat(args)))();\n };\n\n extend(drop, {\n createContext: createContext,\n drops: [],\n defaults: {}\n });\n\n var defaultOptions = {\n classPrefix: 'drop',\n defaults: {\n position: 'bottom left',\n openOn: 'click',\n beforeClose: null,\n constrainToScrollParent: true,\n constrainToWindow: true,\n classes: '',\n remove: false,\n openDelay: 0,\n closeDelay: 50,\n // inherited from openDelay and closeDelay if not explicitly defined\n focusDelay: null,\n blurDelay: null,\n hoverOpenDelay: null,\n hoverCloseDelay: null,\n tetherOptions: {}\n }\n };\n\n extend(drop, defaultOptions, options);\n extend(drop.defaults, defaultOptions.defaults, options.defaults);\n\n if (typeof allDrops[drop.classPrefix] === 'undefined') {\n allDrops[drop.classPrefix] = [];\n }\n\n drop.updateBodyClasses = function () {\n // There is only one body, so despite the context concept, we still iterate through all\n // drops which share our classPrefix.\n\n var anyOpen = false;\n var drops = allDrops[drop.classPrefix];\n var len = drops.length;\n for (var i = 0; i < len; ++i) {\n if (drops[i].isOpened()) {\n anyOpen = true;\n break;\n }\n }\n\n if (anyOpen) {\n addClass(document.body, drop.classPrefix + '-open');\n } else {\n removeClass(document.body, drop.classPrefix + '-open');\n }\n };\n\n var DropInstance = (function (_Evented) {\n _inherits(DropInstance, _Evented);\n\n function DropInstance(opts) {\n _classCallCheck(this, DropInstance);\n\n _get(Object.getPrototypeOf(DropInstance.prototype), 'constructor', this).call(this);\n this.options = extend({}, drop.defaults, opts);\n this.target = this.options.target;\n\n if (typeof this.target === 'undefined') {\n throw new Error('Drop Error: You must provide a target.');\n }\n\n var dataPrefix = 'data-' + drop.classPrefix;\n\n var contentAttr = this.target.getAttribute(dataPrefix);\n if (contentAttr && this.options.content == null) {\n this.options.content = contentAttr;\n }\n\n var attrsOverride = ['position', 'openOn'];\n for (var i = 0; i < attrsOverride.length; ++i) {\n\n var override = this.target.getAttribute(dataPrefix + '-' + attrsOverride[i]);\n if (override && this.options[attrsOverride[i]] == null) {\n this.options[attrsOverride[i]] = override;\n }\n }\n\n if (this.options.classes && this.options.addTargetClasses !== false) {\n addClass(this.target, this.options.classes);\n }\n\n drop.drops.push(this);\n allDrops[drop.classPrefix].push(this);\n\n this._boundEvents = [];\n this.bindMethods();\n this.setupElements();\n this.setupEvents();\n this.setupTether();\n }\n\n _createClass(DropInstance, [{\n key: '_on',\n value: function _on(element, event, handler) {\n this._boundEvents.push({ element: element, event: event, handler: handler });\n element.addEventListener(event, handler);\n }\n }, {\n key: 'bindMethods',\n value: function bindMethods() {\n this.transitionEndHandler = this._transitionEndHandler.bind(this);\n }\n }, {\n key: 'setupElements',\n value: function setupElements() {\n var _this = this;\n\n this.drop = document.createElement('div');\n addClass(this.drop, drop.classPrefix);\n\n if (this.options.classes) {\n addClass(this.drop, this.options.classes);\n }\n\n this.content = document.createElement('div');\n addClass(this.content, drop.classPrefix + '-content');\n\n if (typeof this.options.content === 'function') {\n var generateAndSetContent = function generateAndSetContent() {\n // content function might return a string or an element\n var contentElementOrHTML = _this.options.content.call(_this, _this);\n\n if (typeof contentElementOrHTML === 'string') {\n _this.content.innerHTML = contentElementOrHTML;\n } else if (typeof contentElementOrHTML === 'object') {\n _this.content.innerHTML = '';\n _this.content.appendChild(contentElementOrHTML);\n } else {\n throw new Error('Drop Error: Content function should return a string or HTMLElement.');\n }\n };\n\n generateAndSetContent();\n this.on('open', generateAndSetContent.bind(this));\n } else if (typeof this.options.content === 'object') {\n this.content.appendChild(this.options.content);\n } else {\n this.content.innerHTML = this.options.content;\n }\n\n this.drop.appendChild(this.content);\n }\n }, {\n key: 'setupTether',\n value: function setupTether() {\n // Tether expects two attachment points, one in the target element, one in the\n // drop. We use a single one, and use the order as well, to allow us to put\n // the drop on either side of any of the four corners. This magic converts between\n // the two:\n var dropAttach = this.options.position.split(' ');\n dropAttach[0] = MIRROR_ATTACH[dropAttach[0]];\n dropAttach = dropAttach.join(' ');\n\n var constraints = [];\n if (this.options.constrainToScrollParent) {\n constraints.push({\n to: 'scrollParent',\n pin: 'top, bottom',\n attachment: 'together none'\n });\n } else {\n // To get 'out of bounds' classes\n constraints.push({\n to: 'scrollParent'\n });\n }\n\n if (this.options.constrainToWindow !== false) {\n constraints.push({\n to: 'window',\n attachment: 'together'\n });\n } else {\n // To get 'out of bounds' classes\n constraints.push({\n to: 'window'\n });\n }\n\n var opts = {\n element: this.drop,\n target: this.target,\n attachment: sortAttach(dropAttach),\n targetAttachment: sortAttach(this.options.position),\n classPrefix: drop.classPrefix,\n offset: '0 0',\n targetOffset: '0 0',\n enabled: false,\n constraints: constraints,\n addTargetClasses: this.options.addTargetClasses\n };\n\n if (this.options.tetherOptions !== false) {\n this.tether = new Tether(extend({}, opts, this.options.tetherOptions));\n }\n }\n }, {\n key: 'setupEvents',\n value: function setupEvents() {\n var _this2 = this;\n\n if (!this.options.openOn) {\n return;\n }\n\n if (this.options.openOn === 'always') {\n setTimeout(this.open.bind(this));\n return;\n }\n\n var events = this.options.openOn.split(' ');\n\n if (events.indexOf('click') >= 0) {\n var openHandler = function openHandler(event) {\n _this2.toggle(event);\n event.preventDefault();\n };\n\n var closeHandler = function closeHandler(event) {\n if (!_this2.isOpened()) {\n return;\n }\n\n // Clicking inside dropdown\n if (event.target === _this2.drop || _this2.drop.contains(event.target)) {\n return;\n }\n\n // Clicking target\n if (event.target === _this2.target || _this2.target.contains(event.target)) {\n return;\n }\n\n _this2.close(event);\n };\n\n for (var i = 0; i < clickEvents.length; ++i) {\n var clickEvent = clickEvents[i];\n this._on(this.target, clickEvent, openHandler);\n this._on(document, clickEvent, closeHandler);\n }\n }\n\n var inTimeout = null;\n var outTimeout = null;\n\n var inHandler = function inHandler(event) {\n if (outTimeout !== null) {\n clearTimeout(outTimeout);\n } else {\n inTimeout = setTimeout(function () {\n _this2.open(event);\n inTimeout = null;\n }, (event.type === 'focus' ? _this2.options.focusDelay : _this2.options.hoverOpenDelay) || _this2.options.openDelay);\n }\n };\n\n var outHandler = function outHandler(event) {\n if (inTimeout !== null) {\n clearTimeout(inTimeout);\n } else {\n outTimeout = setTimeout(function () {\n _this2.close(event);\n outTimeout = null;\n }, (event.type === 'blur' ? _this2.options.blurDelay : _this2.options.hoverCloseDelay) || _this2.options.closeDelay);\n }\n };\n\n if (events.indexOf('hover') >= 0) {\n this._on(this.target, 'mouseover', inHandler);\n this._on(this.drop, 'mouseover', inHandler);\n this._on(this.target, 'mouseout', outHandler);\n this._on(this.drop, 'mouseout', outHandler);\n }\n\n if (events.indexOf('focus') >= 0) {\n this._on(this.target, 'focus', inHandler);\n this._on(this.drop, 'focus', inHandler);\n this._on(this.target, 'blur', outHandler);\n this._on(this.drop, 'blur', outHandler);\n }\n }\n }, {\n key: 'isOpened',\n value: function isOpened() {\n if (this.drop) {\n return hasClass(this.drop, drop.classPrefix + '-open');\n }\n }\n }, {\n key: 'toggle',\n value: function toggle(event) {\n if (this.isOpened()) {\n this.close(event);\n } else {\n this.open(event);\n }\n }\n }, {\n key: 'open',\n value: function open(event) {\n var _this3 = this;\n\n /* eslint no-unused-vars: 0 */\n if (this.isOpened()) {\n return;\n }\n\n if (!this.drop.parentNode) {\n document.body.appendChild(this.drop);\n }\n\n if (typeof this.tether !== 'undefined') {\n this.tether.enable();\n }\n\n addClass(this.drop, drop.classPrefix + '-open');\n addClass(this.drop, drop.classPrefix + '-open-transitionend');\n\n setTimeout(function () {\n if (_this3.drop) {\n addClass(_this3.drop, drop.classPrefix + '-after-open');\n }\n });\n\n if (typeof this.tether !== 'undefined') {\n this.tether.position();\n }\n\n this.trigger('open');\n\n drop.updateBodyClasses();\n }\n }, {\n key: '_transitionEndHandler',\n value: function _transitionEndHandler(e) {\n if (e.target !== e.currentTarget) {\n return;\n }\n\n if (!hasClass(this.drop, drop.classPrefix + '-open')) {\n removeClass(this.drop, drop.classPrefix + '-open-transitionend');\n }\n this.drop.removeEventListener(transitionEndEvent, this.transitionEndHandler);\n }\n }, {\n key: 'beforeCloseHandler',\n value: function beforeCloseHandler(event) {\n var shouldClose = true;\n\n if (!this.isClosing && typeof this.options.beforeClose === 'function') {\n this.isClosing = true;\n shouldClose = this.options.beforeClose(event, this) !== false;\n }\n\n this.isClosing = false;\n\n return shouldClose;\n }\n }, {\n key: 'close',\n value: function close(event) {\n if (!this.isOpened()) {\n return;\n }\n\n if (!this.beforeCloseHandler(event)) {\n return;\n }\n\n removeClass(this.drop, drop.classPrefix + '-open');\n removeClass(this.drop, drop.classPrefix + '-after-open');\n\n this.drop.addEventListener(transitionEndEvent, this.transitionEndHandler);\n\n this.trigger('close');\n\n if (typeof this.tether !== 'undefined') {\n this.tether.disable();\n }\n\n drop.updateBodyClasses();\n\n if (this.options.remove) {\n this.remove(event);\n }\n }\n }, {\n key: 'remove',\n value: function remove(event) {\n this.close(event);\n if (this.drop.parentNode) {\n this.drop.parentNode.removeChild(this.drop);\n }\n }\n }, {\n key: 'position',\n value: function position() {\n if (this.isOpened() && typeof this.tether !== 'undefined') {\n this.tether.position();\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.remove();\n\n if (typeof this.tether !== 'undefined') {\n this.tether.destroy();\n }\n\n for (var i = 0; i < this._boundEvents.length; ++i) {\n var _boundEvents$i = this._boundEvents[i];\n var element = _boundEvents$i.element;\n var _event = _boundEvents$i.event;\n var handler = _boundEvents$i.handler;\n\n element.removeEventListener(_event, handler);\n }\n\n this._boundEvents = [];\n\n this.tether = null;\n this.drop = null;\n this.content = null;\n this.target = null;\n\n removeFromArray(allDrops[drop.classPrefix], this);\n removeFromArray(drop.drops, this);\n }\n }]);\n\n return DropInstance;\n })(Evented);\n\n return drop;\n}\n\nvar Drop = createContext();\n\ndocument.addEventListener('DOMContentLoaded', function () {\n Drop.updateBodyClasses();\n});\nreturn Drop;\n\n}));\n\n\n//# sourceURL=webpack:///../node_modules/tether-drop/dist/js/drop.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "../node_modules/tether/dist/js/tether.js": |
|
/*!************************************************!*\ |
|
!*** ../node_modules/tether/dist/js/tether.js ***! |
|
\************************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! tether 1.4.3 */\n\n(function(root, factory) {\n if (true) {\n !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :\n\t\t\t\t__WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n}(this, function(require, exports, module) {\n\n'use strict';\n\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nvar TetherBase = undefined;\nif (typeof TetherBase === 'undefined') {\n TetherBase = { modules: [] };\n}\n\nvar zeroElement = null;\n\n// Same as native getBoundingClientRect, except it takes into account parent <frame> offsets\n// if the element lies within a nested document (<frame> or <iframe>-like).\nfunction getActualBoundingClientRect(node) {\n var boundingRect = node.getBoundingClientRect();\n\n // The original object returned by getBoundingClientRect is immutable, so we clone it\n // We can't use extend because the properties are not considered part of the object by hasOwnProperty in IE9\n var rect = {};\n for (var k in boundingRect) {\n rect[k] = boundingRect[k];\n }\n\n if (node.ownerDocument !== document) {\n var _frameElement = node.ownerDocument.defaultView.frameElement;\n if (_frameElement) {\n var frameRect = getActualBoundingClientRect(_frameElement);\n rect.top += frameRect.top;\n rect.bottom += frameRect.top;\n rect.left += frameRect.left;\n rect.right += frameRect.left;\n }\n }\n\n return rect;\n}\n\nfunction getScrollParents(el) {\n // In firefox if the el is inside an iframe with display: none; window.getComputedStyle() will return null;\n // https://bugzilla.mozilla.org/show_bug.cgi?id=548397\n var computedStyle = getComputedStyle(el) || {};\n var position = computedStyle.position;\n var parents = [];\n\n if (position === 'fixed') {\n return [el];\n }\n\n var parent = el;\n while ((parent = parent.parentNode) && parent && parent.nodeType === 1) {\n var style = undefined;\n try {\n style = getComputedStyle(parent);\n } catch (err) {}\n\n if (typeof style === 'undefined' || style === null) {\n parents.push(parent);\n return parents;\n }\n\n var _style = style;\n var overflow = _style.overflow;\n var overflowX = _style.overflowX;\n var overflowY = _style.overflowY;\n\n if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {\n if (position !== 'absolute' || ['relative', 'absolute', 'fixed'].indexOf(style.position) >= 0) {\n parents.push(parent);\n }\n }\n }\n\n parents.push(el.ownerDocument.body);\n\n // If the node is within a frame, account for the parent window scroll\n if (el.ownerDocument !== document) {\n parents.push(el.ownerDocument.defaultView);\n }\n\n return parents;\n}\n\nvar uniqueId = (function () {\n var id = 0;\n return function () {\n return ++id;\n };\n})();\n\nvar zeroPosCache = {};\nvar getOrigin = function getOrigin() {\n // getBoundingClientRect is unfortunately too accurate. It introduces a pixel or two of\n // jitter as the user scrolls that messes with our ability to detect if two positions\n // are equivilant or not. We place an element at the top left of the page that will\n // get the same jitter, so we can cancel the two out.\n var node = zeroElement;\n if (!node || !document.body.contains(node)) {\n node = document.createElement('div');\n node.setAttribute('data-tether-id', uniqueId());\n extend(node.style, {\n top: 0,\n left: 0,\n position: 'absolute'\n });\n\n document.body.appendChild(node);\n\n zeroElement = node;\n }\n\n var id = node.getAttribute('data-tether-id');\n if (typeof zeroPosCache[id] === 'undefined') {\n zeroPosCache[id] = getActualBoundingClientRect(node);\n\n // Clear the cache when this position call is done\n defer(function () {\n delete zeroPosCache[id];\n });\n }\n\n return zeroPosCache[id];\n};\n\nfunction removeUtilElements() {\n if (zeroElement) {\n document.body.removeChild(zeroElement);\n }\n zeroElement = null;\n};\n\nfunction getBounds(el) {\n var doc = undefined;\n if (el === document) {\n doc = document;\n el = document.documentElement;\n } else {\n doc = el.ownerDocument;\n }\n\n var docEl = doc.documentElement;\n\n var box = getActualBoundingClientRect(el);\n\n var origin = getOrigin();\n\n box.top -= origin.top;\n box.left -= origin.left;\n\n if (typeof box.width === 'undefined') {\n box.width = document.body.scrollWidth - box.left - box.right;\n }\n if (typeof box.height === 'undefined') {\n box.height = document.body.scrollHeight - box.top - box.bottom;\n }\n\n box.top = box.top - docEl.clientTop;\n box.left = box.left - docEl.clientLeft;\n box.right = doc.body.clientWidth - box.width - box.left;\n box.bottom = doc.body.clientHeight - box.height - box.top;\n\n return box;\n}\n\nfunction getOffsetParent(el) {\n return el.offsetParent || document.documentElement;\n}\n\nvar _scrollBarSize = null;\nfunction getScrollBarSize() {\n if (_scrollBarSize) {\n return _scrollBarSize;\n }\n var inner = document.createElement('div');\n inner.style.width = '100%';\n inner.style.height = '200px';\n\n var outer = document.createElement('div');\n extend(outer.style, {\n position: 'absolute',\n top: 0,\n left: 0,\n pointerEvents: 'none',\n visibility: 'hidden',\n width: '200px',\n height: '150px',\n overflow: 'hidden'\n });\n\n outer.appendChild(inner);\n\n document.body.appendChild(outer);\n\n var widthContained = inner.offsetWidth;\n outer.style.overflow = 'scroll';\n var widthScroll = inner.offsetWidth;\n\n if (widthContained === widthScroll) {\n widthScroll = outer.clientWidth;\n }\n\n document.body.removeChild(outer);\n\n var width = widthContained - widthScroll;\n\n _scrollBarSize = { width: width, height: width };\n return _scrollBarSize;\n}\n\nfunction extend() {\n var out = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var args = [];\n\n Array.prototype.push.apply(args, arguments);\n\n args.slice(1).forEach(function (obj) {\n if (obj) {\n for (var key in obj) {\n if (({}).hasOwnProperty.call(obj, key)) {\n out[key] = obj[key];\n }\n }\n }\n });\n\n return out;\n}\n\nfunction removeClass(el, name) {\n if (typeof el.classList !== 'undefined') {\n name.split(' ').forEach(function (cls) {\n if (cls.trim()) {\n el.classList.remove(cls);\n }\n });\n } else {\n var regex = new RegExp('(^| )' + name.split(' ').join('|') + '( |$)', 'gi');\n var className = getClassName(el).replace(regex, ' ');\n setClassName(el, className);\n }\n}\n\nfunction addClass(el, name) {\n if (typeof el.classList !== 'undefined') {\n name.split(' ').forEach(function (cls) {\n if (cls.trim()) {\n el.classList.add(cls);\n }\n });\n } else {\n removeClass(el, name);\n var cls = getClassName(el) + (' ' + name);\n setClassName(el, cls);\n }\n}\n\nfunction hasClass(el, name) {\n if (typeof el.classList !== 'undefined') {\n return el.classList.contains(name);\n }\n var className = getClassName(el);\n return new RegExp('(^| )' + name + '( |$)', 'gi').test(className);\n}\n\nfunction getClassName(el) {\n // Can't use just SVGAnimatedString here since nodes within a Frame in IE have\n // completely separately SVGAnimatedString base classes\n if (el.className instanceof el.ownerDocument.defaultView.SVGAnimatedString) {\n return el.className.baseVal;\n }\n return el.className;\n}\n\nfunction setClassName(el, className) {\n el.setAttribute('class', className);\n}\n\nfunction updateClasses(el, add, all) {\n // Of the set of 'all' classes, we need the 'add' classes, and only the\n // 'add' classes to be set.\n all.forEach(function (cls) {\n if (add.indexOf(cls) === -1 && hasClass(el, cls)) {\n removeClass(el, cls);\n }\n });\n\n add.forEach(function (cls) {\n if (!hasClass(el, cls)) {\n addClass(el, cls);\n }\n });\n}\n\nvar deferred = [];\n\nvar defer = function defer(fn) {\n deferred.push(fn);\n};\n\nvar flush = function flush() {\n var fn = undefined;\n while (fn = deferred.pop()) {\n fn();\n }\n};\n\nvar Evented = (function () {\n function Evented() {\n _classCallCheck(this, Evented);\n }\n\n _createClass(Evented, [{\n key: 'on',\n value: function on(event, handler, ctx) {\n var once = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];\n\n if (typeof this.bindings === 'undefined') {\n this.bindings = {};\n }\n if (typeof this.bindings[event] === 'undefined') {\n this.bindings[event] = [];\n }\n this.bindings[event].push({ handler: handler, ctx: ctx, once: once });\n }\n }, {\n key: 'once',\n value: function once(event, handler, ctx) {\n this.on(event, handler, ctx, true);\n }\n }, {\n key: 'off',\n value: function off(event, handler) {\n if (typeof this.bindings === 'undefined' || typeof this.bindings[event] === 'undefined') {\n return;\n }\n\n if (typeof handler === 'undefined') {\n delete this.bindings[event];\n } else {\n var i = 0;\n while (i < this.bindings[event].length) {\n if (this.bindings[event][i].handler === handler) {\n this.bindings[event].splice(i, 1);\n } else {\n ++i;\n }\n }\n }\n }\n }, {\n key: 'trigger',\n value: function trigger(event) {\n if (typeof this.bindings !== 'undefined' && this.bindings[event]) {\n var i = 0;\n\n for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n while (i < this.bindings[event].length) {\n var _bindings$event$i = this.bindings[event][i];\n var handler = _bindings$event$i.handler;\n var ctx = _bindings$event$i.ctx;\n var once = _bindings$event$i.once;\n\n var context = ctx;\n if (typeof context === 'undefined') {\n context = this;\n }\n\n handler.apply(context, args);\n\n if (once) {\n this.bindings[event].splice(i, 1);\n } else {\n ++i;\n }\n }\n }\n }\n }]);\n\n return Evented;\n})();\n\nTetherBase.Utils = {\n getActualBoundingClientRect: getActualBoundingClientRect,\n getScrollParents: getScrollParents,\n getBounds: getBounds,\n getOffsetParent: getOffsetParent,\n extend: extend,\n addClass: addClass,\n removeClass: removeClass,\n hasClass: hasClass,\n updateClasses: updateClasses,\n defer: defer,\n flush: flush,\n uniqueId: uniqueId,\n Evented: Evented,\n getScrollBarSize: getScrollBarSize,\n removeUtilElements: removeUtilElements\n};\n/* globals TetherBase, performance */\n\n'use strict';\n\nvar _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\nvar _get = function get(_x6, _x7, _x8) { var _again = true; _function: while (_again) { var object = _x6, property = _x7, receiver = _x8; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x6 = parent; _x7 = property; _x8 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nif (typeof TetherBase === 'undefined') {\n throw new Error('You must include the utils.js file before tether.js');\n}\n\nvar _TetherBase$Utils = TetherBase.Utils;\nvar getScrollParents = _TetherBase$Utils.getScrollParents;\nvar getBounds = _TetherBase$Utils.getBounds;\nvar getOffsetParent = _TetherBase$Utils.getOffsetParent;\nvar extend = _TetherBase$Utils.extend;\nvar addClass = _TetherBase$Utils.addClass;\nvar removeClass = _TetherBase$Utils.removeClass;\nvar updateClasses = _TetherBase$Utils.updateClasses;\nvar defer = _TetherBase$Utils.defer;\nvar flush = _TetherBase$Utils.flush;\nvar getScrollBarSize = _TetherBase$Utils.getScrollBarSize;\nvar removeUtilElements = _TetherBase$Utils.removeUtilElements;\n\nfunction within(a, b) {\n var diff = arguments.length <= 2 || arguments[2] === undefined ? 1 : arguments[2];\n\n return a + diff >= b && b >= a - diff;\n}\n\nvar transformKey = (function () {\n if (typeof document === 'undefined') {\n return '';\n }\n var el = document.createElement('div');\n\n var transforms = ['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform'];\n for (var i = 0; i < transforms.length; ++i) {\n var key = transforms[i];\n if (el.style[key] !== undefined) {\n return key;\n }\n }\n})();\n\nvar tethers = [];\n\nvar position = function position() {\n tethers.forEach(function (tether) {\n tether.position(false);\n });\n flush();\n};\n\nfunction now() {\n if (typeof performance === 'object' && typeof performance.now === 'function') {\n return performance.now();\n }\n return +new Date();\n}\n\n(function () {\n var lastCall = null;\n var lastDuration = null;\n var pendingTimeout = null;\n\n var tick = function tick() {\n if (typeof lastDuration !== 'undefined' && lastDuration > 16) {\n // We voluntarily throttle ourselves if we can't manage 60fps\n lastDuration = Math.min(lastDuration - 16, 250);\n\n // Just in case this is the last event, remember to position just once more\n pendingTimeout = setTimeout(tick, 250);\n return;\n }\n\n if (typeof lastCall !== 'undefined' && now() - lastCall < 10) {\n // Some browsers call events a little too frequently, refuse to run more than is reasonable\n return;\n }\n\n if (pendingTimeout != null) {\n clearTimeout(pendingTimeout);\n pendingTimeout = null;\n }\n\n lastCall = now();\n position();\n lastDuration = now() - lastCall;\n };\n\n if (typeof window !== 'undefined' && typeof window.addEventListener !== 'undefined') {\n ['resize', 'scroll', 'touchmove'].forEach(function (event) {\n window.addEventListener(event, tick);\n });\n }\n})();\n\nvar MIRROR_LR = {\n center: 'center',\n left: 'right',\n right: 'left'\n};\n\nvar MIRROR_TB = {\n middle: 'middle',\n top: 'bottom',\n bottom: 'top'\n};\n\nvar OFFSET_MAP = {\n top: 0,\n left: 0,\n middle: '50%',\n center: '50%',\n bottom: '100%',\n right: '100%'\n};\n\nvar autoToFixedAttachment = function autoToFixedAttachment(attachment, relativeToAttachment) {\n var left = attachment.left;\n var top = attachment.top;\n\n if (left === 'auto') {\n left = MIRROR_LR[relativeToAttachment.left];\n }\n\n if (top === 'auto') {\n top = MIRROR_TB[relativeToAttachment.top];\n }\n\n return { left: left, top: top };\n};\n\nvar attachmentToOffset = function attachmentToOffset(attachment) {\n var left = attachment.left;\n var top = attachment.top;\n\n if (typeof OFFSET_MAP[attachment.left] !== 'undefined') {\n left = OFFSET_MAP[attachment.left];\n }\n\n if (typeof OFFSET_MAP[attachment.top] !== 'undefined') {\n top = OFFSET_MAP[attachment.top];\n }\n\n return { left: left, top: top };\n};\n\nfunction addOffset() {\n var out = { top: 0, left: 0 };\n\n for (var _len = arguments.length, offsets = Array(_len), _key = 0; _key < _len; _key++) {\n offsets[_key] = arguments[_key];\n }\n\n offsets.forEach(function (_ref) {\n var top = _ref.top;\n var left = _ref.left;\n\n if (typeof top === 'string') {\n top = parseFloat(top, 10);\n }\n if (typeof left === 'string') {\n left = parseFloat(left, 10);\n }\n\n out.top += top;\n out.left += left;\n });\n\n return out;\n}\n\nfunction offsetToPx(offset, size) {\n if (typeof offset.left === 'string' && offset.left.indexOf('%') !== -1) {\n offset.left = parseFloat(offset.left, 10) / 100 * size.width;\n }\n if (typeof offset.top === 'string' && offset.top.indexOf('%') !== -1) {\n offset.top = parseFloat(offset.top, 10) / 100 * size.height;\n }\n\n return offset;\n}\n\nvar parseOffset = function parseOffset(value) {\n var _value$split = value.split(' ');\n\n var _value$split2 = _slicedToArray(_value$split, 2);\n\n var top = _value$split2[0];\n var left = _value$split2[1];\n\n return { top: top, left: left };\n};\nvar parseAttachment = parseOffset;\n\nvar TetherClass = (function (_Evented) {\n _inherits(TetherClass, _Evented);\n\n function TetherClass(options) {\n var _this = this;\n\n _classCallCheck(this, TetherClass);\n\n _get(Object.getPrototypeOf(TetherClass.prototype), 'constructor', this).call(this);\n this.position = this.position.bind(this);\n\n tethers.push(this);\n\n this.history = [];\n\n this.setOptions(options, false);\n\n TetherBase.modules.forEach(function (module) {\n if (typeof module.initialize !== 'undefined') {\n module.initialize.call(_this);\n }\n });\n\n this.position();\n }\n\n _createClass(TetherClass, [{\n key: 'getClass',\n value: function getClass() {\n var key = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n var classes = this.options.classes;\n\n if (typeof classes !== 'undefined' && classes[key]) {\n return this.options.classes[key];\n } else if (this.options.classPrefix) {\n return this.options.classPrefix + '-' + key;\n } else {\n return key;\n }\n }\n }, {\n key: 'setOptions',\n value: function setOptions(options) {\n var _this2 = this;\n\n var pos = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];\n\n var defaults = {\n offset: '0 0',\n targetOffset: '0 0',\n targetAttachment: 'auto auto',\n classPrefix: 'tether'\n };\n\n this.options = extend(defaults, options);\n\n var _options = this.options;\n var element = _options.element;\n var target = _options.target;\n var targetModifier = _options.targetModifier;\n\n this.element = element;\n this.target = target;\n this.targetModifier = targetModifier;\n\n if (this.target === 'viewport') {\n this.target = document.body;\n this.targetModifier = 'visible';\n } else if (this.target === 'scroll-handle') {\n this.target = document.body;\n this.targetModifier = 'scroll-handle';\n }\n\n ['element', 'target'].forEach(function (key) {\n if (typeof _this2[key] === 'undefined') {\n throw new Error('Tether Error: Both element and target must be defined');\n }\n\n if (typeof _this2[key].jquery !== 'undefined') {\n _this2[key] = _this2[key][0];\n } else if (typeof _this2[key] === 'string') {\n _this2[key] = document.querySelector(_this2[key]);\n }\n });\n\n addClass(this.element, this.getClass('element'));\n if (!(this.options.addTargetClasses === false)) {\n addClass(this.target, this.getClass('target'));\n }\n\n if (!this.options.attachment) {\n throw new Error('Tether Error: You must provide an attachment');\n }\n\n this.targetAttachment = parseAttachment(this.options.targetAttachment);\n this.attachment = parseAttachment(this.options.attachment);\n this.offset = parseOffset(this.options.offset);\n this.targetOffset = parseOffset(this.options.targetOffset);\n\n if (typeof this.scrollParents !== 'undefined') {\n this.disable();\n }\n\n if (this.targetModifier === 'scroll-handle') {\n this.scrollParents = [this.target];\n } else {\n this.scrollParents = getScrollParents(this.target);\n }\n\n if (!(this.options.enabled === false)) {\n this.enable(pos);\n }\n }\n }, {\n key: 'getTargetBounds',\n value: function getTargetBounds() {\n if (typeof this.targetModifier !== 'undefined') {\n if (this.targetModifier === 'visible') {\n if (this.target === document.body) {\n return { top: pageYOffset, left: pageXOffset, height: innerHeight, width: innerWidth };\n } else {\n var bounds = getBounds(this.target);\n\n var out = {\n height: bounds.height,\n width: bounds.width,\n top: bounds.top,\n left: bounds.left\n };\n\n out.height = Math.min(out.height, bounds.height - (pageYOffset - bounds.top));\n out.height = Math.min(out.height, bounds.height - (bounds.top + bounds.height - (pageYOffset + innerHeight)));\n out.height = Math.min(innerHeight, out.height);\n out.height -= 2;\n\n out.width = Math.min(out.width, bounds.width - (pageXOffset - bounds.left));\n out.width = Math.min(out.width, bounds.width - (bounds.left + bounds.width - (pageXOffset + innerWidth)));\n out.width = Math.min(innerWidth, out.width);\n out.width -= 2;\n\n if (out.top < pageYOffset) {\n out.top = pageYOffset;\n }\n if (out.left < pageXOffset) {\n out.left = pageXOffset;\n }\n\n return out;\n }\n } else if (this.targetModifier === 'scroll-handle') {\n var bounds = undefined;\n var target = this.target;\n if (target === document.body) {\n target = document.documentElement;\n\n bounds = {\n left: pageXOffset,\n top: pageYOffset,\n height: innerHeight,\n width: innerWidth\n };\n } else {\n bounds = getBounds(target);\n }\n\n var style = getComputedStyle(target);\n\n var hasBottomScroll = target.scrollWidth > target.clientWidth || [style.overflow, style.overflowX].indexOf('scroll') >= 0 || this.target !== document.body;\n\n var scrollBottom = 0;\n if (hasBottomScroll) {\n scrollBottom = 15;\n }\n\n var height = bounds.height - parseFloat(style.borderTopWidth) - parseFloat(style.borderBottomWidth) - scrollBottom;\n\n var out = {\n width: 15,\n height: height * 0.975 * (height / target.scrollHeight),\n left: bounds.left + bounds.width - parseFloat(style.borderLeftWidth) - 15\n };\n\n var fitAdj = 0;\n if (height < 408 && this.target === document.body) {\n fitAdj = -0.00011 * Math.pow(height, 2) - 0.00727 * height + 22.58;\n }\n\n if (this.target !== document.body) {\n out.height = Math.max(out.height, 24);\n }\n\n var scrollPercentage = this.target.scrollTop / (target.scrollHeight - height);\n out.top = scrollPercentage * (height - out.height - fitAdj) + bounds.top + parseFloat(style.borderTopWidth);\n\n if (this.target === document.body) {\n out.height = Math.max(out.height, 24);\n }\n\n return out;\n }\n } else {\n return getBounds(this.target);\n }\n }\n }, {\n key: 'clearCache',\n value: function clearCache() {\n this._cache = {};\n }\n }, {\n key: 'cache',\n value: function cache(k, getter) {\n // More than one module will often need the same DOM info, so\n // we keep a cache which is cleared on each position call\n if (typeof this._cache === 'undefined') {\n this._cache = {};\n }\n\n if (typeof this._cache[k] === 'undefined') {\n this._cache[k] = getter.call(this);\n }\n\n return this._cache[k];\n }\n }, {\n key: 'enable',\n value: function enable() {\n var _this3 = this;\n\n var pos = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];\n\n if (!(this.options.addTargetClasses === false)) {\n addClass(this.target, this.getClass('enabled'));\n }\n addClass(this.element, this.getClass('enabled'));\n this.enabled = true;\n\n this.scrollParents.forEach(function (parent) {\n if (parent !== _this3.target.ownerDocument) {\n parent.addEventListener('scroll', _this3.position);\n }\n });\n\n if (pos) {\n this.position();\n }\n }\n }, {\n key: 'disable',\n value: function disable() {\n var _this4 = this;\n\n removeClass(this.target, this.getClass('enabled'));\n removeClass(this.element, this.getClass('enabled'));\n this.enabled = false;\n\n if (typeof this.scrollParents !== 'undefined') {\n this.scrollParents.forEach(function (parent) {\n parent.removeEventListener('scroll', _this4.position);\n });\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n var _this5 = this;\n\n this.disable();\n\n tethers.forEach(function (tether, i) {\n if (tether === _this5) {\n tethers.splice(i, 1);\n }\n });\n\n // Remove any elements we were using for convenience from the DOM\n if (tethers.length === 0) {\n removeUtilElements();\n }\n }\n }, {\n key: 'updateAttachClasses',\n value: function updateAttachClasses(elementAttach, targetAttach) {\n var _this6 = this;\n\n elementAttach = elementAttach || this.attachment;\n targetAttach = targetAttach || this.targetAttachment;\n var sides = ['left', 'top', 'bottom', 'right', 'middle', 'center'];\n\n if (typeof this._addAttachClasses !== 'undefined' && this._addAttachClasses.length) {\n // updateAttachClasses can be called more than once in a position call, so\n // we need to clean up after ourselves such that when the last defer gets\n // ran it doesn't add any extra classes from previous calls.\n this._addAttachClasses.splice(0, this._addAttachClasses.length);\n }\n\n if (typeof this._addAttachClasses === 'undefined') {\n this._addAttachClasses = [];\n }\n var add = this._addAttachClasses;\n\n if (elementAttach.top) {\n add.push(this.getClass('element-attached') + '-' + elementAttach.top);\n }\n if (elementAttach.left) {\n add.push(this.getClass('element-attached') + '-' + elementAttach.left);\n }\n if (targetAttach.top) {\n add.push(this.getClass('target-attached') + '-' + targetAttach.top);\n }\n if (targetAttach.left) {\n add.push(this.getClass('target-attached') + '-' + targetAttach.left);\n }\n\n var all = [];\n sides.forEach(function (side) {\n all.push(_this6.getClass('element-attached') + '-' + side);\n all.push(_this6.getClass('target-attached') + '-' + side);\n });\n\n defer(function () {\n if (!(typeof _this6._addAttachClasses !== 'undefined')) {\n return;\n }\n\n updateClasses(_this6.element, _this6._addAttachClasses, all);\n if (!(_this6.options.addTargetClasses === false)) {\n updateClasses(_this6.target, _this6._addAttachClasses, all);\n }\n\n delete _this6._addAttachClasses;\n });\n }\n }, {\n key: 'position',\n value: function position() {\n var _this7 = this;\n\n var flushChanges = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];\n\n // flushChanges commits the changes immediately, leave true unless you are positioning multiple\n // tethers (in which case call Tether.Utils.flush yourself when you're done)\n\n if (!this.enabled) {\n return;\n }\n\n this.clearCache();\n\n // Turn 'auto' attachments into the appropriate corner or edge\n var targetAttachment = autoToFixedAttachment(this.targetAttachment, this.attachment);\n\n this.updateAttachClasses(this.attachment, targetAttachment);\n\n var elementPos = this.cache('element-bounds', function () {\n return getBounds(_this7.element);\n });\n\n var width = elementPos.width;\n var height = elementPos.height;\n\n if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') {\n var _lastSize = this.lastSize;\n\n // We cache the height and width to make it possible to position elements that are\n // getting hidden.\n width = _lastSize.width;\n height = _lastSize.height;\n } else {\n this.lastSize = { width: width, height: height };\n }\n\n var targetPos = this.cache('target-bounds', function () {\n return _this7.getTargetBounds();\n });\n var targetSize = targetPos;\n\n // Get an actual px offset from the attachment\n var offset = offsetToPx(attachmentToOffset(this.attachment), { width: width, height: height });\n var targetOffset = offsetToPx(attachmentToOffset(targetAttachment), targetSize);\n\n var manualOffset = offsetToPx(this.offset, { width: width, height: height });\n var manualTargetOffset = offsetToPx(this.targetOffset, targetSize);\n\n // Add the manually provided offset\n offset = addOffset(offset, manualOffset);\n targetOffset = addOffset(targetOffset, manualTargetOffset);\n\n // It's now our goal to make (element position + offset) == (target position + target offset)\n var left = targetPos.left + targetOffset.left - offset.left;\n var top = targetPos.top + targetOffset.top - offset.top;\n\n for (var i = 0; i < TetherBase.modules.length; ++i) {\n var _module2 = TetherBase.modules[i];\n var ret = _module2.position.call(this, {\n left: left,\n top: top,\n targetAttachment: targetAttachment,\n targetPos: targetPos,\n elementPos: elementPos,\n offset: offset,\n targetOffset: targetOffset,\n manualOffset: manualOffset,\n manualTargetOffset: manualTargetOffset,\n scrollbarSize: scrollbarSize,\n attachment: this.attachment\n });\n\n if (ret === false) {\n return false;\n } else if (typeof ret === 'undefined' || typeof ret !== 'object') {\n continue;\n } else {\n top = ret.top;\n left = ret.left;\n }\n }\n\n // We describe the position three different ways to give the optimizer\n // a chance to decide the best possible way to position the element\n // with the fewest repaints.\n var next = {\n // It's position relative to the page (absolute positioning when\n // the element is a child of the body)\n page: {\n top: top,\n left: left\n },\n\n // It's position relative to the viewport (fixed positioning)\n viewport: {\n top: top - pageYOffset,\n bottom: pageYOffset - top - height + innerHeight,\n left: left - pageXOffset,\n right: pageXOffset - left - width + innerWidth\n }\n };\n\n var doc = this.target.ownerDocument;\n var win = doc.defaultView;\n\n var scrollbarSize = undefined;\n if (win.innerHeight > doc.documentElement.clientHeight) {\n scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);\n next.viewport.bottom -= scrollbarSize.height;\n }\n\n if (win.innerWidth > doc.documentElement.clientWidth) {\n scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);\n next.viewport.right -= scrollbarSize.width;\n }\n\n if (['', 'static'].indexOf(doc.body.style.position) === -1 || ['', 'static'].indexOf(doc.body.parentElement.style.position) === -1) {\n // Absolute positioning in the body will be relative to the page, not the 'initial containing block'\n next.page.bottom = doc.body.scrollHeight - top - height;\n next.page.right = doc.body.scrollWidth - left - width;\n }\n\n if (typeof this.options.optimizations !== 'undefined' && this.options.optimizations.moveElement !== false && !(typeof this.targetModifier !== 'undefined')) {\n (function () {\n var offsetParent = _this7.cache('target-offsetparent', function () {\n return getOffsetParent(_this7.target);\n });\n var offsetPosition = _this7.cache('target-offsetparent-bounds', function () {\n return getBounds(offsetParent);\n });\n var offsetParentStyle = getComputedStyle(offsetParent);\n var offsetParentSize = offsetPosition;\n\n var offsetBorder = {};\n ['Top', 'Left', 'Bottom', 'Right'].forEach(function (side) {\n offsetBorder[side.toLowerCase()] = parseFloat(offsetParentStyle['border' + side + 'Width']);\n });\n\n offsetPosition.right = doc.body.scrollWidth - offsetPosition.left - offsetParentSize.width + offsetBorder.right;\n offsetPosition.bottom = doc.body.scrollHeight - offsetPosition.top - offsetParentSize.height + offsetBorder.bottom;\n\n if (next.page.top >= offsetPosition.top + offsetBorder.top && next.page.bottom >= offsetPosition.bottom) {\n if (next.page.left >= offsetPosition.left + offsetBorder.left && next.page.right >= offsetPosition.right) {\n // We're within the visible part of the target's scroll parent\n var scrollTop = offsetParent.scrollTop;\n var scrollLeft = offsetParent.scrollLeft;\n\n // It's position relative to the target's offset parent (absolute positioning when\n // the element is moved to be a child of the target's offset parent).\n next.offset = {\n top: next.page.top - offsetPosition.top + scrollTop - offsetBorder.top,\n left: next.page.left - offsetPosition.left + scrollLeft - offsetBorder.left\n };\n }\n }\n })();\n }\n\n // We could also travel up the DOM and try each containing context, rather than only\n // looking at the body, but we're gonna get diminishing returns.\n\n this.move(next);\n\n this.history.unshift(next);\n\n if (this.history.length > 3) {\n this.history.pop();\n }\n\n if (flushChanges) {\n flush();\n }\n\n return true;\n }\n\n // THE ISSUE\n }, {\n key: 'move',\n value: function move(pos) {\n var _this8 = this;\n\n if (!(typeof this.element.parentNode !== 'undefined')) {\n return;\n }\n\n var same = {};\n\n for (var type in pos) {\n same[type] = {};\n\n for (var key in pos[type]) {\n var found = false;\n\n for (var i = 0; i < this.history.length; ++i) {\n var point = this.history[i];\n if (typeof point[type] !== 'undefined' && !within(point[type][key], pos[type][key])) {\n found = true;\n break;\n }\n }\n\n if (!found) {\n same[type][key] = true;\n }\n }\n }\n\n var css = { top: '', left: '', right: '', bottom: '' };\n\n var transcribe = function transcribe(_same, _pos) {\n var hasOptimizations = typeof _this8.options.optimizations !== 'undefined';\n var gpu = hasOptimizations ? _this8.options.optimizations.gpu : null;\n if (gpu !== false) {\n var yPos = undefined,\n xPos = undefined;\n if (_same.top) {\n css.top = 0;\n yPos = _pos.top;\n } else {\n css.bottom = 0;\n yPos = -_pos.bottom;\n }\n\n if (_same.left) {\n css.left = 0;\n xPos = _pos.left;\n } else {\n css.right = 0;\n xPos = -_pos.right;\n }\n\n if (window.matchMedia) {\n // HubSpot/tether#207\n var retina = window.matchMedia('only screen and (min-resolution: 1.3dppx)').matches || window.matchMedia('only screen and (-webkit-min-device-pixel-ratio: 1.3)').matches;\n if (!retina) {\n xPos = Math.round(xPos);\n yPos = Math.round(yPos);\n }\n }\n\n css[transformKey] = 'translateX(' + xPos + 'px) translateY(' + yPos + 'px)';\n\n if (transformKey !== 'msTransform') {\n // The Z transform will keep this in the GPU (faster, and prevents artifacts),\n // but IE9 doesn't support 3d transforms and will choke.\n css[transformKey] += \" translateZ(0)\";\n }\n } else {\n if (_same.top) {\n css.top = _pos.top + 'px';\n } else {\n css.bottom = _pos.bottom + 'px';\n }\n\n if (_same.left) {\n css.left = _pos.left + 'px';\n } else {\n css.right = _pos.right + 'px';\n }\n }\n };\n\n var moved = false;\n if ((same.page.top || same.page.bottom) && (same.page.left || same.page.right)) {\n css.position = 'absolute';\n transcribe(same.page, pos.page);\n } else if ((same.viewport.top || same.viewport.bottom) && (same.viewport.left || same.viewport.right)) {\n css.position = 'fixed';\n transcribe(same.viewport, pos.viewport);\n } else if (typeof same.offset !== 'undefined' && same.offset.top && same.offset.left) {\n (function () {\n css.position = 'absolute';\n var offsetParent = _this8.cache('target-offsetparent', function () {\n return getOffsetParent(_this8.target);\n });\n\n if (getOffsetParent(_this8.element) !== offsetParent) {\n defer(function () {\n _this8.element.parentNode.removeChild(_this8.element);\n offsetParent.appendChild(_this8.element);\n });\n }\n\n transcribe(same.offset, pos.offset);\n moved = true;\n })();\n } else {\n css.position = 'absolute';\n transcribe({ top: true, left: true }, pos.page);\n }\n\n if (!moved) {\n if (this.options.bodyElement) {\n if (this.element.parentNode !== this.options.bodyElement) {\n this.options.bodyElement.appendChild(this.element);\n }\n } else {\n var offsetParentIsBody = true;\n var currentNode = this.element.parentNode;\n while (currentNode && currentNode.nodeType === 1 && currentNode.tagName !== 'BODY') {\n if (getComputedStyle(currentNode).position !== 'static') {\n offsetParentIsBody = false;\n break;\n }\n\n currentNode = currentNode.parentNode;\n }\n\n if (!offsetParentIsBody) {\n this.element.parentNode.removeChild(this.element);\n this.element.ownerDocument.body.appendChild(this.element);\n }\n }\n }\n\n // Any css change will trigger a repaint, so let's avoid one if nothing changed\n var writeCSS = {};\n var write = false;\n for (var key in css) {\n var val = css[key];\n var elVal = this.element.style[key];\n\n if (elVal !== val) {\n write = true;\n writeCSS[key] = val;\n }\n }\n\n if (write) {\n defer(function () {\n extend(_this8.element.style, writeCSS);\n _this8.trigger('repositioned');\n });\n }\n }\n }]);\n\n return TetherClass;\n})(Evented);\n\nTetherClass.modules = [];\n\nTetherBase.position = position;\n\nvar Tether = extend(TetherClass, TetherBase);\n/* globals TetherBase */\n\n'use strict';\n\nvar _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\nvar _TetherBase$Utils = TetherBase.Utils;\nvar getBounds = _TetherBase$Utils.getBounds;\nvar extend = _TetherBase$Utils.extend;\nvar updateClasses = _TetherBase$Utils.updateClasses;\nvar defer = _TetherBase$Utils.defer;\n\nvar BOUNDS_FORMAT = ['left', 'top', 'right', 'bottom'];\n\nfunction getBoundingRect(tether, to) {\n if (to === 'scrollParent') {\n to = tether.scrollParents[0];\n } else if (to === 'window') {\n to = [pageXOffset, pageYOffset, innerWidth + pageXOffset, innerHeight + pageYOffset];\n }\n\n if (to === document) {\n to = to.documentElement;\n }\n\n if (typeof to.nodeType !== 'undefined') {\n (function () {\n var node = to;\n var size = getBounds(to);\n var pos = size;\n var style = getComputedStyle(to);\n\n to = [pos.left, pos.top, size.width + pos.left, size.height + pos.top];\n\n // Account any parent Frames scroll offset\n if (node.ownerDocument !== document) {\n var win = node.ownerDocument.defaultView;\n to[0] += win.pageXOffset;\n to[1] += win.pageYOffset;\n to[2] += win.pageXOffset;\n to[3] += win.pageYOffset;\n }\n\n BOUNDS_FORMAT.forEach(function (side, i) {\n side = side[0].toUpperCase() + side.substr(1);\n if (side === 'Top' || side === 'Left') {\n to[i] += parseFloat(style['border' + side + 'Width']);\n } else {\n to[i] -= parseFloat(style['border' + side + 'Width']);\n }\n });\n })();\n }\n\n return to;\n}\n\nTetherBase.modules.push({\n position: function position(_ref) {\n var _this = this;\n\n var top = _ref.top;\n var left = _ref.left;\n var targetAttachment = _ref.targetAttachment;\n\n if (!this.options.constraints) {\n return true;\n }\n\n var _cache = this.cache('element-bounds', function () {\n return getBounds(_this.element);\n });\n\n var height = _cache.height;\n var width = _cache.width;\n\n if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') {\n var _lastSize = this.lastSize;\n\n // Handle the item getting hidden as a result of our positioning without glitching\n // the classes in and out\n width = _lastSize.width;\n height = _lastSize.height;\n }\n\n var targetSize = this.cache('target-bounds', function () {\n return _this.getTargetBounds();\n });\n\n var targetHeight = targetSize.height;\n var targetWidth = targetSize.width;\n\n var allClasses = [this.getClass('pinned'), this.getClass('out-of-bounds')];\n\n this.options.constraints.forEach(function (constraint) {\n var outOfBoundsClass = constraint.outOfBoundsClass;\n var pinnedClass = constraint.pinnedClass;\n\n if (outOfBoundsClass) {\n allClasses.push(outOfBoundsClass);\n }\n if (pinnedClass) {\n allClasses.push(pinnedClass);\n }\n });\n\n allClasses.forEach(function (cls) {\n ['left', 'top', 'right', 'bottom'].forEach(function (side) {\n allClasses.push(cls + '-' + side);\n });\n });\n\n var addClasses = [];\n\n var tAttachment = extend({}, targetAttachment);\n var eAttachment = extend({}, this.attachment);\n\n this.options.constraints.forEach(function (constraint) {\n var to = constraint.to;\n var attachment = constraint.attachment;\n var pin = constraint.pin;\n\n if (typeof attachment === 'undefined') {\n attachment = '';\n }\n\n var changeAttachX = undefined,\n changeAttachY = undefined;\n if (attachment.indexOf(' ') >= 0) {\n var _attachment$split = attachment.split(' ');\n\n var _attachment$split2 = _slicedToArray(_attachment$split, 2);\n\n changeAttachY = _attachment$split2[0];\n changeAttachX = _attachment$split2[1];\n } else {\n changeAttachX = changeAttachY = attachment;\n }\n\n var bounds = getBoundingRect(_this, to);\n\n if (changeAttachY === 'target' || changeAttachY === 'both') {\n if (top < bounds[1] && tAttachment.top === 'top') {\n top += targetHeight;\n tAttachment.top = 'bottom';\n }\n\n if (top + height > bounds[3] && tAttachment.top === 'bottom') {\n top -= targetHeight;\n tAttachment.top = 'top';\n }\n }\n\n if (changeAttachY === 'together') {\n if (tAttachment.top === 'top') {\n if (eAttachment.top === 'bottom' && top < bounds[1]) {\n top += targetHeight;\n tAttachment.top = 'bottom';\n\n top += height;\n eAttachment.top = 'top';\n } else if (eAttachment.top === 'top' && top + height > bounds[3] && top - (height - targetHeight) >= bounds[1]) {\n top -= height - targetHeight;\n tAttachment.top = 'bottom';\n\n eAttachment.top = 'bottom';\n }\n }\n\n if (tAttachment.top === 'bottom') {\n if (eAttachment.top === 'top' && top + height > bounds[3]) {\n top -= targetHeight;\n tAttachment.top = 'top';\n\n top -= height;\n eAttachment.top = 'bottom';\n } else if (eAttachment.top === 'bottom' && top < bounds[1] && top + (height * 2 - targetHeight) <= bounds[3]) {\n top += height - targetHeight;\n tAttachment.top = 'top';\n\n eAttachment.top = 'top';\n }\n }\n\n if (tAttachment.top === 'middle') {\n if (top + height > bounds[3] && eAttachment.top === 'top') {\n top -= height;\n eAttachment.top = 'bottom';\n } else if (top < bounds[1] && eAttachment.top === 'bottom') {\n top += height;\n eAttachment.top = 'top';\n }\n }\n }\n\n if (changeAttachX === 'target' || changeAttachX === 'both') {\n if (left < bounds[0] && tAttachment.left === 'left') {\n left += targetWidth;\n tAttachment.left = 'right';\n }\n\n if (left + width > bounds[2] && tAttachment.left === 'right') {\n left -= targetWidth;\n tAttachment.left = 'left';\n }\n }\n\n if (changeAttachX === 'together') {\n if (left < bounds[0] && tAttachment.left === 'left') {\n if (eAttachment.left === 'right') {\n left += targetWidth;\n tAttachment.left = 'right';\n\n left += width;\n eAttachment.left = 'left';\n } else if (eAttachment.left === 'left') {\n left += targetWidth;\n tAttachment.left = 'right';\n\n left -= width;\n eAttachment.left = 'right';\n }\n } else if (left + width > bounds[2] && tAttachment.left === 'right') {\n if (eAttachment.left === 'left') {\n left -= targetWidth;\n tAttachment.left = 'left';\n\n left -= width;\n eAttachment.left = 'right';\n } else if (eAttachment.left === 'right') {\n left -= targetWidth;\n tAttachment.left = 'left';\n\n left += width;\n eAttachment.left = 'left';\n }\n } else if (tAttachment.left === 'center') {\n if (left + width > bounds[2] && eAttachment.left === 'left') {\n left -= width;\n eAttachment.left = 'right';\n } else if (left < bounds[0] && eAttachment.left === 'right') {\n left += width;\n eAttachment.left = 'left';\n }\n }\n }\n\n if (changeAttachY === 'element' || changeAttachY === 'both') {\n if (top < bounds[1] && eAttachment.top === 'bottom') {\n top += height;\n eAttachment.top = 'top';\n }\n\n if (top + height > bounds[3] && eAttachment.top === 'top') {\n top -= height;\n eAttachment.top = 'bottom';\n }\n }\n\n if (changeAttachX === 'element' || changeAttachX === 'both') {\n if (left < bounds[0]) {\n if (eAttachment.left === 'right') {\n left += width;\n eAttachment.left = 'left';\n } else if (eAttachment.left === 'center') {\n left += width / 2;\n eAttachment.left = 'left';\n }\n }\n\n if (left + width > bounds[2]) {\n if (eAttachment.left === 'left') {\n left -= width;\n eAttachment.left = 'right';\n } else if (eAttachment.left === 'center') {\n left -= width / 2;\n eAttachment.left = 'right';\n }\n }\n }\n\n if (typeof pin === 'string') {\n pin = pin.split(',').map(function (p) {\n return p.trim();\n });\n } else if (pin === true) {\n pin = ['top', 'left', 'right', 'bottom'];\n }\n\n pin = pin || [];\n\n var pinned = [];\n var oob = [];\n\n if (top < bounds[1]) {\n if (pin.indexOf('top') >= 0) {\n top = bounds[1];\n pinned.push('top');\n } else {\n oob.push('top');\n }\n }\n\n if (top + height > bounds[3]) {\n if (pin.indexOf('bottom') >= 0) {\n top = bounds[3] - height;\n pinned.push('bottom');\n } else {\n oob.push('bottom');\n }\n }\n\n if (left < bounds[0]) {\n if (pin.indexOf('left') >= 0) {\n left = bounds[0];\n pinned.push('left');\n } else {\n oob.push('left');\n }\n }\n\n if (left + width > bounds[2]) {\n if (pin.indexOf('right') >= 0) {\n left = bounds[2] - width;\n pinned.push('right');\n } else {\n oob.push('right');\n }\n }\n\n if (pinned.length) {\n (function () {\n var pinnedClass = undefined;\n if (typeof _this.options.pinnedClass !== 'undefined') {\n pinnedClass = _this.options.pinnedClass;\n } else {\n pinnedClass = _this.getClass('pinned');\n }\n\n addClasses.push(pinnedClass);\n pinned.forEach(function (side) {\n addClasses.push(pinnedClass + '-' + side);\n });\n })();\n }\n\n if (oob.length) {\n (function () {\n var oobClass = undefined;\n if (typeof _this.options.outOfBoundsClass !== 'undefined') {\n oobClass = _this.options.outOfBoundsClass;\n } else {\n oobClass = _this.getClass('out-of-bounds');\n }\n\n addClasses.push(oobClass);\n oob.forEach(function (side) {\n addClasses.push(oobClass + '-' + side);\n });\n })();\n }\n\n if (pinned.indexOf('left') >= 0 || pinned.indexOf('right') >= 0) {\n eAttachment.left = tAttachment.left = false;\n }\n if (pinned.indexOf('top') >= 0 || pinned.indexOf('bottom') >= 0) {\n eAttachment.top = tAttachment.top = false;\n }\n\n if (tAttachment.top !== targetAttachment.top || tAttachment.left !== targetAttachment.left || eAttachment.top !== _this.attachment.top || eAttachment.left !== _this.attachment.left) {\n _this.updateAttachClasses(eAttachment, tAttachment);\n _this.trigger('update', {\n attachment: eAttachment,\n targetAttachment: tAttachment\n });\n }\n });\n\n defer(function () {\n if (!(_this.options.addTargetClasses === false)) {\n updateClasses(_this.target, addClasses, allClasses);\n }\n updateClasses(_this.element, addClasses, allClasses);\n });\n\n return { top: top, left: left };\n }\n});\n/* globals TetherBase */\n\n'use strict';\n\nvar _TetherBase$Utils = TetherBase.Utils;\nvar getBounds = _TetherBase$Utils.getBounds;\nvar updateClasses = _TetherBase$Utils.updateClasses;\nvar defer = _TetherBase$Utils.defer;\n\nTetherBase.modules.push({\n position: function position(_ref) {\n var _this = this;\n\n var top = _ref.top;\n var left = _ref.left;\n\n var _cache = this.cache('element-bounds', function () {\n return getBounds(_this.element);\n });\n\n var height = _cache.height;\n var width = _cache.width;\n\n var targetPos = this.getTargetBounds();\n\n var bottom = top + height;\n var right = left + width;\n\n var abutted = [];\n if (top <= targetPos.bottom && bottom >= targetPos.top) {\n ['left', 'right'].forEach(function (side) {\n var targetPosSide = targetPos[side];\n if (targetPosSide === left || targetPosSide === right) {\n abutted.push(side);\n }\n });\n }\n\n if (left <= targetPos.right && right >= targetPos.left) {\n ['top', 'bottom'].forEach(function (side) {\n var targetPosSide = targetPos[side];\n if (targetPosSide === top || targetPosSide === bottom) {\n abutted.push(side);\n }\n });\n }\n\n var allClasses = [];\n var addClasses = [];\n\n var sides = ['left', 'top', 'right', 'bottom'];\n allClasses.push(this.getClass('abutted'));\n sides.forEach(function (side) {\n allClasses.push(_this.getClass('abutted') + '-' + side);\n });\n\n if (abutted.length) {\n addClasses.push(this.getClass('abutted'));\n }\n\n abutted.forEach(function (side) {\n addClasses.push(_this.getClass('abutted') + '-' + side);\n });\n\n defer(function () {\n if (!(_this.options.addTargetClasses === false)) {\n updateClasses(_this.target, addClasses, allClasses);\n }\n updateClasses(_this.element, addClasses, allClasses);\n });\n\n return true;\n }\n});\n/* globals TetherBase */\n\n'use strict';\n\nvar _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\nTetherBase.modules.push({\n position: function position(_ref) {\n var top = _ref.top;\n var left = _ref.left;\n\n if (!this.options.shift) {\n return;\n }\n\n var shift = this.options.shift;\n if (typeof this.options.shift === 'function') {\n shift = this.options.shift.call(this, { top: top, left: left });\n }\n\n var shiftTop = undefined,\n shiftLeft = undefined;\n if (typeof shift === 'string') {\n shift = shift.split(' ');\n shift[1] = shift[1] || shift[0];\n\n var _shift = shift;\n\n var _shift2 = _slicedToArray(_shift, 2);\n\n shiftTop = _shift2[0];\n shiftLeft = _shift2[1];\n\n shiftTop = parseFloat(shiftTop, 10);\n shiftLeft = parseFloat(shiftLeft, 10);\n } else {\n shiftTop = shift.top;\n shiftLeft = shift.left;\n }\n\n top += shiftTop;\n left += shiftLeft;\n\n return { top: top, left: left };\n }\n});\nreturn Tether;\n\n}));\n\n\n//# sourceURL=webpack:///../node_modules/tether/dist/js/tether.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "../node_modules/tinycolor2/tinycolor.js": |
|
/*!***********************************************!*\ |
|
!*** ../node_modules/tinycolor2/tinycolor.js ***! |
|
\***********************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
eval("var __WEBPACK_AMD_DEFINE_RESULT__;// TinyColor v1.4.1\n// https://github.com/bgrins/TinyColor\n// Brian Grinstead, MIT License\n\n(function(Math) {\n\nvar trimLeft = /^\\s+/,\n trimRight = /\\s+$/,\n tinyCounter = 0,\n mathRound = Math.round,\n mathMin = Math.min,\n mathMax = Math.max,\n mathRandom = Math.random;\n\nfunction tinycolor (color, opts) {\n\n color = (color) ? color : '';\n opts = opts || { };\n\n // If input is already a tinycolor, return itself\n if (color instanceof tinycolor) {\n return color;\n }\n // If we are called as a function, call using new instead\n if (!(this instanceof tinycolor)) {\n return new tinycolor(color, opts);\n }\n\n var rgb = inputToRGB(color);\n this._originalInput = color,\n this._r = rgb.r,\n this._g = rgb.g,\n this._b = rgb.b,\n this._a = rgb.a,\n this._roundA = mathRound(100*this._a) / 100,\n this._format = opts.format || rgb.format;\n this._gradientType = opts.gradientType;\n\n // Don't let the range of [0,255] come back in [0,1].\n // Potentially lose a little bit of precision here, but will fix issues where\n // .5 gets interpreted as half of the total, instead of half of 1\n // If it was supposed to be 128, this was already taken care of by `inputToRgb`\n if (this._r < 1) { this._r = mathRound(this._r); }\n if (this._g < 1) { this._g = mathRound(this._g); }\n if (this._b < 1) { this._b = mathRound(this._b); }\n\n this._ok = rgb.ok;\n this._tc_id = tinyCounter++;\n}\n\ntinycolor.prototype = {\n isDark: function() {\n return this.getBrightness() < 128;\n },\n isLight: function() {\n return !this.isDark();\n },\n isValid: function() {\n return this._ok;\n },\n getOriginalInput: function() {\n return this._originalInput;\n },\n getFormat: function() {\n return this._format;\n },\n getAlpha: function() {\n return this._a;\n },\n getBrightness: function() {\n //http://www.w3.org/TR/AERT#color-contrast\n var rgb = this.toRgb();\n return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;\n },\n getLuminance: function() {\n //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef\n var rgb = this.toRgb();\n var RsRGB, GsRGB, BsRGB, R, G, B;\n RsRGB = rgb.r/255;\n GsRGB = rgb.g/255;\n BsRGB = rgb.b/255;\n\n if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);}\n if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);}\n if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);}\n return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);\n },\n setAlpha: function(value) {\n this._a = boundAlpha(value);\n this._roundA = mathRound(100*this._a) / 100;\n return this;\n },\n toHsv: function() {\n var hsv = rgbToHsv(this._r, this._g, this._b);\n return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };\n },\n toHsvString: function() {\n var hsv = rgbToHsv(this._r, this._g, this._b);\n var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);\n return (this._a == 1) ?\n \"hsv(\" + h + \", \" + s + \"%, \" + v + \"%)\" :\n \"hsva(\" + h + \", \" + s + \"%, \" + v + \"%, \"+ this._roundA + \")\";\n },\n toHsl: function() {\n var hsl = rgbToHsl(this._r, this._g, this._b);\n return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };\n },\n toHslString: function() {\n var hsl = rgbToHsl(this._r, this._g, this._b);\n var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);\n return (this._a == 1) ?\n \"hsl(\" + h + \", \" + s + \"%, \" + l + \"%)\" :\n \"hsla(\" + h + \", \" + s + \"%, \" + l + \"%, \"+ this._roundA + \")\";\n },\n toHex: function(allow3Char) {\n return rgbToHex(this._r, this._g, this._b, allow3Char);\n },\n toHexString: function(allow3Char) {\n return '#' + this.toHex(allow3Char);\n },\n toHex8: function(allow4Char) {\n return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);\n },\n toHex8String: function(allow4Char) {\n return '#' + this.toHex8(allow4Char);\n },\n toRgb: function() {\n return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };\n },\n toRgbString: function() {\n return (this._a == 1) ?\n \"rgb(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \")\" :\n \"rgba(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \", \" + this._roundA + \")\";\n },\n toPercentageRgb: function() {\n return { r: mathRound(bound01(this._r, 255) * 100) + \"%\", g: mathRound(bound01(this._g, 255) * 100) + \"%\", b: mathRound(bound01(this._b, 255) * 100) + \"%\", a: this._a };\n },\n toPercentageRgbString: function() {\n return (this._a == 1) ?\n \"rgb(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%)\" :\n \"rgba(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%, \" + this._roundA + \")\";\n },\n toName: function() {\n if (this._a === 0) {\n return \"transparent\";\n }\n\n if (this._a < 1) {\n return false;\n }\n\n return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;\n },\n toFilter: function(secondColor) {\n var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a);\n var secondHex8String = hex8String;\n var gradientType = this._gradientType ? \"GradientType = 1, \" : \"\";\n\n if (secondColor) {\n var s = tinycolor(secondColor);\n secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a);\n }\n\n return \"progid:DXImageTransform.Microsoft.gradient(\"+gradientType+\"startColorstr=\"+hex8String+\",endColorstr=\"+secondHex8String+\")\";\n },\n toString: function(format) {\n var formatSet = !!format;\n format = format || this._format;\n\n var formattedString = false;\n var hasAlpha = this._a < 1 && this._a >= 0;\n var needsAlphaFormat = !formatSet && hasAlpha && (format === \"hex\" || format === \"hex6\" || format === \"hex3\" || format === \"hex4\" || format === \"hex8\" || format === \"name\");\n\n if (needsAlphaFormat) {\n // Special case for \"transparent\", all other non-alpha formats\n // will return rgba when there is transparency.\n if (format === \"name\" && this._a === 0) {\n return this.toName();\n }\n return this.toRgbString();\n }\n if (format === \"rgb\") {\n formattedString = this.toRgbString();\n }\n if (format === \"prgb\") {\n formattedString = this.toPercentageRgbString();\n }\n if (format === \"hex\" || format === \"hex6\") {\n formattedString = this.toHexString();\n }\n if (format === \"hex3\") {\n formattedString = this.toHexString(true);\n }\n if (format === \"hex4\") {\n formattedString = this.toHex8String(true);\n }\n if (format === \"hex8\") {\n formattedString = this.toHex8String();\n }\n if (format === \"name\") {\n formattedString = this.toName();\n }\n if (format === \"hsl\") {\n formattedString = this.toHslString();\n }\n if (format === \"hsv\") {\n formattedString = this.toHsvString();\n }\n\n return formattedString || this.toHexString();\n },\n clone: function() {\n return tinycolor(this.toString());\n },\n\n _applyModification: function(fn, args) {\n var color = fn.apply(null, [this].concat([].slice.call(args)));\n this._r = color._r;\n this._g = color._g;\n this._b = color._b;\n this.setAlpha(color._a);\n return this;\n },\n lighten: function() {\n return this._applyModification(lighten, arguments);\n },\n brighten: function() {\n return this._applyModification(brighten, arguments);\n },\n darken: function() {\n return this._applyModification(darken, arguments);\n },\n desaturate: function() {\n return this._applyModification(desaturate, arguments);\n },\n saturate: function() {\n return this._applyModification(saturate, arguments);\n },\n greyscale: function() {\n return this._applyModification(greyscale, arguments);\n },\n spin: function() {\n return this._applyModification(spin, arguments);\n },\n\n _applyCombination: function(fn, args) {\n return fn.apply(null, [this].concat([].slice.call(args)));\n },\n analogous: function() {\n return this._applyCombination(analogous, arguments);\n },\n complement: function() {\n return this._applyCombination(complement, arguments);\n },\n monochromatic: function() {\n return this._applyCombination(monochromatic, arguments);\n },\n splitcomplement: function() {\n return this._applyCombination(splitcomplement, arguments);\n },\n triad: function() {\n return this._applyCombination(triad, arguments);\n },\n tetrad: function() {\n return this._applyCombination(tetrad, arguments);\n }\n};\n\n// If input is an object, force 1 into \"1.0\" to handle ratios properly\n// String input requires \"1.0\" as input, so 1 will be treated as 1\ntinycolor.fromRatio = function(color, opts) {\n if (typeof color == \"object\") {\n var newColor = {};\n for (var i in color) {\n if (color.hasOwnProperty(i)) {\n if (i === \"a\") {\n newColor[i] = color[i];\n }\n else {\n newColor[i] = convertToPercentage(color[i]);\n }\n }\n }\n color = newColor;\n }\n\n return tinycolor(color, opts);\n};\n\n// Given a string or object, convert that input to RGB\n// Possible string inputs:\n//\n// \"red\"\n// \"#f00\" or \"f00\"\n// \"#ff0000\" or \"ff0000\"\n// \"#ff000000\" or \"ff000000\"\n// \"rgb 255 0 0\" or \"rgb (255, 0, 0)\"\n// \"rgb 1.0 0 0\" or \"rgb (1, 0, 0)\"\n// \"rgba (255, 0, 0, 1)\" or \"rgba 255, 0, 0, 1\"\n// \"rgba (1.0, 0, 0, 1)\" or \"rgba 1.0, 0, 0, 1\"\n// \"hsl(0, 100%, 50%)\" or \"hsl 0 100% 50%\"\n// \"hsla(0, 100%, 50%, 1)\" or \"hsla 0 100% 50%, 1\"\n// \"hsv(0, 100%, 100%)\" or \"hsv 0 100% 100%\"\n//\nfunction inputToRGB(color) {\n\n var rgb = { r: 0, g: 0, b: 0 };\n var a = 1;\n var s = null;\n var v = null;\n var l = null;\n var ok = false;\n var format = false;\n\n if (typeof color == \"string\") {\n color = stringInputToObject(color);\n }\n\n if (typeof color == \"object\") {\n if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {\n rgb = rgbToRgb(color.r, color.g, color.b);\n ok = true;\n format = String(color.r).substr(-1) === \"%\" ? \"prgb\" : \"rgb\";\n }\n else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {\n s = convertToPercentage(color.s);\n v = convertToPercentage(color.v);\n rgb = hsvToRgb(color.h, s, v);\n ok = true;\n format = \"hsv\";\n }\n else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {\n s = convertToPercentage(color.s);\n l = convertToPercentage(color.l);\n rgb = hslToRgb(color.h, s, l);\n ok = true;\n format = \"hsl\";\n }\n\n if (color.hasOwnProperty(\"a\")) {\n a = color.a;\n }\n }\n\n a = boundAlpha(a);\n\n return {\n ok: ok,\n format: color.format || format,\n r: mathMin(255, mathMax(rgb.r, 0)),\n g: mathMin(255, mathMax(rgb.g, 0)),\n b: mathMin(255, mathMax(rgb.b, 0)),\n a: a\n };\n}\n\n\n// Conversion Functions\n// --------------------\n\n// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:\n// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>\n\n// `rgbToRgb`\n// Handle bounds / percentage checking to conform to CSS color spec\n// <http://www.w3.org/TR/css3-color/>\n// *Assumes:* r, g, b in [0, 255] or [0, 1]\n// *Returns:* { r, g, b } in [0, 255]\nfunction rgbToRgb(r, g, b){\n return {\n r: bound01(r, 255) * 255,\n g: bound01(g, 255) * 255,\n b: bound01(b, 255) * 255\n };\n}\n\n// `rgbToHsl`\n// Converts an RGB color value to HSL.\n// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]\n// *Returns:* { h, s, l } in [0,1]\nfunction rgbToHsl(r, g, b) {\n\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, l = (max + min) / 2;\n\n if(max == min) {\n h = s = 0; // achromatic\n }\n else {\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n\n h /= 6;\n }\n\n return { h: h, s: s, l: l };\n}\n\n// `hslToRgb`\n// Converts an HSL color value to RGB.\n// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]\n// *Returns:* { r, g, b } in the set [0, 255]\nfunction hslToRgb(h, s, l) {\n var r, g, b;\n\n h = bound01(h, 360);\n s = bound01(s, 100);\n l = bound01(l, 100);\n\n function hue2rgb(p, q, t) {\n if(t < 0) t += 1;\n if(t > 1) t -= 1;\n if(t < 1/6) return p + (q - p) * 6 * t;\n if(t < 1/2) return q;\n if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n }\n\n if(s === 0) {\n r = g = b = l; // achromatic\n }\n else {\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n\n return { r: r * 255, g: g * 255, b: b * 255 };\n}\n\n// `rgbToHsv`\n// Converts an RGB color value to HSV\n// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]\n// *Returns:* { h, s, v } in [0,1]\nfunction rgbToHsv(r, g, b) {\n\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, v = max;\n\n var d = max - min;\n s = max === 0 ? 0 : d / max;\n\n if(max == min) {\n h = 0; // achromatic\n }\n else {\n switch(max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n return { h: h, s: s, v: v };\n}\n\n// `hsvToRgb`\n// Converts an HSV color value to RGB.\n// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]\n// *Returns:* { r, g, b } in the set [0, 255]\n function hsvToRgb(h, s, v) {\n\n h = bound01(h, 360) * 6;\n s = bound01(s, 100);\n v = bound01(v, 100);\n\n var i = Math.floor(h),\n f = h - i,\n p = v * (1 - s),\n q = v * (1 - f * s),\n t = v * (1 - (1 - f) * s),\n mod = i % 6,\n r = [v, q, p, p, t, v][mod],\n g = [t, v, v, q, p, p][mod],\n b = [p, p, t, v, v, q][mod];\n\n return { r: r * 255, g: g * 255, b: b * 255 };\n}\n\n// `rgbToHex`\n// Converts an RGB color to hex\n// Assumes r, g, and b are contained in the set [0, 255]\n// Returns a 3 or 6 character hex\nfunction rgbToHex(r, g, b, allow3Char) {\n\n var hex = [\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16))\n ];\n\n // Return a 3 character hex if possible\n if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {\n return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);\n }\n\n return hex.join(\"\");\n}\n\n// `rgbaToHex`\n// Converts an RGBA color plus alpha transparency to hex\n// Assumes r, g, b are contained in the set [0, 255] and\n// a in [0, 1]. Returns a 4 or 8 character rgba hex\nfunction rgbaToHex(r, g, b, a, allow4Char) {\n\n var hex = [\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16)),\n pad2(convertDecimalToHex(a))\n ];\n\n // Return a 4 character hex if possible\n if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {\n return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);\n }\n\n return hex.join(\"\");\n}\n\n// `rgbaToArgbHex`\n// Converts an RGBA color to an ARGB Hex8 string\n// Rarely used, but required for \"toFilter()\"\nfunction rgbaToArgbHex(r, g, b, a) {\n\n var hex = [\n pad2(convertDecimalToHex(a)),\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16))\n ];\n\n return hex.join(\"\");\n}\n\n// `equals`\n// Can be called with any tinycolor input\ntinycolor.equals = function (color1, color2) {\n if (!color1 || !color2) { return false; }\n return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();\n};\n\ntinycolor.random = function() {\n return tinycolor.fromRatio({\n r: mathRandom(),\n g: mathRandom(),\n b: mathRandom()\n });\n};\n\n\n// Modification Functions\n// ----------------------\n// Thanks to less.js for some of the basics here\n// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>\n\nfunction desaturate(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.s -= amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl);\n}\n\nfunction saturate(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.s += amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl);\n}\n\nfunction greyscale(color) {\n return tinycolor(color).desaturate(100);\n}\n\nfunction lighten (color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.l += amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl);\n}\n\nfunction brighten(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var rgb = tinycolor(color).toRgb();\n rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));\n rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));\n rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));\n return tinycolor(rgb);\n}\n\nfunction darken (color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.l -= amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl);\n}\n\n// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.\n// Values outside of this range will be wrapped into this range.\nfunction spin(color, amount) {\n var hsl = tinycolor(color).toHsl();\n var hue = (hsl.h + amount) % 360;\n hsl.h = hue < 0 ? 360 + hue : hue;\n return tinycolor(hsl);\n}\n\n// Combination Functions\n// ---------------------\n// Thanks to jQuery xColor for some of the ideas behind these\n// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>\n\nfunction complement(color) {\n var hsl = tinycolor(color).toHsl();\n hsl.h = (hsl.h + 180) % 360;\n return tinycolor(hsl);\n}\n\nfunction triad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })\n ];\n}\n\nfunction tetrad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })\n ];\n}\n\nfunction splitcomplement(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),\n tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})\n ];\n}\n\nfunction analogous(color, results, slices) {\n results = results || 6;\n slices = slices || 30;\n\n var hsl = tinycolor(color).toHsl();\n var part = 360 / slices;\n var ret = [tinycolor(color)];\n\n for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {\n hsl.h = (hsl.h + part) % 360;\n ret.push(tinycolor(hsl));\n }\n return ret;\n}\n\nfunction monochromatic(color, results) {\n results = results || 6;\n var hsv = tinycolor(color).toHsv();\n var h = hsv.h, s = hsv.s, v = hsv.v;\n var ret = [];\n var modification = 1 / results;\n\n while (results--) {\n ret.push(tinycolor({ h: h, s: s, v: v}));\n v = (v + modification) % 1;\n }\n\n return ret;\n}\n\n// Utility Functions\n// ---------------------\n\ntinycolor.mix = function(color1, color2, amount) {\n amount = (amount === 0) ? 0 : (amount || 50);\n\n var rgb1 = tinycolor(color1).toRgb();\n var rgb2 = tinycolor(color2).toRgb();\n\n var p = amount / 100;\n\n var rgba = {\n r: ((rgb2.r - rgb1.r) * p) + rgb1.r,\n g: ((rgb2.g - rgb1.g) * p) + rgb1.g,\n b: ((rgb2.b - rgb1.b) * p) + rgb1.b,\n a: ((rgb2.a - rgb1.a) * p) + rgb1.a\n };\n\n return tinycolor(rgba);\n};\n\n\n// Readability Functions\n// ---------------------\n// <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)\n\n// `contrast`\n// Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2)\ntinycolor.readability = function(color1, color2) {\n var c1 = tinycolor(color1);\n var c2 = tinycolor(color2);\n return (Math.max(c1.getLuminance(),c2.getLuminance())+0.05) / (Math.min(c1.getLuminance(),c2.getLuminance())+0.05);\n};\n\n// `isReadable`\n// Ensure that foreground and background color combinations meet WCAG2 guidelines.\n// The third argument is an optional Object.\n// the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA';\n// the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'.\n// If the entire object is absent, isReadable defaults to {level:\"AA\",size:\"small\"}.\n\n// *Example*\n// tinycolor.isReadable(\"#000\", \"#111\") => false\n// tinycolor.isReadable(\"#000\", \"#111\",{level:\"AA\",size:\"large\"}) => false\ntinycolor.isReadable = function(color1, color2, wcag2) {\n var readability = tinycolor.readability(color1, color2);\n var wcag2Parms, out;\n\n out = false;\n\n wcag2Parms = validateWCAG2Parms(wcag2);\n switch (wcag2Parms.level + wcag2Parms.size) {\n case \"AAsmall\":\n case \"AAAlarge\":\n out = readability >= 4.5;\n break;\n case \"AAlarge\":\n out = readability >= 3;\n break;\n case \"AAAsmall\":\n out = readability >= 7;\n break;\n }\n return out;\n\n};\n\n// `mostReadable`\n// Given a base color and a list of possible foreground or background\n// colors for that base, returns the most readable color.\n// Optionally returns Black or White if the most readable color is unreadable.\n// *Example*\n// tinycolor.mostReadable(tinycolor.mostReadable(\"#123\", [\"#124\", \"#125\"],{includeFallbackColors:false}).toHexString(); // \"#112255\"\n// tinycolor.mostReadable(tinycolor.mostReadable(\"#123\", [\"#124\", \"#125\"],{includeFallbackColors:true}).toHexString(); // \"#ffffff\"\n// tinycolor.mostReadable(\"#a8015a\", [\"#faf3f3\"],{includeFallbackColors:true,level:\"AAA\",size:\"large\"}).toHexString(); // \"#faf3f3\"\n// tinycolor.mostReadable(\"#a8015a\", [\"#faf3f3\"],{includeFallbackColors:true,level:\"AAA\",size:\"small\"}).toHexString(); // \"#ffffff\"\ntinycolor.mostReadable = function(baseColor, colorList, args) {\n var bestColor = null;\n var bestScore = 0;\n var readability;\n var includeFallbackColors, level, size ;\n args = args || {};\n includeFallbackColors = args.includeFallbackColors ;\n level = args.level;\n size = args.size;\n\n for (var i= 0; i < colorList.length ; i++) {\n readability = tinycolor.readability(baseColor, colorList[i]);\n if (readability > bestScore) {\n bestScore = readability;\n bestColor = tinycolor(colorList[i]);\n }\n }\n\n if (tinycolor.isReadable(baseColor, bestColor, {\"level\":level,\"size\":size}) || !includeFallbackColors) {\n return bestColor;\n }\n else {\n args.includeFallbackColors=false;\n return tinycolor.mostReadable(baseColor,[\"#fff\", \"#000\"],args);\n }\n};\n\n\n// Big List of Colors\n// ------------------\n// <http://www.w3.org/TR/css3-color/#svg-color>\nvar names = tinycolor.names = {\n aliceblue: \"f0f8ff\",\n antiquewhite: \"faebd7\",\n aqua: \"0ff\",\n aquamarine: \"7fffd4\",\n azure: \"f0ffff\",\n beige: \"f5f5dc\",\n bisque: \"ffe4c4\",\n black: \"000\",\n blanchedalmond: \"ffebcd\",\n blue: \"00f\",\n blueviolet: \"8a2be2\",\n brown: \"a52a2a\",\n burlywood: \"deb887\",\n burntsienna: \"ea7e5d\",\n cadetblue: \"5f9ea0\",\n chartreuse: \"7fff00\",\n chocolate: \"d2691e\",\n coral: \"ff7f50\",\n cornflowerblue: \"6495ed\",\n cornsilk: \"fff8dc\",\n crimson: \"dc143c\",\n cyan: \"0ff\",\n darkblue: \"00008b\",\n darkcyan: \"008b8b\",\n darkgoldenrod: \"b8860b\",\n darkgray: \"a9a9a9\",\n darkgreen: \"006400\",\n darkgrey: \"a9a9a9\",\n darkkhaki: \"bdb76b\",\n darkmagenta: \"8b008b\",\n darkolivegreen: \"556b2f\",\n darkorange: \"ff8c00\",\n darkorchid: \"9932cc\",\n darkred: \"8b0000\",\n darksalmon: \"e9967a\",\n darkseagreen: \"8fbc8f\",\n darkslateblue: \"483d8b\",\n darkslategray: \"2f4f4f\",\n darkslategrey: \"2f4f4f\",\n darkturquoise: \"00ced1\",\n darkviolet: \"9400d3\",\n deeppink: \"ff1493\",\n deepskyblue: \"00bfff\",\n dimgray: \"696969\",\n dimgrey: \"696969\",\n dodgerblue: \"1e90ff\",\n firebrick: \"b22222\",\n floralwhite: \"fffaf0\",\n forestgreen: \"228b22\",\n fuchsia: \"f0f\",\n gainsboro: \"dcdcdc\",\n ghostwhite: \"f8f8ff\",\n gold: \"ffd700\",\n goldenrod: \"daa520\",\n gray: \"808080\",\n green: \"008000\",\n greenyellow: \"adff2f\",\n grey: \"808080\",\n honeydew: \"f0fff0\",\n hotpink: \"ff69b4\",\n indianred: \"cd5c5c\",\n indigo: \"4b0082\",\n ivory: \"fffff0\",\n khaki: \"f0e68c\",\n lavender: \"e6e6fa\",\n lavenderblush: \"fff0f5\",\n lawngreen: \"7cfc00\",\n lemonchiffon: \"fffacd\",\n lightblue: \"add8e6\",\n lightcoral: \"f08080\",\n lightcyan: \"e0ffff\",\n lightgoldenrodyellow: \"fafad2\",\n lightgray: \"d3d3d3\",\n lightgreen: \"90ee90\",\n lightgrey: \"d3d3d3\",\n lightpink: \"ffb6c1\",\n lightsalmon: \"ffa07a\",\n lightseagreen: \"20b2aa\",\n lightskyblue: \"87cefa\",\n lightslategray: \"789\",\n lightslategrey: \"789\",\n lightsteelblue: \"b0c4de\",\n lightyellow: \"ffffe0\",\n lime: \"0f0\",\n limegreen: \"32cd32\",\n linen: \"faf0e6\",\n magenta: \"f0f\",\n maroon: \"800000\",\n mediumaquamarine: \"66cdaa\",\n mediumblue: \"0000cd\",\n mediumorchid: \"ba55d3\",\n mediumpurple: \"9370db\",\n mediumseagreen: \"3cb371\",\n mediumslateblue: \"7b68ee\",\n mediumspringgreen: \"00fa9a\",\n mediumturquoise: \"48d1cc\",\n mediumvioletred: \"c71585\",\n midnightblue: \"191970\",\n mintcream: \"f5fffa\",\n mistyrose: \"ffe4e1\",\n moccasin: \"ffe4b5\",\n navajowhite: \"ffdead\",\n navy: \"000080\",\n oldlace: \"fdf5e6\",\n olive: \"808000\",\n olivedrab: \"6b8e23\",\n orange: \"ffa500\",\n orangered: \"ff4500\",\n orchid: \"da70d6\",\n palegoldenrod: \"eee8aa\",\n palegreen: \"98fb98\",\n paleturquoise: \"afeeee\",\n palevioletred: \"db7093\",\n papayawhip: \"ffefd5\",\n peachpuff: \"ffdab9\",\n peru: \"cd853f\",\n pink: \"ffc0cb\",\n plum: \"dda0dd\",\n powderblue: \"b0e0e6\",\n purple: \"800080\",\n rebeccapurple: \"663399\",\n red: \"f00\",\n rosybrown: \"bc8f8f\",\n royalblue: \"4169e1\",\n saddlebrown: \"8b4513\",\n salmon: \"fa8072\",\n sandybrown: \"f4a460\",\n seagreen: \"2e8b57\",\n seashell: \"fff5ee\",\n sienna: \"a0522d\",\n silver: \"c0c0c0\",\n skyblue: \"87ceeb\",\n slateblue: \"6a5acd\",\n slategray: \"708090\",\n slategrey: \"708090\",\n snow: \"fffafa\",\n springgreen: \"00ff7f\",\n steelblue: \"4682b4\",\n tan: \"d2b48c\",\n teal: \"008080\",\n thistle: \"d8bfd8\",\n tomato: \"ff6347\",\n turquoise: \"40e0d0\",\n violet: \"ee82ee\",\n wheat: \"f5deb3\",\n white: \"fff\",\n whitesmoke: \"f5f5f5\",\n yellow: \"ff0\",\n yellowgreen: \"9acd32\"\n};\n\n// Make it easy to access colors via `hexNames[hex]`\nvar hexNames = tinycolor.hexNames = flip(names);\n\n\n// Utilities\n// ---------\n\n// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`\nfunction flip(o) {\n var flipped = { };\n for (var i in o) {\n if (o.hasOwnProperty(i)) {\n flipped[o[i]] = i;\n }\n }\n return flipped;\n}\n\n// Return a valid alpha value [0,1] with all invalid values being set to 1\nfunction boundAlpha(a) {\n a = parseFloat(a);\n\n if (isNaN(a) || a < 0 || a > 1) {\n a = 1;\n }\n\n return a;\n}\n\n// Take input from [0, n] and return it as [0, 1]\nfunction bound01(n, max) {\n if (isOnePointZero(n)) { n = \"100%\"; }\n\n var processPercent = isPercentage(n);\n n = mathMin(max, mathMax(0, parseFloat(n)));\n\n // Automatically convert percentage into number\n if (processPercent) {\n n = parseInt(n * max, 10) / 100;\n }\n\n // Handle floating point rounding errors\n if ((Math.abs(n - max) < 0.000001)) {\n return 1;\n }\n\n // Convert into [0, 1] range if it isn't already\n return (n % max) / parseFloat(max);\n}\n\n// Force a number between 0 and 1\nfunction clamp01(val) {\n return mathMin(1, mathMax(0, val));\n}\n\n// Parse a base-16 hex value into a base-10 integer\nfunction parseIntFromHex(val) {\n return parseInt(val, 16);\n}\n\n// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1\n// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>\nfunction isOnePointZero(n) {\n return typeof n == \"string\" && n.indexOf('.') != -1 && parseFloat(n) === 1;\n}\n\n// Check to see if string passed in is a percentage\nfunction isPercentage(n) {\n return typeof n === \"string\" && n.indexOf('%') != -1;\n}\n\n// Force a hex value to have 2 characters\nfunction pad2(c) {\n return c.length == 1 ? '0' + c : '' + c;\n}\n\n// Replace a decimal with it's percentage value\nfunction convertToPercentage(n) {\n if (n <= 1) {\n n = (n * 100) + \"%\";\n }\n\n return n;\n}\n\n// Converts a decimal to a hex value\nfunction convertDecimalToHex(d) {\n return Math.round(parseFloat(d) * 255).toString(16);\n}\n// Converts a hex value to a decimal\nfunction convertHexToDecimal(h) {\n return (parseIntFromHex(h) / 255);\n}\n\nvar matchers = (function() {\n\n // <http://www.w3.org/TR/css3-values/#integers>\n var CSS_INTEGER = \"[-\\\\+]?\\\\d+%?\";\n\n // <http://www.w3.org/TR/css3-values/#number-value>\n var CSS_NUMBER = \"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\";\n\n // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.\n var CSS_UNIT = \"(?:\" + CSS_NUMBER + \")|(?:\" + CSS_INTEGER + \")\";\n\n // Actual matching.\n // Parentheses and commas are optional, but not required.\n // Whitespace can take the place of commas or opening paren\n var PERMISSIVE_MATCH3 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n var PERMISSIVE_MATCH4 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n\n return {\n CSS_UNIT: new RegExp(CSS_UNIT),\n rgb: new RegExp(\"rgb\" + PERMISSIVE_MATCH3),\n rgba: new RegExp(\"rgba\" + PERMISSIVE_MATCH4),\n hsl: new RegExp(\"hsl\" + PERMISSIVE_MATCH3),\n hsla: new RegExp(\"hsla\" + PERMISSIVE_MATCH4),\n hsv: new RegExp(\"hsv\" + PERMISSIVE_MATCH3),\n hsva: new RegExp(\"hsva\" + PERMISSIVE_MATCH4),\n hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,\n hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n };\n})();\n\n// `isValidCSSUnit`\n// Take in a single string / number and check to see if it looks like a CSS unit\n// (see `matchers` above for definition).\nfunction isValidCSSUnit(color) {\n return !!matchers.CSS_UNIT.exec(color);\n}\n\n// `stringInputToObject`\n// Permissive string parsing. Take in a number of formats, and output an object\n// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`\nfunction stringInputToObject(color) {\n\n color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();\n var named = false;\n if (names[color]) {\n color = names[color];\n named = true;\n }\n else if (color == 'transparent') {\n return { r: 0, g: 0, b: 0, a: 0, format: \"name\" };\n }\n\n // Try to match string input using regular expressions.\n // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]\n // Just return an object and let the conversion functions handle that.\n // This way the result will be the same whether the tinycolor is initialized with string or object.\n var match;\n if ((match = matchers.rgb.exec(color))) {\n return { r: match[1], g: match[2], b: match[3] };\n }\n if ((match = matchers.rgba.exec(color))) {\n return { r: match[1], g: match[2], b: match[3], a: match[4] };\n }\n if ((match = matchers.hsl.exec(color))) {\n return { h: match[1], s: match[2], l: match[3] };\n }\n if ((match = matchers.hsla.exec(color))) {\n return { h: match[1], s: match[2], l: match[3], a: match[4] };\n }\n if ((match = matchers.hsv.exec(color))) {\n return { h: match[1], s: match[2], v: match[3] };\n }\n if ((match = matchers.hsva.exec(color))) {\n return { h: match[1], s: match[2], v: match[3], a: match[4] };\n }\n if ((match = matchers.hex8.exec(color))) {\n return {\n r: parseIntFromHex(match[1]),\n g: parseIntFromHex(match[2]),\n b: parseIntFromHex(match[3]),\n a: convertHexToDecimal(match[4]),\n format: named ? \"name\" : \"hex8\"\n };\n }\n if ((match = matchers.hex6.exec(color))) {\n return {\n r: parseIntFromHex(match[1]),\n g: parseIntFromHex(match[2]),\n b: parseIntFromHex(match[3]),\n format: named ? \"name\" : \"hex\"\n };\n }\n if ((match = matchers.hex4.exec(color))) {\n return {\n r: parseIntFromHex(match[1] + '' + match[1]),\n g: parseIntFromHex(match[2] + '' + match[2]),\n b: parseIntFromHex(match[3] + '' + match[3]),\n a: convertHexToDecimal(match[4] + '' + match[4]),\n format: named ? \"name\" : \"hex8\"\n };\n }\n if ((match = matchers.hex3.exec(color))) {\n return {\n r: parseIntFromHex(match[1] + '' + match[1]),\n g: parseIntFromHex(match[2] + '' + match[2]),\n b: parseIntFromHex(match[3] + '' + match[3]),\n format: named ? \"name\" : \"hex\"\n };\n }\n\n return false;\n}\n\nfunction validateWCAG2Parms(parms) {\n // return valid WCAG2 parms for isReadable.\n // If input parms are invalid, return {\"level\":\"AA\", \"size\":\"small\"}\n var level, size;\n parms = parms || {\"level\":\"AA\", \"size\":\"small\"};\n level = (parms.level || \"AA\").toUpperCase();\n size = (parms.size || \"small\").toLowerCase();\n if (level !== \"AA\" && level !== \"AAA\") {\n level = \"AA\";\n }\n if (size !== \"small\" && size !== \"large\") {\n size = \"small\";\n }\n return {\"level\":level, \"size\":size};\n}\n\n// Node: Export function\nif (typeof module !== \"undefined\" && module.exports) {\n module.exports = tinycolor;\n}\n// AMD/requirejs: Define the module\nelse if (true) {\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {return tinycolor;}).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n}\n// Browser: Expose to window\nelse {}\n\n})(Math);\n\n\n//# sourceURL=webpack:///../node_modules/tinycolor2/tinycolor.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./axes_editor.ts": |
|
/*!************************!*\ |
|
!*** ./axes_editor.ts ***! |
|
\************************/ |
|
/*! exports provided: AxesEditorCtrl, axesEditorComponent */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"AxesEditorCtrl\", function() { return AxesEditorCtrl; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"axesEditorComponent\", function() { return axesEditorComponent; });\n/* harmony import */ var grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! grafana/app/core/utils/kbn */ \"grafana/app/core/utils/kbn\");\n/* harmony import */ var grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_0__);\n\nvar AxesEditorCtrl = /** @class */ (function () {\n /** @ngInject **/\n function AxesEditorCtrl($scope, $q) {\n this.$scope = $scope;\n this.$q = $q;\n this.panelCtrl = $scope.ctrl;\n this.panel = this.panelCtrl.panel;\n this.$scope.ctrl = this;\n this.unitFormats = grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_0___default.a.getUnitFormats();\n this.logScales = {\n linear: 1,\n 'log (base 2)': 2,\n 'log (base 10)': 10,\n 'log (base 32)': 32,\n 'log (base 1024)': 1024,\n };\n this.xAxisModes = {\n Time: 'time',\n Series: 'series',\n Histogram: 'histogram',\n };\n this.xAxisStatOptions = [\n { text: 'Avg', value: 'avg' },\n { text: 'Min', value: 'min' },\n { text: 'Max', value: 'max' },\n { text: 'Total', value: 'total' },\n { text: 'Count', value: 'count' },\n { text: 'Current', value: 'current' },\n ];\n if (this.panel.xaxis.mode === 'custom') {\n if (!this.panel.xaxis.name) {\n this.panel.xaxis.name = 'specify field';\n }\n }\n }\n AxesEditorCtrl.prototype.setUnitFormat = function (axis, subItem) {\n axis.format = subItem.value;\n this.panelCtrl.render();\n };\n AxesEditorCtrl.prototype.render = function () {\n this.panelCtrl.render();\n };\n AxesEditorCtrl.prototype.xAxisModeChanged = function () {\n this.panelCtrl.processor.setPanelDefaultsForNewXAxisMode();\n this.panelCtrl.onDataReceived(this.panelCtrl.dataList);\n };\n AxesEditorCtrl.prototype.xAxisValueChanged = function () {\n this.panelCtrl.onDataReceived(this.panelCtrl.dataList);\n };\n AxesEditorCtrl.prototype.getDataFieldNames = function (onlyNumbers) {\n var props = this.panelCtrl.processor.getDataFieldNames(this.panelCtrl.dataList, onlyNumbers);\n var items = props.map(function (prop) {\n return { text: prop, value: prop };\n });\n return this.$q.when(items);\n };\n return AxesEditorCtrl;\n}());\n\n/** @ngInject **/\nfunction axesEditorComponent() {\n 'use strict';\n return {\n restrict: 'E',\n scope: true,\n templateUrl: 'public/plugins/corpglory-grafalys-graph-panel/partials/axes_editor.html',\n controller: AxesEditorCtrl,\n };\n}\n\n\n//# sourceURL=webpack:///./axes_editor.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./colors.ts": |
|
/*!*******************!*\ |
|
!*** ./colors.ts ***! |
|
\*******************/ |
|
/*! exports provided: PALETTE_ROWS, PALETTE_COLUMNS, DEFAULT_ANNOTATION_COLOR, OK_COLOR, ALERTING_COLOR, NO_DATA_COLOR, REGION_FILL_ALPHA, hexToHsl, hslToHex, default */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"PALETTE_ROWS\", function() { return PALETTE_ROWS; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"PALETTE_COLUMNS\", function() { return PALETTE_COLUMNS; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"DEFAULT_ANNOTATION_COLOR\", function() { return DEFAULT_ANNOTATION_COLOR; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"OK_COLOR\", function() { return OK_COLOR; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ALERTING_COLOR\", function() { return ALERTING_COLOR; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"NO_DATA_COLOR\", function() { return NO_DATA_COLOR; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"REGION_FILL_ALPHA\", function() { return REGION_FILL_ALPHA; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"hexToHsl\", function() { return hexToHsl; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"hslToHex\", function() { return hslToHex; });\n/* harmony import */ var tinycolor2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tinycolor2 */ \"../node_modules/tinycolor2/tinycolor.js\");\n/* harmony import */ var tinycolor2__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tinycolor2__WEBPACK_IMPORTED_MODULE_0__);\n\nvar PALETTE_ROWS = 4;\nvar PALETTE_COLUMNS = 14;\nvar DEFAULT_ANNOTATION_COLOR = 'rgba(0, 211, 255, 1)';\nvar OK_COLOR = 'rgba(11, 237, 50, 1)';\nvar ALERTING_COLOR = 'rgba(237, 46, 24, 1)';\nvar NO_DATA_COLOR = 'rgba(150, 150, 150, 1)';\nvar REGION_FILL_ALPHA = 0.09;\nvar colors = [\n '#7EB26D',\n '#EAB839',\n '#6ED0E0',\n '#EF843C',\n '#E24D42',\n '#1F78C1',\n '#BA43A9',\n '#705DA0',\n '#508642',\n '#CCA300',\n '#447EBC',\n '#C15C17',\n '#890F02',\n '#0A437C',\n '#6D1F62',\n '#584477',\n '#B7DBAB',\n '#F4D598',\n '#70DBED',\n '#F9BA8F',\n '#F29191',\n '#82B5D8',\n '#E5A8E2',\n '#AEA2E0',\n '#629E51',\n '#E5AC0E',\n '#64B0C8',\n '#E0752D',\n '#BF1B00',\n '#0A50A1',\n '#962D82',\n '#614D93',\n '#9AC48A',\n '#F2C96D',\n '#65C5DB',\n '#F9934E',\n '#EA6460',\n '#5195CE',\n '#D683CE',\n '#806EB7',\n '#3F6833',\n '#967302',\n '#2F575E',\n '#99440A',\n '#58140C',\n '#052B51',\n '#511749',\n '#3F2B5B',\n '#E0F9D7',\n '#FCEACA',\n '#CFFAFF',\n '#F9E2D2',\n '#FCE2DE',\n '#BADFF4',\n '#F9D9F9',\n '#DEDAF7',\n];\nfunction hexToHsl(color) {\n return tinycolor2__WEBPACK_IMPORTED_MODULE_0___default()(color).toHsl();\n}\nfunction hslToHex(color) {\n return tinycolor2__WEBPACK_IMPORTED_MODULE_0___default()(color).toHexString();\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (colors);\n\n\n//# sourceURL=webpack:///./colors.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./controllers/anomaly_controller.ts": |
|
/*!*******************************************!*\ |
|
!*** ./controllers/anomaly_controller.ts ***! |
|
\*******************************************/ |
|
/*! exports provided: REGION_FILL_ALPHA, REGION_STROKE_ALPHA, REGION_DELETE_COLOR_LIGHT, REGION_DELETE_COLOR_DARK, AnomalyController */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"REGION_FILL_ALPHA\", function() { return REGION_FILL_ALPHA; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"REGION_STROKE_ALPHA\", function() { return REGION_STROKE_ALPHA; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"REGION_DELETE_COLOR_LIGHT\", function() { return REGION_DELETE_COLOR_LIGHT; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"REGION_DELETE_COLOR_DARK\", function() { return REGION_DELETE_COLOR_DARK; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"AnomalyController\", function() { return AnomalyController; });\n/* harmony import */ var _model_anomaly__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../model/anomaly */ \"./model/anomaly.ts\");\n/* harmony import */ var _model_segment_array__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../model/segment_array */ \"./model/segment_array.ts\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_2__);\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (undefined && undefined.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [0, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\nvar __asyncValues = (undefined && undefined.__asyncValues) || function (o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator];\n return m ? m.call(o) : typeof __values === \"function\" ? __values(o) : o[Symbol.iterator]();\n};\n\n\n\nvar REGION_FILL_ALPHA = 0.7;\nvar REGION_STROKE_ALPHA = 0.9;\nvar REGION_DELETE_COLOR_LIGHT = '#d1d1d1';\nvar REGION_DELETE_COLOR_DARK = 'white';\nvar AnomalyController = /** @class */ (function () {\n function AnomalyController(_panelObject, _anomalyService, _emitter) {\n var _this = this;\n this._panelObject = _panelObject;\n this._anomalyService = _anomalyService;\n this._emitter = _emitter;\n this._selectedAnomalyKey = null;\n this._newAnomalyType = null;\n this._creatingNewAnomalyType = false;\n this._savingNewAnomalyType = false;\n this._tempIdCounted = -1;\n this._graphLocked = false;\n this._statusRunners = new Set();\n if (_panelObject.anomalyTypes === undefined) {\n _panelObject.anomalyTypes = [];\n }\n this._labelingDataAddedSegments = new _model_segment_array__WEBPACK_IMPORTED_MODULE_1__[\"SegmentArray\"]();\n this._labelingDataDeletedSegments = new _model_segment_array__WEBPACK_IMPORTED_MODULE_1__[\"SegmentArray\"]();\n this._anomalyTypesSet = new _model_anomaly__WEBPACK_IMPORTED_MODULE_0__[\"AnomalyTypesSet\"](this._panelObject.anomalyTypes);\n this.anomalyTypes.forEach(function (a) { return _this.runAnomalyTypeAlertEnabledWaiter(a); });\n }\n AnomalyController.prototype.getAnomalySegmentsSearcher = function () {\n return this._anomalySegmentsSearcher.bind(this);\n };\n AnomalyController.prototype._anomalySegmentsSearcher = function (point) {\n var result = [];\n this._anomalyTypesSet.anomalyTypes.forEach(function (at) {\n var segs = at.segments.findSegments(point);\n segs.forEach(function (s) {\n result.push({ anomalyType: at, segment: s });\n });\n });\n return result;\n };\n AnomalyController.prototype.createAnomalyType = function () {\n this._newAnomalyType = new _model_anomaly__WEBPACK_IMPORTED_MODULE_0__[\"AnomalyType\"]();\n this._creatingNewAnomalyType = true;\n this._savingNewAnomalyType = false;\n };\n AnomalyController.prototype.saveNewAnomalyType = function (metricExpanded, datasourceRequest, panelId) {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n this._savingNewAnomalyType = true;\n return [4 /*yield*/, this._anomalyService.postNewAnomalyType(metricExpanded, datasourceRequest, this._newAnomalyType, panelId)];\n case 1:\n _a.sent();\n this._anomalyTypesSet.addAnomalyType(this._newAnomalyType);\n this._creatingNewAnomalyType = false;\n this._savingNewAnomalyType = false;\n this.runAnomalyTypeAlertEnabledWaiter(this._newAnomalyType);\n this._runAnomalyTypeStatusWaiter(this._newAnomalyType);\n return [2 /*return*/];\n }\n });\n });\n };\n Object.defineProperty(AnomalyController.prototype, \"creatingAnomalyType\", {\n get: function () { return this._creatingNewAnomalyType; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyController.prototype, \"savingAnomalyType\", {\n get: function () { return this._savingNewAnomalyType; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyController.prototype, \"newAnomalyType\", {\n get: function () { return this._newAnomalyType; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyController.prototype, \"graphLocked\", {\n get: function () { return this._graphLocked; },\n set: function (value) {\n this._graphLocked = value;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyController.prototype, \"labelingAnomaly\", {\n get: function () {\n if (this._selectedAnomalyKey === null) {\n return null;\n }\n return this._anomalyTypesSet.byKey(this._selectedAnomalyKey);\n },\n enumerable: true,\n configurable: true\n });\n AnomalyController.prototype.toggleAnomalyTypeLabelingMode = function (key) {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (this.labelingAnomaly && this.labelingAnomaly.saving) {\n throw new Error('Can`t toggel during saving');\n }\n if (this._selectedAnomalyKey === key) {\n return [2 /*return*/, this.disableAnomalyLabeling()];\n }\n return [4 /*yield*/, this.disableAnomalyLabeling()];\n case 1:\n _a.sent();\n this._selectedAnomalyKey = key;\n this.labelingAnomaly.selected = true;\n this.toggleAnomalyVisibility(key, true);\n return [2 /*return*/];\n }\n });\n });\n };\n AnomalyController.prototype.disableAnomalyLabeling = function () {\n return __awaiter(this, void 0, void 0, function () {\n var _this = this;\n var newIds, anomaly;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (this._selectedAnomalyKey === null) {\n return [2 /*return*/];\n }\n this.labelingAnomaly.saving = true;\n return [4 /*yield*/, this._saveLabelingData()];\n case 1:\n newIds = _a.sent();\n this._labelingDataAddedSegments.getSegments().forEach(function (s, i) {\n _this.labelingAnomaly.segments.updateKey(s.key, newIds[i]);\n });\n this.labelingAnomaly.saving = false;\n anomaly = this.labelingAnomaly;\n this.dropLabeling();\n this._runAnomalyTypeStatusWaiter(anomaly);\n return [2 /*return*/];\n }\n });\n });\n };\n AnomalyController.prototype.undoLabeling = function () {\n var _this = this;\n this._labelingDataAddedSegments.getSegments().forEach(function (s) {\n _this.labelingAnomaly.segments.remove(s.key);\n });\n this._labelingDataDeletedSegments.getSegments().forEach(function (s) {\n _this.labelingAnomaly.segments.addSegment(s);\n });\n this.dropLabeling();\n };\n AnomalyController.prototype.dropLabeling = function () {\n this._labelingDataAddedSegments.clear();\n this._labelingDataDeletedSegments.clear();\n this.labelingAnomaly.selected = false;\n this._selectedAnomalyKey = null;\n this._tempIdCounted = -1;\n };\n Object.defineProperty(AnomalyController.prototype, \"labelingMode\", {\n get: function () {\n return this._selectedAnomalyKey !== null;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyController.prototype, \"labelingDeleteMode\", {\n get: function () {\n if (!this.labelingMode) {\n return false;\n }\n return this.labelingAnomaly.deleteMode;\n },\n enumerable: true,\n configurable: true\n });\n AnomalyController.prototype.addLabelSegment = function (segment) {\n var asegment = this.labelingAnomaly.addLabeledSegment(segment);\n this._labelingDataAddedSegments.addSegment(asegment);\n };\n Object.defineProperty(AnomalyController.prototype, \"anomalyTypes\", {\n get: function () {\n return this._anomalyTypesSet.anomalyTypes;\n },\n enumerable: true,\n configurable: true\n });\n AnomalyController.prototype.onAnomalyColorChange = function (key, value) {\n this._anomalyTypesSet.byKey(key).color = value;\n };\n AnomalyController.prototype.fetchAnomalyTypesStatuses = function () {\n var _this = this;\n this.anomalyTypes.forEach(function (a) { return _this._runAnomalyTypeStatusWaiter(a); });\n };\n AnomalyController.prototype.fetchAnomalyTypesSegments = function (from, to) {\n return __awaiter(this, void 0, void 0, function () {\n var _this = this;\n var tasks;\n return __generator(this, function (_a) {\n if (!lodash__WEBPACK_IMPORTED_MODULE_2___default.a.isNumber(from)) {\n throw new Error('from isn`t number');\n }\n if (!lodash__WEBPACK_IMPORTED_MODULE_2___default.a.isNumber(+to)) {\n throw new Error('to isn`t number');\n }\n tasks = this.anomalyTypes.map(function (a) { return _this.fetchSegments(a, from, to); });\n return [2 /*return*/, Promise.all(tasks)];\n });\n });\n };\n AnomalyController.prototype.fetchSegments = function (anomalyType, from, to) {\n return __awaiter(this, void 0, void 0, function () {\n var allSegmentsList, allSegmentsSet;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (!lodash__WEBPACK_IMPORTED_MODULE_2___default.a.isNumber(from)) {\n throw new Error('from isn`t number');\n }\n if (!lodash__WEBPACK_IMPORTED_MODULE_2___default.a.isNumber(+to)) {\n throw new Error('to isn`t number');\n }\n return [4 /*yield*/, this._anomalyService.getSegments(anomalyType.key, from, to)];\n case 1:\n allSegmentsList = _a.sent();\n allSegmentsSet = new _model_segment_array__WEBPACK_IMPORTED_MODULE_1__[\"SegmentArray\"](allSegmentsList);\n if (anomalyType.selected) {\n this._labelingDataAddedSegments.getSegments().forEach(function (s) { return allSegmentsSet.addSegment(s); });\n this._labelingDataDeletedSegments.getSegments().forEach(function (s) { return allSegmentsSet.remove(s.key); });\n }\n anomalyType.segments = allSegmentsSet;\n return [2 /*return*/];\n }\n });\n });\n };\n AnomalyController.prototype._saveLabelingData = function () {\n return __awaiter(this, void 0, void 0, function () {\n var anomaly;\n return __generator(this, function (_a) {\n anomaly = this.labelingAnomaly;\n if (anomaly === null) {\n throw new Error('anomaly is not selected');\n }\n if (this._labelingDataAddedSegments.length === 0 &&\n this._labelingDataDeletedSegments.length === 0) {\n return [2 /*return*/, []];\n }\n return [2 /*return*/, this._anomalyService.updateSegments(anomaly.key, this._labelingDataAddedSegments, this._labelingDataDeletedSegments)];\n });\n });\n };\n // TODO: move to renderer\n AnomalyController.prototype.updateFlotEvents = function (isEditMode, options) {\n if (options.grid.markings === undefined) {\n options.markings = [];\n }\n for (var i = 0; i < this.anomalyTypes.length; i++) {\n var anomalyType = this.anomalyTypes[i];\n var borderColor = addAlphaToRGB(anomalyType.color, REGION_STROKE_ALPHA);\n var fillColor = addAlphaToRGB(anomalyType.color, REGION_FILL_ALPHA);\n var segments = anomalyType.segments.getSegments();\n if (!anomalyType.visible) {\n continue;\n }\n if (isEditMode && this.labelingMode) {\n if (anomalyType.selected) {\n borderColor = addAlphaToRGB(borderColor, 0.7);\n fillColor = addAlphaToRGB(borderColor, 0.7);\n }\n else {\n continue;\n }\n }\n var rangeDist = +options.xaxis.max - +options.xaxis.min;\n segments.forEach(function (s) {\n var expanded = s.expandDist(rangeDist, 0.01);\n options.grid.markings.push({\n xaxis: { from: expanded.from, to: expanded.to },\n color: fillColor\n });\n options.grid.markings.push({\n xaxis: { from: expanded.from, to: expanded.from },\n color: borderColor\n });\n options.grid.markings.push({\n xaxis: { from: expanded.to, to: expanded.to },\n color: borderColor\n });\n });\n }\n };\n AnomalyController.prototype.deleteLabelingAnomalySegmentsInRange = function (from, to) {\n var _this = this;\n var allRemovedSegs = this.labelingAnomaly.removeSegmentsInRange(from, to);\n allRemovedSegs.forEach(function (s) {\n if (!_this._labelingDataAddedSegments.has(s.key)) {\n _this._labelingDataDeletedSegments.addSegment(s);\n }\n });\n this._labelingDataAddedSegments.removeInRange(from, to);\n };\n AnomalyController.prototype.toggleDeleteMode = function () {\n if (!this.labelingMode) {\n throw new Error('Cant enter delete mode is labeling mode disabled');\n }\n this.labelingAnomaly.deleteMode = !this.labelingAnomaly.deleteMode;\n };\n AnomalyController.prototype.removeAnomalyType = function (key) {\n if (key === this._selectedAnomalyKey) {\n this.dropLabeling();\n }\n this._anomalyTypesSet.removeAnomalyType(key);\n };\n AnomalyController.prototype._runAnomalyTypeStatusWaiter = function (anomalyType) {\n return __awaiter(this, void 0, void 0, function () {\n var statusGenerator, statusGenerator_1, statusGenerator_1_1, status_1, e_1_1, e_1, _a;\n return __generator(this, function (_b) {\n switch (_b.label) {\n case 0:\n if (anomalyType === undefined || anomalyType === null) {\n throw new Error('anomalyType not defined');\n }\n if (this._statusRunners.has(anomalyType.key)) {\n return [2 /*return*/];\n }\n this._statusRunners.add(anomalyType.key);\n statusGenerator = this._anomalyService.getAnomalyTypeStatusGenerator(anomalyType.key, 1000);\n _b.label = 1;\n case 1:\n _b.trys.push([1, 7, 8, 13]);\n statusGenerator_1 = __asyncValues(statusGenerator);\n _b.label = 2;\n case 2: return [4 /*yield*/, statusGenerator_1.next()];\n case 3:\n if (!(statusGenerator_1_1 = _b.sent(), !statusGenerator_1_1.done)) return [3 /*break*/, 6];\n return [4 /*yield*/, statusGenerator_1_1.value];\n case 4:\n status_1 = _b.sent();\n if (anomalyType.status !== status_1) {\n anomalyType.status = status_1;\n this._emitter.emit('anomaly-type-status-change', anomalyType);\n }\n if (!anomalyType.isActiveStatus) {\n return [3 /*break*/, 6];\n }\n _b.label = 5;\n case 5: return [3 /*break*/, 2];\n case 6: return [3 /*break*/, 13];\n case 7:\n e_1_1 = _b.sent();\n e_1 = { error: e_1_1 };\n return [3 /*break*/, 13];\n case 8:\n _b.trys.push([8, , 11, 12]);\n if (!(statusGenerator_1_1 && !statusGenerator_1_1.done && (_a = statusGenerator_1.return))) return [3 /*break*/, 10];\n return [4 /*yield*/, _a.call(statusGenerator_1)];\n case 9:\n _b.sent();\n _b.label = 10;\n case 10: return [3 /*break*/, 12];\n case 11:\n if (e_1) throw e_1.error;\n return [7 /*endfinally*/];\n case 12: return [7 /*endfinally*/];\n case 13:\n this._statusRunners.delete(anomalyType.key);\n return [2 /*return*/];\n }\n });\n });\n };\n AnomalyController.prototype.runAnomalyTypeAlertEnabledWaiter = function (anomalyType) {\n return __awaiter(this, void 0, void 0, function () {\n var enabled;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this._anomalyService.getAlertEnabled(anomalyType.key)];\n case 1:\n enabled = _a.sent();\n if (anomalyType.alertEnabled !== enabled) {\n anomalyType.alertEnabled = enabled;\n this._emitter.emit('anomaly-type-alert-change', anomalyType);\n }\n return [2 /*return*/];\n }\n });\n });\n };\n AnomalyController.prototype.toggleAnomalyTypeAlertEnabled = function (anomalyType) {\n return __awaiter(this, void 0, void 0, function () {\n var enabled;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n enabled = anomalyType.alertEnabled;\n anomalyType.alertEnabled = undefined;\n return [4 /*yield*/, this._anomalyService.setAlertEnabled(anomalyType.key, enabled)];\n case 1:\n _a.sent();\n anomalyType.alertEnabled = enabled;\n this._emitter.emit('anomaly-type-alert-change', anomalyType);\n return [2 /*return*/];\n }\n });\n });\n };\n AnomalyController.prototype.getIdForNewLabelSegment = function () {\n this._tempIdCounted--;\n return this._tempIdCounted;\n };\n AnomalyController.prototype.toggleAnomalyVisibility = function (key, value) {\n var anomaly = this._anomalyTypesSet.byKey(key);\n if (value !== undefined) {\n anomaly.visible = value;\n }\n else {\n anomaly.visible = !anomaly.visible;\n }\n };\n return AnomalyController;\n}());\n\nfunction addAlphaToRGB(colorString, alpha) {\n var color = tinycolor(colorString);\n if (color.isValid()) {\n color.setAlpha(color.getAlpha() * alpha);\n return color.toRgbString();\n }\n else {\n return colorString;\n }\n}\n\n\n//# sourceURL=webpack:///./controllers/anomaly_controller.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./data_processor.ts": |
|
/*!***************************!*\ |
|
!*** ./data_processor.ts ***! |
|
\***************************/ |
|
/*! exports provided: DataProcessor */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"DataProcessor\", function() { return DataProcessor; });\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var grafana_app_core_time_series2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! grafana/app/core/time_series2 */ \"grafana/app/core/time_series2\");\n/* harmony import */ var grafana_app_core_time_series2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_time_series2__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./colors */ \"./colors.ts\");\n\n\n\nvar DataProcessor = /** @class */ (function () {\n function DataProcessor(panel) {\n this.panel = panel;\n }\n DataProcessor.prototype.getSeriesList = function (options) {\n var _this = this;\n if (!options.dataList || options.dataList.length === 0) {\n return [];\n }\n // auto detect xaxis mode\n var firstItem;\n if (options.dataList && options.dataList.length > 0) {\n firstItem = options.dataList[0];\n var autoDetectMode = this.getAutoDetectXAxisMode(firstItem);\n if (this.panel.xaxis.mode !== autoDetectMode) {\n this.panel.xaxis.mode = autoDetectMode;\n this.setPanelDefaultsForNewXAxisMode();\n }\n }\n switch (this.panel.xaxis.mode) {\n case 'series':\n case 'time': {\n return options.dataList.map(function (item, index) {\n return _this.timeSeriesHandler(item, index, options);\n });\n }\n case 'histogram': {\n var histogramDataList = [\n {\n target: 'count',\n datapoints: lodash__WEBPACK_IMPORTED_MODULE_0___default.a.concat([], lodash__WEBPACK_IMPORTED_MODULE_0___default.a.flatten(lodash__WEBPACK_IMPORTED_MODULE_0___default.a.map(options.dataList, 'datapoints'))),\n },\n ];\n return histogramDataList.map(function (item, index) {\n return _this.timeSeriesHandler(item, index, options);\n });\n }\n case 'field': {\n return this.customHandler(firstItem);\n }\n }\n };\n DataProcessor.prototype.getAutoDetectXAxisMode = function (firstItem) {\n switch (firstItem.type) {\n case 'docs':\n return 'field';\n case 'table':\n return 'field';\n default: {\n if (this.panel.xaxis.mode === 'series') {\n return 'series';\n }\n if (this.panel.xaxis.mode === 'histogram') {\n return 'histogram';\n }\n return 'time';\n }\n }\n };\n DataProcessor.prototype.setPanelDefaultsForNewXAxisMode = function () {\n switch (this.panel.xaxis.mode) {\n case 'time': {\n this.panel.bars = false;\n this.panel.lines = true;\n this.panel.points = false;\n this.panel.legend.show = true;\n this.panel.tooltip.shared = true;\n this.panel.xaxis.values = [];\n break;\n }\n case 'series': {\n this.panel.bars = true;\n this.panel.lines = false;\n this.panel.points = false;\n this.panel.stack = false;\n this.panel.legend.show = false;\n this.panel.tooltip.shared = false;\n this.panel.xaxis.values = ['total'];\n break;\n }\n case 'histogram': {\n this.panel.bars = true;\n this.panel.lines = false;\n this.panel.points = false;\n this.panel.stack = false;\n this.panel.legend.show = false;\n this.panel.tooltip.shared = false;\n break;\n }\n }\n };\n DataProcessor.prototype.timeSeriesHandler = function (seriesData, index, options) {\n var datapoints = seriesData.datapoints || [];\n var alias = seriesData.target;\n var colorIndex = index % _colors__WEBPACK_IMPORTED_MODULE_2__[\"default\"].length;\n var color = seriesData.color || this.panel.aliasColors[alias] || _colors__WEBPACK_IMPORTED_MODULE_2__[\"default\"][colorIndex];\n var series = new grafana_app_core_time_series2__WEBPACK_IMPORTED_MODULE_1___default.a({\n datapoints: datapoints,\n alias: alias,\n color: color,\n unit: seriesData.unit,\n });\n if (datapoints && datapoints.length > 0) {\n var last = datapoints[datapoints.length - 1][1];\n var from = options.range.from;\n if (last - from < -10000) {\n series.isOutsideRange = true;\n }\n }\n return series;\n };\n DataProcessor.prototype.customHandler = function (dataItem) {\n var nameField = this.panel.xaxis.name;\n if (!nameField) {\n throw {\n message: 'No field name specified to use for x-axis, check your axes settings',\n };\n }\n return [];\n };\n DataProcessor.prototype.validateXAxisSeriesValue = function () {\n switch (this.panel.xaxis.mode) {\n case 'series': {\n if (this.panel.xaxis.values.length === 0) {\n this.panel.xaxis.values = ['total'];\n return;\n }\n var validOptions = this.getXAxisValueOptions({});\n var found = lodash__WEBPACK_IMPORTED_MODULE_0___default.a.find(validOptions, { value: this.panel.xaxis.values[0] });\n if (!found) {\n this.panel.xaxis.values = ['total'];\n }\n return;\n }\n }\n };\n DataProcessor.prototype.getDataFieldNames = function (dataList, onlyNumbers) {\n if (dataList.length === 0) {\n return [];\n }\n var fields = [];\n var firstItem = dataList[0];\n var fieldParts = [];\n function getPropertiesRecursive(obj) {\n lodash__WEBPACK_IMPORTED_MODULE_0___default.a.forEach(obj, function (value, key) {\n if (lodash__WEBPACK_IMPORTED_MODULE_0___default.a.isObject(value)) {\n fieldParts.push(key);\n getPropertiesRecursive(value);\n }\n else {\n if (!onlyNumbers || lodash__WEBPACK_IMPORTED_MODULE_0___default.a.isNumber(value)) {\n var field = fieldParts.concat(key).join('.');\n fields.push(field);\n }\n }\n });\n fieldParts.pop();\n }\n if (firstItem.type === 'docs') {\n if (firstItem.datapoints.length === 0) {\n return [];\n }\n getPropertiesRecursive(firstItem.datapoints[0]);\n }\n return fields;\n };\n DataProcessor.prototype.getXAxisValueOptions = function (options) {\n switch (this.panel.xaxis.mode) {\n case 'series': {\n return [\n { text: 'Avg', value: 'avg' },\n { text: 'Min', value: 'min' },\n { text: 'Max', value: 'max' },\n { text: 'Total', value: 'total' },\n { text: 'Count', value: 'count' },\n ];\n }\n }\n return [];\n };\n DataProcessor.prototype.pluckDeep = function (obj, property) {\n var propertyParts = property.split('.');\n var value = obj;\n for (var i = 0; i < propertyParts.length; ++i) {\n if (value[propertyParts[i]]) {\n value = value[propertyParts[i]];\n }\n else {\n return undefined;\n }\n }\n return value;\n };\n return DataProcessor;\n}());\n\n\n\n//# sourceURL=webpack:///./data_processor.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./graph_legend.ts": |
|
/*!*************************!*\ |
|
!*** ./graph_legend.ts ***! |
|
\*************************/ |
|
/*! exports provided: GraphLegend */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"GraphLegend\", function() { return GraphLegend; });\n/* harmony import */ var perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! perfect-scrollbar */ \"../node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\nvar GraphLegend = /** @class */ (function () {\n function GraphLegend($elem, popoverSrv, scope) {\n var _this = this;\n this.$elem = $elem;\n this.popoverSrv = popoverSrv;\n this.scope = scope;\n this.firstRender = true;\n this.ctrl = scope.ctrl;\n this.panel = this.ctrl.panel;\n scope.$on('$destroy', function () {\n if (_this.legendScrollbar) {\n _this.legendScrollbar.destroy();\n }\n });\n }\n GraphLegend.prototype.getSeriesIndexForElement = function (el) {\n return el.parents('[data-series-index]').data('series-index');\n };\n GraphLegend.prototype.openColorSelector = function (e) {\n var _this = this;\n // if we clicked inside poup container ignore click\n if (jquery__WEBPACK_IMPORTED_MODULE_1__(e.target).parents('.popover').length) {\n return;\n }\n var el = jquery__WEBPACK_IMPORTED_MODULE_1__(e.currentTarget).find('.fa-minus');\n var index = this.getSeriesIndexForElement(el);\n var series = this.seriesList[index];\n this.popoverSrv.show({\n element: el[0],\n position: 'bottom left',\n targetAttachment: 'top left',\n template: '<series-color-picker series=\"series\" onToggleAxis=\"toggleAxis\" onColorChange=\"colorSelected\"/>',\n openOn: 'hover',\n model: {\n series: series,\n toggleAxis: function () {\n _this.ctrl.toggleAxis(series);\n },\n colorSelected: function (color) {\n _this.ctrl.changeSeriesColor(series, color);\n },\n },\n });\n };\n GraphLegend.prototype.toggleSeries = function (e) {\n var el = jquery__WEBPACK_IMPORTED_MODULE_1__(e.currentTarget);\n var index = this.getSeriesIndexForElement(el);\n var seriesInfo = this.seriesList[index];\n var scrollPosition = this.$elem.find('tbody').scrollTop();\n this.ctrl.toggleSeries(seriesInfo, e);\n this.$elem.find('tbody').scrollTop(scrollPosition);\n };\n GraphLegend.prototype.sortLegend = function (e) {\n var el = jquery__WEBPACK_IMPORTED_MODULE_1__(e.currentTarget);\n var stat = el.data('stat');\n if (stat !== this.panel.legend.sort) {\n this.panel.legend.sortDesc = null;\n }\n // if already sort ascending, disable sorting\n if (this.panel.legend.sortDesc === false) {\n this.panel.legend.sort = null;\n this.panel.legend.sortDesc = null;\n this.ctrl.render();\n return;\n }\n this.panel.legend.sortDesc = !this.panel.legend.sortDesc;\n this.panel.legend.sort = stat;\n this.ctrl.render();\n };\n GraphLegend.prototype.getTableHeaderHtml = function (statName) {\n if (!this.panel.legend[statName]) {\n return '';\n }\n var html = '<th class=\"pointer\" data-stat=\"' + statName + '\">' + statName;\n if (this.panel.legend.sort === statName) {\n var cssClass = this.panel.legend.sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up';\n html += ' <span class=\"' + cssClass + '\"></span>';\n }\n return html + '</th>';\n };\n GraphLegend.prototype.render = function () {\n this.data = this.ctrl.seriesList;\n if (!this.ctrl.panel.legend.show) {\n this.$elem.empty();\n this.firstRender = true;\n return;\n }\n if (this.firstRender) {\n this.$elem.on('click', '.graph-legend-icon', this.openColorSelector.bind(this));\n this.$elem.on('click', '.graph-legend-alias', this.toggleSeries.bind(this));\n this.$elem.on('click', 'th', this.sortLegend.bind(this));\n this.firstRender = false;\n }\n this.seriesList = this.data;\n this.$elem.empty();\n // Set min-width if side style and there is a value, otherwise remove the CSS propery\n var width = this.panel.legend.rightSide && this.panel.legend.sideWidth ? this.panel.legend.sideWidth + 'px' : '';\n this.$elem.css('min-width', width);\n this.$elem.toggleClass('graph-legend-table', this.panel.legend.alignAsTable === true);\n var tableHeaderElem;\n if (this.panel.legend.alignAsTable) {\n var header = '<tr>';\n header += '<th colspan=\"2\" style=\"text-align:left\"></th>';\n if (this.panel.legend.values) {\n header += this.getTableHeaderHtml('min');\n header += this.getTableHeaderHtml('max');\n header += this.getTableHeaderHtml('avg');\n header += this.getTableHeaderHtml('current');\n header += this.getTableHeaderHtml('total');\n }\n header += '</tr>';\n tableHeaderElem = jquery__WEBPACK_IMPORTED_MODULE_1__(header);\n }\n if (this.panel.legend.sort) {\n this.seriesList = lodash__WEBPACK_IMPORTED_MODULE_2___default.a.sortBy(this.seriesList, function (series) {\n return series.stats[this.panel.legend.sort];\n });\n if (this.panel.legend.sortDesc) {\n this.seriesList = this.seriesList.reverse();\n }\n }\n // render first time for getting proper legend height\n if (!this.panel.legend.rightSide) {\n this.renderLegendElement(tableHeaderElem);\n this.$elem.empty();\n }\n this.renderLegendElement(tableHeaderElem);\n };\n GraphLegend.prototype.renderSeriesLegendElements = function () {\n var seriesElements = [];\n for (var i = 0; i < this.seriesList.length; i++) {\n var series = this.seriesList[i];\n if (series.hideFromLegend(this.panel.legend)) {\n continue;\n }\n var html = '<div class=\"graph-legend-series';\n if (series.yaxis === 2) {\n html += ' graph-legend-series--right-y';\n }\n if (this.ctrl.hiddenSeries[series.alias]) {\n html += ' graph-legend-series-hidden';\n }\n html += '\" data-series-index=\"' + i + '\">';\n html += '<div class=\"graph-legend-icon\">';\n html += '<i class=\"fa fa-minus pointer\" style=\"color:' + series.color + '\"></i>';\n html += '</div>';\n html +=\n '<a class=\"graph-legend-alias pointer\" title=\"' + series.aliasEscaped + '\">' + series.aliasEscaped + '</a>';\n if (this.panel.legend.values) {\n var avg = series.formatValue(series.stats.avg);\n var current = series.formatValue(series.stats.current);\n var min = series.formatValue(series.stats.min);\n var max = series.formatValue(series.stats.max);\n var total = series.formatValue(series.stats.total);\n if (this.panel.legend.min) {\n html += '<div class=\"graph-legend-value min\">' + min + '</div>';\n }\n if (this.panel.legend.max) {\n html += '<div class=\"graph-legend-value max\">' + max + '</div>';\n }\n if (this.panel.legend.avg) {\n html += '<div class=\"graph-legend-value avg\">' + avg + '</div>';\n }\n if (this.panel.legend.current) {\n html += '<div class=\"graph-legend-value current\">' + current + '</div>';\n }\n if (this.panel.legend.total) {\n html += '<div class=\"graph-legend-value total\">' + total + '</div>';\n }\n }\n html += '</div>';\n seriesElements.push(jquery__WEBPACK_IMPORTED_MODULE_1__(html));\n }\n return seriesElements;\n };\n GraphLegend.prototype.renderLegendElement = function (tableHeaderElem) {\n var seriesElements = this.renderSeriesLegendElements();\n if (this.panel.legend.alignAsTable) {\n var tbodyElem = jquery__WEBPACK_IMPORTED_MODULE_1__('<tbody></tbody>');\n tbodyElem.append(tableHeaderElem);\n tbodyElem.append(seriesElements);\n this.$elem.append(tbodyElem);\n }\n else {\n this.$elem.append(seriesElements);\n }\n if (!this.panel.legend.rightSide) {\n this.addScrollbar();\n }\n else {\n this.destroyScrollbar();\n }\n };\n GraphLegend.prototype.addScrollbar = function () {\n var scrollbarOptions = {\n // Number of pixels the content height can surpass the container height without enabling the scroll bar.\n scrollYMarginOffset: 2,\n suppressScrollX: true,\n };\n if (!this.legendScrollbar) {\n this.legendScrollbar = new perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0__[\"default\"](this.$elem[0], scrollbarOptions);\n }\n else {\n this.legendScrollbar.update();\n }\n };\n GraphLegend.prototype.destroyScrollbar = function () {\n if (this.legendScrollbar) {\n this.legendScrollbar.destroy();\n }\n };\n return GraphLegend;\n}());\n\n\n\n//# sourceURL=webpack:///./graph_legend.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./graph_renderer.ts": |
|
/*!***************************!*\ |
|
!*** ./graph_renderer.ts ***! |
|
\***************************/ |
|
/*! exports provided: GraphRenderer */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"GraphRenderer\", function() { return GraphRenderer; });\n/* harmony import */ var _model_segment__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./model/segment */ \"./model/segment.ts\");\n/* harmony import */ var _graph_tooltip__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./graph_tooltip */ \"./graph_tooltip.ts\");\n/* harmony import */ var _threshold_manager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./threshold_manager */ \"./threshold_manager.ts\");\n/* harmony import */ var _histogram__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./histogram */ \"./histogram.ts\");\n/* harmony import */ var _controllers_anomaly_controller__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controllers/anomaly_controller */ \"./controllers/anomaly_controller.ts\");\n/* harmony import */ var _vendor_flot_jquery_flot__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./vendor/flot/jquery.flot */ \"./vendor/flot/jquery.flot.js\");\n/* harmony import */ var _vendor_flot_jquery_flot__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _vendor_flot_jquery_flot_time__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.time */ \"./vendor/flot/jquery.flot.time.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_time__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_time__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _vendor_flot_jquery_flot_selection__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.selection */ \"./vendor/flot/jquery.flot.selection.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_selection__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_selection__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var _vendor_flot_jquery_flot_stack__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.stack */ \"./vendor/flot/jquery.flot.stack.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_stack__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_stack__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var _vendor_flot_jquery_flot_stackpercent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.stackpercent */ \"./vendor/flot/jquery.flot.stackpercent.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_stackpercent__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_stackpercent__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var _vendor_flot_jquery_flot_fillbelow__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.fillbelow */ \"./vendor/flot/jquery.flot.fillbelow.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_fillbelow__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_fillbelow__WEBPACK_IMPORTED_MODULE_10__);\n/* harmony import */ var _vendor_flot_jquery_flot_crosshair__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.crosshair */ \"./vendor/flot/jquery.flot.crosshair.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_crosshair__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_crosshair__WEBPACK_IMPORTED_MODULE_11__);\n/* harmony import */ var _vendor_flot_jquery_flot_dashes__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.dashes */ \"./vendor/flot/jquery.flot.dashes.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_dashes__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_dashes__WEBPACK_IMPORTED_MODULE_12__);\n/* harmony import */ var _vendor_flot_jquery_flot_events__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./vendor/flot/jquery.flot.events */ \"./vendor/flot/jquery.flot.events.js\");\n/* harmony import */ var _vendor_flot_jquery_flot_events__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot_events__WEBPACK_IMPORTED_MODULE_13__);\n/* harmony import */ var grafana_app_core_utils_ticks__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! grafana/app/core/utils/ticks */ \"grafana/app/core/utils/ticks\");\n/* harmony import */ var grafana_app_core_utils_ticks__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_utils_ticks__WEBPACK_IMPORTED_MODULE_14__);\n/* harmony import */ var grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! grafana/app/core/core */ \"grafana/app/core/core\");\n/* harmony import */ var grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15__);\n/* harmony import */ var grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! grafana/app/core/utils/kbn */ \"grafana/app/core/utils/kbn\");\n/* harmony import */ var grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_16__);\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_17__);\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_18__);\n/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! moment */ \"moment\");\n/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_19___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_19__);\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar COLOR_SELECTION = '#666';\nvar GraphRenderer = /** @class */ (function () {\n function GraphRenderer($elem, timeSrv, popoverSrv, contextSrv, scope) {\n var _this = this;\n // private eventManager;\n this.flotOptions = {};\n var self = this;\n this.$elem = $elem;\n this.ctrl = scope.ctrl;\n this.dashboard = this.ctrl.dashboard;\n this.panel = this.ctrl.panel;\n this.timeSrv = timeSrv;\n this.popoverSrv = popoverSrv;\n this.contextSrv = contextSrv;\n this.scope = scope;\n this._anomalyController = this.ctrl.anomalyController;\n if (this._anomalyController === undefined) {\n throw new Error('anomalyController is undefined');\n }\n this.annotations = [];\n this.panelWidth = 0;\n // this.eventManager = new EventManager(this.ctrl);\n this.flotOptions = {};\n this.thresholdManager = new _threshold_manager__WEBPACK_IMPORTED_MODULE_2__[\"ThresholdManager\"](this.ctrl);\n this.tooltip = new _graph_tooltip__WEBPACK_IMPORTED_MODULE_1__[\"GraphTooltip\"]($elem, this.dashboard, scope, function () { return _this.sortedSeries; }, this._anomalyController.getAnomalySegmentsSearcher());\n // panel events\n this.ctrl.events.on('panel-teardown', function () {\n _this.thresholdManager = null;\n if (_this.plot) {\n _this.plot.destroy();\n _this.plot = null;\n }\n });\n // global events\n grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15__[\"appEvents\"].on('graph-hover', this._onGraphHover.bind(this), scope);\n grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15__[\"appEvents\"].on('graph-hover-clear', this._onGraphHoverClear.bind(this), scope);\n $elem.bind('plotselected', function (event, selectionEvent) {\n if (_this.panel.xaxis.mode !== 'time') {\n // Skip if panel in histogram or series mode\n _this.plot.clearSelection();\n return;\n }\n if (_this._isAnomalyEvent(selectionEvent)) {\n _this.plot.clearSelection();\n var id = _this._anomalyController.getIdForNewLabelSegment();\n var segment = new _model_segment__WEBPACK_IMPORTED_MODULE_0__[\"Segment\"](id, Math.round(selectionEvent.xaxis.from), Math.round(selectionEvent.xaxis.to));\n if (_this._anomalyController.labelingDeleteMode) {\n _this._anomalyController.deleteLabelingAnomalySegmentsInRange(segment.from, segment.to);\n }\n else {\n _this._anomalyController.addLabelSegment(segment);\n }\n _this._renderPanel();\n return;\n }\n if ((selectionEvent.ctrlKey || selectionEvent.metaKey) && contextSrv.isEditor) {\n // Add annotation\n setTimeout(function () {\n // this.eventManager.updateTime(selectionEvent.xaxis);\n }, 100);\n }\n else {\n scope.$apply(function () {\n timeSrv.setTime({\n from: moment__WEBPACK_IMPORTED_MODULE_19___default.a.utc(selectionEvent.xaxis.from),\n to: moment__WEBPACK_IMPORTED_MODULE_19___default.a.utc(selectionEvent.xaxis.to),\n });\n });\n }\n });\n $elem.bind('plotclick', function (event, flotEvent, item) {\n if (_this.panel.xaxis.mode !== 'time') {\n // Skip if panel in histogram or series mode\n return;\n }\n if (_this._isAnomalyEvent(flotEvent)) {\n return;\n }\n if ((flotEvent.ctrlKey || flotEvent.metaKey) && contextSrv.isEditor) {\n // Skip if range selected (added in \"plotselected\" event handler)\n var isRangeSelection = flotEvent.x !== flotEvent.x1;\n if (!isRangeSelection) {\n setTimeout(function () {\n // this.eventManager.updateTime({ from: flotEvent.x, to: null });\n }, 100);\n }\n }\n });\n $elem.mouseleave(function () {\n if (_this.panel.tooltip.shared) {\n var plot = $elem.data().plot;\n if (plot) {\n _this.tooltip.clear(plot);\n }\n }\n grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15__[\"appEvents\"].emit('graph-hover-clear');\n });\n $elem.bind(\"plothover\", function (event, pos, item) {\n self.tooltip.show(pos, item);\n pos.panelRelY = (pos.pageY - $elem.offset().top) / $elem.height();\n self._graphMousePosition = _this.plot.p2c(pos);\n grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15__[\"appEvents\"].emit('graph-hover', { pos: pos, panel: _this.panel });\n });\n $elem.bind(\"plotclick\", function (event, pos, item) {\n grafana_app_core_core__WEBPACK_IMPORTED_MODULE_15__[\"appEvents\"].emit('graph-click', { pos: pos, panel: _this.panel, item: item });\n });\n $elem.mousedown(function (e) {\n _this._anomalyController.graphLocked = true;\n _this._chooseSelectionColor(e);\n });\n jquery__WEBPACK_IMPORTED_MODULE_17__(document).mouseup(function (e) {\n _this._anomalyController.graphLocked = false;\n });\n }\n GraphRenderer.prototype.render = function (renderData) {\n this.data = renderData || this.data;\n if (!this.data) {\n return;\n }\n this.annotations = this.ctrl.annotations || [];\n this._buildFlotPairs(this.data);\n updateLegendValues(this.data, this.panel);\n this._renderPanel();\n if (this.tooltip.visible) {\n var pos = this.plot.c2p(this._graphMousePosition);\n var canvasOffset = this.$elem.find('.flot-overlay').offset();\n this.tooltip.show(pos);\n this.plot.setCrosshair(pos);\n }\n };\n GraphRenderer.prototype._onGraphHover = function (evt) {\n if (!this.dashboard.sharedTooltipModeEnabled()) {\n return;\n }\n // ignore if we are the emitter\n if (!this.plot || evt.panel.id === this.panel.id || this.ctrl.otherPanelInFullscreenMode()) {\n return;\n }\n this._graphMousePosition = this.plot.p2c(evt.pos);\n this.tooltip.show(evt.pos);\n };\n GraphRenderer.prototype._onGraphHoverClear = function () {\n if (this.plot) {\n this.tooltip.clear(this.plot);\n }\n };\n GraphRenderer.prototype._shouldAbortRender = function () {\n if (!this.data) {\n return true;\n }\n if (this.panelWidth === 0) {\n return true;\n }\n return false;\n };\n GraphRenderer.prototype._drawHook = function (plot) {\n // add left axis labels\n if (this.panel.yaxes[0].label && this.panel.yaxes[0].show) {\n jquery__WEBPACK_IMPORTED_MODULE_17__(\"<div class='axisLabel left-yaxis-label flot-temp-elem'></div>\")\n .text(this.panel.yaxes[0].label)\n .appendTo(this.$elem);\n }\n // add right axis labels\n if (this.panel.yaxes[1].label && this.panel.yaxes[1].show) {\n jquery__WEBPACK_IMPORTED_MODULE_17__(\"<div class='axisLabel right-yaxis-label flot-temp-elem'></div>\")\n .text(this.panel.yaxes[1].label)\n .appendTo(this.$elem);\n }\n if (this.ctrl.dataWarning) {\n jquery__WEBPACK_IMPORTED_MODULE_17__(\"<div class=\\\"datapoints-warning flot-temp-elem\\\">\" + this.ctrl.dataWarning.title + \"</div>\").appendTo(this.$elem);\n }\n this.thresholdManager.draw(plot);\n };\n GraphRenderer.prototype._processOffsetHook = function (plot, gridMargin) {\n var left = this.panel.yaxes[0];\n var right = this.panel.yaxes[1];\n if (left.show && left.label) {\n gridMargin.left = 20;\n }\n if (right.show && right.label) {\n gridMargin.right = 20;\n }\n // apply y-axis min/max options\n var yaxis = plot.getYAxes();\n for (var i = 0; i < yaxis.length; i++) {\n var axis = yaxis[i];\n var panelOptions = this.panel.yaxes[i];\n axis.options.max = axis.options.max !== null ? axis.options.max : panelOptions.max;\n axis.options.min = axis.options.min !== null ? axis.options.min : panelOptions.min;\n }\n };\n // Series could have different timeSteps,\n // let's find the smallest one so that bars are correctly rendered.\n // In addition, only take series which are rendered as bars for this.\n GraphRenderer.prototype._getMinTimeStepOfSeries = function (data) {\n var min = Number.MAX_VALUE;\n for (var i = 0; i < data.length; i++) {\n if (!data[i].stats.timeStep) {\n continue;\n }\n if (this.panel.bars) {\n if (data[i].bars && data[i].bars.show === false) {\n continue;\n }\n }\n else {\n if (typeof data[i].bars === 'undefined' || typeof data[i].bars.show === 'undefined' || !data[i].bars.show) {\n continue;\n }\n }\n if (data[i].stats.timeStep < min) {\n min = data[i].stats.timeStep;\n }\n }\n return min;\n };\n // Function for rendering panel\n GraphRenderer.prototype._renderPanel = function () {\n this.panelWidth = this.$elem.width();\n if (this._shouldAbortRender()) {\n return;\n }\n // give space to alert editing\n this.thresholdManager.prepare(this.$elem, this.data);\n // un-check dashes if lines are unchecked\n this.panel.dashes = this.panel.lines ? this.panel.dashes : false;\n // Populate element\n this._buildFlotOptions(this.panel);\n this._prepareXAxis(this.panel);\n this._configureYAxisOptions(this.data);\n this.thresholdManager.addFlotOptions(this.flotOptions, this.panel);\n // this.eventManager.addFlotEvents(this.annotations, this.flotOptions);\n this._anomalyController.updateFlotEvents(this.contextSrv.isEditor, this.flotOptions);\n this.sortedSeries = this._sortSeries(this.data, this.panel);\n this._callPlot(true);\n };\n GraphRenderer.prototype._chooseSelectionColor = function (e) {\n var color = COLOR_SELECTION;\n var fillAlpha = 0.4;\n var strokeAlpha = 0.4;\n if (this._isAnomalyEvent(e)) {\n if (this._anomalyController.labelingDeleteMode) {\n color = this.contextSrv.user.lightTheme ?\n _controllers_anomaly_controller__WEBPACK_IMPORTED_MODULE_4__[\"REGION_DELETE_COLOR_LIGHT\"] :\n _controllers_anomaly_controller__WEBPACK_IMPORTED_MODULE_4__[\"REGION_DELETE_COLOR_DARK\"];\n }\n else {\n color = this._anomalyController.labelingAnomaly.color;\n }\n fillAlpha = _controllers_anomaly_controller__WEBPACK_IMPORTED_MODULE_4__[\"REGION_FILL_ALPHA\"];\n strokeAlpha = _controllers_anomaly_controller__WEBPACK_IMPORTED_MODULE_4__[\"REGION_STROKE_ALPHA\"];\n }\n this.plot.getOptions().selection.color = color;\n };\n GraphRenderer.prototype._buildFlotPairs = function (data) {\n for (var i = 0; i < data.length; i++) {\n var series = data[i];\n series.data = series.getFlotPairs(series.nullPointMode || this.panel.nullPointMode);\n // if hidden remove points and disable stack\n if (this.ctrl.hiddenSeries[series.alias]) {\n series.data = [];\n series.stack = false;\n }\n }\n };\n GraphRenderer.prototype._prepareXAxis = function (panel) {\n switch (panel.xaxis.mode) {\n case 'series': {\n this.flotOptions.series.bars.barWidth = 0.7;\n this.flotOptions.series.bars.align = 'center';\n for (var i = 0; i < this.data.length; i++) {\n var series = this.data[i];\n series.data = [[i + 1, series.stats[panel.xaxis.values[0]]]];\n }\n this._addXSeriesAxis();\n break;\n }\n case 'histogram': {\n var bucketSize = void 0;\n var values = Object(_histogram__WEBPACK_IMPORTED_MODULE_3__[\"getSeriesValues\"])(this.data);\n if (this.data.length && values.length) {\n var histMin = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.min(lodash__WEBPACK_IMPORTED_MODULE_18___default.a.map(this.data, function (s) { return s.stats.min; }));\n var histMax = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.max(lodash__WEBPACK_IMPORTED_MODULE_18___default.a.map(this.data, function (s) { return s.stats.max; }));\n var ticks = panel.xaxis.buckets || this.panelWidth / 50;\n bucketSize = Object(grafana_app_core_utils_ticks__WEBPACK_IMPORTED_MODULE_14__[\"tickStep\"])(histMin, histMax, ticks);\n var histogram = Object(_histogram__WEBPACK_IMPORTED_MODULE_3__[\"convertValuesToHistogram\"])(values, bucketSize);\n this.data[0].data = histogram;\n this.flotOptions.series.bars.barWidth = bucketSize * 0.8;\n }\n else {\n bucketSize = 0;\n }\n this._addXHistogramAxis(bucketSize);\n break;\n }\n case 'table': {\n this.flotOptions.series.bars.barWidth = 0.7;\n this.flotOptions.series.bars.align = 'center';\n this._addXTableAxis();\n break;\n }\n default: {\n this.flotOptions.series.bars.barWidth = this._getMinTimeStepOfSeries(this.data) / 1.5;\n this._addTimeAxis();\n break;\n }\n }\n };\n GraphRenderer.prototype._callPlot = function (incrementRenderCounter) {\n try {\n this.plot = jquery__WEBPACK_IMPORTED_MODULE_17__[\"plot\"](this.$elem, this.sortedSeries, this.flotOptions);\n if (this.ctrl.renderError) {\n delete this.ctrl.error;\n delete this.ctrl.inspector;\n }\n }\n catch (e) {\n console.log('flotcharts error', e);\n this.ctrl.error = e.message || 'Render Error';\n this.ctrl.renderError = true;\n this.ctrl.inspector = { error: e };\n }\n if (incrementRenderCounter) {\n this.ctrl.renderingCompleted();\n }\n };\n GraphRenderer.prototype._buildFlotOptions = function (panel) {\n var stack = panel.stack ? true : null;\n this.flotOptions = {\n hooks: {\n draw: [this._drawHook.bind(this)],\n processOffset: [this._processOffsetHook.bind(this)],\n },\n legend: { show: false },\n series: {\n stackpercent: panel.stack ? panel.percentage : false,\n stack: panel.percentage ? null : stack,\n lines: {\n show: panel.lines,\n zero: false,\n fill: this._translateFillOption(panel.fill),\n lineWidth: panel.dashes ? 0 : panel.linewidth,\n steps: panel.steppedLine,\n },\n dashes: {\n show: panel.dashes,\n lineWidth: panel.linewidth,\n dashLength: [panel.dashLength, panel.spaceLength],\n },\n bars: {\n show: panel.bars,\n fill: 1,\n barWidth: 1,\n zero: false,\n lineWidth: 0,\n },\n points: {\n show: panel.points,\n fill: 1,\n fillColor: false,\n radius: panel.points ? panel.pointradius : 2,\n },\n shadowSize: 0,\n },\n yaxes: [],\n xaxis: {},\n grid: {\n minBorderMargin: 0,\n markings: [],\n backgroundColor: null,\n borderWidth: 0,\n hoverable: true,\n clickable: true,\n color: '#c8c8c8',\n margin: { left: 0, right: 0 },\n labelMarginX: 0,\n },\n selection: {\n mode: 'x'\n },\n crosshair: {\n mode: 'x',\n },\n };\n };\n GraphRenderer.prototype._sortSeries = function (series, panel) {\n var sortBy = panel.legend.sort;\n var sortOrder = panel.legend.sortDesc;\n var haveSortBy = sortBy !== null || sortBy !== undefined;\n var haveSortOrder = sortOrder !== null || sortOrder !== undefined;\n var shouldSortBy = panel.stack && haveSortBy && haveSortOrder;\n var sortDesc = panel.legend.sortDesc === true ? -1 : 1;\n series.sort(function (x, y) {\n if (x.zindex > y.zindex) {\n return 1;\n }\n if (x.zindex < y.zindex) {\n return -1;\n }\n if (shouldSortBy) {\n if (x.stats[sortBy] > y.stats[sortBy]) {\n return 1 * sortDesc;\n }\n if (x.stats[sortBy] < y.stats[sortBy]) {\n return -1 * sortDesc;\n }\n }\n return 0;\n });\n return series;\n };\n GraphRenderer.prototype._translateFillOption = function (fill) {\n if (this.panel.percentage && this.panel.stack) {\n return fill === 0 ? 0.001 : fill / 10;\n }\n else {\n return fill / 10;\n }\n };\n GraphRenderer.prototype._addTimeAxis = function () {\n var ticks = this.panelWidth / 100;\n var min = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.isUndefined(this.ctrl.range.from) ? null : this.ctrl.range.from.valueOf();\n var max = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.isUndefined(this.ctrl.range.to) ? null : this.ctrl.range.to.valueOf();\n this.flotOptions.xaxis = {\n timezone: this.dashboard.getTimezone(),\n show: this.panel.xaxis.show,\n mode: 'time',\n min: min,\n max: max,\n label: 'Datetime',\n ticks: ticks,\n timeformat: this._timeFormat(ticks, min, max),\n };\n };\n GraphRenderer.prototype._addXSeriesAxis = function () {\n var ticks = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.map(this.data, function (series, index) {\n return [index + 1, series.alias];\n });\n this.flotOptions.xaxis = {\n timezone: this.dashboard.getTimezone(),\n show: this.panel.xaxis.show,\n mode: null,\n min: 0,\n max: ticks.length + 1,\n label: 'Datetime',\n ticks: ticks,\n };\n };\n GraphRenderer.prototype._addXHistogramAxis = function (bucketSize) {\n var ticks, min, max;\n var defaultTicks = this.panelWidth / 50;\n if (this.data.length && bucketSize) {\n ticks = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.map(this.data[0].data, function (point) { return point[0]; });\n min = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.min(ticks);\n max = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.max(ticks);\n // Adjust tick step\n var tickStep_1 = bucketSize;\n var ticks_num = Math.floor((max - min) / tickStep_1);\n while (ticks_num > defaultTicks) {\n tickStep_1 = tickStep_1 * 2;\n ticks_num = Math.ceil((max - min) / tickStep_1);\n }\n // Expand ticks for pretty view\n min = Math.floor(min / tickStep_1) * tickStep_1;\n max = Math.ceil(max / tickStep_1) * tickStep_1;\n ticks = [];\n for (var i = min; i <= max; i += tickStep_1) {\n ticks.push(i);\n }\n }\n else {\n // Set defaults if no data\n ticks = defaultTicks / 2;\n min = 0;\n max = 1;\n }\n this.flotOptions.xaxis = {\n timezone: this.dashboard.getTimezone(),\n show: this.panel.xaxis.show,\n mode: null,\n min: min,\n max: max,\n label: 'Histogram',\n ticks: ticks,\n };\n // Use 'short' format for histogram values\n this._configureAxisMode(this.flotOptions.xaxis, 'short');\n };\n GraphRenderer.prototype._addXTableAxis = function () {\n var ticks = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.map(this.data, function (series, seriesIndex) {\n return lodash__WEBPACK_IMPORTED_MODULE_18___default.a.map(series.datapoints, function (point, pointIndex) {\n var tickIndex = seriesIndex * series.datapoints.length + pointIndex;\n return [tickIndex + 1, point[1]];\n });\n });\n ticks = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.flatten(ticks, true);\n this.flotOptions.xaxis = {\n timezone: this.dashboard.getTimezone(),\n show: this.panel.xaxis.show,\n mode: null,\n min: 0,\n max: ticks.length + 1,\n label: 'Datetime',\n ticks: ticks,\n };\n };\n GraphRenderer.prototype._configureYAxisOptions = function (data) {\n var defaults = {\n position: 'left',\n show: this.panel.yaxes[0].show,\n index: 1,\n logBase: this.panel.yaxes[0].logBase || 1,\n min: this._parseNumber(this.panel.yaxes[0].min),\n max: this._parseNumber(this.panel.yaxes[0].max),\n tickDecimals: this.panel.yaxes[0].decimals,\n };\n this.flotOptions.yaxes.push(defaults);\n if (lodash__WEBPACK_IMPORTED_MODULE_18___default.a.find(data, { yaxis: 2 })) {\n var secondY = lodash__WEBPACK_IMPORTED_MODULE_18___default.a.clone(defaults);\n secondY.index = 2;\n secondY.show = this.panel.yaxes[1].show;\n secondY.logBase = this.panel.yaxes[1].logBase || 1;\n secondY.position = 'right';\n secondY.min = this._parseNumber(this.panel.yaxes[1].min);\n secondY.max = this._parseNumber(this.panel.yaxes[1].max);\n secondY.tickDecimals = this.panel.yaxes[1].decimals;\n this.flotOptions.yaxes.push(secondY);\n this._applyLogScale(this.flotOptions.yaxes[1], data);\n this._configureAxisMode(this.flotOptions.yaxes[1], this.panel.percentage && this.panel.stack ? 'percent' : this.panel.yaxes[1].format);\n }\n this._applyLogScale(this.flotOptions.yaxes[0], data);\n this._configureAxisMode(this.flotOptions.yaxes[0], this.panel.percentage && this.panel.stack ? 'percent' : this.panel.yaxes[0].format);\n };\n GraphRenderer.prototype._parseNumber = function (value) {\n if (value === null || typeof value === 'undefined') {\n return null;\n }\n return lodash__WEBPACK_IMPORTED_MODULE_18___default.a.toNumber(value);\n };\n GraphRenderer.prototype._applyLogScale = function (axis, data) {\n if (axis.logBase === 1) {\n return;\n }\n var minSetToZero = axis.min === 0;\n if (axis.min < Number.MIN_VALUE) {\n axis.min = null;\n }\n if (axis.max < Number.MIN_VALUE) {\n axis.max = null;\n }\n var series, i;\n var max = axis.max, min = axis.min;\n for (i = 0; i < data.length; i++) {\n series = data[i];\n if (series.yaxis === axis.index) {\n if (!max || max < series.stats.max) {\n max = series.stats.max;\n }\n if (!min || min > series.stats.logmin) {\n min = series.stats.logmin;\n }\n }\n }\n axis.transform = function (v) {\n return v < Number.MIN_VALUE ? null : Math.log(v) / Math.log(axis.logBase);\n };\n axis.inverseTransform = function (v) {\n return Math.pow(axis.logBase, v);\n };\n if (!max && !min) {\n max = axis.inverseTransform(+2);\n min = axis.inverseTransform(-2);\n }\n else if (!max) {\n max = min * axis.inverseTransform(+4);\n }\n else if (!min) {\n min = max * axis.inverseTransform(-4);\n }\n if (axis.min) {\n min = axis.inverseTransform(Math.ceil(axis.transform(axis.min)));\n }\n else {\n min = axis.min = axis.inverseTransform(Math.floor(axis.transform(min)));\n }\n if (axis.max) {\n max = axis.inverseTransform(Math.floor(axis.transform(axis.max)));\n }\n else {\n max = axis.max = axis.inverseTransform(Math.ceil(axis.transform(max)));\n }\n if (!min || min < Number.MIN_VALUE || !max || max < Number.MIN_VALUE) {\n return;\n }\n if (Number.isFinite(min) && Number.isFinite(max)) {\n if (minSetToZero) {\n axis.min = 0.1;\n min = 1;\n }\n axis.ticks = this._generateTicksForLogScaleYAxis(min, max, axis.logBase);\n if (minSetToZero) {\n axis.ticks.unshift(0.1);\n }\n if (axis.ticks[axis.ticks.length - 1] > axis.max) {\n axis.max = axis.ticks[axis.ticks.length - 1];\n }\n }\n else {\n axis.ticks = [1, 2];\n delete axis.min;\n delete axis.max;\n }\n };\n GraphRenderer.prototype._generateTicksForLogScaleYAxis = function (min, max, logBase) {\n var ticks = [];\n var nextTick;\n for (nextTick = min; nextTick <= max; nextTick *= logBase) {\n ticks.push(nextTick);\n }\n var maxNumTicks = Math.ceil(this.ctrl.height / 25);\n var numTicks = ticks.length;\n if (numTicks > maxNumTicks) {\n var factor = Math.ceil(numTicks / maxNumTicks) * logBase;\n ticks = [];\n for (nextTick = min; nextTick <= max * factor; nextTick *= factor) {\n ticks.push(nextTick);\n }\n }\n return ticks;\n };\n GraphRenderer.prototype._configureAxisMode = function (axis, format) {\n axis.tickFormatter = function (val, axis) {\n return grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_16___default.a.valueFormats[format](val, axis.tickDecimals, axis.scaledDecimals);\n };\n };\n GraphRenderer.prototype._timeFormat = function (ticks, min, max) {\n if (min && max && ticks) {\n var range = max - min;\n var secPerTick = range / ticks / 1000;\n var oneDay = 86400000;\n var oneYear = 31536000000;\n if (secPerTick <= 45) {\n return '%H:%M:%S';\n }\n if (secPerTick <= 7200 || range <= oneDay) {\n return '%H:%M';\n }\n if (secPerTick <= 80000) {\n return '%m/%d %H:%M';\n }\n if (secPerTick <= 2419200 || range <= oneYear) {\n return '%m/%d';\n }\n return '%Y-%m';\n }\n return '%H:%M';\n };\n GraphRenderer.prototype._isAnomalyEvent = function (obj) {\n return (obj.ctrlKey || obj.metaKey) &&\n this.contextSrv.isEditor &&\n this._anomalyController.labelingMode;\n };\n return GraphRenderer;\n}());\n\nfunction updateLegendValues(data, panel) {\n for (var i = 0; i < data.length; i++) {\n var series = data[i];\n var yaxes = panel.yaxes;\n var seriesYAxis = series.yaxis || 1;\n var axis = yaxes[seriesYAxis - 1];\n var _a = Object(grafana_app_core_utils_ticks__WEBPACK_IMPORTED_MODULE_14__[\"getFlotTickDecimals\"])(data, axis), tickDecimals = _a.tickDecimals, scaledDecimals = _a.scaledDecimals;\n var formater = grafana_app_core_utils_kbn__WEBPACK_IMPORTED_MODULE_16___default.a.valueFormats[panel.yaxes[seriesYAxis - 1].format];\n // decimal override\n if (lodash__WEBPACK_IMPORTED_MODULE_18___default.a.isNumber(panel.decimals)) {\n series.updateLegendValues(formater, panel.decimals, null);\n }\n else {\n // auto decimals\n // legend and tooltip gets one more decimal precision\n // than graph legend ticks\n tickDecimals = (tickDecimals || -1) + 1;\n series.updateLegendValues(formater, tickDecimals, scaledDecimals + 2);\n }\n }\n}\n\n\n//# sourceURL=webpack:///./graph_renderer.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./graph_tooltip.ts": |
|
/*!**************************!*\ |
|
!*** ./graph_tooltip.ts ***! |
|
\**************************/ |
|
/*! exports provided: GraphTooltip */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"GraphTooltip\", function() { return GraphTooltip; });\nvar GraphTooltip = /** @class */ (function () {\n function GraphTooltip($elem, dashboard, scope, getSeriesFn, _anomalySegmentsSearcher) {\n this.$elem = $elem;\n this.dashboard = dashboard;\n this.scope = scope;\n this.getSeriesFn = getSeriesFn;\n this._anomalySegmentsSearcher = _anomalySegmentsSearcher;\n this._visible = false;\n this._lastItem = undefined;\n this.ctrl = scope.ctrl;\n this.panel = this.ctrl.panel;\n this.$tooltip = $('<div class=\"graph-tooltip\">');\n }\n GraphTooltip.prototype.clear = function (plot) {\n this._visible = false;\n this.$tooltip.detach();\n plot.clearCrosshair();\n plot.unhighlight();\n };\n ;\n GraphTooltip.prototype.show = function (pos, item) {\n if (item === undefined) {\n item = this._lastItem;\n }\n else {\n this._lastItem = item;\n }\n this._visible = true;\n var plot = this.$elem.data().plot;\n var plotData = plot.getData();\n var xAxes = plot.getXAxes();\n var xMode = xAxes[0].options.mode;\n var seriesList = this.getSeriesFn();\n var allSeriesMode = this.panel.tooltip.shared;\n var group, value, absoluteTime, hoverInfo, i, series, seriesHtml, tooltipFormat;\n // if panelRelY is defined another panel wants us to show a tooltip\n // get pageX from position on x axis and pageY from relative position in original panel\n if (pos.panelRelY) {\n var pointOffset = plot.pointOffset({ x: pos.x });\n if (Number.isNaN(pointOffset.left) || pointOffset.left < 0 || pointOffset.left > this.$elem.width()) {\n this.clear(plot);\n return;\n }\n pos.pageX = this.$elem.offset().left + pointOffset.left;\n pos.pageY = this.$elem.offset().top + this.$elem.height() * pos.panelRelY;\n var isVisible = pos.pageY >= $(window).scrollTop() &&\n pos.pageY <= $(window).innerHeight() + $(window).scrollTop();\n if (!isVisible) {\n this.clear(plot);\n return;\n }\n plot.setCrosshair(pos);\n allSeriesMode = true;\n if (this.dashboard.sharedCrosshairModeOnly()) {\n // if only crosshair mode we are done\n return;\n }\n }\n if (seriesList.length === 0) {\n return;\n }\n if (seriesList[0].hasMsResolution) {\n tooltipFormat = 'YYYY-MM-DD HH:mm:ss.SSS';\n }\n else {\n tooltipFormat = 'YYYY-MM-DD HH:mm:ss';\n }\n if (allSeriesMode) {\n plot.unhighlight();\n var seriesHoverInfo = this._getMultiSeriesPlotHoverInfo(plotData, pos);\n seriesHtml = '';\n absoluteTime = this.dashboard.formatDate(seriesHoverInfo.time, tooltipFormat);\n // Dynamically reorder the hovercard for the current time point if the\n // option is enabled.\n if (this.panel.tooltip.sort === 2) {\n seriesHoverInfo.series.sort(function (a, b) { return b.value - a.value; });\n }\n else if (this.panel.tooltip.sort === 1) {\n seriesHoverInfo.series.sort(function (a, b) { return a.value - b.value; });\n }\n for (i = 0; i < seriesHoverInfo.series.length; i++) {\n hoverInfo = seriesHoverInfo.series[i];\n if (hoverInfo.hidden) {\n continue;\n }\n var highlightClass = '';\n if (item && hoverInfo.index === item.seriesIndex) {\n highlightClass = 'graph-tooltip-list-item--highlight';\n }\n series = seriesList[hoverInfo.index];\n value = series.formatValue(hoverInfo.value);\n seriesHtml += '<div class=\"graph-tooltip-list-item ' + highlightClass + '\"><div class=\"graph-tooltip-series-name\">';\n seriesHtml += '<i class=\"fa fa-minus\" style=\"color:' + hoverInfo.color + ';\"></i> ' + hoverInfo.label + ':</div>';\n seriesHtml += '<div class=\"graph-tooltip-value\">' + value + '</div></div>';\n plot.highlight(hoverInfo.index, hoverInfo.hoverIndex);\n }\n seriesHtml += this._appendAnomaliesHTML(pos.x);\n this._renderAndShow(absoluteTime, seriesHtml, pos, xMode);\n }\n // single series tooltip\n else if (item) {\n series = seriesList[item.seriesIndex];\n group = '<div class=\"graph-tooltip-list-item\"><div class=\"graph-tooltip-series-name\">';\n group += '<i class=\"fa fa-minus\" style=\"color:' + item.series.color + ';\"></i> ' + series.aliasEscaped + ':</div>';\n if (this.panel.stack && this.panel.tooltip.value_type === 'individual') {\n value = item.datapoint[1] - item.datapoint[2];\n }\n else {\n value = item.datapoint[1];\n }\n value = series.formatValue(value);\n absoluteTime = this.dashboard.formatDate(item.datapoint[0], tooltipFormat);\n group += '<div class=\"graph-tooltip-value\">' + value + '</div>';\n group += this._appendAnomaliesHTML(pos.x);\n this._renderAndShow(absoluteTime, group, pos, xMode);\n }\n // no hit\n else {\n this.$tooltip.detach();\n }\n };\n ;\n GraphTooltip.prototype.destroy = function () {\n this._visible = false;\n this.$tooltip.remove();\n };\n ;\n Object.defineProperty(GraphTooltip.prototype, \"visible\", {\n get: function () { return this._visible; },\n enumerable: true,\n configurable: true\n });\n GraphTooltip.prototype._findHoverIndexFromDataPoints = function (posX, series, last) {\n var ps = series.datapoints.pointsize;\n var initial = last * ps;\n var len = series.datapoints.points.length;\n for (var j = initial; j < len; j += ps) {\n // Special case of a non stepped line, highlight the very last point just before a null point\n if ((!series.lines.steps && series.datapoints.points[initial] != null && series.datapoints.points[j] == null)\n //normal case\n || series.datapoints.points[j] > posX) {\n return Math.max(j - ps, 0) / ps;\n }\n }\n return j / ps - 1;\n };\n ;\n GraphTooltip.prototype._findHoverIndexFromData = function (posX, series) {\n var lower = 0;\n var upper = series.data.length - 1;\n var middle;\n while (true) {\n if (lower > upper) {\n return Math.max(upper, 0);\n }\n middle = Math.floor((lower + upper) / 2);\n if (series.data[middle][0] === posX) {\n return middle;\n }\n else if (series.data[middle][0] < posX) {\n lower = middle + 1;\n }\n else {\n upper = middle - 1;\n }\n }\n };\n ;\n GraphTooltip.prototype._appendAnomaliesHTML = function (pos) {\n var _this = this;\n var result = '';\n var segments = this._anomalySegmentsSearcher(pos);\n if (segments.length === 0) {\n return '';\n }\n segments.forEach(function (s) {\n var from = _this.dashboard.formatDate(s.segment.from, 'HH:mm:ss.SSS');\n var to = _this.dashboard.formatDate(s.segment.to, 'HH:mm:ss.SSS');\n result += \"\\n <div class=\\\"graph-tooltip-list-item\\\">\\n <div class=\\\"graph-tooltip-series-name\\\">\\n <i class=\\\"fa fa-exclamation\\\" style=\\\"color:\" + s.anomalyType.color + \"\\\"></i>\\n \" + s.anomalyType.name + \":\\n </div>\\n <div class=\\\"graph-tooltip-value\\\">\\n <i class=\\\"fa \" + (s.segment.labeled ? \"fa-thumb-tack\" : \"fa-search-plus\") + \"\\\" aria-hidden=\\\"true\\\"></i>\\n \" + from + \" \\u2014 \" + to + \"\\n </div>\\n </div>\\n \";\n });\n return result;\n };\n GraphTooltip.prototype._renderAndShow = function (absoluteTime, innerHtml, pos, xMode) {\n if (xMode === 'time') {\n innerHtml = '<div class=\"graph-tooltip-time\">' + absoluteTime + '</div>' + innerHtml;\n }\n this.$tooltip.html(innerHtml).place_tt(pos.pageX + 20, pos.pageY);\n };\n ;\n GraphTooltip.prototype._getMultiSeriesPlotHoverInfo = function (seriesList, pos) {\n var value, series, hoverIndex, hoverDistance, pointTime, yaxis;\n // 3 sub-arrays, 1st for hidden series, 2nd for left yaxis, 3rd for right yaxis.\n var results = [[], [], []];\n //now we know the current X (j) position for X and Y values\n var lastValue = 0; //needed for stacked values\n var minDistance, minTime;\n for (var i = 0; i < seriesList.length; i++) {\n series = seriesList[i];\n if (!series.data.length || (this.panel.legend.hideEmpty && series.allIsNull)) {\n // Init value so that it does not brake series sorting\n results[0].push({ hidden: true, value: 0 });\n continue;\n }\n if (!series.data.length || (this.panel.legend.hideZero && series.allIsZero)) {\n // Init value so that it does not brake series sorting\n results[0].push({ hidden: true, value: 0 });\n continue;\n }\n hoverIndex = this._findHoverIndexFromData(pos.x, series);\n hoverDistance = pos.x - series.data[hoverIndex][0];\n pointTime = series.data[hoverIndex][0];\n // Take the closest point before the cursor, or if it does not exist, the closest after\n if (!minDistance\n || (hoverDistance >= 0 && (hoverDistance < minDistance || minDistance < 0))\n || (hoverDistance < 0 && hoverDistance > minDistance)) {\n minDistance = hoverDistance;\n minTime = pointTime;\n }\n if (series.stack) {\n if (this.panel.tooltip.value_type === 'individual') {\n value = series.data[hoverIndex][1];\n }\n else if (!series.stack) {\n value = series.data[hoverIndex][1];\n }\n else {\n lastValue += series.data[hoverIndex][1];\n value = lastValue;\n }\n }\n else {\n value = series.data[hoverIndex][1];\n }\n // Highlighting multiple Points depending on the plot type\n if (series.lines.steps || series.stack) {\n // stacked and steppedLine plots can have series with different length.\n // Stacked series can increase its length on each new stacked serie if null points found,\n // to speed the index search we begin always on the last found hoverIndex.\n hoverIndex = this._findHoverIndexFromDataPoints(pos.x, series, hoverIndex);\n }\n // Be sure we have a yaxis so that it does not brake series sorting\n yaxis = 0;\n if (series.yaxis) {\n yaxis = series.yaxis.n;\n }\n results[yaxis].push({\n value: value,\n hoverIndex: hoverIndex,\n color: series.color,\n label: series.aliasEscaped,\n time: pointTime,\n distance: hoverDistance,\n index: i\n });\n }\n // Contat the 3 sub-arrays\n results = results[0].concat(results[1], results[2]);\n // Time of the point closer to pointer\n return { series: results, time: minTime };\n };\n ;\n return GraphTooltip;\n}());\n\n\n\n//# sourceURL=webpack:///./graph_tooltip.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./histogram.ts": |
|
/*!**********************!*\ |
|
!*** ./histogram.ts ***! |
|
\**********************/ |
|
/*! exports provided: getSeriesValues, convertValuesToHistogram */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getSeriesValues\", function() { return getSeriesValues; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"convertValuesToHistogram\", function() { return convertValuesToHistogram; });\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);\n\n/**\n * Convert series into array of series values.\n * @param data Array of series\n */\nfunction getSeriesValues(dataList) {\n var VALUE_INDEX = 0;\n var values = [];\n // Count histogam stats\n for (var i = 0; i < dataList.length; i++) {\n var series = dataList[i];\n var datapoints = series.datapoints;\n for (var j = 0; j < datapoints.length; j++) {\n if (datapoints[j][VALUE_INDEX] !== null) {\n values.push(datapoints[j][VALUE_INDEX]);\n }\n }\n }\n return values;\n}\n/**\n * Convert array of values into timeseries-like histogram:\n * [[val_1, count_1], [val_2, count_2], ..., [val_n, count_n]]\n * @param values\n * @param bucketSize\n */\nfunction convertValuesToHistogram(values, bucketSize) {\n var histogram = {};\n for (var i = 0; i < values.length; i++) {\n var bound = getBucketBound(values[i], bucketSize);\n if (histogram[bound]) {\n histogram[bound] = histogram[bound] + 1;\n }\n else {\n histogram[bound] = 1;\n }\n }\n var histogam_series = lodash__WEBPACK_IMPORTED_MODULE_0___default.a.map(histogram, function (count, bound) {\n return [Number(bound), count];\n });\n // Sort by Y axis values\n return lodash__WEBPACK_IMPORTED_MODULE_0___default.a.sortBy(histogam_series, function (point) { return point[0]; });\n}\nfunction getBucketBound(value, bucketSize) {\n return Math.floor(value / bucketSize) * bucketSize;\n}\n\n\n//# sourceURL=webpack:///./histogram.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./model/anomaly.ts": |
|
/*!**************************!*\ |
|
!*** ./model/anomaly.ts ***! |
|
\**************************/ |
|
/*! exports provided: AnomalySegment, AnomalyType, AnomalyTypesSet */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"AnomalySegment\", function() { return AnomalySegment; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"AnomalyType\", function() { return AnomalyType; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"AnomalyTypesSet\", function() { return AnomalyTypesSet; });\n/* harmony import */ var _segment_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./segment_array */ \"./model/segment_array.ts\");\n/* harmony import */ var _segment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./segment */ \"./model/segment.ts\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_2__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n\n\nvar AnomalySegment = /** @class */ (function (_super) {\n __extends(AnomalySegment, _super);\n function AnomalySegment(labeled, key, from, to) {\n var _this = _super.call(this, key, from, to) || this;\n _this.labeled = labeled;\n if (!lodash__WEBPACK_IMPORTED_MODULE_2___default.a.isBoolean(labeled)) {\n throw new Error('labeled value is not boolean');\n }\n return _this;\n }\n return AnomalySegment;\n}(_segment__WEBPACK_IMPORTED_MODULE_1__[\"Segment\"]));\n\nvar AnomalyType = /** @class */ (function () {\n function AnomalyType(_panelObject) {\n this._panelObject = _panelObject;\n this._selected = false;\n this._deleteMode = false;\n this._saving = false;\n this._segmentSet = new _segment_array__WEBPACK_IMPORTED_MODULE_0__[\"SegmentArray\"]();\n if (_panelObject === undefined) {\n this._panelObject = {};\n }\n lodash__WEBPACK_IMPORTED_MODULE_2___default.a.defaults(this._panelObject, {\n name: 'anomaly_name', confidence: 0.2, color: 'red'\n });\n //this._metric = new Metric(_panelObject.metric);\n }\n Object.defineProperty(AnomalyType.prototype, \"key\", {\n get: function () { return this.name; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"name\", {\n get: function () { return this._panelObject.name; },\n set: function (value) { this._panelObject.name = value; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"confidence\", {\n get: function () { return this._panelObject.confidence; },\n set: function (value) { this._panelObject.confidence = value; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"color\", {\n get: function () { return this._panelObject.color; },\n set: function (value) { this._panelObject.color = value; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"selected\", {\n get: function () { return this._selected; },\n set: function (value) { this._selected = value; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"deleteMode\", {\n get: function () { return this._deleteMode; },\n set: function (value) { this._deleteMode = value; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"saving\", {\n get: function () { return this._saving; },\n set: function (value) { this._saving = value; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"visible\", {\n get: function () {\n return (this._panelObject.visible === undefined) ? true : this._panelObject.visible;\n },\n set: function (value) {\n this._panelObject.visible = value;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"metric\", {\n get: function () { return this._metric; },\n enumerable: true,\n configurable: true\n });\n AnomalyType.prototype.addLabeledSegment = function (segment) {\n var asegment = new AnomalySegment(true, segment.key, segment.from, segment.to);\n this._segmentSet.addSegment(asegment);\n return asegment;\n };\n AnomalyType.prototype.removeSegmentsInRange = function (from, to) {\n return this._segmentSet.removeInRange(from, to);\n };\n Object.defineProperty(AnomalyType.prototype, \"segments\", {\n get: function () { return this._segmentSet; },\n set: function (value) {\n this._segmentSet.setSegments(value.getSegments());\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"status\", {\n get: function () { return this._status; },\n set: function (value) {\n if (value !== 'ready' &&\n value !== 'learning' &&\n value !== 'pending' &&\n value !== 'failed') {\n throw new Error('Unsupported status value: ' + value);\n }\n this._status = value;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"isActiveStatus\", {\n get: function () {\n return this.status !== 'ready' && this.status !== 'failed';\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"panelObject\", {\n get: function () { return this._panelObject; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(AnomalyType.prototype, \"alertEnabled\", {\n get: function () {\n return this._alertEnabled;\n },\n set: function (value) {\n this._alertEnabled = value;\n },\n enumerable: true,\n configurable: true\n });\n return AnomalyType;\n}());\n\nvar AnomalyTypesSet = /** @class */ (function () {\n function AnomalyTypesSet(_panelObject) {\n this._panelObject = _panelObject;\n if (_panelObject === undefined) {\n throw new Error('panel object can`t be undefined');\n }\n this._mapAnomalyKeyIndex = new Map();\n this._anomalyTypes = _panelObject.map(function (p) { return new AnomalyType(p); });\n this._rebuildIndex();\n }\n Object.defineProperty(AnomalyTypesSet.prototype, \"anomalyTypes\", {\n get: function () { return this._anomalyTypes; },\n enumerable: true,\n configurable: true\n });\n AnomalyTypesSet.prototype.addAnomalyType = function (anomalyType) {\n this._panelObject.push(anomalyType.panelObject);\n this._mapAnomalyKeyIndex[anomalyType.name] = this._anomalyTypes.length;\n this._anomalyTypes.push(anomalyType);\n };\n AnomalyTypesSet.prototype.removeAnomalyType = function (key) {\n var index = this._mapAnomalyKeyIndex[key];\n this._panelObject.splice(index, 1);\n this._anomalyTypes.splice(index, 1);\n this._rebuildIndex();\n };\n AnomalyTypesSet.prototype._rebuildIndex = function () {\n var _this = this;\n this._anomalyTypes.forEach(function (a, i) {\n _this._mapAnomalyKeyIndex[a.key] = i;\n });\n };\n AnomalyTypesSet.prototype.byKey = function (key) {\n return this._anomalyTypes[this._mapAnomalyKeyIndex[key]];\n };\n AnomalyTypesSet.prototype.byIndex = function (index) {\n return this._anomalyTypes[index];\n };\n return AnomalyTypesSet;\n}());\n\n\n\n//# sourceURL=webpack:///./model/anomaly.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./model/metric.ts": |
|
/*!*************************!*\ |
|
!*** ./model/metric.ts ***! |
|
\*************************/ |
|
/*! exports provided: Target, Metric, MetricExpanded, MetricMap */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Target\", function() { return Target; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Metric\", function() { return Metric; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"MetricExpanded\", function() { return MetricExpanded; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"MetricMap\", function() { return MetricMap; });\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var md5__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! md5 */ \"../node_modules/md5/md5.js\");\n/* harmony import */ var md5__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(md5__WEBPACK_IMPORTED_MODULE_1__);\n\n\nvar Target = /** @class */ (function () {\n function Target(any) {\n this._data = lodash__WEBPACK_IMPORTED_MODULE_0___default.a.cloneDeep(any);\n this._strip();\n }\n Target.prototype._strip = function () {\n delete this._data.alias;\n };\n Target.prototype.getHash = function () {\n return md5__WEBPACK_IMPORTED_MODULE_1___default()(JSON.stringify(this._data));\n };\n Target.prototype.getJSON = function () {\n return this._data;\n };\n return Target;\n}());\n\nvar Metric = /** @class */ (function () {\n function Metric(_panelObj) {\n this._panelObj = _panelObj;\n if (_panelObj === undefined) {\n throw new Error('_panelObj is undefined');\n }\n }\n Object.defineProperty(Metric.prototype, \"datasource\", {\n get: function () { return this._panelObj.datasource; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Metric.prototype, \"targetHashs\", {\n get: function () { return this._panelObj.targetHashs; },\n enumerable: true,\n configurable: true\n });\n return Metric;\n}());\n\nvar MetricExpanded = /** @class */ (function () {\n function MetricExpanded(datasource, targets) {\n this.datasource = datasource;\n this._targets = targets.map(function (t) { return new Target(t); });\n }\n MetricExpanded.prototype.toJSON = function () {\n return {\n datasource: this.datasource,\n targets: this._targets.map(function (t) { return t.getJSON(); })\n };\n };\n return MetricExpanded;\n}());\n\nvar MetricMap = /** @class */ (function () {\n function MetricMap(datasource, targets) {\n var _this = this;\n this._cache = new Map();\n targets.forEach(function (t) {\n _this._cache.set(t.getHash(), t);\n });\n }\n return MetricMap;\n}());\n\n\n\n//# sourceURL=webpack:///./model/metric.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./model/segment.ts": |
|
/*!**************************!*\ |
|
!*** ./model/segment.ts ***! |
|
\**************************/ |
|
/*! exports provided: Segment */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Segment\", function() { return Segment; });\nvar Segment = /** @class */ (function () {\n function Segment(_key, from, to) {\n this._key = _key;\n this.from = from;\n this.to = to;\n if (isNaN(this._key)) {\n throw new Error('Key can`t be NaN');\n }\n if (isNaN(+from)) {\n throw new Error('from can`t be NaN');\n }\n if (isNaN(+to)) {\n throw new Error('to can`t be NaN');\n }\n }\n Object.defineProperty(Segment.prototype, \"key\", {\n get: function () { return this._key; },\n set: function (value) { this._key = value; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Segment.prototype, \"middle\", {\n get: function () { return (this.from + this.to) / 2; },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Segment.prototype, \"length\", {\n get: function () {\n return Math.max(this.from, this.to) - Math.min(this.from, this.to);\n },\n enumerable: true,\n configurable: true\n });\n Segment.prototype.expandDist = function (allDist, portion) {\n if (allDist * portion < this.length) {\n return new Segment(this._key, this.from, this.to);\n }\n var p = Math.round(this.middle - allDist * portion / 2);\n var q = Math.round(this.middle + allDist * portion / 2);\n p = Math.min(p, this.from);\n q = Math.max(q, this.to);\n return new Segment(this._key, p, q);\n };\n Segment.prototype.equals = function (segment) {\n return this._key === segment._key;\n };\n return Segment;\n}());\n\n\n\n//# sourceURL=webpack:///./model/segment.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./model/segment_array.ts": |
|
/*!********************************!*\ |
|
!*** ./model/segment_array.ts ***! |
|
\********************************/ |
|
/*! exports provided: SegmentArray */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"SegmentArray\", function() { return SegmentArray; });\nvar SegmentArray = /** @class */ (function () {\n function SegmentArray(segments) {\n this.segments = segments;\n this._keyToSegment = new Map();\n this.setSegments(segments);\n }\n SegmentArray.prototype.getSegments = function (from, to) {\n if (from === undefined) {\n from = -Infinity;\n }\n if (to === undefined) {\n to = Infinity;\n }\n var result = [];\n for (var i = 0; i < this._segments.length; i++) {\n var s = this._segments[i];\n if (from <= s.from && s.to <= to) {\n result.push(s);\n }\n }\n return result;\n };\n SegmentArray.prototype.setSegments = function (segments) {\n var _this = this;\n this._segments = [];\n this._keyToSegment.clear();\n if (segments) {\n segments.forEach(function (s) {\n _this.addSegment(s);\n });\n }\n };\n SegmentArray.prototype.addSegment = function (segment) {\n if (this.has(segment.key)) {\n throw new Error(\"Segment with key \" + segment.key + \" exists in set\");\n }\n this._keyToSegment.set(segment.key, segment);\n this._segments.push(segment);\n };\n SegmentArray.prototype.findSegments = function (point) {\n return this._segments.filter(function (s) { return (s.from <= point) && (point <= s.to); });\n };\n SegmentArray.prototype.removeInRange = function (from, to) {\n var deleted = [];\n var newSegments = [];\n for (var i = 0; i < this._segments.length; i++) {\n var s = this._segments[i];\n if (from <= s.from && s.to <= to) {\n this._keyToSegment.delete(s.key);\n deleted.push(s);\n }\n else {\n newSegments.push(s);\n }\n }\n this._segments = newSegments;\n return deleted;\n };\n Object.defineProperty(SegmentArray.prototype, \"length\", {\n get: function () {\n return this._segments.length;\n },\n enumerable: true,\n configurable: true\n });\n SegmentArray.prototype.clear = function () {\n this._segments = [];\n this._keyToSegment.clear();\n };\n SegmentArray.prototype.has = function (key) {\n return this._keyToSegment.has(key);\n };\n SegmentArray.prototype.remove = function (key) {\n if (!this.has(key)) {\n return false;\n }\n var index = this._segments.findIndex(function (s) { return s.key === key; });\n this._segments.splice(index, 1);\n this._keyToSegment.delete(key);\n return true;\n };\n SegmentArray.prototype.updateKey = function (fromKey, toKey) {\n var segment = this._keyToSegment.get(fromKey);\n this._keyToSegment.delete(fromKey);\n segment.key = toKey;\n this._keyToSegment.set(toKey, segment);\n };\n return SegmentArray;\n}());\n\n\n\n//# sourceURL=webpack:///./model/segment_array.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./module.ts": |
|
/*!*******************!*\ |
|
!*** ./module.ts ***! |
|
\*******************/ |
|
/*! exports provided: GraphCtrl, PanelCtrl */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"GraphCtrl\", function() { return GraphCtrl; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"PanelCtrl\", function() { return GraphCtrl; });\n/* harmony import */ var _series_overrides_ctrl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./series_overrides_ctrl */ \"./series_overrides_ctrl.ts\");\n/* harmony import */ var _thresholds_form__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./thresholds_form */ \"./thresholds_form.ts\");\n/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./template */ \"./template.ts\");\n/* harmony import */ var _graph_renderer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./graph_renderer */ \"./graph_renderer.ts\");\n/* harmony import */ var _graph_legend__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./graph_legend */ \"./graph_legend.ts\");\n/* harmony import */ var _data_processor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./data_processor */ \"./data_processor.ts\");\n/* harmony import */ var _model_metric__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./model/metric */ \"./model/metric.ts\");\n/* harmony import */ var _services_anomaly_service__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./services/anomaly_service */ \"./services/anomaly_service.ts\");\n/* harmony import */ var _controllers_anomaly_controller__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./controllers/anomaly_controller */ \"./controllers/anomaly_controller.ts\");\n/* harmony import */ var _axes_editor__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./axes_editor */ \"./axes_editor.ts\");\n/* harmony import */ var grafana_app_plugins_sdk__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! grafana/app/plugins/sdk */ \"grafana/app/plugins/sdk\");\n/* harmony import */ var grafana_app_plugins_sdk__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(grafana_app_plugins_sdk__WEBPACK_IMPORTED_MODULE_10__);\n/* harmony import */ var grafana_app_core_core__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! grafana/app/core/core */ \"grafana/app/core/core\");\n/* harmony import */ var grafana_app_core_core__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_core__WEBPACK_IMPORTED_MODULE_11__);\n/* harmony import */ var grafana_app_core_config__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! grafana/app/core/config */ \"grafana/app/core/config\");\n/* harmony import */ var grafana_app_core_config__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_config__WEBPACK_IMPORTED_MODULE_12__);\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_13__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (undefined && undefined.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [0, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar BACKEND_VARIABLE_NAME = 'HASTIC_SERVER_URL';\nvar GraphCtrl = /** @class */ (function (_super) {\n __extends(GraphCtrl, _super);\n /** @ngInject */\n function GraphCtrl($scope, $injector, annotationsSrv, keybindingSrv, backendSrv, popoverSrv, contextSrv, alertSrv) {\n var _this = _super.call(this, $scope, $injector) || this;\n _this.annotationsSrv = annotationsSrv;\n _this.keybindingSrv = keybindingSrv;\n _this.backendSrv = backendSrv;\n _this.popoverSrv = popoverSrv;\n _this.contextSrv = contextSrv;\n _this.alertSrv = alertSrv;\n _this.hiddenSeries = {};\n _this.seriesList = [];\n _this.dataList = [];\n _this.annotations = [];\n _this.colors = [];\n _this.analyticsTypes = ['Anomaly detection', 'Pattern Detection (not implemented yet)'];\n _this.anomalyTypes = []; // TODO: remove it later. Only for alert tab\n _this.panelDefaults = {\n // datasource name, null = default datasource\n datasource: null,\n // sets client side (flot) or native graphite png renderer (png)\n renderer: 'flot',\n yaxes: [\n {\n label: null,\n show: true,\n logBase: 1,\n min: null,\n max: null,\n format: 'short',\n },\n {\n label: null,\n show: true,\n logBase: 1,\n min: null,\n max: null,\n format: 'short',\n },\n ],\n xaxis: {\n show: true,\n mode: 'time',\n name: null,\n values: [],\n buckets: null,\n },\n // show/hide lines\n lines: true,\n // fill factor\n fill: 1,\n // line width in pixels\n linewidth: 1,\n // show/hide dashed line\n dashes: false,\n // length of a dash\n dashLength: 10,\n // length of space between two dashes\n spaceLength: 10,\n // show hide points\n points: false,\n // point radius in pixels\n pointradius: 5,\n // show hide bars\n bars: false,\n // enable/disable stacking\n stack: false,\n // stack percentage mode\n percentage: false,\n // legend options\n legend: {\n show: true,\n values: false,\n min: false,\n max: false,\n current: false,\n total: false,\n avg: false,\n },\n // how null points should be handled\n nullPointMode: 'null',\n // staircase line mode\n steppedLine: false,\n // tooltip options\n tooltip: {\n value_type: 'individual',\n shared: true,\n sort: 0,\n },\n // time overrides\n timeFrom: null,\n timeShift: null,\n // metric queries\n targets: [{}],\n // series color overrides\n aliasColors: {},\n // other style overrides\n seriesOverrides: [],\n thresholds: [],\n anomalyType: '',\n analyticsType: 'Anomaly detection',\n };\n lodash__WEBPACK_IMPORTED_MODULE_13___default.a.defaults(_this.panel, _this.panelDefaults);\n lodash__WEBPACK_IMPORTED_MODULE_13___default.a.defaults(_this.panel.tooltip, _this.panelDefaults.tooltip);\n lodash__WEBPACK_IMPORTED_MODULE_13___default.a.defaults(_this.panel.legend, _this.panelDefaults.legend);\n lodash__WEBPACK_IMPORTED_MODULE_13___default.a.defaults(_this.panel.xaxis, _this.panelDefaults.xaxis);\n _this.processor = new _data_processor__WEBPACK_IMPORTED_MODULE_5__[\"DataProcessor\"](_this.panel);\n var anomalyService = new _services_anomaly_service__WEBPACK_IMPORTED_MODULE_7__[\"AnomalyService\"](_this.backendURL, backendSrv);\n _this.runBackendConnectivityCheck();\n _this.anomalyController = new _controllers_anomaly_controller__WEBPACK_IMPORTED_MODULE_8__[\"AnomalyController\"](_this.panel, anomalyService, _this.events);\n _this.anomalyTypes = _this.panel.anomalyTypes;\n keybindingSrv.bind('d', _this.onDKey.bind(_this));\n _this.events.on('render', _this.onRender.bind(_this));\n _this.events.on('data-received', _this.onDataReceived.bind(_this));\n _this.events.on('data-error', _this.onDataError.bind(_this));\n _this.events.on('data-snapshot-load', _this.onDataSnapshotLoad.bind(_this));\n _this.events.on('init-edit-mode', _this.onInitEditMode.bind(_this));\n _this.events.on('init-panel-actions', _this.onInitPanelActions.bind(_this));\n _this.events.on('anomaly-type-alert-change', function () {\n _this.$scope.$digest();\n });\n _this.events.on('anomaly-type-status-change', function (anomalyType) { return __awaiter(_this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (anomalyType === undefined) {\n throw new Error('anomalyType is undefined');\n }\n if (!(anomalyType.status === 'ready')) return [3 /*break*/, 2];\n return [4 /*yield*/, this.anomalyController.fetchSegments(anomalyType, +this.range.from, +this.range.to)];\n case 1:\n _a.sent();\n _a.label = 2;\n case 2:\n this.render(this.seriesList);\n this.$scope.$digest();\n return [2 /*return*/];\n }\n });\n }); });\n grafana_app_core_core__WEBPACK_IMPORTED_MODULE_11__[\"appEvents\"].on('ds-request-response', function (data) {\n var requestConfig = data.config;\n _this.datasourceRequest = {\n url: requestConfig.url,\n type: requestConfig.inspect.type,\n method: requestConfig.method,\n data: requestConfig.data,\n params: requestConfig.params\n };\n });\n _this.anomalyController.fetchAnomalyTypesStatuses();\n return _this;\n }\n Object.defineProperty(GraphCtrl.prototype, \"backendURL\", {\n get: function () {\n if (this.templateSrv.index[BACKEND_VARIABLE_NAME] === undefined) {\n return undefined;\n }\n return this.templateSrv.index[BACKEND_VARIABLE_NAME].current.value;\n },\n enumerable: true,\n configurable: true\n });\n GraphCtrl.prototype.runBackendConnectivityCheck = function () {\n return __awaiter(this, void 0, void 0, function () {\n var as, isOK;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (this.backendURL === '' || this.backendURL === undefined) {\n this.alertSrv.set(\"Dashboard variable $\" + BACKEND_VARIABLE_NAME + \" is missing\", \"Please set $\" + BACKEND_VARIABLE_NAME, 'warning', 4000);\n return [2 /*return*/];\n }\n as = new _services_anomaly_service__WEBPACK_IMPORTED_MODULE_7__[\"AnomalyService\"](this.backendURL, this.backendSrv);\n return [4 /*yield*/, as.isBackendOk()];\n case 1:\n isOK = _a.sent();\n if (!isOK) {\n this.alertSrv.set('Can`t connect to Hastic server', \"Hastic server: \\\"\" + this.backendURL + \"\\\"\", 'warning', 4000);\n }\n return [2 /*return*/];\n }\n });\n });\n };\n GraphCtrl.prototype.link = function (scope, elem, attrs, ctrl) {\n var $graphElem = $(elem[0]).find('#graphPanel');\n var $legendElem = $(elem[0]).find('#graphLegend');\n this._graphRenderer = new _graph_renderer__WEBPACK_IMPORTED_MODULE_3__[\"GraphRenderer\"]($graphElem, this.timeSrv, this.popoverSrv, this.contextSrv, this.$scope);\n this._graphLegend = new _graph_legend__WEBPACK_IMPORTED_MODULE_4__[\"GraphLegend\"]($legendElem, this.popoverSrv, this.$scope);\n };\n GraphCtrl.prototype.onInitEditMode = function () {\n var partialPath = this.panelPath + 'partials';\n this.addEditorTab('Analytics', partialPath + \"/tab_analytics.html\", 2);\n this.addEditorTab('Axes', _axes_editor__WEBPACK_IMPORTED_MODULE_9__[\"axesEditorComponent\"], 3);\n this.addEditorTab('Legend', partialPath + \"/tab_legend.html\", 4);\n this.addEditorTab('Display', partialPath + \"/tab_display.html\", 5);\n if (grafana_app_core_config__WEBPACK_IMPORTED_MODULE_12___default.a.alertingEnabled) {\n this.addEditorTab('Alert', grafana_app_plugins_sdk__WEBPACK_IMPORTED_MODULE_10__[\"alertTab\"], 6);\n }\n this.subTabIndex = 0;\n };\n GraphCtrl.prototype.onInitPanelActions = function (actions) {\n actions.push({ text: 'Export CSV', click: 'ctrl.exportCsv()' });\n actions.push({ text: 'Toggle legend', click: 'ctrl.toggleLegend()' });\n };\n GraphCtrl.prototype.issueQueries = function (datasource) {\n this.annotationsPromise = this.annotationsSrv.getAnnotations({\n dashboard: this.dashboard,\n panel: this.panel,\n range: this.range,\n });\n return _super.prototype.issueQueries.call(this, datasource);\n };\n GraphCtrl.prototype.zoomOut = function (evt) {\n this.publishAppEvent('zoom-out', 2);\n };\n GraphCtrl.prototype.onDataSnapshotLoad = function (snapshotData) {\n this.annotationsPromise = this.annotationsSrv.getAnnotations({\n dashboard: this.dashboard,\n panel: this.panel,\n range: this.range,\n });\n this.onDataReceived(snapshotData);\n };\n GraphCtrl.prototype.onDataError = function (err) {\n this.seriesList = [];\n this.annotations = [];\n this.render([]);\n };\n GraphCtrl.prototype.onDataReceived = function (dataList) {\n return __awaiter(this, void 0, void 0, function () {\n var hasSomePoint, _i, _a, series, loadTasks, results;\n return __generator(this, function (_b) {\n switch (_b.label) {\n case 0:\n this.dataList = dataList;\n this.seriesList = this.processor.getSeriesList({\n dataList: dataList,\n range: this.range,\n });\n //this.onPredictionReceived(this.seriesList);\n this.dataWarning = null;\n hasSomePoint = this.seriesList.some(function (s) { return s.datapoints.length > 0; });\n if (!hasSomePoint) {\n this.dataWarning = {\n title: 'No data points',\n tip: 'No datapoints returned from data query',\n };\n }\n else {\n for (_i = 0, _a = this.seriesList; _i < _a.length; _i++) {\n series = _a[_i];\n if (series.isOutsideRange) {\n this.dataWarning = {\n title: 'Data points outside time range',\n tip: 'Can be caused by timezone mismatch or missing time filter in query',\n };\n break;\n }\n }\n }\n loadTasks = [\n this.annotationsPromise,\n this.anomalyController.fetchAnomalyTypesSegments(+this.range.from, +this.range.to)\n ];\n return [4 /*yield*/, Promise.all(loadTasks)];\n case 1:\n results = _b.sent();\n this.loading = false;\n this.alertState = results[0].alertState;\n this.annotations = results[0].annotations;\n this.render(this.seriesList);\n return [2 /*return*/];\n }\n });\n });\n };\n GraphCtrl.prototype.onPredictionReceived = function (spanList) {\n var predictions = [];\n for (var _i = 0, spanList_1 = spanList; _i < spanList_1.length; _i++) {\n var span = spanList_1[_i];\n var predictionLow = {\n target: '',\n color: '',\n datapoints: []\n };\n var predictionHigh = {\n target: '',\n color: '',\n datapoints: []\n };\n for (var _a = 0, _b = span.datapoints; _a < _b.length; _a++) {\n var datapoint = _b[_a];\n predictionHigh.datapoints.push([datapoint[0] + 2, datapoint[1]]);\n predictionLow.datapoints.push([datapoint[0] - 2, datapoint[1]]);\n }\n predictionHigh.target = span.label + \" high\";\n predictionLow.target = span.label + \" low\";\n predictionHigh.color = span.color;\n predictionLow.color = span.color;\n predictions.push(predictionHigh, predictionLow);\n }\n var predictionSeries = this.processor.getSeriesList({\n dataList: predictions,\n range: this.range\n });\n for (var _c = 0, predictionSeries_1 = predictionSeries; _c < predictionSeries_1.length; _c++) {\n var serie = predictionSeries_1[_c];\n serie.prediction = true;\n this.seriesList.push(serie);\n }\n };\n GraphCtrl.prototype.onRender = function (data) {\n if (!this.seriesList) {\n return;\n }\n var _loop_1 = function (series) {\n if (series.prediction) {\n overrideItem = lodash__WEBPACK_IMPORTED_MODULE_13___default.a.find(this_1.panel.seriesOverrides, function (el) { return el.alias === series.alias; });\n if (overrideItem !== undefined) {\n this_1.addSeriesOverride({\n alias: series.alias,\n linewidth: 0,\n legend: false,\n // if pointradius === 0 -> point still shows, that's why pointradius === -1\n pointradius: -1,\n fill: 3\n });\n }\n }\n series.applySeriesOverrides(this_1.panel.seriesOverrides);\n if (series.unit) {\n this_1.panel.yaxes[series.yaxis - 1].format = series.unit;\n }\n };\n var this_1 = this, overrideItem;\n for (var _i = 0, _a = this.seriesList; _i < _a.length; _i++) {\n var series = _a[_i];\n _loop_1(series);\n }\n if (!this.anomalyController.graphLocked) {\n this._graphLegend.render();\n this._graphRenderer.render(data);\n }\n };\n GraphCtrl.prototype.changeSeriesColor = function (series, color) {\n series.color = color;\n this.panel.aliasColors[series.alias] = series.color;\n this.render();\n };\n GraphCtrl.prototype.toggleSeries = function (serie, event) {\n if (event.ctrlKey || event.metaKey || event.shiftKey) {\n if (this.hiddenSeries[serie.alias]) {\n delete this.hiddenSeries[serie.alias];\n }\n else {\n this.hiddenSeries[serie.alias] = true;\n }\n }\n else {\n this.toggleSeriesExclusiveMode(serie);\n }\n this.render();\n };\n GraphCtrl.prototype.toggleSeriesExclusiveMode = function (serie) {\n var _this = this;\n var hidden = this.hiddenSeries;\n if (hidden[serie.alias]) {\n delete hidden[serie.alias];\n }\n // check if every other series is hidden\n var alreadyExclusive = lodash__WEBPACK_IMPORTED_MODULE_13___default.a.every(this.seriesList, function (value) {\n if (value.alias === serie.alias) {\n return true;\n }\n return hidden[value.alias];\n });\n if (alreadyExclusive) {\n // remove all hidden series\n lodash__WEBPACK_IMPORTED_MODULE_13___default.a.each(this.seriesList, function (value) {\n delete _this.hiddenSeries[value.alias];\n });\n }\n else {\n // hide all but this serie\n lodash__WEBPACK_IMPORTED_MODULE_13___default.a.each(this.seriesList, function (value) {\n if (value.alias === serie.alias) {\n return;\n }\n _this.hiddenSeries[value.alias] = true;\n });\n }\n };\n GraphCtrl.prototype.toggleAxis = function (info) {\n var override = lodash__WEBPACK_IMPORTED_MODULE_13___default.a.find(this.panel.seriesOverrides, { alias: info.alias });\n if (!override) {\n override = { alias: info.alias };\n this.panel.seriesOverrides.push(override);\n }\n info.yaxis = override.yaxis = info.yaxis === 2 ? 1 : 2;\n this.render();\n };\n GraphCtrl.prototype.addSeriesOverride = function (override) {\n this.panel.seriesOverrides.push(override || {});\n };\n GraphCtrl.prototype.removeSeriesOverride = function (override) {\n this.panel.seriesOverrides = lodash__WEBPACK_IMPORTED_MODULE_13___default.a.without(this.panel.seriesOverrides, override);\n this.render();\n };\n GraphCtrl.prototype.toggleLegend = function () {\n this.panel.legend.show = !this.panel.legend.show;\n this.refresh();\n };\n GraphCtrl.prototype.legendValuesOptionChanged = function () {\n var legend = this.panel.legend;\n legend.values = legend.min || legend.max || legend.avg || legend.current || legend.total;\n this.render();\n };\n GraphCtrl.prototype.exportCsv = function () {\n var scope = this.$scope.$new(true);\n scope.seriesList = this.seriesList;\n this.publishAppEvent('show-modal', {\n templateHtml: '<export-data-modal data=\"seriesList\"></export-data-modal>',\n scope: scope,\n modalClass: 'modal--narrow',\n });\n };\n GraphCtrl.prototype.getAnnotationsByTag = function (tag) {\n var res = [];\n for (var _i = 0, _a = this.annotations; _i < _a.length; _i++) {\n var annotation = _a[_i];\n if (annotation.tags.indexOf(tag) >= 0) {\n res.push(annotation);\n }\n }\n return res;\n };\n Object.defineProperty(GraphCtrl.prototype, \"annotationTags\", {\n get: function () {\n var res = [];\n for (var _i = 0, _a = this.annotations; _i < _a.length; _i++) {\n var annotation = _a[_i];\n for (var _b = 0, _c = annotation.tags; _b < _c.length; _b++) {\n var tag = _c[_b];\n if (res.indexOf(tag) < 0) {\n res.push(tag);\n }\n }\n }\n return res;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(GraphCtrl.prototype, \"panelPath\", {\n get: function () {\n if (this._panelPath === undefined) {\n this._panelPath = '/public/plugins/' + this.pluginId + '/';\n }\n return this._panelPath;\n },\n enumerable: true,\n configurable: true\n });\n GraphCtrl.prototype.createNewAnomalyType = function () {\n this.anomalyController.createAnomalyType();\n };\n GraphCtrl.prototype.saveAnomalyType = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n this.refresh();\n return [4 /*yield*/, this.anomalyController.saveNewAnomalyType(new _model_metric__WEBPACK_IMPORTED_MODULE_6__[\"MetricExpanded\"](this.panel.datasource, this.panel.targets), this.datasourceRequest, this.panel.id)];\n case 1:\n _a.sent();\n this.$scope.$digest();\n this.render(this.seriesList);\n return [2 /*return*/];\n }\n });\n });\n };\n GraphCtrl.prototype.onAnomalyColorChange = function (key, value) {\n this.anomalyController.onAnomalyColorChange(key, value);\n this.render();\n };\n GraphCtrl.prototype.onAnomalyRemove = function (key) {\n this.anomalyController.removeAnomalyType(key);\n this.render();\n };\n GraphCtrl.prototype.onAnomalyCancelLabeling = function (key) {\n var _this = this;\n this.$scope.$root.appEvent('confirm-modal', {\n title: 'Clear anomaly labeling',\n text2: 'Your changes will be lost.',\n yesText: 'Clear',\n icon: 'fa-warning',\n altActionText: 'Save',\n onAltAction: function () {\n _this.onToggleAnomalyTypeLabelingMode(key);\n },\n onConfirm: function () {\n _this.anomalyController.undoLabeling();\n _this.render();\n },\n });\n };\n GraphCtrl.prototype.onToggleAnomalyTypeLabelingMode = function (key) {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.anomalyController.toggleAnomalyTypeLabelingMode(key)];\n case 1:\n _a.sent();\n this.$scope.$digest();\n this.render();\n return [2 /*return*/];\n }\n });\n });\n };\n GraphCtrl.prototype.onDKey = function () {\n if (!this.anomalyController.labelingMode) {\n return;\n }\n this.anomalyController.toggleDeleteMode();\n };\n GraphCtrl.prototype.onAnomalyAlertChange = function (anomalyType) {\n this.anomalyController.toggleAnomalyTypeAlertEnabled(anomalyType);\n };\n GraphCtrl.prototype.onAnomalyToggleVisibility = function (key) {\n this.anomalyController.toggleAnomalyVisibility(key);\n this.render();\n };\n GraphCtrl.template = _template__WEBPACK_IMPORTED_MODULE_2__[\"default\"];\n return GraphCtrl;\n}(grafana_app_plugins_sdk__WEBPACK_IMPORTED_MODULE_10__[\"MetricsPanelCtrl\"]));\n\n\n\n//# sourceURL=webpack:///./module.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./series_overrides_ctrl.ts": |
|
/*!**********************************!*\ |
|
!*** ./series_overrides_ctrl.ts ***! |
|
\**********************************/ |
|
/*! exports provided: SeriesOverridesCtrl */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"SeriesOverridesCtrl\", function() { return SeriesOverridesCtrl; });\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var angular__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! angular */ \"angular\");\n/* harmony import */ var angular__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(angular__WEBPACK_IMPORTED_MODULE_1__);\n\n\nvar SeriesOverridesCtrl = /** @class */ (function () {\n /** @ngInject */\n function SeriesOverridesCtrl($scope, $element, popoverSrv) {\n $scope.overrideMenu = [];\n $scope.currentOverrides = [];\n $scope.override = $scope.override || {};\n $scope.addOverrideOption = function (name, propertyName, values) {\n var option = {\n text: name,\n propertyName: propertyName,\n index: $scope.overrideMenu.lenght,\n values: values,\n submenu: lodash__WEBPACK_IMPORTED_MODULE_0___default.a.map(values, function (value) {\n return { text: String(value), value: value };\n }),\n };\n $scope.overrideMenu.push(option);\n };\n $scope.setOverride = function (item, subItem) {\n // handle color overrides\n if (item.propertyName === 'color') {\n $scope.openColorSelector($scope.override['color']);\n return;\n }\n $scope.override[item.propertyName] = subItem.value;\n // automatically disable lines for this series and the fill bellow to series\n // can be removed by the user if they still want lines\n if (item.propertyName === 'fillBelowTo') {\n $scope.override['lines'] = false;\n $scope.ctrl.addSeriesOverride({ alias: subItem.value, lines: false });\n }\n $scope.updateCurrentOverrides();\n $scope.ctrl.render();\n };\n $scope.colorSelected = function (color) {\n $scope.override['color'] = color;\n $scope.updateCurrentOverrides();\n $scope.ctrl.render();\n };\n $scope.openColorSelector = function (color) {\n var fakeSeries = { color: color };\n popoverSrv.show({\n element: $element.find('.dropdown')[0],\n position: 'top center',\n openOn: 'click',\n template: '<series-color-picker series=\"series\" onColorChange=\"colorSelected\" />',\n model: {\n autoClose: true,\n colorSelected: $scope.colorSelected,\n series: fakeSeries,\n },\n onClose: function () {\n $scope.ctrl.render();\n },\n });\n };\n $scope.removeOverride = function (option) {\n delete $scope.override[option.propertyName];\n $scope.updateCurrentOverrides();\n $scope.ctrl.refresh();\n };\n $scope.getSeriesNames = function () {\n return lodash__WEBPACK_IMPORTED_MODULE_0___default.a.map($scope.ctrl.seriesList, function (series) {\n return series.alias;\n });\n };\n $scope.updateCurrentOverrides = function () {\n $scope.currentOverrides = [];\n lodash__WEBPACK_IMPORTED_MODULE_0___default.a.each($scope.overrideMenu, function (option) {\n var value = $scope.override[option.propertyName];\n if (lodash__WEBPACK_IMPORTED_MODULE_0___default.a.isUndefined(value)) {\n return;\n }\n $scope.currentOverrides.push({\n name: option.text,\n propertyName: option.propertyName,\n value: String(value),\n });\n });\n };\n $scope.addOverrideOption('Bars', 'bars', [true, false]);\n $scope.addOverrideOption('Lines', 'lines', [true, false]);\n $scope.addOverrideOption('Line fill', 'fill', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n $scope.addOverrideOption('Line width', 'linewidth', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n $scope.addOverrideOption('Null point mode', 'nullPointMode', ['connected', 'null', 'null as zero']);\n $scope.addOverrideOption('Fill below to', 'fillBelowTo', $scope.getSeriesNames());\n $scope.addOverrideOption('Staircase line', 'steppedLine', [true, false]);\n $scope.addOverrideOption('Dashes', 'dashes', [true, false]);\n $scope.addOverrideOption('Dash Length', 'dashLength', [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 11,\n 12,\n 13,\n 14,\n 15,\n 16,\n 17,\n 18,\n 19,\n 20,\n ]);\n $scope.addOverrideOption('Dash Space', 'spaceLength', [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 11,\n 12,\n 13,\n 14,\n 15,\n 16,\n 17,\n 18,\n 19,\n 20,\n ]);\n $scope.addOverrideOption('Points', 'points', [true, false]);\n $scope.addOverrideOption('Points Radius', 'pointradius', [1, 2, 3, 4, 5]);\n $scope.addOverrideOption('Stack', 'stack', [true, false, 'A', 'B', 'C', 'D']);\n $scope.addOverrideOption('Color', 'color', ['change']);\n $scope.addOverrideOption('Y-axis', 'yaxis', [1, 2]);\n $scope.addOverrideOption('Z-index', 'zindex', [-3, -2, -1, 0, 1, 2, 3]);\n $scope.addOverrideOption('Transform', 'transform', ['negative-Y']);\n $scope.addOverrideOption('Legend', 'legend', [true, false]);\n $scope.updateCurrentOverrides();\n }\n return SeriesOverridesCtrl;\n}());\n\nangular__WEBPACK_IMPORTED_MODULE_1___default.a.module('grafana.controllers').controller('SeriesOverridesCtrl', SeriesOverridesCtrl);\n\n\n//# sourceURL=webpack:///./series_overrides_ctrl.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./services/anomaly_service.ts": |
|
/*!*************************************!*\ |
|
!*** ./services/anomaly_service.ts ***! |
|
\*************************************/ |
|
/*! exports provided: AnomalyService */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"AnomalyService\", function() { return AnomalyService; });\n/* harmony import */ var _model_anomaly__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../model/anomaly */ \"./model/anomaly.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (undefined && undefined.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [0, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\nvar __await = (undefined && undefined.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }\nvar __asyncGenerator = (undefined && undefined.__asyncGenerator) || function (thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n};\n\nvar AnomalyService = /** @class */ (function () {\n function AnomalyService(_backendURL, _backendSrv) {\n this._backendURL = _backendURL;\n this._backendSrv = _backendSrv;\n }\n AnomalyService.prototype.postNewAnomalyType = function (metric, datasourceRequest, newAnomalyType, panelId) {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n return [2 /*return*/, this._backendSrv.post(this._backendURL + '/anomalies', {\n name: newAnomalyType.name,\n metric: metric.toJSON(),\n panelUrl: window.location.origin + window.location.pathname + (\"?panelId=\" + panelId + \"&fullscreen\"),\n datasource: datasourceRequest\n })];\n });\n });\n };\n ;\n AnomalyService.prototype.isBackendOk = function () {\n return __awaiter(this, void 0, void 0, function () {\n var data, e_1;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n _a.trys.push([0, 2, , 3]);\n return [4 /*yield*/, this._backendSrv.get(this._backendURL)];\n case 1:\n data = _a.sent();\n return [2 /*return*/, true];\n case 2:\n e_1 = _a.sent();\n return [2 /*return*/, false];\n case 3: return [2 /*return*/];\n }\n });\n });\n };\n AnomalyService.prototype.updateSegments = function (key, addedSegments, removedSegments) {\n return __awaiter(this, void 0, void 0, function () {\n var getJSONs, payload, data;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n getJSONs = function (segs) { return segs.getSegments().map(function (segment) { return ({\n \"start\": segment.from,\n \"finish\": segment.to\n }); }); };\n payload = {\n name: key,\n added_segments: getJSONs(addedSegments),\n removed_segments: removedSegments.getSegments().map(function (s) { return s.key; })\n };\n return [4 /*yield*/, this._backendSrv.patch(this._backendURL + '/segments', payload)];\n case 1:\n data = _a.sent();\n if (data.added_ids === undefined) {\n throw new Error('Server didn`t send added_ids');\n }\n return [2 /*return*/, data.added_ids];\n }\n });\n });\n };\n AnomalyService.prototype.getSegments = function (key, from, to) {\n return __awaiter(this, void 0, void 0, function () {\n var payload, data, segments;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n payload = { anomaly_id: key };\n if (from !== undefined) {\n payload['from'] = from;\n }\n if (to !== undefined) {\n payload['to'] = to;\n }\n return [4 /*yield*/, this._backendSrv.get(this._backendURL + '/segments', payload)];\n case 1:\n data = _a.sent();\n if (data.segments === undefined) {\n throw new Error('Server didn`t return segments array');\n }\n segments = data.segments;\n return [2 /*return*/, segments.map(function (s) { return new _model_anomaly__WEBPACK_IMPORTED_MODULE_0__[\"AnomalySegment\"](s.labeled, s.id, s.start, s.finish); })];\n }\n });\n });\n };\n AnomalyService.prototype.getAnomalyTypeStatusGenerator = function (key, duration) {\n return __asyncGenerator(this, arguments, function getAnomalyTypeStatusGenerator_1() {\n var _this = this;\n var statusCheck, timeout;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n statusCheck = function () { return __awaiter(_this, void 0, void 0, function () {\n var data;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this._backendSrv.get(this._backendURL + '/anomalies/status', { name: key })];\n case 1:\n data = _a.sent();\n return [2 /*return*/, data.status];\n }\n });\n }); };\n timeout = function () { return __awaiter(_this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n return [2 /*return*/, new Promise(function (resolve) { return setTimeout(resolve, duration); })];\n });\n }); };\n _a.label = 1;\n case 1:\n if (false) {}\n return [4 /*yield*/, __await(statusCheck())];\n case 2: return [4 /*yield*/, _a.sent()];\n case 3:\n _a.sent();\n return [4 /*yield*/, __await(timeout())];\n case 4:\n _a.sent();\n return [3 /*break*/, 1];\n case 5: return [2 /*return*/];\n }\n });\n });\n };\n AnomalyService.prototype.getAlertEnabled = function (key) {\n return __awaiter(this, void 0, void 0, function () {\n var data;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this._backendSrv.get(this._backendURL + '/alerts', { anomaly_id: key })];\n case 1:\n data = _a.sent();\n return [2 /*return*/, data.enable];\n }\n });\n });\n };\n AnomalyService.prototype.setAlertEnabled = function (key, value) {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n return [2 /*return*/, this._backendSrv.post(this._backendURL + '/alerts', { anomaly_id: key, enable: value })];\n });\n });\n };\n return AnomalyService;\n}());\n\n\n\n//# sourceURL=webpack:///./services/anomaly_service.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./template.ts": |
|
/*!*********************!*\ |
|
!*** ./template.ts ***! |
|
\*********************/ |
|
/*! exports provided: default */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\nvar template = \"\\n<div class=\\\"graph-panel\\\" ng-class=\\\"{'graph-panel--legend-right': ctrl.panel.legend.rightSide}\\\">\\n <div class=\\\"graph-panel__chart\\\" id=\\\"graphPanel\\\" ng-dblclick=\\\"ctrl.zoomOut()\\\" />\\n <div class=\\\"hastic-graph-legend\\\" id=\\\"graphLegend\\\" />\\n</div>\\n\";\n/* harmony default export */ __webpack_exports__[\"default\"] = (template);\n\n\n//# sourceURL=webpack:///./template.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./threshold_manager.ts": |
|
/*!******************************!*\ |
|
!*** ./threshold_manager.ts ***! |
|
\******************************/ |
|
/*! exports provided: ThresholdManager */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ThresholdManager\", function() { return ThresholdManager; });\n/* harmony import */ var _vendor_flot_jquery_flot__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vendor/flot/jquery.flot */ \"./vendor/flot/jquery.flot.js\");\n/* harmony import */ var _vendor_flot_jquery_flot__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_vendor_flot_jquery_flot__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash */ \"lodash\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\nvar ThresholdManager = /** @class */ (function () {\n function ThresholdManager(panelCtrl) {\n this.panelCtrl = panelCtrl;\n }\n ThresholdManager.prototype.getHandleHtml = function (handleIndex, model, valueStr) {\n var stateClass = model.colorMode;\n if (model.colorMode === 'custom') {\n stateClass = 'critical';\n }\n return \"\\n <div class=\\\"alert-handle-wrapper alert-handle-wrapper--T\" + handleIndex + \"\\\">\\n <div class=\\\"alert-handle-line alert-handle-line--\" + stateClass + \"\\\">\\n </div>\\n <div class=\\\"alert-handle\\\" data-handle-index=\\\"\" + handleIndex + \"\\\">\\n <i class=\\\"icon-gf icon-gf-\" + stateClass + \" alert-state-\" + stateClass + \"\\\"></i>\\n <span class=\\\"alert-handle-value\\\">\" + valueStr + \"<i class=\\\"alert-handle-grip\\\"></i></span>\\n </div>\\n </div>\";\n };\n ThresholdManager.prototype.initDragging = function (evt) {\n var handleElem = jquery__WEBPACK_IMPORTED_MODULE_1__(evt.currentTarget).parents('.alert-handle-wrapper');\n var handleIndex = jquery__WEBPACK_IMPORTED_MODULE_1__(evt.currentTarget).data('handleIndex');\n var lastY = null;\n var posTop;\n var plot = this.plot;\n var panelCtrl = this.panelCtrl;\n var model = this.thresholds[handleIndex];\n function dragging(evt) {\n if (lastY === null) {\n lastY = evt.clientY;\n }\n else {\n var diff = evt.clientY - lastY;\n posTop = posTop + diff;\n lastY = evt.clientY;\n handleElem.css({ top: posTop + diff });\n }\n }\n function stopped() {\n // calculate graph level\n var graphValue = plot.c2p({ left: 0, top: posTop }).y;\n graphValue = parseInt(graphValue.toFixed(0));\n model.value = graphValue;\n handleElem.off('mousemove', dragging);\n handleElem.off('mouseup', dragging);\n handleElem.off('mouseleave', dragging);\n // trigger digest and render\n panelCtrl.$scope.$apply(function () {\n panelCtrl.render();\n panelCtrl.events.emit('threshold-changed', {\n threshold: model,\n handleIndex: handleIndex,\n });\n });\n }\n lastY = null;\n posTop = handleElem.position().top;\n handleElem.on('mousemove', dragging);\n handleElem.on('mouseup', stopped);\n handleElem.on('mouseleave', stopped);\n };\n ThresholdManager.prototype.cleanUp = function () {\n this.placeholder.find('.alert-handle-wrapper').remove();\n this.needsCleanup = false;\n };\n ThresholdManager.prototype.renderHandle = function (handleIndex, defaultHandleTopPos) {\n var model = this.thresholds[handleIndex];\n var value = model.value;\n var valueStr = value;\n var handleTopPos = 0;\n // handle no value\n if (!lodash__WEBPACK_IMPORTED_MODULE_2___default.a.isNumber(value)) {\n valueStr = '';\n handleTopPos = defaultHandleTopPos;\n }\n else {\n var valueCanvasPos = this.plot.p2c({ x: 0, y: value });\n handleTopPos = Math.round(Math.min(Math.max(valueCanvasPos.top, 0), this.height) - 6);\n }\n var handleElem = jquery__WEBPACK_IMPORTED_MODULE_1__(this.getHandleHtml(handleIndex, model, valueStr));\n this.placeholder.append(handleElem);\n handleElem.toggleClass('alert-handle-wrapper--no-value', valueStr === '');\n handleElem.css({ top: handleTopPos });\n };\n ThresholdManager.prototype.shouldDrawHandles = function () {\n return !this.hasSecondYAxis && this.panelCtrl.editingThresholds && this.panelCtrl.panel.thresholds.length > 0;\n };\n ThresholdManager.prototype.prepare = function (elem, data) {\n this.hasSecondYAxis = false;\n for (var i = 0; i < data.length; i++) {\n if (data[i].yaxis > 1) {\n this.hasSecondYAxis = true;\n break;\n }\n }\n if (this.shouldDrawHandles()) {\n var thresholdMargin = this.panelCtrl.panel.thresholds.length > 1 ? '220px' : '110px';\n elem.css('margin-right', thresholdMargin);\n }\n else if (this.needsCleanup) {\n elem.css('margin-right', '0');\n }\n };\n ThresholdManager.prototype.draw = function (plot) {\n this.thresholds = this.panelCtrl.panel.thresholds;\n this.plot = plot;\n this.placeholder = plot.getPlaceholder();\n if (this.needsCleanup) {\n this.cleanUp();\n }\n if (!this.shouldDrawHandles()) {\n return;\n }\n this.height = plot.height();\n if (this.thresholds.length > 0) {\n this.renderHandle(0, 10);\n }\n if (this.thresholds.length > 1) {\n this.renderHandle(1, this.height - 30);\n }\n this.placeholder.off('mousedown', '.alert-handle');\n this.placeholder.on('mousedown', '.alert-handle', this.initDragging.bind(this));\n this.needsCleanup = true;\n };\n ThresholdManager.prototype.addFlotOptions = function (options, panel) {\n if (!panel.thresholds || panel.thresholds.length === 0) {\n return;\n }\n var gtLimit = Infinity;\n var ltLimit = -Infinity;\n var i, threshold, other;\n for (i = 0; i < panel.thresholds.length; i++) {\n threshold = panel.thresholds[i];\n if (!lodash__WEBPACK_IMPORTED_MODULE_2___default.a.isNumber(threshold.value)) {\n continue;\n }\n var limit;\n switch (threshold.op) {\n case 'gt': {\n limit = gtLimit;\n // if next threshold is less then op and greater value, then use that as limit\n if (panel.thresholds.length > i + 1) {\n other = panel.thresholds[i + 1];\n if (other.value > threshold.value) {\n limit = other.value;\n ltLimit = limit;\n }\n }\n break;\n }\n case 'lt': {\n limit = ltLimit;\n // if next threshold is less then op and greater value, then use that as limit\n if (panel.thresholds.length > i + 1) {\n other = panel.thresholds[i + 1];\n if (other.value < threshold.value) {\n limit = other.value;\n gtLimit = limit;\n }\n }\n break;\n }\n }\n var fillColor, lineColor;\n switch (threshold.colorMode) {\n case 'critical': {\n fillColor = 'rgba(234, 112, 112, 0.12)';\n lineColor = 'rgba(237, 46, 24, 0.60)';\n break;\n }\n case 'warning': {\n fillColor = 'rgba(235, 138, 14, 0.12)';\n lineColor = 'rgba(247, 149, 32, 0.60)';\n break;\n }\n case 'ok': {\n fillColor = 'rgba(11, 237, 50, 0.090)';\n lineColor = 'rgba(6,163,69, 0.60)';\n break;\n }\n case 'custom': {\n fillColor = threshold.fillColor;\n lineColor = threshold.lineColor;\n break;\n }\n }\n // fill\n if (threshold.fill) {\n options.grid.markings.push({\n yaxis: { from: threshold.value, to: limit },\n color: fillColor,\n });\n }\n if (threshold.line) {\n options.grid.markings.push({\n yaxis: { from: threshold.value, to: threshold.value },\n color: lineColor,\n });\n }\n }\n };\n return ThresholdManager;\n}());\n\n\n\n//# sourceURL=webpack:///./threshold_manager.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./thresholds_form.ts": |
|
/*!****************************!*\ |
|
!*** ./thresholds_form.ts ***! |
|
\****************************/ |
|
/*! exports provided: ThresholdFormCtrl */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ThresholdFormCtrl\", function() { return ThresholdFormCtrl; });\n/* harmony import */ var grafana_app_core_core_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! grafana/app/core/core_module */ \"grafana/app/core/core_module\");\n/* harmony import */ var grafana_app_core_core_module__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(grafana_app_core_core_module__WEBPACK_IMPORTED_MODULE_0__);\n\nvar ThresholdFormCtrl = /** @class */ (function () {\n /** @ngInject */\n function ThresholdFormCtrl($scope) {\n var _this = this;\n this.panel = this.panelCtrl.panel;\n if (this.panel.alert) {\n this.disabled = true;\n }\n var unbindDestroy = $scope.$on('$destroy', function () {\n _this.panelCtrl.editingThresholds = false;\n _this.panelCtrl.render();\n unbindDestroy();\n });\n this.panelCtrl.editingThresholds = true;\n }\n ThresholdFormCtrl.prototype.addThreshold = function () {\n this.panel.thresholds.push({\n value: undefined,\n colorMode: 'critical',\n op: 'gt',\n fill: true,\n line: true,\n });\n this.panelCtrl.render();\n };\n ThresholdFormCtrl.prototype.removeThreshold = function (index) {\n this.panel.thresholds.splice(index, 1);\n this.panelCtrl.render();\n };\n ThresholdFormCtrl.prototype.render = function () {\n this.panelCtrl.render();\n };\n ThresholdFormCtrl.prototype.onFillColorChange = function (index) {\n var _this = this;\n return function (newColor) {\n _this.panel.thresholds[index].fillColor = newColor;\n _this.render();\n };\n };\n ThresholdFormCtrl.prototype.onLineColorChange = function (index) {\n var _this = this;\n return function (newColor) {\n _this.panel.thresholds[index].lineColor = newColor;\n _this.render();\n };\n };\n return ThresholdFormCtrl;\n}());\n\nvar template = \"\\n<div class=\\\"gf-form-group\\\">\\n <h5>Thresholds</h5>\\n <p class=\\\"muted\\\" ng-show=\\\"ctrl.disabled\\\">\\n Visual thresholds options <strong>disabled.</strong>\\n Visit the Alert tab update your thresholds. <br>\\n To re-enable thresholds, the alert rule must be deleted from this panel.\\n </p>\\n <div ng-class=\\\"{'thresholds-form-disabled': ctrl.disabled}\\\">\\n <div class=\\\"gf-form-inline\\\" ng-repeat=\\\"threshold in ctrl.panel.thresholds\\\">\\n <div class=\\\"gf-form\\\">\\n <label class=\\\"gf-form-label\\\">T{{$index+1}}</label>\\n </div>\\n\\n <div class=\\\"gf-form\\\">\\n <div class=\\\"gf-form-select-wrapper\\\">\\n <select class=\\\"gf-form-input\\\" ng-model=\\\"threshold.op\\\"\\n ng-options=\\\"f for f in ['gt', 'lt']\\\" ng-change=\\\"ctrl.render()\\\" ng-disabled=\\\"ctrl.disabled\\\"></select>\\n </div>\\n <input type=\\\"number\\\" ng-model=\\\"threshold.value\\\" class=\\\"gf-form-input width-8\\\"\\n ng-change=\\\"ctrl.render()\\\" placeholder=\\\"value\\\" ng-disabled=\\\"ctrl.disabled\\\">\\n </div>\\n\\n <div class=\\\"gf-form\\\">\\n <label class=\\\"gf-form-label\\\">Color</label>\\n <div class=\\\"gf-form-select-wrapper\\\">\\n <select class=\\\"gf-form-input\\\" ng-model=\\\"threshold.colorMode\\\"\\n ng-options=\\\"f for f in ['custom', 'critical', 'warning', 'ok']\\\" ng-change=\\\"ctrl.render()\\\" ng-disabled=\\\"ctrl.disabled\\\">\\n </select>\\n </div>\\n </div>\\n\\n <gf-form-switch class=\\\"gf-form\\\" label=\\\"Fill\\\" checked=\\\"threshold.fill\\\"\\n on-change=\\\"ctrl.render()\\\" ng-disabled=\\\"ctrl.disabled\\\"></gf-form-switch>\\n\\n <div class=\\\"gf-form\\\" ng-if=\\\"threshold.fill && threshold.colorMode === 'custom'\\\">\\n <label class=\\\"gf-form-label\\\">Fill color</label>\\n <span class=\\\"gf-form-label\\\">\\n <color-picker color=\\\"threshold.fillColor\\\" onChange=\\\"ctrl.onFillColorChange($index)\\\"></color-picker>\\n </span>\\n </div>\\n\\n <gf-form-switch class=\\\"gf-form\\\" label=\\\"Line\\\" checked=\\\"threshold.line\\\"\\n on-change=\\\"ctrl.render()\\\" ng-disabled=\\\"ctrl.disabled\\\"></gf-form-switch>\\n\\n <div class=\\\"gf-form\\\" ng-if=\\\"threshold.line && threshold.colorMode === 'custom'\\\">\\n <label class=\\\"gf-form-label\\\">Line color</label>\\n <span class=\\\"gf-form-label\\\">\\n <color-picker color=\\\"threshold.lineColor\\\" onChange=\\\"ctrl.onLineColorChange($index)\\\"></color-picker>\\n </span>\\n </div>\\n\\n <div class=\\\"gf-form\\\">\\n <label class=\\\"gf-form-label\\\">\\n <a class=\\\"pointer\\\" ng-click=\\\"ctrl.removeThreshold($index)\\\" ng-disabled=\\\"ctrl.disabled\\\">\\n <i class=\\\"fa fa-trash\\\"></i>\\n </a>\\n </label>\\n </div>\\n </div>\\n\\n <div class=\\\"gf-form-button-row\\\">\\n <button class=\\\"btn btn-inverse\\\" ng-click=\\\"ctrl.addThreshold()\\\" ng-disabled=\\\"ctrl.disabled\\\">\\n <i class=\\\"fa fa-plus\\\"></i> Add Threshold\\n </button>\\n </div>\\n </div>\\n</div>\\n\";\ngrafana_app_core_core_module__WEBPACK_IMPORTED_MODULE_0___default.a.directive('hasticGraphThresholdForm', function () {\n return {\n restrict: 'E',\n template: template,\n controller: ThresholdFormCtrl,\n bindToController: true,\n controllerAs: 'ctrl',\n scope: {\n panelCtrl: '=',\n },\n };\n});\n\n\n//# sourceURL=webpack:///./thresholds_form.ts?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.crosshair.js": |
|
/*!**********************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.crosshair.js ***! |
|
\**********************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("/* Flot plugin for showing crosshairs when the mouse hovers over the plot.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\n\tcrosshair: {\n\t\tmode: null or \"x\" or \"y\" or \"xy\"\n\t\tcolor: color\n\t\tlineWidth: number\n\t}\n\nSet the mode to one of \"x\", \"y\" or \"xy\". The \"x\" mode enables a vertical\ncrosshair that lets you trace the values on the x axis, \"y\" enables a\nhorizontal crosshair and \"xy\" enables them both. \"color\" is the color of the\ncrosshair (default is \"rgba(170, 0, 0, 0.80)\"), \"lineWidth\" is the width of\nthe drawn lines (default is 1).\n\nThe plugin also adds four public methods:\n\n - setCrosshair( pos )\n\n Set the position of the crosshair. Note that this is cleared if the user\n moves the mouse. \"pos\" is in coordinates of the plot and should be on the\n form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple\n axes), which is coincidentally the same format as what you get from a\n \"plothover\" event. If \"pos\" is null, the crosshair is cleared.\n\n - clearCrosshair()\n\n Clear the crosshair.\n\n - lockCrosshair(pos)\n\n Cause the crosshair to lock to the current location, no longer updating if\n the user moves the mouse. Optionally supply a position (passed on to\n setCrosshair()) to move it to.\n\n Example usage:\n\n\tvar myFlot = $.plot( $(\"#graph\"), ..., { crosshair: { mode: \"x\" } } };\n\t$(\"#graph\").bind( \"plothover\", function ( evt, position, item ) {\n\t\tif ( item ) {\n\t\t\t// Lock the crosshair to the data point being hovered\n\t\t\tmyFlot.lockCrosshair({\n\t\t\t\tx: item.datapoint[ 0 ],\n\t\t\t\ty: item.datapoint[ 1 ]\n\t\t\t});\n\t\t} else {\n\t\t\t// Return normal crosshair operation\n\t\t\tmyFlot.unlockCrosshair();\n\t\t}\n\t});\n\n - unlockCrosshair()\n\n Free the crosshair to move again after locking it.\n*/\n\n(function ($) {\n var options = {\n crosshair: {\n mode: null, // one of null, \"x\", \"y\" or \"xy\",\n color: \"rgba(170, 0, 0, 0.80)\",\n lineWidth: 1\n }\n };\n \n function init(plot) {\n // position of crosshair in pixels\n var crosshair = { x: -1, y: -1, locked: false };\n\n plot.setCrosshair = function setCrosshair(pos) {\n if (!pos)\n crosshair.x = -1;\n else {\n var o = plot.p2c(pos);\n crosshair.x = Math.max(0, Math.min(o.left, plot.width()));\n crosshair.y = Math.max(0, Math.min(o.top, plot.height()));\n }\n \n plot.triggerRedrawOverlay();\n };\n \n plot.clearCrosshair = plot.setCrosshair; // passes null for pos\n \n plot.lockCrosshair = function lockCrosshair(pos) {\n if (pos)\n plot.setCrosshair(pos);\n crosshair.locked = true;\n };\n\n plot.unlockCrosshair = function unlockCrosshair() {\n crosshair.locked = false;\n };\n\n function onMouseOut(e) {\n if (crosshair.locked)\n return;\n\n if (crosshair.x != -1) {\n crosshair.x = -1;\n plot.triggerRedrawOverlay();\n }\n }\n\n function onMouseMove(e) {\n if (crosshair.locked)\n return;\n \n if (plot.getSelection && plot.getSelection()) {\n crosshair.x = -1; // hide the crosshair while selecting\n return;\n }\n \n var offset = plot.offset();\n crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));\n crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));\n plot.triggerRedrawOverlay();\n }\n \n plot.hooks.bindEvents.push(function (plot, eventHolder) {\n if (!plot.getOptions().crosshair.mode)\n return;\n\n eventHolder.mouseout(onMouseOut);\n eventHolder.mousemove(onMouseMove);\n });\n\n plot.hooks.drawOverlay.push(function (plot, ctx) {\n var c = plot.getOptions().crosshair;\n if (!c.mode)\n return;\n\n var plotOffset = plot.getPlotOffset();\n \n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n\n if (crosshair.x != -1) {\n var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;\n\n ctx.strokeStyle = c.color;\n ctx.lineWidth = c.lineWidth;\n ctx.lineJoin = \"round\";\n\n ctx.beginPath();\n if (c.mode.indexOf(\"x\") != -1) {\n var drawX = Math.floor(crosshair.x) + adj;\n ctx.moveTo(drawX, 0);\n ctx.lineTo(drawX, plot.height());\n }\n if (c.mode.indexOf(\"y\") != -1) {\n var drawY = Math.floor(crosshair.y) + adj;\n ctx.moveTo(0, drawY);\n ctx.lineTo(plot.width(), drawY);\n }\n ctx.stroke();\n }\n ctx.restore();\n });\n\n plot.hooks.shutdown.push(function (plot, eventHolder) {\n eventHolder.unbind(\"mouseout\", onMouseOut);\n eventHolder.unbind(\"mousemove\", onMouseMove);\n });\n }\n \n $.plot.plugins.push({\n init: init,\n options: options,\n name: 'crosshair',\n version: '1.0'\n });\n})(jQuery);\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.crosshair.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.dashes.js": |
|
/*!*******************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.dashes.js ***! |
|
\*******************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("/*\n * jQuery.flot.dashes\n *\n * options = {\n * series: {\n * dashes: {\n *\n * // show\n * // default: false\n * // Whether to show dashes for the series.\n * show: <boolean>,\n *\n * // lineWidth\n * // default: 2\n * // The width of the dashed line in pixels.\n * lineWidth: <number>,\n *\n * // dashLength\n * // default: 10\n * // Controls the length of the individual dashes and the amount of\n * // space between them.\n * // If this is a number, the dashes and spaces will have that length.\n * // If this is an array, it is read as [ dashLength, spaceLength ]\n * dashLength: <number> or <array[2]>\n * }\n * }\n * }\n */\n(function($){\n\n function init(plot) {\n\n plot.hooks.processDatapoints.push(function(plot, series, datapoints) {\n\n if (!series.dashes.show) return;\n\n plot.hooks.draw.push(function(plot, ctx) {\n\n var plotOffset = plot.getPlotOffset(),\n axisx = series.xaxis,\n axisy = series.yaxis;\n\n function plotDashes(xoffset, yoffset) {\n\n var points = datapoints.points,\n ps = datapoints.pointsize,\n prevx = null,\n prevy = null,\n dashRemainder = 0,\n dashOn = true,\n dashOnLength,\n dashOffLength;\n\n if (series.dashes.dashLength[0]) {\n dashOnLength = series.dashes.dashLength[0];\n if (series.dashes.dashLength[1]) {\n dashOffLength = series.dashes.dashLength[1];\n } else {\n dashOffLength = dashOnLength;\n }\n } else {\n dashOffLength = dashOnLength = series.dashes.dashLength;\n }\n\n ctx.beginPath();\n\n for (var i = ps; i < points.length; i += ps) {\n\n var x1 = points[i - ps],\n y1 = points[i - ps + 1],\n x2 = points[i],\n y2 = points[i + 1];\n\n if (x1 == null || x2 == null) continue;\n\n // clip with ymin\n if (y1 <= y2 && y1 < axisy.min) {\n if (y2 < axisy.min) continue; // line segment is outside\n // compute new intersection point\n x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n y1 = axisy.min;\n } else if (y2 <= y1 && y2 < axisy.min) {\n if (y1 < axisy.min) continue;\n x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n y2 = axisy.min;\n }\n\n // clip with ymax\n if (y1 >= y2 && y1 > axisy.max) {\n if (y2 > axisy.max) continue;\n x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n y1 = axisy.max;\n } else if (y2 >= y1 && y2 > axisy.max) {\n if (y1 > axisy.max) continue;\n x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n y2 = axisy.max;\n }\n\n // clip with xmin\n if (x1 <= x2 && x1 < axisx.min) {\n if (x2 < axisx.min) continue;\n y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n x1 = axisx.min;\n } else if (x2 <= x1 && x2 < axisx.min) {\n if (x1 < axisx.min) continue;\n y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n x2 = axisx.min;\n }\n\n // clip with xmax\n if (x1 >= x2 && x1 > axisx.max) {\n if (x2 > axisx.max) continue;\n y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n x1 = axisx.max;\n } else if (x2 >= x1 && x2 > axisx.max) {\n if (x1 > axisx.max) continue;\n y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n x2 = axisx.max;\n }\n\n if (x1 != prevx || y1 != prevy) {\n ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);\n }\n\n var ax1 = axisx.p2c(x1) + xoffset,\n ay1 = axisy.p2c(y1) + yoffset,\n ax2 = axisx.p2c(x2) + xoffset,\n ay2 = axisy.p2c(y2) + yoffset,\n dashOffset;\n\n function lineSegmentOffset(segmentLength) {\n\n var c = Math.sqrt(Math.pow(ax2 - ax1, 2) + Math.pow(ay2 - ay1, 2));\n\n if (c <= segmentLength) {\n return {\n deltaX: ax2 - ax1,\n deltaY: ay2 - ay1,\n distance: c,\n remainder: segmentLength - c\n }\n } else {\n var xsign = ax2 > ax1 ? 1 : -1,\n ysign = ay2 > ay1 ? 1 : -1;\n return {\n deltaX: xsign * Math.sqrt(Math.pow(segmentLength, 2) / (1 + Math.pow((ay2 - ay1)/(ax2 - ax1), 2))),\n deltaY: ysign * Math.sqrt(Math.pow(segmentLength, 2) - Math.pow(segmentLength, 2) / (1 + Math.pow((ay2 - ay1)/(ax2 - ax1), 2))),\n distance: segmentLength,\n remainder: 0\n };\n }\n }\n //-end lineSegmentOffset\n\n do {\n\n dashOffset = lineSegmentOffset(\n dashRemainder > 0 ? dashRemainder :\n dashOn ? dashOnLength : dashOffLength);\n\n if (dashOffset.deltaX != 0 || dashOffset.deltaY != 0) {\n if (dashOn) {\n ctx.lineTo(ax1 + dashOffset.deltaX, ay1 + dashOffset.deltaY);\n } else {\n ctx.moveTo(ax1 + dashOffset.deltaX, ay1 + dashOffset.deltaY);\n }\n }\n\n dashOn = !dashOn;\n dashRemainder = dashOffset.remainder;\n ax1 += dashOffset.deltaX;\n ay1 += dashOffset.deltaY;\n\n } while (dashOffset.distance > 0);\n\n prevx = x2;\n prevy = y2;\n }\n\n ctx.stroke();\n }\n //-end plotDashes\n\n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n ctx.lineJoin = 'round';\n\n var lw = series.dashes.lineWidth,\n sw = series.shadowSize;\n\n // FIXME: consider another form of shadow when filling is turned on\n if (lw > 0 && sw > 0) {\n // draw shadow as a thick and thin line with transparency\n ctx.lineWidth = sw;\n ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n // position shadow at angle from the mid of line\n var angle = Math.PI/18;\n plotDashes(Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2));\n ctx.lineWidth = sw/2;\n plotDashes(Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4));\n }\n\n ctx.lineWidth = lw;\n ctx.strokeStyle = series.color;\n\n if (lw > 0) {\n plotDashes(0, 0);\n }\n\n ctx.restore();\n\n });\n //-end draw hook\n\n });\n //-end processDatapoints hook\n\n }\n //-end init\n\n $.plot.plugins.push({\n init: init,\n options: {\n series: {\n dashes: {\n show: false,\n lineWidth: 2,\n dashLength: 10\n }\n }\n },\n name: 'dashes',\n version: '0.1'\n });\n\n})(jQuery)\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.dashes.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.events.js": |
|
/*!*******************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.events.js ***! |
|
\*******************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n __webpack_require__(/*! jquery */ \"jquery\"),\n __webpack_require__(/*! lodash */ \"lodash\"),\n __webpack_require__(/*! angular */ \"angular\"),\n __webpack_require__(/*! tether-drop */ \"../node_modules/tether-drop/dist/js/drop.js\"),\n], __WEBPACK_AMD_DEFINE_RESULT__ = (function ($, _, angular, Drop) {\n 'use strict';\n\n function createAnnotationToolip(element, event, plot) {\n var injector = angular.element(document).injector();\n var content = document.createElement('div');\n content.innerHTML = '<annotation-tooltip event=\"event\" on-edit=\"onEdit()\"></annotation-tooltip>';\n\n injector.invoke([\"$compile\", \"$rootScope\", function($compile, $rootScope) {\n var eventManager = plot.getOptions().events.manager;\n var tmpScope = $rootScope.$new(true);\n tmpScope.event = event;\n tmpScope.onEdit = function() {\n eventManager.editEvent(event);\n };\n\n $compile(content)(tmpScope);\n tmpScope.$digest();\n tmpScope.$destroy();\n\n var drop = new Drop({\n target: element[0],\n content: content,\n position: \"bottom center\",\n classes: 'drop-popover drop-popover--annotation',\n openOn: 'hover',\n hoverCloseDelay: 200,\n tetherOptions: {\n constraints: [{to: 'window', pin: true, attachment: \"both\"}]\n }\n });\n\n drop.open();\n\n drop.on('close', function() {\n setTimeout(function() {\n drop.destroy();\n });\n });\n }]);\n }\n\n var markerElementToAttachTo = null;\n\n function createEditPopover(element, event, plot) {\n var eventManager = plot.getOptions().events.manager;\n if (eventManager.editorOpen) {\n // update marker element to attach to (needed in case of legend on the right\n // when there is a double render pass and the inital marker element is removed)\n markerElementToAttachTo = element;\n return;\n }\n\n // mark as openend\n eventManager.editorOpened();\n // set marker elment to attache to\n markerElementToAttachTo = element;\n\n // wait for element to be attached and positioned\n setTimeout(function() {\n\n var injector = angular.element(document).injector();\n var content = document.createElement('div');\n content.innerHTML = '<event-editor panel-ctrl=\"panelCtrl\" event=\"event\" close=\"close()\"></event-editor>';\n\n injector.invoke([\"$compile\", \"$rootScope\", function($compile, $rootScope) {\n var scope = $rootScope.$new(true);\n var drop;\n\n scope.event = event;\n scope.panelCtrl = eventManager.panelCtrl;\n scope.close = function() {\n drop.close();\n };\n\n $compile(content)(scope);\n scope.$digest();\n\n drop = new Drop({\n target: markerElementToAttachTo[0],\n content: content,\n position: \"bottom center\",\n classes: 'drop-popover drop-popover--form',\n openOn: 'click',\n tetherOptions: {\n constraints: [{to: 'window', pin: true, attachment: \"both\"}]\n }\n });\n\n drop.open();\n eventManager.editorOpened();\n\n drop.on('close', function() {\n // need timeout here in order call drop.destroy\n setTimeout(function() {\n eventManager.editorClosed();\n scope.$destroy();\n drop.destroy();\n });\n });\n }]);\n\n }, 100);\n }\n\n /*\n * jquery.flot.events\n *\n * description: Flot plugin for adding events/markers to the plot\n * version: 0.2.5\n * authors:\n * Alexander Wunschik <alex@wunschik.net>\n * Joel Oughton <joeloughton@gmail.com>\n * Nicolas Joseph <www.nicolasjoseph.com>\n *\n * website: https://github.com/mojoaxel/flot-events\n *\n * released under MIT License and GPLv2+\n */\n\n /**\n * A class that allows for the drawing an remove of some object\n */\n var DrawableEvent = function(object, drawFunc, clearFunc, moveFunc, left, top, width, height) {\n var _object = object;\n var\t_drawFunc = drawFunc;\n var\t_clearFunc = clearFunc;\n var\t_moveFunc = moveFunc;\n var\t_position = { left: left, top: top };\n var\t_width = width;\n var\t_height = height;\n\n this.width = function() { return _width; };\n this.height = function() { return _height; };\n this.position = function() { return _position; };\n this.draw = function() { _drawFunc(_object); };\n this.clear = function() { _clearFunc(_object); };\n this.getObject = function() { return _object; };\n this.moveTo = function(position) {\n _position = position;\n _moveFunc(_object, _position);\n };\n };\n\n /**\n * Event class that stores options (eventType, min, max, title, description) and the object to draw.\n */\n var VisualEvent = function(options, drawableEvent) {\n var _parent;\n var _options = options;\n var _drawableEvent = drawableEvent;\n var _hidden = false;\n\n this.visual = function() { return _drawableEvent; };\n this.getOptions = function() { return _options; };\n this.getParent = function() { return _parent; };\n this.isHidden = function() { return _hidden; };\n this.hide = function() { _hidden = true; };\n this.unhide = function() { _hidden = false; };\n };\n\n /**\n * A Class that handles the event-markers inside the given plot\n */\n var EventMarkers = function(plot) {\n var _events = [];\n\n this._types = [];\n this._plot = plot;\n this.eventsEnabled = false;\n\n this.getEvents = function() {\n return _events;\n };\n\n this.setTypes = function(types) {\n return this._types = types;\n };\n\n /**\n * create internal objects for the given events\n */\n this.setupEvents = function(events) {\n var that = this;\n var parts = _.partition(events, 'isRegion');\n var regions = parts[0];\n events = parts[1];\n\n $.each(events, function(index, event) {\n var ve = new VisualEvent(event, that._buildDiv(event));\n _events.push(ve);\n });\n\n $.each(regions, function (index, event) {\n var vre = new VisualEvent(event, that._buildRegDiv(event));\n _events.push(vre);\n });\n\n _events.sort(function(a, b) {\n var ao = a.getOptions(), bo = b.getOptions();\n if (ao.min > bo.min) { return 1; }\n if (ao.min < bo.min) { return -1; }\n return 0;\n });\n };\n\n /**\n * draw the events to the plot\n */\n this.drawEvents = function() {\n var that = this;\n // var o = this._plot.getPlotOffset();\n\n $.each(_events, function(index, event) {\n // check event is inside the graph range\n if (that._insidePlot(event.getOptions().min) && !event.isHidden()) {\n event.visual().draw();\n } else {\n event.visual().getObject().hide();\n }\n });\n };\n\n /**\n * update the position of the event-markers (e.g. after scrolling or zooming)\n */\n this.updateEvents = function() {\n var that = this;\n var o = this._plot.getPlotOffset(), left, top;\n var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];\n\n $.each(_events, function(index, event) {\n top = o.top + that._plot.height() - event.visual().height();\n left = xaxis.p2c(event.getOptions().min) + o.left - event.visual().width() / 2;\n event.visual().moveTo({ top: top, left: left });\n });\n };\n\n /**\n * remove all events from the plot\n */\n this._clearEvents = function() {\n $.each(_events, function(index, val) {\n val.visual().clear();\n });\n _events = [];\n };\n\n /**\n * create a DOM element for the given event\n */\n this._buildDiv = function(event) {\n var that = this;\n\n var container = this._plot.getPlaceholder();\n var o = this._plot.getPlotOffset();\n var axes = this._plot.getAxes();\n var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];\n var yaxis, top, left, color, markerSize, markerShow, lineStyle, lineWidth;\n var markerTooltip;\n\n // determine the y axis used\n if (axes.yaxis && axes.yaxis.used) { yaxis = axes.yaxis; }\n if (axes.yaxis2 && axes.yaxis2.used) { yaxis = axes.yaxis2; }\n\n // map the eventType to a types object\n var eventTypeId = event.eventType;\n\n if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) {\n color = '#666';\n } else {\n color = this._types[eventTypeId].color;\n }\n\n if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].markerSize) {\n markerSize = 8; //default marker size\n } else {\n markerSize = this._types[eventTypeId].markerSize;\n }\n\n if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerShow === undefined) {\n markerShow = true;\n } else {\n markerShow = this._types[eventTypeId].markerShow;\n }\n\n if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerTooltip === undefined) {\n markerTooltip = true;\n } else {\n markerTooltip = this._types[eventTypeId].markerTooltip;\n }\n\n if (this._types == null || !this._types[eventTypeId] || !this._types[eventTypeId].lineStyle) {\n lineStyle = 'dashed'; //default line style\n } else {\n lineStyle = this._types[eventTypeId].lineStyle.toLowerCase();\n }\n\n if (this._types == null || !this._types[eventTypeId] || this._types[eventTypeId].lineWidth === undefined) {\n lineWidth = 1; //default line width\n } else {\n lineWidth = this._types[eventTypeId].lineWidth;\n }\n\n var topOffset = xaxis.options.eventSectionHeight || 0;\n topOffset = topOffset / 3;\n\n top = o.top + this._plot.height() + topOffset;\n left = xaxis.p2c(event.min) + o.left;\n\n var line = $('<div class=\"events_line flot-temp-elem\"></div>').css({\n \"position\": \"absolute\",\n \"opacity\": 0.8,\n \"left\": left + 'px',\n \"top\": 8,\n \"width\": lineWidth + \"px\",\n \"height\": this._plot.height() + topOffset * 0.8,\n \"border-left-width\": lineWidth + \"px\",\n \"border-left-style\": lineStyle,\n \"border-left-color\": color,\n \"color\": color\n })\n .appendTo(container);\n\n if (markerShow) {\n var marker = $('<div class=\"events_marker\"></div>').css({\n \"position\": \"absolute\",\n \"left\": (-markerSize - Math.round(lineWidth / 2)) + \"px\",\n \"font-size\": 0,\n \"line-height\": 0,\n \"width\": 0,\n \"height\": 0,\n \"border-left\": markerSize+\"px solid transparent\",\n \"border-right\": markerSize+\"px solid transparent\"\n });\n\n marker.appendTo(line);\n\n if (this._types[eventTypeId] && this._types[eventTypeId].position && this._types[eventTypeId].position.toUpperCase() === 'BOTTOM') {\n marker.css({\n \"top\": top-markerSize-8 +\"px\",\n \"border-top\": \"none\",\n \"border-bottom\": markerSize+\"px solid \" + color\n });\n } else {\n marker.css({\n \"top\": \"0px\",\n \"border-top\": markerSize+\"px solid \" + color,\n \"border-bottom\": \"none\"\n });\n }\n\n marker.data({\n \"event\": event\n });\n\n var mouseenter = function() {\n createAnnotationToolip(marker, $(this).data(\"event\"), that._plot);\n };\n\n if (event.editModel) {\n createEditPopover(marker, event.editModel, that._plot);\n }\n\n var mouseleave = function() {\n that._plot.clearSelection();\n };\n\n if (markerTooltip) {\n marker.css({ \"cursor\": \"help\" });\n marker.hover(mouseenter, mouseleave);\n }\n }\n\n var drawableEvent = new DrawableEvent(\n line,\n function drawFunc(obj) { obj.show(); },\n function(obj) { obj.remove(); },\n function(obj, position) {\n obj.css({\n top: position.top,\n left: position.left\n });\n },\n left,\n top,\n line.width(),\n line.height()\n );\n\n return drawableEvent;\n };\n\n /**\n * create a DOM element for the given region\n */\n this._buildRegDiv = function (event) {\n var that = this;\n\n var container = this._plot.getPlaceholder();\n var o = this._plot.getPlotOffset();\n var axes = this._plot.getAxes();\n var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];\n var yaxis, top, left, lineWidth, regionWidth, lineStyle, color, markerTooltip;\n\n // determine the y axis used\n if (axes.yaxis && axes.yaxis.used) { yaxis = axes.yaxis; }\n if (axes.yaxis2 && axes.yaxis2.used) { yaxis = axes.yaxis2; }\n\n // map the eventType to a types object\n var eventTypeId = event.eventType;\n\n if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) {\n color = '#666';\n } else {\n color = this._types[eventTypeId].color;\n }\n\n if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerTooltip === undefined) {\n markerTooltip = true;\n } else {\n markerTooltip = this._types[eventTypeId].markerTooltip;\n }\n\n if (this._types == null || !this._types[eventTypeId] || this._types[eventTypeId].lineWidth === undefined) {\n lineWidth = 1; //default line width\n } else {\n lineWidth = this._types[eventTypeId].lineWidth;\n }\n\n if (this._types == null || !this._types[eventTypeId] || !this._types[eventTypeId].lineStyle) {\n lineStyle = 'dashed'; //default line style\n } else {\n lineStyle = this._types[eventTypeId].lineStyle.toLowerCase();\n }\n\n var topOffset = 2;\n top = o.top + this._plot.height() + topOffset;\n\n var timeFrom = Math.min(event.min, event.timeEnd);\n var timeTo = Math.max(event.min, event.timeEnd);\n left = xaxis.p2c(timeFrom) + o.left;\n var right = xaxis.p2c(timeTo) + o.left;\n regionWidth = right - left;\n\n _.each([left, right], function(position) {\n var line = $('<div class=\"events_line flot-temp-elem\"></div>').css({\n \"position\": \"absolute\",\n \"opacity\": 0.8,\n \"left\": position + 'px',\n \"top\": 8,\n \"width\": lineWidth + \"px\",\n \"height\": that._plot.height() + topOffset,\n \"border-left-width\": lineWidth + \"px\",\n \"border-left-style\": lineStyle,\n \"border-left-color\": color,\n \"color\": color\n });\n line.appendTo(container);\n });\n\n var region = $('<div class=\"events_marker region_marker flot-temp-elem\"></div>').css({\n \"position\": \"absolute\",\n \"opacity\": 0.5,\n \"left\": left + 'px',\n \"top\": top,\n \"width\": Math.round(regionWidth + lineWidth) + \"px\",\n \"height\": \"0.5rem\",\n \"border-left-color\": color,\n \"color\": color,\n \"background-color\": color\n });\n region.appendTo(container);\n\n region.data({\n \"event\": event\n });\n\n var mouseenter = function () {\n createAnnotationToolip(region, $(this).data(\"event\"), that._plot);\n };\n\n if (event.editModel) {\n createEditPopover(region, event.editModel, that._plot);\n }\n\n var mouseleave = function () {\n that._plot.clearSelection();\n };\n\n if (markerTooltip) {\n region.css({ \"cursor\": \"help\" });\n region.hover(mouseenter, mouseleave);\n }\n\n var drawableEvent = new DrawableEvent(\n region,\n function drawFunc(obj) { obj.show(); },\n function (obj) { obj.remove(); },\n function (obj, position) {\n obj.css({\n top: position.top,\n left: position.left\n });\n },\n left,\n top,\n region.width(),\n region.height()\n );\n\n return drawableEvent;\n };\n\n /**\n * check if the event is inside visible range\n */\n this._insidePlot = function(x) {\n var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1];\n var xc = xaxis.p2c(x);\n return xc > 0 && xc < xaxis.p2c(xaxis.max);\n };\n };\n\n /**\n * initialize the plugin for the given plot\n */\n function init(plot) {\n /*jshint validthis:true */\n var that = this;\n var eventMarkers = new EventMarkers(plot);\n\n plot.getEvents = function() {\n return eventMarkers._events;\n };\n\n plot.hideEvents = function() {\n $.each(eventMarkers._events, function(index, event) {\n event.visual().getObject().hide();\n });\n };\n\n plot.showEvents = function() {\n plot.hideEvents();\n $.each(eventMarkers._events, function(index, event) {\n event.hide();\n });\n\n that.eventMarkers.drawEvents();\n };\n\n // change events on an existing plot\n plot.setEvents = function(events) {\n if (eventMarkers.eventsEnabled) {\n eventMarkers.setupEvents(events);\n }\n };\n\n plot.hooks.processOptions.push(function(plot, options) {\n // enable the plugin\n if (options.events.data != null) {\n eventMarkers.eventsEnabled = true;\n }\n });\n\n plot.hooks.draw.push(function(plot) {\n var options = plot.getOptions();\n\n if (eventMarkers.eventsEnabled) {\n // check for first run\n if (eventMarkers.getEvents().length < 1) {\n eventMarkers.setTypes(options.events.types);\n eventMarkers.setupEvents(options.events.data);\n } else {\n eventMarkers.updateEvents();\n }\n }\n\n eventMarkers.drawEvents();\n });\n }\n\n var defaultOptions = {\n events: {\n data: null,\n types: null,\n xaxis: 1,\n position: 'BOTTOM'\n }\n };\n\n $.plot.plugins.push({\n init: init,\n options: defaultOptions,\n name: \"events\",\n version: \"0.2.5\"\n });\n}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.events.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.fillbelow.js": |
|
/*!**********************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.fillbelow.js ***! |
|
\**********************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("(function($) {\n \"use strict\";\n\n var options = {\n series: {\n fillBelowTo: null\n }\n };\n\n function init(plot) {\n function findBelowSeries( series, allseries ) {\n\n var i;\n\n for ( i = 0; i < allseries.length; ++i ) {\n if ( allseries[ i ].id === series.fillBelowTo ) {\n return allseries[ i ];\n }\n }\n\n return null;\n }\n\n /* top and bottom doesn't actually matter for this, we're just using it to help make this easier to think about */\n /* this is a vector cross product operation */\n function segmentIntersection(top_left_x, top_left_y, top_right_x, top_right_y, bottom_left_x, bottom_left_y, bottom_right_x, bottom_right_y) {\n var top_delta_x, top_delta_y, bottom_delta_x, bottom_delta_y,\n s, t;\n\n top_delta_x = top_right_x - top_left_x;\n top_delta_y = top_right_y - top_left_y;\n bottom_delta_x = bottom_right_x - bottom_left_x;\n bottom_delta_y = bottom_right_y - bottom_left_y;\n\n s = (\n (-top_delta_y * (top_left_x - bottom_left_x)) + (top_delta_x * (top_left_y - bottom_left_y))\n ) / (\n -bottom_delta_x * top_delta_y + top_delta_x * bottom_delta_y\n );\n\n t = (\n (bottom_delta_x * (top_left_y - bottom_left_y)) - (bottom_delta_y * (top_left_x - bottom_left_x))\n ) / (\n -bottom_delta_x * top_delta_y + top_delta_x * bottom_delta_y\n );\n\n // Collision detected\n if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {\n return [\n top_left_x + (t * top_delta_x), // X\n top_left_y + (t * top_delta_y) // Y\n ];\n }\n\n // No collision\n return null;\n }\n\n function plotDifferenceArea(plot, ctx, series) {\n if ( series.fillBelowTo === null ) {\n return;\n }\n\n var otherseries,\n\n ps,\n points,\n\n otherps,\n otherpoints,\n\n plotOffset,\n fillStyle;\n\n function openPolygon(x, y) {\n ctx.beginPath();\n ctx.moveTo(\n series.xaxis.p2c(x) + plotOffset.left,\n series.yaxis.p2c(y) + plotOffset.top\n );\n\n }\n\n function closePolygon() {\n ctx.closePath();\n ctx.fill();\n }\n\n function validateInput() {\n if (points.length/ps !== otherpoints.length/otherps) {\n console.error(\"Refusing to graph inconsistent number of points\");\n return false;\n }\n\n var i;\n for (i = 0; i < (points.length / ps); i++) {\n if (\n points[i * ps] !== null &&\n otherpoints[i * otherps] !== null &&\n points[i * ps] !== otherpoints[i * otherps]\n ) {\n console.error(\"Refusing to graph points without matching value\");\n return false;\n }\n }\n\n return true;\n }\n\n function findNextStart(start_i, end_i) {\n console.assert(end_i > start_i, \"expects the end index to be greater than the start index\");\n\n var start = (\n start_i === 0 ||\n points[start_i - 1] === null ||\n otherpoints[start_i - 1] === null\n ),\n equal = false,\n i,\n intersect;\n\n for (i = start_i; i < end_i; i++) {\n // Take note of null points\n if (\n points[(i * ps) + 1] === null ||\n otherpoints[(i * ps) + 1] === null\n ) {\n equal = false;\n start = true;\n }\n\n // Take note of equal points\n else if (points[(i * ps) + 1] === otherpoints[(i * otherps) + 1]) {\n equal = true;\n start = false;\n }\n\n\n else if (points[(i * ps) + 1] > otherpoints[(i * otherps) + 1]) {\n // If we begin above the desired point\n if (start) {\n openPolygon(points[i * ps], points[(i * ps) + 1]);\n }\n\n // If an equal point preceeds this, start the polygon at that equal point\n else if (equal) {\n openPolygon(points[(i - 1) * ps], points[((i - 1) * ps) + 1]);\n }\n\n // Otherwise, find the intersection point, and start it there\n else {\n intersect = intersectionPoint(i);\n openPolygon(intersect[0], intersect[1]);\n }\n\n topTraversal(i, end_i);\n return;\n }\n\n // If we go below equal, equal at any preceeding point is irrelevant\n else {\n start = false;\n equal = false;\n }\n }\n }\n\n function intersectionPoint(right_i) {\n console.assert(right_i > 0, \"expects the second point in the series line segment\");\n\n var i, intersect;\n\n for (i = 1; i < (otherpoints.length/otherps); i++) {\n intersect = segmentIntersection(\n points[(right_i - 1) * ps], points[((right_i - 1) * ps) + 1],\n points[right_i * ps], points[(right_i * ps) + 1],\n\n otherpoints[(i - 1) * otherps], otherpoints[((i - 1) * otherps) + 1],\n otherpoints[i * otherps], otherpoints[(i * otherps) + 1]\n );\n\n if (intersect !== null) {\n return intersect;\n }\n }\n\n console.error(\"intersectionPoint() should only be called when an intersection happens\");\n }\n\n function bottomTraversal(start_i, end_i) {\n console.assert(start_i >= end_i, \"the start should be the rightmost point, and the end should be the leftmost (excluding the equal or intersecting point)\");\n\n var i;\n\n for (i = start_i; i >= end_i; i--) {\n ctx.lineTo(\n otherseries.xaxis.p2c(otherpoints[i * otherps]) + plotOffset.left,\n otherseries.yaxis.p2c(otherpoints[(i * otherps) + 1]) + plotOffset.top\n );\n }\n\n closePolygon();\n }\n\n function topTraversal(start_i, end_i) {\n console.assert(start_i <= end_i, \"the start should be the rightmost point, and the end should be the leftmost (excluding the equal or intersecting point)\");\n\n var i,\n intersect;\n\n for (i = start_i; i < end_i; i++) {\n if (points[(i * ps) + 1] === null && i > start_i) {\n bottomTraversal(i - 1, start_i);\n findNextStart(i, end_i);\n return;\n }\n\n else if (points[(i * ps) + 1] === otherpoints[(i * otherps) + 1]) {\n bottomTraversal(i, start_i);\n findNextStart(i, end_i);\n return;\n }\n\n else if (points[(i * ps) + 1] < otherpoints[(i * otherps) + 1]) {\n intersect = intersectionPoint(i);\n ctx.lineTo(\n series.xaxis.p2c(intersect[0]) + plotOffset.left,\n series.yaxis.p2c(intersect[1]) + plotOffset.top\n );\n bottomTraversal(i, start_i);\n findNextStart(i, end_i);\n return;\n\n }\n\n else {\n ctx.lineTo(\n series.xaxis.p2c(points[i * ps]) + plotOffset.left,\n series.yaxis.p2c(points[(i * ps) + 1]) + plotOffset.top\n );\n }\n }\n\n bottomTraversal(end_i, start_i);\n }\n\n\n // Begin processing\n\n otherseries = findBelowSeries( series, plot.getData() );\n\n if ( !otherseries ) {\n return;\n }\n\n ps = series.datapoints.pointsize;\n points = series.datapoints.points;\n otherps = otherseries.datapoints.pointsize;\n otherpoints = otherseries.datapoints.points;\n plotOffset = plot.getPlotOffset();\n\n if (!validateInput()) {\n return;\n }\n\n\n // Flot's getFillStyle() should probably be exposed somewhere\n fillStyle = $.color.parse(series.color);\n fillStyle.a = 0.4;\n fillStyle.normalize();\n ctx.fillStyle = fillStyle.toString();\n\n\n // Begin recursive bi-directional traversal\n findNextStart(0, points.length/ps);\n }\n\n plot.hooks.drawSeries.push(plotDifferenceArea);\n }\n\n $.plot.plugins.push({\n init: init,\n options: options,\n name: \"fillbelow\",\n version: \"0.1.0\"\n });\n\n})(jQuery);\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.fillbelow.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.js": |
|
/*!************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.js ***! |
|
\************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("/* Javascript plotting library for jQuery, version 0.8.3.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\n*/\n\n// first an inline dependency, jquery.colorhelpers.js, we inline it here\n// for convenience\n\n/* Plugin for jQuery for working with colors.\n *\n * Version 1.1.\n *\n * Inspiration from jQuery color animation plugin by John Resig.\n *\n * Released under the MIT license by Ole Laursen, October 2009.\n *\n * Examples:\n *\n * $.color.parse(\"#fff\").scale('rgb', 0.25).add('a', -0.5).toString()\n * var c = $.color.extract($(\"#mydiv\"), 'background-color');\n * console.log(c.r, c.g, c.b, c.a);\n * $.color.make(100, 50, 25, 0.4).toString() // returns \"rgba(100,50,25,0.4)\"\n *\n * Note that .scale() and .add() return the same modified object\n * instead of making a new one.\n *\n * V. 1.1: Fix error handling so e.g. parsing an empty string does\n * produce a color rather than just crashing.\n */\n(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return\"rgb(\"+[o.r,o.g,o.b].join(\",\")+\")\"}else{return\"rgba(\"+[o.r,o.g,o.b,o.a].join(\",\")+\")\"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=\"\"&&c!=\"transparent\")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),\"body\"));if(c==\"rgba(0, 0, 0, 0)\")c=\"transparent\";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name==\"transparent\")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],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],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);\n\n// the actual Flot code\n(function($) {\n\n\t// Cache the prototype hasOwnProperty for faster access\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM\n // operation produces the same effect as detach, i.e. removing the element\n // without touching its jQuery data.\n\n // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.\n\n if (!$.fn.detach) {\n $.fn.detach = function() {\n return this.each(function() {\n if (this.parentNode) {\n this.parentNode.removeChild( this );\n }\n });\n };\n }\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The Canvas object is a wrapper around an HTML5 <canvas> tag.\n\t//\n\t// @constructor\n\t// @param {string} cls List of classes to apply to the canvas.\n\t// @param {element} container Element onto which to append the canvas.\n\t//\n\t// Requiring a container is a little iffy, but unfortunately canvas\n\t// operations don't work unless the canvas is attached to the DOM.\n\n\tfunction Canvas(cls, container) {\n\n\t\tvar element = container.children(\".\" + cls)[0];\n\n\t\tif (element == null) {\n\n\t\t\telement = document.createElement(\"canvas\");\n\t\t\telement.className = cls;\n\n\t\t\t$(element).css({ direction: \"ltr\", position: \"absolute\", left: 0, top: 0 })\n\t\t\t\t.appendTo(container);\n\n\t\t\t// If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas\n\n\t\t\tif (!element.getContext) {\n\t\t\t\tif (window.G_vmlCanvasManager) {\n\t\t\t\t\telement = window.G_vmlCanvasManager.initElement(element);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element = element;\n\n\t\tvar context = this.context = element.getContext(\"2d\");\n\n\t\t// Determine the screen's ratio of physical to device-independent\n\t\t// pixels. This is the ratio between the canvas width that the browser\n\t\t// advertises and the number of pixels actually present in that space.\n\n\t\t// The iPhone 4, for example, has a device-independent width of 320px,\n\t\t// but its screen is actually 640px wide. It therefore has a pixel\n\t\t// ratio of 2, while most normal devices have a ratio of 1.\n\n\t\tvar devicePixelRatio = window.devicePixelRatio || 1,\n\t\t\tbackingStoreRatio =\n\t\t\t\tcontext.webkitBackingStorePixelRatio ||\n\t\t\t\tcontext.mozBackingStorePixelRatio ||\n\t\t\t\tcontext.msBackingStorePixelRatio ||\n\t\t\t\tcontext.oBackingStorePixelRatio ||\n\t\t\t\tcontext.backingStorePixelRatio || 1;\n\n\t\tthis.pixelRatio = devicePixelRatio / backingStoreRatio;\n\n\t\t// Size the canvas to match the internal dimensions of its container\n\n\t\tthis.resize(container.width(), container.height());\n\n\t\t// Collection of HTML div layers for text overlaid onto the canvas\n\n\t\tthis.textContainer = null;\n\t\tthis.text = {};\n\n\t\t// Cache of text fragments and metrics, so we can avoid expensively\n\t\t// re-calculating them when the plot is re-rendered in a loop.\n\n\t\tthis._textCache = {};\n\t\tthis._textSizeCache = window.flotTextSizeCache = window.flotTextSizeCache || {};\n\t}\n\n\t// Resizes the canvas to the given dimensions.\n\t//\n\t// @param {number} width New width of the canvas, in pixels.\n\t// @param {number} width New height of the canvas, in pixels.\n\n\tCanvas.prototype.resize = function(width, height) {\n\n\t\tif (width <= 0 || height <= 0) {\n\t\t\tthrow new Error(\"Invalid dimensions for plot, width = \" + width + \", height = \" + height);\n\t\t}\n\n\t\tvar element = this.element,\n\t\t\tcontext = this.context,\n\t\t\tpixelRatio = this.pixelRatio;\n\n\t\t// Resize the canvas, increasing its density based on the display's\n\t\t// pixel ratio; basically giving it more pixels without increasing the\n\t\t// size of its element, to take advantage of the fact that retina\n\t\t// displays have that many more pixels in the same advertised space.\n\n\t\t// Resizing should reset the state (excanvas seems to be buggy though)\n\n\t\tif (this.width != width) {\n\t\t\telement.width = width * pixelRatio;\n\t\t\telement.style.width = width + \"px\";\n\t\t\tthis.width = width;\n\t\t}\n\n\t\tif (this.height != height) {\n\t\t\telement.height = height * pixelRatio;\n\t\t\telement.style.height = height + \"px\";\n\t\t\tthis.height = height;\n\t\t}\n\n\t\t// Save the context, so we can reset in case we get replotted. The\n\t\t// restore ensure that we're really back at the initial state, and\n\t\t// should be safe even if we haven't saved the initial state yet.\n\n\t\tcontext.restore();\n\t\tcontext.save();\n\n\t\t// Scale the coordinate space to match the display density; so even though we\n\t\t// may have twice as many pixels, we still want lines and other drawing to\n\t\t// appear at the same size; the extra pixels will just make them crisper.\n\n\t\tcontext.scale(pixelRatio, pixelRatio);\n\t};\n\n\t// Clears the entire canvas area, not including any overlaid HTML text\n\n\tCanvas.prototype.clear = function() {\n\t\tthis.context.clearRect(0, 0, this.width, this.height);\n\t};\n\n\t// Finishes rendering the canvas, including managing the text overlay.\n\n\tCanvas.prototype.render = function() {\n\n\t\tvar cache = this._textCache;\n\n\t\t// For each text layer, add elements marked as active that haven't\n\t\t// already been rendered, and remove those that are no longer active.\n\n\t\tfor (var layerKey in cache) {\n\t\t\tif (hasOwnProperty.call(cache, layerKey)) {\n\n\t\t\t\tvar layer = this.getTextLayer(layerKey),\n\t\t\t\t\tlayerCache = cache[layerKey];\n\n\t\t\t\tlayer.hide();\n\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tif (position.active) {\n\t\t\t\t\t\t\t\t\t\tif (!position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tlayer.append(position.element);\n\t\t\t\t\t\t\t\t\t\t\tposition.rendered = true;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tpositions.splice(i--, 1);\n\t\t\t\t\t\t\t\t\t\tif (position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tposition.element.detach();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (positions.length == 0) {\n\t\t\t\t\t\t\t\t\tdelete styleCache[key];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlayer.show();\n\t\t\t}\n\t\t}\n\t};\n\n\t// Creates (if necessary) and returns the text overlay container.\n\t//\n\t// @param {string} classes String of space-separated CSS classes used to\n\t// uniquely identify the text layer.\n\t// @return {object} The jQuery-wrapped text-layer div.\n\n\tCanvas.prototype.getTextLayer = function(classes) {\n\n\t\tvar layer = this.text[classes];\n\n\t\t// Create the text layer if it doesn't exist\n\n\t\tif (layer == null) {\n\n\t\t\t// Create the text layer container, if it doesn't exist\n\n\t\t\tif (this.textContainer == null) {\n\t\t\t\tthis.textContainer = $(\"<div class='flot-text flot-temp-elem'></div>\")\n\t\t\t\t\t.css({\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\tbottom: 0,\n\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\t'font-size': \"smaller\",\n\t\t\t\t\t\tcolor: \"#545454\"\n\t\t\t\t\t})\n\t\t\t\t\t.insertAfter(this.element);\n\t\t\t}\n\n\t\t\tlayer = this.text[classes] = $(\"<div></div>\")\n\t\t\t\t.addClass(classes)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tbottom: 0,\n\t\t\t\t\tright: 0\n\t\t\t\t})\n\t\t\t\t.appendTo(this.textContainer);\n\t\t}\n\n\t\treturn layer;\n\t};\n\n\t// Creates (if necessary) and returns a text info object.\n\t//\n\t// The object looks like this:\n\t//\n\t// {\n\t// width: Width of the text's wrapper div.\n\t// height: Height of the text's wrapper div.\n\t// element: The jQuery-wrapped HTML div containing the text.\n\t// positions: Array of positions at which this text is drawn.\n\t// }\n\t//\n\t// The positions array contains objects that look like this:\n\t//\n\t// {\n\t// active: Flag indicating whether the text should be visible.\n\t// rendered: Flag indicating whether the text is currently visible.\n\t// element: The jQuery-wrapped HTML div containing the text.\n\t// x: X coordinate at which to draw the text.\n\t// y: Y coordinate at which to draw the text.\n\t// }\n\t//\n\t// Each position after the first receives a clone of the original element.\n\t//\n\t// The idea is that that the width, height, and general 'identity' of the\n\t// text is constant no matter where it is placed; the placements are a\n\t// secondary property.\n\t//\n\t// Canvas maintains a cache of recently-used text info objects; getTextInfo\n\t// either returns the cached element or creates a new entry.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t// identifying the layer containing this text.\n\t// @param {string} text Text string to retrieve info for.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t// classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t// Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @return {object} a text info object.\n\n\tCanvas.prototype.getTextInfo = function(layer, text, font, angle, width) {\n\n\t\tvar textStyle, layerCache, styleCache, info;\n\n\t\t// Cast the value to a string, in case we were given a number or such\n\n\t\ttext = \"\" + text;\n\n\t\t// If the font is a font-spec object, generate a CSS font definition\n\n\t\tif (typeof font === \"object\") {\n\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px/\" + font.lineHeight + \"px \" + font.family;\n\t\t} else {\n\t\t\ttextStyle = font;\n\t\t}\n\n\t\t// Retrieve (or create) the cache for the text's layer and styles\n\n\t\tlayerCache = this._textCache[layer];\n\n\t\tif (layerCache == null) {\n\t\t\tlayerCache = this._textCache[layer] = {};\n\t\t}\n\n\t\tstyleCache = layerCache[textStyle];\n\n\t\tif (styleCache == null) {\n\t\t\tstyleCache = layerCache[textStyle] = {};\n\t\t}\n\n\t\tinfo = styleCache[text];\n\n\t\t// If we can't find a matching element in our cache, create a new one\n\n\t\tif (info == null) {\n\n\t\t\tvar element = $(\"<div></div>\").html(text)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t'max-width': width,\n\t\t\t\t\ttop: -9999\n\t\t\t\t})\n\t\t\t\t.appendTo(this.getTextLayer(layer));\n\n\t\t\tif (typeof font === \"object\") {\n\t\t\t\telement.css({\n\t\t\t\t\tfont: textStyle,\n\t\t\t\t\tcolor: font.color\n\t\t\t\t});\n\t\t\t} else if (typeof font === \"string\") {\n\t\t\t\telement.addClass(font);\n\t\t\t}\n\n info = styleCache[text] = { element: element, positions: [] };\n\n var size = this._textSizeCache[text];\n\t\t\tif (size) {\n info.width = size.width;\n info.height = size.height;\n\t\t\t} else {\n info.width = element.outerWidth(true);\n info.height = element.outerHeight(true);\n this._textSizeCache[text] = { width: info.width, height: info.height };\n\t\t\t}\n\t\t\telement.detach();\n\t\t}\n\n\t\treturn info;\n\t};\n\n\t// Adds a text string to the canvas text overlay.\n\t//\n\t// The text isn't drawn immediately; it is marked as rendering, which will\n\t// result in its addition to the canvas on the next render pass.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t// identifying the layer containing this text.\n\t// @param {number} x X coordinate at which to draw the text.\n\t// @param {number} y Y coordinate at which to draw the text.\n\t// @param {string} text Text string to draw.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t// classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t// Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @param {string=} halign Horizontal alignment of the text; either \"left\",\n\t// \"center\" or \"right\".\n\t// @param {string=} valign Vertical alignment of the text; either \"top\",\n\t// \"middle\" or \"bottom\".\n\n\tCanvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {\n\n\t\tvar info = this.getTextInfo(layer, text, font, angle, width),\n\t\t\tpositions = info.positions;\n\n\t\t// Tweak the div's position to match the text's alignment\n\n\t\tif (halign == \"center\") {\n\t\t\tx -= info.width / 2;\n\t\t} else if (halign == \"right\") {\n\t\t\tx -= info.width;\n\t\t}\n\n\t\tif (valign == \"middle\") {\n\t\t\ty -= info.height / 2;\n\t\t} else if (valign == \"bottom\") {\n\t\t\ty -= info.height;\n\t\t}\n\n\t\t// Determine whether this text already exists at this position.\n\t\t// If so, mark it for inclusion in the next render pass.\n\n\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\tposition.active = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// If the text doesn't exist at this position, create a new entry\n\n\t\t// For the very first position we'll re-use the original element,\n\t\t// while for subsequent ones we'll clone it.\n\n\t\tposition = {\n\t\t\tactive: true,\n\t\t\trendered: false,\n\t\t\telement: positions.length ? info.element.clone() : info.element,\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\n\t\tpositions.push(position);\n\n\t\t// Move the element to its final position within the container\n\n\t\tposition.element.css({\n\t\t\ttop: Math.round(y),\n\t\t\tleft: Math.round(x),\n\t\t\t'text-align': halign\t// In case the text wraps\n\t\t});\n\t};\n\n\t// Removes one or more text strings from the canvas text overlay.\n\t//\n\t// If no parameters are given, all text within the layer is removed.\n\t//\n\t// Note that the text is not immediately removed; it is simply marked as\n\t// inactive, which will result in its removal on the next render pass.\n\t// This avoids the performance penalty for 'clear and redraw' behavior,\n\t// where we potentially get rid of all text on a layer, but will likely\n\t// add back most or all of it later, as when redrawing axes, for example.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t// identifying the layer containing this text.\n\t// @param {number=} x X coordinate of the text.\n\t// @param {number=} y Y coordinate of the text.\n\t// @param {string=} text Text string to remove.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t// classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which the text is rotated, in degrees.\n\t// Angle is currently unused, it will be implemented in the future.\n\n\tCanvas.prototype.removeText = function(layer, x, y, text, font, angle) {\n\t\tif (text == null) {\n\t\t\tvar layerCache = this._textCache[layer];\n\t\t\tif (layerCache != null) {\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tposition.active = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tvar positions = this.getTextInfo(layer, text, font, angle).positions;\n\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\t\tposition.active = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The top-level container for the entire plot.\n\n function Plot(placeholder, data_, options_, plugins) {\n // data is on the form:\n // [ series1, series2 ... ]\n // where series is either just the data as [ [x1, y1], [x2, y2], ... ]\n // or { data: [ [x1, y1], [x2, y2], ... ], label: \"some label\", ... }\n\n var series = [],\n options = {\n // the color theme used for graphs\n colors: [\"#edc240\", \"#afd8f8\", \"#cb4b4b\", \"#4da74d\", \"#9440ed\"],\n legend: {\n show: true,\n noColumns: 1, // number of colums in legend table\n labelFormatter: null, // fn: string -> string\n labelBoxBorderColor: \"#ccc\", // border color for the little label boxes\n container: null, // container (as jQuery object) to put legend in, null means default on top of graph\n position: \"ne\", // position of default legend container within plot\n margin: 5, // distance from grid edge to default legend container within plot\n backgroundColor: null, // null means auto-detect\n backgroundOpacity: 0.85, // set to 0 to avoid background\n sorted: null // default to no legend sorting\n },\n xaxis: {\n show: null, // null = auto-detect, true = always, false = never\n position: \"bottom\", // or \"top\"\n mode: null, // null or \"time\"\n font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: \"italic\", weight: \"bold\", family: \"sans-serif\", variant: \"small-caps\" }\n color: null, // base color, labels, ticks\n tickColor: null, // possibly different color of ticks, e.g. \"rgba(0,0,0,0.15)\"\n transform: null, // null or f: number -> number to transform axis\n inverseTransform: null, // if transform is set, this should be the inverse function\n min: null, // min. value to show, null means set automatically\n max: null, // max. value to show, null means set automatically\n autoscaleMargin: null, // margin in % to add if auto-setting min/max\n ticks: null, // either [1, 3] or [[1, \"a\"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks\n tickFormatter: null, // fn: number -> string\n labelWidth: null, // size of tick labels in pixels\n labelHeight: null,\n reserveSpace: null, // whether to reserve space even if axis isn't shown\n tickLength: null, // size in pixels of ticks, or \"full\" for whole line\n alignTicksWithAxis: null, // axis number or null for no sync\n tickDecimals: null, // no. of decimals, null means auto\n tickSize: null, // number or [number, \"unit\"]\n minTickSize: null // number or [number, \"unit\"]\n },\n yaxis: {\n autoscaleMargin: 0.02,\n position: \"left\" // or \"right\"\n },\n xaxes: [],\n yaxes: [],\n series: {\n points: {\n show: false,\n radius: 3,\n lineWidth: 2, // in pixels\n fill: true,\n fillColor: \"#ffffff\",\n symbol: \"circle\" // or callback\n },\n lines: {\n // we don't put in show: false so we can see\n // whether lines were actively disabled\n lineWidth: 2, // in pixels\n fill: false,\n fillColor: null,\n steps: false\n // Omit 'zero', so we can later default its value to\n // match that of the 'fill' option.\n },\n bars: {\n show: false,\n lineWidth: 2, // in pixels\n barWidth: 1, // in units of the x axis\n fill: true,\n fillColor: null,\n align: \"left\", // \"left\", \"right\", or \"center\"\n horizontal: false,\n zero: true\n },\n shadowSize: 3,\n highlightColor: null\n },\n grid: {\n show: true,\n aboveData: false,\n color: \"#545454\", // primary color used for outline and labels\n backgroundColor: null, // null for transparent, else color\n borderColor: null, // set if different from the grid color\n tickColor: null, // color for the ticks, e.g. \"rgba(0,0,0,0.15)\"\n margin: 0, // distance from the canvas edge to the grid\n labelMargin: 5, // in pixels\n eventSectionHeight: 0, // space for event section\n axisMargin: 8, // in pixels\n borderWidth: 2, // in pixels\n minBorderMargin: null, // in pixels, null means taken from points radius\n markings: null, // array of ranges or fn: axes -> array of ranges\n markingsColor: \"#f4f4f4\",\n markingsLineWidth: 2,\n // interactive stuff\n clickable: false,\n hoverable: false,\n autoHighlight: true, // highlight in case mouse is near\n mouseActiveRadius: 10 // how far the mouse can be away to activate an item\n },\n interaction: {\n redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow\n },\n hooks: {}\n },\n surface = null, // the canvas for the plot itself\n overlay = null, // canvas for interactive stuff on top of plot\n eventHolder = null, // jQuery object that events should be bound to\n ctx = null, octx = null,\n xaxes = [], yaxes = [],\n plotOffset = { left: 0, right: 0, top: 0, bottom: 0},\n plotWidth = 0, plotHeight = 0,\n hooks = {\n processOptions: [],\n processRawData: [],\n processDatapoints: [],\n processOffset: [],\n drawBackground: [],\n drawSeries: [],\n draw: [],\n bindEvents: [],\n drawOverlay: [],\n shutdown: []\n },\n plot = this;\n\n // public functions\n plot.setData = setData;\n plot.setupGrid = setupGrid;\n plot.draw = draw;\n plot.getPlaceholder = function() { return placeholder; };\n plot.getCanvas = function() { return surface.element; };\n plot.getPlotOffset = function() { return plotOffset; };\n plot.width = function () { return plotWidth; };\n plot.height = function () { return plotHeight; };\n plot.offset = function () {\n var o = eventHolder.offset();\n o.left += plotOffset.left;\n o.top += plotOffset.top;\n return o;\n };\n plot.getData = function () { return series; };\n plot.getAxes = function () {\n var res = {}, i;\n $.each(xaxes.concat(yaxes), function (_, axis) {\n if (axis)\n res[axis.direction + (axis.n != 1 ? axis.n : \"\") + \"axis\"] = axis;\n });\n return res;\n };\n plot.getXAxes = function () { return xaxes; };\n plot.getYAxes = function () { return yaxes; };\n plot.c2p = canvasToAxisCoords;\n plot.p2c = axisToCanvasCoords;\n plot.getOptions = function () { return options; };\n plot.highlight = highlight;\n plot.unhighlight = unhighlight;\n plot.triggerRedrawOverlay = triggerRedrawOverlay;\n plot.pointOffset = function(point) {\n return {\n left: parseInt(xaxes[axisNumber(point, \"x\") - 1].p2c(+point.x) + plotOffset.left, 10),\n top: parseInt(yaxes[axisNumber(point, \"y\") - 1].p2c(+point.y) + plotOffset.top, 10)\n };\n };\n plot.shutdown = shutdown;\n plot.destroy = function () {\n shutdown();\n placeholder.removeData(\"plot\").empty();\n\n series = [];\n options = null;\n surface = null;\n overlay = null;\n eventHolder = null;\n ctx = null;\n octx = null;\n xaxes = [];\n yaxes = [];\n hooks = null;\n highlights = [];\n plot = null;\n };\n plot.resize = function () {\n \tvar width = placeholder.width(),\n \t\theight = placeholder.height();\n surface.resize(width, height);\n overlay.resize(width, height);\n };\n\n // public attributes\n plot.hooks = hooks;\n\n // initialize\n initPlugins(plot);\n parseOptions(options_);\n setupCanvases();\n setData(data_);\n setupGrid();\n draw();\n bindEvents();\n\n\n function executeHooks(hook, args) {\n args = [plot].concat(args);\n for (var i = 0; i < hook.length; ++i)\n hook[i].apply(this, args);\n }\n\n function initPlugins() {\n\n // References to key classes, allowing plugins to modify them\n\n var classes = {\n Canvas: Canvas\n };\n\n for (var i = 0; i < plugins.length; ++i) {\n var p = plugins[i];\n p.init(plot, classes);\n if (p.options)\n $.extend(true, options, p.options);\n }\n }\n\n function parseOptions(opts) {\n\n $.extend(true, options, opts);\n\n // $.extend merges arrays, rather than replacing them. When less\n // colors are provided than the size of the default palette, we\n // end up with those colors plus the remaining defaults, which is\n // not expected behavior; avoid it by replacing them here.\n\n if (opts && opts.colors) {\n \toptions.colors = opts.colors;\n }\n\n if (options.xaxis.color == null)\n options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n if (options.yaxis.color == null)\n options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility\n options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;\n if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility\n options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;\n\n if (options.grid.borderColor == null)\n options.grid.borderColor = options.grid.color;\n if (options.grid.tickColor == null)\n options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n // Fill in defaults for axis options, including any unspecified\n // font-spec fields, if a font-spec was provided.\n\n // If no x/y axis options were provided, create one of each anyway,\n // since the rest of the code assumes that they exist.\n\n var i, axisOptions, axisCount,\n fontSize = placeholder.css(\"font-size\"),\n fontSizeDefault = fontSize ? +fontSize.replace(\"px\", \"\") : 13,\n fontDefaults = {\n style: placeholder.css(\"font-style\"),\n size: Math.round(0.8 * fontSizeDefault),\n variant: placeholder.css(\"font-variant\"),\n weight: placeholder.css(\"font-weight\"),\n family: placeholder.css(\"font-family\")\n };\n\n axisCount = options.xaxes.length || 1;\n for (i = 0; i < axisCount; ++i) {\n\n axisOptions = options.xaxes[i];\n if (axisOptions && !axisOptions.tickColor) {\n axisOptions.tickColor = axisOptions.color;\n }\n\n axisOptions = $.extend(true, {}, options.xaxis, axisOptions);\n options.xaxes[i] = axisOptions;\n\n if (axisOptions.font) {\n axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n if (!axisOptions.font.color) {\n axisOptions.font.color = axisOptions.color;\n }\n if (!axisOptions.font.lineHeight) {\n axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);\n }\n }\n }\n\n axisCount = options.yaxes.length || 1;\n for (i = 0; i < axisCount; ++i) {\n\n axisOptions = options.yaxes[i];\n if (axisOptions && !axisOptions.tickColor) {\n axisOptions.tickColor = axisOptions.color;\n }\n\n axisOptions = $.extend(true, {}, options.yaxis, axisOptions);\n options.yaxes[i] = axisOptions;\n\n if (axisOptions.font) {\n axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n if (!axisOptions.font.color) {\n axisOptions.font.color = axisOptions.color;\n }\n if (!axisOptions.font.lineHeight) {\n axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);\n }\n }\n }\n\n // backwards compatibility, to be removed in future\n if (options.xaxis.noTicks && options.xaxis.ticks == null)\n options.xaxis.ticks = options.xaxis.noTicks;\n if (options.yaxis.noTicks && options.yaxis.ticks == null)\n options.yaxis.ticks = options.yaxis.noTicks;\n if (options.x2axis) {\n options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);\n options.xaxes[1].position = \"top\";\n // Override the inherit to allow the axis to auto-scale\n if (options.x2axis.min == null) {\n options.xaxes[1].min = null;\n }\n if (options.x2axis.max == null) {\n options.xaxes[1].max = null;\n }\n }\n if (options.y2axis) {\n options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);\n options.yaxes[1].position = \"right\";\n // Override the inherit to allow the axis to auto-scale\n if (options.y2axis.min == null) {\n options.yaxes[1].min = null;\n }\n if (options.y2axis.max == null) {\n options.yaxes[1].max = null;\n }\n }\n if (options.grid.coloredAreas)\n options.grid.markings = options.grid.coloredAreas;\n if (options.grid.coloredAreasColor)\n options.grid.markingsColor = options.grid.coloredAreasColor;\n if (options.lines)\n $.extend(true, options.series.lines, options.lines);\n if (options.points)\n $.extend(true, options.series.points, options.points);\n if (options.bars)\n $.extend(true, options.series.bars, options.bars);\n if (options.shadowSize != null)\n options.series.shadowSize = options.shadowSize;\n if (options.highlightColor != null)\n options.series.highlightColor = options.highlightColor;\n\n // save options on axes for future reference\n for (i = 0; i < options.xaxes.length; ++i)\n getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];\n for (i = 0; i < options.yaxes.length; ++i)\n getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];\n\n // add hooks from options\n for (var n in hooks)\n if (options.hooks[n] && options.hooks[n].length)\n hooks[n] = hooks[n].concat(options.hooks[n]);\n\n executeHooks(hooks.processOptions, [options]);\n }\n\n function setData(d) {\n series = parseData(d);\n fillInSeriesOptions();\n processData();\n }\n\n function parseData(d) {\n var res = [];\n for (var i = 0; i < d.length; ++i) {\n var s = $.extend(true, {}, options.series);\n\n if (d[i].data != null) {\n s.data = d[i].data; // move the data instead of deep-copy\n delete d[i].data;\n\n $.extend(true, s, d[i]);\n\n d[i].data = s.data;\n }\n else\n s.data = d[i];\n res.push(s);\n }\n\n return res;\n }\n\n function axisNumber(obj, coord) {\n var a = obj[coord + \"axis\"];\n if (typeof a == \"object\") // if we got a real axis, extract number\n a = a.n;\n if (typeof a != \"number\")\n a = 1; // default to first axis\n return a;\n }\n\n function allAxes() {\n // return flat array without annoying null entries\n return $.grep(xaxes.concat(yaxes), function (a) { return a; });\n }\n\n function canvasToAxisCoords(pos) {\n // return an object with x/y corresponding to all used axes\n var res = {}, i, axis;\n for (i = 0; i < xaxes.length; ++i) {\n axis = xaxes[i];\n if (axis && axis.used)\n res[\"x\" + axis.n] = axis.c2p(pos.left);\n }\n\n for (i = 0; i < yaxes.length; ++i) {\n axis = yaxes[i];\n if (axis && axis.used)\n res[\"y\" + axis.n] = axis.c2p(pos.top);\n }\n\n if (res.x1 !== undefined)\n res.x = res.x1;\n if (res.y1 !== undefined)\n res.y = res.y1;\n\n return res;\n }\n\n function axisToCanvasCoords(pos) {\n // get canvas coords from the first pair of x/y found in pos\n var res = {}, i, axis, key;\n\n for (i = 0; i < xaxes.length; ++i) {\n axis = xaxes[i];\n if (axis && axis.used) {\n key = \"x\" + axis.n;\n if (pos[key] == null && axis.n == 1)\n key = \"x\";\n\n if (pos[key] != null) {\n res.left = axis.p2c(pos[key]);\n break;\n }\n }\n }\n\n for (i = 0; i < yaxes.length; ++i) {\n axis = yaxes[i];\n if (axis && axis.used) {\n key = \"y\" + axis.n;\n if (pos[key] == null && axis.n == 1)\n key = \"y\";\n\n if (pos[key] != null) {\n res.top = axis.p2c(pos[key]);\n break;\n }\n }\n }\n\n return res;\n }\n\n function getOrCreateAxis(axes, number) {\n if (!axes[number - 1])\n axes[number - 1] = {\n n: number, // save the number for future reference\n direction: axes == xaxes ? \"x\" : \"y\",\n options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)\n };\n\n return axes[number - 1];\n }\n\n function fillInSeriesOptions() {\n\n var neededColors = series.length, maxIndex = -1, i;\n\n // Subtract the number of series that already have fixed colors or\n // color indexes from the number that we still need to generate.\n\n for (i = 0; i < series.length; ++i) {\n var sc = series[i].color;\n if (sc != null) {\n neededColors--;\n if (typeof sc == \"number\" && sc > maxIndex) {\n maxIndex = sc;\n }\n }\n }\n\n // If any of the series have fixed color indexes, then we need to\n // generate at least as many colors as the highest index.\n\n if (neededColors <= maxIndex) {\n neededColors = maxIndex + 1;\n }\n\n // Generate all the colors, using first the option colors and then\n // variations on those colors once they're exhausted.\n\n var c, colors = [], colorPool = options.colors,\n colorPoolSize = colorPool.length, variation = 0;\n\n for (i = 0; i < neededColors; i++) {\n\n c = $.color.parse(colorPool[i % colorPoolSize] || \"#666\");\n\n // Each time we exhaust the colors in the pool we adjust\n // a scaling factor used to produce more variations on\n // those colors. The factor alternates negative/positive\n // to produce lighter/darker colors.\n\n // Reset the variation after every few cycles, or else\n // it will end up producing only white or black colors.\n\n if (i % colorPoolSize == 0 && i) {\n if (variation >= 0) {\n if (variation < 0.5) {\n variation = -variation - 0.2;\n } else variation = 0;\n } else variation = -variation;\n }\n\n colors[i] = c.scale('rgb', 1 + variation);\n }\n\n // Finalize the series options, filling in their colors\n\n var colori = 0, s;\n for (i = 0; i < series.length; ++i) {\n s = series[i];\n\n // assign colors\n if (s.color == null) {\n s.color = colors[colori].toString();\n ++colori;\n }\n else if (typeof s.color == \"number\")\n s.color = colors[s.color].toString();\n\n // turn on lines automatically in case nothing is set\n if (s.lines.show == null) {\n var v, show = true;\n for (v in s)\n if (s[v] && s[v].show) {\n show = false;\n break;\n }\n if (show)\n s.lines.show = true;\n }\n\n // If nothing was provided for lines.zero, default it to match\n // lines.fill, since areas by default should extend to zero.\n\n if (s.lines.zero == null) {\n s.lines.zero = !!s.lines.fill;\n }\n\n // setup axes\n s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, \"x\"));\n s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, \"y\"));\n }\n }\n\n function processData() {\n var topSentry = Number.POSITIVE_INFINITY,\n bottomSentry = Number.NEGATIVE_INFINITY,\n fakeInfinity = Number.MAX_VALUE,\n i, j, k, m, length,\n s, points, ps, x, y, axis, val, f, p,\n data, format;\n\n function updateAxis(axis, min, max) {\n if (min < axis.datamin && min != -fakeInfinity)\n axis.datamin = min;\n if (max > axis.datamax && max != fakeInfinity)\n axis.datamax = max;\n }\n\n $.each(allAxes(), function (_, axis) {\n // init axis\n axis.datamin = topSentry;\n axis.datamax = bottomSentry;\n axis.used = false;\n });\n\n for (i = 0; i < series.length; ++i) {\n s = series[i];\n s.datapoints = { points: [] };\n\n executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);\n }\n\n // first pass: clean and copy data\n for (i = 0; i < series.length; ++i) {\n s = series[i];\n\n data = s.data;\n format = s.datapoints.format;\n\n if (!format) {\n format = [];\n // find out how to copy\n format.push({ x: true, number: true, required: true });\n format.push({ y: true, number: true, required: true });\n\n if (s.bars.show || (s.lines.show && s.lines.fill)) {\n var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));\n format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });\n if (s.bars.horizontal) {\n delete format[format.length - 1].y;\n format[format.length - 1].x = true;\n }\n }\n\n s.datapoints.format = format;\n }\n\n if (s.datapoints.pointsize != null)\n continue; // already filled in\n\n s.datapoints.pointsize = format.length;\n\n ps = s.datapoints.pointsize;\n points = s.datapoints.points;\n\n var insertSteps = s.lines.show && s.lines.steps;\n s.xaxis.used = s.yaxis.used = true;\n\n for (j = k = 0; j < data.length; ++j, k += ps) {\n p = data[j];\n\n var nullify = p == null;\n if (!nullify) {\n for (m = 0; m < ps; ++m) {\n val = p[m];\n f = format[m];\n\n if (f) {\n if (f.number && val != null) {\n val = +val; // convert to number\n if (isNaN(val))\n val = null;\n else if (val == Infinity)\n val = fakeInfinity;\n else if (val == -Infinity)\n val = -fakeInfinity;\n }\n\n if (val == null) {\n if (f.required)\n nullify = true;\n\n if (f.defaultValue != null)\n val = f.defaultValue;\n }\n }\n\n points[k + m] = val;\n }\n }\n\n if (nullify) {\n for (m = 0; m < ps; ++m) {\n val = points[k + m];\n if (val != null) {\n f = format[m];\n // extract min/max info\n if (f.autoscale !== false) {\n if (f.x) {\n updateAxis(s.xaxis, val, val);\n }\n if (f.y) {\n updateAxis(s.yaxis, val, val);\n }\n }\n }\n points[k + m] = null;\n }\n }\n\n if (insertSteps && k > 0 && (!nullify || points[k - ps] != null)) {\n // copy the point to make room for a middle point\n for (m = 0; m < ps; ++m)\n points[k + ps + m] = points[k + m];\n\n // middle point has same y\n points[k + 1] = points[k - ps + 1] || 0;\n\n // if series has null values, let's give the last !null value a nice step\n if(nullify)\n \tpoints[k] = p[0];\n\n // we've added a point, better reflect that\n k += ps;\n }\n }\n }\n\n // give the hooks a chance to run\n for (i = 0; i < series.length; ++i) {\n s = series[i];\n points = s.datapoints.points;\n ps = s.datapoints.pointsize;\n\n // grafana\n if (s.transform === 'negative-Y') {\n for (j = 0; j < points.length; j += ps) {\n if (points[j] == null)\n continue;\n\n val = points[j + 1];\n points[j + 1] = -val;\n }\n }\n\n executeHooks(hooks.processDatapoints, [ s, s.datapoints]);\n }\n\n // second pass: find datamax/datamin for auto-scaling\n for (i = 0; i < series.length; ++i) {\n s = series[i];\n points = s.datapoints.points;\n ps = s.datapoints.pointsize;\n format = s.datapoints.format;\n\n var xmin = topSentry, ymin = topSentry,\n xmax = bottomSentry, ymax = bottomSentry;\n\n for (j = 0; j < points.length; j += ps) {\n if (points[j] == null)\n continue;\n\n for (m = 0; m < ps; ++m) {\n val = points[j + m];\n f = format[m];\n if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)\n continue;\n\n if (f.x) {\n if (val < xmin)\n xmin = val;\n if (val > xmax)\n xmax = val;\n }\n if (f.y) {\n if (val < ymin)\n ymin = val;\n if (val > ymax)\n ymax = val;\n }\n }\n }\n\n if (s.bars.show) {\n // make sure we got room for the bar on the dancing floor\n var delta;\n\n switch (s.bars.align) {\n case \"left\":\n delta = 0;\n break;\n case \"right\":\n delta = -s.bars.barWidth;\n break;\n default:\n delta = -s.bars.barWidth / 2;\n }\n\n if (s.bars.horizontal) {\n ymin += delta;\n ymax += delta + s.bars.barWidth;\n }\n else {\n xmin += delta;\n xmax += delta + s.bars.barWidth;\n }\n }\n\n updateAxis(s.xaxis, xmin, xmax);\n updateAxis(s.yaxis, ymin, ymax);\n }\n\n $.each(allAxes(), function (_, axis) {\n if (axis.datamin == topSentry)\n axis.datamin = null;\n if (axis.datamax == bottomSentry)\n axis.datamax = null;\n });\n }\n\n function setupCanvases() {\n // Make sure the placeholder is clear of everything except canvases\n // from a previous plot in this container that we'll try to re-use.\n\n placeholder.find(\".flot-temp-elem\").remove();\n\n if (placeholder.css(\"position\") == 'static')\n placeholder.css(\"position\", \"relative\"); // for positioning labels and overlay\n\n surface = new Canvas(\"flot-base\", placeholder);\n overlay = new Canvas(\"flot-overlay\", placeholder); // overlay canvas for interactive features\n\n ctx = surface.context;\n octx = overlay.context;\n\n // define which element we're listening for events on\n eventHolder = $(overlay.element).unbind();\n\n // If we're re-using a plot object, shut down the old one\n\n var existing = placeholder.data(\"plot\");\n\n if (existing) {\n existing.shutdown();\n overlay.clear();\n }\n\n // save in case we get replotted\n placeholder.data(\"plot\", plot);\n }\n\n function bindEvents() {\n // bind events\n if (options.grid.hoverable) {\n eventHolder.mousemove(onMouseMove);\n\n // Use bind, rather than .mouseleave, because we officially\n // still support jQuery 1.2.6, which doesn't define a shortcut\n // for mouseenter or mouseleave. This was a bug/oversight that\n // was fixed somewhere around 1.3.x. We can return to using\n // .mouseleave when we drop support for 1.2.6.\n\n eventHolder.bind(\"mouseleave\", onMouseLeave);\n }\n\n if (options.grid.clickable)\n eventHolder.click(onClick);\n\n executeHooks(hooks.bindEvents, [eventHolder]);\n }\n\n function shutdown() {\n if (redrawTimeout)\n clearTimeout(redrawTimeout);\n\n eventHolder.unbind(\"mousemove\", onMouseMove);\n eventHolder.unbind(\"mouseleave\", onMouseLeave);\n eventHolder.unbind(\"click\", onClick);\n\n executeHooks(hooks.shutdown, [eventHolder]);\n }\n\n function setTransformationHelpers(axis) {\n // set helper functions on the axis, assumes plot area\n // has been computed already\n\n function identity(x) { return x; }\n\n var s, m, t = axis.options.transform || identity,\n it = axis.options.inverseTransform;\n\n // precompute how much the axis is scaling a point\n // in canvas space\n if (axis.direction == \"x\") {\n s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));\n m = Math.min(t(axis.max), t(axis.min));\n }\n else {\n s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));\n s = -s;\n m = Math.max(t(axis.max), t(axis.min));\n }\n\n // data point to canvas coordinate\n if (t == identity) // slight optimization\n axis.p2c = function (p) { return (p - m) * s; };\n else\n axis.p2c = function (p) { return (t(p) - m) * s; };\n // canvas coordinate to data point\n if (!it)\n axis.c2p = function (c) { return m + c / s; };\n else\n axis.c2p = function (c) { return it(m + c / s); };\n }\n\n function measureTickLabels(axis) {\n\n var opts = axis.options,\n ticks = axis.ticks || [],\n labelWidth = opts.labelWidth || 0,\n labelHeight = opts.labelHeight || 0,\n maxWidth = labelWidth || (axis.direction == \"x\" ? Math.floor(surface.width / (ticks.length || 1)) : null),\n legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n font = opts.font || \"flot-tick-label tickLabel\";\n\n for (var i = 0; i < ticks.length; ++i) {\n\n var t = ticks[i];\n\n if (!t.label)\n continue;\n\n var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);\n\n /// Grafana fix, add +1 to label width\n labelWidth = Math.max(labelWidth, info.width + 1);\n labelHeight = Math.max(labelHeight, info.height);\n }\n\n axis.labelWidth = opts.labelWidth || labelWidth;\n axis.labelHeight = opts.labelHeight || labelHeight;\n }\n\n function allocateAxisBoxFirstPhase(axis) {\n // find the bounding box of the axis by looking at label\n // widths/heights and ticks, make room by diminishing the\n // plotOffset; this first phase only looks at one\n // dimension per axis, the other dimension depends on the\n // other axes so will have to wait\n\n var lw = axis.labelWidth,\n lh = axis.labelHeight,\n pos = axis.options.position,\n isXAxis = axis.direction === \"x\",\n tickLength = axis.options.tickLength,\n axisMargin = options.grid.axisMargin,\n padding = options.grid.labelMargin,\n eventSectionPadding = options.grid.eventSectionHeight,\n innermost = true,\n outermost = true,\n first = true,\n found = false;\n\n // Determine the axis's position in its direction and on its side\n\n $.each(isXAxis ? xaxes : yaxes, function(i, a) {\n if (a && (a.show || a.reserveSpace)) {\n if (a === axis) {\n found = true;\n } else if (a.options.position === pos) {\n if (found) {\n outermost = false;\n } else {\n innermost = false;\n }\n }\n if (!found) {\n first = false;\n }\n }\n });\n\n // The outermost axis on each side has no margin\n\n if (outermost) {\n axisMargin = 0;\n }\n\n // The ticks for the first axis in each direction stretch across\n\n if (tickLength == null) {\n tickLength = first ? \"full\" : 5;\n }\n\n if (!isNaN(+tickLength))\n padding += +tickLength;\n\n if (isXAxis) {\n // Add space for event section\n lh += padding;\n lh += eventSectionPadding;\n\n if (pos == \"bottom\") {\n plotOffset.bottom += lh + axisMargin;\n axis.box = { top: surface.height - plotOffset.bottom, height: lh };\n }\n else {\n axis.box = { top: plotOffset.top + axisMargin, height: lh };\n plotOffset.top += lh + axisMargin;\n }\n }\n else {\n lw += padding;\n\n if (pos == \"left\") {\n axis.box = { left: plotOffset.left + axisMargin, width: lw };\n plotOffset.left += lw + axisMargin;\n }\n else {\n plotOffset.right += lw + axisMargin;\n axis.box = { left: surface.width - plotOffset.right, width: lw };\n }\n }\n\n // save for future reference\n axis.position = pos;\n axis.tickLength = tickLength;\n axis.box.padding = padding;\n axis.box.eventSectionPadding = eventSectionPadding;\n axis.innermost = innermost;\n }\n\n function allocateAxisBoxSecondPhase(axis) {\n // now that all axis boxes have been placed in one\n // dimension, we can set the remaining dimension coordinates\n if (axis.direction == \"x\") {\n axis.box.left = plotOffset.left - axis.labelWidth / 2;\n axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;\n }\n else {\n axis.box.top = plotOffset.top - axis.labelHeight / 2;\n axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;\n }\n }\n\n function adjustLayoutForThingsStickingOut() {\n // possibly adjust plot offset to ensure everything stays\n // inside the canvas and isn't clipped off\n\n var minMargin = options.grid.minBorderMargin,\n axis, i;\n\n // check stuff from the plot (FIXME: this should just read\n // a value from the series, otherwise it's impossible to\n // customize)\n if (minMargin == null) {\n minMargin = 0;\n for (i = 0; i < series.length; ++i)\n minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));\n }\n\n var margins = {\n left: minMargin,\n right: minMargin,\n top: minMargin,\n bottom: minMargin\n };\n\n // check axis labels, note we don't check the actual\n // labels but instead use the overall width/height to not\n // jump as much around with replots\n $.each(allAxes(), function (_, axis) {\n if (axis.reserveSpace && axis.ticks && axis.ticks.length) {\n if (axis.direction === \"x\") {\n margins.left = Math.max(margins.left, axis.labelWidth / 2);\n margins.right = Math.max(margins.right, axis.labelWidth / 2);\n } else {\n margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);\n margins.top = Math.max(margins.top, axis.labelHeight / 2);\n }\n }\n });\n\n plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));\n plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));\n plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));\n plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));\n }\n\n function setupGrid() {\n var i, axes = allAxes(), showGrid = options.grid.show;\n\n // Initialize the plot's offset from the edge of the canvas\n\n for (var a in plotOffset) {\n var margin = options.grid.margin || 0;\n plotOffset[a] = typeof margin == \"number\" ? margin : margin[a] || 0;\n }\n\n executeHooks(hooks.processOffset, [plotOffset]);\n\n // If the grid is visible, add its border width to the offset\n\n for (var a in plotOffset) {\n if(typeof(options.grid.borderWidth) == \"object\") {\n plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;\n }\n else {\n plotOffset[a] += showGrid ? options.grid.borderWidth : 0;\n }\n }\n\n $.each(axes, function (_, axis) {\n var axisOpts = axis.options;\n axis.show = axisOpts.show == null ? axis.used : axisOpts.show;\n axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;\n setRange(axis);\n });\n\n if (showGrid) {\n\n var allocatedAxes = $.grep(axes, function (axis) {\n return axis.show || axis.reserveSpace;\n });\n\n $.each(allocatedAxes, function (_, axis) {\n // make the ticks\n setupTickGeneration(axis);\n setTicks(axis);\n snapRangeToTicks(axis, axis.ticks);\n // find labelWidth/Height for axis\n measureTickLabels(axis);\n });\n\n // with all dimensions calculated, we can compute the\n // axis bounding boxes, start from the outside\n // (reverse order)\n for (i = allocatedAxes.length - 1; i >= 0; --i)\n allocateAxisBoxFirstPhase(allocatedAxes[i]);\n\n // make sure we've got enough space for things that\n // might stick out\n adjustLayoutForThingsStickingOut();\n\n $.each(allocatedAxes, function (_, axis) {\n allocateAxisBoxSecondPhase(axis);\n });\n }\n\n plotWidth = surface.width - plotOffset.left - plotOffset.right;\n plotHeight = surface.height - plotOffset.bottom - plotOffset.top;\n\n // now we got the proper plot dimensions, we can compute the scaling\n $.each(axes, function (_, axis) {\n setTransformationHelpers(axis);\n });\n\n if (showGrid) {\n drawAxisLabels();\n }\n\n insertLegend();\n }\n\n function setRange(axis) {\n var opts = axis.options,\n min = +(opts.min != null ? opts.min : axis.datamin),\n max = +(opts.max != null ? opts.max : axis.datamax),\n delta = max - min;\n\n if (delta == 0.0) {\n // Grafana fix: wide Y min and max using increased wideFactor\n // when all series values are the same\n var wideFactor = 0.25;\n var widen = Math.abs(max == 0 ? 1 : max * wideFactor);\n\n if (opts.min == null) {\n min -= widen;\n }\n // always widen max if we couldn't widen min to ensure we\n // don't fall into min == max which doesn't work\n if (opts.max == null || opts.min != null) {\n max += widen;\n }\n }\n else {\n // consider autoscaling\n var margin = opts.autoscaleMargin;\n if (margin != null) {\n if (opts.min == null) {\n min -= delta * margin;\n // make sure we don't go below zero if all values\n // are positive\n if (min < 0 && axis.datamin != null && axis.datamin >= 0)\n min = 0;\n }\n if (opts.max == null) {\n max += delta * margin;\n if (max > 0 && axis.datamax != null && axis.datamax <= 0)\n max = 0;\n }\n }\n }\n axis.min = min;\n axis.max = max;\n }\n\n function setupTickGeneration(axis) {\n var opts = axis.options;\n\n // estimate number of ticks\n var noTicks;\n if (typeof opts.ticks == \"number\" && opts.ticks > 0)\n noTicks = opts.ticks;\n else\n // heuristic based on the model a*sqrt(x) fitted to\n // some data points that seemed reasonable\n noTicks = 0.3 * Math.sqrt(axis.direction == \"x\" ? surface.width : surface.height);\n\n var delta = (axis.max - axis.min) / noTicks,\n dec = -Math.floor(Math.log(delta) / Math.LN10),\n maxDec = opts.tickDecimals;\n\n if (maxDec != null && dec > maxDec) {\n dec = maxDec;\n }\n\n var magn = Math.pow(10, -dec),\n norm = delta / magn, // norm is between 1.0 and 10.0\n size;\n\n if (norm < 1.5) {\n size = 1;\n } else if (norm < 3) {\n size = 2;\n // special case for 2.5, requires an extra decimal\n if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {\n size = 2.5;\n ++dec;\n }\n } else if (norm < 7.5) {\n size = 5;\n } else {\n size = 10;\n }\n\n size *= magn;\n\n if (opts.minTickSize != null && size < opts.minTickSize) {\n size = opts.minTickSize;\n }\n\n axis.delta = delta;\n axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);\n axis.tickSize = opts.tickSize || size;\n // grafana addition\n axis.scaledDecimals = axis.tickDecimals - Math.floor(Math.log(axis.tickSize) / Math.LN10);\n\n // Time mode was moved to a plug-in in 0.8, and since so many people use it\n // we'll add an especially friendly reminder to make sure they included it.\n\n if (opts.mode == \"time\" && !axis.tickGenerator) {\n throw new Error(\"Time mode requires the flot.time plugin.\");\n }\n\n // Flot supports base-10 axes; any other mode else is handled by a plug-in,\n // like flot.time.js.\n\n if (!axis.tickGenerator) {\n\n axis.tickGenerator = function (axis) {\n\n var ticks = [],\n start = floorInBase(axis.min, axis.tickSize),\n i = 0,\n v = Number.NaN,\n prev;\n\n do {\n prev = v;\n v = start + i * axis.tickSize;\n ticks.push(v);\n ++i;\n } while (v < axis.max && v != prev);\n return ticks;\n };\n\n\t\t\t\taxis.tickFormatter = function (value, axis) {\n\n\t\t\t\t\tvar factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;\n\t\t\t\t\tvar formatted = \"\" + Math.round(value * factor) / factor;\n\n\t\t\t\t\t// If tickDecimals was specified, ensure that we have exactly that\n\t\t\t\t\t// much precision; otherwise default to the value's own precision.\n\n\t\t\t\t\tif (axis.tickDecimals != null) {\n\t\t\t\t\t\tvar decimal = formatted.indexOf(\".\");\n\t\t\t\t\t\tvar precision = decimal == -1 ? 0 : formatted.length - decimal - 1;\n\t\t\t\t\t\tif (precision < axis.tickDecimals) {\n\t\t\t\t\t\t\treturn (precision ? formatted : formatted + \".\") + (\"\" + factor).substr(1, axis.tickDecimals - precision);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n return formatted;\n };\n }\n\n if ($.isFunction(opts.tickFormatter))\n axis.tickFormatter = function (v, axis) { return \"\" + opts.tickFormatter(v, axis); };\n\n if (opts.alignTicksWithAxis != null) {\n var otherAxis = (axis.direction == \"x\" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];\n if (otherAxis && otherAxis.used && otherAxis != axis) {\n // consider snapping min/max to outermost nice ticks\n var niceTicks = axis.tickGenerator(axis);\n if (niceTicks.length > 0) {\n if (opts.min == null)\n axis.min = Math.min(axis.min, niceTicks[0]);\n if (opts.max == null && niceTicks.length > 1)\n axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);\n }\n\n axis.tickGenerator = function (axis) {\n // copy ticks, scaled to this axis\n var ticks = [], v, i;\n for (i = 0; i < otherAxis.ticks.length; ++i) {\n v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);\n v = axis.min + v * (axis.max - axis.min);\n ticks.push(v);\n }\n return ticks;\n };\n\n // we might need an extra decimal since forced\n // ticks don't necessarily fit naturally\n if (!axis.mode && opts.tickDecimals == null) {\n var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),\n ts = axis.tickGenerator(axis);\n\n // only proceed if the tick interval rounded\n // with an extra decimal doesn't give us a\n // zero at end\n if (!(ts.length > 1 && /\\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))\n axis.tickDecimals = extraDec;\n }\n }\n }\n }\n\n function setTicks(axis) {\n var oticks = axis.options.ticks, ticks = [];\n if (oticks == null || (typeof oticks == \"number\" && oticks > 0))\n ticks = axis.tickGenerator(axis);\n else if (oticks) {\n if ($.isFunction(oticks))\n // generate the ticks\n ticks = oticks(axis);\n else\n ticks = oticks;\n }\n\n // clean up/labelify the supplied ticks, copy them over\n var i, v;\n axis.ticks = [];\n for (i = 0; i < ticks.length; ++i) {\n var label = null;\n var t = ticks[i];\n if (typeof t == \"object\") {\n v = +t[0];\n if (t.length > 1)\n label = t[1];\n }\n else\n v = +t;\n if (label == null)\n label = axis.tickFormatter(v, axis);\n if (!isNaN(v))\n axis.ticks.push({ v: v, label: label });\n }\n }\n\n function snapRangeToTicks(axis, ticks) {\n if (axis.options.autoscaleMargin && ticks.length > 0) {\n // snap to ticks\n if (axis.options.min == null)\n axis.min = Math.min(axis.min, ticks[0].v);\n if (axis.options.max == null && ticks.length > 1)\n axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);\n }\n }\n\n function draw() {\n\n surface.clear();\n\n executeHooks(hooks.drawBackground, [ctx]);\n\n var grid = options.grid;\n\n // draw background, if any\n if (grid.show && grid.backgroundColor)\n drawBackground();\n\n if (grid.show && !grid.aboveData) {\n drawGrid();\n }\n\n for (var i = 0; i < series.length; ++i) {\n executeHooks(hooks.drawSeries, [ctx, series[i]]);\n drawSeries(series[i]);\n }\n\n executeHooks(hooks.draw, [ctx]);\n\n if (grid.show && grid.aboveData) {\n drawGrid();\n }\n\n surface.render();\n\n // A draw implies that either the axes or data have changed, so we\n // should probably update the overlay highlights as well.\n\n triggerRedrawOverlay();\n }\n\n function extractRange(ranges, coord) {\n var axis, from, to, key, axes = allAxes();\n\n for (var i = 0; i < axes.length; ++i) {\n axis = axes[i];\n if (axis.direction == coord) {\n key = coord + axis.n + \"axis\";\n if (!ranges[key] && axis.n == 1)\n key = coord + \"axis\"; // support x1axis as xaxis\n if (ranges[key]) {\n from = ranges[key].from;\n to = ranges[key].to;\n break;\n }\n }\n }\n\n // backwards-compat stuff - to be removed in future\n if (!ranges[key]) {\n axis = coord == \"x\" ? xaxes[0] : yaxes[0];\n from = ranges[coord + \"1\"];\n to = ranges[coord + \"2\"];\n }\n\n // auto-reverse as an added bonus\n if (from != null && to != null && from > to) {\n var tmp = from;\n from = to;\n to = tmp;\n }\n\n return { from: from, to: to, axis: axis };\n }\n\n function drawBackground() {\n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n\n ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, \"rgba(255, 255, 255, 0)\");\n ctx.fillRect(0, 0, plotWidth, plotHeight);\n ctx.restore();\n }\n\n function drawGrid() {\n var i, axes, bw, bc;\n\n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n\n // draw markings\n var markings = options.grid.markings;\n if (markings) {\n if ($.isFunction(markings)) {\n axes = plot.getAxes();\n // xmin etc. is backwards compatibility, to be\n // removed in the future\n axes.xmin = axes.xaxis.min;\n axes.xmax = axes.xaxis.max;\n axes.ymin = axes.yaxis.min;\n axes.ymax = axes.yaxis.max;\n\n markings = markings(axes);\n }\n\n for (i = 0; i < markings.length; ++i) {\n var m = markings[i],\n xrange = extractRange(m, \"x\"),\n yrange = extractRange(m, \"y\");\n\n // fill in missing\n if (xrange.from == null)\n xrange.from = xrange.axis.min;\n if (xrange.to == null)\n xrange.to = xrange.axis.max;\n if (yrange.from == null)\n yrange.from = yrange.axis.min;\n if (yrange.to == null)\n yrange.to = yrange.axis.max;\n\n // clip\n if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||\n yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)\n continue;\n\n xrange.from = Math.max(xrange.from, xrange.axis.min);\n xrange.to = Math.min(xrange.to, xrange.axis.max);\n yrange.from = Math.max(yrange.from, yrange.axis.min);\n yrange.to = Math.min(yrange.to, yrange.axis.max);\n\n var xequal = xrange.from === xrange.to,\n yequal = yrange.from === yrange.to;\n\n if (xequal && yequal) {\n continue;\n }\n\n // then draw\n xrange.from = Math.floor(xrange.axis.p2c(xrange.from));\n xrange.to = Math.floor(xrange.axis.p2c(xrange.to));\n yrange.from = Math.floor(yrange.axis.p2c(yrange.from));\n yrange.to = Math.floor(yrange.axis.p2c(yrange.to));\n\n if (xequal || yequal) {\n var lineWidth = m.lineWidth || options.grid.markingsLineWidth,\n subPixel = lineWidth % 2 ? 0.5 : 0;\n ctx.beginPath();\n ctx.strokeStyle = m.color || options.grid.markingsColor;\n ctx.lineWidth = lineWidth;\n if (xequal) {\n ctx.moveTo(xrange.to + subPixel, yrange.from);\n ctx.lineTo(xrange.to + subPixel, yrange.to);\n } else {\n ctx.moveTo(xrange.from, yrange.to + subPixel);\n ctx.lineTo(xrange.to, yrange.to + subPixel);\n }\n ctx.stroke();\n } else {\n ctx.fillStyle = m.color || options.grid.markingsColor;\n ctx.fillRect(xrange.from, yrange.to,\n xrange.to - xrange.from,\n yrange.from - yrange.to);\n }\n }\n }\n\n // draw the ticks\n axes = allAxes();\n bw = options.grid.borderWidth;\n\n for (var j = 0; j < axes.length; ++j) {\n var axis = axes[j], box = axis.box,\n t = axis.tickLength, x, y, xoff, yoff;\n if (!axis.show || axis.ticks.length == 0)\n continue;\n\n ctx.lineWidth = 1;\n\n // find the edges\n if (axis.direction == \"x\") {\n x = 0;\n if (t == \"full\")\n y = (axis.position == \"top\" ? 0 : plotHeight);\n else\n y = box.top - plotOffset.top + (axis.position == \"top\" ? box.height : 0);\n }\n else {\n y = 0;\n if (t == \"full\")\n x = (axis.position == \"left\" ? 0 : plotWidth);\n else\n x = box.left - plotOffset.left + (axis.position == \"left\" ? box.width : 0);\n }\n\n // draw tick bar\n if (!axis.innermost) {\n ctx.strokeStyle = axis.options.color;\n ctx.beginPath();\n xoff = yoff = 0;\n if (axis.direction == \"x\")\n xoff = plotWidth + 1;\n else\n yoff = plotHeight + 1;\n\n if (ctx.lineWidth == 1) {\n if (axis.direction == \"x\") {\n y = Math.floor(y) + 0.5;\n } else {\n x = Math.floor(x) + 0.5;\n }\n }\n\n ctx.moveTo(x, y);\n ctx.lineTo(x + xoff, y + yoff);\n ctx.stroke();\n }\n\n // draw ticks\n\n ctx.strokeStyle = axis.options.tickColor;\n\n ctx.beginPath();\n for (i = 0; i < axis.ticks.length; ++i) {\n var v = axis.ticks[i].v;\n\n xoff = yoff = 0;\n\n if (isNaN(v) || v < axis.min || v > axis.max\n // skip those lying on the axes if we got a border\n || (t == \"full\"\n && ((typeof bw == \"object\" && bw[axis.position] > 0) || bw > 0)\n && (v == axis.min || v == axis.max)))\n continue;\n\n if (axis.direction == \"x\") {\n x = axis.p2c(v);\n yoff = t == \"full\" ? -plotHeight : t;\n\n if (axis.position == \"top\")\n yoff = -yoff;\n }\n else {\n y = axis.p2c(v);\n xoff = t == \"full\" ? -plotWidth : t;\n\n if (axis.position == \"left\")\n xoff = -xoff;\n }\n\n if (ctx.lineWidth == 1) {\n if (axis.direction == \"x\")\n x = Math.floor(x) + 0.5;\n else\n y = Math.floor(y) + 0.5;\n }\n\n ctx.moveTo(x, y);\n ctx.lineTo(x + xoff, y + yoff);\n }\n\n ctx.stroke();\n }\n\n\n // draw border\n if (bw) {\n // If either borderWidth or borderColor is an object, then draw the border\n // line by line instead of as one rectangle\n bc = options.grid.borderColor;\n if(typeof bw == \"object\" || typeof bc == \"object\") {\n if (typeof bw !== \"object\") {\n bw = {top: bw, right: bw, bottom: bw, left: bw};\n }\n if (typeof bc !== \"object\") {\n bc = {top: bc, right: bc, bottom: bc, left: bc};\n }\n\n if (bw.top > 0) {\n ctx.strokeStyle = bc.top;\n ctx.lineWidth = bw.top;\n ctx.beginPath();\n ctx.moveTo(0 - bw.left, 0 - bw.top/2);\n ctx.lineTo(plotWidth, 0 - bw.top/2);\n ctx.stroke();\n }\n\n if (bw.right > 0) {\n ctx.strokeStyle = bc.right;\n ctx.lineWidth = bw.right;\n ctx.beginPath();\n ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);\n ctx.lineTo(plotWidth + bw.right / 2, plotHeight);\n ctx.stroke();\n }\n\n if (bw.bottom > 0) {\n ctx.strokeStyle = bc.bottom;\n ctx.lineWidth = bw.bottom;\n ctx.beginPath();\n ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);\n ctx.lineTo(0, plotHeight + bw.bottom / 2);\n ctx.stroke();\n }\n\n if (bw.left > 0) {\n ctx.strokeStyle = bc.left;\n ctx.lineWidth = bw.left;\n ctx.beginPath();\n ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);\n ctx.lineTo(0- bw.left/2, 0);\n ctx.stroke();\n }\n }\n else {\n ctx.lineWidth = bw;\n ctx.strokeStyle = options.grid.borderColor;\n ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);\n }\n }\n\n ctx.restore();\n }\n\n function drawAxisLabels() {\n\n $.each(allAxes(), function (_, axis) {\n var box = axis.box,\n legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n font = axis.options.font || \"flot-tick-label tickLabel\",\n tick, x, y, halign, valign;\n\n // Remove text before checking for axis.show and ticks.length;\n // otherwise plugins, like flot-tickrotor, that draw their own\n // tick labels will end up with both theirs and the defaults.\n\n surface.removeText(layer);\n\n if (!axis.show || axis.ticks.length == 0)\n return;\n\n for (var i = 0; i < axis.ticks.length; ++i) {\n\n tick = axis.ticks[i];\n if (!tick.label || tick.v < axis.min || tick.v > axis.max)\n continue;\n\n if (axis.direction == \"x\") {\n halign = \"center\";\n x = plotOffset.left + axis.p2c(tick.v);\n if (axis.position == \"bottom\") {\n y = box.top + box.padding + box.eventSectionPadding;\n } else {\n y = box.top + box.height - box.padding;\n valign = \"bottom\";\n }\n } else {\n valign = \"middle\";\n y = plotOffset.top + axis.p2c(tick.v);\n if (axis.position == \"left\") {\n x = box.left + box.width - box.padding;\n halign = \"right\";\n } else {\n x = box.left + box.padding;\n }\n }\n\n surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);\n }\n });\n }\n\n function drawSeries(series) {\n if (series.lines.show)\n drawSeriesLines(series);\n if (series.bars.show)\n drawSeriesBars(series);\n if (series.points.show)\n drawSeriesPoints(series);\n }\n\n function drawSeriesLines(series) {\n function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {\n var points = datapoints.points,\n ps = datapoints.pointsize,\n prevx = null, prevy = null;\n\n ctx.beginPath();\n for (var i = ps; i < points.length; i += ps) {\n var x1 = points[i - ps], y1 = points[i - ps + 1],\n x2 = points[i], y2 = points[i + 1];\n\n if (x1 == null || x2 == null)\n continue;\n\n // clip with ymin\n if (y1 <= y2 && y1 < axisy.min) {\n if (y2 < axisy.min)\n continue; // line segment is outside\n // compute new intersection point\n x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n y1 = axisy.min;\n }\n else if (y2 <= y1 && y2 < axisy.min) {\n if (y1 < axisy.min)\n continue;\n x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n y2 = axisy.min;\n }\n\n // clip with ymax\n if (y1 >= y2 && y1 > axisy.max) {\n if (y2 > axisy.max)\n continue;\n x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n y1 = axisy.max;\n }\n else if (y2 >= y1 && y2 > axisy.max) {\n if (y1 > axisy.max)\n continue;\n x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n y2 = axisy.max;\n }\n\n // clip with xmin\n if (x1 <= x2 && x1 < axisx.min) {\n if (x2 < axisx.min)\n continue;\n y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n x1 = axisx.min;\n }\n else if (x2 <= x1 && x2 < axisx.min) {\n if (x1 < axisx.min)\n continue;\n y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n x2 = axisx.min;\n }\n\n // clip with xmax\n if (x1 >= x2 && x1 > axisx.max) {\n if (x2 > axisx.max)\n continue;\n y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n x1 = axisx.max;\n }\n else if (x2 >= x1 && x2 > axisx.max) {\n if (x1 > axisx.max)\n continue;\n y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n x2 = axisx.max;\n }\n\n if (x1 != prevx || y1 != prevy)\n ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);\n\n prevx = x2;\n prevy = y2;\n ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);\n }\n ctx.stroke();\n }\n\n function plotLineArea(datapoints, axisx, axisy) {\n var points = datapoints.points,\n ps = datapoints.pointsize,\n bottom = Math.min(Math.max(0, axisy.min), axisy.max),\n i = 0, top, areaOpen = false,\n ypos = 1, segmentStart = 0, segmentEnd = 0;\n\n // we process each segment in two turns, first forward\n // direction to sketch out top, then once we hit the\n // end we go backwards to sketch the bottom\n while (true) {\n if (ps > 0 && i > points.length + ps)\n break;\n\n i += ps; // ps is negative if going backwards\n\n var x1 = points[i - ps],\n y1 = points[i - ps + ypos],\n x2 = points[i], y2 = points[i + ypos];\n\n if (areaOpen) {\n if (ps > 0 && x1 != null && x2 == null) {\n // at turning point\n segmentEnd = i;\n ps = -ps;\n ypos = 2;\n continue;\n }\n\n if (ps < 0 && i == segmentStart + ps) {\n // done with the reverse sweep\n ctx.fill();\n areaOpen = false;\n ps = -ps;\n ypos = 1;\n i = segmentStart = segmentEnd + ps;\n continue;\n }\n }\n\n if (x1 == null || x2 == null)\n continue;\n\n // clip x values\n\n // clip with xmin\n if (x1 <= x2 && x1 < axisx.min) {\n if (x2 < axisx.min)\n continue;\n y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n x1 = axisx.min;\n }\n else if (x2 <= x1 && x2 < axisx.min) {\n if (x1 < axisx.min)\n continue;\n y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n x2 = axisx.min;\n }\n\n // clip with xmax\n if (x1 >= x2 && x1 > axisx.max) {\n if (x2 > axisx.max)\n continue;\n y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n x1 = axisx.max;\n }\n else if (x2 >= x1 && x2 > axisx.max) {\n if (x1 > axisx.max)\n continue;\n y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n x2 = axisx.max;\n }\n\n if (!areaOpen) {\n // open area\n ctx.beginPath();\n ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));\n areaOpen = true;\n }\n\n // now first check the case where both is outside\n if (y1 >= axisy.max && y2 >= axisy.max) {\n ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));\n ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));\n continue;\n }\n else if (y1 <= axisy.min && y2 <= axisy.min) {\n ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));\n ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));\n continue;\n }\n\n // else it's a bit more complicated, there might\n // be a flat maxed out rectangle first, then a\n // triangular cutout or reverse; to find these\n // keep track of the current x values\n var x1old = x1, x2old = x2;\n\n // clip the y values, without shortcutting, we\n // go through all cases in turn\n\n // clip with ymin\n if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {\n x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n y1 = axisy.min;\n }\n else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {\n x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n y2 = axisy.min;\n }\n\n // clip with ymax\n if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {\n x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n y1 = axisy.max;\n }\n else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {\n x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n y2 = axisy.max;\n }\n\n // if the x value was changed we got a rectangle\n // to fill\n if (x1 != x1old) {\n ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));\n // it goes to (x1, y1), but we fill that below\n }\n\n // fill triangular section, this sometimes result\n // in redundant points if (x1, y1) hasn't changed\n // from previous line to, but we just ignore that\n ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));\n ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n\n // fill the other rectangle if it's there\n if (x2 != x2old) {\n ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));\n }\n }\n }\n\n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n ctx.lineJoin = \"round\";\n\n var lw = series.lines.lineWidth,\n sw = series.shadowSize;\n // FIXME: consider another form of shadow when filling is turned on\n if (lw > 0 && sw > 0) {\n // draw shadow as a thick and thin line with transparency\n ctx.lineWidth = sw;\n ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n // position shadow at angle from the mid of line\n var angle = Math.PI/18;\n plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);\n ctx.lineWidth = sw/2;\n plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);\n }\n\n ctx.lineWidth = lw;\n ctx.strokeStyle = series.color;\n var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);\n if (fillStyle) {\n ctx.fillStyle = fillStyle;\n plotLineArea(series.datapoints, series.xaxis, series.yaxis);\n }\n\n if (lw > 0)\n plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);\n ctx.restore();\n }\n\n function drawSeriesPoints(series) {\n function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {\n var points = datapoints.points, ps = datapoints.pointsize;\n\n for (var i = 0; i < points.length; i += ps) {\n var x = points[i], y = points[i + 1];\n if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n continue;\n\n ctx.beginPath();\n x = axisx.p2c(x);\n y = axisy.p2c(y) + offset;\n if (symbol == \"circle\")\n ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);\n else\n symbol(ctx, x, y, radius, shadow);\n ctx.closePath();\n\n if (fillStyle) {\n ctx.fillStyle = fillStyle;\n ctx.fill();\n }\n ctx.stroke();\n }\n }\n\n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n\n var lw = series.points.lineWidth,\n sw = series.shadowSize,\n radius = series.points.radius,\n symbol = series.points.symbol;\n\n // If the user sets the line width to 0, we change it to a very\n // small value. A line width of 0 seems to force the default of 1.\n // Doing the conditional here allows the shadow setting to still be\n // optional even with a lineWidth of 0.\n\n if( lw == 0 )\n lw = 0.0001;\n\n if (lw > 0 && sw > 0) {\n // draw shadow in two steps\n var w = sw / 2;\n ctx.lineWidth = w;\n ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n plotPoints(series.datapoints, radius, null, w + w/2, true,\n series.xaxis, series.yaxis, symbol);\n\n ctx.strokeStyle = \"rgba(0,0,0,0.2)\";\n plotPoints(series.datapoints, radius, null, w/2, true,\n series.xaxis, series.yaxis, symbol);\n }\n\n ctx.lineWidth = lw;\n ctx.strokeStyle = series.color;\n plotPoints(series.datapoints, radius,\n getFillStyle(series.points, series.color), 0, false,\n series.xaxis, series.yaxis, symbol);\n ctx.restore();\n }\n\n function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {\n var left, right, bottom, top,\n drawLeft, drawRight, drawTop, drawBottom,\n tmp;\n\n // in horizontal mode, we start the bar from the left\n // instead of from the bottom so it appears to be\n // horizontal rather than vertical\n if (horizontal) {\n drawBottom = drawRight = drawTop = true;\n drawLeft = false;\n left = b;\n right = x;\n top = y + barLeft;\n bottom = y + barRight;\n\n // account for negative bars\n if (right < left) {\n tmp = right;\n right = left;\n left = tmp;\n drawLeft = true;\n drawRight = false;\n }\n }\n else {\n drawLeft = drawRight = drawTop = true;\n drawBottom = false;\n left = x + barLeft;\n right = x + barRight;\n bottom = b;\n top = y;\n\n // account for negative bars\n if (top < bottom) {\n tmp = top;\n top = bottom;\n bottom = tmp;\n drawBottom = true;\n drawTop = false;\n }\n }\n\n // clip\n if (right < axisx.min || left > axisx.max ||\n top < axisy.min || bottom > axisy.max)\n return;\n\n if (left < axisx.min) {\n left = axisx.min;\n drawLeft = false;\n }\n\n if (right > axisx.max) {\n right = axisx.max;\n drawRight = false;\n }\n\n if (bottom < axisy.min) {\n bottom = axisy.min;\n drawBottom = false;\n }\n\n if (top > axisy.max) {\n top = axisy.max;\n drawTop = false;\n }\n\n left = axisx.p2c(left);\n bottom = axisy.p2c(bottom);\n right = axisx.p2c(right);\n top = axisy.p2c(top);\n\n // fill the bar\n if (fillStyleCallback) {\n c.fillStyle = fillStyleCallback(bottom, top);\n c.fillRect(left, top, right - left, bottom - top)\n }\n\n // draw outline\n if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {\n c.beginPath();\n\n // FIXME: inline moveTo is buggy with excanvas\n c.moveTo(left, bottom);\n if (drawLeft)\n c.lineTo(left, top);\n else\n c.moveTo(left, top);\n if (drawTop)\n c.lineTo(right, top);\n else\n c.moveTo(right, top);\n if (drawRight)\n c.lineTo(right, bottom);\n else\n c.moveTo(right, bottom);\n if (drawBottom)\n c.lineTo(left, bottom);\n else\n c.moveTo(left, bottom);\n c.stroke();\n }\n }\n\n function drawSeriesBars(series) {\n function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {\n var points = datapoints.points, ps = datapoints.pointsize;\n\n for (var i = 0; i < points.length; i += ps) {\n if (points[i] == null)\n continue;\n drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);\n }\n }\n\n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n\n // FIXME: figure out a way to add shadows (for instance along the right edge)\n ctx.lineWidth = series.bars.lineWidth;\n ctx.strokeStyle = series.color;\n\n var barLeft;\n\n switch (series.bars.align) {\n case \"left\":\n barLeft = 0;\n break;\n case \"right\":\n barLeft = -series.bars.barWidth;\n break;\n default:\n barLeft = -series.bars.barWidth / 2;\n }\n\n var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;\n plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);\n ctx.restore();\n }\n\n function getFillStyle(filloptions, seriesColor, bottom, top) {\n var fill = filloptions.fill;\n if (!fill)\n return null;\n\n if (filloptions.fillColor)\n return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);\n\n var c = $.color.parse(seriesColor);\n c.a = typeof fill == \"number\" ? fill : 0.4;\n c.normalize();\n return c.toString();\n }\n\n function insertLegend() {\n\n if (options.legend.container != null) {\n $(options.legend.container).html(\"\");\n } else {\n placeholder.find(\".legend\").remove();\n }\n\n if (!options.legend.show) {\n return;\n }\n\n var fragments = [], entries = [], rowStarted = false,\n lf = options.legend.labelFormatter, s, label;\n\n // Build a list of legend entries, with each having a label and a color\n\n for (var i = 0; i < series.length; ++i) {\n s = series[i];\n if (s.label) {\n label = lf ? lf(s.label, s) : s.label;\n if (label) {\n entries.push({\n label: label,\n color: s.color\n });\n }\n }\n }\n\n // Sort the legend using either the default or a custom comparator\n\n if (options.legend.sorted) {\n if ($.isFunction(options.legend.sorted)) {\n entries.sort(options.legend.sorted);\n } else if (options.legend.sorted == \"reverse\") {\n \tentries.reverse();\n } else {\n var ascending = options.legend.sorted != \"descending\";\n entries.sort(function(a, b) {\n return a.label == b.label ? 0 : (\n (a.label < b.label) != ascending ? 1 : -1 // Logical XOR\n );\n });\n }\n }\n\n // Generate markup for the list of entries, in their final order\n\n for (var i = 0; i < entries.length; ++i) {\n\n var entry = entries[i];\n\n if (i % options.legend.noColumns == 0) {\n if (rowStarted)\n fragments.push('</tr>');\n fragments.push('<tr>');\n rowStarted = true;\n }\n\n fragments.push(\n '<td class=\"legendColorBox\"><div style=\"border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px\"><div style=\"width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden\"></div></div></td>' +\n '<td class=\"legendLabel\">' + entry.label + '</td>'\n );\n }\n\n if (rowStarted)\n fragments.push('</tr>');\n\n if (fragments.length == 0)\n return;\n\n var table = '<table style=\"font-size:smaller;color:' + options.grid.color + '\">' + fragments.join(\"\") + '</table>';\n if (options.legend.container != null)\n $(options.legend.container).html(table);\n else {\n var pos = \"\",\n p = options.legend.position,\n m = options.legend.margin;\n if (m[0] == null)\n m = [m, m];\n if (p.charAt(0) == \"n\")\n pos += 'top:' + (m[1] + plotOffset.top) + 'px;';\n else if (p.charAt(0) == \"s\")\n pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';\n if (p.charAt(1) == \"e\")\n pos += 'right:' + (m[0] + plotOffset.right) + 'px;';\n else if (p.charAt(1) == \"w\")\n pos += 'left:' + (m[0] + plotOffset.left) + 'px;';\n var legend = $('<div class=\"legend\">' + table.replace('style=\"', 'style=\"position:absolute;' + pos +';') + '</div>').appendTo(placeholder);\n if (options.legend.backgroundOpacity != 0.0) {\n // put in the transparent background\n // separately to avoid blended labels and\n // label boxes\n var c = options.legend.backgroundColor;\n if (c == null) {\n c = options.grid.backgroundColor;\n if (c && typeof c == \"string\")\n c = $.color.parse(c);\n else\n c = $.color.extract(legend, 'background-color');\n c.a = 1;\n c = c.toString();\n }\n var div = legend.children();\n $('<div style=\"position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';\"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);\n }\n }\n }\n\n\n // interactive features\n\n var highlights = [],\n redrawTimeout = null;\n\n // returns the data item the mouse is over, or null if none is found\n function findNearbyItem(mouseX, mouseY, seriesFilter) {\n var maxDistance = options.grid.mouseActiveRadius,\n smallestDistance = maxDistance * maxDistance + 1,\n item = null, foundPoint = false, i, j, ps;\n\n for (i = series.length - 1; i >= 0; --i) {\n if (!seriesFilter(series[i]))\n continue;\n\n var s = series[i],\n axisx = s.xaxis,\n axisy = s.yaxis,\n points = s.datapoints.points,\n mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster\n my = axisy.c2p(mouseY),\n maxx = maxDistance / axisx.scale,\n maxy = maxDistance / axisy.scale;\n\n ps = s.datapoints.pointsize;\n // with inverse transforms, we can't use the maxx/maxy\n // optimization, sadly\n if (axisx.options.inverseTransform)\n maxx = Number.MAX_VALUE;\n if (axisy.options.inverseTransform)\n maxy = Number.MAX_VALUE;\n\n if (s.lines.show || s.points.show) {\n for (j = 0; j < points.length; j += ps) {\n var x = points[j], y = points[j + 1];\n if (x == null)\n continue;\n\n // For points and lines, the cursor must be within a\n // certain distance to the data point\n if (x - mx > maxx || x - mx < -maxx ||\n y - my > maxy || y - my < -maxy)\n continue;\n\n // We have to calculate distances in pixels, not in\n // data units, because the scales of the axes may be different\n var dx = Math.abs(axisx.p2c(x) - mouseX),\n dy = Math.abs(axisy.p2c(y) - mouseY),\n dist = dx * dx + dy * dy; // we save the sqrt\n\n // use <= to ensure last point takes precedence\n // (last generally means on top of)\n if (dist < smallestDistance) {\n smallestDistance = dist;\n item = [i, j / ps];\n }\n }\n }\n\n if (s.bars.show && !item) { // no other point can be nearby\n\n var barLeft, barRight;\n\n switch (s.bars.align) {\n case \"left\":\n barLeft = 0;\n break;\n case \"right\":\n barLeft = -s.bars.barWidth;\n break;\n default:\n barLeft = -s.bars.barWidth / 2;\n }\n\n barRight = barLeft + s.bars.barWidth;\n\n for (j = 0; j < points.length; j += ps) {\n var x = points[j], y = points[j + 1], b = points[j + 2];\n if (x == null)\n continue;\n\n // for a bar graph, the cursor must be inside the bar\n if (series[i].bars.horizontal ?\n (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&\n my >= y + barLeft && my <= y + barRight) :\n (mx >= x + barLeft && mx <= x + barRight &&\n my >= Math.min(b, y) && my <= Math.max(b, y)))\n item = [i, j / ps];\n }\n }\n }\n\n if (item) {\n i = item[0];\n j = item[1];\n ps = series[i].datapoints.pointsize;\n\n return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),\n dataIndex: j,\n series: series[i],\n seriesIndex: i };\n }\n\n return null;\n }\n\n function onMouseMove(e) {\n if (options.grid.hoverable)\n triggerClickHoverEvent(\"plothover\", e,\n function (s) { return s[\"hoverable\"] != false; });\n }\n\n function onMouseLeave(e) {\n if (options.grid.hoverable)\n triggerClickHoverEvent(\"plothover\", e,\n function (s) { return false; });\n }\n\n function onClick(e) {\n if (plot.isSelecting) {\n return;\n }\n\n triggerClickHoverEvent(\"plotclick\", e, function (s) { return s[\"clickable\"] != false; });\n }\n\n // trigger click or hover event (they send the same parameters\n // so we share their code)\n function triggerClickHoverEvent(eventname, event, seriesFilter) {\n var offset = eventHolder.offset(),\n canvasX = event.pageX - offset.left - plotOffset.left,\n canvasY = event.pageY - offset.top - plotOffset.top,\n pos = canvasToAxisCoords({ left: canvasX, top: canvasY });\n\n pos.pageX = event.pageX;\n pos.pageY = event.pageY;\n\n // Add ctrlKey and metaKey to event\n pos.ctrlKey = event.ctrlKey;\n pos.metaKey = event.metaKey;\n\n var item = findNearbyItem(canvasX, canvasY, seriesFilter);\n\n if (item) {\n // fill in mouse pos for any listeners out there\n item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);\n item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);\n }\n\n if (options.grid.autoHighlight) {\n // clear auto-highlights\n for (var i = 0; i < highlights.length; ++i) {\n var h = highlights[i];\n if (h.auto == eventname &&\n !(item && h.series == item.series &&\n h.point[0] == item.datapoint[0] &&\n h.point[1] == item.datapoint[1]))\n unhighlight(h.series, h.point);\n }\n\n if (item)\n highlight(item.series, item.datapoint, eventname);\n }\n\n placeholder.trigger(eventname, [ pos, item ]);\n }\n\n function triggerRedrawOverlay() {\n var t = options.interaction.redrawOverlayInterval;\n if (t == -1) { // skip event queue\n drawOverlay();\n return;\n }\n\n if (!redrawTimeout)\n redrawTimeout = setTimeout(drawOverlay, t);\n }\n\n function drawOverlay() {\n redrawTimeout = null;\n\n // draw highlights\n octx.save();\n overlay.clear();\n octx.translate(plotOffset.left, plotOffset.top);\n\n var i, hi;\n for (i = 0; i < highlights.length; ++i) {\n hi = highlights[i];\n\n if (hi.series.bars.show)\n drawBarHighlight(hi.series, hi.point);\n else\n drawPointHighlight(hi.series, hi.point);\n }\n octx.restore();\n\n executeHooks(hooks.drawOverlay, [octx]);\n }\n\n function highlight(s, point, auto) {\n if (typeof s == \"number\")\n s = series[s];\n\n if (typeof point == \"number\") {\n var ps = s.datapoints.pointsize;\n point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n }\n\n var i = indexOfHighlight(s, point);\n if (i == -1) {\n highlights.push({ series: s, point: point, auto: auto });\n\n triggerRedrawOverlay();\n }\n else if (!auto)\n highlights[i].auto = false;\n }\n\n function unhighlight(s, point) {\n if (s == null && point == null) {\n highlights = [];\n triggerRedrawOverlay();\n return;\n }\n\n if (typeof s == \"number\")\n s = series[s];\n\n if (typeof point == \"number\") {\n var ps = s.datapoints.pointsize;\n point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n }\n\n var i = indexOfHighlight(s, point);\n if (i != -1) {\n highlights.splice(i, 1);\n\n triggerRedrawOverlay();\n }\n }\n\n function indexOfHighlight(s, p) {\n for (var i = 0; i < highlights.length; ++i) {\n var h = highlights[i];\n if (h.series == s && h.point[0] == p[0]\n && h.point[1] == p[1])\n return i;\n }\n return -1;\n }\n\n function drawPointHighlight(series, point) {\n var x = point[0], y = point[1],\n axisx = series.xaxis, axisy = series.yaxis,\n highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();\n\n if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n return;\n\n var pointRadius = series.points.radius + series.points.lineWidth / 2;\n octx.lineWidth = pointRadius;\n octx.strokeStyle = highlightColor;\n var radius = 1.5 * pointRadius;\n x = axisx.p2c(x);\n y = axisy.p2c(y);\n\n octx.beginPath();\n if (series.points.symbol == \"circle\")\n octx.arc(x, y, radius, 0, 2 * Math.PI, false);\n else\n series.points.symbol(octx, x, y, radius, false);\n octx.closePath();\n octx.stroke();\n }\n\n function drawBarHighlight(series, point) {\n var highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),\n fillStyle = highlightColor,\n barLeft;\n\n switch (series.bars.align) {\n case \"left\":\n barLeft = 0;\n break;\n case \"right\":\n barLeft = -series.bars.barWidth;\n break;\n default:\n barLeft = -series.bars.barWidth / 2;\n }\n\n octx.lineWidth = series.bars.lineWidth;\n octx.strokeStyle = highlightColor;\n\n drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,\n function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);\n }\n\n function getColorOrGradient(spec, bottom, top, defaultColor) {\n if (typeof spec == \"string\")\n return spec;\n else {\n // assume this is a gradient spec; IE currently only\n // supports a simple vertical gradient properly, so that's\n // what we support too\n var gradient = ctx.createLinearGradient(0, top, 0, bottom);\n\n for (var i = 0, l = spec.colors.length; i < l; ++i) {\n var c = spec.colors[i];\n if (typeof c != \"string\") {\n var co = $.color.parse(defaultColor);\n if (c.brightness != null)\n co = co.scale('rgb', c.brightness);\n if (c.opacity != null)\n co.a *= c.opacity;\n c = co.toString();\n }\n gradient.addColorStop(i / (l - 1), c);\n }\n\n return gradient;\n }\n }\n }\n\n // Add the plot function to the top level of the jQuery object\n\n $.plot = function(placeholder, data, options) {\n //var t0 = new Date();\n var plot = new Plot($(placeholder), data, options, $.plot.plugins);\n //(window.console ? console.log : alert)(\"time used (msecs): \" + ((new Date()).getTime() - t0.getTime()));\n return plot;\n };\n\n $.plot.version = \"0.8.3\";\n\n $.plot.plugins = [];\n\n // Also add the plot function as a chainable property\n\n $.fn.plot = function(data, options) {\n return this.each(function() {\n $.plot(this, data, options);\n });\n };\n\n // round to nearby lower multiple of base\n function floorInBase(n, base) {\n return base * Math.floor(n / base);\n }\n\n})(jQuery);\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.selection.js": |
|
/*!**********************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.selection.js ***! |
|
\**********************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("/* Flot plugin for selecting regions of a plot.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\nselection: {\n\tmode: null or \"x\" or \"y\" or \"xy\",\n\tcolor: color,\n\tshape: \"round\" or \"miter\" or \"bevel\",\n\tminSize: number of pixels\n}\n\nSelection support is enabled by setting the mode to one of \"x\", \"y\" or \"xy\".\nIn \"x\" mode, the user will only be able to specify the x range, similarly for\n\"y\" mode. For \"xy\", the selection becomes a rectangle where both ranges can be\nspecified. \"color\" is color of the selection (if you need to change the color\nlater on, you can get to it with plot.getOptions().selection.color). \"shape\"\nis the shape of the corners of the selection.\n\n\"minSize\" is the minimum size a selection can be in pixels. This value can\nbe customized to determine the smallest size a selection can be and still\nhave the selection rectangle be displayed. When customizing this value, the\nfact that it refers to pixels, not axis units must be taken into account.\nThus, for example, if there is a bar graph in time mode with BarWidth set to 1\nminute, setting \"minSize\" to 1 will not make the minimum selection size 1\nminute, but rather 1 pixel. Note also that setting \"minSize\" to 0 will prevent\n\"plotunselected\" events from being fired when the user clicks the mouse without\ndragging.\n\nWhen selection support is enabled, a \"plotselected\" event will be emitted on\nthe DOM element you passed into the plot function. The event handler gets a\nparameter with the ranges selected on the axes, like this:\n\n\tplaceholder.bind( \"plotselected\", function( event, ranges ) {\n\t\talert(\"You selected \" + ranges.xaxis.from + \" to \" + ranges.xaxis.to)\n\t\t// similar for yaxis - with multiple axes, the extra ones are in\n\t\t// x2axis, x3axis, ...\n\t});\n\nThe \"plotselected\" event is only fired when the user has finished making the\nselection. A \"plotselecting\" event is fired during the process with the same\nparameters as the \"plotselected\" event, in case you want to know what's\nhappening while it's happening,\n\nA \"plotunselected\" event with no arguments is emitted when the user clicks the\nmouse to remove the selection. As stated above, setting \"minSize\" to 0 will\ndestroy this behavior.\n\nThe plugin allso adds the following methods to the plot object:\n\n- setSelection( ranges, preventEvent )\n\n Set the selection rectangle. The passed in ranges is on the same form as\n returned in the \"plotselected\" event. If the selection mode is \"x\", you\n should put in either an xaxis range, if the mode is \"y\" you need to put in\n an yaxis range and both xaxis and yaxis if the selection mode is \"xy\", like\n this:\n\n\tsetSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });\n\n setSelection will trigger the \"plotselected\" event when called. If you don't\n want that to happen, e.g. if you're inside a \"plotselected\" handler, pass\n true as the second parameter. If you are using multiple axes, you can\n specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of\n xaxis, the plugin picks the first one it sees.\n\n- clearSelection( preventEvent )\n\n Clear the selection rectangle. Pass in true to avoid getting a\n \"plotunselected\" event.\n\n- getSelection()\n\n Returns the current selection in the same format as the \"plotselected\"\n event. If there's currently no selection, the function returns null.\n\n*/\n\n(function ($) {\n function init(plot) {\n var selection = {\n first: { x: -1, y: -1}, second: { x: -1, y: -1},\n show: false,\n active: false\n };\n\n // FIXME: The drag handling implemented here should be\n // abstracted out, there's some similar code from a library in\n // the navigation plugin, this should be massaged a bit to fit\n // the Flot cases here better and reused. Doing this would\n // make this plugin much slimmer.\n var savedhandlers = {};\n\n var mouseUpHandler = null;\n\n function onMouseMove(e) {\n if (selection.active) {\n updateSelection(e);\n\n plot.getPlaceholder().trigger(\"plotselecting\", [ getSelection() ]);\n }\n }\n\n function onMouseDown(e) {\n if (e.which != 1) // only accept left-click\n return;\n\n // cancel out any text selections\n document.body.focus();\n\n // prevent text selection and drag in old-school browsers\n if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {\n savedhandlers.onselectstart = document.onselectstart;\n document.onselectstart = function () { return false; };\n }\n if (document.ondrag !== undefined && savedhandlers.ondrag == null) {\n savedhandlers.ondrag = document.ondrag;\n document.ondrag = function () { return false; };\n }\n\n setSelectionPos(selection.first, e);\n\n selection.active = true;\n\n // this is a bit silly, but we have to use a closure to be\n // able to whack the same handler again\n mouseUpHandler = function (e) { onMouseUp(e); };\n\n $(document).one(\"mouseup\", mouseUpHandler);\n }\n\n function onMouseUp(e) {\n mouseUpHandler = null;\n\n // revert drag stuff for old-school browsers\n if (document.onselectstart !== undefined)\n document.onselectstart = savedhandlers.onselectstart;\n if (document.ondrag !== undefined)\n document.ondrag = savedhandlers.ondrag;\n\n // no more dragging\n selection.active = false;\n updateSelection(e);\n\n if (selectionIsSane())\n triggerSelectedEvent(e);\n else {\n // this counts as a clear\n plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n plot.getPlaceholder().trigger(\"plotselecting\", [ null ]);\n }\n\n setTimeout(function() {\n plot.isSelecting = false;\n }, 10);\n\n return false;\n }\n\n function getSelection() {\n if (!selectionIsSane())\n return null;\n\n if (!selection.show) return null;\n\n var r = {}, c1 = selection.first, c2 = selection.second;\n var axes = plot.getAxes();\n // look if no axis is used\n var noAxisInUse = true;\n $.each(axes, function (name, axis) {\n if (axis.used) {\n anyUsed = false;\n }\n })\n\n $.each(axes, function (name, axis) {\n if (axis.used || noAxisInUse) {\n var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);\n r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };\n }\n });\n return r;\n }\n\n function triggerSelectedEvent(event) {\n var r = getSelection();\n\n // Add ctrlKey and metaKey to event\n r.ctrlKey = event.ctrlKey;\n r.metaKey = event.metaKey;\n\n plot.getPlaceholder().trigger(\"plotselected\", [ r ]);\n\n // backwards-compat stuff, to be removed in future\n if (r.xaxis && r.yaxis)\n plot.getPlaceholder().trigger(\"selected\", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);\n }\n\n function clamp(min, value, max) {\n return value < min ? min: (value > max ? max: value);\n }\n\n function setSelectionPos(pos, e) {\n var o = plot.getOptions();\n var offset = plot.getPlaceholder().offset();\n var plotOffset = plot.getPlotOffset();\n pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());\n pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());\n\n if (o.selection.mode == \"y\")\n pos.x = pos == selection.first ? 0 : plot.width();\n\n if (o.selection.mode == \"x\")\n pos.y = pos == selection.first ? 0 : plot.height();\n }\n\n function updateSelection(pos) {\n if (pos.pageX == null)\n return;\n\n setSelectionPos(selection.second, pos);\n if (selectionIsSane()) {\n plot.isSelecting = true;\n selection.show = true;\n plot.triggerRedrawOverlay();\n }\n else\n clearSelection(true);\n }\n\n function clearSelection(preventEvent) {\n if (selection.show) {\n selection.show = false;\n plot.triggerRedrawOverlay();\n if (!preventEvent)\n plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n }\n }\n\n // function taken from markings support in Flot\n function extractRange(ranges, coord) {\n var axis, from, to, key, axes = plot.getAxes();\n\n for (var k in axes) {\n axis = axes[k];\n if (axis.direction == coord) {\n key = coord + axis.n + \"axis\";\n if (!ranges[key] && axis.n == 1)\n key = coord + \"axis\"; // support x1axis as xaxis\n if (ranges[key]) {\n from = ranges[key].from;\n to = ranges[key].to;\n break;\n }\n }\n }\n\n // backwards-compat stuff - to be removed in future\n if (!ranges[key]) {\n axis = coord == \"x\" ? plot.getXAxes()[0] : plot.getYAxes()[0];\n from = ranges[coord + \"1\"];\n to = ranges[coord + \"2\"];\n }\n\n // auto-reverse as an added bonus\n if (from != null && to != null && from > to) {\n var tmp = from;\n from = to;\n to = tmp;\n }\n\n return { from: from, to: to, axis: axis };\n }\n\n function setSelection(ranges, preventEvent) {\n var axis, range, o = plot.getOptions();\n\n if (o.selection.mode == \"y\") {\n selection.first.x = 0;\n selection.second.x = plot.width();\n }\n else {\n range = extractRange(ranges, \"x\");\n\n selection.first.x = range.axis.p2c(range.from);\n selection.second.x = range.axis.p2c(range.to);\n }\n\n if (o.selection.mode == \"x\") {\n selection.first.y = 0;\n selection.second.y = plot.height();\n }\n else {\n range = extractRange(ranges, \"y\");\n\n selection.first.y = range.axis.p2c(range.from);\n selection.second.y = range.axis.p2c(range.to);\n }\n\n selection.show = true;\n plot.triggerRedrawOverlay();\n if (!preventEvent && selectionIsSane())\n triggerSelectedEvent();\n }\n\n function selectionIsSane() {\n var minSize = plot.getOptions().selection.minSize;\n return Math.abs(selection.second.x - selection.first.x) >= minSize &&\n Math.abs(selection.second.y - selection.first.y) >= minSize;\n }\n\n plot.clearSelection = clearSelection;\n plot.setSelection = setSelection;\n plot.getSelection = getSelection;\n\n plot.hooks.bindEvents.push(function(plot, eventHolder) {\n var o = plot.getOptions();\n if (o.selection.mode != null) {\n eventHolder.mousemove(onMouseMove);\n eventHolder.mousedown(onMouseDown);\n }\n });\n\n\n plot.hooks.drawOverlay.push(function (plot, ctx) {\n // draw selection\n if (selection.show && selectionIsSane()) {\n var plotOffset = plot.getPlotOffset();\n var o = plot.getOptions();\n\n ctx.save();\n ctx.translate(plotOffset.left, plotOffset.top);\n\n var c = $.color.parse(o.selection.color);\n\n ctx.strokeStyle = c.scale('a', o.selection.strokeAlpha).toString();\n ctx.lineWidth = 1;\n ctx.lineJoin = o.selection.shape;\n ctx.fillStyle = c.scale('a', o.selection.fillAlpha).toString();\n\n var x = Math.min(selection.first.x, selection.second.x) + 0.5,\n y = Math.min(selection.first.y, selection.second.y) + 0.5,\n w = Math.abs(selection.second.x - selection.first.x) - 1,\n h = Math.abs(selection.second.y - selection.first.y) - 1;\n\n ctx.fillRect(x, y, w, h);\n ctx.strokeRect(x, y, w, h);\n\n ctx.restore();\n }\n });\n\n plot.hooks.shutdown.push(function (plot, eventHolder) {\n eventHolder.unbind(\"mousemove\", onMouseMove);\n eventHolder.unbind(\"mousedown\", onMouseDown);\n\n if (mouseUpHandler)\n $(document).unbind(\"mouseup\", mouseUpHandler);\n });\n\n }\n\n $.plot.plugins.push({\n init: init,\n options: {\n selection: {\n mode: null, // one of null, \"x\", \"y\" or \"xy\"\n color: \"#e8cfac\",\n shape: \"round\", // one of \"round\", \"miter\", or \"bevel\"\n minSize: 5, // minimum number of pixels\n strokeAlpha: 0.8,\n fillAlpha: 0.4,\n }\n },\n name: 'selection',\n version: '1.1'\n });\n})(jQuery);\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.selection.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.stack.js": |
|
/*!******************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.stack.js ***! |
|
\******************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("/* Flot plugin for stacking data sets rather than overlyaing them.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin assumes the data is sorted on x (or y if stacking horizontally).\nFor line charts, it is assumed that if a line has an undefined gap (from a\nnull point), then the line above it should have the same gap - insert zeros\ninstead of \"null\" if you want another behaviour. This also holds for the start\nand end of the chart. Note that stacking a mix of positive and negative values\nin most instances doesn't make sense (so it looks weird).\n\nTwo or more series are stacked when their \"stack\" attribute is set to the same\nkey (which can be any number or string or just \"true\"). To specify the default\nstack, you can set the stack option like this:\n\n series: {\n stack: null/false, true, or a key (number/string)\n }\n\nYou can also specify it for a single series, like this:\n\n $.plot( $(\"#placeholder\"), [{\n data: [ ... ],\n stack: true\n }])\n\nThe stacking order is determined by the order of the data series in the array\n(later series end up on top of the previous).\n\nInternally, the plugin modifies the datapoints in each series, adding an\noffset to the y value. For line series, extra data points are inserted through\ninterpolation. If there's a second y value, it's also adjusted (e.g for bar\ncharts or filled areas).\n\n*/\n\n(function ($) {\n var options = {\n series: { stack: null } // or number/string\n };\n\n function init(plot) {\n function findMatchingSeries(s, allseries) {\n var res = null;\n for (var i = 0; i < allseries.length; ++i) {\n if (s == allseries[i])\n break;\n\n if (allseries[i].stack == s.stack)\n res = allseries[i];\n }\n\n return res;\n }\n\n function stackData(plot, s, datapoints) {\n if (s.stack == null || s.stack === false)\n return;\n\n var other = findMatchingSeries(s, plot.getData());\n if (!other)\n return;\n\n var ps = datapoints.pointsize,\n points = datapoints.points,\n otherps = other.datapoints.pointsize,\n otherpoints = other.datapoints.points,\n newpoints = [],\n px, py, intery, qx, qy, bottom,\n withlines = s.lines.show,\n horizontal = s.bars.horizontal,\n withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),\n withsteps = withlines && s.lines.steps,\n keyOffset = horizontal ? 1 : 0,\n accumulateOffset = horizontal ? 0 : 1,\n i = 0, j = 0, l, m;\n\n while (true) {\n if (i >= points.length && j >= otherpoints.length)\n break;\n\n l = newpoints.length;\n\n if (i < points.length && points[i] == null) {\n // copy gaps\n for (m = 0; m < ps; ++m)\n newpoints.push(points[i + m]);\n i += ps;\n }\n else if (i >= points.length) {\n // take the remaining points from the previous series\n for (m = 0; m < ps; ++m)\n newpoints.push(otherpoints[j + m]);\n if (withbottom)\n newpoints[l + 2] = otherpoints[j + accumulateOffset];\n j += otherps;\n }\n else if (j >= otherpoints.length) {\n // take the remaining points from the current series\n for (m = 0; m < ps; ++m)\n newpoints.push(points[i + m]);\n i += ps;\n }\n else if (j < otherpoints.length && otherpoints[j] == null) {\n // ignore point\n j += otherps;\n }\n else {\n // cases where we actually got two points\n px = points[i + keyOffset];\n py = points[i + accumulateOffset];\n qx = otherpoints[j + keyOffset];\n qy = otherpoints[j + accumulateOffset];\n bottom = 0;\n\n if (px == qx) {\n for (m = 0; m < ps; ++m)\n newpoints.push(points[i + m]);\n\n newpoints[l + accumulateOffset] += qy;\n bottom = qy;\n\n i += ps;\n j += otherps;\n }\n else if (px > qx) {\n // take the point from the previous series so that next series will correctly stack\n if (i == 0) {\n for (m = 0; m < ps; ++m)\n newpoints.push(otherpoints[j + m]);\n bottom = qy;\n }\n // we got past point below, might need to\n // insert interpolated extra point\n if (i > 0 && points[i - ps] != null) {\n intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);\n newpoints.push(qx);\n newpoints.push(intery + qy);\n for (m = 2; m < ps; ++m)\n newpoints.push(points[i + m]);\n bottom = qy;\n }\n\n j += otherps;\n }\n else { // px < qx\n for (m = 0; m < ps; ++m)\n newpoints.push(points[i + m]);\n\n // we might be able to interpolate a point below,\n // this can give us a better y\n if (j > 0 && otherpoints[j - otherps] != null)\n bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);\n\n newpoints[l + accumulateOffset] += bottom;\n\n i += ps;\n }\n\n fromgap = false;\n\n if (l != newpoints.length && withbottom)\n newpoints[l + 2] = bottom;\n }\n\n // maintain the line steps invariant\n if (withsteps && l != newpoints.length && l > 0\n && newpoints[l] != null\n && newpoints[l] != newpoints[l - ps]\n && newpoints[l + 1] != newpoints[l - ps + 1]) {\n for (m = 0; m < ps; ++m)\n newpoints[l + ps + m] = newpoints[l + m];\n newpoints[l + 1] = newpoints[l - ps + 1];\n }\n }\n\n datapoints.points = newpoints;\n }\n\n plot.hooks.processDatapoints.push(stackData);\n }\n\n $.plot.plugins.push({\n init: init,\n options: options,\n name: 'stack',\n version: '1.2'\n });\n})(jQuery);\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.stack.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.stackpercent.js": |
|
/*!*************************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.stackpercent.js ***! |
|
\*************************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("(function ($) {\n var options = {\n series: {\n stackpercent: null\n } // or number/string\n };\n\n function init(plot) {\n\n // will be built up dynamically as a hash from x-value, or y-value if horizontal\n var stackBases = {};\n var processed = false;\n var stackSums = {};\n\n //set percentage for stacked chart\n function processRawData(plot, series, data, datapoints) {\n if (!processed) {\n processed = true;\n stackSums = getStackSums(plot.getData());\n }\n\t\t\tif (series.stackpercent == true) {\n\t\t\t\tvar num = data.length;\n\t\t\t\tseries.percents = [];\n\t\t\t\tvar key_idx = 0;\n\t\t\t\tvar value_idx = 1;\n\t\t\t\tif (series.bars && series.bars.horizontal && series.bars.horizontal === true) {\n\t\t\t\t\tkey_idx = 1;\n\t\t\t\t\tvalue_idx = 0;\n\t\t\t\t}\n\t\t\t\tfor (var j = 0; j < num; j++) {\n\t\t\t\t\tvar sum = stackSums[data[j][key_idx] + \"\"];\n\t\t\t\t\tif (sum > 0) {\n\t\t\t\t\t\tseries.percents.push(data[j][value_idx] * 100 / sum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tseries.percents.push(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n }\n\n //calculate summary\n function getStackSums(_data) {\n var data_len = _data.length;\n var sums = {};\n if (data_len > 0) {\n //caculate summary\n for (var i = 0; i < data_len; i++) {\n if (_data[i].stackpercent) {\n\t\t\t\t\t\tvar key_idx = 0;\n\t\t\t\t\t\tvar value_idx = 1;\n\t\t\t\t\t\tif (_data[i].bars && _data[i].bars.horizontal && _data[i].bars.horizontal === true) {\n\t\t\t\t\t\t\tkey_idx = 1;\n\t\t\t\t\t\t\tvalue_idx = 0;\n\t\t\t\t\t\t}\n var num = _data[i].data.length;\n for (var j = 0; j < num; j++) {\n var value = 0;\n if (_data[i].data[j][1] != null) {\n value = _data[i].data[j][value_idx];\n }\n if (sums[_data[i].data[j][key_idx] + \"\"]) {\n sums[_data[i].data[j][key_idx] + \"\"] += value;\n } else {\n sums[_data[i].data[j][key_idx] + \"\"] = value;\n }\n\n }\n }\n }\n }\n return sums;\n }\n\n function stackData(plot, s, datapoints) {\n if (!s.stackpercent) return;\n if (!processed) {\n stackSums = getStackSums(plot.getData());\n }\n var newPoints = [];\n\n\n\t\t\tvar key_idx = 0;\n\t\t\tvar value_idx = 1;\n\t\t\tif (s.bars && s.bars.horizontal && s.bars.horizontal === true) {\n\t\t\t\tkey_idx = 1;\n\t\t\t\tvalue_idx = 0;\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < datapoints.points.length; i += 3) {\n\t\t\t\t// note that the values need to be turned into absolute y-values.\n\t\t\t\t// in other words, if you were to stack (x, y1), (x, y2), and (x, y3),\n\t\t\t\t// (each from different series, which is where stackBases comes in),\n\t\t\t\t// you'd want the new points to be (x, y1, 0), (x, y1+y2, y1), (x, y1+y2+y3, y1+y2)\n\t\t\t\t// generally, (x, thisValue + (base up to this point), + (base up to this point))\n\t\t\t\tif (!stackBases[datapoints.points[i + key_idx]]) {\n\t\t\t\t\tstackBases[datapoints.points[i + key_idx]] = 0;\n\t\t\t\t}\n\t\t\t\tnewPoints[i + key_idx] = datapoints.points[i + key_idx];\n\t\t\t\tnewPoints[i + value_idx] = datapoints.points[i + value_idx] + stackBases[datapoints.points[i + key_idx]];\n\t\t\t\tnewPoints[i + 2] = stackBases[datapoints.points[i + key_idx]];\n\t\t\t\tstackBases[datapoints.points[i + key_idx]] += datapoints.points[i + value_idx];\n\t\t\t\t// change points to percentage values\n\t\t\t\t// you may need to set yaxis:{ max = 100 }\n\t\t\t\tif ( stackSums[newPoints[i+key_idx]+\"\"] > 0 ){\n\t\t\t\t\tnewPoints[i + value_idx] = newPoints[i + value_idx] * 100 / stackSums[newPoints[i + key_idx] + \"\"];\n\t\t\t\t\tnewPoints[i + 2] = newPoints[i + 2] * 100 / stackSums[newPoints[i + key_idx] + \"\"];\n\t\t\t\t} else {\n\t\t\t\t\tnewPoints[i + value_idx] = 0;\n\t\t\t\t\tnewPoints[i + 2] = 0;\n\t\t\t\t}\n\t\t\t}\n\n datapoints.points = newPoints;\n }\n\n\t\tplot.hooks.processRawData.push(processRawData);\n plot.hooks.processDatapoints.push(stackData);\n }\n\n $.plot.plugins.push({\n init: init,\n options: options,\n name: 'stackpercent',\n version: '0.1'\n });\n})(jQuery);\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.stackpercent.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "./vendor/flot/jquery.flot.time.js": |
|
/*!*****************************************!*\ |
|
!*** ./vendor/flot/jquery.flot.time.js ***! |
|
\*****************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("/* Pretty handling of time axes.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nSet axis.mode to \"time\" to enable. See the section \"Time series data\" in\nAPI.txt for details.\n\n*/\n\n(function($) {\n\n\tvar options = {\n\t\txaxis: {\n\t\t\ttimezone: null,\t\t// \"browser\" for local to the client or timezone for timezone-js\n\t\t\ttimeformat: null,\t// format string to use\n\t\t\ttwelveHourClock: false,\t// 12 or 24 time in time mode\n\t\t\tmonthNames: null\t// list of names of months\n\t\t}\n\t};\n\n\t// round to nearby lower multiple of base\n\n\tfunction floorInBase(n, base) {\n\t\treturn base * Math.floor(n / base);\n\t}\n\n\t// Returns a string with the date d formatted according to fmt.\n\t// A subset of the Open Group's strftime format is supported.\n\n\tfunction formatDate(d, fmt, monthNames, dayNames) {\n\n\t\tif (typeof d.strftime == \"function\") {\n\t\t\treturn d.strftime(fmt);\n\t\t}\n\n\t\tvar leftPad = function(n, pad) {\n\t\t\tn = \"\" + n;\n\t\t\tpad = \"\" + (pad == null ? \"0\" : pad);\n\t\t\treturn n.length == 1 ? pad + n : n;\n\t\t};\n\n\t\tvar r = [];\n\t\tvar escape = false;\n\t\tvar hours = d.getHours();\n\t\tvar isAM = hours < 12;\n\n\t\tif (monthNames == null) {\n\t\t\tmonthNames = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\t\t}\n\n\t\tif (dayNames == null) {\n\t\t\tdayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\t\t}\n\n\t\tvar hours12;\n\n\t\tif (hours > 12) {\n\t\t\thours12 = hours - 12;\n\t\t} else if (hours == 0) {\n\t\t\thours12 = 12;\n\t\t} else {\n\t\t\thours12 = hours;\n\t\t}\n\n\t\tfor (var i = 0; i < fmt.length; ++i) {\n\n\t\t\tvar c = fmt.charAt(i);\n\n\t\t\tif (escape) {\n\t\t\t\tswitch (c) {\n\t\t\t\t\tcase 'a': c = \"\" + dayNames[d.getDay()]; break;\n\t\t\t\t\tcase 'b': c = \"\" + monthNames[d.getMonth()]; break;\n\t\t\t\t\tcase 'd': c = leftPad(d.getDate(), \"\"); break;\n\t\t\t\t\tcase 'e': c = leftPad(d.getDate(), \" \"); break;\n\t\t\t\t\tcase 'h':\t// For back-compat with 0.7; remove in 1.0\n\t\t\t\t\tcase 'H': c = leftPad(hours); break;\n\t\t\t\t\tcase 'I': c = leftPad(hours12); break;\n\t\t\t\t\tcase 'l': c = leftPad(hours12, \" \"); break;\n\t\t\t\t\tcase 'm': c = leftPad(d.getMonth() + 1, \"\"); break;\n\t\t\t\t\tcase 'M': c = leftPad(d.getMinutes()); break;\n\t\t\t\t\t// quarters not in Open Group's strftime specification\n\t\t\t\t\tcase 'q':\n\t\t\t\t\t\tc = \"\" + (Math.floor(d.getMonth() / 3) + 1); break;\n\t\t\t\t\tcase 'S': c = leftPad(d.getSeconds()); break;\n\t\t\t\t\tcase 'y': c = leftPad(d.getFullYear() % 100); break;\n\t\t\t\t\tcase 'Y': c = \"\" + d.getFullYear(); break;\n\t\t\t\t\tcase 'p': c = (isAM) ? (\"\" + \"am\") : (\"\" + \"pm\"); break;\n\t\t\t\t\tcase 'P': c = (isAM) ? (\"\" + \"AM\") : (\"\" + \"PM\"); break;\n\t\t\t\t\tcase 'w': c = \"\" + d.getDay(); break;\n\t\t\t\t}\n\t\t\t\tr.push(c);\n\t\t\t\tescape = false;\n\t\t\t} else {\n\t\t\t\tif (c == \"%\") {\n\t\t\t\t\tescape = true;\n\t\t\t\t} else {\n\t\t\t\t\tr.push(c);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn r.join(\"\");\n\t}\n\n\t// To have a consistent view of time-based data independent of which time\n\t// zone the client happens to be in we need a date-like object independent\n\t// of time zones. This is done through a wrapper that only calls the UTC\n\t// versions of the accessor methods.\n\n\tfunction makeUtcWrapper(d) {\n\n\t\tfunction addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {\n\t\t\tsourceObj[sourceMethod] = function() {\n\t\t\t\treturn targetObj[targetMethod].apply(targetObj, arguments);\n\t\t\t};\n\t\t};\n\n\t\tvar utc = {\n\t\t\tdate: d\n\t\t};\n\n\t\t// support strftime, if found\n\n\t\tif (d.strftime != undefined) {\n\t\t\taddProxyMethod(utc, \"strftime\", d, \"strftime\");\n\t\t}\n\n\t\taddProxyMethod(utc, \"getTime\", d, \"getTime\");\n\t\taddProxyMethod(utc, \"setTime\", d, \"setTime\");\n\n\t\tvar props = [\"Date\", \"Day\", \"FullYear\", \"Hours\", \"Milliseconds\", \"Minutes\", \"Month\", \"Seconds\"];\n\n\t\tfor (var p = 0; p < props.length; p++) {\n\t\t\taddProxyMethod(utc, \"get\" + props[p], d, \"getUTC\" + props[p]);\n\t\t\taddProxyMethod(utc, \"set\" + props[p], d, \"setUTC\" + props[p]);\n\t\t}\n\n\t\treturn utc;\n\t};\n\n\t// select time zone strategy. This returns a date-like object tied to the\n\t// desired timezone\n\n\tfunction dateGenerator(ts, opts) {\n\t\tif (opts.timezone == \"browser\") {\n\t\t\treturn new Date(ts);\n\t\t} else if (!opts.timezone || opts.timezone == \"utc\") {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t} else if (typeof timezoneJS != \"undefined\" && typeof timezoneJS.Date != \"undefined\") {\n\t\t\tvar d = new timezoneJS.Date();\n\t\t\t// timezone-js is fickle, so be sure to set the time zone before\n\t\t\t// setting the time.\n\t\t\td.setTimezone(opts.timezone);\n\t\t\td.setTime(ts);\n\t\t\treturn d;\n\t\t} else {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t}\n\t}\n\n\t// map of app. size of time units in milliseconds\n\n\tvar timeUnitSize = {\n\t\t\"second\": 1000,\n\t\t\"minute\": 60 * 1000,\n\t\t\"hour\": 60 * 60 * 1000,\n\t\t\"day\": 24 * 60 * 60 * 1000,\n\t\t\"month\": 30 * 24 * 60 * 60 * 1000,\n\t\t\"quarter\": 3 * 30 * 24 * 60 * 60 * 1000,\n\t\t\"year\": 365.2425 * 24 * 60 * 60 * 1000\n\t};\n\n\t// the allowed tick sizes, after 1 year we use\n\t// an integer algorithm\n\n\tvar baseSpec = [\n\t\t[1, \"second\"], [2, \"second\"], [5, \"second\"], [10, \"second\"],\n\t\t[30, \"second\"],\n\t\t[1, \"minute\"], [2, \"minute\"], [5, \"minute\"], [10, \"minute\"],\n\t\t[30, \"minute\"],\n\t\t[1, \"hour\"], [2, \"hour\"], [4, \"hour\"],\n\t\t[8, \"hour\"], [12, \"hour\"],\n\t\t[1, \"day\"], [2, \"day\"], [3, \"day\"],\n\t\t[0.25, \"month\"], [0.5, \"month\"], [1, \"month\"],\n\t\t[2, \"month\"]\n\t];\n\n\t// we don't know which variant(s) we'll need yet, but generating both is\n\t// cheap\n\n\tvar specMonths = baseSpec.concat([[3, \"month\"], [6, \"month\"],\n\t\t[1, \"year\"]]);\n\tvar specQuarters = baseSpec.concat([[1, \"quarter\"], [2, \"quarter\"],\n\t\t[1, \"year\"]]);\n\n\tfunction init(plot) {\n\t\tplot.hooks.processOptions.push(function (plot, options) {\n\t\t\t$.each(plot.getAxes(), function(axisName, axis) {\n\n\t\t\t\tvar opts = axis.options;\n\n\t\t\t\tif (opts.mode == \"time\") {\n\t\t\t\t\taxis.tickGenerator = function(axis) {\n\n\t\t\t\t\t\tvar ticks = [];\n\t\t\t\t\t\tvar d = dateGenerator(axis.min, opts);\n\t\t\t\t\t\tvar minSize = 0;\n\n\t\t\t\t\t\t// make quarter use a possibility if quarters are\n\t\t\t\t\t\t// mentioned in either of these options\n\n\t\t\t\t\t\tvar spec = (opts.tickSize && opts.tickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ||\n\t\t\t\t\t\t\t(opts.minTickSize && opts.minTickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ? specQuarters : specMonths;\n\n\t\t\t\t\t\tif (opts.minTickSize != null) {\n\t\t\t\t\t\t\tif (typeof opts.tickSize == \"number\") {\n\t\t\t\t\t\t\t\tminSize = opts.tickSize;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tminSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (var i = 0; i < spec.length - 1; ++i) {\n\t\t\t\t\t\t\tif (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]\n\t\t\t\t\t\t\t\t\t\t\t + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2\n\t\t\t\t\t\t\t\t&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = spec[i][0];\n\t\t\t\t\t\tvar unit = spec[i][1];\n\n\t\t\t\t\t\t// special-case the possibility of several years\n\n\t\t\t\t\t\tif (unit == \"year\") {\n\n\t\t\t\t\t\t\t// if given a minTickSize in years, just use it,\n\t\t\t\t\t\t\t// ensuring that it's an integer\n\n\t\t\t\t\t\t\tif (opts.minTickSize != null && opts.minTickSize[1] == \"year\") {\n\t\t\t\t\t\t\t\tsize = Math.floor(opts.minTickSize[0]);\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tvar magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));\n\t\t\t\t\t\t\t\tvar norm = (axis.delta / timeUnitSize.year) / magn;\n\n\t\t\t\t\t\t\t\tif (norm < 1.5) {\n\t\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t\t} else if (norm < 3) {\n\t\t\t\t\t\t\t\t\tsize = 2;\n\t\t\t\t\t\t\t\t} else if (norm < 7.5) {\n\t\t\t\t\t\t\t\t\tsize = 5;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsize = 10;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsize *= magn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// minimum size for years is 1\n\n\t\t\t\t\t\t\tif (size < 1) {\n\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\taxis.tickSize = opts.tickSize || [size, unit];\n\t\t\t\t\t\tvar tickSize = axis.tickSize[0];\n\t\t\t\t\t\tunit = axis.tickSize[1];\n\n\t\t\t\t\t\tvar step = tickSize * timeUnitSize[unit];\n\n\t\t\t\t\t\tif (unit == \"second\") {\n\t\t\t\t\t\t\td.setSeconds(floorInBase(d.getSeconds(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"minute\") {\n\t\t\t\t\t\t\td.setMinutes(floorInBase(d.getMinutes(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"hour\") {\n\t\t\t\t\t\t\td.setHours(floorInBase(d.getHours(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"month\") {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"quarter\") {\n\t\t\t\t\t\t\td.setMonth(3 * floorInBase(d.getMonth() / 3,\n\t\t\t\t\t\t\t\ttickSize));\n\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\td.setFullYear(floorInBase(d.getFullYear(), tickSize));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// reset smaller components\n\n\t\t\t\t\t\td.setMilliseconds(0);\n\n\t\t\t\t\t\tif (step >= timeUnitSize.minute) {\n\t\t\t\t\t\t\td.setSeconds(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.hour) {\n\t\t\t\t\t\t\td.setMinutes(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day) {\n\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day * 4) {\n\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.month * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 3));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.quarter * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 6));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.year) {\n\t\t\t\t\t\t\td.setMonth(0);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar carry = 0;\n\t\t\t\t\t\tvar v = Number.NaN;\n\t\t\t\t\t\tvar prev;\n\n\t\t\t\t\t\tdo {\n\n\t\t\t\t\t\t\tprev = v;\n\t\t\t\t\t\t\tv = d.getTime();\n\t\t\t\t\t\t\tticks.push(v);\n\n\t\t\t\t\t\t\tif (unit == \"month\" || unit == \"quarter\") {\n\t\t\t\t\t\t\t\tif (tickSize < 1) {\n\n\t\t\t\t\t\t\t\t\t// a bit complicated - we'll divide the\n\t\t\t\t\t\t\t\t\t// month/quarter up but we need to take\n\t\t\t\t\t\t\t\t\t// care of fractions so we don't end up in\n\t\t\t\t\t\t\t\t\t// the middle of a day\n\n\t\t\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t\t\t\tvar start = d.getTime();\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\t(unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t\tvar end = d.getTime();\n\t\t\t\t\t\t\t\t\td.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);\n\t\t\t\t\t\t\t\t\tcarry = d.getHours();\n\t\t\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\ttickSize * (unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\t\td.setFullYear(d.getFullYear() + tickSize);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\td.setTime(v + step);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while (v < axis.max && v != prev);\n\n\t\t\t\t\t\treturn ticks;\n\t\t\t\t\t};\n\n\t\t\t\t\taxis.tickFormatter = function (v, axis) {\n\n\t\t\t\t\t\tvar d = dateGenerator(v, axis.options);\n\n\t\t\t\t\t\t// first check global format\n\n\t\t\t\t\t\tif (opts.timeformat != null) {\n\t\t\t\t\t\t\treturn formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// possibly use quarters if quarters are mentioned in\n\t\t\t\t\t\t// any of these places\n\n\t\t\t\t\t\tvar useQuarters = (axis.options.tickSize &&\n\t\t\t\t\t\t\t\taxis.options.tickSize[1] == \"quarter\") ||\n\t\t\t\t\t\t\t(axis.options.minTickSize &&\n\t\t\t\t\t\t\t\taxis.options.minTickSize[1] == \"quarter\");\n\n\t\t\t\t\t\tvar t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];\n\t\t\t\t\t\tvar span = axis.max - axis.min;\n\t\t\t\t\t\tvar suffix = (opts.twelveHourClock) ? \" %p\" : \"\";\n\t\t\t\t\t\tvar hourCode = (opts.twelveHourClock) ? \"%I\" : \"%H\";\n\t\t\t\t\t\tvar fmt;\n\n\t\t\t\t\t\tif (t < timeUnitSize.minute) {\n\t\t\t\t\t\t\tfmt = hourCode + \":%M:%S\" + suffix;\n\t\t\t\t\t\t} else if (t < timeUnitSize.day) {\n\t\t\t\t\t\t\tif (span < 2 * timeUnitSize.day) {\n\t\t\t\t\t\t\t\tfmt = hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %d \" + hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t < timeUnitSize.month) {\n\t\t\t\t\t\t\tfmt = \"%b %d\";\n\t\t\t\t\t\t} else if ((useQuarters && t < timeUnitSize.quarter) ||\n\t\t\t\t\t\t\t(!useQuarters && t < timeUnitSize.year)) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"%b\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (useQuarters && t < timeUnitSize.year) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"Q%q\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"Q%q %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfmt = \"%Y\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);\n\n\t\t\t\t\t\treturn rt;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: 'time',\n\t\tversion: '1.0'\n\t});\n\n\t// Time-axis support used to be in Flot core, which exposed the\n\t// formatDate function on the plot object. Various plugins depend\n\t// on the function, so we need to re-expose it here.\n\n\t$.plot.formatDate = formatDate;\n\n})(jQuery);\n\n\n//# sourceURL=webpack:///./vendor/flot/jquery.flot.time.js?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "angular": |
|
/*!**************************!*\ |
|
!*** external "angular" ***! |
|
\**************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_angular__;\n\n//# sourceURL=webpack:///external_%22angular%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "grafana/app/core/config": |
|
/*!**********************************!*\ |
|
!*** external "app/core/config" ***! |
|
\**********************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_grafana_app_core_config__;\n\n//# sourceURL=webpack:///external_%22app/core/config%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "grafana/app/core/core": |
|
/*!********************************!*\ |
|
!*** external "app/core/core" ***! |
|
\********************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_grafana_app_core_core__;\n\n//# sourceURL=webpack:///external_%22app/core/core%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "grafana/app/core/core_module": |
|
/*!***************************************!*\ |
|
!*** external "app/core/core_module" ***! |
|
\***************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_grafana_app_core_core_module__;\n\n//# sourceURL=webpack:///external_%22app/core/core_module%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "grafana/app/core/time_series2": |
|
/*!****************************************!*\ |
|
!*** external "app/core/time_series2" ***! |
|
\****************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_grafana_app_core_time_series2__;\n\n//# sourceURL=webpack:///external_%22app/core/time_series2%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "grafana/app/core/utils/kbn": |
|
/*!*************************************!*\ |
|
!*** external "app/core/utils/kbn" ***! |
|
\*************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_grafana_app_core_utils_kbn__;\n\n//# sourceURL=webpack:///external_%22app/core/utils/kbn%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "grafana/app/core/utils/ticks": |
|
/*!***************************************!*\ |
|
!*** external "app/core/utils/ticks" ***! |
|
\***************************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_grafana_app_core_utils_ticks__;\n\n//# sourceURL=webpack:///external_%22app/core/utils/ticks%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "grafana/app/plugins/sdk": |
|
/*!**********************************!*\ |
|
!*** external "app/plugins/sdk" ***! |
|
\**********************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_grafana_app_plugins_sdk__;\n\n//# sourceURL=webpack:///external_%22app/plugins/sdk%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "jquery": |
|
/*!*************************!*\ |
|
!*** external "jquery" ***! |
|
\*************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__;\n\n//# sourceURL=webpack:///external_%22jquery%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "lodash": |
|
/*!*************************!*\ |
|
!*** external "lodash" ***! |
|
\*************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_lodash__;\n\n//# sourceURL=webpack:///external_%22lodash%22?"); |
|
|
|
/***/ }), |
|
|
|
/***/ "moment": |
|
/*!*************************!*\ |
|
!*** external "moment" ***! |
|
\*************************/ |
|
/*! no static exports found */ |
|
/***/ (function(module, exports) { |
|
|
|
eval("module.exports = __WEBPACK_EXTERNAL_MODULE_moment__;\n\n//# sourceURL=webpack:///external_%22moment%22?"); |
|
|
|
/***/ }) |
|
|
|
/******/ })});; |