@c8y/ngx-components 1021.52.0 → 1021.54.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.component.d.ts +10 -2
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.component.d.ts.map +1 -1
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.model.d.ts +11 -0
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.model.d.ts.map +1 -0
- package/alarm-event-selector/alarm-event-selection-list/alarm-event-selection-list.component.d.ts +10 -4
- package/alarm-event-selector/alarm-event-selection-list/alarm-event-selection-list.component.d.ts.map +1 -1
- package/alarm-event-selector/alarm-event-selector-list-item/alarm-event-selector-list-item.component.d.ts +3 -1
- package/alarm-event-selector/alarm-event-selector-list-item/alarm-event-selector-list-item.component.d.ts.map +1 -1
- package/alarm-event-selector/alarm-event-selector.model.d.ts +7 -0
- package/alarm-event-selector/alarm-event-selector.model.d.ts.map +1 -1
- package/core/dashboard/dashboard-child-action.component.d.ts +1 -1
- package/core/dashboard/dashboard-child-action.component.d.ts.map +1 -1
- package/core/dashboard/dashboard.module.d.ts +29 -29
- package/core/dashboard/index.d.ts +3 -0
- package/core/dashboard/index.d.ts.map +1 -1
- package/core/dashboard/widgets-dashboard.component.d.ts +1 -1
- package/core/dashboard/widgets-dashboard.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts +1 -1
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.d.ts +1 -1
- package/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context-date-range.service.d.ts +10 -0
- package/core/dashboard/wiget-time-context/widget-time-context-date-range.service.d.ts.map +1 -0
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts +7 -4
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts +0 -1
- package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts.map +1 -1
- package/core/date-picker/date-picker.component.d.ts +1 -1
- package/core/date-picker/date-picker.component.d.ts.map +1 -1
- package/core/date-picker/date-picker.module.d.ts +9 -9
- package/core/date-time-picker/close-date-picker.directive.d.ts +1 -1
- package/core/date-time-picker/close-date-picker.directive.d.ts.map +1 -1
- package/core/date-time-picker/date-time-picker.component.d.ts +6 -3
- package/core/date-time-picker/date-time-picker.component.d.ts.map +1 -1
- package/core/date-time-picker/date-time-picker.module.d.ts +11 -11
- package/core/date-time-picker/date-time-picker.module.d.ts.map +1 -1
- package/core/forms/forms.module.d.ts +18 -18
- package/core/forms/required-input-placeholder.directive.d.ts +1 -1
- package/core/forms/required-input-placeholder.directive.d.ts.map +1 -1
- package/core/router/router.service.d.ts.map +1 -1
- package/core/user/user-menu.service.d.ts +36 -11
- package/core/user/user-menu.service.d.ts.map +1 -1
- package/datapoint-explorer/c8y-ngx-components-datapoint-explorer.d.ts.map +1 -0
- package/datapoint-explorer/datapoint-explorer.module.d.ts +7 -0
- package/datapoint-explorer/datapoint-explorer.module.d.ts.map +1 -0
- package/datapoint-explorer/index.d.ts +2 -0
- package/datapoint-explorer/index.d.ts.map +1 -0
- package/datapoint-explorer/view/c8y-ngx-components-datapoint-explorer-view.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/naming-dictionary.d.ts +3 -0
- package/datapoint-explorer/view/configuration/naming-dictionary.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.component.d.ts +38 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.component.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.model.d.ts +7 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.model.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.service.d.ts +15 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.service.d.ts.map +1 -0
- package/datapoint-explorer/view/create-new-report-modal/create-new-report-modal.component.d.ts +25 -0
- package/datapoint-explorer/view/create-new-report-modal/create-new-report-modal.component.d.ts.map +1 -0
- package/datapoint-explorer/view/datapoint-explorer.component.d.ts +67 -0
- package/datapoint-explorer/view/datapoint-explorer.component.d.ts.map +1 -0
- package/datapoint-explorer/view/datapoint-explorer.service.d.ts +9 -0
- package/datapoint-explorer/view/datapoint-explorer.service.d.ts.map +1 -0
- package/datapoint-explorer/view/index.d.ts +2 -0
- package/datapoint-explorer/view/index.d.ts.map +1 -0
- package/datapoint-explorer/view/send-as-widget-to-report-modal/send-as-widget-to-report-modal.component.d.ts +23 -0
- package/datapoint-explorer/view/send-as-widget-to-report-modal/send-as-widget-to-report-modal.component.d.ts.map +1 -0
- package/echart/c8y-ngx-components-echart.d.ts.map +1 -0
- package/echart/chart-alerts/chart-alerts.component.d.ts +8 -0
- package/echart/chart-alerts/chart-alerts.component.d.ts.map +1 -0
- package/echart/charts.component.d.ts +63 -0
- package/echart/charts.component.d.ts.map +1 -0
- package/echart/index.d.ts +5 -0
- package/echart/index.d.ts.map +1 -0
- package/echart/models/c8y-ngx-components-echart-models.d.ts.map +1 -0
- package/echart/models/chart.model.d.ts +37 -0
- package/echart/models/chart.model.d.ts.map +1 -0
- package/echart/models/datapoints-graph-widget.model.d.ts +126 -0
- package/echart/models/datapoints-graph-widget.model.d.ts.map +1 -0
- package/echart/models/index.d.ts +4 -0
- package/echart/models/index.d.ts.map +1 -0
- package/echart/models/svg-icons.model.d.ts +22 -0
- package/echart/models/svg-icons.model.d.ts.map +1 -0
- package/echart/services/chart-alarms.service.d.ts +17 -0
- package/echart/services/chart-alarms.service.d.ts.map +1 -0
- package/echart/services/chart-events.service.d.ts +17 -0
- package/echart/services/chart-events.service.d.ts.map +1 -0
- package/echart/services/chart-realtime.service.d.ts +35 -0
- package/echart/services/chart-realtime.service.d.ts.map +1 -0
- package/echart/services/chart-types.service.d.ts +15 -0
- package/echart/services/chart-types.service.d.ts.map +1 -0
- package/echart/services/custom-measurements.service.d.ts +12 -0
- package/echart/services/custom-measurements.service.d.ts.map +1 -0
- package/echart/services/echarts-options.service.d.ts +143 -0
- package/echart/services/echarts-options.service.d.ts.map +1 -0
- package/echart/services/y-axis.service.d.ts +17 -0
- package/echart/services/y-axis.service.d.ts.map +1 -0
- package/esm2022/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.component.mjs +37 -12
- package/esm2022/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.model.mjs +2 -0
- package/esm2022/alarm-event-selector/alarm-event-selection-list/alarm-event-selection-list.component.mjs +39 -12
- package/esm2022/alarm-event-selector/alarm-event-selector-list-item/alarm-event-selector-list-item.component.mjs +6 -4
- package/esm2022/alarm-event-selector/alarm-event-selector.component.mjs +1 -1
- package/esm2022/alarm-event-selector/alarm-event-selector.model.mjs +1 -1
- package/esm2022/alarm-event-selector/custom-alarm-event-form/custom-alarm-event-form.component.mjs +1 -1
- package/esm2022/alarms/alarms-filter.component.mjs +3 -3
- package/esm2022/core/dashboard/dashboard-child-action.component.mjs +3 -3
- package/esm2022/core/dashboard/dashboard.module.mjs +17 -14
- package/esm2022/core/dashboard/index.mjs +4 -1
- package/esm2022/core/dashboard/widgets-dashboard.component.mjs +9 -9
- package/esm2022/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.mjs +11 -9
- package/esm2022/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.mjs +8 -7
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context-date-range.service.mjs +23 -0
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.component.mjs +70 -26
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.model.mjs +1 -1
- package/esm2022/core/date-picker/date-picker.component.mjs +29 -14
- package/esm2022/core/date-picker/date-picker.module.mjs +9 -7
- package/esm2022/core/date-time-picker/close-date-picker.directive.mjs +4 -3
- package/esm2022/core/date-time-picker/date-time-picker.component.mjs +57 -29
- package/esm2022/core/date-time-picker/date-time-picker.module.mjs +11 -7
- package/esm2022/core/forms/forms.module.mjs +3 -3
- package/esm2022/core/forms/ip-range-input-list.component.mjs +5 -5
- package/esm2022/core/forms/required-input-placeholder.directive.mjs +4 -3
- package/esm2022/core/router/router.service.mjs +1 -1
- package/esm2022/core/user/user-menu.service.mjs +57 -17
- package/esm2022/datapoint-explorer/c8y-ngx-components-datapoint-explorer.mjs +5 -0
- package/esm2022/datapoint-explorer/datapoint-explorer.module.mjs +65 -0
- package/esm2022/datapoint-explorer/index.mjs +2 -0
- package/esm2022/datapoint-explorer/view/c8y-ngx-components-datapoint-explorer-view.mjs +5 -0
- package/esm2022/datapoint-explorer/view/configuration/naming-dictionary.mjs +65 -0
- package/esm2022/datapoint-explorer/view/configuration/workspace-configuration.component.mjs +169 -0
- package/esm2022/datapoint-explorer/view/configuration/workspace-configuration.model.mjs +2 -0
- package/esm2022/datapoint-explorer/view/configuration/workspace-configuration.service.mjs +40 -0
- package/esm2022/datapoint-explorer/view/create-new-report-modal/create-new-report-modal.component.mjs +64 -0
- package/esm2022/datapoint-explorer/view/datapoint-explorer.component.mjs +279 -0
- package/esm2022/datapoint-explorer/view/datapoint-explorer.service.mjs +23 -0
- package/esm2022/datapoint-explorer/view/index.mjs +2 -0
- package/esm2022/datapoint-explorer/view/send-as-widget-to-report-modal/send-as-widget-to-report-modal.component.mjs +48 -0
- package/esm2022/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.mjs +3 -3
- package/esm2022/datapoint-selector/datapoint-selector-list-item/datapoint-selector-list-item.component.mjs +3 -3
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.mjs +3 -3
- package/esm2022/datapoints-export-selector/datapoints-export-selector.component.mjs +3 -3
- package/esm2022/device-list/add-smart-group.component.mjs +3 -3
- package/esm2022/echart/c8y-ngx-components-echart.mjs +5 -0
- package/esm2022/echart/chart-alerts/chart-alerts.component.mjs +16 -0
- package/esm2022/echart/charts.component.mjs +560 -0
- package/esm2022/echart/index.mjs +5 -0
- package/esm2022/echart/models/c8y-ngx-components-echart-models.mjs +5 -0
- package/esm2022/echart/models/chart.model.mjs +2 -0
- package/esm2022/echart/models/datapoints-graph-widget.model.mjs +17 -0
- package/esm2022/echart/models/index.mjs +4 -0
- package/esm2022/echart/models/svg-icons.model.mjs +22 -0
- package/esm2022/echart/services/chart-alarms.service.mjs +58 -0
- package/esm2022/echart/services/chart-events.service.mjs +44 -0
- package/esm2022/echart/services/chart-realtime.service.mjs +193 -0
- package/esm2022/echart/services/chart-types.service.mjs +102 -0
- package/esm2022/echart/services/custom-measurements.service.mjs +52 -0
- package/esm2022/echart/services/echarts-options.service.mjs +857 -0
- package/esm2022/echart/services/y-axis.service.mjs +150 -0
- package/esm2022/interval-picker/interval-picker.component.mjs +3 -3
- package/esm2022/interval-picker/interval-picker.model.mjs +1 -1
- package/esm2022/report-dashboard/index.mjs +2 -1
- package/esm2022/time-context/c8y-ngx-components-time-context.mjs +5 -0
- package/esm2022/time-context/index.mjs +2 -0
- package/esm2022/time-context/time-context.component.mjs +217 -0
- package/esm2022/time-context/time-context.service.mjs +83 -0
- package/esm2022/translation-editor/lazy/translation-editor/translation-editor.component.mjs +6 -5
- package/esm2022/widgets/cockpit-exports/index.mjs +8 -1
- package/esm2022/widgets/definitions/datapoints-graph/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +5 -0
- package/esm2022/widgets/definitions/datapoints-graph/index.mjs +31 -0
- package/esm2022/widgets/definitions/index.mjs +3 -2
- package/esm2022/widgets/implementations/datapoints-graph/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +5 -0
- package/esm2022/widgets/implementations/datapoints-graph/datapoints-graph-config/datapoints-graph-widget-config.component.mjs +239 -0
- package/esm2022/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.mjs +241 -0
- package/esm2022/widgets/implementations/datapoints-graph/index.mjs +3 -0
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs +80 -28
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-alarms.mjs +2 -2
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +658 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer.mjs +72 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +4 -4
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +4 -4
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-list.mjs +2 -2
- package/fesm2022/c8y-ngx-components-device-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart-models.mjs +46 -0
- package/fesm2022/c8y-ngx-components-echart-models.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-echart.mjs +2023 -0
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-interval-picker.mjs +2 -2
- package/fesm2022/c8y-ngx-components-interval-picker.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-report-dashboard.mjs +1 -1
- package/fesm2022/c8y-ngx-components-time-context.mjs +300 -0
- package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs +5 -4
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs +7 -0
- package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +38 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs +2 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +467 -0
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components.mjs +429 -277
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/interval-picker/interval-picker.component.d.ts.map +1 -1
- package/interval-picker/interval-picker.model.d.ts.map +1 -1
- package/locales/de.po +206 -279
- package/locales/es.po +206 -279
- package/locales/fr.po +206 -279
- package/locales/ja_JP.po +196 -279
- package/locales/ko.po +455 -444
- package/locales/locales.pot +200 -0
- package/locales/nl.po +206 -279
- package/locales/pl.po +206 -279
- package/locales/pt_BR.po +206 -279
- package/locales/zh_CN.po +450 -443
- package/locales/zh_TW.po +452 -445
- package/package.json +1 -1
- package/report-dashboard/index.d.ts +1 -0
- package/report-dashboard/index.d.ts.map +1 -1
- package/time-context/c8y-ngx-components-time-context.d.ts.map +1 -0
- package/time-context/index.d.ts +2 -0
- package/time-context/index.d.ts.map +1 -0
- package/time-context/time-context.component.d.ts +61 -0
- package/time-context/time-context.component.d.ts.map +1 -0
- package/time-context/time-context.service.d.ts +25 -0
- package/time-context/time-context.service.d.ts.map +1 -0
- package/translation-editor/lazy/translation-editor/translation-editor.component.d.ts.map +1 -1
- package/widgets/cockpit-exports/index.d.ts +6 -0
- package/widgets/cockpit-exports/index.d.ts.map +1 -1
- package/widgets/definitions/datapoints-graph/c8y-ngx-components-widgets-definitions-datapoints-graph.d.ts.map +1 -0
- package/widgets/definitions/datapoints-graph/index.d.ts +16 -0
- package/widgets/definitions/datapoints-graph/index.d.ts.map +1 -0
- package/widgets/definitions/index.d.ts +1 -0
- package/widgets/definitions/index.d.ts.map +1 -1
- package/widgets/implementations/datapoints-graph/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts.map +1 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-config/datapoints-graph-widget-config.component.d.ts +43 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-config/datapoints-graph-widget-config.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.d.ts +54 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-graph/index.d.ts +3 -0
- package/widgets/implementations/datapoints-graph/index.d.ts.map +1 -0
|
@@ -0,0 +1,857 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import { DatePipe } from '@c8y/ngx-components';
|
|
4
|
+
import { YAxisService } from './y-axis.service';
|
|
5
|
+
import { ChartTypesService } from './chart-types.service';
|
|
6
|
+
import { AlarmStatus } from '@c8y/client';
|
|
7
|
+
import { ICONS_MAP } from '../models/svg-icons.model';
|
|
8
|
+
import { Router } from '@angular/router';
|
|
9
|
+
import { AlarmSeverityToIconPipe, AlarmSeverityToLabelPipe } from '@c8y/ngx-components/alarms';
|
|
10
|
+
import { INTERVALS } from '@c8y/ngx-components/interval-picker';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
import * as i1 from "@c8y/ngx-components";
|
|
13
|
+
import * as i2 from "./y-axis.service";
|
|
14
|
+
import * as i3 from "./chart-types.service";
|
|
15
|
+
import * as i4 from "@c8y/ngx-components/alarms";
|
|
16
|
+
import * as i5 from "@angular/router";
|
|
17
|
+
const INDEX_HTML = '/index.html';
|
|
18
|
+
export class EchartsOptionsService {
|
|
19
|
+
constructor(datePipe, yAxisService, chartTypesService, severityIconPipe, severityLabelPipe, router) {
|
|
20
|
+
this.datePipe = datePipe;
|
|
21
|
+
this.yAxisService = yAxisService;
|
|
22
|
+
this.chartTypesService = chartTypesService;
|
|
23
|
+
this.severityIconPipe = severityIconPipe;
|
|
24
|
+
this.severityLabelPipe = severityLabelPipe;
|
|
25
|
+
this.router = router;
|
|
26
|
+
this.TOOLTIP_WIDTH = 300;
|
|
27
|
+
}
|
|
28
|
+
getChartOptions(datapointsWithValues, timeRange, showSplitLines, events, alarms, displayOptions, selectedTimeRange, aggregatedDatapoints, sliderZoomUsed = false) {
|
|
29
|
+
const yAxis = this.yAxisService.getYAxis(datapointsWithValues, {
|
|
30
|
+
showSplitLines: showSplitLines.YAxis,
|
|
31
|
+
mergeMatchingDatapoints: displayOptions.mergeMatchingDatapoints,
|
|
32
|
+
showLabelAndUnit: displayOptions.showLabelAndUnit
|
|
33
|
+
});
|
|
34
|
+
const leftAxis = yAxis.filter(yx => yx.position === 'left');
|
|
35
|
+
const gridLeft = leftAxis.length ? leftAxis.length * this.yAxisService.Y_AXIS_OFFSET : 16;
|
|
36
|
+
const rightAxis = yAxis.filter(yx => yx.position === 'right');
|
|
37
|
+
const gridRight = rightAxis.length ? rightAxis.length * this.yAxisService.Y_AXIS_OFFSET : 16;
|
|
38
|
+
let intervalInMs = this.calculateExtendedIntervalInMs(selectedTimeRange?.interval || timeRange.interval || 'hours', selectedTimeRange || timeRange);
|
|
39
|
+
if (sliderZoomUsed) {
|
|
40
|
+
intervalInMs = this.calculateExtendedIntervalInMs(timeRange.interval || 'hours', timeRange);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
grid: {
|
|
44
|
+
containLabel: false, // axis labels are not taken into account to calculate graph grid
|
|
45
|
+
left: gridLeft,
|
|
46
|
+
top: 16,
|
|
47
|
+
right: gridRight,
|
|
48
|
+
bottom: 68
|
|
49
|
+
},
|
|
50
|
+
dataZoom: [
|
|
51
|
+
{
|
|
52
|
+
type: 'inside',
|
|
53
|
+
// TODO: use 'none' only when this bug is fixed https://github.com/apache/echarts/issues/17858
|
|
54
|
+
filterMode: datapointsWithValues.some(dp => dp.lineType === 'bars') ? 'filter' : 'none',
|
|
55
|
+
zoomOnMouseWheel: true,
|
|
56
|
+
startValue: selectedTimeRange
|
|
57
|
+
? selectedTimeRange.dateFrom.valueOf()
|
|
58
|
+
: timeRange.dateFrom.valueOf(),
|
|
59
|
+
endValue: selectedTimeRange
|
|
60
|
+
? selectedTimeRange.dateTo.valueOf()
|
|
61
|
+
: timeRange.dateTo.valueOf()
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: 'slider',
|
|
65
|
+
show: displayOptions.showSlider,
|
|
66
|
+
bottom: 8,
|
|
67
|
+
realtime: false
|
|
68
|
+
}
|
|
69
|
+
], // on realtime, 'none' will cause extending chart line to left edge of the chart
|
|
70
|
+
animation: false,
|
|
71
|
+
toolbox: {
|
|
72
|
+
show: true,
|
|
73
|
+
itemSize: 0, // toolbox is needed for zooming in action, but we provide our own buttons
|
|
74
|
+
feature: {
|
|
75
|
+
dataZoom: {
|
|
76
|
+
yAxisIndex: 'none'
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
tooltip: {
|
|
81
|
+
trigger: 'axis',
|
|
82
|
+
axisPointer: {
|
|
83
|
+
type: 'cross',
|
|
84
|
+
snap: true
|
|
85
|
+
},
|
|
86
|
+
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
87
|
+
formatter: this.getTooltipFormatter(),
|
|
88
|
+
appendToBody: true,
|
|
89
|
+
position: this.tooltipPosition(),
|
|
90
|
+
transitionDuration: 0
|
|
91
|
+
},
|
|
92
|
+
legend: {
|
|
93
|
+
show: false
|
|
94
|
+
},
|
|
95
|
+
xAxis: {
|
|
96
|
+
min: new Date(timeRange.dateFrom).valueOf() - intervalInMs,
|
|
97
|
+
max: timeRange.dateTo,
|
|
98
|
+
type: 'time',
|
|
99
|
+
animation: false,
|
|
100
|
+
axisPointer: {
|
|
101
|
+
label: {
|
|
102
|
+
show: false
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
axisLine: {
|
|
106
|
+
// align X axis to 0 of Y axis of datapoint with lineType 'bars'
|
|
107
|
+
onZeroAxisIndex: datapointsWithValues.findIndex(dp => dp.lineType === 'bars')
|
|
108
|
+
},
|
|
109
|
+
axisLabel: {
|
|
110
|
+
hideOverlap: true,
|
|
111
|
+
borderWidth: 2, // as there is no margin for labels spacing, transparent border is a workaround
|
|
112
|
+
borderColor: 'transparent'
|
|
113
|
+
},
|
|
114
|
+
splitLine: {
|
|
115
|
+
show: showSplitLines.XAxis,
|
|
116
|
+
lineStyle: { opacity: 0.8, type: 'dashed', width: 2 }
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
yAxis,
|
|
120
|
+
series: [
|
|
121
|
+
...this.getAggregatedSeries(aggregatedDatapoints || []).filter(series => series !== undefined),
|
|
122
|
+
...this.getChartSeries(datapointsWithValues, events, alarms, displayOptions)
|
|
123
|
+
]
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
calculateExtendedIntervalInMs(interval, selectedTimeRange) {
|
|
127
|
+
let intervalInMs = INTERVALS.find(i => i.id === interval).timespanInMs;
|
|
128
|
+
switch (interval) {
|
|
129
|
+
case 'minutes':
|
|
130
|
+
intervalInMs = INTERVALS.find(i => i.id === interval).timespanInMs * 60;
|
|
131
|
+
break;
|
|
132
|
+
case 'hours':
|
|
133
|
+
intervalInMs = INTERVALS.find(i => i.id === interval).timespanInMs * 24;
|
|
134
|
+
break;
|
|
135
|
+
case 'days':
|
|
136
|
+
intervalInMs = INTERVALS.find(i => i.id === interval).timespanInMs * 28;
|
|
137
|
+
break;
|
|
138
|
+
case 'weeks':
|
|
139
|
+
intervalInMs = INTERVALS.find(i => i.id === interval).timespanInMs * 12;
|
|
140
|
+
break;
|
|
141
|
+
case 'months':
|
|
142
|
+
intervalInMs = INTERVALS.find(i => i.id === interval).timespanInMs * 12;
|
|
143
|
+
break;
|
|
144
|
+
case 'custom':
|
|
145
|
+
intervalInMs =
|
|
146
|
+
(new Date(selectedTimeRange.dateTo).valueOf() -
|
|
147
|
+
new Date(selectedTimeRange.dateFrom).valueOf()) *
|
|
148
|
+
12;
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
intervalInMs = INTERVALS.find(i => i.id === interval).timespanInMs;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
return intervalInMs;
|
|
155
|
+
}
|
|
156
|
+
getAggregatedSeries(aggregatedDatapoints) {
|
|
157
|
+
const series = [];
|
|
158
|
+
aggregatedDatapoints.forEach((dp, idx) => {
|
|
159
|
+
const renderType = dp.renderType || 'min';
|
|
160
|
+
if (renderType === 'area') {
|
|
161
|
+
series.push(this.getSingleSeries(dp, 'min', idx, true, 'aggr'));
|
|
162
|
+
series.push(this.getSingleSeries(dp, 'max', idx, true, 'aggr'));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
series.push(this.getSingleSeries(dp, renderType, idx, false, 'aggr'));
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
series.forEach((s) => {
|
|
169
|
+
s.datapointId = 'aggregated';
|
|
170
|
+
s.typeOfSeries = 'fake';
|
|
171
|
+
s.itemStyle = {
|
|
172
|
+
...s.itemStyle,
|
|
173
|
+
opacity: 0
|
|
174
|
+
};
|
|
175
|
+
s.lineStyle = {
|
|
176
|
+
...s.lineStyle,
|
|
177
|
+
opacity: 0
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
return [series[0]];
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* This method is used to get the series for alarms and events.
|
|
184
|
+
* @param dp - The data point.
|
|
185
|
+
* @param renderType - The render type.
|
|
186
|
+
* @param isMinMaxChart - If the chart is min max chart.
|
|
187
|
+
* @param items - All alarms or events which should be displayed on the chart.
|
|
188
|
+
* @param itemType - The item type.
|
|
189
|
+
* @param id - The id of the device
|
|
190
|
+
*/
|
|
191
|
+
getAlarmOrEventSeries(dp, renderType, isMinMaxChart = false, items = [], itemType = 'alarm', displayOptions = { displayMarkedLine: true, displayMarkedPoint: true }, id, idx, realtime) {
|
|
192
|
+
if (!items.length) {
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
if (!displayOptions.displayMarkedLine && !displayOptions.displayMarkedPoint) {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
//filter items that are not __hidden
|
|
199
|
+
const filteredItems = items.filter(item => !item['__hidden']);
|
|
200
|
+
const itemsByType = this.groupByType(filteredItems, 'type');
|
|
201
|
+
const isAlarm = itemType === 'alarm';
|
|
202
|
+
return Object.entries(itemsByType).flatMap(([type, itemsOfType]) => {
|
|
203
|
+
// Main series data
|
|
204
|
+
const mainData = itemsOfType.map(item => [item.creationTime, null, 'markLineFlag']);
|
|
205
|
+
// Is a specific datapoint template selected for this alarm/event type?
|
|
206
|
+
let isDpTemplateSelected = false;
|
|
207
|
+
// MarkPoint data
|
|
208
|
+
const markPointData = itemsOfType.reduce((acc, item) => {
|
|
209
|
+
isDpTemplateSelected =
|
|
210
|
+
item['selectedDatapoint'] &&
|
|
211
|
+
dp['__target'] &&
|
|
212
|
+
item['selectedDatapoint']['fragment'] === dp['fragment'] &&
|
|
213
|
+
item['selectedDatapoint']['series'] === dp['series'] &&
|
|
214
|
+
item['selectedDatapoint']['target'] === dp['__target']['id'];
|
|
215
|
+
if (dp.__target?.id === item.source.id) {
|
|
216
|
+
const isCleared = isAlarm && item.status === AlarmStatus.CLEARED;
|
|
217
|
+
const isEvent = !isAlarm;
|
|
218
|
+
return acc.concat(this.createMarkPoint(item, dp, isCleared, isEvent, realtime));
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
if (!item.creationTime) {
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
224
|
+
return acc.concat([
|
|
225
|
+
{
|
|
226
|
+
coord: [item.creationTime, null],
|
|
227
|
+
name: item.type,
|
|
228
|
+
itemType: item.type,
|
|
229
|
+
itemStyle: { color: item['color'] }
|
|
230
|
+
}
|
|
231
|
+
]);
|
|
232
|
+
}
|
|
233
|
+
}, []);
|
|
234
|
+
// Construct series with markPoint
|
|
235
|
+
const seriesWithMarkPoint = {
|
|
236
|
+
id: `${type}/${dp.__target?.id}+${id ? id : ''}-markPoint`,
|
|
237
|
+
name: `${type}-markPoint`,
|
|
238
|
+
typeOfSeries: itemType,
|
|
239
|
+
data: mainData,
|
|
240
|
+
isDpTemplateSelected,
|
|
241
|
+
position: 'bottom',
|
|
242
|
+
silent: true,
|
|
243
|
+
markPoint: {
|
|
244
|
+
showSymbol: true,
|
|
245
|
+
symbolKeepAspect: true,
|
|
246
|
+
data: markPointData
|
|
247
|
+
},
|
|
248
|
+
yAxisIndex: idx,
|
|
249
|
+
...this.chartTypesService.getSeriesOptions(dp, isMinMaxChart, renderType)
|
|
250
|
+
};
|
|
251
|
+
const markLineData = this.createMarkLine(itemsOfType);
|
|
252
|
+
// Construct series with markLine
|
|
253
|
+
const seriesWithMarkLine = {
|
|
254
|
+
id: `${type}/${dp.__target?.id}+${id ? id : ''}-markLine`,
|
|
255
|
+
name: `${type}-markLine`,
|
|
256
|
+
typeOfSeries: itemType,
|
|
257
|
+
isDpTemplateSelected,
|
|
258
|
+
data: mainData,
|
|
259
|
+
markLine: {
|
|
260
|
+
showSymbol: false,
|
|
261
|
+
symbol: ['none', 'none'], // no symbol at the start/end of the line
|
|
262
|
+
data: markLineData
|
|
263
|
+
},
|
|
264
|
+
...this.chartTypesService.getSeriesOptions(dp, isMinMaxChart, renderType)
|
|
265
|
+
};
|
|
266
|
+
//depending on the options return only the required series
|
|
267
|
+
if (displayOptions.displayMarkedLine && displayOptions.displayMarkedPoint) {
|
|
268
|
+
return [seriesWithMarkLine, seriesWithMarkPoint];
|
|
269
|
+
}
|
|
270
|
+
else if (displayOptions.displayMarkedLine) {
|
|
271
|
+
return [seriesWithMarkLine];
|
|
272
|
+
}
|
|
273
|
+
else if (displayOptions.displayMarkedPoint) {
|
|
274
|
+
return [seriesWithMarkPoint];
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* This method is used to get tooltip formatter for alarms and events.
|
|
283
|
+
* @param tooltipParams - The tooltip parameters.
|
|
284
|
+
* @param params - The parameters data.
|
|
285
|
+
* @param allEvents - All events.
|
|
286
|
+
* @param allAlarms - All alarms.
|
|
287
|
+
* @returns The formatted string for the tooltip.
|
|
288
|
+
*/
|
|
289
|
+
getTooltipFormatterForAlarmAndEvents(tooltipParams, params, allEvents, allAlarms) {
|
|
290
|
+
if (!Array.isArray(tooltipParams)) {
|
|
291
|
+
return '';
|
|
292
|
+
}
|
|
293
|
+
const XAxisValue = tooltipParams[0].data[0];
|
|
294
|
+
const YAxisReadings = [];
|
|
295
|
+
const allSeries = this.echartsInstance?.getOption()['series'];
|
|
296
|
+
// filter out alarm and event series
|
|
297
|
+
const allDataPointSeries = allSeries.filter(series => series['typeOfSeries'] !== 'alarm' && series['typeOfSeries'] !== 'event');
|
|
298
|
+
this.processSeries(allDataPointSeries, XAxisValue, YAxisReadings);
|
|
299
|
+
// find event and alarm of the same type as the hovered markedLine or markedPoint
|
|
300
|
+
const event = allEvents.find(e => e.type === params.data.itemType);
|
|
301
|
+
const alarm = allAlarms.find(a => a.type === params.data.itemType);
|
|
302
|
+
let value = '';
|
|
303
|
+
if (event) {
|
|
304
|
+
value = this.processEvent(event);
|
|
305
|
+
}
|
|
306
|
+
if (alarm) {
|
|
307
|
+
this.processAlarm(alarm).then(alarmVal => {
|
|
308
|
+
value = alarmVal;
|
|
309
|
+
YAxisReadings.push(value);
|
|
310
|
+
const options = this.echartsInstance?.getOption();
|
|
311
|
+
if (!options.tooltip || !Array.isArray(options.tooltip)) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
const updatedOptions = {
|
|
315
|
+
tooltip: options['tooltip'][0]
|
|
316
|
+
};
|
|
317
|
+
if (!updatedOptions.tooltip) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
updatedOptions.tooltip.formatter = `<div style="width: ${this.TOOLTIP_WIDTH}px">${YAxisReadings.join('')}</div>`;
|
|
321
|
+
updatedOptions.tooltip.transitionDuration = 0;
|
|
322
|
+
updatedOptions.tooltip.position = this.tooltipPosition();
|
|
323
|
+
this.echartsInstance?.setOption(updatedOptions);
|
|
324
|
+
return;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
YAxisReadings.push(value);
|
|
328
|
+
return `<div style="width: 300px">${YAxisReadings.join('')}</div>`;
|
|
329
|
+
}
|
|
330
|
+
tooltipPosition() {
|
|
331
|
+
let lastPositionOfTooltip = {};
|
|
332
|
+
if (this.tooltipPositionCallback) {
|
|
333
|
+
return this.tooltipPositionCallback;
|
|
334
|
+
}
|
|
335
|
+
this.tooltipPositionCallback = (point, // position of mouse in chart [X, Y]; 0,0 is top left corner
|
|
336
|
+
_, // tooltip data
|
|
337
|
+
dom, // tooltip element
|
|
338
|
+
__, size // size of chart
|
|
339
|
+
) => {
|
|
340
|
+
const offset = 10;
|
|
341
|
+
const [mouseX, mouseY] = point;
|
|
342
|
+
const chartWidth = size?.viewSize[0] || 0;
|
|
343
|
+
const chartHeight = size?.viewSize[1] || 0;
|
|
344
|
+
const tooltipWidth = size?.contentSize[0] || 0;
|
|
345
|
+
const tooltipHeight = size?.contentSize[1] || 0;
|
|
346
|
+
const tooltipRect = dom?.getBoundingClientRect();
|
|
347
|
+
const tooltipOverflowsBottomEdge = tooltipRect.bottom > window.innerHeight;
|
|
348
|
+
const tooltipOverflowsRightEdge = tooltipRect.right > window.innerWidth;
|
|
349
|
+
const tooltipWouldOverflowBottomEdgeOnPositionChange = !lastPositionOfTooltip.top &&
|
|
350
|
+
tooltipRect.bottom + 2 * offset + tooltipHeight > window.innerHeight;
|
|
351
|
+
const tooltipWouldOverflowRightEdgeOnPositionChange = !lastPositionOfTooltip.left &&
|
|
352
|
+
tooltipRect.right + 2 * offset + tooltipWidth > window.innerWidth;
|
|
353
|
+
let verticalPosition = {
|
|
354
|
+
top: mouseY + offset
|
|
355
|
+
};
|
|
356
|
+
let horizontalPosition = {
|
|
357
|
+
left: mouseX + offset
|
|
358
|
+
};
|
|
359
|
+
if (tooltipOverflowsBottomEdge || tooltipWouldOverflowBottomEdgeOnPositionChange) {
|
|
360
|
+
verticalPosition = {
|
|
361
|
+
bottom: chartHeight - mouseY + offset
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
if (tooltipOverflowsRightEdge || tooltipWouldOverflowRightEdgeOnPositionChange) {
|
|
365
|
+
horizontalPosition = {
|
|
366
|
+
right: chartWidth - mouseX + offset
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
lastPositionOfTooltip = {
|
|
370
|
+
...verticalPosition,
|
|
371
|
+
...horizontalPosition
|
|
372
|
+
};
|
|
373
|
+
return lastPositionOfTooltip;
|
|
374
|
+
};
|
|
375
|
+
return this.tooltipPositionCallback;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* This method is used to add the data point info to the tooltip.
|
|
379
|
+
* @param allDataPointSeries - All the data point series.
|
|
380
|
+
* @param XAxisValue - The X Axis value.
|
|
381
|
+
* @param YAxisReadings - The Y Axis readings.
|
|
382
|
+
*/
|
|
383
|
+
processSeries(allDataPointSeries, XAxisValue, YAxisReadings) {
|
|
384
|
+
allDataPointSeries.forEach((series) => {
|
|
385
|
+
let value = '';
|
|
386
|
+
if (series.id.endsWith('/min')) {
|
|
387
|
+
value = this.processMinSeries(series, allDataPointSeries, XAxisValue);
|
|
388
|
+
}
|
|
389
|
+
else if (!series.id.endsWith('/max')) {
|
|
390
|
+
value = this.processRegularSeries(series, XAxisValue);
|
|
391
|
+
}
|
|
392
|
+
if (value) {
|
|
393
|
+
YAxisReadings.push(`<div class="d-flex a-i-center p-b-8"><span class='dlt-c8y-icon-circle m-r-4' style='color: ${series.itemStyle.color};'></span>` + // color circle
|
|
394
|
+
`<strong>${series.datapointLabel}</strong></div>` + // name
|
|
395
|
+
`${value}` // single value or min-max range
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* This method is used to process the min series.
|
|
402
|
+
* @param series - The series.
|
|
403
|
+
* @param allDataPointSeries - All the data point series.
|
|
404
|
+
* @param XAxisValue - The X Axis value.
|
|
405
|
+
* @returns The processed value.
|
|
406
|
+
*/
|
|
407
|
+
processMinSeries(series, allDataPointSeries, XAxisValue) {
|
|
408
|
+
const minValue = this.findValueForExactOrEarlierTimestamp(series.data, XAxisValue);
|
|
409
|
+
if (!minValue) {
|
|
410
|
+
return '';
|
|
411
|
+
}
|
|
412
|
+
const maxSeries = allDataPointSeries.find(s => s['id'] === series.id.replace('/min', '/max'));
|
|
413
|
+
const maxValue = this.findValueForExactOrEarlierTimestamp(maxSeries?.['data'], XAxisValue);
|
|
414
|
+
return (`<div class="d-flex a-i-center separator-top p-t-8 p-b-8"><label class="text-12 m-r-8 m-b-0">${this.datePipe.transform(minValue[0])}</label>` +
|
|
415
|
+
`<span class="m-l-auto text-12">${minValue[1]} — ${maxValue?.[1]}` +
|
|
416
|
+
(series.datapointUnit ? ` ${series.datapointUnit}` : '') +
|
|
417
|
+
`</span></div>`);
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* This method is used to process the regular series.
|
|
421
|
+
* @param series - The series.
|
|
422
|
+
* @param XAxisValue - The X Axis value.
|
|
423
|
+
* @returns The processed value.
|
|
424
|
+
*/
|
|
425
|
+
processRegularSeries(series, XAxisValue) {
|
|
426
|
+
const seriesValue = this.findValueForExactOrEarlierTimestamp(series.data, XAxisValue);
|
|
427
|
+
if (!seriesValue) {
|
|
428
|
+
return '';
|
|
429
|
+
}
|
|
430
|
+
return (`<div class="d-flex a-i-center p-t-8 p-b-8 separator-top">` +
|
|
431
|
+
`<label class="m-b-0 m-r-8 text-12">${this.datePipe.transform(seriesValue[0])}</label><span class="m-l-auto text-12">` +
|
|
432
|
+
seriesValue[1]?.toString() +
|
|
433
|
+
(series.datapointUnit ? ` ${series.datapointUnit}` : '') +
|
|
434
|
+
`</span></div>`);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* This method is used to process the event tooltip.
|
|
438
|
+
* @param event - The event object.
|
|
439
|
+
* @returns The processed value.
|
|
440
|
+
*/
|
|
441
|
+
processEvent(event) {
|
|
442
|
+
let value = `<ul class="list-unstyled small separator-top">`;
|
|
443
|
+
value += `<li class="p-t-4 p-b-4 d-flex separator-bottom text-no-wrap"><label class="small m-b-0 m-r-8">Event type</label><code class="m-l-auto">${event.type}</code></li>`;
|
|
444
|
+
value += `<li class="p-t-4 p-b-4 d-flex separator-bottom text-no-wrap"><label class="small m-b-0 m-r-8">Event text</label><span class="m-l-auto">${event.text}<span></li>`;
|
|
445
|
+
value += `<li class="p-t-4 p-b-4 d-flex separator-bottom text-no-wrap"><label class="small m-b-0 m-r-8">Last update</label><span class="m-l-auto">${this.datePipe.transform(event['lastUpdated'])}<span></li>`;
|
|
446
|
+
value += `</ul>`;
|
|
447
|
+
return value;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* This method is used to process the alarm tooltip.
|
|
451
|
+
* @param alarm - The alarm object.
|
|
452
|
+
* @returns The processed value.
|
|
453
|
+
*/
|
|
454
|
+
async processAlarm(alarm) {
|
|
455
|
+
let value = `<ul class="list-unstyled small separator-top m-0">`;
|
|
456
|
+
value += `<li class="p-t-4 p-b-4 d-flex a-i-center separator-bottom text-no-wrap"><label class="text-label-small m-b-0 m-r-8">Alarm Severity</label>`;
|
|
457
|
+
value += `<span class="small d-inline-flex a-i-center gap-4 m-l-auto"><i class="stroked-icon icon-14 status dlt-c8y-icon-${this.severityIconPipe.transform(alarm.severity)} ${alarm.severity.toLowerCase()}" > </i> ${this.severityLabelPipe.transform(alarm.severity)} </span></li>`;
|
|
458
|
+
value += `<li class="p-t-4 p-b-4 d-flex separator-bottom text-no-wrap"><label class="text-label-small m-b-0 m-r-8">Alarm Type</label><span class="small m-l-auto"><code>${alarm.type}</code></span></li>`;
|
|
459
|
+
value += `<li class="p-t-4 p-b-4 d-flex separator-bottom text-no-wrap"><label class="text-label-small m-b-0 m-r-8">Message</label><span class="small m-l-auto" style="overflow: hidden; text-overflow: ellipsis;" title="${alarm.text}">${alarm.text}</span></li>`;
|
|
460
|
+
value += `<li class="p-t-4 p-b-4 d-flex separator-bottom text-no-wrap"><label class="text-label-small m-b-0 m-r-8">Last Updated</label><span class="small m-l-auto">${this.datePipe.transform(alarm['lastUpdated'])}</span></li>`;
|
|
461
|
+
const exists = await this.alarmRouteExists();
|
|
462
|
+
if (exists) {
|
|
463
|
+
const currentUrl = window.location.href;
|
|
464
|
+
const baseUrlIndex = currentUrl.indexOf(INDEX_HTML);
|
|
465
|
+
const baseUrl = currentUrl.substring(0, baseUrlIndex + INDEX_HTML.length);
|
|
466
|
+
value += `<li class="p-t-4 p-b-4 d-flex separator-bottom text-no-wrap"><label class="text-label-small m-b-0 m-r-8">Link</label><span class="small m-l-auto"><a href="${baseUrl}#/alarms/${alarm.id}">Alarm Details</a></span></li>`;
|
|
467
|
+
}
|
|
468
|
+
value += `<li class="p-t-4 p-b-4 d-flex text-no-wrap"><label class="text-label-small m-b-0 m-r-8">Alarm count</label><span class="small m-l-auto"><span class="badge badge-info">${alarm.count}</span></span></li>`;
|
|
469
|
+
value += `</ul>`;
|
|
470
|
+
return value;
|
|
471
|
+
}
|
|
472
|
+
async alarmRouteExists() {
|
|
473
|
+
const exists = this.router.config.some(route => {
|
|
474
|
+
return `${route.path}` === 'alarms';
|
|
475
|
+
});
|
|
476
|
+
return exists;
|
|
477
|
+
}
|
|
478
|
+
getChartSeries(datapointsWithValues, events, alarms, displayOptions) {
|
|
479
|
+
const series = [];
|
|
480
|
+
let eventSeries = [];
|
|
481
|
+
let alarmSeries = [];
|
|
482
|
+
datapointsWithValues.forEach((dp, idx) => {
|
|
483
|
+
const renderType = dp.renderType || 'min';
|
|
484
|
+
if (renderType === 'area') {
|
|
485
|
+
series.push(this.getSingleSeries(dp, 'min', idx, true));
|
|
486
|
+
series.push(this.getSingleSeries(dp, 'max', idx, true));
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
series.push(this.getSingleSeries(dp, renderType, idx, false));
|
|
490
|
+
}
|
|
491
|
+
const newEventSeries = this.getAlarmOrEventSeries(dp, renderType, false, events, 'event', displayOptions, null, idx);
|
|
492
|
+
const newAlarmSeries = this.getAlarmOrEventSeries(dp, renderType, false, alarms, 'alarm', displayOptions, null, idx);
|
|
493
|
+
eventSeries = [...eventSeries, ...newEventSeries];
|
|
494
|
+
alarmSeries = [...alarmSeries, ...newAlarmSeries];
|
|
495
|
+
});
|
|
496
|
+
const deduplicateFilterCallback = (obj1, i, arr) => {
|
|
497
|
+
const duplicates = arr.filter(obj2 => obj1['id'] === obj2['id'] && i !== arr.indexOf(obj2));
|
|
498
|
+
if (duplicates.length > 0) {
|
|
499
|
+
return obj1['isDpTemplateSelected'];
|
|
500
|
+
}
|
|
501
|
+
return true;
|
|
502
|
+
};
|
|
503
|
+
const deduplicateFilterCallbackFallback = (obj1, i, arr) => arr.findIndex(obj2 => obj2['id'] === obj1['id']) === i;
|
|
504
|
+
let deduplicatedEvents = eventSeries.filter(deduplicateFilterCallback);
|
|
505
|
+
let deduplicatedAlarms = alarmSeries.filter(deduplicateFilterCallback);
|
|
506
|
+
if (deduplicatedAlarms.length === 0) {
|
|
507
|
+
deduplicatedAlarms = alarmSeries.filter(deduplicateFilterCallbackFallback);
|
|
508
|
+
}
|
|
509
|
+
if (deduplicatedEvents.length === 0) {
|
|
510
|
+
deduplicatedEvents = eventSeries.filter(deduplicateFilterCallbackFallback);
|
|
511
|
+
}
|
|
512
|
+
return [...series, ...deduplicatedEvents, ...deduplicatedAlarms];
|
|
513
|
+
}
|
|
514
|
+
groupByType(items, typeField) {
|
|
515
|
+
return items.reduce((grouped, item) => {
|
|
516
|
+
(grouped[item[typeField]] = grouped[item[typeField]] || []).push(item);
|
|
517
|
+
return grouped;
|
|
518
|
+
}, {});
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* This method interpolates between two data points. The goal is to place the markPoint on the chart in the right place.
|
|
522
|
+
* @param dpValuesArray array of data points
|
|
523
|
+
* @param targetTime time of the alarm or event
|
|
524
|
+
* @returns interpolated data point
|
|
525
|
+
*/
|
|
526
|
+
interpolateBetweenTwoDps(dpValuesArray, targetTime) {
|
|
527
|
+
let maxValue;
|
|
528
|
+
let minValue;
|
|
529
|
+
return dpValuesArray.reduce((acc, curr, idx, arr) => {
|
|
530
|
+
if (new Date(curr.time).getTime() <= targetTime) {
|
|
531
|
+
if (idx === arr.length - 1) {
|
|
532
|
+
return {
|
|
533
|
+
time: targetTime,
|
|
534
|
+
values: [{ min: minValue, max: maxValue }]
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
const nextDp = arr[idx + 1];
|
|
538
|
+
if (new Date(nextDp.time).getTime() >= targetTime) {
|
|
539
|
+
const timeDiff = new Date(nextDp.time).getTime() - new Date(curr.time).getTime();
|
|
540
|
+
const targetTimeDiff = targetTime - new Date(curr.time).getTime();
|
|
541
|
+
const minValueDiff = nextDp.values[0]?.min - curr.values[0]?.min;
|
|
542
|
+
const maxValueDiff = nextDp.values[0]?.max - curr.values[0]?.max;
|
|
543
|
+
minValue = curr.values[0]?.min + (minValueDiff * targetTimeDiff) / timeDiff;
|
|
544
|
+
maxValue = curr.values[0]?.max + (maxValueDiff * targetTimeDiff) / timeDiff;
|
|
545
|
+
return {
|
|
546
|
+
time: targetTime,
|
|
547
|
+
values: [{ min: minValue, max: maxValue }]
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return acc;
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
getClosestDpValueToTargetTime(dpValuesArray, targetTime) {
|
|
555
|
+
return dpValuesArray.reduce((prev, curr) =>
|
|
556
|
+
//should take the value closest to the target time, for realtime the current time would always change
|
|
557
|
+
Math.abs(new Date(curr.time).getTime() - targetTime) <
|
|
558
|
+
Math.abs(new Date(prev.time).getTime() - targetTime)
|
|
559
|
+
? curr
|
|
560
|
+
: prev);
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* This method creates a markPoint on the chart which represents the icon of the alarm or event.
|
|
564
|
+
* @param item Single alarm or event
|
|
565
|
+
* @param dp Data point
|
|
566
|
+
* @param isCleared If the alarm is cleared in case of alarm
|
|
567
|
+
* @param isEvent If the item is an event
|
|
568
|
+
* @param realtime If the chart is in realtime mode
|
|
569
|
+
* @returns MarkPointDataItemOption[]
|
|
570
|
+
*/
|
|
571
|
+
createMarkPoint(item, dp, isCleared, isEvent, realtime) {
|
|
572
|
+
// check if dp.values object is empty
|
|
573
|
+
if (!item.creationTime || Object.keys(dp.values).length === 0) {
|
|
574
|
+
return [];
|
|
575
|
+
}
|
|
576
|
+
const dpValuesArray = Object.entries(dp.values).map(([time, values]) => ({
|
|
577
|
+
time: new Date(time).getTime(),
|
|
578
|
+
values
|
|
579
|
+
}));
|
|
580
|
+
const creationTime = new Date(item.creationTime).getTime();
|
|
581
|
+
const lastUpdatedTime = new Date(item['lastUpdated']).getTime();
|
|
582
|
+
let coordCreationTime;
|
|
583
|
+
let coordLastUpdatedTime;
|
|
584
|
+
if (realtime) {
|
|
585
|
+
const lastValue = dpValuesArray[dpValuesArray.length - 1];
|
|
586
|
+
coordCreationTime = [
|
|
587
|
+
item.creationTime,
|
|
588
|
+
lastValue?.values[0]?.min ?? lastValue?.values[1] ?? null
|
|
589
|
+
];
|
|
590
|
+
coordLastUpdatedTime = [
|
|
591
|
+
item['lastUpdated'],
|
|
592
|
+
lastValue?.values[0]?.min ?? lastValue?.values[1] ?? null
|
|
593
|
+
];
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
const closestDpValue = this.interpolateBetweenTwoDps(dpValuesArray, creationTime);
|
|
597
|
+
const dpValuesForNewAlarms = this.getClosestDpValueToTargetTime(dpValuesArray, creationTime);
|
|
598
|
+
const closestDpValueLastUpdated = this.interpolateBetweenTwoDps(dpValuesArray, lastUpdatedTime);
|
|
599
|
+
const dpValuesForNewAlarmsLastUpdated = this.getClosestDpValueToTargetTime(dpValuesArray, lastUpdatedTime);
|
|
600
|
+
coordCreationTime = [
|
|
601
|
+
item.creationTime,
|
|
602
|
+
closestDpValue?.values[0]?.min ??
|
|
603
|
+
closestDpValue?.values[1] ??
|
|
604
|
+
dpValuesForNewAlarms?.values[0]?.min ??
|
|
605
|
+
dpValuesForNewAlarms?.values[1] ??
|
|
606
|
+
null
|
|
607
|
+
];
|
|
608
|
+
coordLastUpdatedTime = [
|
|
609
|
+
item['lastUpdated'],
|
|
610
|
+
closestDpValueLastUpdated?.values[0]?.min ??
|
|
611
|
+
closestDpValueLastUpdated?.values[1] ??
|
|
612
|
+
dpValuesForNewAlarmsLastUpdated?.values[0]?.min ??
|
|
613
|
+
dpValuesForNewAlarmsLastUpdated?.values[1] ??
|
|
614
|
+
null
|
|
615
|
+
];
|
|
616
|
+
}
|
|
617
|
+
if (isEvent) {
|
|
618
|
+
return [
|
|
619
|
+
{
|
|
620
|
+
coord: coordCreationTime,
|
|
621
|
+
name: item.type,
|
|
622
|
+
itemType: item.type,
|
|
623
|
+
itemStyle: {
|
|
624
|
+
color: item['color']
|
|
625
|
+
},
|
|
626
|
+
symbol: 'circle',
|
|
627
|
+
symbolSize: 24
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
coord: coordCreationTime,
|
|
631
|
+
name: item.type,
|
|
632
|
+
itemType: item.type,
|
|
633
|
+
itemStyle: { color: 'white' },
|
|
634
|
+
symbol: ICONS_MAP.EVENT,
|
|
635
|
+
symbolSize: 16
|
|
636
|
+
}
|
|
637
|
+
];
|
|
638
|
+
}
|
|
639
|
+
return isCleared
|
|
640
|
+
? [
|
|
641
|
+
{
|
|
642
|
+
coord: coordCreationTime,
|
|
643
|
+
name: item.type,
|
|
644
|
+
itemType: item.type,
|
|
645
|
+
itemStyle: {
|
|
646
|
+
color: item['color']
|
|
647
|
+
},
|
|
648
|
+
symbol: 'circle',
|
|
649
|
+
symbolSize: 24
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
coord: coordCreationTime,
|
|
653
|
+
name: item.type,
|
|
654
|
+
itemType: item.type,
|
|
655
|
+
itemStyle: { color: 'white' },
|
|
656
|
+
symbol: ICONS_MAP[item.severity],
|
|
657
|
+
symbolSize: 16
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
coord: coordLastUpdatedTime,
|
|
661
|
+
name: item.type,
|
|
662
|
+
itemType: item.type,
|
|
663
|
+
itemStyle: {
|
|
664
|
+
color: item['color']
|
|
665
|
+
},
|
|
666
|
+
symbol: 'circle',
|
|
667
|
+
symbolSize: 24
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
coord: coordLastUpdatedTime,
|
|
671
|
+
name: item.type,
|
|
672
|
+
itemType: item.type,
|
|
673
|
+
itemStyle: { color: 'white' },
|
|
674
|
+
symbol: ICONS_MAP.CLEARED,
|
|
675
|
+
symbolSize: 16
|
|
676
|
+
}
|
|
677
|
+
]
|
|
678
|
+
: [
|
|
679
|
+
{
|
|
680
|
+
coord: coordCreationTime,
|
|
681
|
+
name: item.type,
|
|
682
|
+
itemType: item.type,
|
|
683
|
+
itemStyle: {
|
|
684
|
+
color: item['color']
|
|
685
|
+
},
|
|
686
|
+
symbol: 'circle',
|
|
687
|
+
symbolSize: 24
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
coord: coordCreationTime,
|
|
691
|
+
name: item.type,
|
|
692
|
+
itemType: item.type,
|
|
693
|
+
itemStyle: { color: 'white' },
|
|
694
|
+
symbol: ICONS_MAP[item.severity],
|
|
695
|
+
symbolSize: 16
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
coord: coordLastUpdatedTime,
|
|
699
|
+
name: item.type,
|
|
700
|
+
itemType: item.type,
|
|
701
|
+
itemStyle: {
|
|
702
|
+
color: item['color']
|
|
703
|
+
},
|
|
704
|
+
symbol: 'circle',
|
|
705
|
+
symbolSize: 24
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
coord: coordLastUpdatedTime,
|
|
709
|
+
name: item.type,
|
|
710
|
+
itemType: item.type,
|
|
711
|
+
itemStyle: { color: 'white' },
|
|
712
|
+
symbol: ICONS_MAP[item.severity],
|
|
713
|
+
symbolSize: 16
|
|
714
|
+
}
|
|
715
|
+
];
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* This method creates a markLine on the chart which represents the line between every alarm or event on the chart.
|
|
719
|
+
* @param items Array of alarms or events
|
|
720
|
+
* @returns MarkLineDataItemOptionBase[]
|
|
721
|
+
*/
|
|
722
|
+
createMarkLine(items) {
|
|
723
|
+
return items.reduce((acc, item) => {
|
|
724
|
+
if (!item.creationTime) {
|
|
725
|
+
return acc;
|
|
726
|
+
}
|
|
727
|
+
if (item.creationTime === item['lastUpdated']) {
|
|
728
|
+
return acc.concat([
|
|
729
|
+
{
|
|
730
|
+
xAxis: item.creationTime,
|
|
731
|
+
itemType: item.type,
|
|
732
|
+
label: { show: false, formatter: () => item.type },
|
|
733
|
+
itemStyle: { color: item['color'] }
|
|
734
|
+
}
|
|
735
|
+
]);
|
|
736
|
+
}
|
|
737
|
+
else {
|
|
738
|
+
return acc.concat([
|
|
739
|
+
{
|
|
740
|
+
xAxis: item.creationTime,
|
|
741
|
+
itemType: item.type,
|
|
742
|
+
label: { show: false, formatter: () => item.type },
|
|
743
|
+
itemStyle: { color: item['color'] }
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
xAxis: item['lastUpdated'],
|
|
747
|
+
itemType: item.type,
|
|
748
|
+
label: { show: false, formatter: () => item.type },
|
|
749
|
+
itemStyle: { color: item['color'] }
|
|
750
|
+
}
|
|
751
|
+
]);
|
|
752
|
+
}
|
|
753
|
+
}, []);
|
|
754
|
+
}
|
|
755
|
+
getSingleSeries(dp, renderType, idx, isMinMaxChart = false, seriesType = '') {
|
|
756
|
+
const datapointId = dp.__target?.id + dp.fragment + dp.series;
|
|
757
|
+
return {
|
|
758
|
+
datapointId,
|
|
759
|
+
datapointUnit: dp.unit || '',
|
|
760
|
+
// 'id' property is needed as 'seriesId' in tooltip formatter
|
|
761
|
+
id: isMinMaxChart
|
|
762
|
+
? `${datapointId}/${renderType}${seriesType}`
|
|
763
|
+
: `${datapointId}${seriesType}`,
|
|
764
|
+
name: `${dp.label} (${dp.__target?.['name']})`,
|
|
765
|
+
// datapointLabel used to proper display of tooltip
|
|
766
|
+
datapointLabel: dp.label || '',
|
|
767
|
+
data: Object.entries(dp.values).map(([dateString, values]) => {
|
|
768
|
+
return [dateString, values[0][renderType]];
|
|
769
|
+
}),
|
|
770
|
+
yAxisIndex: idx,
|
|
771
|
+
...this.chartTypesService.getSeriesOptions(dp, isMinMaxChart, renderType)
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* This method creates a general tooltip formatter for the chart.
|
|
776
|
+
* @returns TooltipFormatterCallback<TopLevelFormatterParams>
|
|
777
|
+
*/
|
|
778
|
+
getTooltipFormatter() {
|
|
779
|
+
return params => {
|
|
780
|
+
if (!Array.isArray(params) || !params[0]?.data) {
|
|
781
|
+
return '';
|
|
782
|
+
}
|
|
783
|
+
const data = params[0].data;
|
|
784
|
+
const XAxisValue = data[0];
|
|
785
|
+
const YAxisReadings = [];
|
|
786
|
+
const allSeries = this.echartsInstance?.getOption()['series'];
|
|
787
|
+
const allDataPointSeries = allSeries.filter(series => series['typeOfSeries'] !== 'alarm' &&
|
|
788
|
+
series['typeOfSeries'] !== 'event' &&
|
|
789
|
+
series['typeOfSeries'] !== 'fake');
|
|
790
|
+
allDataPointSeries.forEach((series) => {
|
|
791
|
+
let value;
|
|
792
|
+
const id = series['id'];
|
|
793
|
+
if (id.endsWith('/min')) {
|
|
794
|
+
const minValue = this.findValueForExactOrEarlierTimestamp(series['data'], XAxisValue);
|
|
795
|
+
if (!minValue) {
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
const maxSeries = allDataPointSeries.find(s => s['id'] === id.replace('/min', '/max'));
|
|
799
|
+
if (!maxSeries) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
const maxValue = this.findValueForExactOrEarlierTimestamp(maxSeries['data'], XAxisValue);
|
|
803
|
+
if (maxValue === null) {
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
value =
|
|
807
|
+
`<div class="d-flex a-i-center separator-top p-t-8 p-b-8">` +
|
|
808
|
+
`<label class="text-12 m-r-8 m-b-0">${this.datePipe.transform(minValue[0])}</label>` +
|
|
809
|
+
`<div class="m-l-auto text-12" >${minValue[1]} — ${maxValue[1]}` +
|
|
810
|
+
(series['datapointUnit'] ? ` ${series['datapointUnit']}` : '') +
|
|
811
|
+
`</div></div>`;
|
|
812
|
+
}
|
|
813
|
+
else if (id.endsWith('/max')) {
|
|
814
|
+
// do nothing, value is handled in 'min' case
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
else {
|
|
818
|
+
const seriesValue = this.findValueForExactOrEarlierTimestamp(series['data'], XAxisValue);
|
|
819
|
+
if (!seriesValue) {
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
value =
|
|
823
|
+
`<div class="d-flex a-i-center separator-top p-t-8 p-b-8">` +
|
|
824
|
+
`<label class="text-12 m-r-8 m-b-0">${this.datePipe.transform(seriesValue[0])}</label>` +
|
|
825
|
+
`<div class="m-l-auto text-12" >${seriesValue[1]?.toString()}` +
|
|
826
|
+
(series['datapointUnit'] ? ` ${series['datapointUnit']}` : '') +
|
|
827
|
+
`</div></div>`;
|
|
828
|
+
}
|
|
829
|
+
const itemStyle = series['itemStyle'];
|
|
830
|
+
YAxisReadings.push(`<div class="d-flex a-i-center p-b-8"><span class='dlt-c8y-icon-circle m-r-4' style='color: ${itemStyle.color}'></span>` + // color circle
|
|
831
|
+
`<strong>${series['datapointLabel']} </strong></div>` + // name
|
|
832
|
+
`${value}` // single value or min-max range
|
|
833
|
+
);
|
|
834
|
+
});
|
|
835
|
+
return `<div style="width: ${this.TOOLTIP_WIDTH}px">${YAxisReadings.join('')}</div>`;
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
findValueForExactOrEarlierTimestamp(values, timestampString) {
|
|
839
|
+
const timestamp = new Date(timestampString).valueOf();
|
|
840
|
+
return values.reduce((acc, curr) => {
|
|
841
|
+
if (new Date(curr[0]).valueOf() <= timestamp) {
|
|
842
|
+
if (acc === null ||
|
|
843
|
+
Math.abs(new Date(curr[0]).valueOf() - timestamp) <
|
|
844
|
+
Math.abs(new Date(acc[0]).valueOf() - timestamp)) {
|
|
845
|
+
return curr;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return acc;
|
|
849
|
+
}, null);
|
|
850
|
+
}
|
|
851
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: EchartsOptionsService, deps: [{ token: i1.DatePipe }, { token: i2.YAxisService }, { token: i3.ChartTypesService }, { token: i4.AlarmSeverityToIconPipe }, { token: i4.AlarmSeverityToLabelPipe }, { token: i5.Router }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
852
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: EchartsOptionsService }); }
|
|
853
|
+
}
|
|
854
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: EchartsOptionsService, decorators: [{
|
|
855
|
+
type: Injectable
|
|
856
|
+
}], ctorParameters: () => [{ type: i1.DatePipe }, { type: i2.YAxisService }, { type: i3.ChartTypesService }, { type: i4.AlarmSeverityToIconPipe }, { type: i4.AlarmSeverityToLabelPipe }, { type: i5.Router }] });
|
|
857
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNoYXJ0cy1vcHRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9lY2hhcnQvc2VydmljZXMvZWNoYXJ0cy1vcHRpb25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBYS9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUcxRCxPQUFPLEVBQUUsV0FBVyxFQUFnQyxNQUFNLGFBQWEsQ0FBQztBQUN4RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFdEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9GLE9BQU8sRUFBWSxTQUFTLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7Ozs7OztBQWExRSxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUM7QUFHakMsTUFBTSxPQUFPLHFCQUFxQjtJQUtoQyxZQUNVLFFBQWtCLEVBQ2xCLFlBQTBCLEVBQzFCLGlCQUFvQyxFQUNwQyxnQkFBeUMsRUFDekMsaUJBQTJDLEVBQzNDLE1BQWM7UUFMZCxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUF5QjtRQUN6QyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQTBCO1FBQzNDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFUaEIsa0JBQWEsR0FBRyxH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akMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERhdGVQaXBlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgdHlwZSB7IEVDaGFydHNPcHRpb24sIFNlcmllc09wdGlvbiB9IGZyb20gJ2VjaGFydHMnO1xuaW1wb3J0IHsgRUNoYXJ0cyB9IGZyb20gJ2VjaGFydHMnO1xuaW1wb3J0IHtcbiAgRGF0YXBvaW50Q2hhcnRSZW5kZXJUeXBlLFxuICBEcFdpdGhWYWx1ZXMsXG4gIERhdGVTdHJpbmcsXG4gIERwVmFsdWVzSXRlbSxcbiAgTWFya0xpbmVEYXRhLFxuICBNYXJrUG9pbnREYXRhLFxuICBTZXJpZXNEYXRhcG9pbnRJbmZvLFxuICBTZXJpZXNWYWx1ZVxufSBmcm9tICcuLi9tb2RlbHMnO1xuaW1wb3J0IHsgWUF4aXNTZXJ2aWNlIH0gZnJvbSAnLi95LWF4aXMuc2VydmljZSc7XG5pbXBvcnQgeyBDaGFydFR5cGVzU2VydmljZSB9IGZyb20gJy4vY2hhcnQtdHlwZXMuc2VydmljZSc7XG5pbXBvcnQgdHlwZSB7IENhbGxiYWNrRGF0YVBhcmFtcywgVG9vbHRpcEZvcm1hdHRlckNhbGxiYWNrIH0gZnJvbSAnZWNoYXJ0cy90eXBlcy9zcmMvdXRpbC90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IFRvcExldmVsRm9ybWF0dGVyUGFyYW1zIH0gZnJvbSAnZWNoYXJ0cy90eXBlcy9zcmMvY29tcG9uZW50L3Rvb2x0aXAvVG9vbHRpcE1vZGVsJztcbmltcG9ydCB7IEFsYXJtU3RhdHVzLCBJQWxhcm0sIElFdmVudCwgU2V2ZXJpdHlUeXBlIH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgSUNPTlNfTUFQIH0gZnJvbSAnLi4vbW9kZWxzL3N2Zy1pY29ucy5tb2RlbCc7XG5pbXBvcnQgeyBDdXN0b21TZXJpZXNPcHRpb25zIH0gZnJvbSAnLi4vbW9kZWxzL2NoYXJ0Lm1vZGVsJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBBbGFybVNldmVyaXR5VG9JY29uUGlwZSwgQWxhcm1TZXZlcml0eVRvTGFiZWxQaXBlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9hbGFybXMnO1xuaW1wb3J0IHsgSW50ZXJ2YWwsIElOVEVSVkFMUyB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvaW50ZXJ2YWwtcGlja2VyJztcblxudHlwZSBUb29sdGlwUG9zaXRpb25DYWxsYmFjayA9IChcbiAgcG9pbnQ6IFtudW1iZXIsIG51bWJlcl0sIC8vIHBvc2l0aW9uIG9mIG1vdXNlIGluIGNoYXJ0IFtYLCBZXTsgMCwwIGlzIHRvcCBsZWZ0IGNvcm5lclxuICBfOiBhbnksIC8vIHRvb2x0aXAgZGF0YVxuICBkb206IEhUTUxFbGVtZW50IHwgdW5rbm93biwgLy8gdG9vbHRpcCBlbGVtZW50XG4gIF9fOiBhbnksIC8vIHZhbGlkIG9ubHkgd2hlbiBtb3VzZSBpcyBvbiBncmFwaGljIGVsZW1lbnRzOyBub3QgcmVsZXZhbnQgaW4gb3VyIGNhc2VcbiAgc2l6ZToge1xuICAgIGNvbnRlbnRTaXplOiBbbnVtYmVyLCBudW1iZXJdOyAvLyBzaXplIG9mIHRvb2x0aXBcbiAgICB2aWV3U2l6ZTogW251bWJlciwgbnVtYmVyXTsgLy8gc2l6ZSBvZiB0aGUgY2hhcnRcbiAgfSB8IG51bGwgLy8gc2l6ZSBvZiBjaGFydFxuKSA9PiBQYXJ0aWFsPFJlY29yZDwndG9wJyB8ICdib3R0b20nIHwgJ2xlZnQnIHwgJ3JpZ2h0JywgbnVtYmVyPj47XG5cbmNvbnN0IElOREVYX0hUTUwgPSAnL2luZGV4Lmh0bWwnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRWNoYXJ0c09wdGlvbnNTZXJ2aWNlIHtcbiAgZWNoYXJ0c0luc3RhbmNlOiBFQ2hhcnRzIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIFRPT0xUSVBfV0lEVEggPSAzMDA7XG4gIHByaXZhdGUgdG9vbHRpcFBvc2l0aW9uQ2FsbGJhY2s6IFRvb2x0aXBQb3NpdGlvbkNhbGxiYWNrIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZGF0ZVBpcGU6IERhdGVQaXBlLFxuICAgIHByaXZhdGUgeUF4aXNTZXJ2aWNlOiBZQXhpc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjaGFydFR5cGVzU2VydmljZTogQ2hhcnRUeXBlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBzZXZlcml0eUljb25QaXBlOiBBbGFybVNldmVyaXR5VG9JY29uUGlwZSxcbiAgICBwcml2YXRlIHNldmVyaXR5TGFiZWxQaXBlOiBBbGFybVNldmVyaXR5VG9MYWJlbFBpcGUsXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlclxuICApIHt9XG5cbiAgZ2V0Q2hhcnRPcHRpb25zKFxuICAgIGRhdGFwb2ludHNXaXRoVmFsdWVzOiBEcFdpdGhWYWx1ZXNbXSxcbiAgICB0aW1lUmFuZ2U6IHsgZGF0ZUZyb206IHN0cmluZzsgZGF0ZVRvOiBzdHJpbmc7IGludGVydmFsOiBJbnRlcnZhbFsnaWQnXSB9LFxuICAgIHNob3dTcGxpdExpbmVzOiB7IFlBeGlzOiBib29sZWFuOyBYQXhpczogYm9vbGVhbiB9LFxuICAgIGV2ZW50czogSUV2ZW50W10sXG4gICAgYWxhcm1zOiBJQWxhcm1bXSxcbiAgICBkaXNwbGF5T3B0aW9uczoge1xuICAgICAgZGlzcGxheU1hcmtlZExpbmU6IGJvb2xlYW47XG4gICAgICBkaXNwbGF5TWFya2VkUG9pbnQ6IGJvb2xlYW47XG4gICAgICBtZXJnZU1hdGNoaW5nRGF0YXBvaW50czogYm9vbGVhbjtcbiAgICAgIHNob3dMYWJlbEFuZFVuaXQ6IGJvb2xlYW47XG4gICAgICBzaG93U2xpZGVyOiBib29sZWFuO1xuICAgIH0sXG4gICAgc2VsZWN0ZWRUaW1lUmFuZ2U/OiB7IGRhdGVGcm9tOiBzdHJpbmc7IGRhdGVUbzogc3RyaW5nOyBpbnRlcnZhbDogSW50ZXJ2YWxbJ2lkJ10gfSB8IG51bGwsXG4gICAgYWdncmVnYXRlZERhdGFwb2ludHM/OiBEcFdpdGhWYWx1ZXNbXSxcbiAgICBzbGlkZXJab29tVXNlZCA9IGZhbHNlXG4gICk6IEVDaGFydHNPcHRpb24ge1xuICAgIGNvbnN0IHlBeGlzID0gdGhpcy55QXhpc1NlcnZpY2UuZ2V0WUF4aXMoZGF0YXBvaW50c1dpdGhWYWx1ZXMsIHtcbiAgICAgIHNob3dTcGxpdExpbmVzOiBzaG93U3BsaXRMaW5lcy5ZQXhpcyxcbiAgICAgIG1lcmdlTWF0Y2hpbmdEYXRhcG9pbnRzOiBkaXNwbGF5T3B0aW9ucy5tZXJnZU1hdGNoaW5nRGF0YXBvaW50cyxcbiAgICAgIHNob3dMYWJlbEFuZFVuaXQ6IGRpc3BsYXlPcHRpb25zLnNob3dMYWJlbEFuZFVuaXRcbiAgICB9KTtcbiAgICBjb25zdCBsZWZ0QXhpcyA9IHlBeGlzLmZpbHRlcih5eCA9PiB5eC5wb3NpdGlvbiA9PT0gJ2xlZnQnKTtcbiAgICBjb25zdCBncmlkTGVmdCA9IGxlZnRBeGlzLmxlbmd0aCA/IGxlZnRBeGlzLmxlbmd0aCAqIHRoaXMueUF4aXNTZXJ2aWNlLllfQVhJU19PRkZTRVQgOiAxNjtcbiAgICBjb25zdCByaWdodEF4aXMgPSB5QXhpcy5maWx0ZXIoeXggPT4geXgucG9zaXRpb24gPT09ICdyaWdodCcpO1xuICAgIGNvbnN0IGdyaWRSaWdodCA9IHJpZ2h0QXhpcy5sZW5ndGggPyByaWdodEF4aXMubGVuZ3RoICogdGhpcy55QXhpc1NlcnZpY2UuWV9BWElTX09GRlNFVCA6IDE2O1xuICAgIGxldCBpbnRlcnZhbEluTXMgPSB0aGlzLmNhbGN1bGF0ZUV4dGVuZGVkSW50ZXJ2YWxJbk1zKFxuICAgICAgc2VsZWN0ZWRUaW1lUmFuZ2U/LmludGVydmFsIHx8IHRpbWVSYW5nZS5pbnRlcnZhbCB8fCAnaG91cnMnLFxuICAgICAgc2VsZWN0ZWRUaW1lUmFuZ2UgfHwgdGltZVJhbmdlXG4gICAgKTtcbiAgICBpZiAoc2xpZGVyWm9vbVVzZWQpIHtcbiAgICAgIGludGVydmFsSW5NcyA9IHRoaXMuY2FsY3VsYXRlRXh0ZW5kZWRJbnRlcnZhbEluTXModGltZVJhbmdlLmludGVydmFsIHx8ICdob3VycycsIHRpbWVSYW5nZSk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBncmlkOiB7XG4gICAgICAgIGNvbnRhaW5MYWJlbDogZmFsc2UsIC8vIGF4aXMgbGFiZWxzIGFyZSBub3QgdGFrZW4gaW50byBhY2NvdW50IHRvIGNhbGN1bGF0ZSBncmFwaCBncmlkXG4gICAgICAgIGxlZnQ6IGdyaWRMZWZ0LFxuICAgICAgICB0b3A6IDE2LFxuICAgICAgICByaWdodDogZ3JpZFJpZ2h0LFxuICAgICAgICBib3R0b206IDY4XG4gICAgICB9LFxuICAgICAgZGF0YVpvb206IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdpbnNpZGUnLFxuICAgICAgICAgIC8vIFRPRE86IHVzZSAnbm9uZScgb25seSB3aGVuIHRoaXMgYnVnIGlzIGZpeGVkIGh0dHBzOi8vZ2l0aHViLmNvbS9hcGFjaGUvZWNoYXJ0cy9pc3N1ZXMvMTc4NThcbiAgICAgICAgICBmaWx0ZXJNb2RlOiBkYXRhcG9pbnRzV2l0aFZhbHVlcy5zb21lKGRwID0+IGRwLmxpbmVUeXBlID09PSAnYmFycycpID8gJ2ZpbHRlcicgOiAnbm9uZScsXG4gICAgICAgICAgem9vbU9uTW91c2VXaGVlbDogdHJ1ZSxcbiAgICAgICAgICBzdGFydFZhbHVlOiBzZWxlY3RlZFRpbWVSYW5nZVxuICAgICAgICAgICAgPyBzZWxlY3RlZFRpbWVSYW5nZS5kYXRlRnJvbS52YWx1ZU9mKClcbiAgICAgICAgICAgIDogdGltZVJhbmdlLmRhdGVGcm9tLnZhbHVlT2YoKSxcbiAgICAgICAgICBlbmRWYWx1ZTogc2VsZWN0ZWRUaW1lUmFuZ2VcbiAgICAgICAgICAgID8gc2VsZWN0ZWRUaW1lUmFuZ2UuZGF0ZVRvLnZhbHVlT2YoKVxuICAgICAgICAgICAgOiB0aW1lUmFuZ2UuZGF0ZVRvLnZhbHVlT2YoKVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ3NsaWRlcicsXG4gICAgICAgICAgc2hvdzogZGlzcGxheU9wdGlvbnMuc2hvd1NsaWRlcixcbiAgICAgICAgICBib3R0b206IDgsXG4gICAgICAgICAgcmVhbHRpbWU6IGZhbHNlXG4gICAgICAgIH1cbiAgICAgIF0sIC8vIG9uIHJlYWx0aW1lLCAnbm9uZScgd2lsbCBjYXVzZSBleHRlbmRpbmcgY2hhcnQgbGluZSB0byBsZWZ0IGVkZ2Ugb2YgdGhlIGNoYXJ0XG4gICAgICBhbmltYXRpb246IGZhbHNlLFxuICAgICAgdG9vbGJveDoge1xuICAgICAgICBzaG93OiB0cnVlLFxuICAgICAgICBpdGVtU2l6ZTogMCwgLy8gdG9vbGJveCBpcyBuZWVkZWQgZm9yIHpvb21pbmcgaW4gYWN0aW9uLCBidXQgd2UgcHJvdmlkZSBvdXIgb3duIGJ1dHRvbnNcbiAgICAgICAgZmVhdHVyZToge1xuICAgICAgICAgIGRhdGFab29tOiB7XG4gICAgICAgICAgICB5QXhpc0luZGV4OiAnbm9uZSdcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB0b29sdGlwOiB7XG4gICAgICAgIHRyaWdnZXI6ICdheGlzJyxcbiAgICAgICAgYXhpc1BvaW50ZXI6IHtcbiAgICAgICAgICB0eXBlOiAnY3Jvc3MnLFxuICAgICAgICAgIHNuYXA6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjkpJyxcbiAgICAgICAgZm9ybWF0dGVyOiB0aGlzLmdldFRvb2x0aXBGb3JtYXR0ZXIoKSxcbiAgICAgICAgYXBwZW5kVG9Cb2R5OiB0cnVlLFxuICAgICAgICBwb3NpdGlvbjogdGhpcy50b29sdGlwUG9zaXRpb24oKSxcbiAgICAgICAgdHJhbnNpdGlvbkR1cmF0aW9uOiAwXG4gICAgICB9LFxuICAgICAgbGVnZW5kOiB7XG4gICAgICAgIHNob3c6IGZhbHNlXG4gICAgICB9LFxuICAgICAgeEF4aXM6IHtcbiAgICAgICAgbWluOiBuZXcgRGF0ZSh0aW1lUmFuZ2UuZGF0ZUZyb20pLnZhbHVlT2YoKSAtIGludGVydmFsSW5NcyxcbiAgICAgICAgbWF4OiB0aW1lUmFuZ2UuZGF0ZVRvLFxuICAgICAgICB0eXBlOiAndGltZScsXG4gICAgICAgIGFuaW1hdGlvbjogZmFsc2UsXG4gICAgICAgIGF4aXNQb2ludGVyOiB7XG4gICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgIHNob3c6IGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBheGlzTGluZToge1xuICAgICAgICAgIC8vIGFsaWduIFggYXhpcyB0byAwIG9mIFkgYXhpcyBvZiBkYXRhcG9pbnQgd2l0aCBsaW5lVHlwZSAnYmFycydcbiAgICAgICAgICBvblplcm9BeGlzSW5kZXg6IGRhdGFwb2ludHNXaXRoVmFsdWVzLmZpbmRJbmRleChkcCA9PiBkcC5saW5lVHlwZSA9PT0gJ2JhcnMnKVxuICAgICAgICB9LFxuICAgICAgICBheGlzTGFiZWw6IHtcbiAgICAgICAgICBoaWRlT3ZlcmxhcDogdHJ1ZSxcbiAgICAgICAgICBib3JkZXJXaWR0aDogMiwgLy8gYXMgdGhlcmUgaXMgbm8gbWFyZ2luIGZvciBsYWJlbHMgc3BhY2luZywgdHJhbnNwYXJlbnQgYm9yZGVyIGlzIGEgd29ya2Fyb3VuZFxuICAgICAgICAgIGJvcmRlckNvbG9yOiAndHJhbnNwYXJlbnQnXG4gICAgICAgIH0sXG4gICAgICAgIHNwbGl0TGluZToge1xuICAgICAgICAgIHNob3c6IHNob3dTcGxpdExpbmVzLlhBeGlzLFxuICAgICAgICAgIGxpbmVTdHlsZTogeyBvcGFjaXR5OiAwLjgsIHR5cGU6ICdkYXNoZWQnLCB3aWR0aDogMiB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB5QXhpcyxcbiAgICAgIHNlcmllczogW1xuICAgICAgICAuLi50aGlzLmdldEFnZ3JlZ2F0ZWRTZXJpZXMoYWdncmVnYXRlZERhdGFwb2ludHMgfHwgW10pLmZpbHRlcihcbiAgICAgICAgICBzZXJpZXMgPT4gc2VyaWVzICE9PSB1bmRlZmluZWRcbiAgICAgICAgKSxcbiAgICAgICAgLi4udGhpcy5nZXRDaGFydFNlcmllcyhkYXRhcG9pbnRzV2l0aFZhbHVlcywgZXZlbnRzLCBhbGFybXMsIGRpc3BsYXlPcHRpb25zKVxuICAgICAgXVxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVFeHRlbmRlZEludGVydmFsSW5NcyhpbnRlcnZhbDogSW50ZXJ2YWxbJ2lkJ10sIHNlbGVjdGVkVGltZVJhbmdlKTogbnVtYmVyIHtcbiAgICBsZXQgaW50ZXJ2YWxJbk1zID0gSU5URVJWQUxTLmZpbmQoaSA9PiBpLmlkID09PSBpbnRlcnZhbCkudGltZXNwYW5Jbk1zO1xuICAgIHN3aXRjaCAoaW50ZXJ2YWwpIHtcbiAgICAgIGNhc2UgJ21pbnV0ZXMnOlxuICAgICAgICBpbnRlcnZhbEluTXMgPSBJTlRFUlZBTFMuZmluZChpID0+IGkuaWQgPT09IGludGVydmFsKS50aW1lc3BhbkluTXMgKiA2MDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdob3Vycyc6XG4gICAgICAgIGludGVydmFsSW5NcyA9IElOVEVSVkFMUy5maW5kKGkgPT4gaS5pZCA9PT0gaW50ZXJ2YWwpLnRpbWVzcGFuSW5NcyAqIDI0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2RheXMnOlxuICAgICAgICBpbnRlcnZhbEluTXMgPSBJTlRFUlZBTFMuZmluZChpID0+IGkuaWQgPT09IGludGVydmFsKS50aW1lc3BhbkluTXMgKiAyODtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd3ZWVrcyc6XG4gICAgICAgIGludGVydmFsSW5NcyA9IElOVEVSVkFMUy5maW5kKGkgPT4gaS5pZCA9PT0gaW50ZXJ2YWwpLnRpbWVzcGFuSW5NcyAqIDEyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21vbnRocyc6XG4gICAgICAgIGludGVydmFsSW5NcyA9IElOVEVSVkFMUy5maW5kKGkgPT4gaS5pZCA9PT0gaW50ZXJ2YWwpLnRpbWVzcGFuSW5NcyAqIDEyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2N1c3RvbSc6XG4gICAgICAgIGludGVydmFsSW5NcyA9XG4gICAgICAgICAgKG5ldyBEYXRlKHNlbGVjdGVkVGltZVJhbmdlLmRhdGVUbykudmFsdWVPZigpIC1cbiAgICAgICAgICAgIG5ldyBEYXRlKHNlbGVjdGVkVGltZVJhbmdlLmRhdGVGcm9tKS52YWx1ZU9mKCkpICpcbiAgICAgICAgICAxMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpbnRlcnZhbEluTXMgPSBJTlRFUlZBTFMuZmluZChpID0+IGkuaWQgPT09IGludGVydmFsKS50aW1lc3BhbkluTXM7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gaW50ZXJ2YWxJbk1zO1xuICB9XG5cbiAgZ2V0QWdncmVnYXRlZFNlcmllcyhhZ2dyZWdhdGVkRGF0YXBvaW50czogRHBXaXRoVmFsdWVzW10pOiBTZXJpZXNPcHRpb25bXSB7XG4gICAgY29uc3Qgc2VyaWVzOiBTZXJpZXNPcHRpb25bXSA9IFtdO1xuICAgIGFnZ3JlZ2F0ZWREYXRhcG9pbnRzLmZvckVhY2goKGRwLCBpZHgpID0+IHtcbiAgICAgIGNvbnN0IHJlbmRlclR5cGU6IERhdGFwb2ludENoYXJ0UmVuZGVyVHlwZSA9IGRwLnJlbmRlclR5cGUgfHwgJ21pbic7XG4gICAgICBpZiAocmVuZGVyVHlwZSA9PT0gJ2FyZWEnKSB7XG4gICAgICAgIHNlcmllcy5wdXNoKHRoaXMuZ2V0U2luZ2xlU2VyaWVzKGRwLCAnbWluJywgaWR4LCB0cnVlLCAnYWdncicpKTtcbiAgICAgICAgc2VyaWVzLnB1c2godGhpcy5nZXRTaW5nbGVTZXJpZXMoZHAsICdtYXgnLCBpZHgsIHRydWUsICdhZ2dyJykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VyaWVzLnB1c2godGhpcy5nZXRTaW5nbGVTZXJpZXMoZHAsIHJlbmRlclR5cGUsIGlkeCwgZmFsc2UsICdhZ2dyJykpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgc2VyaWVzLmZvckVhY2goKHM6IGFueSkgPT4ge1xuICAgICAgcy5kYXRhcG9pbnRJZCA9ICdhZ2dyZWdhdGVkJztcbiAgICAgIHMudHlwZU9mU2VyaWVzID0gJ2Zha2UnO1xuICAgICAgcy5pdGVtU3R5bGUgPSB7XG4gICAgICAgIC4uLnMuaXRlbVN0eWxlLFxuICAgICAgICBvcGFjaXR5OiAwXG4gICAgICB9O1xuICAgICAgcy5saW5lU3R5bGUgPSB7XG4gICAgICAgIC4uLnMubGluZVN0eWxlLFxuICAgICAgICBvcGFjaXR5OiAwXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIFtzZXJpZXNbMF1dO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gZ2V0IHRoZSBzZXJpZXMgZm9yIGFsYXJtcyBhbmQgZXZlbnRzLlxuICAgKiBAcGFyYW0gZHAgLSBUaGUgZGF0YSBwb2ludC5cbiAgICogQHBhcmFtIHJlbmRlclR5cGUgLSBUaGUgcmVuZGVyIHR5cGUuXG4gICAqIEBwYXJhbSBpc01pbk1heENoYXJ0IC0gSWYgdGhlIGNoYXJ0IGlzIG1pbiBtYXggY2hhcnQuXG4gICAqIEBwYXJhbSBpdGVtcyAtIEFsbCBhbGFybXMgb3IgZXZlbnRzIHdoaWNoIHNob3VsZCBiZSBkaXNwbGF5ZWQgb24gdGhlIGNoYXJ0LlxuICAgKiBAcGFyYW0gaXRlbVR5cGUgLSBUaGUgaXRlbSB0eXBlLlxuICAgKiBAcGFyYW0gaWQgLSBUaGUgaWQgb2YgdGhlIGRldmljZVxuICAgKi9cbiAgZ2V0QWxhcm1PckV2ZW50U2VyaWVzKFxuICAgIGRwOiBEcFdpdGhWYWx1ZXMsXG4gICAgcmVuZGVyVHlwZTogRGF0YXBvaW50Q2hhcnRSZW5kZXJUeXBlLFxuICAgIGlzTWluTWF4Q2hhcnQgPSBmYWxzZSxcbiAgICBpdGVtczogSUFsYXJtW10gfCBJRXZlbnRbXSA9IFtdLFxuICAgIGl0ZW1UeXBlOiAnYWxhcm0nIHwgJ2V2ZW50JyA9ICdhbGFybScsXG4gICAgZGlzcGxheU9wdGlvbnMgPSB7IGRpc3BsYXlNYXJrZWRMaW5lOiB0cnVlLCBkaXNwbGF5TWFya2VkUG9pbnQ6IHRydWUgfSxcbiAgICBpZD86IHN0cmluZyB8IG51bWJlcixcbiAgICBpZHg/OiBudW1iZXIsXG4gICAgcmVhbHRpbWU/OiBib29sZWFuXG4gICk6IEN1c3RvbVNlcmllc09wdGlvbnNbXSB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBpZiAoIWRpc3BsYXlPcHRpb25zLmRpc3BsYXlNYXJrZWRMaW5lICYmICFkaXNwbGF5T3B0aW9ucy5kaXNwbGF5TWFya2VkUG9pbnQpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvL2ZpbHRlciBpdGVtcyB0aGF0IGFyZSBub3QgX19oaWRkZW5cbiAgICBjb25zdCBmaWx0ZXJlZEl0ZW1zOiBJQWxhcm1bXSB8IElFdmVudFtdID0gaXRlbXMuZmlsdGVyKGl0ZW0gPT4gIWl0ZW1bJ19faGlkZGVuJ10pO1xuICAgIGNvbnN0IGl0ZW1zQnlUeXBlID0gdGhpcy5ncm91cEJ5VHlwZShmaWx0ZXJlZEl0ZW1zLCAndHlwZScpO1xuICAgIGNvbnN0IGlzQWxhcm0gPSBpdGVtVHlwZSA9PT0gJ2FsYXJtJztcblxuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhpdGVtc0J5VHlwZSkuZmxhdE1hcChcbiAgICAgIChbdHlwZSwgaXRlbXNPZlR5cGVdOiBbc3RyaW5nLCAoSUFsYXJtIHwgSUV2ZW50KVtdXSkgPT4ge1xuICAgICAgICAvLyBNYWluIHNlcmllcyBkYXRhXG4gICAgICAgIGNvbnN0IG1haW5EYXRhID0gaXRlbXNPZlR5cGUubWFwKGl0ZW0gPT4gW2l0ZW0uY3JlYXRpb25UaW1lLCBudWxsLCAnbWFya0xpbmVGbGFnJ10pO1xuICAgICAgICAvLyBJcyBhIHNwZWNpZmljIGRhdGFwb2ludCB0ZW1wbGF0ZSBzZWxlY3RlZCBmb3IgdGhpcyBhbGFybS9ldmVudCB0eXBlP1xuICAgICAgICBsZXQgaXNEcFRlbXBsYXRlU2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgICAvLyBNYXJrUG9pbnQgZGF0YVxuICAgICAgICBjb25zdCBtYXJrUG9pbnREYXRhID0gaXRlbXNPZlR5cGUucmVkdWNlPE1hcmtQb2ludERhdGFbXT4oKGFjYywgaXRlbSkgPT4ge1xuICAgICAgICAgIGlzRHBUZW1wbGF0ZVNlbGVjdGVkID1cbiAgICAgICAgICAgIGl0ZW1bJ3NlbGVjdGVkRGF0YXBvaW50J10gJiZcbiAgICAgICAgICAgIGRwWydfX3RhcmdldCddICYmXG4gICAgICAgICAgICBpdGVtWydzZWxlY3RlZERhdGFwb2ludCddWydmcmFnbWVudCddID09PSBkcFsnZnJhZ21lbnQnXSAmJlxuICAgICAgICAgICAgaXRlbVsnc2VsZWN0ZWREYXRhcG9pbnQnXVsnc2VyaWVzJ10gPT09IGRwWydzZXJpZXMnXSAmJlxuICAgICAgICAgICAgaXRlbVsnc2VsZWN0ZWREYXRhcG9pbnQnXVsndGFyZ2V0J10gPT09IGRwWydfX3RhcmdldCddWydpZCddO1xuICAgICAgICAgIGlmIChkcC5fX3RhcmdldD8uaWQgPT09IGl0ZW0uc291cmNlLmlkKSB7XG4gICAgICAgICAgICBjb25zdCBpc0NsZWFyZWQgPSBpc0FsYXJtICYmIGl0ZW0uc3RhdHVzID09PSBBbGFybVN0YXR1cy5DTEVBUkVEO1xuICAgICAgICAgICAgY29uc3QgaXNFdmVudCA9ICFpc0FsYXJtO1xuICAgICAgICAgICAgcmV0dXJuIGFjYy5jb25jYXQodGhpcy5jcmVhdGVNYXJrUG9pbnQoaXRlbSwgZHAsIGlzQ2xlYXJlZCwgaXNFdmVudCwgcmVhbHRpbWUpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFpdGVtLmNyZWF0aW9uVGltZSkge1xuICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYWNjLmNvbmNhdChbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb29yZDogW2l0ZW0uY3JlYXRpb25UaW1lLCBudWxsXSxcbiAgICAgICAgICAgICAgICBuYW1lOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICAgICAgaXRlbVR5cGU6IGl0ZW0udHlwZSxcbiAgICAgICAgICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6IGl0ZW1bJ2NvbG9yJ10gfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIFtdKTtcblxuICAgICAgICAvLyBDb25zdHJ1Y3Qgc2VyaWVzIHdpdGggbWFya1BvaW50XG4gICAgICAgIGNvbnN0IHNlcmllc1dpdGhNYXJrUG9pbnQgPSB7XG4gICAgICAgICAgaWQ6IGAke3R5cGV9LyR7ZHAuX190YXJnZXQ/LmlkfSske2lkID8gaWQgOiAnJ30tbWFya1BvaW50YCxcbiAgICAgICAgICBuYW1lOiBgJHt0eXBlfS1tYXJrUG9pbnRgLFxuICAgICAgICAgIHR5cGVPZlNlcmllczogaXRlbVR5cGUsXG4gICAgICAgICAgZGF0YTogbWFpbkRhdGEsXG4gICAgICAgICAgaXNEcFRlbXBsYXRlU2VsZWN0ZWQsXG4gICAgICAgICAgcG9zaXRpb246ICdib3R0b20nLFxuICAgICAgICAgIHNpbGVudDogdHJ1ZSxcbiAgICAgICAgICBtYXJrUG9pbnQ6IHtcbiAgICAgICAgICAgIHNob3dTeW1ib2w6IHRydWUsXG4gICAgICAgICAgICBzeW1ib2xLZWVwQXNwZWN0OiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogbWFya1BvaW50RGF0YVxuICAgICAgICAgIH0sXG4gICAgICAgICAgeUF4aXNJbmRleDogaWR4LFxuICAgICAgICAgIC4uLnRoaXMuY2hhcnRUeXBlc1NlcnZpY2UuZ2V0U2VyaWVzT3B0aW9ucyhkcCwgaXNNaW5NYXhDaGFydCwgcmVuZGVyVHlwZSlcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBtYXJrTGluZURhdGEgPSB0aGlzLmNyZWF0ZU1hcmtMaW5lKGl0ZW1zT2ZUeXBlKTtcblxuICAgICAgICAvLyBDb25zdHJ1Y3Qgc2VyaWVzIHdpdGggbWFya0xpbmVcbiAgICAgICAgY29uc3Qgc2VyaWVzV2l0aE1hcmtMaW5lID0ge1xuICAgICAgICAgIGlkOiBgJHt0eXBlfS8ke2RwLl9fdGFyZ2V0Py5pZH0rJHtpZCA/IGlkIDogJyd9LW1hcmtMaW5lYCxcbiAgICAgICAgICBuYW1lOiBgJHt0eXBlfS1tYXJrTGluZWAsXG4gICAgICAgICAgdHlwZU9mU2VyaWVzOiBpdGVtVHlwZSxcbiAgICAgICAgICBpc0RwVGVtcGxhdGVTZWxlY3RlZCxcbiAgICAgICAgICBkYXRhOiBtYWluRGF0YSxcbiAgICAgICAgICBtYXJrTGluZToge1xuICAgICAgICAgICAgc2hvd1N5bWJvbDogZmFsc2UsXG4gICAgICAgICAgICBzeW1ib2w6IFsnbm9uZScsICdub25lJ10sIC8vIG5vIHN5bWJvbCBhdCB0aGUgc3RhcnQvZW5kIG9mIHRoZSBsaW5lXG4gICAgICAgICAgICBkYXRhOiBtYXJrTGluZURhdGFcbiAgICAgICAgICB9LFxuICAgICAgICAgIC4uLnRoaXMuY2hhcnRUeXBlc1NlcnZpY2UuZ2V0U2VyaWVzT3B0aW9ucyhkcCwgaXNNaW5NYXhDaGFydCwgcmVuZGVyVHlwZSlcbiAgICAgICAgfTtcblxuICAgICAgICAvL2RlcGVuZGluZyBvbiB0aGUgb3B0aW9ucyByZXR1cm4gb25seSB0aGUgcmVxdWlyZWQgc2VyaWVzXG4gICAgICAgIGlmIChkaXNwbGF5T3B0aW9ucy5kaXNwbGF5TWFya2VkTGluZSAmJiBkaXNwbGF5T3B0aW9ucy5kaXNwbGF5TWFya2VkUG9pbnQpIHtcbiAgICAgICAgICByZXR1cm4gW3Nlcmllc1dpdGhNYXJrTGluZSwgc2VyaWVzV2l0aE1hcmtQb2ludF07XG4gICAgICAgIH0gZWxzZSBpZiAoZGlzcGxheU9wdGlvbnMuZGlzcGxheU1hcmtlZExpbmUpIHtcbiAgICAgICAgICByZXR1cm4gW3Nlcmllc1dpdGhNYXJrTGluZV07XG4gICAgICAgIH0gZWxzZSBpZiAoZGlzcGxheU9wdGlvbnMuZGlzcGxheU1hcmtlZFBvaW50KSB7XG4gICAgICAgICAgcmV0dXJuIFtzZXJpZXNXaXRoTWFya1BvaW50XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICkgYXMgQ3VzdG9tU2VyaWVzT3B0aW9uc1tdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gZ2V0IHRvb2x0aXAgZm9ybWF0dGVyIGZvciBhbGFybXMgYW5kIGV2ZW50cy5cbiAgICogQHBhcmFtIHRvb2x0aXBQYXJhbXMgLSBUaGUgdG9vbHRpcCBwYXJhbWV0ZXJzLlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZGF0YS5cbiAgICogQHBhcmFtIGFsbEV2ZW50cyAtIEFsbCBldmVudHMuXG4gICAqIEBwYXJhbSBhbGxBbGFybXMgLSBBbGwgYWxhcm1zLlxuICAgKiBAcmV0dXJucyBUaGUgZm9ybWF0dGVkIHN0cmluZyBmb3IgdGhlIHRvb2x0aXAuXG4gICAqL1xuICBnZXRUb29sdGlwRm9ybWF0dGVyRm9yQWxhcm1BbmRFdmVudHMoXG4gICAgdG9vbHRpcFBhcmFtczogQ2FsbGJhY2tEYXRhUGFyYW1zLFxuICAgIHBhcmFtczogeyBkYXRhOiB7IGl0ZW1UeXBlOiBzdHJpbmcgfSB9LFxuICAgIGFsbEV2ZW50czogSUV2ZW50W10sXG4gICAgYWxsQWxhcm1zOiBJQWxhcm1bXVxuICApOiBzdHJpbmcge1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh0b29sdGlwUGFyYW1zKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBjb25zdCBYQXhpc1ZhbHVlOiBzdHJpbmcgPSB0b29sdGlwUGFyYW1zWzBdLmRhdGFbMF07XG4gICAgY29uc3QgWUF4aXNSZWFkaW5nczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBhbGxTZXJpZXMgPSB0aGlzLmVjaGFydHNJbnN0YW5jZT8uZ2V0T3B0aW9uKClbJ3NlcmllcyddIGFzIEN1c3RvbVNlcmllc09wdGlvbnNbXTtcblxuICAgIC8vIGZpbHRlciBvdXQgYWxhcm0gYW5kIGV2ZW50IHNlcmllc1xuICAgIGNvbnN0IGFsbERhdGFQb2ludFNlcmllcyA9IGFsbFNlcmllcy5maWx0ZXIoXG4gICAgICBzZXJpZXMgPT4gc2VyaWVzWyd0eXBlT2ZTZXJpZXMnXSAhPT0gJ2FsYXJtJyAmJiBzZXJpZXNbJ3R5cGVPZlNlcmllcyddICE9PSAnZXZlbnQnXG4gICAgKTtcblxuICAgIHRoaXMucHJvY2Vzc1NlcmllcyhhbGxEYXRhUG9pbnRTZXJpZXMsIFhBeGlzVmFsdWUsIFlBeGlzUmVhZGluZ3MpO1xuXG4gICAgLy8gZmluZCBldmVudCBhbmQgYWxhcm0gb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGUgaG92ZXJlZCBtYXJrZWRMaW5lIG9yIG1hcmtlZFBvaW50XG4gICAgY29uc3QgZXZlbnQgPSBhbGxFdmVudHMuZmluZChlID0+IGUudHlwZSA9PT0gcGFyYW1zLmRhdGEuaXRlbVR5cGUpO1xuICAgIGNvbnN0IGFsYXJtID0gYWxsQWxhcm1zLmZpbmQoYSA9PiBhLnR5cGUgPT09IHBhcmFtcy5kYXRhLml0ZW1UeXBlKTtcblxuICAgIGxldCB2YWx1ZSA9ICcnO1xuICAgIGlmIChldmVudCkge1xuICAgICAgdmFsdWUgPSB0aGlzLnByb2Nlc3NFdmVudChldmVudCk7XG4gICAgfVxuXG4gICAgaWYgKGFsYXJtKSB7XG4gICAgICB0aGlzLnByb2Nlc3NBbGFybShhbGFybSkudGhlbihhbGFybVZhbCA9PiB7XG4gICAgICAgIHZhbHVlID0gYWxhcm1WYWw7XG4gICAgICAgIFlBeGlzUmVhZGluZ3MucHVzaCh2YWx1ZSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmVjaGFydHNJbnN0YW5jZT8uZ2V0T3B0aW9uKCkgYXMgRUNoYXJ0c09wdGlvbjtcbiAgICAgICAgaWYgKCFvcHRpb25zLnRvb2x0aXAgfHwgIUFycmF5LmlzQXJyYXkob3B0aW9ucy50b29sdGlwKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cGRhdGVkT3B0aW9uczogUGFydGlhbDxTZXJpZXNPcHRpb24+ID0ge1xuICAgICAgICAgIHRvb2x0aXA6IG9wdGlvbnNbJ3Rvb2x0aXAnXVswXVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghdXBkYXRlZE9wdGlvbnMudG9vbHRpcCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB1cGRhdGVkT3B0aW9ucy50b29sdGlwLmZvcm1hdHRlciA9IGA8ZGl2IHN0eWxlPVwid2lkdGg6ICR7dGhpcy5UT09MVElQX1dJRFRIfXB4XCI+JHtZQXhpc1JlYWRpbmdzLmpvaW4oJycpfTwvZGl2PmA7XG4gICAgICAgIHVwZGF0ZWRPcHRpb25zLnRvb2x0aXAudHJhbnNpdGlvbkR1cmF0aW9uID0gMDtcbiAgICAgICAgdXBkYXRlZE9wdGlvbnMudG9vbHRpcC5wb3NpdGlvbiA9IHRoaXMudG9vbHRpcFBvc2l0aW9uKCk7XG4gICAgICAgIHRoaXMuZWNoYXJ0c0luc3RhbmNlPy5zZXRPcHRpb24odXBkYXRlZE9wdGlvbnMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9KTtcbiAgICB9XG4gICAgWUF4aXNSZWFkaW5ncy5wdXNoKHZhbHVlKTtcblxuICAgIHJldHVybiBgPGRpdiBzdHlsZT1cIndpZHRoOiAzMDBweFwiPiR7WUF4aXNSZWFkaW5ncy5qb2luKCcnKX08L2Rpdj5gO1xuICB9XG5cbiAgcHJpdmF0ZSB0b29sdGlwUG9zaXRpb24oKTogVG9vbHRpcFBvc2l0aW9uQ2FsbGJhY2sge1xuICAgIGxldCBsYXN0UG9zaXRpb25PZlRvb2x0aXA6IFBhcnRpYWw8UmVjb3JkPCd0b3AnIHwgJ2JvdHRvbScgfCAnbGVmdCcgfCAncmlnaHQnLCBudW1iZXI+PiA9IHt9O1xuICAgIGlmICh0aGlzLnRvb2x0aXBQb3NpdGlvbkNhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gdGhpcy50b29sdGlwUG9zaXRpb25DYWxsYmFjaztcbiAgICB9XG5cbiAgICB0aGlzLnRvb2x0aXBQb3NpdGlvbkNhbGxiYWNrID0gKFxuICAgICAgcG9pbnQ6IFtudW1iZXIsIG51bWJlcl0sIC8vIHBvc2l0aW9uIG9mIG1vdXNlIGluIGNoYXJ0IFtYLCBZXTsgMCwwIGlzIHRvcCBsZWZ0IGNvcm5lclxuICAgICAgXzogYW55LCAvLyB0b29sdGlwIGRhdGFcbiAgICAgIGRvbTogSFRNTEVsZW1lbnQgfCB1bmtub3duLCAvLyB0b29sdGlwIGVsZW1lbnRcbiAgICAgIF9fOiBhbnksXG4gICAgICBzaXplOiB7XG4gICAgICAgIGNvbnRlbnRTaXplOiBbbnVtYmVyLCBudW1iZXJdOyAvLyBzaXplIG9mIHRvb2x0aXBcbiAgICAgICAgdmlld1NpemU6IFtudW1iZXIsIG51bWJlcl07XG4gICAgICB9IHwgbnVsbCAvLyBzaXplIG9mIGNoYXJ0XG4gICAgKSA9PiB7XG4gICAgICBjb25zdCBvZmZzZXQgPSAxMDtcbiAgICAgIGNvbnN0IFttb3VzZVgsIG1vdXNlWV0gPSBwb2ludDtcbiAgICAgIGNvbnN0IGNoYXJ0V2lkdGggPSBzaXplPy52aWV3U2l6ZVswXSB8fCAwO1xuICAgICAgY29uc3QgY2hhcnRIZWlnaHQgPSBzaXplPy52aWV3U2l6ZVsxXSB8fCAwO1xuICAgICAgY29uc3QgdG9vbHRpcFdpZHRoID0gc2l6ZT8uY29udGVudFNpemVbMF0gfHwgMDtcbiAgICAgIGNvbnN0IHRvb2x0aXBIZWlnaHQgPSBzaXplPy5jb250ZW50U2l6ZVsxXSB8fCAwO1xuICAgICAgY29uc3QgdG9vbHRpcFJlY3QgPSAoZG9tIGFzIEhUTUxFbGVtZW50KT8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB0b29sdGlwT3ZlcmZsb3dzQm90dG9tRWRnZSA9IHRvb2x0aXBSZWN0LmJvdHRvbSA+IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgY29uc3QgdG9vbHRpcE92ZXJmbG93c1JpZ2h0RWRnZSA9IHRvb2x0aXBSZWN0LnJpZ2h0ID4gd2luZG93LmlubmVyV2lkdGg7XG5cbiAgICAgIGNvbnN0IHRvb2x0aXBXb3VsZE92ZXJmbG93Qm90dG9tRWRnZU9uUG9zaXRpb25DaGFuZ2UgPVxuICAgICAgICAhbGFzdFBvc2l0aW9uT2ZUb29sdGlwLnRvcCAmJlxuICAgICAgICB0b29sdGlwUmVjdC5ib3R0b20gKyAyICogb2Zmc2V0ICsgdG9vbHRpcEhlaWdodCA+IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgY29uc3QgdG9vbHRpcFdvdWxkT3ZlcmZsb3dSaWdodEVkZ2VPblBvc2l0aW9uQ2hhbmdlID1cbiAgICAgICAgIWxhc3RQb3NpdGlvbk9mVG9vbHRpcC5sZWZ0ICYmXG4gICAgICAgIHRvb2x0aXBSZWN0LnJpZ2h0ICsgMiAqIG9mZnNldCArIHRvb2x0aXBXaWR0aCA+IHdpbmRvdy5pbm5lcldpZHRoO1xuXG4gICAgICBsZXQgdmVydGljYWxQb3NpdGlvbjogeyB0b3A6IG51bWJlciB9IHwgeyBib3R0b206IG51bWJlciB9ID0ge1xuICAgICAgICB0b3A6IG1vdXNlWSArIG9mZnNldFxuICAgICAgfTtcbiAgICAgIGxldCBob3Jpem9udGFsUG9zaXRpb246IHsgbGVmdDogbnVtYmVyIH0gfCB7IHJpZ2h0OiBudW1iZXIgfSA9IHtcbiAgICAgICAgbGVmdDogbW91c2VYICsgb2Zmc2V0XG4gICAgICB9O1xuXG4gICAgICBpZiAodG9vbHRpcE92ZXJmbG93c0JvdHRvbUVkZ2UgfHwgdG9vbHRpcFdvdWxkT3ZlcmZsb3dCb3R0b21FZGdlT25Qb3NpdGlvbkNoYW5nZSkge1xuICAgICAgICB2ZXJ0aWNhbFBvc2l0aW9uID0ge1xuICAgICAgICAgIGJvdHRvbTogY2hhcnRIZWlnaHQgLSBtb3VzZVkgKyBvZmZzZXRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmICh0b29sdGlwT3ZlcmZsb3dzUmlnaHRFZGdlIHx8IHRvb2x0aXBXb3VsZE92ZXJmbG93UmlnaHRFZGdlT25Qb3NpdGlvbkNoYW5nZSkge1xuICAgICAgICBob3Jpem9udGFsUG9zaXRpb24gPSB7XG4gICAgICAgICAgcmlnaHQ6IGNoYXJ0V2lkdGggLSBtb3VzZVggKyBvZmZzZXRcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgbGFzdFBvc2l0aW9uT2ZUb29sdGlwID0ge1xuICAgICAgICAuLi52ZXJ0aWNhbFBvc2l0aW9uLFxuICAgICAgICAuLi5ob3Jpem9udGFsUG9zaXRpb25cbiAgICAgIH07XG4gICAgICByZXR1cm4gbGFzdFBvc2l0aW9uT2ZUb29sdGlwO1xuICAgIH07XG4gICAgcmV0dXJuIHRoaXMudG9vbHRpcFBvc2l0aW9uQ2FsbGJhY2s7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBhZGQgdGhlIGRhdGEgcG9pbnQgaW5mbyB0byB0aGUgdG9vbHRpcC5cbiAgICogQHBhcmFtIGFsbERhdGFQb2ludFNlcmllcyAtIEFsbCB0aGUgZGF0YSBwb2ludCBzZXJpZXMuXG4gICAqIEBwYXJhbSBYQXhpc1ZhbHVlIC0gVGhlIFggQXhpcyB2YWx1ZS5cbiAgICogQHBhcmFtIFlBeGlzUmVhZGluZ3MgLSBUaGUgWSBBeGlzIHJlYWRpbmdzLlxuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzU2VyaWVzKFxuICAgIGFsbERhdGFQb2ludFNlcmllczogQ3VzdG9tU2VyaWVzT3B0aW9uc1tdLFxuICAgIFhBeGlzVmFsdWU6IHN0cmluZyxcbiAgICBZQXhpc1JlYWRpbmdzOiBzdHJpbmdbXVxuICApOiB2b2lkIHtcbiAgICBhbGxEYXRhUG9pbnRTZXJpZXMuZm9yRWFjaCgoc2VyaWVzOiBhbnkpID0+IHtcbiAgICAgIGxldCB2YWx1ZSA9ICcnO1xuICAgICAgaWYgKHNlcmllcy5pZC5lbmRzV2l0aCgnL21pbicpKSB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5wcm9jZXNzTWluU2VyaWVzKHNlcmllcywgYWxsRGF0YVBvaW50U2VyaWVzLCBYQXhpc1ZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAoIXNlcmllcy5pZC5lbmRzV2l0aCgnL21heCcpKSB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5wcm9jZXNzUmVndWxhclNlcmllcyhzZXJpZXMsIFhBeGlzVmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgWUF4aXNSZWFkaW5ncy5wdXNoKFxuICAgICAgICAgIGA8ZGl2IGNsYXNzPVwiZC1mbGV4IGEtaS1jZW50ZXIgcC1iLThcIj48c3BhbiBjbGFzcz0nZGx0LWM4eS1pY29uLWNpcmNsZSBtLXItNCcgc3R5bGU9J2NvbG9yOiAke3Nlcmllcy5pdGVtU3R5bGUuY29sb3J9Oyc+PC9zcGFuPmAgKyAvLyBjb2xvciBjaXJjbGVcbiAgICAgICAgICAgIGA8c3Ryb25nPiR7c2VyaWVzLmRhdGFwb2ludExhYmVsfTwvc3Ryb25nPjwvZGl2PmAgKyAvLyBuYW1lXG4gICAgICAgICAgICBgJHt2YWx1ZX1gIC8vIHNpbmdsZSB2YWx1ZSBvciBtaW4tbWF4IHJhbmdlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBwcm9jZXNzIHRoZSBtaW4gc2VyaWVzLlxuICAgKiBAcGFyYW0gc2VyaWVzIC0gVGhlIHNlcmllcy5cbiAgICogQHBhcmFtIGFsbERhdGFQb2ludFNlcmllcyAtIEFsbCB0aGUgZGF0YSBwb2ludCBzZXJpZXMuXG4gICAqIEBwYXJhbSBYQXhpc1ZhbHVlIC0gVGhlIFggQXhpcyB2YWx1ZS5cbiAgICogQHJldHVybnMgVGhlIHByb2Nlc3NlZCB2YWx1ZS5cbiAgICovXG4gIHByaXZhdGUgcHJvY2Vzc01pblNlcmllcyhcbiAgICBzZXJpZXM6IGFueSxcbiAgICBhbGxEYXRhUG9pbnRTZXJpZXM6IEN1c3RvbVNlcmllc09wdGlvbnNbXSxcbiAgICBYQXhpc1ZhbHVlOiBzdHJpbmdcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBtaW5WYWx1ZSA9IHRoaXMuZmluZFZhbHVlRm9yRXhhY3RPckVhcmxpZXJUaW1lc3RhbXAoc2VyaWVzLmRhdGEsIFhBeGlzVmFsdWUpO1xuICAgIGlmICghbWluVmFsdWUpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgY29uc3QgbWF4U2VyaWVzID0gYWxsRGF0YVBvaW50U2VyaWVzLmZpbmQocyA9PiBzWydpZCddID09PSBzZXJpZXMuaWQucmVwbGFjZSgnL21pbicsICcvbWF4JykpO1xuICAgIGNvbnN0IG1heFZhbHVlID0gdGhpcy5maW5kVmFsdWVGb3JFeGFjdE9yRWFybGllclRpbWVzdGFtcChcbiAgICAgIG1heFNlcmllcz8uWydkYXRhJ10gYXMgU2VyaWVzVmFsdWVbXSxcbiAgICAgIFhBeGlzVmFsdWVcbiAgICApO1xuICAgIHJldHVybiAoXG4gICAgICBgPGRpdiBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyIHNlcGFyYXRvci10b3AgcC10LTggcC1iLThcIj48bGFiZWwgY2xhc3M9XCJ0ZXh0LTEyIG0tci04IG0tYi0wXCI+JHt0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybShtaW5WYWx1ZVswXSl9PC9sYWJlbD5gICtcbiAgICAgIGA8c3BhbiBjbGFzcz1cIm0tbC1hdXRvIHRleHQtMTJcIj4ke21pblZhbHVlWzFdfSDigJQgJHttYXhWYWx1ZT8uWzFdfWAgK1xuICAgICAgKHNlcmllcy5kYXRhcG9pbnRVbml0ID8gYCAke3Nlcmllcy5kYXRhcG9pbnRVbml0fWAgOiAnJykgK1xuICAgICAgYDwvc3Bhbj48L2Rpdj5gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHByb2Nlc3MgdGhlIHJlZ3VsYXIgc2VyaWVzLlxuICAgKiBAcGFyYW0gc2VyaWVzIC0gVGhlIHNlcmllcy5cbiAgICogQHBhcmFtIFhBeGlzVmFsdWUgLSBUaGUgWCBBeGlzIHZhbHVlLlxuICAgKiBAcmV0dXJucyBUaGUgcHJvY2Vzc2VkIHZhbHVlLlxuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzUmVndWxhclNlcmllcyhzZXJpZXM6IGFueSwgWEF4aXNWYWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzZXJpZXNWYWx1ZSA9IHRoaXMuZmluZFZhbHVlRm9yRXhhY3RPckVhcmxpZXJUaW1lc3RhbXAoc2VyaWVzLmRhdGEsIFhBeGlzVmFsdWUpO1xuICAgIGlmICghc2VyaWVzVmFsdWUpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIGA8ZGl2IGNsYXNzPVwiZC1mbGV4IGEtaS1jZW50ZXIgcC10LTggcC1iLTggc2VwYXJhdG9yLXRvcFwiPmAgK1xuICAgICAgYDxsYWJlbCBjbGFzcz1cIm0tYi0wIG0tci04IHRleHQtMTJcIj4ke3RoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKFxuICAgICAgICBzZXJpZXNWYWx1ZVswXVxuICAgICAgKX08L2xhYmVsPjxzcGFuIGNsYXNzPVwibS1sLWF1dG8gdGV4dC0xMlwiPmAgK1xuICAgICAgc2VyaWVzVmFsdWVbMV0/LnRvU3RyaW5nKCkgK1xuICAgICAgKHNlcmllcy5kYXRhcG9pbnRVbml0ID8gYCAke3Nlcmllcy5kYXRhcG9pbnRVbml0fWAgOiAnJykgK1xuICAgICAgYDwvc3Bhbj48L2Rpdj5gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHByb2Nlc3MgdGhlIGV2ZW50IHRvb2x0aXAuXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBldmVudCBvYmplY3QuXG4gICAqIEByZXR1cm5zIFRoZSBwcm9jZXNzZWQgdmFsdWUuXG4gICAqL1xuICBwcml2YXRlIHByb2Nlc3NFdmVudChldmVudDogSUV2ZW50KTogc3RyaW5nIHtcbiAgICBsZXQgdmFsdWUgPSBgPHVsIGNsYXNzPVwibGlzdC11bnN0eWxlZCBzbWFsbCBzZXBhcmF0b3ItdG9wXCI+YDtcbiAgICB2YWx1ZSArPSBgPGxpIGNsYXNzPVwicC10LTQgcC1iLTQgZC1mbGV4IHNlcGFyYXRvci1ib3R0b20gdGV4dC1uby13cmFwXCI+PGxhYmVsIGNsYXNzPVwic21hbGwgbS1iLTAgbS1yLThcIj5FdmVudCB0eXBlPC9sYWJlbD48Y29kZSBjbGFzcz1cIm0tbC1hdXRvXCI+JHtldmVudC50eXBlfTwvY29kZT48L2xpPmA7XG4gICAgdmFsdWUgKz0gYDxsaSBjbGFzcz1cInAtdC00IHAtYi00IGQtZmxleCBzZXBhcmF0b3ItYm90dG9tIHRleHQtbm8td3JhcFwiPjxsYWJlbCBjbGFzcz1cInNtYWxsIG0tYi0wIG0tci04XCI+RXZlbnQgdGV4dDwvbGFiZWw+PHNwYW4gY2xhc3M9XCJtLWwtYXV0b1wiPiR7ZXZlbnQudGV4dH08c3Bhbj48L2xpPmA7XG4gICAgdmFsdWUgKz0gYDxsaSBjbGFzcz1cInAtdC00IHAtYi00IGQtZmxleCBzZXBhcmF0b3ItYm90dG9tIHRleHQtbm8td3JhcFwiPjxsYWJlbCBjbGFzcz1cInNtYWxsIG0tYi0wIG0tci04XCI+TGFzdCB1cGRhdGU8L2xhYmVsPjxzcGFuIGNsYXNzPVwibS1sLWF1dG9cIj4ke3RoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKGV2ZW50WydsYXN0VXBkYXRlZCddKX08c3Bhbj48L2xpPmA7XG4gICAgdmFsdWUgKz0gYDwvdWw+YDtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBwcm9jZXNzIHRoZSBhbGFybSB0b29sdGlwLlxuICAgKiBAcGFyYW0gYWxhcm0gLSBUaGUgYWxhcm0gb2JqZWN0LlxuICAgKiBAcmV0dXJucyBUaGUgcHJvY2Vzc2VkIHZhbHVlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzQWxhcm0oYWxhcm06IElBbGFybSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgbGV0IHZhbHVlID0gYDx1bCBjbGFzcz1cImxpc3QtdW5zdHlsZWQgc21hbGwgc2VwYXJhdG9yLXRvcCBtLTBcIj5gO1xuICAgIHZhbHVlICs9IGA8bGkgY2xhc3M9XCJwLXQtNCBwLWItNCBkLWZsZXggYS1pLWNlbnRlciBzZXBhcmF0b3ItYm90dG9tIHRleHQtbm8td3JhcFwiPjxsYWJlbCBjbGFzcz1cInRleHQtbGFiZWwtc21hbGwgbS1iLTAgbS1yLThcIj5BbGFybSBTZXZlcml0eTwvbGFiZWw+YDtcbiAgICB2YWx1ZSArPSBgPHNwYW4gY2xhc3M9XCJzbWFsbCBkLWlubGluZS1mbGV4IGEtaS1jZW50ZXIgZ2FwLTQgbS1sLWF1dG9cIj48aSBjbGFzcz1cInN0cm9rZWQtaWNvbiBpY29uLTE0IHN0YXR1cyBkbHQtYzh5LWljb24tJHt0aGlzLnNldmVyaXR5SWNvblBpcGUudHJhbnNmb3JtKGFsYXJtLnNldmVyaXR5KX0gJHthbGFybS5zZXZlcml0eS50b0xvd2VyQ2FzZSgpfVwiID4gPC9pPiAke3RoaXMuc2V2ZXJpdHlMYWJlbFBpcGUudHJhbnNmb3JtKGFsYXJtLnNldmVyaXR5KX0gPC9zcGFuPjwvbGk+YDtcbiAgICB2YWx1ZSArPSBgPGxpIGNsYXNzPVwicC10LTQgcC1iLTQgZC1mbGV4IHNlcGFyYXRvci1ib3R0b20gdGV4dC1uby13cmFwXCI+PGxhYmVsIGNsYXNzPVwidGV4dC1sYWJlbC1zbWFsbCBtLWItMCBtLXItOFwiPkFsYXJtIFR5cGU8L2xhYmVsPjxzcGFuIGNsYXNzPVwic21hbGwgbS1sLWF1dG9cIj48Y29kZT4ke2FsYXJtLnR5cGV9PC9jb2RlPjwvc3Bhbj48L2xpPmA7XG4gICAgdmFsdWUgKz0gYDxsaSBjbGFzcz1cInAtdC00IHAtYi00IGQtZmxleCBzZXBhcmF0b3ItYm90dG9tIHRleHQtbm8td3JhcFwiPjxsYWJlbCBjbGFzcz1cInRleHQtbGFiZWwtc21hbGwgbS1iLTAgbS1yLThcIj5NZXNzYWdlPC9sYWJlbD48c3BhbiBjbGFzcz1cInNtYWxsIG0tbC1hdXRvXCIgc3R5bGU9XCJvdmVyZmxvdzogaGlkZGVuOyB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcIiB0aXRsZT1cIiR7YWxhcm0udGV4dH1cIj4ke2FsYXJtLnRleHR9PC9zcGFuPjwvbGk+YDtcbiAgICB2YWx1ZSArPSBgPGxpIGNsYXNzPVwicC10LTQgcC1iLTQgZC1mbGV4IHNlcGFyYXRvci1ib3R0b20gdGV4dC1uby13cmFwXCI+PGxhYmVsIGNsYXNzPVwidGV4dC1sYWJlbC1zbWFsbCBtLWItMCBtLXItOFwiPkxhc3QgVXBkYXRlZDwvbGFiZWw+PHNwYW4gY2xhc3M9XCJzbWFsbCBtLWwtYXV0b1wiPiR7dGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0oYWxhcm1bJ2xhc3RVcGRhdGVkJ10pfTwvc3Bhbj48L2xpPmA7XG4gICAgY29uc3QgZXhpc3RzID0gYXdhaXQgdGhpcy5hbGFybVJvdXRlRXhpc3RzKCk7XG4gICAgaWYgKGV4aXN0cykge1xuICAgICAgY29uc3QgY3VycmVudFVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgY29uc3QgYmFzZVVybEluZGV4ID0gY3VycmVudFVybC5pbmRleE9mKElOREVYX0hUTUwpO1xuICAgICAgY29uc3QgYmFzZVVybCA9IGN1cnJlbnRVcmwuc3Vic3RyaW5nKDAsIGJhc2VVcmxJbmRleCArIElOREVYX0hUTUwubGVuZ3RoKTtcbiAgICAgIHZhbHVlICs9IGA8bGkgY2xhc3M9XCJwLXQtNCBwLWItNCBkLWZsZXggc2VwYXJhdG9yLWJvdHRvbSB0ZXh0LW5vLXdyYXBcIj48bGFiZWwgY2xhc3M9XCJ0ZXh0LWxhYmVsLXNtYWxsIG0tYi0wIG0tci04XCI+TGluazwvbGFiZWw+PHNwYW4gY2xhc3M9XCJzbWFsbCBtLWwtYXV0b1wiPjxhIGhyZWY9XCIke2Jhc2VVcmx9Iy9hbGFybXMvJHthbGFybS5pZH1cIj5BbGFybSBEZXRhaWxzPC9hPjwvc3Bhbj48L2xpPmA7XG4gICAgfVxuICAgIHZhbHVlICs9IGA8bGkgY2xhc3M9XCJwLXQtNCBwLWItNCBkLWZsZXggdGV4dC1uby13cmFwXCI+PGxhYmVsIGNsYXNzPVwidGV4dC1sYWJlbC1zbWFsbCBtLWItMCBtLXItOFwiPkFsYXJtIGNvdW50PC9sYWJlbD48c3BhbiBjbGFzcz1cInNtYWxsIG0tbC1hdXRvXCI+PHNwYW4gY2xhc3M9XCJiYWRnZSBiYWRnZS1pbmZvXCI+JHthbGFybS5jb3VudH08L3NwYW4+PC9zcGFuPjwvbGk+YDtcbiAgICB2YWx1ZSArPSBgPC91bD5gO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYWxhcm1Sb3V0ZUV4aXN0cygpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBleGlzdHMgPSB0aGlzLnJvdXRlci5jb25maWcuc29tZShyb3V0ZSA9PiB7XG4gICAgICByZXR1cm4gYCR7cm91dGUucGF0aH1gID09PSAnYWxhcm1zJztcbiAgICB9KTtcbiAgICByZXR1cm4gZXhpc3RzO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDaGFydFNlcmllcyhcbiAgICBkYXRhcG9pbnRzV2l0aFZhbHVlczogRHBXaXRoVmFsdWVzW10sXG4gICAgZXZlbnRzOiBJRXZlbnRbXSxcbiAgICBhbGFybXM6IElBbGFybVtdLFxuICAgIGRpc3BsYXlPcHRpb25zOiB7IGRpc3BsYXlNYXJrZWRMaW5lOiBib29sZWFuOyBkaXNwbGF5TWFya2VkUG9pbnQ6IGJvb2xlYW4gfVxuICApOiBDdXN0b21TZXJpZXNPcHRpb25zW10gfCBTZXJpZXNPcHRpb25bXSB7XG4gICAgY29uc3Qgc2VyaWVzOiBTZXJpZXNPcHRpb25bXSA9IFtdO1xuICAgIGxldCBldmVudFNlcmllczogQ3VzdG9tU2VyaWVzT3B0aW9uc1tdID0gW107XG4gICAgbGV0IGFsYXJtU2VyaWVzOiBDdXN0b21TZXJpZXNPcHRpb25zW10gPSBbXTtcbiAgICBkYXRhcG9pbnRzV2l0aFZhbHVlcy5mb3JFYWNoKChkcCwgaWR4KSA9PiB7XG4gICAgICBjb25zdCByZW5kZXJUeXBlOiBEYXRhcG9pbnRDaGFydFJlbmRlclR5cGUgPSBkcC5yZW5kZXJUeXBlIHx8ICdtaW4nO1xuICAgICAgaWYgKHJlbmRlclR5cGUgPT09ICdhcmVhJykge1xuICAgICAgICBzZXJpZXMucHVzaCh0aGlzLmdldFNpbmdsZVNlcmllcyhkcCwgJ21pbicsIGlkeCwgdHJ1ZSkpO1xuICAgICAgICBzZXJpZXMucHVzaCh0aGlzLmdldFNpbmdsZVNlcmllcyhkcCwgJ21heCcsIGlkeCwgdHJ1ZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VyaWVzLnB1c2godGhpcy5nZXRTaW5nbGVTZXJpZXMoZHAsIHJlbmRlclR5cGUsIGlkeCwgZmFsc2UpKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbmV3RXZlbnRTZXJpZXMgPSB0aGlzLmdldEFsYXJtT3JFdmVudFNlcmllcyhcbiAgICAgICAgZHAsXG4gICAgICAgIHJlbmRlclR5cGUsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBldmVudHMsXG4gICAgICAgICdldmVudCcsXG4gICAgICAgIGRpc3BsYXlPcHRpb25zLFxuICAgICAgICBudWxsLFxuICAgICAgICBpZHhcbiAgICAgICk7XG4gICAgICBjb25zdCBuZXdBbGFybVNlcmllcyA9IHRoaXMuZ2V0QWxhcm1PckV2ZW50U2VyaWVzKFxuICAgICAgICBkcCxcbiAgICAgICAgcmVuZGVyVHlwZSxcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIGFsYXJtcyxcbiAgICAgICAgJ2FsYXJtJyxcbiAgICAgICAgZGlzcGxheU9wdGlvbnMsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGlkeFxuICAgICAgKTtcbiAgICAgIGV2ZW50U2VyaWVzID0gWy4uLmV2ZW50U2VyaWVzLCAuLi5uZXdFdmVudFNlcmllc107XG4gICAgICBhbGFybVNlcmllcyA9IFsuLi5hbGFybVNlcmllcywgLi4ubmV3QWxhcm1TZXJpZXNdO1xuICAgIH0pO1xuICAgIGNvbnN0IGRlZHVwbGljYXRlRmlsdGVyQ2FsbGJhY2sgPSAoXG4gICAgICBvYmoxOiBDdXN0b21TZXJpZXNPcHRpb25zLFxuICAgICAgaTogbnVtYmVyLFxuICAgICAgYXJyOiBTZXJpZXNPcHRpb25bXVxuICAgICk6IG9iajEgaXMgQ3VzdG9tU2VyaWVzT3B0aW9ucyA9PiB7XG4gICAgICBjb25zdCBkdXBsaWNhdGVzID0gYXJyLmZpbHRlcihvYmoyID0+IG9iajFbJ2lkJ10gPT09IG9iajJbJ2lkJ10gJiYgaSAhPT0gYXJyLmluZGV4T2Yob2JqMikpO1xuXG4gICAgICBpZiAoZHVwbGljYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBvYmoxWydpc0RwVGVtcGxhdGVTZWxlY3RlZCddIGFzIGJvb2xlYW47XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBjb25zdCBkZWR1cGxpY2F0ZUZpbHRlckNhbGxiYWNrRmFsbGJhY2sgPSAoXG4gICAgICBvYmoxOiBTZXJpZXNPcHRpb24sXG4gICAgICBpOiBudW1iZXIsXG4gICAgICBhcnI6IFNlcmllc09wdGlvbltdXG4gICAgKTogb2JqMSBpcyBTZXJpZXNPcHRpb24gPT4gYXJyLmZpbmRJbmRleChvYmoyID0+IG9iajJbJ2lkJ10gPT09IG9iajFbJ2lkJ10pID09PSBpO1xuXG4gICAgbGV0IGRlZHVwbGljYXRlZEV2ZW50cyA9IGV2ZW50U2VyaWVzLmZpbHRlcihkZWR1cGxpY2F0ZUZpbHRlckNhbGxiYWNrKTtcbiAgICBsZXQgZGVkdXBsaWNhdGVkQWxhcm1zID0gYWxhcm1TZXJpZXMuZmlsdGVyKGRlZHVwbGljYXRlRmlsdGVyQ2FsbGJhY2spO1xuICAgIGlmIChkZWR1cGxpY2F0ZWRBbGFybXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBkZWR1cGxpY2F0ZWRBbGFybXMgPSBhbGFybVNlcmllcy5maWx0ZXIoZGVkdXBsaWNhdGVGaWx0ZXJDYWxsYmFja0ZhbGxiYWNrKTtcbiAgICB9XG4gICAgaWYgKGRlZHVwbGljYXRlZEV2ZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGRlZHVwbGljYXRlZEV2ZW50cyA9IGV2ZW50U2VyaWVzLmZpbHRlcihkZWR1cGxpY2F0ZUZpbHRlckNhbGxiYWNrRmFsbGJhY2spO1xuICAgIH1cbiAgICByZXR1cm4gWy4uLnNlcmllcywgLi4uZGVkdXBsaWNhdGVkRXZlbnRzLCAuLi5kZWR1cGxpY2F0ZWRBbGFybXNdO1xuICB9XG5cbiAgcHJpdmF0ZSBncm91cEJ5VHlwZShcbiAgICBpdGVtczogSUFsYXJtW10gfCBJRXZlbnRbXSxcbiAgICB0eXBlRmllbGQ6IHN0cmluZ1xuICApOiBSZWNvcmQ8c3RyaW5nLCBJQWxhcm1bXSB8IElFdmVudFtdPiB7XG4gICAgcmV0dXJuIGl0ZW1zLnJlZHVjZSgoZ3JvdXBlZCwgaXRlbSkgPT4ge1xuICAgICAgKGdyb3VwZWRbaXRlbVt0eXBlRmllbGRdXSA9IGdyb3VwZWRbaXRlbVt0eXBlRmllbGRdXSB8fCBbXSkucHVzaChpdGVtKTtcbiAgICAgIHJldHVybiBncm91cGVkO1xuICAgIH0sIHt9IGFzIGFueSk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgaW50ZXJwb2xhdGVzIGJldHdlZW4gdHdvIGRhdGEgcG9pbnRzLiBUaGUgZ29hbCBpcyB0byBwbGFjZSB0aGUgbWFya1BvaW50IG9uIHRoZSBjaGFydCBpbiB0aGUgcmlnaHQgcGxhY2UuXG4gICAqIEBwYXJhbSBkcFZhbHVlc0FycmF5IGFycmF5IG9mIGRhdGEgcG9pbnRzXG4gICAqIEBwYXJhbSB0YXJnZXRUaW1lIHRpbWUgb2YgdGhlIGFsYXJtIG9yIGV2ZW50XG4gICAqIEByZXR1cm5zIGludGVycG9sYXRlZCBkYXRhIHBvaW50XG4gICAqL1xuICBwcml2YXRlIGludGVycG9sYXRlQmV0d2VlblR3b0RwcyhcbiAgICBkcFZhbHVlc0FycmF5OiBEcFZhbHVlc0l0ZW1bXSxcbiAgICB0YXJnZXRUaW1lOiBudW1iZXJcbiAgKTogRHBWYWx1ZXNJdGVtIHtcbiAgICBsZXQgbWF4VmFsdWU6IG51bWJlcjtcbiAgICBsZXQgbWluVmFsdWU6IG51bWJlcjtcbiAgICByZXR1cm4gZHBWYWx1ZXNBcnJheS5yZWR1Y2UoKGFjYywgY3VyciwgaWR4LCBhcnIpID0+IHtcbiAgICAgIGlmIChuZXcgRGF0ZShjdXJyLnRpbWUpLmdldFRpbWUoKSA8PSB0YXJnZXRUaW1lKSB7XG4gICAgICAgIGlmIChpZHggPT09IGFyci5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRpbWU6IHRhcmdldFRpbWUsXG4gICAgICAgICAgICB2YWx1ZXM6IFt7IG1pbjogbWluVmFsdWUsIG1heDogbWF4VmFsdWUgfV1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5leHREcCA9IGFycltpZHggKyAxXTtcbiAgICAgICAgaWYgKG5ldyBEYXRlKG5leHREcC50aW1lKS5nZXRUaW1lKCkgPj0gdGFyZ2V0VGltZSkge1xuICAgICAgICAgIGNvbnN0IHRpbWVEaWZmID0gbmV3IERhdGUobmV4dERwLnRpbWUpLmdldFRpbWUoKSAtIG5ldyBEYXRlKGN1cnIudGltZSkuZ2V0VGltZSgpO1xuICAgICAgICAgIGNvbnN0IHRhcmdldFRpbWVEaWZmID0gdGFyZ2V0VGltZSAtIG5ldyBEYXRlKGN1cnIudGltZSkuZ2V0VGltZSgpO1xuICAgICAgICAgIGNvbnN0IG1pblZhbHVlRGlmZiA9IG5leHREcC52YWx1ZXNbMF0/Lm1pbiAtIGN1cnIudmFsdWVzWzBdPy5taW47XG4gICAgICAgICAgY29uc3QgbWF4VmFsdWVEaWZmID0gbmV4dERwLnZhbHVlc1swXT8ubWF4IC0gY3Vyci52YWx1ZXNbMF0/Lm1heDtcbiAgICAgICAgICBtaW5WYWx1ZSA9IGN1cnIudmFsdWVzWzBdPy5taW4gKyAobWluVmFsdWVEaWZmICogdGFyZ2V0VGltZURpZmYpIC8gdGltZURpZmY7XG4gICAgICAgICAgbWF4VmFsdWUgPSBjdXJyLnZhbHVlc1swXT8ubWF4ICsgKG1heFZhbHVlRGlmZiAqIHRhcmdldFRpbWVEaWZmKSAvIHRpbWVEaWZmO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0aW1lOiB0YXJnZXRUaW1lLFxuICAgICAgICAgICAgdmFsdWVzOiBbeyBtaW46IG1pblZhbHVlLCBtYXg6IG1heFZhbHVlIH1dXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2xvc2VzdERwVmFsdWVUb1RhcmdldFRpbWUoXG4gICAgZHBWYWx1ZXNBcnJheTogRHBWYWx1ZXNJdGVtW10sXG4gICAgdGFyZ2V0VGltZTogbnVtYmVyXG4gICk6IERwVmFsdWVzSXRlbSB7XG4gICAgcmV0dXJuIGRwVmFsdWVzQXJyYXkucmVkdWNlKChwcmV2LCBjdXJyKSA9PlxuICAgICAgLy9zaG91bGQgdGFrZSB0aGUgdmFsdWUgY2xvc2VzdCB0byB0aGUgdGFyZ2V0IHRpbWUsIGZvciByZWFsdGltZSB0aGUgY3VycmVudCB0aW1lIHdvdWxkIGFsd2F5cyBjaGFuZ2VcbiAgICAgIE1hdGguYWJzKG5ldyBEYXRlKGN1cnIudGltZSkuZ2V0VGltZSgpIC0gdGFyZ2V0VGltZSkgPFxuICAgICAgTWF0aC5hYnMobmV3IERhdGUocHJldi50aW1lKS5nZXRUaW1lKCkgLSB0YXJnZXRUaW1lKVxuICAgICAgICA/IGN1cnJcbiAgICAgICAgOiBwcmV2XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgbWFya1BvaW50IG9uIHRoZSBjaGFydCB3aGljaCByZXByZXNlbnRzIHRoZSBpY29uIG9mIHRoZSBhbGFybSBvciBldmVudC5cbiAgICogQHBhcmFtIGl0ZW0gU2luZ2xlIGFsYXJtIG9yIGV2ZW50XG4gICAqIEBwYXJhbSBkcCBEYXRhIHBvaW50XG4gICAqIEBwYXJhbSBpc0NsZWFyZWQgSWYgdGhlIGFsYXJtIGlzIGNsZWFyZWQgaW4gY2FzZSBvZiBhbGFybVxuICAgKiBAcGFyYW0gaXNFdmVudCBJZiB0aGUgaXRlbSBpcyBhbiBldmVudFxuICAgKiBAcGFyYW0gcmVhbHRpbWUgSWYgdGhlIGNoYXJ0IGlzIGluIHJlYWx0aW1lIG1vZGVcbiAgICogQHJldHVybnMgTWFya1BvaW50RGF0YUl0ZW1PcHRpb25bXVxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVNYXJrUG9pbnQoXG4gICAgaXRlbTogSUFsYXJtIHwgSUV2ZW50LFxuICAgIGRwOiBEcFdpdGhWYWx1ZXMsXG4gICAgaXNDbGVhcmVkOiBib29sZWFuLFxuICAgIGlzRXZlbnQ6IGJvb2xlYW4sXG4gICAgcmVhbHRpbWU6IGJvb2xlYW5cbiAgKTogTWFya1BvaW50RGF0YVtdIHtcbiAgICAvLyBjaGVjayBpZiBkcC52YWx1ZXMgb2JqZWN0IGlzIGVtcHR5XG4gICAgaWYgKCFpdGVtLmNyZWF0aW9uVGltZSB8fCBPYmplY3Qua2V5cyhkcC52YWx1ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGRwVmFsdWVzQXJyYXk6IERwVmFsdWVzSXRlbVtdID0gT2JqZWN0LmVudHJpZXMoZHAudmFsdWVzKS5tYXAoKFt0aW1lLCB2YWx1ZXNdKSA9PiAoe1xuICAgICAgdGltZTogbmV3IERhdGUodGltZSkuZ2V0VGltZSgpLFxuICAgICAgdmFsdWVzXG4gICAgfSkpO1xuICAgIGNvbnN0IGNyZWF0aW9uVGltZSA9IG5ldyBEYXRlKGl0ZW0uY3JlYXRpb25UaW1lKS5nZXRUaW1lKCk7XG4gICAgY29uc3QgbGFzdFVwZGF0ZWRUaW1lID0gbmV3IERhdGUoaXRlbVsnbGFzdFVwZGF0ZWQnXSkuZ2V0VGltZSgpO1xuXG4gICAgbGV0IGNvb3JkQ3JlYXRpb25UaW1lOiBhbnk7XG4gICAgbGV0IGNvb3JkTGFzdFVwZGF0ZWRUaW1lOiBhbnk7XG5cbiAgICBpZiAocmVhbHRpbWUpIHtcbiAgICAgIGNvbnN0IGxhc3RWYWx1ZSA9IGRwVmFsdWVzQXJyYXlbZHBWYWx1ZXNBcnJheS5sZW5ndGggLSAxXTtcbiAgICAgIGNvb3JkQ3JlYXRpb25UaW1lID0gW1xuICAgICAgICBpdGVtLmNyZWF0aW9uVGltZSxcbiAgICAgICAgbGFzdFZhbHVlPy52YWx1ZXNbMF0/Lm1pbiA/PyBsYXN0VmFsdWU/LnZhbHVlc1sxXSA/PyBudWxsXG4gICAgICBdO1xuICAgICAgY29vcmRMYXN0VXBkYXRlZFRpbWUgPSBbXG4gICAgICAgIGl0ZW1bJ2xhc3RVcGRhdGVkJ10sXG4gICAgICAgIGxhc3RWYWx1ZT8udmFsdWVzWzBdPy5taW4gPz8gbGFzdFZhbHVlPy52YWx1ZXNbMV0gPz8gbnVsbFxuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY2xvc2VzdERwVmFsdWUgPSB0aGlzLmludGVycG9sYXRlQmV0d2VlblR3b0RwcyhkcFZhbHVlc0FycmF5LCBjcmVhdGlvblRpbWUpO1xuICAgICAgY29uc3QgZHBWYWx1ZXNGb3JOZXdBbGFybXMgPSB0aGlzLmdldENsb3Nlc3REcFZhbHVlVG9UYXJnZXRUaW1lKGRwVmFsdWVzQXJyYXksIGNyZWF0aW9uVGltZSk7XG4gICAgICBjb25zdCBjbG9zZXN0RHBWYWx1ZUxhc3RVcGRhdGVkID0gdGhpcy5pbnRlcnBvbGF0ZUJldHdlZW5Ud29EcHMoXG4gICAgICAgIGRwVmFsdWVzQXJyYXksXG4gICAgICAgIGxhc3RVcGRhdGVkVGltZVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGRwVmFsdWVzRm9yTmV3QWxhcm1zTGFzdFVwZGF0ZWQgPSB0aGlzLmdldENsb3Nlc3REcFZhbHVlVG9UYXJnZXRUaW1lKFxuICAgICAgICBkcFZhbHVlc0FycmF5LFxuICAgICAgICBsYXN0VXBkYXRlZFRpbWVcbiAgICAgICk7XG5cbiAgICAgIGNvb3JkQ3JlYXRpb25UaW1lID0gW1xuICAgICAgICBpdGVtLmNyZWF0aW9uVGltZSxcbiAgICAgICAgY2xvc2VzdERwVmFsdWU/LnZhbHVlc1swXT8ubWluID8/XG4gICAgICAgICAgY2xvc2VzdERwVmFsdWU/LnZhbHVlc1sxXSA/P1xuICAgICAgICAgIGRwVmFsdWVzRm9yTmV3QWxhcm1zPy52YWx1ZXNbMF0/Lm1pbiA/P1xuICAgICAgICAgIGRwVmFsdWVzRm9yTmV3QWxhcm1zPy52YWx1ZXNbMV0gPz9cbiAgICAgICAgICBudWxsXG4gICAgICBdO1xuICAgICAgY29vcmRMYXN0VXBkYXRlZFRpbWUgPSBbXG4gICAgICAgIGl0ZW1bJ2xhc3RVcGRhdGVkJ10sXG4gICAgICAgIGNsb3Nlc3REcFZhbHVlTGFzdFVwZGF0ZWQ/LnZhbHVlc1swXT8ubWluID8/XG4gICAgICAgICAgY2xvc2VzdERwVmFsdWVMYXN0VXBkYXRlZD8udmFsdWVzWzFdID8/XG4gICAgICAgICAgZHBWYWx1ZXNGb3JOZXdBbGFybXNMYXN0VXBkYXRlZD8udmFsdWVzWzBdPy5taW4gPz9cbiAgICAgICAgICBkcFZhbHVlc0Zvck5ld0FsYXJtc0xhc3RVcGRhdGVkPy52YWx1ZXNbMV0gPz9cbiAgICAgICAgICBudWxsXG4gICAgICBdO1xuICAgIH1cblxuICAgIGlmIChpc0V2ZW50KSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB7XG4gICAgICAgICAgY29vcmQ6IGNvb3JkQ3JlYXRpb25UaW1lLFxuICAgICAgICAgIG5hbWU6IGl0ZW0udHlwZSxcbiAgICAgICAgICBpdGVtVHlwZTogaXRlbS50eXBlLFxuICAgICAgICAgIGl0ZW1TdHlsZToge1xuICAgICAgICAgICAgY29sb3I6IGl0ZW1bJ2NvbG9yJ11cbiAgICAgICAgICB9LFxuICAgICAgICAgIHN5bWJvbDogJ2NpcmNsZScsXG4gICAgICAgICAgc3ltYm9sU2l6ZTogMjRcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGNvb3JkOiBjb29yZENyZWF0aW9uVGltZSxcbiAgICAgICAgICBuYW1lOiBpdGVtLnR5cGUsXG4gICAgICAgICAgaXRlbVR5cGU6IGl0ZW0udHlwZSxcbiAgICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6ICd3aGl0ZScgfSxcbiAgICAgICAgICBzeW1ib2w6IElDT05TX01BUC5FVkVOVCxcbiAgICAgICAgICBzeW1ib2xTaXplOiAxNlxuICAgICAgICB9XG4gICAgICBdO1xuICAgIH1cblxuICAgIHJldHVybiBpc0NsZWFyZWRcbiAgICAgID8gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvb3JkOiBjb29yZENyZWF0aW9uVGltZSxcbiAgICAgICAgICAgIG5hbWU6IGl0ZW0udHlwZSxcbiAgICAgICAgICAgIGl0ZW1UeXBlOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtU3R5bGU6IHtcbiAgICAgICAgICAgICAgY29sb3I6IGl0ZW1bJ2NvbG9yJ11cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgc3ltYm9sU2l6ZTogMjRcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvb3JkOiBjb29yZENyZWF0aW9uVGltZSxcbiAgICAgICAgICAgIG5hbWU6IGl0ZW0udHlwZSxcbiAgICAgICAgICAgIGl0ZW1UeXBlOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6ICd3aGl0ZScgfSxcbiAgICAgICAgICAgIHN5bWJvbDogSUNPTlNfTUFQW2l0ZW0uc2V2ZXJpdHkgYXMgU2V2ZXJpdHlUeXBlXSxcbiAgICAgICAgICAgIHN5bWJvbFNpemU6IDE2XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb29yZDogY29vcmRMYXN0VXBkYXRlZFRpbWUsXG4gICAgICAgICAgICBuYW1lOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtVHlwZTogaXRlbS50eXBlLFxuICAgICAgICAgICAgaXRlbVN0eWxlOiB7XG4gICAgICAgICAgICAgIGNvbG9yOiBpdGVtWydjb2xvciddXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3ltYm9sOiAnY2lyY2xlJyxcbiAgICAgICAgICAgIHN5bWJvbFNpemU6IDI0XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb29yZDogY29vcmRMYXN0VXBkYXRlZFRpbWUsXG4gICAgICAgICAgICBuYW1lOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtVHlwZTogaXRlbS50eXBlLFxuICAgICAgICAgICAgaXRlbVN0eWxlOiB7IGNvbG9yOiAnd2hpdGUnIH0sXG4gICAgICAgICAgICBzeW1ib2w6IElDT05TX01BUC5DTEVBUkVELFxuICAgICAgICAgICAgc3ltYm9sU2l6ZTogMTZcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvb3JkOiBjb29yZENyZWF0aW9uVGltZSxcbiAgICAgICAgICAgIG5hbWU6IGl0ZW0udHlwZSxcbiAgICAgICAgICAgIGl0ZW1UeXBlOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtU3R5bGU6IHtcbiAgICAgICAgICAgICAgY29sb3I6IGl0ZW1bJ2NvbG9yJ11cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgc3ltYm9sU2l6ZTogMjRcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvb3JkOiBjb29yZENyZWF0aW9uVGltZSxcbiAgICAgICAgICAgIG5hbWU6IGl0ZW0udHlwZSxcbiAgICAgICAgICAgIGl0ZW1UeXBlOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6ICd3aGl0ZScgfSxcbiAgICAgICAgICAgIHN5bWJvbDogSUNPTlNfTUFQW2l0ZW0uc2V2ZXJpdHkgYXMgU2V2ZXJpdHlUeXBlXSxcbiAgICAgICAgICAgIHN5bWJvbFNpemU6IDE2XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb29yZDogY29vcmRMYXN0VXBkYXRlZFRpbWUsXG4gICAgICAgICAgICBuYW1lOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtVHlwZTogaXRlbS50eXBlLFxuICAgICAgICAgICAgaXRlbVN0eWxlOiB7XG4gICAgICAgICAgICAgIGNvbG9yOiBpdGVtWydjb2xvciddXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3ltYm9sOiAnY2lyY2xlJyxcbiAgICAgICAgICAgIHN5bWJvbFNpemU6IDI0XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb29yZDogY29vcmRMYXN0VXBkYXRlZFRpbWUsXG4gICAgICAgICAgICBuYW1lOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBpdGVtVHlwZTogaXRlbS50eXBlLFxuICAgICAgICAgICAgaXRlbVN0eWxlOiB7IGNvbG9yOiAnd2hpdGUnIH0sXG4gICAgICAgICAgICBzeW1ib2w6IElDT05TX01BUFtpdGVtLnNldmVyaXR5IGFzIFNldmVyaXR5VHlwZV0sXG4gICAgICAgICAgICBzeW1ib2xTaXplOiAxNlxuICAgICAgICAgIH1cbiAgICAgICAgXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgbWFya0xpbmUgb24gdGhlIGNoYXJ0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGxpbmUgYmV0d2VlbiBldmVyeSBhbGFybSBvciBldmVudCBvbiB0aGUgY2hhcnQuXG4gICAqIEBwYXJhbSBpdGVtcyBBcnJheSBvZiBhbGFybXMgb3IgZXZlbnRzXG4gICAqIEByZXR1cm5zIE1hcmtMaW5lRGF0YUl0ZW1PcHRpb25CYXNlW11cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlTWFya0xpbmU8VCBleHRlbmRzIElBbGFybSB8IElFdmVudD4oaXRlbXM6IFRbXSk6IE1hcmtMaW5lRGF0YVtdIHtcbiAgICByZXR1cm4gaXRlbXMucmVkdWNlPE1hcmtMaW5lRGF0YVtdPigoYWNjLCBpdGVtKSA9PiB7XG4gICAgICBpZiAoIWl0ZW0uY3JlYXRpb25UaW1lKSB7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbS5jcmVhdGlvblRpbWUgPT09IGl0ZW1bJ2xhc3RVcGRhdGVkJ10pIHtcbiAgICAgICAgcmV0dXJuIGFjYy5jb25jYXQoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHhBeGlzOiBpdGVtLmNyZWF0aW9uVGltZSxcbiAgICAgICAgICAgIGl0ZW1UeXBlOiBpdGVtLnR5cGUsXG4gICAgICAgICAgICBsYWJlbDogeyBzaG93OiBmYWxzZSwgZm9ybWF0dGVyOiAoKSA9PiBpdGVtLnR5cGUgfSxcbiAgICAgICAgICAgIGl0ZW1TdHlsZTogeyBjb2xvcjogaXRlbVsnY29sb3InXSB9XG4gICAgICAgICAgfVxuICAgICAgICBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhY2MuY29uY2F0KFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB4QXhpczogaXRlbS5jcmVhdGlvblRpbWUsXG4gICAgICAgICAgICBpdGVtVHlwZTogaXRlbS50eXBlLFxuICAgICAgICAgICAgbGFiZWw6IHsgc2hvdzogZmFsc2UsIGZvcm1hdHRlcjogKCkgPT4gaXRlbS50eXBlIH0sXG4gICAgICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6IGl0ZW1bJ2NvbG9yJ10gfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgeEF4aXM6IGl0ZW1bJ2xhc3RVcGRhdGVkJ10sXG4gICAgICAgICAgICBpdGVtVHlwZTogaXRlbS50eXBlLFxuICAgICAgICAgICAgbGFiZWw6IHsgc2hvdzogZmFsc2UsIGZvcm1hdHRlcjogKCkgPT4gaXRlbS50eXBlIH0sXG4gICAgICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6IGl0ZW1bJ2NvbG9yJ10gfVxuICAgICAgICAgIH1cbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgfSwgW10pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTaW5nbGVTZXJpZXMoXG4gICAgZHA6IERwV2l0aFZhbHVlcyxcbiAgICByZW5kZXJUeXBlOiBFeGNsdWRlPERhdGFwb2ludENoYXJ0UmVuZGVyVHlwZSwgJ2FyZWEnPixcbiAgICBpZHg6IG51bWJlcixcbiAgICBpc01pbk1heENoYXJ0ID0gZmFsc2UsXG4gICAgc2VyaWVzVHlwZSA9ICcnXG4gICk6IFNlcmllc09wdGlvbiAmIFNlcmllc0RhdGFwb2ludEluZm8ge1xuICAgIGNvbnN0IGRhdGFwb2ludElkID0gZHAuX190YXJnZXQ/LmlkICsgZHAuZnJhZ21lbnQgKyBkcC5zZXJpZXM7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGFwb2ludElkLFxuICAgICAgZGF0YXBvaW50VW5pdDogZHAudW5pdCB8fCAnJyxcbiAgICAgIC8vICdpZCcgcHJvcGVydHkgaXMgbmVlZGVkIGFzICdzZXJpZXNJZCcgaW4gdG9vbHRpcCBmb3JtYXR0ZXJcbiAgICAgIGlkOiBpc01pbk1heENoYXJ0XG4gICAgICAgID8gYCR7ZGF0YXBvaW50SWR9LyR7cmVuZGVyVHlwZX0ke3Nlcmllc1R5cGV9YFxuICAgICAgICA6IGAke2RhdGFwb2ludElkfSR7c2VyaWVzVHlwZX1gLFxuICAgICAgbmFtZTogYCR7ZHAubGFiZWx9ICgke2RwLl9fdGFyZ2V0Py5bJ25hbWUnXX0pYCxcbiAgICAgIC8vIGRhdGFwb2ludExhYmVsIHVzZWQgdG8gcHJvcGVyIGRpc3BsYXkgb2YgdG9vbHRpcFxuICAgICAgZGF0YXBvaW50TGFiZWw6IGRwLmxhYmVsIHx8ICcnLFxuICAgICAgZGF0YTogT2JqZWN0LmVudHJpZXMoZHAudmFsdWVzKS5tYXAoKFtkYXRlU3RyaW5nLCB2YWx1ZXNdKSA9PiB7XG4gICAgICAgIHJldHVybiBbZGF0ZVN0cmluZywgdmFsdWVzWzBdW3JlbmRlclR5cGVdXTtcbiAgICAgIH0pLFxuICAgICAgeUF4aXNJbmRleDogaWR4LFxuICAgICAgLi4udGhpcy5jaGFydFR5cGVzU2VydmljZS5nZXRTZXJpZXNPcHRpb25zKGRwLCBpc01pbk1heENoYXJ0LCByZW5kZXJUeXBlKVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgY3JlYXRlcyBhIGdlbmVyYWwgdG9vbHRpcCBmb3JtYXR0ZXIgZm9yIHRoZSBjaGFydC5cbiAgICogQHJldHVybnMgVG9vbHRpcEZvcm1hdHRlckNhbGxiYWNrPFRvcExldmVsRm9ybWF0dGVyUGFyYW1zPlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRUb29sdGlwRm9ybWF0dGVyKCk6IFRvb2x0aXBGb3JtYXR0ZXJDYWxsYmFjazxUb3BMZXZlbEZvcm1hdHRlclBhcmFtcz4ge1xuICAgIHJldHVybiBwYXJhbXMgPT4ge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHBhcmFtcykgfHwgIXBhcmFtc1swXT8uZGF0YSkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG4gICAgICBjb25zdCBkYXRhID0gcGFyYW1zWzBdLmRhdGEgYXMgW3N0cmluZywgLi4uYW55W11dO1xuICAgICAgY29uc3QgWEF4aXNWYWx1ZTogc3RyaW5nID0gZGF0YVswXTtcbiAgICAgIGNvbnN0IFlBeGlzUmVhZGluZ3M6IHN0cmluZ1tdID0gW107XG4gICAgICBjb25zdCBhbGxTZXJpZXMgPSB0aGlzLmVjaGFydHNJbnN0YW5jZT8uZ2V0T3B0aW9uKClbJ3NlcmllcyddIGFzIEN1c3RvbVNlcmllc09wdGlvbnNbXTtcblxuICAgICAgY29uc3QgYWxsRGF0YVBvaW50U2VyaWVzID0gYWxsU2VyaWVzLmZpbHRlcihcbiAgICAgICAgc2VyaWVzID0+XG4gICAgICAgICAgc2VyaWVzWyd0eXBlT2ZTZXJpZXMnXSAhPT0gJ2FsYXJtJyAmJlxuICAgICAgICAgIHNlcmllc1sndHlwZU9mU2VyaWVzJ10gIT09ICdldmVudCcgJiZcbiAgICAgICAgICBzZXJpZXNbJ3R5cGVPZlNlcmllcyddICE9PSAnZmFrZSdcbiAgICAgICk7XG5cbiAgICAgIGFsbERhdGFQb2ludFNlcmllcy5mb3JFYWNoKChzZXJpZXM6IEN1c3RvbVNlcmllc09wdGlvbnMpID0+IHtcbiAgICAgICAgbGV0IHZhbHVlOiBzdHJpbmc7XG4gICAgICAgIGNvbnN0IGlkID0gc2VyaWVzWydpZCddIGFzIHN0cmluZztcbiAgICAgICAgaWYgKGlkLmVuZHNXaXRoKCcvbWluJykpIHtcbiAgICAgICAgICBjb25zdCBtaW5WYWx1ZSA9IHRoaXMuZmluZFZhbHVlRm9yRXhhY3RPckVhcmxpZXJUaW1lc3RhbXAoXG4gICAgICAgICAgICBzZXJpZXNbJ2RhdGEnXSBhcyBTZXJpZXNWYWx1ZVtdLFxuICAgICAgICAgICAgWEF4aXNWYWx1ZVxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFtaW5WYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBtYXhTZXJpZXMgPSBhbGxEYXRhUG9pbnRTZXJpZXMuZmluZChzID0+IHNbJ2lkJ10gPT09IGlkLnJlcGxhY2UoJy9taW4nLCAnL21heCcpKTtcbiAgICAgICAgICBpZiAoIW1heFNlcmllcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBtYXhWYWx1ZSA9IHRoaXMuZmluZFZhbHVlRm9yRXhhY3RPckVhcmxpZXJUaW1lc3RhbXAoXG4gICAgICAgICAgICBtYXhTZXJpZXNbJ2RhdGEnXSBhcyBTZXJpZXNWYWx1ZVtdLFxuICAgICAgICAgICAgWEF4aXNWYWx1ZVxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKG1heFZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhbHVlID1cbiAgICAgICAgICAgIGA8ZGl2IGNsYXNzPVwiZC1mbGV4IGEtaS1jZW50ZXIgc2VwYXJhdG9yLXRvcCBwLXQtOCBwLWItOFwiPmAgK1xuICAgICAgICAgICAgYDxsYWJlbCBjbGFzcz1cInRleHQtMTIgbS1yLTggbS1iLTBcIj4ke3RoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKG1pblZhbHVlWzBdKX08L2xhYmVsPmAgK1xuICAgICAgICAgICAgYDxkaXYgY2xhc3M9XCJtLWwtYXV0byB0ZXh0LTEyXCIgPiR7bWluVmFsdWVbMV19IOKAlCAke21heFZhbHVlWzFdfWAgK1xuICAgICAgICAgICAgKHNlcmllc1snZGF0YXBvaW50VW5pdCddID8gYCAke3Nlcmllc1snZGF0YXBvaW50VW5pdCddfWAgOiAnJykgK1xuICAgICAgICAgICAgYDwvZGl2PjwvZGl2PmA7XG4gICAgICAgIH0gZWxzZSBpZiAoaWQuZW5kc1dpdGgoJy9tYXgnKSkge1xuICAgICAgICAgIC8vIGRvIG5vdGhpbmcsIHZhbHVlIGlzIGhhbmRsZWQgIGluICdtaW4nIGNhc2VcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc2VyaWVzVmFsdWUgPSB0aGlzLmZpbmRWYWx1ZUZvckV4YWN0T3JFYXJsaWVyVGltZXN0YW1wKFxuICAgICAgICAgICAgc2VyaWVzWydkYXRhJ10gYXMgU2VyaWVzVmFsdWVbXSxcbiAgICAgICAgICAgIFhBeGlzVmFsdWVcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmICghc2VyaWVzVmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFsdWUgPVxuICAgICAgICAgICAgYDxkaXYgY2xhc3M9XCJkLWZsZXggYS1pLWNlbnRlciBzZXBhcmF0b3ItdG9wIHAtdC04IHAtYi04XCI+YCArXG4gICAgICAgICAgICBgPGxhYmVsIGNsYXNzPVwidGV4dC0xMiBtLXItOCBtLWItMFwiPiR7dGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0oc2VyaWVzVmFsdWVbMF0pfTwvbGFiZWw+YCArXG4gICAgICAgICAgICBgPGRpdiBjbGFzcz1cIm0tbC1hdXRvIHRleHQtMTJcIiA+JHtzZXJpZXNWYWx1ZVsxXT8udG9TdHJpbmcoKX1gICtcbiAgICAgICAgICAgIChzZXJpZXNbJ2RhdGFwb2ludFVuaXQnXSA/IGAgJHtzZXJpZXNbJ2RhdGFwb2ludFVuaXQnXX1gIDogJycpICtcbiAgICAgICAgICAgIGA8L2Rpdj48L2Rpdj5gO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXRlbVN0eWxlID0gc2VyaWVzWydpdGVtU3R5bGUnXSBhcyB7IGNvbG9yOiBzdHJpbmcgfTtcblxuICAgICAgICBZQXhpc1JlYWRpbmdzLnB1c2goXG4gICAgICAgICAgYDxkaXYgY2xhc3M9XCJkLWZsZXggYS1pLWNlbnRlciBwLWItOFwiPjxzcGFuIGNsYXNzPSdkbHQtYzh5LWljb24tY2lyY2xlIG0tci00JyBzdHlsZT0nY29sb3I6ICR7aXRlbVN0eWxlLmNvbG9yfSc+PC9zcGFuPmAgKyAvLyBjb2xvciBjaXJjbGVcbiAgICAgICAgICAgIGA8c3Ryb25nPiR7c2VyaWVzWydkYXRhcG9pbnRMYWJlbCddfSA8L3N0cm9uZz48L2Rpdj5gICsgLy8gbmFtZVxuICAgICAgICAgICAgYCR7dmFsdWV9YCAvLyBzaW5nbGUgdmFsdWUgb3IgbWluLW1heCByYW5nZVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBgPGRpdiBzdHlsZT1cIndpZHRoOiAke3RoaXMuVE9PTFRJUF9XSURUSH1weFwiPiR7WUF4aXNSZWFkaW5ncy5qb2luKCcnKX08L2Rpdj5gO1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGZpbmRWYWx1ZUZvckV4YWN0T3JFYXJsaWVyVGltZXN0YW1wKFxuICAgIHZhbHVlczogU2VyaWVzVmFsdWVbXSxcbiAgICB0aW1lc3RhbXBTdHJpbmc6IERhdGVTdHJpbmdcbiAgKTogU2VyaWVzVmFsdWUgfCBudWxsIHtcbiAgICBjb25zdCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSh0aW1lc3RhbXBTdHJpbmcpLnZhbHVlT2YoKTtcbiAgICByZXR1cm4gdmFsdWVzLnJlZHVjZSgoYWNjOiBTZXJpZXNWYWx1ZSB8IG51bGwsIGN1cnI6IFNlcmllc1ZhbHVlKSA9PiB7XG4gICAgICBpZiAobmV3IERhdGUoY3VyclswXSkudmFsdWVPZigpIDw9IHRpbWVzdGFtcCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgYWNjID09PSBudWxsIHx8XG4gICAgICAgICAgTWF0aC5hYnMobmV3IERhdGUoY3VyclswXSkudmFsdWVPZigpIC0gdGltZXN0YW1wKSA8XG4gICAgICAgICAgICBNYXRoLmFicyhuZXcgRGF0ZShhY2NbMF0pLnZhbHVlT2YoKSAtIHRpbWVzdGFtcClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgbnVsbCk7XG4gIH1cbn1cbiJdfQ==
|