gamma-app-controller 1.1.25 → 1.1.27
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/esm2020/lib/application-controller/application-controller.module.mjs +20 -20
- package/esm2020/lib/application-controller/application-dataset-component/application-dataset/application-dataset.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-filter/application-filter.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-menu-controller/application-menus/application-menus.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-metric-config/all-metrics-config/all-metrics-config.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-metric-config/create-metrics/create-metrics.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-view-components/application-views/application-views.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.mjs +1 -1
- package/esm2020/lib/application-controller/page-controller/page-config/page-config.component.mjs +11 -11
- package/esm2020/lib/application-controller/page-controller/page-config-multi-layout/page-config-multi-layout.component.mjs +10 -10
- package/esm2020/lib/application-controller/page-controller/page-controller/page-controller.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/dash-chart/dash-chart.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/dash-table/dash-table.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/dash-today-previous/dash-today-previous.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/geo-map/geo-map.component.mjs +2 -2
- package/esm2020/lib/application-controller/support-components/heat-map/heat-map.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/single-card/single-card.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/table-with-bar/table-with-bar.component.mjs +2 -2
- package/esm2020/lib/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +116 -0
- package/esm2020/lib/shared/advanced-component/app-advance-header/app-header.component.mjs +306 -0
- package/esm2020/lib/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +80 -0
- package/esm2020/lib/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +379 -0
- package/esm2020/lib/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +188 -0
- package/esm2020/lib/shared/advanced-component/gamma-geo-chart/gamma-geo-chart.component.mjs +435 -0
- package/esm2020/lib/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.mjs +334 -0
- package/esm2020/lib/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +155 -0
- package/esm2020/lib/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +20 -0
- package/esm2020/lib/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +187 -0
- package/esm2020/lib/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +86 -0
- package/esm2020/lib/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +439 -0
- package/esm2020/lib/shared/app-title/app-title.component.mjs +67 -0
- package/esm2020/lib/shared/gamam-widget/gamam-widget.component.mjs +35 -0
- package/esm2020/lib/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +273 -0
- package/esm2020/lib/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +142 -0
- package/esm2020/lib/shared/kpi-comon-service.mjs +537 -0
- package/esm2020/lib/{application-controller/shared → shared}/loader/loader.component.mjs +1 -1
- package/esm2020/lib/{application-controller/shared → shared}/loading/loading.component.mjs +1 -1
- package/esm2020/lib/shared/loading/loadingModule.mjs +28 -0
- package/esm2020/lib/shared/safeHtmlPipe.mjs +20 -0
- package/esm2020/lib/template-module/KpiCreationModule/create-kpi-tree.component.mjs +381 -0
- package/esm2020/lib/template-module/KpiCreationModule/createKpi.service.mjs +90 -0
- package/esm2020/lib/template-module/KpiCreationModule/kpiCreation.module.mjs +184 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animation.mjs +15 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/defaults.mjs +12 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/expand-collapse.mjs +16 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/fade.mjs +160 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/shake.mjs +58 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/slide.mjs +116 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/zoom.mjs +36 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/aside/aside.component.mjs +85 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/basic/basic.component.mjs +118 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/collapsable/collapsable.component.mjs +159 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/divider/divider.component.mjs +27 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/group/group.component.mjs +37 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/spacer/spacer.component.mjs +27 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/moment-helper.mjs +4 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/treeview-navigation.service.mjs +2 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/treeview-shared.service.mjs +16 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/treeview.component.mjs +134 -0
- package/esm2020/lib/template-module/bookmarked-template/bookmarked-template.component.mjs +816 -0
- package/esm2020/lib/template-module/bookmarked-template/bookmarkedTemplate.module.mjs +149 -0
- package/esm2020/lib/template-module/cdrConfigModule/cdr-config.component.mjs +1 -1
- package/esm2020/lib/template-module/cdrConfigModule/cdrConfig.module.mjs +2 -2
- package/esm2020/lib/template-module/defaulLandingComponent/defaultLandingComponent.module.mjs +149 -0
- package/esm2020/lib/template-module/defaulLandingComponent/landing-component.component.mjs +870 -0
- package/esm2020/lib/template-module/exceptionConfigModule/exception-operation.component.mjs +1 -1
- package/esm2020/lib/template-module/exceptionConfigModule/exceptionConfig.module.mjs +2 -2
- package/esm2020/lib/template-module/kpiWithMultiLayout/dynamin-modal-multi.component.mjs +180 -0
- package/esm2020/lib/template-module/kpiWithMultiLayout/kpi-with-multilayout.component.mjs +992 -0
- package/esm2020/lib/template-module/kpiWithMultiLayout/kpiWithMultiayout.module.mjs +154 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.mjs +180 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.mjs +1046 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/kpiWithSingleLayout.module.mjs +154 -0
- package/esm2020/public-api.mjs +39 -20
- package/fesm2015/gamma-app-controller.mjs +6750 -475
- package/fesm2015/gamma-app-controller.mjs.map +1 -1
- package/fesm2020/gamma-app-controller.mjs +6709 -475
- package/fesm2020/gamma-app-controller.mjs.map +1 -1
- package/lib/application-controller/application-controller.module.d.ts +19 -19
- package/lib/application-controller/page-controller/page-config/page-config.component.d.ts +9 -9
- package/lib/application-controller/page-controller/page-config-multi-layout/page-config-multi-layout.component.d.ts +8 -8
- package/lib/{application-controller/shared → shared}/advanced-component/app-advance-header/app-header.component.d.ts +18 -2
- package/lib/{application-controller/shared → shared}/advanced-component/gamm-single-number-card/gamm-single-number-card.component.d.ts +3 -5
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-advance-chart/gamma-advance-chart.component.d.ts +3 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.d.ts +4 -2
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-geo-chart/gamma-geo-chart.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-heatmap/gamma-heatmap.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.d.ts +6 -2
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-today-previous/gamma-today-previous.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/google-geo-map/google-geo-map.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/app-title/app-title.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/gamam-widget/gamam-widget.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/gamma-advance-filter/gamma-advance-filter.component.d.ts +3 -2
- package/lib/{application-controller/shared → shared}/gamma-bread-crumbs/bread-crumbs.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/kpi-comon-service.d.ts +1 -1
- package/lib/template-module/KpiCreationModule/create-kpi-tree.component.d.ts +75 -0
- package/lib/template-module/KpiCreationModule/createKpi.service.d.ts +32 -0
- package/lib/template-module/KpiCreationModule/kpiCreation.module.d.ts +23 -0
- package/lib/template-module/KpiCreationModule/treeview/animation.d.ts +1 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/defaults.d.ts +11 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/expand-collapse.d.ts +2 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/fade.d.ts +11 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/shake.d.ts +2 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/slide.d.ts +9 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/zoom.d.ts +3 -0
- package/lib/template-module/KpiCreationModule/treeview/components/aside/aside.component.d.ts +26 -0
- package/lib/template-module/KpiCreationModule/treeview/components/basic/basic.component.d.ts +29 -0
- package/lib/template-module/KpiCreationModule/treeview/components/collapsable/collapsable.component.d.ts +37 -0
- package/lib/template-module/KpiCreationModule/treeview/components/divider/divider.component.d.ts +13 -0
- package/lib/template-module/KpiCreationModule/treeview/components/group/group.component.d.ts +17 -0
- package/lib/template-module/KpiCreationModule/treeview/components/spacer/spacer.component.d.ts +13 -0
- package/lib/template-module/KpiCreationModule/treeview/moment-helper.d.ts +3 -0
- package/lib/template-module/KpiCreationModule/treeview/treeview-navigation.service.d.ts +39 -0
- package/lib/template-module/KpiCreationModule/treeview/treeview-shared.service.d.ts +8 -0
- package/lib/template-module/KpiCreationModule/treeview/treeview.component.d.ts +52 -0
- package/lib/template-module/bookmarked-template/bookmarked-template.component.d.ts +109 -0
- package/lib/template-module/bookmarked-template/bookmarkedTemplate.module.d.ts +16 -0
- package/lib/template-module/cdrConfigModule/cdrConfig.module.d.ts +1 -1
- package/lib/template-module/defaulLandingComponent/defaultLandingComponent.module.d.ts +16 -0
- package/lib/template-module/defaulLandingComponent/landing-component.component.d.ts +109 -0
- package/lib/template-module/exceptionConfigModule/exceptionConfig.module.d.ts +1 -1
- package/lib/template-module/kpiWithMultiLayout/dynamin-modal-multi.component.d.ts +42 -0
- package/lib/template-module/kpiWithMultiLayout/kpi-with-multilayout.component.d.ts +117 -0
- package/lib/template-module/kpiWithMultiLayout/kpiWithMultiayout.module.d.ts +17 -0
- package/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.d.ts +42 -0
- package/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.d.ts +122 -0
- package/lib/template-module/kpiWithSingleLayout/kpiWithSingleLayout.module.d.ts +17 -0
- package/package.json +1 -1
- package/public-api.d.ts +38 -19
- package/esm2020/lib/application-controller/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +0 -124
- package/esm2020/lib/application-controller/shared/advanced-component/app-advance-header/app-header.component.mjs +0 -220
- package/esm2020/lib/application-controller/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +0 -95
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +0 -362
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +0 -177
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-geo-chart/gamma-geo-chart.component.mjs +0 -441
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.mjs +0 -328
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +0 -155
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +0 -20
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +0 -157
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +0 -85
- package/esm2020/lib/application-controller/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +0 -439
- package/esm2020/lib/application-controller/shared/app-title/app-title.component.mjs +0 -67
- package/esm2020/lib/application-controller/shared/gamam-widget/gamam-widget.component.mjs +0 -35
- package/esm2020/lib/application-controller/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +0 -237
- package/esm2020/lib/application-controller/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +0 -142
- package/esm2020/lib/application-controller/shared/kpi-comon-service.mjs +0 -537
- package/esm2020/lib/application-controller/shared/loading/loadingModule.mjs +0 -28
- package/esm2020/lib/application-controller/shared/safeHtmlPipe.mjs +0 -20
- /package/lib/{application-controller/shared → shared}/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-with-percentage/contentSafeHtml.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/loader/loader.component.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/loading/loading.component.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/loading/loadingModule.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/safeHtmlPipe.d.ts +0 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import moment from '../../../application-controller/moment-helper';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "../../../application-controller/common";
|
|
5
|
+
import * as i2 from "@angular/common";
|
|
6
|
+
import * as i3 from "@angular/material/tooltip";
|
|
7
|
+
import * as i4 from "../../loader/loader.component";
|
|
8
|
+
export class GammaHeatChartComponent {
|
|
9
|
+
constructor(commonService) {
|
|
10
|
+
this.commonService = commonService;
|
|
11
|
+
this.dataSourseForTable = [];
|
|
12
|
+
this.isLoader = true;
|
|
13
|
+
this.tableDataConfig = {};
|
|
14
|
+
this.enrichNameList = ["formatBytes", "formatBytsToKb", "formatBytsToGb", "reformatNumberWithThousandSeparatorV3", "formatBytesv2"];
|
|
15
|
+
this.activeTab = 'basic';
|
|
16
|
+
this.isAdvanceFilter = false;
|
|
17
|
+
this.isHeatMapClick = false;
|
|
18
|
+
this.heatChartDataSource = {};
|
|
19
|
+
this.chartDataForTooltip = {};
|
|
20
|
+
this.dataSourseForHeatMap = [];
|
|
21
|
+
this.viewProperties = {
|
|
22
|
+
enableClickEvent: false,
|
|
23
|
+
enableRightClickEvent: true,
|
|
24
|
+
clickEventOptions: {
|
|
25
|
+
associatedViews: [],
|
|
26
|
+
eventType: ""
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
this.optionalDrilDownDataSource = [];
|
|
30
|
+
this.allConfiguredViews = [];
|
|
31
|
+
this.colorArray = [];
|
|
32
|
+
this.firstColor = "rgba(45, 110, 18, 1)";
|
|
33
|
+
this.secondColor = "rgba(255, 204, 0, 1)";
|
|
34
|
+
this.singleColor = "rgba(255, 204, 0, 1)";
|
|
35
|
+
this.heatmapChartConfig = {};
|
|
36
|
+
this.getTableConfigOutPut = new EventEmitter();
|
|
37
|
+
this.oRowClick = new EventEmitter();
|
|
38
|
+
this.onrightClickContextSelection = new EventEmitter();
|
|
39
|
+
this.rightClickEnable = true;
|
|
40
|
+
}
|
|
41
|
+
set chartDataSource(value) {
|
|
42
|
+
if (value === undefined || value.length === 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.isLoader = true;
|
|
47
|
+
this.page_config = value;
|
|
48
|
+
this.page_parms = value.titleParams;
|
|
49
|
+
if (value.kpiConfig.dataSource && value.kpiConfig.dataSource.length !== 0) {
|
|
50
|
+
this.heatmapChartConfig = value.kpiConfig.dataConfig;
|
|
51
|
+
this.colorArray = value.kpiConfig.dataConfig.color;
|
|
52
|
+
this.getHeatmapData(value.kpiConfig.dataSource);
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
this.isLoader = false;
|
|
55
|
+
}, 200);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
this.dataSourseForTable = [];
|
|
60
|
+
this.tableDataConfig['columns'] = [];
|
|
61
|
+
this.isLoader = false;
|
|
62
|
+
}, 200);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
ngOnInit() {
|
|
67
|
+
}
|
|
68
|
+
getHeatmapData(heatMapData) {
|
|
69
|
+
debugger;
|
|
70
|
+
this.heatChartDataSource = {};
|
|
71
|
+
this.isAdvanceFilter = false;
|
|
72
|
+
if (heatMapData && heatMapData.length !== 0) {
|
|
73
|
+
if (this.heatmapChartConfig.chartFormat == "topx") {
|
|
74
|
+
const { result, uniqueDates } = this.generateDateWiseColorCodedData(heatMapData);
|
|
75
|
+
this.heatChartDataSource.dataSet = this.getTransposedHeatmapData(result);
|
|
76
|
+
this.heatChartDataSource["argumentValue"] = uniqueDates;
|
|
77
|
+
}
|
|
78
|
+
else if ((this.heatmapChartConfig.chartFormat == "simple")) {
|
|
79
|
+
const { result, uniqueDates } = this.generateData(heatMapData);
|
|
80
|
+
this.heatChartDataSource["dataSet"] = result;
|
|
81
|
+
this.heatChartDataSource["argumentValue"] = uniqueDates;
|
|
82
|
+
}
|
|
83
|
+
this.isHeatMapClick = false;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.isHeatMapClick = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
getTransposedHeatmapData(dataSet) {
|
|
90
|
+
const transposed = [];
|
|
91
|
+
const maxBoxes = Math.max(...dataSet.map(item => item.dataset.length));
|
|
92
|
+
for (let i = 0; i < maxBoxes; i++) {
|
|
93
|
+
const row = [];
|
|
94
|
+
for (let j = 0; j < dataSet.length; j++) {
|
|
95
|
+
const box = dataSet[j].dataset[i];
|
|
96
|
+
row.push({
|
|
97
|
+
box: box || null,
|
|
98
|
+
date: dataSet[j].record_date
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
transposed.push(row);
|
|
102
|
+
}
|
|
103
|
+
return transposed;
|
|
104
|
+
}
|
|
105
|
+
generateDateWiseColorCodedData(data) {
|
|
106
|
+
const result = [];
|
|
107
|
+
const uniqueDates = new Set();
|
|
108
|
+
const allEntries = [];
|
|
109
|
+
const topArg = this.heatmapChartConfig.topArgument;
|
|
110
|
+
const leftArg = this.heatmapChartConfig.leftArgument;
|
|
111
|
+
const valueField = this.heatmapChartConfig.columns[0].dataField;
|
|
112
|
+
data.forEach(entry => {
|
|
113
|
+
const formattedDate = (moment(entry[topArg]).format('YYYY-MM-DD')) ? moment(entry[topArg]).format('YYYY-MM-DD') : topArg;
|
|
114
|
+
uniqueDates.add(formattedDate);
|
|
115
|
+
entry.resultDataset.forEach(item => {
|
|
116
|
+
allEntries.push({
|
|
117
|
+
[topArg]: formattedDate,
|
|
118
|
+
[leftArg]: item[`${leftArg}`],
|
|
119
|
+
[valueField]: item[`${valueField}`]
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
let coloredData;
|
|
124
|
+
if (this.heatmapChartConfig.type === 'gradient') {
|
|
125
|
+
coloredData = this.getFormateDataByColorCodeForGradient(allEntries, valueField);
|
|
126
|
+
}
|
|
127
|
+
else if (this.heatmapChartConfig.type === 'twoColor') {
|
|
128
|
+
coloredData = this.getFormateDataByColorCodeForWithTwoColor(allEntries, valueField);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
coloredData = this.getFormateDataByColorCodeForWithSingleColor(allEntries, valueField);
|
|
132
|
+
}
|
|
133
|
+
const dateMap = {};
|
|
134
|
+
coloredData.forEach(item => {
|
|
135
|
+
const date = item[topArg];
|
|
136
|
+
if (!dateMap[date]) {
|
|
137
|
+
dateMap[date] = [];
|
|
138
|
+
}
|
|
139
|
+
let toolTip = `Record Date : ${item[topArg]} \n${this.commonService.convertString(valueField)} : ${this.commonService.ThousandSeparatorWithTwoDecimals(item[valueField])}`;
|
|
140
|
+
dateMap[date].push({
|
|
141
|
+
[leftArg]: item[leftArg],
|
|
142
|
+
[valueField]: item[valueField],
|
|
143
|
+
color: item.color,
|
|
144
|
+
toolTip: toolTip,
|
|
145
|
+
[topArg]: date,
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
const sortedDates = Array.from(uniqueDates).sort((a, b) => moment(b).diff(moment(a)));
|
|
149
|
+
for (const date of sortedDates) {
|
|
150
|
+
result.push({
|
|
151
|
+
record_date: date,
|
|
152
|
+
dataset: dateMap[date] || []
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
result,
|
|
157
|
+
uniqueDates: sortedDates
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
generateData(data) {
|
|
161
|
+
const result = [];
|
|
162
|
+
const uniqueDates = new Set();
|
|
163
|
+
const dataSourceMap = {};
|
|
164
|
+
const topArg = this.heatmapChartConfig.topArgument;
|
|
165
|
+
const leftArg = this.heatmapChartConfig.leftArgument;
|
|
166
|
+
const valueField = this.heatmapChartConfig.columns[0].dataField;
|
|
167
|
+
data.forEach(item => {
|
|
168
|
+
const rowKey = item[leftArg];
|
|
169
|
+
const columnKey = moment(item[topArg]).format('YYYY-MM-DD');
|
|
170
|
+
if (!dataSourceMap[rowKey]) {
|
|
171
|
+
dataSourceMap[rowKey] = {
|
|
172
|
+
datasource: rowKey,
|
|
173
|
+
dataset: []
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
let toolTip = `${this.commonService.convertString(leftArg)} : ${item[leftArg]} \nRecord Date : ${columnKey} \n${this.commonService.convertString(valueField)} : ${this.commonService.ThousandSeparatorWithTwoDecimals(item[valueField])}`;
|
|
177
|
+
dataSourceMap[rowKey].dataset.push({
|
|
178
|
+
...item,
|
|
179
|
+
toolTip: toolTip,
|
|
180
|
+
[topArg]: columnKey,
|
|
181
|
+
});
|
|
182
|
+
uniqueDates.add(columnKey);
|
|
183
|
+
});
|
|
184
|
+
const uniqueDatesArray = Array.from(uniqueDates);
|
|
185
|
+
for (const key in dataSourceMap) {
|
|
186
|
+
const dataset = dataSourceMap[key].dataset;
|
|
187
|
+
let formattedDataset;
|
|
188
|
+
if (this.heatmapChartConfig.type == "gradient") {
|
|
189
|
+
formattedDataset = this.getFormateDataByColorCodeForGradient(dataset, this.heatmapChartConfig.columns[0].dataField);
|
|
190
|
+
}
|
|
191
|
+
else if (this.heatmapChartConfig.type == "twoColor") {
|
|
192
|
+
formattedDataset = this.getFormateDataByColorCodeForWithTwoColor(dataset, this.heatmapChartConfig.columns[0].dataField);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
formattedDataset = this.getFormateDataByColorCodeForWithSingleColor(dataset, this.heatmapChartConfig.columns[0].dataField);
|
|
196
|
+
}
|
|
197
|
+
const dateToItemMap = {};
|
|
198
|
+
formattedDataset.forEach(item => {
|
|
199
|
+
dateToItemMap[item[topArg]] = item;
|
|
200
|
+
});
|
|
201
|
+
const completeDataset = uniqueDatesArray.map((date) => {
|
|
202
|
+
if (dateToItemMap[date]) {
|
|
203
|
+
return dateToItemMap[date];
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
return {
|
|
207
|
+
[topArg]: date,
|
|
208
|
+
avgSize: "No Data",
|
|
209
|
+
fileCount: 0,
|
|
210
|
+
fileSize: 0,
|
|
211
|
+
color: "rgb(242, 118, 109)"
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
result.push({
|
|
216
|
+
datasource: key,
|
|
217
|
+
dataset: completeDataset
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
result: result,
|
|
222
|
+
uniqueDates: uniqueDatesArray
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
getFormateDataByColorCodeForGradient(filedata, column) {
|
|
226
|
+
filedata.forEach(item => {
|
|
227
|
+
item.avgSize = parseFloat(item[column]);
|
|
228
|
+
});
|
|
229
|
+
const maxAvgSize = Math.max(...filedata.map(item => item[column]));
|
|
230
|
+
const minAvgSize = Math.min(...filedata.map(item => item[column]));
|
|
231
|
+
const [minColorStr, maxColorStr] = this.colorArray || ["rgba(45, 110, 18,1)", "rgba(255, 204, 0,1)"];
|
|
232
|
+
const minColor = this.parseRGBA(minColorStr);
|
|
233
|
+
const maxColor = this.parseRGBA(maxColorStr);
|
|
234
|
+
filedata.forEach(item => {
|
|
235
|
+
item.color = this.calculateColor(item[column], minAvgSize, maxAvgSize, minColor, maxColor);
|
|
236
|
+
});
|
|
237
|
+
return filedata;
|
|
238
|
+
}
|
|
239
|
+
getFormateDataByColorCodeForWithTwoColor(filedata, column) {
|
|
240
|
+
filedata.forEach(item => {
|
|
241
|
+
item[column] = parseFloat(item[column]);
|
|
242
|
+
});
|
|
243
|
+
const [minColorStr, maxColorStr] = this.colorArray || ["rgba(45, 110, 18,1)", "rgba(255, 204, 0,1)"];
|
|
244
|
+
const minColor = this.parseRGBA(minColorStr);
|
|
245
|
+
const maxColor = this.parseRGBA(maxColorStr);
|
|
246
|
+
filedata.forEach(item => {
|
|
247
|
+
if (item[column] == 0) {
|
|
248
|
+
item.color = `rgb(${minColor.join(',')})`;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
item.color = `rgb(${maxColor.join(',')})`;
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
return filedata;
|
|
255
|
+
}
|
|
256
|
+
getFormateDataByColorCodeForWithSingleColor(filedata, column) {
|
|
257
|
+
filedata.forEach(item => {
|
|
258
|
+
item[column] = parseFloat(item[column]);
|
|
259
|
+
});
|
|
260
|
+
const [singleColor] = this.colorArray || ["rgba(255, 204, 0,1)"];
|
|
261
|
+
const minColor = this.parseRGBA(singleColor);
|
|
262
|
+
filedata.forEach(item => {
|
|
263
|
+
item.color = `rgb(${minColor.join(',')})`;
|
|
264
|
+
});
|
|
265
|
+
return filedata;
|
|
266
|
+
}
|
|
267
|
+
parseRGBA(colorStr) {
|
|
268
|
+
const values = colorStr.match(/[\d.]+/g)?.map(Number) || [];
|
|
269
|
+
if (values.length === 3)
|
|
270
|
+
values.push(1);
|
|
271
|
+
return [
|
|
272
|
+
values[0] ?? 0,
|
|
273
|
+
values[1] ?? 0,
|
|
274
|
+
values[2] ?? 0,
|
|
275
|
+
values[3] ?? 1
|
|
276
|
+
];
|
|
277
|
+
}
|
|
278
|
+
calculateColor(avgSize, minAvgSize, maxAvgSize, minColor, maxColor) {
|
|
279
|
+
if (minAvgSize != maxAvgSize) {
|
|
280
|
+
let gradient = (avgSize - minAvgSize) / (maxAvgSize - minAvgSize);
|
|
281
|
+
let color = minColor.map((channel, index) => {
|
|
282
|
+
return Math.round(channel + gradient * (maxColor[index] - channel));
|
|
283
|
+
});
|
|
284
|
+
return `rgb(${color.join(',')})`;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
return `rgb(${minColor.join(',')})`;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
transformColumns(mainobj) {
|
|
291
|
+
return Object.keys(mainobj).map(key => {
|
|
292
|
+
return {
|
|
293
|
+
visible: true,
|
|
294
|
+
dataField: key,
|
|
295
|
+
caption: key
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
getObjectKeys(obj) {
|
|
300
|
+
return Object.keys(obj);
|
|
301
|
+
}
|
|
302
|
+
callServiceFunction(functionName, value) {
|
|
303
|
+
if (value !== undefined) {
|
|
304
|
+
if (typeof this.commonService[functionName] === "function") {
|
|
305
|
+
return this.commonService[functionName](value);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
console.error(`Function ${functionName} not found in CommonService`);
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
return "No Data";
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
GammaHeatChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaHeatChartComponent, deps: [{ token: i1.CommonService }], target: i0.ɵɵFactoryTarget.Component });
|
|
318
|
+
GammaHeatChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: GammaHeatChartComponent, selector: "app-gamma-heatmap", inputs: { rightClickEnable: "rightClickEnable", chartDataSource: "chartDataSource" }, outputs: { getTableConfigOutPut: "getTableConfigOutPut", oRowClick: "oRowClick", onrightClickContextSelection: "onrightClickContextSelection" }, ngImport: i0, template: "<div class=\"mx-2 bg-gray-800\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n <ng-container *ngIf=\"!isLoader\">\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'simple'\">\n <div class=\"p-3 h-auto overflow-x-auto\">\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-22 max-w-[20%] h-10 flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 text-sm flex items-center justify-center\">\n {{item}}\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-8 flex text-sm items-center min-w-22 justify-end px-2 inline\">\n {{ item.datasource }}\n </div>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-start\">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [ngStyle]=\"{ 'background-color': box.color }\" [matTooltip]=\"box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n {{ callServiceFunction(heatmapChartConfig.columns[0].enrichName,\n box[heatmapChartConfig.columns[0].dataField]) }}\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'topx'\">\n <div class=\"p-3 h-auto overflow-x-auto\">\n <div class=\"flex flex-row\">\n <ng-container *ngFor=\"let header of heatChartDataSource.argumentValue\">\n <div class=\"min-w-32 text-sm font-medium text-center mb-2\">\n {{ header }}\n </div>\n </ng-container>\n </div>\n\n <div *ngFor=\"let row of heatChartDataSource.dataSet\" class=\"flex flex-row\">\n <ng-container *ngFor=\"let cell of row\">\n <div *ngIf=\"cell.box\"\n class=\"h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800 min-w-32 cursor-pointer\"\n [ngStyle]=\"{ 'background-color': cell.box.color }\" [matTooltip]=\"cell.box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n {{ cell.box[heatmapChartConfig.leftArgument] }} ({{\n callServiceFunction(heatmapChartConfig.columns[0].enrichName,\n cell.box[heatmapChartConfig.columns[0].dataField]) }})\n </div>\n <div *ngIf=\"!cell.box\" class=\"h-8 min-w-32\"></div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i4.LoaderComponent, selector: "app-loader" }] });
|
|
319
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaHeatChartComponent, decorators: [{
|
|
320
|
+
type: Component,
|
|
321
|
+
args: [{ selector: 'app-gamma-heatmap', template: "<div class=\"mx-2 bg-gray-800\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n <ng-container *ngIf=\"!isLoader\">\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'simple'\">\n <div class=\"p-3 h-auto overflow-x-auto\">\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-22 max-w-[20%] h-10 flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 text-sm flex items-center justify-center\">\n {{item}}\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-8 flex text-sm items-center min-w-22 justify-end px-2 inline\">\n {{ item.datasource }}\n </div>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-start\">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-22 max-w-[20%] h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [ngStyle]=\"{ 'background-color': box.color }\" [matTooltip]=\"box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n {{ callServiceFunction(heatmapChartConfig.columns[0].enrichName,\n box[heatmapChartConfig.columns[0].dataField]) }}\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"heatmapChartConfig.chartFormat == 'topx'\">\n <div class=\"p-3 h-auto overflow-x-auto\">\n <div class=\"flex flex-row\">\n <ng-container *ngFor=\"let header of heatChartDataSource.argumentValue\">\n <div class=\"min-w-32 text-sm font-medium text-center mb-2\">\n {{ header }}\n </div>\n </ng-container>\n </div>\n\n <div *ngFor=\"let row of heatChartDataSource.dataSet\" class=\"flex flex-row\">\n <ng-container *ngFor=\"let cell of row\">\n <div *ngIf=\"cell.box\"\n class=\"h-8 border-2 text-sm cursor-pointer flex items-center justify-center text-gray-800 min-w-32 cursor-pointer\"\n [ngStyle]=\"{ 'background-color': cell.box.color }\" [matTooltip]=\"cell.box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n {{ cell.box[heatmapChartConfig.leftArgument] }} ({{\n callServiceFunction(heatmapChartConfig.columns[0].enrichName,\n cell.box[heatmapChartConfig.columns[0].dataField]) }})\n </div>\n <div *ngIf=\"!cell.box\" class=\"h-8 min-w-32\"></div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>" }]
|
|
322
|
+
}], ctorParameters: function () { return [{ type: i1.CommonService }]; }, propDecorators: { getTableConfigOutPut: [{
|
|
323
|
+
type: Output
|
|
324
|
+
}], oRowClick: [{
|
|
325
|
+
type: Output
|
|
326
|
+
}], onrightClickContextSelection: [{
|
|
327
|
+
type: Output
|
|
328
|
+
}], rightClickEnable: [{
|
|
329
|
+
type: Input
|
|
330
|
+
}], chartDataSource: [{
|
|
331
|
+
type: Input,
|
|
332
|
+
args: ['chartDataSource']
|
|
333
|
+
}] } });
|
|
334
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FtbWEtaGVhdG1hcC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW1tYS1hcHAtY29udHJvbGxlci9zcmMvbGliL3NoYXJlZC9hZHZhbmNlZC1jb21wb25lbnQvZ2FtbWEtaGVhdG1hcC9nYW1tYS1oZWF0bWFwLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dhbW1hLWFwcC1jb250cm9sbGVyL3NyYy9saWIvc2hhcmVkL2FkdmFuY2VkLWNvbXBvbmVudC9nYW1tYS1oZWF0bWFwL2dhbW1hLWhlYXRtYXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLE1BQU0sTUFBTSwrQ0FBK0MsQ0FBQzs7Ozs7O0FBT25FLE1BQU0sT0FBTyx1QkFBdUI7SUEyRWxDLFlBQW1CLGFBQTRCO1FBQTVCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBekUvQyx1QkFBa0IsR0FBUSxFQUFFLENBQUM7UUFHN0IsYUFBUSxHQUFZLElBQUksQ0FBQztRQUN6QixvQkFBZSxHQUFRLEVBQUUsQ0FBQztRQUMxQixtQkFBYyxHQUFHLENBQUMsYUFBYSxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLHVDQUF1QyxFQUFFLGVBQWUsQ0FBQyxDQUFBO1FBSTlILGNBQVMsR0FBVyxPQUFPLENBQUM7UUFLNUIsb0JBQWUsR0FBWSxLQUFLLENBQUM7UUFDakMsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFFaEMsd0JBQW1CLEdBQVEsRUFBRSxDQUFDO1FBQzlCLHdCQUFtQixHQUFRLEVBQUUsQ0FBQztRQUk5Qix5QkFBb0IsR0FBUSxFQUFFLENBQUM7UUFHL0IsbUJBQWMsR0FBUTtZQUNwQixnQkFBZ0IsRUFBRSxL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eEIsS0FBSztnQkFHRixlQUFlO3NCQURsQixLQUFLO3VCQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbIlxuXG5cbmltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCBtb21lbnQgZnJvbSAnLi4vLi4vLi4vYXBwbGljYXRpb24tY29udHJvbGxlci9tb21lbnQtaGVscGVyJztcbmltcG9ydCB7IENvbW1vblNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL2NvbW1vbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1nYW1tYS1oZWF0bWFwJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dhbW1hLWhlYXRtYXAuY29tcG9uZW50Lmh0bWwnLFxufSlcbmV4cG9ydCBjbGFzcyBHYW1tYUhlYXRDaGFydENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gaXNKc29uUHJldmlldzogYm9vbGVhblxuICBkYXRhU291cnNlRm9yVGFibGU6IGFueSA9IFtdO1xuICBqc2FvbkRhdGFzb3VyY2U6IGFueTtcbiAgY29uZmlnQ29sdW1lOiBhbnk7XG4gIGlzTG9hZGVyOiBib29sZWFuID0gdHJ1ZTtcbiAgdGFibGVEYXRhQ29uZmlnOiBhbnkgPSB7fTtcbiAgZW5yaWNoTmFtZUxpc3QgPSBbXCJmb3JtYXRCeXRlc1wiLCBcImZvcm1hdEJ5dHNUb0tiXCIsIFwiZm9ybWF0Qnl0c1RvR2JcIiwgXCJyZWZvcm1hdE51bWJlcldpdGhUaG91c2FuZFNlcGFyYXRvclYzXCIsIFwiZm9ybWF0Qnl0ZXN2MlwiXVxuICBwYWdlX2NvbmZpZzogYW55O1xuICBwYWdlX3Bhcm1zOiBhbnk7XG4gIHBhZ2Vfc2VsZWN0ZWRfb3BlcmF0b3I6IGFueTtcbiAgYWN0aXZlVGFiOiBzdHJpbmcgPSAnYmFzaWMnO1xuXG4gIHRhYmxlSGVpZ2h0OiBhbnk7XG5cblxuICBpc0FkdmFuY2VGaWx0ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNIZWF0TWFwQ2xpY2s6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBoZWF0Q2hhcnREYXRhU291cmNlOiBhbnkgPSB7fTtcbiAgY2hhcnREYXRhRm9yVG9vbHRpcDogYW55ID0ge307XG5cblxuXG4gIGRhdGFTb3Vyc2VGb3JIZWF0TWFwOiBhbnkgPSBbXTtcbiAgc2VsZWN0ZWRWaWV3Q29uZmlnczogYW55O1xuXG4gIHZpZXdQcm9wZXJ0aWVzOiBhbnkgPSB7XG4gICAgZW5hYmxlQ2xpY2tFdmVudDogZmFsc2UsXG4gICAgZW5hYmxlUmlnaHRDbGlja0V2ZW50OiB0cnVlLFxuICAgIGNsaWNrRXZlbnRPcHRpb25zOiB7XG4gICAgICBhc3NvY2lhdGVkVmlld3M6IFtdLFxuICAgICAgZXZlbnRUeXBlOiBcIlwiXG4gICAgfVxuICB9O1xuICBvcHRpb25hbERyaWxEb3duRGF0YVNvdXJjZTogYW55ID0gW107XG4gIHNlbGVjdGVkVGFibGVWaWV3VHlwZTogYW55O1xuXG4gIGFsbENvbmZpZ3VyZWRWaWV3czogYW55ID0gW107XG4gIGNvbG9yQXJyYXk6IGFueSA9IFtdO1xuICBmaXJzdENvbG9yID0gXCJyZ2JhKDQ1LCAxMTAsIDE4LCAxKVwiO1xuICBzZWNvbmRDb2xvciA9IFwicmdiYSgyNTUsIDIwNCwgMCwgMSlcIjtcbiAgc2luZ2xlQ29sb3IgPSBcInJnYmEoMjU1LCAyMDQsIDAsIDEpXCI7XG5cbiAgaGVhdG1hcENoYXJ0Q29uZmlnOiBhbnkgPSB7fTtcbiAgQE91dHB1dCgpIHB1YmxpYyBnZXRUYWJsZUNvbmZpZ091dFB1dDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb1Jvd0NsaWNrOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBvbnJpZ2h0Q2xpY2tDb250ZXh0U2VsZWN0aW9uOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQElucHV0KCkgcmlnaHRDbGlja0VuYWJsZTogYm9vbGVhbiA9IHRydWU7XG5cbiAgQElucHV0KCdjaGFydERhdGFTb3VyY2UnKVxuICBzZXQgY2hhcnREYXRhU291cmNlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNMb2FkZXIgPSB0cnVlO1xuICAgICAgdGhpcy5wYWdlX2NvbmZpZyA9IHZhbHVlO1xuICAgICAgdGhpcy5wYWdlX3Bhcm1zID0gdmFsdWUudGl0bGVQYXJhbXM7XG4gICAgICBpZiAodmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2UgJiYgdmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2UubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnID0gdmFsdWUua3BpQ29uZmlnLmRhdGFDb25maWc7XG4gICAgICAgIHRoaXMuY29sb3JBcnJheSA9IHZhbHVlLmtwaUNvbmZpZy5kYXRhQ29uZmlnLmNvbG9yO1xuICAgICAgICB0aGlzLmdldEhlYXRtYXBEYXRhKHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlKTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgICB9LCAyMDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5kYXRhU291cnNlRm9yVGFibGUgPSBbXTtcbiAgICAgICAgICB0aGlzLnRhYmxlRGF0YUNvbmZpZ1snY29sdW1ucyddID0gW107XG4gICAgICAgICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgICB9LCAyMDApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBjb21tb25TZXJ2aWNlOiBDb21tb25TZXJ2aWNlKSB7IH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgfVxuXG4gIGdldEhlYXRtYXBEYXRhKGhlYXRNYXBEYXRhKSB7XG4gICAgZGVidWdnZXJcbiAgICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2UgPSB7fTtcbiAgICB0aGlzLmlzQWR2YW5jZUZpbHRlciA9IGZhbHNlO1xuICAgIGlmIChoZWF0TWFwRGF0YSAmJiBoZWF0TWFwRGF0YS5sZW5ndGggIT09IDApIHtcbiAgICAgIGlmICh0aGlzLmhlYXRtYXBDaGFydENvbmZpZy5jaGFydEZvcm1hdCA9PSBcInRvcHhcIikge1xuICAgICAgICBjb25zdCB7IHJlc3VsdCwgdW5pcXVlRGF0ZXMgfSA9IHRoaXMuZ2VuZXJhdGVEYXRlV2lzZUNvbG9yQ29kZWREYXRhKGhlYXRNYXBEYXRhKTtcbiAgICAgICAgLy8gdW5pcXVlRGF0ZXMuc29ydCgpO1xuICAgICAgICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2UuZGF0YVNldCA9IHRoaXMuZ2V0VHJhbnNwb3NlZEhlYXRtYXBEYXRhKHJlc3VsdCk7XG4gICAgICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImFyZ3VtZW50VmFsdWVcIl0gPSB1bmlxdWVEYXRlcztcbiAgICAgIH0gZWxzZSBpZiAoKHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNoYXJ0Rm9ybWF0ID09IFwic2ltcGxlXCIpKSB7XG4gICAgICAgIGNvbnN0IHsgcmVzdWx0LCB1bmlxdWVEYXRlcyB9ID0gdGhpcy5nZW5lcmF0ZURhdGEoaGVhdE1hcERhdGEpO1xuICAgICAgICAvLyB1bmlxdWVEYXRlcy5zb3J0KCk7XG4gICAgICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImRhdGFTZXRcIl0gPSByZXN1bHQ7XG4gICAgICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImFyZ3VtZW50VmFsdWVcIl0gPSB1bmlxdWVEYXRlcztcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc0hlYXRNYXBDbGljayA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzSGVhdE1hcENsaWNrID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlID0ge307XG4gICAgLy8gdGhpcy5pc0FkdmFuY2VGaWx0ZXIgPSBmYWxzZTtcblxuICAgIC8vIGlmIChoZWF0TWFwRGF0YSAmJiBoZWF0TWFwRGF0YS5sZW5ndGggIT09IDApIHtcbiAgICAvLyAgIGNvbnN0IHsgcmVzdWx0LCB1bmlxdWVEYXRlcyB9ID0gdGhpcy5nZW5lcmF0ZURhdGEoaGVhdE1hcERhdGEpXG4gICAgLy8gICB1bmlxdWVEYXRlcy5zb3J0KCk7XG4gICAgLy8gICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2VbXCJkYXRhU2V0XCJdID0gcmVzdWx0O1xuICAgIC8vICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlW1wiYXJndW1lbnRWYWx1ZVwiXSA9IHVuaXF1ZURhdGVzO1xuICAgIC8vICAgdGhpcy5pc0hlYXRNYXBDbGljayA9IGZhbHNlO1xuICAgIC8vIH0gZWxzZSB7XG4gICAgLy8gICB0aGlzLmlzSGVhdE1hcENsaWNrID0gZmFsc2U7XG4gICAgLy8gfVxuXG5cbiAgfVxuXG4gIGdldFRyYW5zcG9zZWRIZWF0bWFwRGF0YShkYXRhU2V0OiBhbnlbXSk6IGFueVtdIHtcbiAgICBjb25zdCB0cmFuc3Bvc2VkOiBhbnlbXSA9IFtdO1xuICAgIGNvbnN0IG1heEJveGVzID0gTWF0aC5tYXgoLi4uZGF0YVNldC5tYXAoaXRlbSA9PiBpdGVtLmRhdGFzZXQubGVuZ3RoKSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1heEJveGVzOyBpKyspIHtcbiAgICAgIGNvbnN0IHJvdzogYW55W10gPSBbXTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZGF0YVNldC5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBib3ggPSBkYXRhU2V0W2pdLmRhdGFzZXRbaV07XG4gICAgICAgIHJvdy5wdXNoKHtcbiAgICAgICAgICBib3g6IGJveCB8fCBudWxsLFxuICAgICAgICAgIGRhdGU6IGRhdGFTZXRbal0ucmVjb3JkX2RhdGVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0cmFuc3Bvc2VkLnB1c2gocm93KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJhbnNwb3NlZDtcbiAgfVxuXG4gIGdlbmVyYXRlRGF0ZVdpc2VDb2xvckNvZGVkRGF0YShkYXRhOiBhbnlbXSkge1xuICAgIGNvbnN0IHJlc3VsdDogYW55W10gPSBbXTtcbiAgICBjb25zdCB1bmlxdWVEYXRlcyA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBhbGxFbnRyaWVzOiBhbnlbXSA9IFtdO1xuXG4gICAgY29uc3QgdG9wQXJnID0gdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudG9wQXJndW1lbnQ7XG4gICAgY29uc3QgbGVmdEFyZyA9IHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmxlZnRBcmd1bWVudDtcbiAgICBjb25zdCB2YWx1ZUZpZWxkID0gdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY29sdW1uc1swXS5kYXRhRmllbGQ7XG5cbiAgICBkYXRhLmZvckVhY2goZW50cnkgPT4ge1xuICAgICAgY29uc3QgZm9ybWF0dGVkRGF0ZSA9IChtb21lbnQoZW50cnlbdG9wQXJnXSkuZm9ybWF0KCdZWVlZLU1NLUREJykpID8gbW9tZW50KGVudHJ5W3RvcEFyZ10pLmZvcm1hdCgnWVlZWS1NTS1ERCcpIDogdG9wQXJnO1xuICAgICAgdW5pcXVlRGF0ZXMuYWRkKGZvcm1hdHRlZERhdGUpO1xuXG4gICAgICBlbnRyeS5yZXN1bHREYXRhc2V0LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGFsbEVudHJpZXMucHVzaCh7XG4gICAgICAgICAgW3RvcEFyZ106IGZvcm1hdHRlZERhdGUsXG4gICAgICAgICAgW2xlZnRBcmddOiBpdGVtW2Ake2xlZnRBcmd9YF0sXG4gICAgICAgICAgW3ZhbHVlRmllbGRdOiBpdGVtW2Ake3ZhbHVlRmllbGR9YF1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGxldCBjb2xvcmVkRGF0YTtcbiAgICBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PT0gJ2dyYWRpZW50Jykge1xuICAgICAgY29sb3JlZERhdGEgPSB0aGlzLmdldEZvcm1hdGVEYXRhQnlDb2xvckNvZGVGb3JHcmFkaWVudChhbGxFbnRyaWVzLCB2YWx1ZUZpZWxkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLnR5cGUgPT09ICd0d29Db2xvcicpIHtcbiAgICAgIGNvbG9yZWREYXRhID0gdGhpcy5nZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yV2l0aFR3b0NvbG9yKGFsbEVudHJpZXMsIHZhbHVlRmllbGQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2xvcmVkRGF0YSA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvcldpdGhTaW5nbGVDb2xvcihhbGxFbnRyaWVzLCB2YWx1ZUZpZWxkKTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRlTWFwOiB7IFtkYXRlOiBzdHJpbmddOiBhbnlbXSB9ID0ge307XG5cbiAgICBjb2xvcmVkRGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgY29uc3QgZGF0ZTogYW55ID0gaXRlbVt0b3BBcmddO1xuXG4gICAgICBpZiAoIWRhdGVNYXBbZGF0ZV0pIHtcbiAgICAgICAgZGF0ZU1hcFtkYXRlXSA9IFtdO1xuICAgICAgfVxuICAgICAgbGV0IHRvb2xUaXAgPSBgUmVjb3JkIERhdGUgOiAke2l0ZW1bdG9wQXJnXX0gXFxuJHt0aGlzLmNvbW1vblNlcnZpY2UuY29udmVydFN0cmluZyh2YWx1ZUZpZWxkKX0gOiAke3RoaXMuY29tbW9uU2VydmljZS5UaG91c2FuZFNlcGFyYXRvcldpdGhUd29EZWNpbWFscyhpdGVtW3ZhbHVlRmllbGRdKX1gXG4gICAgICBkYXRlTWFwW2RhdGVdLnB1c2goe1xuICAgICAgICBbbGVmdEFyZ106IGl0ZW1bbGVmdEFyZ10sXG4gICAgICAgIFt2YWx1ZUZpZWxkXTogaXRlbVt2YWx1ZUZpZWxkXSxcbiAgICAgICAgY29sb3I6IGl0ZW0uY29sb3IsXG4gICAgICAgIHRvb2xUaXA6IHRvb2xUaXAsXG4gICAgICAgIFt0b3BBcmddOiBkYXRlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgXG4gICAgY29uc3Qgc29ydGVkRGF0ZXMgPSBBcnJheS5mcm9tKHVuaXF1ZURhdGVzKS5zb3J0KChhLCBiKSA9PiBtb21lbnQoYikuZGlmZihtb21lbnQoYSkpKTtcblxuICAgIGZvciAoY29uc3QgZGF0ZSBvZiBzb3J0ZWREYXRlcyBhcyBzdHJpbmdbXSkge1xuICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICByZWNvcmRfZGF0ZTogZGF0ZSxcbiAgICAgICAgZGF0YXNldDogZGF0ZU1hcFtkYXRlXSB8fCBbXVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlc3VsdCxcbiAgICAgIHVuaXF1ZURhdGVzOiBzb3J0ZWREYXRlc1xuICAgIH07XG4gIH1cblxuICBnZW5lcmF0ZURhdGEoZGF0YSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGNvbnN0IHVuaXF1ZURhdGVzID0gbmV3IFNldCgpO1xuICAgIGNvbnN0IGRhdGFTb3VyY2VNYXAgPSB7fTtcbiAgICBjb25zdCB0b3BBcmcgPSB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50b3BBcmd1bWVudDtcbiAgICBjb25zdCBsZWZ0QXJnID0gdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcubGVmdEFyZ3VtZW50O1xuICAgIGNvbnN0IHZhbHVlRmllbGQgPSB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmRhdGFGaWVsZDtcblxuICAgIGRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGNvbnN0IHJvd0tleSA9IGl0ZW1bbGVmdEFyZ107XG4gICAgICBjb25zdCBjb2x1bW5LZXkgPSBtb21lbnQoaXRlbVt0b3BBcmddKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcblxuICAgICAgaWYgKCFkYXRhU291cmNlTWFwW3Jvd0tleV0pIHtcbiAgICAgICAgZGF0YVNvdXJjZU1hcFtyb3dLZXldID0ge1xuICAgICAgICAgIGRhdGFzb3VyY2U6IHJvd0tleSxcbiAgICAgICAgICBkYXRhc2V0OiBbXVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgbGV0IHRvb2xUaXAgPSBgJHt0aGlzLmNvbW1vblNlcnZpY2UuY29udmVydFN0cmluZyhsZWZ0QXJnKX0gOiAke2l0ZW1bbGVmdEFyZ119IFxcblJlY29yZCBEYXRlIDogJHtjb2x1bW5LZXl9IFxcbiR7dGhpcy5jb21tb25TZXJ2aWNlLmNvbnZlcnRTdHJpbmcodmFsdWVGaWVsZCl9IDogJHt0aGlzLmNvbW1vblNlcnZpY2UuVGhvdXNhbmRTZXBhcmF0b3JXaXRoVHdvRGVjaW1hbHMoaXRlbVt2YWx1ZUZpZWxkXSl9YFxuXG4gICAgICBkYXRhU291cmNlTWFwW3Jvd0tleV0uZGF0YXNldC5wdXNoKHtcbiAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgIHRvb2xUaXA6IHRvb2xUaXAsXG4gICAgICAgIFt0b3BBcmddOiBjb2x1bW5LZXksXG5cbiAgICAgIH0pO1xuXG4gICAgICB1bmlxdWVEYXRlcy5hZGQoY29sdW1uS2V5KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHVuaXF1ZURhdGVzQXJyYXkgPSBBcnJheS5mcm9tKHVuaXF1ZURhdGVzKTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGFTb3VyY2VNYXApIHtcbiAgICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhU291cmNlTWFwW2tleV0uZGF0YXNldDtcbiAgICAgIGxldCBmb3JtYXR0ZWREYXRhc2V0O1xuXG4gICAgICBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PSBcImdyYWRpZW50XCIpIHtcbiAgICAgICAgZm9ybWF0dGVkRGF0YXNldCA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvckdyYWRpZW50KGRhdGFzZXQsIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PSBcInR3b0NvbG9yXCIpIHtcbiAgICAgICAgZm9ybWF0dGVkRGF0YXNldCA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvcldpdGhUd29Db2xvcihkYXRhc2V0LCB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmRhdGFGaWVsZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3JtYXR0ZWREYXRhc2V0ID0gdGhpcy5nZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yV2l0aFNpbmdsZUNvbG9yKGRhdGFzZXQsIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkKTtcblxuICAgICAgfVxuXG4gICAgICBjb25zdCBkYXRlVG9JdGVtTWFwID0ge307XG4gICAgICBmb3JtYXR0ZWREYXRhc2V0LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGRhdGVUb0l0ZW1NYXBbaXRlbVt0b3BBcmddXSA9IGl0ZW07XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgY29tcGxldGVEYXRhc2V0ID0gdW5pcXVlRGF0ZXNBcnJheS5tYXAoKGRhdGU6IGFueSkgPT4ge1xuICAgICAgICBpZiAoZGF0ZVRvSXRlbU1hcFtkYXRlXSkge1xuICAgICAgICAgIHJldHVybiBkYXRlVG9JdGVtTWFwW2RhdGVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBbdG9wQXJnXTogZGF0ZSxcbiAgICAgICAgICAgIGF2Z1NpemU6IFwiTm8gRGF0YVwiLFxuICAgICAgICAgICAgZmlsZUNvdW50OiAwLFxuICAgICAgICAgICAgZmlsZVNpemU6IDAsXG4gICAgICAgICAgICBjb2xvcjogXCJyZ2IoMjQyLCAxMTgsIDEwOSlcIlxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgIGRhdGFzb3VyY2U6IGtleSxcbiAgICAgICAgZGF0YXNldDogY29tcGxldGVEYXRhc2V0XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVzdWx0OiByZXN1bHQsXG4gICAgICB1bmlxdWVEYXRlczogdW5pcXVlRGF0ZXNBcnJheVxuICAgIH07XG4gIH1cblxuXG5cbiAgZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvckdyYWRpZW50KGZpbGVkYXRhLCBjb2x1bW4pIHtcbiAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaXRlbS5hdmdTaXplID0gcGFyc2VGbG9hdChpdGVtW2NvbHVtbl0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgbWF4QXZnU2l6ZSA9IE1hdGgubWF4KC4uLmZpbGVkYXRhLm1hcChpdGVtID0+IGl0ZW1bY29sdW1uXSkpO1xuICAgIGNvbnN0IG1pbkF2Z1NpemUgPSBNYXRoLm1pbiguLi5maWxlZGF0YS5tYXAoaXRlbSA9PiBpdGVtW2NvbHVtbl0pKTtcblxuICAgIGNvbnN0IFttaW5Db2xvclN0ciwgbWF4Q29sb3JTdHJdID0gdGhpcy5jb2xvckFycmF5IHx8IFtcInJnYmEoNDUsIDExMCwgMTgsMSlcIiwgXCJyZ2JhKDI1NSwgMjA0LCAwLDEpXCJdO1xuICAgIGNvbnN0IG1pbkNvbG9yID0gdGhpcy5wYXJzZVJHQkEobWluQ29sb3JTdHIpO1xuICAgIGNvbnN0IG1heENvbG9yID0gdGhpcy5wYXJzZVJHQkEobWF4Q29sb3JTdHIpO1xuXG4gICAgZmlsZWRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGl0ZW0uY29sb3IgPSB0aGlzLmNhbGN1bGF0ZUNvbG9yKGl0ZW1bY29sdW1uXSwgbWluQXZnU2l6ZSwgbWF4QXZnU2l6ZSwgbWluQ29sb3IsIG1heENvbG9yKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBmaWxlZGF0YTtcbiAgfVxuICBnZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yV2l0aFR3b0NvbG9yKGZpbGVkYXRhLCBjb2x1bW4pIHtcbiAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaXRlbVtjb2x1bW5dID0gcGFyc2VGbG9hdChpdGVtW2NvbHVtbl0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgW21pbkNvbG9yU3RyLCBtYXhDb2xvclN0cl0gPSB0aGlzLmNvbG9yQXJyYXkgfHwgW1wicmdiYSg0NSwgMTEwLCAxOCwxKVwiLCBcInJnYmEoMjU1LCAyMDQsIDAsMSlcIl07XG4gICAgY29uc3QgbWluQ29sb3IgPSB0aGlzLnBhcnNlUkdCQShtaW5Db2xvclN0cik7XG4gICAgY29uc3QgbWF4Q29sb3IgPSB0aGlzLnBhcnNlUkdCQShtYXhDb2xvclN0cik7XG5cbiAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaWYgKGl0ZW1bY29sdW1uXSA9PSAwKSB7XG4gICAgICAgIGl0ZW0uY29sb3IgPSBgcmdiKCR7bWluQ29sb3Iuam9pbignLCcpfSlgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbS5jb2xvciA9IGByZ2IoJHttYXhDb2xvci5qb2luKCcsJyl9KWA7XG4gICAgICB9XG5cbiAgICB9KTtcblxuICAgIHJldHVybiBmaWxlZGF0YTtcbiAgfVxuICBnZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yV2l0aFNpbmdsZUNvbG9yKGZpbGVkYXRhLCBjb2x1bW4pIHtcbiAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaXRlbVtjb2x1bW5dID0gcGFyc2VGbG9hdChpdGVtW2NvbHVtbl0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgW3NpbmdsZUNvbG9yXSA9IHRoaXMuY29sb3JBcnJheSB8fCBbXCJyZ2JhKDI1NSwgMjA0LCAwLDEpXCJdO1xuICAgIGNvbnN0IG1pbkNvbG9yID0gdGhpcy5wYXJzZVJHQkEoc2luZ2xlQ29sb3IpO1xuXG4gICAgZmlsZWRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGl0ZW0uY29sb3IgPSBgcmdiKCR7bWluQ29sb3Iuam9pbignLCcpfSlgO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZpbGVkYXRhO1xuICB9XG5cbiAgcGFyc2VSR0JBKGNvbG9yU3RyOiBzdHJpbmcpOiBudW1iZXJbXSB7XG4gICAgY29uc3QgdmFsdWVzID0gY29sb3JTdHIubWF0Y2goL1tcXGQuXSsvZyk/Lm1hcChOdW1iZXIpIHx8IFtdO1xuICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAzKSB2YWx1ZXMucHVzaCgxKTtcbiAgICByZXR1cm4gW1xuICAgICAgdmFsdWVzWzBdID8/IDAsXG4gICAgICB2YWx1ZXNbMV0gPz8gMCxcbiAgICAgIHZhbHVlc1syXSA/PyAwLFxuICAgICAgdmFsdWVzWzNdID8/IDFcbiAgICBdO1xuICB9XG5cbiAgY2FsY3VsYXRlQ29sb3IoYXZnU2l6ZSwgbWluQXZnU2l6ZSwgbWF4QXZnU2l6ZSwgbWluQ29sb3IsIG1heENvbG9yKSB7XG4gICAgaWYgKG1pbkF2Z1NpemUgIT0gbWF4QXZnU2l6ZSkge1xuICAgICAgbGV0IGdyYWRpZW50ID0gKGF2Z1NpemUgLSBtaW5BdmdTaXplKSAvIChtYXhBdmdTaXplIC0gbWluQXZnU2l6ZSk7XG4gICAgICBsZXQgY29sb3IgPSBtaW5Db2xvci5tYXAoKGNoYW5uZWwsIGluZGV4KSA9PiB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKGNoYW5uZWwgKyBncmFkaWVudCAqIChtYXhDb2xvcltpbmRleF0gLSBjaGFubmVsKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBgcmdiKCR7Y29sb3Iuam9pbignLCcpfSlgO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYHJnYigke21pbkNvbG9yLmpvaW4oJywnKX0pYFxuICAgIH1cblxuICB9XG5cblxuXG4gIHRyYW5zZm9ybUNvbHVtbnMobWFpbm9iajogYW55KTogYW55W10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhtYWlub2JqKS5tYXAoa2V5ID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgIGRhdGFGaWVsZDoga2V5LFxuICAgICAgICBjYXB0aW9uOiBrZXlcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuXG5cbiAgZ2V0T2JqZWN0S2V5cyhvYmo6IGFueSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMob2JqKTtcbiAgfVxuXG5cbiAgY2FsbFNlcnZpY2VGdW5jdGlvbihmdW5jdGlvbk5hbWU6IHN0cmluZywgdmFsdWUpOiBhbnkge1xuXG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5jb21tb25TZXJ2aWNlW2Z1bmN0aW9uTmFtZV0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21tb25TZXJ2aWNlW2Z1bmN0aW9uTmFtZV0odmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRnVuY3Rpb24gJHtmdW5jdGlvbk5hbWV9IG5vdCBmb3VuZCBpbiBDb21tb25TZXJ2aWNlYCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJObyBEYXRhXCJcbiAgICB9XG5cbiAgfVxuXG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJteC0yIGJnLWdyYXktODAwXCI+XG4gICAgPGFwcC1sb2FkZXIgKm5nSWY9XCJpc0xvYWRlclwiPjwvYXBwLWxvYWRlcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzTG9hZGVyXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoZWF0bWFwQ2hhcnRDb25maWcuY2hhcnRGb3JtYXQgPT0gJ3NpbXBsZSdcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTMgaC1hdXRvIG92ZXJmbG93LXgtYXV0b1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbmxpbmUtYmxvY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1ub3dyYXAganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXNocmluay0wIHctMjIgbWF4LXctWzIwJV0gaC0xMCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBoZWF0Q2hhcnREYXRhU291cmNlLmFyZ3VtZW50VmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxleC1zaHJpbmstMCBtaW4tdy0yMiBtYXgtdy1bMjAlXSBoLTggdGV4dC1zbSBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7aXRlbX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBoZWF0Q2hhcnREYXRhU291cmNlLmRhdGFTZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLTggZmxleCB0ZXh0LXNtIGl0ZW1zLWNlbnRlciBtaW4tdy0yMiBqdXN0aWZ5LWVuZCBweC0yIGlubGluZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0uZGF0YXNvdXJjZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5saW5lLWJsb2NrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1ub3dyYXAganVzdGlmeS1zdGFydFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBib3ggb2YgaXRlbS5kYXRhc2V0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1zaHJpbmstMCBtaW4tdy0yMiBtYXgtdy1bMjAlXSBoLTggYm9yZGVyLTIgdGV4dC1zbSBjdXJzb3ItcG9pbnRlciBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciB0ZXh0LWdyYXktODAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICdiYWNrZ3JvdW5kLWNvbG9yJzogYm94LmNvbG9yIH1cIiBbbWF0VG9vbHRpcF09XCJib3gudG9vbFRpcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcENsYXNzPVwiY3VzdG9tLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjYWxsU2VydmljZUZ1bmN0aW9uKGhlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmVucmljaE5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94W2hlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmRhdGFGaWVsZF0pIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoZWF0bWFwQ2hhcnRDb25maWcuY2hhcnRGb3JtYXQgPT0gJ3RvcHgnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC0zIGgtYXV0byBvdmVyZmxvdy14LWF1dG9cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBoZWFkZXIgb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5hcmd1bWVudFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluLXctMzIgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWNlbnRlciBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgaGVhZGVyIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCByb3cgb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5kYXRhU2V0XCIgY2xhc3M9XCJmbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNlbGwgb2Ygcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY2VsbC5ib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaC04IGJvcmRlci0yIHRleHQtc20gY3Vyc29yLXBvaW50ZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgdGV4dC1ncmF5LTgwMCBtaW4tdy0zMiBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnYmFja2dyb3VuZC1jb2xvcic6IGNlbGwuYm94LmNvbG9yIH1cIiBbbWF0VG9vbHRpcF09XCJjZWxsLmJveC50b29sVGlwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwQ2xhc3M9XCJjdXN0b20tdG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNlbGwuYm94W2hlYXRtYXBDaGFydENvbmZpZy5sZWZ0QXJndW1lbnRdIH19ICh7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxTZXJ2aWNlRnVuY3Rpb24oaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZW5yaWNoTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmJveFtoZWF0bWFwQ2hhcnRDb25maWcuY29sdW1uc1swXS5kYXRhRmllbGRdKSB9fSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFjZWxsLmJveFwiIGNsYXNzPVwiaC04IG1pbi13LTMyXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuPC9kaXY+Il19
|