gamma-app-controller 1.1.26 → 1.1.28
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 +1 -1
- package/esm2020/lib/template-module/KpiCreationModule/kpiCreation.module.mjs +2 -2
- package/esm2020/lib/template-module/bookmarked-template/bookmarked-dataset-call.service.mjs +364 -0
- package/esm2020/lib/template-module/bookmarked-template/bookmarked-layout.service.mjs +121 -0
- package/esm2020/lib/template-module/bookmarked-template/bookmarked-template.component.mjs +816 -0
- package/esm2020/lib/template-module/bookmarked-template/bookmarkedTemplate.module.mjs +151 -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 +151 -0
- package/esm2020/lib/template-module/defaulLandingComponent/landing-component.component.mjs +870 -0
- package/esm2020/lib/template-module/defaulLandingComponent/landing-component.service.mjs +121 -0
- package/esm2020/lib/template-module/defaulLandingComponent/landing-dataset-call.service.mjs +364 -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-multi-layout.service.mjs +121 -0
- package/esm2020/lib/template-module/kpiWithMultiLayout/kpi-with-multilayout.component.mjs +992 -0
- package/esm2020/lib/template-module/kpiWithMultiLayout/kpiWithMultiayout.module.mjs +156 -0
- package/esm2020/lib/template-module/kpiWithMultiLayout/single-layout-dataset-call.service.mjs +364 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.mjs +180 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/kpi-single-layout.service.mjs +121 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.mjs +1046 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/kpiWithSingleLayout.module.mjs +156 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/multi-layout-dataset-call.service.mjs +364 -0
- package/esm2020/public-api.mjs +38 -20
- package/fesm2015/gamma-app-controller.mjs +7025 -399
- package/fesm2015/gamma-app-controller.mjs.map +1 -1
- package/fesm2020/gamma-app-controller.mjs +6970 -399
- 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/kpiCreation.module.d.ts +1 -1
- package/lib/template-module/bookmarked-template/bookmarked-dataset-call.service.d.ts +24 -0
- package/lib/template-module/bookmarked-template/bookmarked-layout.service.d.ts +33 -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/defaulLandingComponent/landing-component.service.d.ts +33 -0
- package/lib/template-module/defaulLandingComponent/landing-dataset-call.service.d.ts +24 -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-multi-layout.service.d.ts +33 -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/kpiWithMultiLayout/single-layout-dataset-call.service.d.ts +24 -0
- package/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.d.ts +42 -0
- package/lib/template-module/kpiWithSingleLayout/kpi-single-layout.service.d.ts +33 -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/lib/template-module/kpiWithSingleLayout/multi-layout-dataset-call.service.d.ts +24 -0
- package/package.json +1 -1
- package/public-api.d.ts +37 -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
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
-
import moment from './../../../moment-helper';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
import * as i1 from "../../../common";
|
|
5
|
-
import * as i2 from "@angular/common";
|
|
6
|
-
import * as i3 from "../../loader/loader.component";
|
|
7
|
-
export class GammaHeatChartComponent {
|
|
8
|
-
constructor(commonService) {
|
|
9
|
-
this.commonService = commonService;
|
|
10
|
-
this.dataSourseForTable = [];
|
|
11
|
-
this.isLoader = true;
|
|
12
|
-
this.tableDataConfig = {};
|
|
13
|
-
this.enrichNameList = ["formatBytes", "formatBytsToKb", "formatBytsToGb", "reformatNumberWithThousandSeparatorV3", "formatBytesv2"];
|
|
14
|
-
this.activeTab = 'basic';
|
|
15
|
-
this.isAdvanceFilter = false;
|
|
16
|
-
this.isHeatMapClick = false;
|
|
17
|
-
this.heatChartDataSource = {};
|
|
18
|
-
this.chartDataForTooltip = {};
|
|
19
|
-
this.dataSourseForHeatMap = [];
|
|
20
|
-
this.viewProperties = {
|
|
21
|
-
enableClickEvent: false,
|
|
22
|
-
enableRightClickEvent: true,
|
|
23
|
-
clickEventOptions: {
|
|
24
|
-
associatedViews: [],
|
|
25
|
-
eventType: ""
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
this.optionalDrilDownDataSource = [];
|
|
29
|
-
this.allConfiguredViews = [];
|
|
30
|
-
this.colorArray = [];
|
|
31
|
-
this.firstColor = "rgba(45, 110, 18, 1)";
|
|
32
|
-
this.secondColor = "rgba(255, 204, 0, 1)";
|
|
33
|
-
this.singleColor = "rgba(255, 204, 0, 1)";
|
|
34
|
-
this.heatmapChartConfig = {};
|
|
35
|
-
this.getTableConfigOutPut = new EventEmitter();
|
|
36
|
-
this.oRowClick = new EventEmitter();
|
|
37
|
-
this.onrightClickContextSelection = new EventEmitter();
|
|
38
|
-
this.rightClickEnable = true;
|
|
39
|
-
}
|
|
40
|
-
set chartDataSource(value) {
|
|
41
|
-
if (value === undefined || value.length === 0) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
this.isLoader = true;
|
|
46
|
-
this.page_config = value;
|
|
47
|
-
this.page_parms = value.titleParams;
|
|
48
|
-
if (value.kpiConfig.dataSource && value.kpiConfig.dataSource.length !== 0) {
|
|
49
|
-
this.heatmapChartConfig = value.kpiConfig.dataConfig;
|
|
50
|
-
this.colorArray = value.kpiConfig.dataConfig.color;
|
|
51
|
-
this.getHeatmapData(value.kpiConfig.dataSource);
|
|
52
|
-
setTimeout(() => {
|
|
53
|
-
this.isLoader = false;
|
|
54
|
-
}, 200);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
setTimeout(() => {
|
|
58
|
-
this.dataSourseForTable = [];
|
|
59
|
-
this.tableDataConfig['columns'] = [];
|
|
60
|
-
this.isLoader = false;
|
|
61
|
-
}, 200);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
ngOnInit() {
|
|
66
|
-
}
|
|
67
|
-
getHeatmapData(heatMapData) {
|
|
68
|
-
this.heatChartDataSource = {};
|
|
69
|
-
this.isAdvanceFilter = false;
|
|
70
|
-
if (heatMapData && heatMapData.length !== 0) {
|
|
71
|
-
if (this.heatmapChartConfig.chartFormat == "topx") {
|
|
72
|
-
const { result, uniqueDates } = this.generateDateWiseColorCodedData(heatMapData);
|
|
73
|
-
uniqueDates.sort();
|
|
74
|
-
this.heatChartDataSource.dataSet = this.getTransposedHeatmapData(result);
|
|
75
|
-
this.heatChartDataSource["argumentValue"] = uniqueDates;
|
|
76
|
-
}
|
|
77
|
-
else if ((this.heatmapChartConfig.chartFormat == "simple")) {
|
|
78
|
-
const { result, uniqueDates } = this.generateData(heatMapData);
|
|
79
|
-
uniqueDates.sort();
|
|
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
|
-
dateMap[date].push({
|
|
140
|
-
[leftArg]: item[leftArg],
|
|
141
|
-
[valueField]: item[valueField],
|
|
142
|
-
color: item.color,
|
|
143
|
-
[topArg]: date,
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
for (const date of Array.from(uniqueDates).sort()) {
|
|
147
|
-
result.push({
|
|
148
|
-
record_date: date,
|
|
149
|
-
dataset: dateMap[date] || []
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
return {
|
|
153
|
-
result,
|
|
154
|
-
uniqueDates: Array.from(uniqueDates).sort()
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
generateData(data) {
|
|
158
|
-
const result = [];
|
|
159
|
-
const uniqueDates = new Set();
|
|
160
|
-
const dataSourceMap = {};
|
|
161
|
-
const topArg = this.heatmapChartConfig.topArgument;
|
|
162
|
-
const leftArg = this.heatmapChartConfig.leftArgument;
|
|
163
|
-
data.forEach(item => {
|
|
164
|
-
const rowKey = item[leftArg];
|
|
165
|
-
const columnKey = moment(item[topArg]).format('YYYY-MM-DD');
|
|
166
|
-
if (!dataSourceMap[rowKey]) {
|
|
167
|
-
dataSourceMap[rowKey] = {
|
|
168
|
-
datasource: rowKey,
|
|
169
|
-
dataset: []
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
dataSourceMap[rowKey].dataset.push({
|
|
173
|
-
...item,
|
|
174
|
-
[topArg]: columnKey
|
|
175
|
-
});
|
|
176
|
-
uniqueDates.add(columnKey);
|
|
177
|
-
});
|
|
178
|
-
const uniqueDatesArray = Array.from(uniqueDates);
|
|
179
|
-
for (const key in dataSourceMap) {
|
|
180
|
-
const dataset = dataSourceMap[key].dataset;
|
|
181
|
-
let formattedDataset;
|
|
182
|
-
if (this.heatmapChartConfig.type == "gradient") {
|
|
183
|
-
formattedDataset = this.getFormateDataByColorCodeForGradient(dataset, this.heatmapChartConfig.columns[0].dataField);
|
|
184
|
-
}
|
|
185
|
-
else if (this.heatmapChartConfig.type == "twoColor") {
|
|
186
|
-
formattedDataset = this.getFormateDataByColorCodeForWithTwoColor(dataset, this.heatmapChartConfig.columns[0].dataField);
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
formattedDataset = this.getFormateDataByColorCodeForWithSingleColor(dataset, this.heatmapChartConfig.columns[0].dataField);
|
|
190
|
-
}
|
|
191
|
-
const dateToItemMap = {};
|
|
192
|
-
formattedDataset.forEach(item => {
|
|
193
|
-
dateToItemMap[item[topArg]] = item;
|
|
194
|
-
});
|
|
195
|
-
const completeDataset = uniqueDatesArray.map((date) => {
|
|
196
|
-
if (dateToItemMap[date]) {
|
|
197
|
-
return dateToItemMap[date];
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
return {
|
|
201
|
-
[topArg]: date,
|
|
202
|
-
avgSize: "No Data",
|
|
203
|
-
fileCount: 0,
|
|
204
|
-
fileSize: 0,
|
|
205
|
-
color: "rgb(242, 118, 109)"
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
result.push({
|
|
210
|
-
datasource: key,
|
|
211
|
-
dataset: completeDataset
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
return {
|
|
215
|
-
result: result,
|
|
216
|
-
uniqueDates: uniqueDatesArray
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
getFormateDataByColorCodeForGradient(filedata, column) {
|
|
220
|
-
filedata.forEach(item => {
|
|
221
|
-
item.avgSize = parseFloat(item[column]);
|
|
222
|
-
});
|
|
223
|
-
const maxAvgSize = Math.max(...filedata.map(item => item[column]));
|
|
224
|
-
const minAvgSize = Math.min(...filedata.map(item => item[column]));
|
|
225
|
-
const [minColorStr, maxColorStr] = this.colorArray || ["rgba(45, 110, 18,1)", "rgba(255, 204, 0,1)"];
|
|
226
|
-
const minColor = this.parseRGBA(minColorStr);
|
|
227
|
-
const maxColor = this.parseRGBA(maxColorStr);
|
|
228
|
-
filedata.forEach(item => {
|
|
229
|
-
item.color = this.calculateColor(item[column], minAvgSize, maxAvgSize, minColor, maxColor);
|
|
230
|
-
});
|
|
231
|
-
return filedata;
|
|
232
|
-
}
|
|
233
|
-
getFormateDataByColorCodeForWithTwoColor(filedata, column) {
|
|
234
|
-
filedata.forEach(item => {
|
|
235
|
-
item[column] = parseFloat(item[column]);
|
|
236
|
-
});
|
|
237
|
-
const [minColorStr, maxColorStr] = this.colorArray || ["rgba(45, 110, 18,1)", "rgba(255, 204, 0,1)"];
|
|
238
|
-
const minColor = this.parseRGBA(minColorStr);
|
|
239
|
-
const maxColor = this.parseRGBA(maxColorStr);
|
|
240
|
-
filedata.forEach(item => {
|
|
241
|
-
if (item[column] == 0) {
|
|
242
|
-
item.color = `rgb(${minColor.join(',')})`;
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
item.color = `rgb(${maxColor.join(',')})`;
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
return filedata;
|
|
249
|
-
}
|
|
250
|
-
getFormateDataByColorCodeForWithSingleColor(filedata, column) {
|
|
251
|
-
filedata.forEach(item => {
|
|
252
|
-
item[column] = parseFloat(item[column]);
|
|
253
|
-
});
|
|
254
|
-
const [singleColor] = this.colorArray || ["rgba(255, 204, 0,1)"];
|
|
255
|
-
const minColor = this.parseRGBA(singleColor);
|
|
256
|
-
filedata.forEach(item => {
|
|
257
|
-
item.color = `rgb(${minColor.join(',')})`;
|
|
258
|
-
});
|
|
259
|
-
return filedata;
|
|
260
|
-
}
|
|
261
|
-
parseRGBA(colorStr) {
|
|
262
|
-
const values = colorStr.match(/[\d.]+/g)?.map(Number) || [];
|
|
263
|
-
if (values.length === 3)
|
|
264
|
-
values.push(1);
|
|
265
|
-
return [
|
|
266
|
-
values[0] ?? 0,
|
|
267
|
-
values[1] ?? 0,
|
|
268
|
-
values[2] ?? 0,
|
|
269
|
-
values[3] ?? 1
|
|
270
|
-
];
|
|
271
|
-
}
|
|
272
|
-
calculateColor(avgSize, minAvgSize, maxAvgSize, minColor, maxColor) {
|
|
273
|
-
if (minAvgSize != maxAvgSize) {
|
|
274
|
-
let gradient = (avgSize - minAvgSize) / (maxAvgSize - minAvgSize);
|
|
275
|
-
let color = minColor.map((channel, index) => {
|
|
276
|
-
return Math.round(channel + gradient * (maxColor[index] - channel));
|
|
277
|
-
});
|
|
278
|
-
return `rgb(${color.join(',')})`;
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
return `rgb(${minColor.join(',')})`;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
transformColumns(mainobj) {
|
|
285
|
-
return Object.keys(mainobj).map(key => {
|
|
286
|
-
return {
|
|
287
|
-
visible: true,
|
|
288
|
-
dataField: key,
|
|
289
|
-
caption: key
|
|
290
|
-
};
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
getObjectKeys(obj) {
|
|
294
|
-
return Object.keys(obj);
|
|
295
|
-
}
|
|
296
|
-
callServiceFunction(functionName, value) {
|
|
297
|
-
if (value !== undefined) {
|
|
298
|
-
if (typeof this.commonService[functionName] === "function") {
|
|
299
|
-
return this.commonService[functionName](value);
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
console.error(`Function ${functionName} not found in CommonService`);
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
307
|
-
return "No Data";
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
GammaHeatChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaHeatChartComponent, deps: [{ token: i1.CommonService }], target: i0.ɵɵFactoryTarget.Component });
|
|
312
|
-
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=\"mx-5 h-[60vh] overflow-x-auto\">\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-64 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-64 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 }\"\n [attr.title]=\"'Record Date: ' + box[heatmapChartConfig.topArgument] + ', Value: ' + box[heatmapChartConfig.columns[0].dataField]\">\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=\"mx-5 h-[60vh] 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\"\n [ngStyle]=\"{ 'background-color': cell.box.color }\"\n [attr.title]=\"'Record Date: ' + cell.box[heatmapChartConfig.topArgument] + ', Value: ' + cell.box[heatmapChartConfig.columns[0].dataField]\">\n {{ cell.box[heatmapChartConfig.leftArgument] }} ({{\n commonService.abbreviateNumber(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: "component", type: i3.LoaderComponent, selector: "app-loader" }] });
|
|
313
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaHeatChartComponent, decorators: [{
|
|
314
|
-
type: Component,
|
|
315
|
-
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=\"mx-5 h-[60vh] overflow-x-auto\">\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-64 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-64 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 }\"\n [attr.title]=\"'Record Date: ' + box[heatmapChartConfig.topArgument] + ', Value: ' + box[heatmapChartConfig.columns[0].dataField]\">\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=\"mx-5 h-[60vh] 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\"\n [ngStyle]=\"{ 'background-color': cell.box.color }\"\n [attr.title]=\"'Record Date: ' + cell.box[heatmapChartConfig.topArgument] + ', Value: ' + cell.box[heatmapChartConfig.columns[0].dataField]\">\n {{ cell.box[heatmapChartConfig.leftArgument] }} ({{\n commonService.abbreviateNumber(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>" }]
|
|
316
|
-
}], ctorParameters: function () { return [{ type: i1.CommonService }]; }, propDecorators: { getTableConfigOutPut: [{
|
|
317
|
-
type: Output
|
|
318
|
-
}], oRowClick: [{
|
|
319
|
-
type: Output
|
|
320
|
-
}], onrightClickContextSelection: [{
|
|
321
|
-
type: Output
|
|
322
|
-
}], rightClickEnable: [{
|
|
323
|
-
type: Input
|
|
324
|
-
}], chartDataSource: [{
|
|
325
|
-
type: Input,
|
|
326
|
-
args: ['chartDataSource']
|
|
327
|
-
}] } });
|
|
328
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FtbWEtaGVhdG1hcC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW1tYS1hcHAtY29udHJvbGxlci9zcmMvbGliL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvc2hhcmVkL2FkdmFuY2VkLWNvbXBvbmVudC9nYW1tYS1oZWF0bWFwL2dhbW1hLWhlYXRtYXAuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FtbWEtYXBwLWNvbnRyb2xsZXIvc3JjL2xpYi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL3NoYXJlZC9hZHZhbmNlZC1jb21wb25lbnQvZ2FtbWEtaGVhdG1hcC9nYW1tYS1oZWF0bWFwLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0UsT0FBTyxNQUFNLE1BQU0sMEJBQTBCLENBQUM7Ozs7O0FBTzlDLE1BQU0sT0FBTyx1QkFBdUI7SUE0RWxDLFlBQW1CLGFBQTRCO1FBQTVCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBMUUvQyx1QkFBa0IsR0FBUSxFQUFFLENBQUM7UUFHN0IsYUFBUSxHQUFZLElBQUksQ0FBQztRQUN6QixvQkFBZSxHQUFRLEVBQUUsQ0FBQztRQUMxQixtQkFBYyxHQUFHLENBQUMsYUFBYSxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLHVDQUF1QyxFQUFFLGVBQWUsQ0FBQyxDQUFBO1FBSTlILGNBQVMsR0FBVyxPQUFPLENBQUM7UUFLNUIsb0JBQWUsR0FBWSxLQUFLLENBQUM7UUFDakMsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFFaEMsd0JBQW1CLEdBQVEsRUFBRSxDQUFDO1FBQzlCLHdCQUFtQixHQUFRLEVBQUUsQ0FBQztRQUk5Qix5QkFBb0Is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QyxZQUFZLENBQUMsS0FBSyxVQUFVLEVBQUU7Z0JBQzFELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNoRDtpQkFBTTtnQkFDTCxPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksWUFBWSw2QkFBNkIsQ0FBQyxDQUFDO2dCQUNyRSxPQUFPLElBQUksQ0FBQzthQUNiO1NBQ0Y7YUFBTTtZQUNMLE9BQU8sU0FBUyxDQUFBO1NBQ2pCO0lBRUgsQ0FBQzs7b0hBaFlVLHVCQUF1Qjt3R0FBdkIsdUJBQXVCLGdTQ1hwQyw4ekhBMkRNOzJGRGhETyx1QkFBdUI7a0JBSm5DLFNBQVM7K0JBQ0UsbUJBQW1CO29HQWdEWixvQkFBb0I7c0JBQXBDLE1BQU07Z0JBQ1UsU0FBUztzQkFBekIsTUFBTTtnQkFDVSw0QkFBNEI7c0JBQTVDLE1BQU07Z0JBQ0UsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUdGLGVBQWU7c0JBRGxCLEtBQUs7dUJBQUMsaUJBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiXG5cblxuaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IG1vbWVudCBmcm9tICcuLy4uLy4uLy4uL21vbWVudC1oZWxwZXInO1xuaW1wb3J0IHsgQ29tbW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2NvbW1vbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1nYW1tYS1oZWF0bWFwJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dhbW1hLWhlYXRtYXAuY29tcG9uZW50Lmh0bWwnLFxufSlcbmV4cG9ydCBjbGFzcyBHYW1tYUhlYXRDaGFydENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIGlzSnNvblByZXZpZXc6IGJvb2xlYW5cbiAgZGF0YVNvdXJzZUZvclRhYmxlOiBhbnkgPSBbXTtcbiAganNhb25EYXRhc291cmNlOiBhbnk7XG4gIGNvbmZpZ0NvbHVtZTogYW55O1xuICBpc0xvYWRlcjogYm9vbGVhbiA9IHRydWU7XG4gIHRhYmxlRGF0YUNvbmZpZzogYW55ID0ge307XG4gIGVucmljaE5hbWVMaXN0ID0gW1wiZm9ybWF0Qnl0ZXNcIiwgXCJmb3JtYXRCeXRzVG9LYlwiLCBcImZvcm1hdEJ5dHNUb0diXCIsIFwicmVmb3JtYXROdW1iZXJXaXRoVGhvdXNhbmRTZXBhcmF0b3JWM1wiLCBcImZvcm1hdEJ5dGVzdjJcIl1cbiAgcGFnZV9jb25maWc6IGFueTtcbiAgcGFnZV9wYXJtczogYW55O1xuICBwYWdlX3NlbGVjdGVkX29wZXJhdG9yOiBhbnk7XG4gIGFjdGl2ZVRhYjogc3RyaW5nID0gJ2Jhc2ljJztcblxuICB0YWJsZUhlaWdodDogYW55O1xuXG5cbiAgaXNBZHZhbmNlRmlsdGVyOiBib29sZWFuID0gZmFsc2U7XG4gIGlzSGVhdE1hcENsaWNrOiBib29sZWFuID0gZmFsc2U7XG5cbiAgaGVhdENoYXJ0RGF0YVNvdXJjZTogYW55ID0ge307XG4gIGNoYXJ0RGF0YUZvclRvb2x0aXA6IGFueSA9IHt9O1xuXG5cblxuICBkYXRhU291cnNlRm9ySGVhdE1hcDogYW55ID0gW107XG4gIHNlbGVjdGVkVmlld0NvbmZpZ3M6IGFueTtcblxuICB2aWV3UHJvcGVydGllczogYW55ID0ge1xuICAgIGVuYWJsZUNsaWNrRXZlbnQ6IGZhbHNlLFxuICAgIGVuYWJsZVJpZ2h0Q2xpY2tFdmVudDogdHJ1ZSxcbiAgICBjbGlja0V2ZW50T3B0aW9uczoge1xuICAgICAgYXNzb2NpYXRlZFZpZXdzOiBbXSxcbiAgICAgIGV2ZW50VHlwZTogXCJcIlxuICAgIH1cbiAgfTtcbiAgb3B0aW9uYWxEcmlsRG93bkRhdGFTb3VyY2U6IGFueSA9IFtdO1xuICBzZWxlY3RlZFRhYmxlVmlld1R5cGU6IGFueTtcblxuICBhbGxDb25maWd1cmVkVmlld3M6IGFueSA9IFtdO1xuICBjb2xvckFycmF5OiBhbnkgPSBbXTtcbiAgZmlyc3RDb2xvciA9IFwicmdiYSg0NSwgMTEwLCAxOCwgMSlcIjtcbiAgc2Vjb25kQ29sb3IgPSBcInJnYmEoMjU1LCAyMDQsIDAsIDEpXCI7XG4gIHNpbmdsZUNvbG9yID0gXCJyZ2JhKDI1NSwgMjA0LCAwLCAxKVwiO1xuXG4gIGhlYXRtYXBDaGFydENvbmZpZzogYW55ID0ge307XG4gIEBPdXRwdXQoKSBwdWJsaWMgZ2V0VGFibGVDb25maWdPdXRQdXQ6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcHVibGljIG9Sb3dDbGljazogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb25yaWdodENsaWNrQ29udGV4dFNlbGVjdGlvbjogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBJbnB1dCgpIHJpZ2h0Q2xpY2tFbmFibGU6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIEBJbnB1dCgnY2hhcnREYXRhU291cmNlJylcbiAgc2V0IGNoYXJ0RGF0YVNvdXJjZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzTG9hZGVyID0gdHJ1ZTtcbiAgICAgIHRoaXMucGFnZV9jb25maWcgPSB2YWx1ZTtcbiAgICAgIHRoaXMucGFnZV9wYXJtcyA9IHZhbHVlLnRpdGxlUGFyYW1zO1xuICAgICAgaWYgKHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlICYmIHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICBcbiAgICAgICAgdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcgPSB2YWx1ZS5rcGlDb25maWcuZGF0YUNvbmZpZztcbiAgICAgICAgdGhpcy5jb2xvckFycmF5ID0gdmFsdWUua3BpQ29uZmlnLmRhdGFDb25maWcuY29sb3I7XG4gICAgICAgIHRoaXMuZ2V0SGVhdG1hcERhdGEodmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2UpO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLmlzTG9hZGVyID0gZmFsc2U7XG4gICAgICAgIH0sIDIwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLmRhdGFTb3Vyc2VGb3JUYWJsZSA9IFtdO1xuICAgICAgICAgIHRoaXMudGFibGVEYXRhQ29uZmlnWydjb2x1bW5zJ10gPSBbXTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGVyID0gZmFsc2U7XG4gICAgICAgIH0sIDIwMCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIGNvbW1vblNlcnZpY2U6IENvbW1vblNlcnZpY2UpIHsgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICB9XG5cbiAgZ2V0SGVhdG1hcERhdGEoaGVhdE1hcERhdGEpIHtcblxuICAgICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2UgPSB7fTtcbiAgICAgICAgdGhpcy5pc0FkdmFuY2VGaWx0ZXIgPSBmYWxzZTtcblxuICAgICAgICBpZiAoaGVhdE1hcERhdGEgJiYgaGVhdE1hcERhdGEubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY2hhcnRGb3JtYXQgPT0gXCJ0b3B4XCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHJlc3VsdCwgdW5pcXVlRGF0ZXMgfSA9IHRoaXMuZ2VuZXJhdGVEYXRlV2lzZUNvbG9yQ29kZWREYXRhKGhlYXRNYXBEYXRhKTtcbiAgICAgICAgICAgICAgICB1bmlxdWVEYXRlcy5zb3J0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlLmRhdGFTZXQgPSB0aGlzLmdldFRyYW5zcG9zZWRIZWF0bWFwRGF0YShyZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImFyZ3VtZW50VmFsdWVcIl0gPSB1bmlxdWVEYXRlcztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNoYXJ0Rm9ybWF0ID09IFwic2ltcGxlXCIpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyByZXN1bHQsIHVuaXF1ZURhdGVzIH0gPSB0aGlzLmdlbmVyYXRlRGF0YShoZWF0TWFwRGF0YSk7XG4gICAgICAgICAgICAgICAgdW5pcXVlRGF0ZXMuc29ydCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImRhdGFTZXRcIl0gPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlW1wiYXJndW1lbnRWYWx1ZVwiXSA9IHVuaXF1ZURhdGVzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmlzSGVhdE1hcENsaWNrID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmlzSGVhdE1hcENsaWNrID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgIC8vIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZSA9IHt9O1xuICAgIC8vIHRoaXMuaXNBZHZhbmNlRmlsdGVyID0gZmFsc2U7XG5cbiAgICAvLyBpZiAoaGVhdE1hcERhdGEgJiYgaGVhdE1hcERhdGEubGVuZ3RoICE9PSAwKSB7XG4gICAgLy8gICBjb25zdCB7IHJlc3VsdCwgdW5pcXVlRGF0ZXMgfSA9IHRoaXMuZ2VuZXJhdGVEYXRhKGhlYXRNYXBEYXRhKVxuICAgIC8vICAgdW5pcXVlRGF0ZXMuc29ydCgpO1xuICAgIC8vICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlW1wiZGF0YVNldFwiXSA9IHJlc3VsdDtcbiAgICAvLyAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImFyZ3VtZW50VmFsdWVcIl0gPSB1bmlxdWVEYXRlcztcbiAgICAvLyAgIHRoaXMuaXNIZWF0TWFwQ2xpY2sgPSBmYWxzZTtcbiAgICAvLyB9IGVsc2Uge1xuICAgIC8vICAgdGhpcy5pc0hlYXRNYXBDbGljayA9IGZhbHNlO1xuICAgIC8vIH1cblxuXG4gIH1cblxuICAgZ2V0VHJhbnNwb3NlZEhlYXRtYXBEYXRhKGRhdGFTZXQ6IGFueVtdKTogYW55W10ge1xuICAgICAgICAgIGNvbnN0IHRyYW5zcG9zZWQ6IGFueVtdID0gW107XG4gICAgICAgICAgY29uc3QgbWF4Qm94ZXMgPSBNYXRoLm1heCguLi5kYXRhU2V0Lm1hcChpdGVtID0+IGl0ZW0uZGF0YXNldC5sZW5ndGgpKTtcbiAgXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXhCb3hlczsgaSsrKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJvdzogYW55W10gPSBbXTtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBkYXRhU2V0Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBib3ggPSBkYXRhU2V0W2pdLmRhdGFzZXRbaV07XG4gICAgICAgICAgICAgICAgICByb3cucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgYm94OiBib3ggfHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICBkYXRlOiBkYXRhU2V0W2pdLnJlY29yZF9kYXRlXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0cmFuc3Bvc2VkLnB1c2gocm93KTtcbiAgICAgICAgICB9XG4gIFxuICAgICAgICAgIHJldHVybiB0cmFuc3Bvc2VkO1xuICAgICAgfVxuICBcbiAgICAgIGdlbmVyYXRlRGF0ZVdpc2VDb2xvckNvZGVkRGF0YShkYXRhOiBhbnlbXSkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdDogYW55W10gPSBbXTtcbiAgICAgICAgICBjb25zdCB1bmlxdWVEYXRlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICBjb25zdCBhbGxFbnRyaWVzOiBhbnlbXSA9IFtdO1xuICBcbiAgICAgICAgICBjb25zdCB0b3BBcmcgPSB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50b3BBcmd1bWVudDtcbiAgICAgICAgICBjb25zdCBsZWZ0QXJnID0gdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcubGVmdEFyZ3VtZW50O1xuICAgICAgICAgIGNvbnN0IHZhbHVlRmllbGQgPSB0aGlzLmhlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmRhdGFGaWVsZDtcbiAgXG4gICAgICAgICAgZGF0YS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkRGF0ZSA9IChtb21lbnQoZW50cnlbdG9wQXJnXSkuZm9ybWF0KCdZWVlZLU1NLUREJykpID8gbW9tZW50KGVudHJ5W3RvcEFyZ10pLmZvcm1hdCgnWVlZWS1NTS1ERCcpIDogdG9wQXJnO1xuICAgICAgICAgICAgICB1bmlxdWVEYXRlcy5hZGQoZm9ybWF0dGVkRGF0ZSk7XG4gIFxuICAgICAgICAgICAgICBlbnRyeS5yZXN1bHREYXRhc2V0LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICBhbGxFbnRyaWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgIFt0b3BBcmddOiBmb3JtYXR0ZWREYXRlLFxuICAgICAgICAgICAgICAgICAgICAgIFtsZWZ0QXJnXTogaXRlbVtgJHtsZWZ0QXJnfWBdLFxuICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZUZpZWxkXTogaXRlbVtgJHt2YWx1ZUZpZWxkfWBdXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gIFxuICAgICAgICAgIGxldCBjb2xvcmVkRGF0YTtcbiAgICAgICAgICBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PT0gJ2dyYWRpZW50Jykge1xuICAgICAgICAgICAgICBjb2xvcmVkRGF0YSA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvckdyYWRpZW50KGFsbEVudHJpZXMsIHZhbHVlRmllbGQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudHlwZSA9PT0gJ3R3b0NvbG9yJykge1xuICAgICAgICAgICAgICBjb2xvcmVkRGF0YSA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvcldpdGhUd29Db2xvcihhbGxFbnRyaWVzLCB2YWx1ZUZpZWxkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb2xvcmVkRGF0YSA9IHRoaXMuZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZUZvcldpdGhTaW5nbGVDb2xvcihhbGxFbnRyaWVzLCB2YWx1ZUZpZWxkKTtcbiAgICAgICAgICB9XG4gIFxuICAgICAgICAgIGNvbnN0IGRhdGVNYXA6IHsgW2RhdGU6IHN0cmluZ106IGFueVtdIH0gPSB7fTtcbiAgXG4gICAgICAgICAgY29sb3JlZERhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZGF0ZTogYW55ID0gaXRlbVt0b3BBcmddO1xuICBcbiAgICAgICAgICAgICAgaWYgKCFkYXRlTWFwW2RhdGVdKSB7XG4gICAgICAgICAgICAgICAgICBkYXRlTWFwW2RhdGVdID0gW107XG4gICAgICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgICAgIGRhdGVNYXBbZGF0ZV0ucHVzaCh7XG4gICAgICAgICAgICAgICAgICBbbGVmdEFyZ106IGl0ZW1bbGVmdEFyZ10sXG4gICAgICAgICAgICAgICAgICBbdmFsdWVGaWVsZF06IGl0ZW1bdmFsdWVGaWVsZF0sXG4gICAgICAgICAgICAgICAgICBjb2xvcjogaXRlbS5jb2xvcixcbiAgICAgICAgICAgICAgICAgIFt0b3BBcmddOiBkYXRlLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgXG4gICAgICAgICAgLy8gU3RlcCA0OiBCdWlsZCBmaW5hbCByZXN1bHRcbiAgICAgICAgICBmb3IgKGNvbnN0IGRhdGUgb2YgQXJyYXkuZnJvbSh1bmlxdWVEYXRlcykuc29ydCgpIGFzIHN0cmluZ1tdKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIHJlY29yZF9kYXRlOiBkYXRlLFxuICAgICAgICAgICAgICAgICAgZGF0YXNldDogZGF0ZU1hcFtkYXRlXSB8fCBbXVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gIFxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgdW5pcXVlRGF0ZXM6IEFycmF5LmZyb20odW5pcXVlRGF0ZXMpLnNvcnQoKVxuICAgICAgICAgIH07XG4gICAgICB9XG5cbiAgZ2VuZXJhdGVEYXRhKGRhdGEpIHtcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBjb25zdCB1bmlxdWVEYXRlcyA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBkYXRhU291cmNlTWFwID0ge307XG4gICAgY29uc3QgdG9wQXJnID0gdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcudG9wQXJndW1lbnQ7XG4gICAgY29uc3QgbGVmdEFyZyA9IHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmxlZnRBcmd1bWVudDtcblxuICAgIGRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGNvbnN0IHJvd0tleSA9IGl0ZW1bbGVmdEFyZ107XG4gICAgICBjb25zdCBjb2x1bW5LZXkgPSBtb21lbnQoaXRlbVt0b3BBcmddKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcblxuICAgICAgaWYgKCFkYXRhU291cmNlTWFwW3Jvd0tleV0pIHtcbiAgICAgICAgZGF0YVNvdXJjZU1hcFtyb3dLZXldID0ge1xuICAgICAgICAgIGRhdGFzb3VyY2U6IHJvd0tleSxcbiAgICAgICAgICBkYXRhc2V0OiBbXVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBkYXRhU291cmNlTWFwW3Jvd0tleV0uZGF0YXNldC5wdXNoKHtcbiAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgW3RvcEFyZ106IGNvbHVtbktleVxuICAgICAgfSk7XG5cbiAgICAgIHVuaXF1ZURhdGVzLmFkZChjb2x1bW5LZXkpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgdW5pcXVlRGF0ZXNBcnJheSA9IEFycmF5LmZyb20odW5pcXVlRGF0ZXMpO1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gZGF0YVNvdXJjZU1hcCkge1xuICAgICAgY29uc3QgZGF0YXNldCA9IGRhdGFTb3VyY2VNYXBba2V5XS5kYXRhc2V0O1xuICAgICAgbGV0IGZvcm1hdHRlZERhdGFzZXQ7XG5cbiAgICAgIGlmICh0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50eXBlID09IFwiZ3JhZGllbnRcIikge1xuICAgICAgICBmb3JtYXR0ZWREYXRhc2V0ID0gdGhpcy5nZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yR3JhZGllbnQoZGF0YXNldCwgdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY29sdW1uc1swXS5kYXRhRmllbGQpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmhlYXRtYXBDaGFydENvbmZpZy50eXBlID09IFwidHdvQ29sb3JcIikge1xuICAgICAgICBmb3JtYXR0ZWREYXRhc2V0ID0gdGhpcy5nZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yV2l0aFR3b0NvbG9yKGRhdGFzZXQsIHRoaXMuaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvcm1hdHRlZERhdGFzZXQgPSB0aGlzLmdldEZvcm1hdGVEYXRhQnlDb2xvckNvZGVGb3JXaXRoU2luZ2xlQ29sb3IoZGF0YXNldCwgdGhpcy5oZWF0bWFwQ2hhcnRDb25maWcuY29sdW1uc1swXS5kYXRhRmllbGQpO1xuXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRhdGVUb0l0ZW1NYXAgPSB7fTtcbiAgICAgIGZvcm1hdHRlZERhdGFzZXQuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgZGF0ZVRvSXRlbU1hcFtpdGVtW3RvcEFyZ11dID0gaXRlbTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb21wbGV0ZURhdGFzZXQgPSB1bmlxdWVEYXRlc0FycmF5Lm1hcCgoZGF0ZTogYW55KSA9PiB7XG4gICAgICAgIGlmIChkYXRlVG9JdGVtTWFwW2RhdGVdKSB7XG4gICAgICAgICAgcmV0dXJuIGRhdGVUb0l0ZW1NYXBbZGF0ZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFt0b3BBcmddOiBkYXRlLFxuICAgICAgICAgICAgYXZnU2l6ZTogXCJObyBEYXRhXCIsXG4gICAgICAgICAgICBmaWxlQ291bnQ6IDAsXG4gICAgICAgICAgICBmaWxlU2l6ZTogMCxcbiAgICAgICAgICAgIGNvbG9yOiBcInJnYigyNDIsIDExOCwgMTA5KVwiXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgZGF0YXNvdXJjZToga2V5LFxuICAgICAgICBkYXRhc2V0OiBjb21wbGV0ZURhdGFzZXRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZXN1bHQ6IHJlc3VsdCxcbiAgICAgIHVuaXF1ZURhdGVzOiB1bmlxdWVEYXRlc0FycmF5XG4gICAgfTtcbiAgfVxuXG5cblxuICBnZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlRm9yR3JhZGllbnQoZmlsZWRhdGEsIGNvbHVtbikge1xuICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpdGVtLmF2Z1NpemUgPSBwYXJzZUZsb2F0KGl0ZW1bY29sdW1uXSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBtYXhBdmdTaXplID0gTWF0aC5tYXgoLi4uZmlsZWRhdGEubWFwKGl0ZW0gPT4gaXRlbVtjb2x1bW5dKSk7XG4gICAgY29uc3QgbWluQXZnU2l6ZSA9IE1hdGgubWluKC4uLmZpbGVkYXRhLm1hcChpdGVtID0+IGl0ZW1bY29sdW1uXSkpO1xuXG4gICAgY29uc3QgW21pbkNvbG9yU3RyLCBtYXhDb2xvclN0cl0gPSB0aGlzLmNvbG9yQXJyYXkgfHwgW1wicmdiYSg0NSwgMTEwLCAxOCwxKVwiLCBcInJnYmEoMjU1LCAyMDQsIDAsMSlcIl07XG4gICAgY29uc3QgbWluQ29sb3IgPSB0aGlzLnBhcnNlUkdCQShtaW5Db2xvclN0cik7XG4gICAgY29uc3QgbWF4Q29sb3IgPSB0aGlzLnBhcnNlUkdCQShtYXhDb2xvclN0cik7XG5cbiAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaXRlbS5jb2xvciA9IHRoaXMuY2FsY3VsYXRlQ29sb3IoaXRlbVtjb2x1bW5dLCBtaW5BdmdTaXplLCBtYXhBdmdTaXplLCBtaW5Db2xvciwgbWF4Q29sb3IpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZpbGVkYXRhO1xuICB9XG4gIGdldEZvcm1hdGVEYXRhQnlDb2xvckNvZGVGb3JXaXRoVHdvQ29sb3IoZmlsZWRhdGEsIGNvbHVtbikge1xuICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpdGVtW2NvbHVtbl0gPSBwYXJzZUZsb2F0KGl0ZW1bY29sdW1uXSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBbbWluQ29sb3JTdHIsIG1heENvbG9yU3RyXSA9IHRoaXMuY29sb3JBcnJheSB8fCBbXCJyZ2JhKDQ1LCAxMTAsIDE4LDEpXCIsIFwicmdiYSgyNTUsIDIwNCwgMCwxKVwiXTtcbiAgICBjb25zdCBtaW5Db2xvciA9IHRoaXMucGFyc2VSR0JBKG1pbkNvbG9yU3RyKTtcbiAgICBjb25zdCBtYXhDb2xvciA9IHRoaXMucGFyc2VSR0JBKG1heENvbG9yU3RyKTtcblxuICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpZiAoaXRlbVtjb2x1bW5dID09IDApIHtcbiAgICAgICAgaXRlbS5jb2xvciA9IGByZ2IoJHttaW5Db2xvci5qb2luKCcsJyl9KWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtLmNvbG9yID0gYHJnYigke21heENvbG9yLmpvaW4oJywnKX0pYDtcbiAgICAgIH1cblxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZpbGVkYXRhO1xuICB9XG4gIGdldEZvcm1hdGVEYXRhQnlDb2xvckNvZGVGb3JXaXRoU2luZ2xlQ29sb3IoZmlsZWRhdGEsIGNvbHVtbikge1xuICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpdGVtW2NvbHVtbl0gPSBwYXJzZUZsb2F0KGl0ZW1bY29sdW1uXSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBbc2luZ2xlQ29sb3JdID0gdGhpcy5jb2xvckFycmF5IHx8IFtcInJnYmEoMjU1LCAyMDQsIDAsMSlcIl07XG4gICAgY29uc3QgbWluQ29sb3IgPSB0aGlzLnBhcnNlUkdCQShzaW5nbGVDb2xvcik7XG5cbiAgICBmaWxlZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaXRlbS5jb2xvciA9IGByZ2IoJHttaW5Db2xvci5qb2luKCcsJyl9KWA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmlsZWRhdGE7XG4gIH1cblxuICBwYXJzZVJHQkEoY29sb3JTdHI6IHN0cmluZyk6IG51bWJlcltdIHtcbiAgICBjb25zdCB2YWx1ZXMgPSBjb2xvclN0ci5tYXRjaCgvW1xcZC5dKy9nKT8ubWFwKE51bWJlcikgfHwgW107XG4gICAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDMpIHZhbHVlcy5wdXNoKDEpO1xuICAgIHJldHVybiBbXG4gICAgICB2YWx1ZXNbMF0gPz8gMCxcbiAgICAgIHZhbHVlc1sxXSA/PyAwLFxuICAgICAgdmFsdWVzWzJdID8/IDAsXG4gICAgICB2YWx1ZXNbM10gPz8gMVxuICAgIF07XG4gIH1cblxuICBjYWxjdWxhdGVDb2xvcihhdmdTaXplLCBtaW5BdmdTaXplLCBtYXhBdmdTaXplLCBtaW5Db2xvciwgbWF4Q29sb3IpIHtcbiAgICBpZiAobWluQXZnU2l6ZSAhPSBtYXhBdmdTaXplKSB7XG4gICAgICBsZXQgZ3JhZGllbnQgPSAoYXZnU2l6ZSAtIG1pbkF2Z1NpemUpIC8gKG1heEF2Z1NpemUgLSBtaW5BdmdTaXplKTtcbiAgICAgIGxldCBjb2xvciA9IG1pbkNvbG9yLm1hcCgoY2hhbm5lbCwgaW5kZXgpID0+IHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoY2hhbm5lbCArIGdyYWRpZW50ICogKG1heENvbG9yW2luZGV4XSAtIGNoYW5uZWwpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGByZ2IoJHtjb2xvci5qb2luKCcsJyl9KWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgcmdiKCR7bWluQ29sb3Iuam9pbignLCcpfSlgXG4gICAgfVxuXG4gIH1cblxuXG5cbiAgdHJhbnNmb3JtQ29sdW1ucyhtYWlub2JqOiBhbnkpOiBhbnlbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG1haW5vYmopLm1hcChrZXkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgZGF0YUZpZWxkOiBrZXksXG4gICAgICAgIGNhcHRpb246IGtleVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICBnZXRPYmplY3RLZXlzKG9iajogYW55KTogc3RyaW5nW10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhvYmopO1xuICB9XG5cblxuICBjYWxsU2VydmljZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZTogc3RyaW5nLCB2YWx1ZSk6IGFueSB7XG5cbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLmNvbW1vblNlcnZpY2VbZnVuY3Rpb25OYW1lXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbW1vblNlcnZpY2VbZnVuY3Rpb25OYW1lXSh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBGdW5jdGlvbiAke2Z1bmN0aW9uTmFtZX0gbm90IGZvdW5kIGluIENvbW1vblNlcnZpY2VgKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBcIk5vIERhdGFcIlxuICAgIH1cblxuICB9XG5cblxufVxuIiwiPGRpdiBjbGFzcz1cIm14LTIgYmctZ3JheS04MDBcIj5cbiAgICA8YXBwLWxvYWRlciAqbmdJZj1cImlzTG9hZGVyXCI+PC9hcHAtbG9hZGVyPlxuICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0xvYWRlclwiPlxuICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoZWF0bWFwQ2hhcnRDb25maWcuY2hhcnRGb3JtYXQgPT0gJ3NpbXBsZSdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXgtNSBoLVs2MHZoXSBvdmVyZmxvdy14LWF1dG9cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlubGluZS1ibG9ja1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1ub3dyYXAganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1zaHJpbmstMCB3LTY0IG1heC13LVsyMCVdIGgtMTAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBpdGVtIG9mIGhlYXRDaGFydERhdGFTb3VyY2UuYXJndW1lbnRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxleC1zaHJpbmstMCBtaW4tdy0yMiBtYXgtdy1bMjAlXSBoLTggdGV4dC1zbSBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2l0ZW19fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGhlYXRDaGFydERhdGFTb3VyY2UuZGF0YVNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaC04IGZsZXggdGV4dC1zbSBpdGVtcy1jZW50ZXIgbWluLXctNjQganVzdGlmeS1lbmQgcHgtMiBpbmxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgaXRlbS5kYXRhc291cmNlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlubGluZS1ibG9ja1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LW5vd3JhcCBqdXN0aWZ5LXN0YXJ0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBib3ggb2YgaXRlbS5kYXRhc2V0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTAgbWluLXctMjIgbWF4LXctWzIwJV0gaC04IGJvcmRlci0yIHRleHQtc20gY3Vyc29yLXBvaW50ZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgdGV4dC1ncmF5LTgwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ2JhY2tncm91bmQtY29sb3InOiBib3guY29sb3IgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLnRpdGxlXT1cIidSZWNvcmQgRGF0ZTogJyArIGJveFtoZWF0bWFwQ2hhcnRDb25maWcudG9wQXJndW1lbnRdICsgJywgVmFsdWU6ICcgKyBib3hbaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkXVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBib3hbaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkXX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoZWF0bWFwQ2hhcnRDb25maWcuY2hhcnRGb3JtYXQgPT0gJ3RvcHgnXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm14LTUgaC1bNjB2aF0gb3ZlcmZsb3cteC1hdXRvXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBoZWFkZXIgb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5hcmd1bWVudFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbi13LTMyIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1jZW50ZXIgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBoZWFkZXIgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCByb3cgb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5kYXRhU2V0XCIgY2xhc3M9XCJmbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjZWxsIG9mIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjZWxsLmJveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaC04IGJvcmRlci0yIHRleHQtc20gY3Vyc29yLXBvaW50ZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgdGV4dC1ncmF5LTgwMCBtaW4tdy0zMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ2JhY2tncm91bmQtY29sb3InOiBjZWxsLmJveC5jb2xvciB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIudGl0bGVdPVwiJ1JlY29yZCBEYXRlOiAnICsgY2VsbC5ib3hbaGVhdG1hcENoYXJ0Q29uZmlnLnRvcEFyZ3VtZW50XSArICcsIFZhbHVlOiAnICsgY2VsbC5ib3hbaGVhdG1hcENoYXJ0Q29uZmlnLmNvbHVtbnNbMF0uZGF0YUZpZWxkXVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjZWxsLmJveFtoZWF0bWFwQ2hhcnRDb25maWcubGVmdEFyZ3VtZW50XSB9fSAoe3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uU2VydmljZS5hYmJyZXZpYXRlTnVtYmVyKGNlbGwuYm94W2hlYXRtYXBDaGFydENvbmZpZy5jb2x1bW5zWzBdLmRhdGFGaWVsZF0pIH19KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhY2VsbC5ib3hcIiBjbGFzcz1cImgtOCBtaW4tdy0zMlwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuPC9kaXY+Il19
|