diff --git a/dist/module.js b/dist/module.js index 0598b2e..ea4a4a4 100644 --- a/dist/module.js +++ b/dist/module.js @@ -198,7 +198,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (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, data, status_1, error, 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 data = _b.sent();\n status_1 = data.status;\n error = data.errorMessage;\n if (anomalyType.status !== status_1) {\n anomalyType.status = status_1;\n if (error !== undefined) {\n anomalyType.error = error;\n }\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?"); +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, rangeDist) {\n var result = [];\n this._anomalyTypesSet.anomalyTypes.forEach(function (at) {\n var segs = at.segments.findSegments(point, rangeDist);\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, data, status_1, error, 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 data = _b.sent();\n status_1 = data.status;\n error = data.errorMessage;\n if (anomalyType.status !== status_1) {\n anomalyType.status = status_1;\n if (error !== undefined) {\n anomalyType.error = error;\n }\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?"); /***/ }), @@ -246,7 +246,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (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 = $('
');\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 += '
';\n seriesHtml += ' ' + hoverInfo.label + ':
';\n seriesHtml += '
' + value + '
';\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 = '
';\n group += ' ' + series.aliasEscaped + ':
';\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 += '
' + value + '
';\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
\\n
\\n \\n \" + s.anomalyType.name + \":\\n
\\n
\\n \\n \" + from + \" \\u2014 \" + to + \"\\n
\\n
\\n \";\n });\n return result;\n };\n GraphTooltip.prototype._renderAndShow = function (absoluteTime, innerHtml, pos, xMode) {\n if (xMode === 'time') {\n innerHtml = '
' + absoluteTime + '
' + 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?"); +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 = $('
');\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 var rangeDist = Math.abs(xAxes[0].max - xAxes[0].min);\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 += '
';\n seriesHtml += ' ' + hoverInfo.label + ':
';\n seriesHtml += '
' + value + '
';\n plot.highlight(hoverInfo.index, hoverInfo.hoverIndex);\n }\n seriesHtml += this._appendAnomaliesHTML(pos.x, rangeDist);\n this._renderAndShow(absoluteTime, seriesHtml, pos, xMode);\n }\n // single series tooltip\n else if (item) {\n series = seriesList[item.seriesIndex];\n group = '
';\n group += ' ' + series.aliasEscaped + ':
';\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 += '
' + value + '
';\n group += this._appendAnomaliesHTML(pos.x, rangeDist);\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, rangeDist) {\n var _this = this;\n var result = '';\n var segments = this._anomalySegmentsSearcher(pos, rangeDist);\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
\\n
\\n \\n \" + s.anomalyType.name + \":\\n
\\n
\\n \\n \" + from + \" \\u2014 \" + to + \"\\n
\\n
\\n \";\n });\n return result;\n };\n GraphTooltip.prototype._renderAndShow = function (absoluteTime, innerHtml, pos, xMode) {\n if (xMode === 'time') {\n innerHtml = '
' + absoluteTime + '
' + 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?"); /***/ }), @@ -306,7 +306,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (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?"); +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, rangeDist) {\n return this._segments.filter(function (s) {\n var expanded = s.expandDist(rangeDist, 0.01);\n return (expanded.from <= point) && (point <= expanded.to);\n });\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?"); /***/ }), @@ -318,7 +318,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (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.patterns = ['General approach', 'Peaks', 'Jumps', 'Drops'];\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 };\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: '',\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?"); +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.patterns = ['General approach', 'Drops', 'Jumps', 'Peaks'];\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 };\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: '',\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?"); /***/ }), diff --git a/dist/partials/tab_analytics.html b/dist/partials/tab_analytics.html index afa2e82..dbfe59e 100644 --- a/dist/partials/tab_analytics.html +++ b/dist/partials/tab_analytics.html @@ -13,7 +13,6 @@