gamma-app-controller 1.1.26 → 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.
Files changed (119) hide show
  1. package/esm2020/lib/application-controller/application-controller.module.mjs +20 -20
  2. package/esm2020/lib/application-controller/application-dataset-component/application-dataset/application-dataset.component.mjs +1 -1
  3. package/esm2020/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.mjs +1 -1
  4. package/esm2020/lib/application-controller/application-filter/application-filter.component.mjs +1 -1
  5. package/esm2020/lib/application-controller/application-menu-controller/application-menus/application-menus.component.mjs +1 -1
  6. package/esm2020/lib/application-controller/application-metric-config/all-metrics-config/all-metrics-config.component.mjs +1 -1
  7. package/esm2020/lib/application-controller/application-metric-config/create-metrics/create-metrics.component.mjs +1 -1
  8. package/esm2020/lib/application-controller/application-view-components/application-views/application-views.component.mjs +1 -1
  9. package/esm2020/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.mjs +1 -1
  10. package/esm2020/lib/application-controller/page-controller/page-config/page-config.component.mjs +11 -11
  11. package/esm2020/lib/application-controller/page-controller/page-config-multi-layout/page-config-multi-layout.component.mjs +10 -10
  12. package/esm2020/lib/application-controller/page-controller/page-controller/page-controller.component.mjs +1 -1
  13. package/esm2020/lib/application-controller/support-components/dash-chart/dash-chart.component.mjs +1 -1
  14. package/esm2020/lib/application-controller/support-components/dash-table/dash-table.component.mjs +1 -1
  15. package/esm2020/lib/application-controller/support-components/dash-today-previous/dash-today-previous.component.mjs +1 -1
  16. package/esm2020/lib/application-controller/support-components/geo-map/geo-map.component.mjs +2 -2
  17. package/esm2020/lib/application-controller/support-components/heat-map/heat-map.component.mjs +1 -1
  18. package/esm2020/lib/application-controller/support-components/single-card/single-card.component.mjs +1 -1
  19. package/esm2020/lib/application-controller/support-components/table-with-bar/table-with-bar.component.mjs +2 -2
  20. package/esm2020/lib/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +116 -0
  21. package/esm2020/lib/shared/advanced-component/app-advance-header/app-header.component.mjs +306 -0
  22. package/esm2020/lib/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +80 -0
  23. package/esm2020/lib/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +379 -0
  24. package/esm2020/lib/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +188 -0
  25. package/esm2020/lib/shared/advanced-component/gamma-geo-chart/gamma-geo-chart.component.mjs +435 -0
  26. package/esm2020/lib/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.mjs +334 -0
  27. package/esm2020/lib/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +155 -0
  28. package/esm2020/lib/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +20 -0
  29. package/esm2020/lib/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +187 -0
  30. package/esm2020/lib/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +86 -0
  31. package/esm2020/lib/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +439 -0
  32. package/esm2020/lib/shared/app-title/app-title.component.mjs +67 -0
  33. package/esm2020/lib/shared/gamam-widget/gamam-widget.component.mjs +35 -0
  34. package/esm2020/lib/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +273 -0
  35. package/esm2020/lib/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +142 -0
  36. package/esm2020/lib/shared/kpi-comon-service.mjs +537 -0
  37. package/esm2020/lib/{application-controller/shared → shared}/loader/loader.component.mjs +1 -1
  38. package/esm2020/lib/{application-controller/shared → shared}/loading/loading.component.mjs +1 -1
  39. package/esm2020/lib/shared/loading/loadingModule.mjs +28 -0
  40. package/esm2020/lib/shared/safeHtmlPipe.mjs +20 -0
  41. package/esm2020/lib/template-module/KpiCreationModule/create-kpi-tree.component.mjs +1 -1
  42. package/esm2020/lib/template-module/KpiCreationModule/kpiCreation.module.mjs +2 -2
  43. package/esm2020/lib/template-module/bookmarked-template/bookmarked-template.component.mjs +816 -0
  44. package/esm2020/lib/template-module/bookmarked-template/bookmarkedTemplate.module.mjs +149 -0
  45. package/esm2020/lib/template-module/cdrConfigModule/cdr-config.component.mjs +1 -1
  46. package/esm2020/lib/template-module/cdrConfigModule/cdrConfig.module.mjs +2 -2
  47. package/esm2020/lib/template-module/defaulLandingComponent/defaultLandingComponent.module.mjs +149 -0
  48. package/esm2020/lib/template-module/defaulLandingComponent/landing-component.component.mjs +870 -0
  49. package/esm2020/lib/template-module/exceptionConfigModule/exception-operation.component.mjs +1 -1
  50. package/esm2020/lib/template-module/exceptionConfigModule/exceptionConfig.module.mjs +2 -2
  51. package/esm2020/lib/template-module/kpiWithMultiLayout/dynamin-modal-multi.component.mjs +180 -0
  52. package/esm2020/lib/template-module/kpiWithMultiLayout/kpi-with-multilayout.component.mjs +992 -0
  53. package/esm2020/lib/template-module/kpiWithMultiLayout/kpiWithMultiayout.module.mjs +154 -0
  54. package/esm2020/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.mjs +180 -0
  55. package/esm2020/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.mjs +1046 -0
  56. package/esm2020/lib/template-module/kpiWithSingleLayout/kpiWithSingleLayout.module.mjs +154 -0
  57. package/esm2020/public-api.mjs +30 -20
  58. package/fesm2015/gamma-app-controller.mjs +5121 -399
  59. package/fesm2015/gamma-app-controller.mjs.map +1 -1
  60. package/fesm2020/gamma-app-controller.mjs +5082 -399
  61. package/fesm2020/gamma-app-controller.mjs.map +1 -1
  62. package/lib/application-controller/application-controller.module.d.ts +19 -19
  63. package/lib/application-controller/page-controller/page-config/page-config.component.d.ts +9 -9
  64. package/lib/application-controller/page-controller/page-config-multi-layout/page-config-multi-layout.component.d.ts +8 -8
  65. package/lib/{application-controller/shared → shared}/advanced-component/app-advance-header/app-header.component.d.ts +18 -2
  66. package/lib/{application-controller/shared → shared}/advanced-component/gamm-single-number-card/gamm-single-number-card.component.d.ts +3 -5
  67. package/lib/{application-controller/shared → shared}/advanced-component/gamma-advance-chart/gamma-advance-chart.component.d.ts +3 -1
  68. package/lib/{application-controller/shared → shared}/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.d.ts +4 -2
  69. package/lib/{application-controller/shared → shared}/advanced-component/gamma-geo-chart/gamma-geo-chart.component.d.ts +1 -1
  70. package/lib/{application-controller/shared → shared}/advanced-component/gamma-heatmap/gamma-heatmap.component.d.ts +1 -1
  71. package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.d.ts +1 -1
  72. package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.d.ts +6 -2
  73. package/lib/{application-controller/shared → shared}/advanced-component/gamma-today-previous/gamma-today-previous.component.d.ts +1 -1
  74. package/lib/{application-controller/shared → shared}/advanced-component/google-geo-map/google-geo-map.component.d.ts +1 -1
  75. package/lib/{application-controller/shared → shared}/app-title/app-title.component.d.ts +1 -1
  76. package/lib/{application-controller/shared → shared}/gamam-widget/gamam-widget.component.d.ts +1 -1
  77. package/lib/{application-controller/shared → shared}/gamma-advance-filter/gamma-advance-filter.component.d.ts +3 -2
  78. package/lib/{application-controller/shared → shared}/gamma-bread-crumbs/bread-crumbs.component.d.ts +1 -1
  79. package/lib/{application-controller/shared → shared}/kpi-comon-service.d.ts +1 -1
  80. package/lib/template-module/KpiCreationModule/kpiCreation.module.d.ts +1 -1
  81. package/lib/template-module/bookmarked-template/bookmarked-template.component.d.ts +109 -0
  82. package/lib/template-module/bookmarked-template/bookmarkedTemplate.module.d.ts +16 -0
  83. package/lib/template-module/cdrConfigModule/cdrConfig.module.d.ts +1 -1
  84. package/lib/template-module/defaulLandingComponent/defaultLandingComponent.module.d.ts +16 -0
  85. package/lib/template-module/defaulLandingComponent/landing-component.component.d.ts +109 -0
  86. package/lib/template-module/exceptionConfigModule/exceptionConfig.module.d.ts +1 -1
  87. package/lib/template-module/kpiWithMultiLayout/dynamin-modal-multi.component.d.ts +42 -0
  88. package/lib/template-module/kpiWithMultiLayout/kpi-with-multilayout.component.d.ts +117 -0
  89. package/lib/template-module/kpiWithMultiLayout/kpiWithMultiayout.module.d.ts +17 -0
  90. package/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.d.ts +42 -0
  91. package/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.d.ts +122 -0
  92. package/lib/template-module/kpiWithSingleLayout/kpiWithSingleLayout.module.d.ts +17 -0
  93. package/package.json +1 -1
  94. package/public-api.d.ts +29 -19
  95. package/esm2020/lib/application-controller/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +0 -124
  96. package/esm2020/lib/application-controller/shared/advanced-component/app-advance-header/app-header.component.mjs +0 -220
  97. package/esm2020/lib/application-controller/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +0 -95
  98. package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +0 -362
  99. package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +0 -177
  100. package/esm2020/lib/application-controller/shared/advanced-component/gamma-geo-chart/gamma-geo-chart.component.mjs +0 -441
  101. package/esm2020/lib/application-controller/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.mjs +0 -328
  102. package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +0 -155
  103. package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +0 -20
  104. package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +0 -157
  105. package/esm2020/lib/application-controller/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +0 -85
  106. package/esm2020/lib/application-controller/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +0 -439
  107. package/esm2020/lib/application-controller/shared/app-title/app-title.component.mjs +0 -67
  108. package/esm2020/lib/application-controller/shared/gamam-widget/gamam-widget.component.mjs +0 -35
  109. package/esm2020/lib/application-controller/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +0 -237
  110. package/esm2020/lib/application-controller/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +0 -142
  111. package/esm2020/lib/application-controller/shared/kpi-comon-service.mjs +0 -537
  112. package/esm2020/lib/application-controller/shared/loading/loadingModule.mjs +0 -28
  113. package/esm2020/lib/application-controller/shared/safeHtmlPipe.mjs +0 -20
  114. /package/lib/{application-controller/shared → shared}/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.d.ts +0 -0
  115. /package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-with-percentage/contentSafeHtml.d.ts +0 -0
  116. /package/lib/{application-controller/shared → shared}/loader/loader.component.d.ts +0 -0
  117. /package/lib/{application-controller/shared → shared}/loading/loading.component.d.ts +0 -0
  118. /package/lib/{application-controller/shared → shared}/loading/loadingModule.d.ts +0 -0
  119. /package/lib/{application-controller/shared → shared}/safeHtmlPipe.d.ts +0 -0
@@ -0,0 +1,379 @@
1
+ import { Component, Input } 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 "ngx-toastr";
6
+ import * as i3 from "../../kpi-comon-service";
7
+ import * as i4 from "@angular/common";
8
+ import * as i5 from "devextreme-angular/core";
9
+ import * as i6 from "devextreme-angular/ui/nested";
10
+ import * as i7 from "devextreme-angular/ui/chart";
11
+ import * as i8 from "devextreme-angular/ui/funnel";
12
+ import * as i9 from "devextreme-angular/ui/pie-chart";
13
+ import * as i10 from "@angular/material/tooltip";
14
+ import * as i11 from "../../app-title/app-title.component";
15
+ import * as i12 from "../../loader/loader.component";
16
+ export class GammaAdvanceChartComponent {
17
+ constructor(commonService, toastr, kpiService, renderer, el, cdr) {
18
+ this.commonService = commonService;
19
+ this.toastr = toastr;
20
+ this.kpiService = kpiService;
21
+ this.renderer = renderer;
22
+ this.el = el;
23
+ this.cdr = cdr;
24
+ this.chartConfig = {};
25
+ this.page_config = {};
26
+ this.isLoader = true;
27
+ this.creatChartDataSource = undefined;
28
+ this.finalChartDataSource = [];
29
+ this.isFullScreen = false;
30
+ this.customizeTooltip = (info) => ({
31
+ html: `<table width=100% height=30 border=0 style=\'font-size: 13px\'>
32
+ <tr><td style=\'text-align: left; color: white\'> ${this.commonService.convertToTitleCase(this.chartConfig.argumentField)} : ${info.argumentText} </td></tr>
33
+ <tr><td style=\'text-align: left; color: white; padding-top: 5px\'> ${info.seriesName} :
34
+ ${this.getValue(info.seriesName, info.value)} </td></tr>
35
+ </table>`,
36
+ });
37
+ this.customizeText = ({ percentText, item: { argument } }) => `<span style='font-size: 28px'>${percentText}</span><br/>${argument}`;
38
+ }
39
+ set chartDataSource(value) {
40
+ this.creatChartDataSource = value;
41
+ if (this.creatChartDataSource === undefined || this.creatChartDataSource.length === 0) {
42
+ this.isChartvisible = false;
43
+ return;
44
+ }
45
+ else {
46
+ this.isLoader = true;
47
+ this.page_config = value;
48
+ this.chartOrderBy = (value.kpiConfig.descendingOrder) ? value.kpiConfig.descendingOrder : false;
49
+ this.chartDisplayDateFormat = (value.kpiConfig.displayDateFormat) ? value.kpiConfig.displayDateFormat : "MM-DD";
50
+ if (value.kpiConfig.dataSource && value.kpiConfig.dataSource.length !== 0) {
51
+ this.chartConfig = value.kpiConfig.dataConfig;
52
+ if (value.kpiConfig.formate == "daily") {
53
+ const sortedData = value.kpiConfig.dataSource
54
+ .filter(record => record.recordDate)
55
+ .sort((a, b) => moment(b.recordDate).diff(moment(a.recordDate)));
56
+ const mostRecentRecord = sortedData[0];
57
+ const filteredObjects = sortedData.filter(data => data.recordDate === value.endDate);
58
+ if (this.chartConfig.chartType == 'funnel') {
59
+ this.finalChartDataSource = Object.keys(mostRecentRecord).filter(key => key !== 'recordDate').map(key => ({
60
+ argument: key,
61
+ value: Math.abs(parseInt(mostRecentRecord[key]))
62
+ }));
63
+ console.log(this.finalChartDataSource);
64
+ }
65
+ else {
66
+ this.getDailyChart(filteredObjects, value.kpiConfig.dataConfig);
67
+ }
68
+ this.isLoader = false;
69
+ }
70
+ else if (value.kpiConfig.formate == "monthly") {
71
+ if (value.kpiConfig.dataSource && value.kpiConfig.dataSource.length !== 0) {
72
+ if (this.chartConfig.chartType == 'bubble') {
73
+ this.bubbleChartData = value.kpiConfig.dataSource;
74
+ this.getBubbleChartData();
75
+ }
76
+ else {
77
+ if (this.chartOrderBy) {
78
+ let shortName = value.kpiConfig.dataConfig['argumentField'].toLowerCase();
79
+ if (shortName.includes('date')) {
80
+ value.kpiConfig.dataSource = value.kpiConfig.dataSource
81
+ .filter(record => record[value.kpiConfig.dataConfig['argumentField']])
82
+ .sort((a, b) => moment(b[value.kpiConfig.dataConfig['argumentField']]).diff(moment(a[value.kpiConfig.dataConfig['argumentField']])));
83
+ }
84
+ }
85
+ this.getMonthlyChart(value.kpiConfig.dataSource, value.kpiConfig.dataConfig);
86
+ this.isChartvisible == true;
87
+ }
88
+ }
89
+ else {
90
+ this.cdr.detectChanges();
91
+ }
92
+ this.isLoader = false;
93
+ }
94
+ else if (value.kpiConfig.formate == "hourly") {
95
+ debugger;
96
+ if (value.kpiConfig.dataSource && value.kpiConfig.dataSource.length !== 0) {
97
+ const sortedData = value.kpiConfig.dataSource
98
+ .filter(record => record.hour)
99
+ .sort((a, b) => moment(a.hour, 'hh').diff(moment(b.hour, 'hh')));
100
+ const mostRecentRecord = sortedData[0];
101
+ const filteredObjects = sortedData.filter(data => data.recordDate === mostRecentRecord.recordDate);
102
+ this.getHourChart(filteredObjects, value.kpiConfig.dataConfig);
103
+ this.isChartvisible == true;
104
+ this.chartConfig.caption = sortedData[0].recordDate;
105
+ }
106
+ else {
107
+ this.cdr.detectChanges();
108
+ }
109
+ this.isLoader = false;
110
+ }
111
+ }
112
+ }
113
+ }
114
+ ngOnInit() {
115
+ }
116
+ getHourChart(data, dataConfig) {
117
+ if (data) {
118
+ data.forEach(val => {
119
+ if (val[dataConfig.argumentField].toString().length == 1) {
120
+ val[dataConfig.argumentField] = '0' + val[dataConfig.argumentField];
121
+ }
122
+ let label = val[dataConfig.argumentField].toString();
123
+ val[dataConfig.argumentField] = label;
124
+ });
125
+ setTimeout(() => {
126
+ this.finalChartDataSource = data;
127
+ }, 500);
128
+ }
129
+ else {
130
+ this.toastr.error(this.kpi_name + 'Chart Error');
131
+ }
132
+ }
133
+ getMonthlyChart(data, dataConfig) {
134
+ const valueFields = dataConfig.chart_config.map(config => config.valueField);
135
+ data.forEach((entry) => {
136
+ valueFields.forEach((field) => {
137
+ if (entry.hasOwnProperty(field)) {
138
+ if (typeof entry[field] === "string") {
139
+ entry[field] = Number(entry[field]);
140
+ }
141
+ }
142
+ });
143
+ });
144
+ if (data) {
145
+ let content = this.chartConfig.argumentField.toLowerCase();
146
+ if (content.includes('date')) {
147
+ const dataSource = data.map(obj => {
148
+ const newObj = { ...obj };
149
+ if (newObj.hasOwnProperty(this.chartConfig.argumentField)) {
150
+ newObj[this.chartConfig.argumentField] = moment(newObj[this.chartConfig.argumentField]).format(this.chartDisplayDateFormat);
151
+ }
152
+ return newObj;
153
+ });
154
+ this.finalChartDataSource = dataSource;
155
+ }
156
+ else {
157
+ this.finalChartDataSource = data;
158
+ }
159
+ }
160
+ else {
161
+ this.toastr.error(this.kpi_name + 'Chart Error');
162
+ }
163
+ }
164
+ getDailyChart(data, dataConfig) {
165
+ const valueFields = dataConfig.chart_config.map(config => config.valueField);
166
+ if (data) {
167
+ let content = this.chartConfig.argumentField.toLowerCase();
168
+ if (content.includes('date')) {
169
+ const dataSource = data.map(obj => {
170
+ const newObj = { ...obj };
171
+ if (newObj.hasOwnProperty(this.chartConfig.argumentField)) {
172
+ newObj[this.chartConfig.argumentField] = moment(newObj[this.chartConfig.argumentField]).format(this.chartDisplayDateFormat);
173
+ }
174
+ return newObj;
175
+ });
176
+ this.finalChartDataSource = dataSource;
177
+ }
178
+ else {
179
+ this.finalChartDataSource = data;
180
+ }
181
+ }
182
+ else {
183
+ this.toastr.error(this.kpi_name + ' Chart Error');
184
+ }
185
+ }
186
+ getReconDailyChart(data, dataConfig) {
187
+ this.finalChartDataSource = [];
188
+ const recon_key = dataConfig.reconKey;
189
+ const recon_column = dataConfig.reconColumns;
190
+ this.finalChartDataSource = this.getFinalData(data, recon_column);
191
+ }
192
+ getFinalData(mainData, reconColumn) {
193
+ mainData.forEach(data => {
194
+ reconColumn.forEach(column => {
195
+ const firstKeyValue = data[column.firstKey];
196
+ const secondKeyValue = data[column.secondKey];
197
+ const mouDiff = Math.abs(firstKeyValue - secondKeyValue);
198
+ data[column.finalKey] = mouDiff;
199
+ });
200
+ });
201
+ return mainData;
202
+ }
203
+ calculateTotal(pieChart) {
204
+ const totalValue = pieChart.getAllSeries()[0].getVisiblePoints().reduce((s, p) => s + p.originalValue, 0);
205
+ return this.formatNumber(totalValue);
206
+ }
207
+ formatNumber(value) {
208
+ if (value >= 1e9) {
209
+ return (value / 1e9).toFixed(2) + 'B';
210
+ }
211
+ else if (value >= 1e6) {
212
+ return (value / 1e6).toFixed(2) + 'M';
213
+ }
214
+ else if (value >= 1e3) {
215
+ return (value / 1e3).toFixed(2) + 'K';
216
+ }
217
+ else {
218
+ return value.toFixed(2);
219
+ }
220
+ }
221
+ pointClickHandler(arg) {
222
+ arg.target.select();
223
+ }
224
+ getValue(contextKey, value) {
225
+ let context_data;
226
+ const sml_key = contextKey.toLowerCase();
227
+ if (typeof value === "number") {
228
+ if (sml_key === "count" || sml_key === "hour" || sml_key === "denomination" || sml_key.includes("count")) {
229
+ context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 0);
230
+ }
231
+ else if (sml_key.includes('volume') || sml_key.includes('upload') || sml_key.includes('download')) {
232
+ if (sml_key == 'billablevolume') {
233
+ context_data = this.commonService.formatBytsToGb(value * 1024, 2);
234
+ }
235
+ else {
236
+ context_data = this.commonService.formatBytsToGb(value * 1024, 2);
237
+ }
238
+ }
239
+ else if (sml_key == "uplink" || sml_key == "downlink") {
240
+ context_data = this.commonService.formatBytsToGb(value, 2);
241
+ }
242
+ else if (this.hasDecimal(value)) {
243
+ context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 2);
244
+ }
245
+ else if (!this.hasDecimal(value)) {
246
+ context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 0);
247
+ }
248
+ else {
249
+ context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 2);
250
+ }
251
+ }
252
+ else {
253
+ context_data = value;
254
+ }
255
+ return context_data;
256
+ }
257
+ hasDecimal(number) {
258
+ return number % 1 !== 0;
259
+ }
260
+ toggleFullScreen() {
261
+ this.isLoader = true;
262
+ this.isFullScreen = !this.isFullScreen;
263
+ const div = this.el.nativeElement.querySelector('.not-full-screen');
264
+ if (this.isFullScreen) {
265
+ this.renderer.addClass(div, 'full-screen');
266
+ setTimeout(() => {
267
+ this.isLoader = false;
268
+ }, 10);
269
+ }
270
+ else {
271
+ this.renderer.removeClass(div, 'full-screen');
272
+ setTimeout(() => {
273
+ this.isLoader = false;
274
+ }, 10);
275
+ }
276
+ }
277
+ getBubbleChartData() {
278
+ this.heatChartDataSource = {};
279
+ const { result, uniqueDates } = this.generateData(this.bubbleChartData, this.chartConfig);
280
+ this.heatChartDataSource["dataSet"] = result;
281
+ this.heatChartDataSource["argumentValue"] = uniqueDates;
282
+ }
283
+ generateData(data, chartConfig) {
284
+ const result = [];
285
+ const uniqueDates = new Set();
286
+ const dataSourceMap = {};
287
+ const sourceField = chartConfig.sourceField;
288
+ const argumentField = chartConfig.argumentField;
289
+ const valueField = chartConfig.chart_config[0].valueField;
290
+ const minBubbleSize = (this.chartConfig.minBubbleSize) ? parseInt(this.chartConfig.minBubbleSize) : 8;
291
+ const maxBubbleSize = (this.chartConfig.maxBubbleSize) ? parseInt(this.chartConfig.maxBubbleSize) : 20;
292
+ data.forEach(item => {
293
+ const sourceFieldValue = item[sourceField];
294
+ const argumentFieldValue = item[argumentField];
295
+ const { [sourceField]: _, [argumentField]: __, ...rest } = item;
296
+ if (!dataSourceMap[sourceFieldValue]) {
297
+ dataSourceMap[sourceFieldValue] = {
298
+ datasource: sourceFieldValue,
299
+ dataset: []
300
+ };
301
+ }
302
+ dataSourceMap[sourceFieldValue].dataset.push({
303
+ ...rest,
304
+ [argumentField]: moment(argumentFieldValue).format(this.chartDisplayDateFormat)
305
+ });
306
+ uniqueDates.add(moment(argumentFieldValue).format(this.chartDisplayDateFormat));
307
+ });
308
+ const uniqueDatesArray = Array.from(uniqueDates);
309
+ for (const key in dataSourceMap) {
310
+ const dataset = dataSourceMap[key].dataset;
311
+ const formattedDataset = this.getFormateDataByColorCode(dataset, valueField, minBubbleSize, maxBubbleSize);
312
+ const dateToItemMap = {};
313
+ formattedDataset.forEach(item => {
314
+ dateToItemMap[item[argumentField]] = item;
315
+ });
316
+ const completeDataset = uniqueDatesArray.map((date) => {
317
+ if (dateToItemMap[date]) {
318
+ return dateToItemMap[date];
319
+ }
320
+ else {
321
+ return {
322
+ fileCount: 0,
323
+ [argumentField]: date,
324
+ [valueField]: 0,
325
+ color: "rgb(242, 118, 109)"
326
+ };
327
+ }
328
+ });
329
+ result.push({
330
+ datasource: key,
331
+ dataset: completeDataset
332
+ });
333
+ }
334
+ return {
335
+ result: result,
336
+ uniqueDates: uniqueDatesArray
337
+ };
338
+ }
339
+ getFormateDataByColorCode(filedata, valueField, minBubbleSize, maxBubbleSize) {
340
+ filedata.forEach(item => {
341
+ item[valueField] = parseFloat(item[valueField]);
342
+ });
343
+ let maxRechargeCount = Math.max(...filedata.map(item => item[valueField]));
344
+ let minRechargeCount = Math.min(...filedata.map(item => item[valueField]));
345
+ let minColor = [43, 224, 91];
346
+ let maxColor = [65, 135, 24];
347
+ let hover = [135, 184, 106];
348
+ filedata.forEach(item => {
349
+ let size = this.mapRange(item[valueField], minRechargeCount, maxRechargeCount, minBubbleSize, maxBubbleSize);
350
+ item.size = size;
351
+ item.toolTip = (item[valueField]) ? item[valueField] : '0';
352
+ item.hover = `rgb(${hover.join(',')})`;
353
+ if (item[valueField] == 0 || item[valueField] == undefined) {
354
+ item.color = `rgb(${minColor.join(',')})`;
355
+ }
356
+ else {
357
+ item.color = `rgb(${maxColor.join(',')})`;
358
+ }
359
+ });
360
+ return filedata;
361
+ }
362
+ mapRange(value, inMin, inMax, outMin, outMax) {
363
+ return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
364
+ }
365
+ }
366
+ GammaAdvanceChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaAdvanceChartComponent, deps: [{ token: i1.CommonService }, { token: i2.ToastrService }, { token: i3.kpicommonService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
367
+ GammaAdvanceChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: GammaAdvanceChartComponent, selector: "app-gamma-advance-chart", inputs: { componentId: "componentId", kpi_name: "kpi_name", chartDataSource: "chartDataSource" }, ngImport: i0, template: "<div class=\"not-full-screen\" (dblclick)=\"toggleFullScreen()\">\n <ng-container *ngIf=\"page_config?.widGetConfig?.display\">\n <app-title [title]=\"page_config.widGetConfig.widgetTitle\" [operators]=\"page_config.operations\"\n [displayType]=\"'chart'\"></app-title>\n </ng-container>\n <div class=\"mx-2 p-2 bg-gray-800\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n <ng-container\n *ngIf=\"chartConfig.chartType !== 'doughnut' && chartConfig.chartType !== 'pie' && chartConfig.chartType !== 'funnel' && chartConfig.chartType !== 'bubble'\">\n \n <dx-chart id=\"chart\" [dataSource]=\"finalChartDataSource\"\n [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\" *ngIf=\"!isLoader\"\n [valueAxis]=\"chartConfig.valueAxisConfig\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.axis\">\n <dxi-value-axis name=\"{{item.axis}}\" position=\"{{item.position}}\">\n <dxo-title text=\"{{item.name}}\"></dxo-title>\n </dxi-value-axis>\n </ng-container>\n\n </ng-container>\n <dxo-argument-axis>\n <dxo-label overlappingBehavior=\"rotate\" [rotationAngle]=\"270\"></dxo-label>\n </dxo-argument-axis>\n <dxo-tooltip [enabled]=\"true\" [shared]=\"true\" [customizeTooltip]=\"customizeTooltip\">\n </dxo-tooltip>\n <dxo-common-series-settings argumentField=\"{{chartConfig.argumentField}}\">\n </dxo-common-series-settings>\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"item && !item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\">\n </dxi-series>\n </ng-container>\n\n </ng-container>\n <dxo-size [height]=\"chartHeight\">\n </dxo-size>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\" verticalAlignment=\"{{chartConfig.verticalAlignment}}\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\">\n </dxo-legend>\n </dx-chart>\n </ng-container>\n\n\n\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut' || chartConfig.chartType == 'pie'\">\n\n <dx-pie-chart id=\"pie\" [type]=\"chartConfig.chartType\" [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\"\n [dataSource]=\"finalChartDataSource\" centerTemplate=\"centerTemplate\"\n (onPointClick)=\"pointClickHandler($event)\" [palette]=\"chartConfig.palette\">\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"!item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\"\n verticalAlignment=\"{{chartConfig.verticalAlignment}}\"></dxo-legend>\n <!-- <dxo-export [enabled]=\"true\"></dxo-export> -->\n <dxo-tooltip [enabled]=\"true\" [customizeTooltip]=\"customizeTooltip\" format=\"currency\">\n </dxo-tooltip>\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut'\">\n <svg *dxTemplate=\"let pieChart of 'centerTemplate'\">\n <circle cx=\"100\" cy=\"100\" [attr.r]=\"pieChart.getInnerRadius() - 6\" fill=\"gray\" opacity=\"0.0001\">\n </circle>\n \n <text text-anchor=\"middle\" style=\"font-size: 15px\" x=\"100\" y=\"100\" fill=\"#eee\">\n <tspan x=\"100\">{{ calculateTotal(pieChart) }}</tspan>\n <!-- display: inline -->\n <!-- <tspan x=\"100\" dy=\"20px\" style=\"font-weight: 600\"></tspan> -->\n </text>\n </svg>\n </ng-container>\n </dx-pie-chart>\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'funnel'\">\n <dx-funnel id=\"funnel\" [dataSource]=\"finalChartDataSource\" argumentField=\"argument\" valueField=\"value\"\n palette=\"Soft Pastel\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-export [enabled]=\"false\"></dxo-export>\n <dxo-tooltip [enabled]=\"true\"> </dxo-tooltip>\n <dxo-item>\n <dxo-border [visible]=\"true\"> </dxo-border>\n </dxo-item>\n <dxo-label [visible]=\"true\" position=\"inside\" backgroundColor=\"none\"\n [customizeText]=\"customizeText\"></dxo-label>\n </dx-funnel>\n\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'bubble'\">\n <div class=\"mx-5 overflow-x-auto\">\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-10 text-sm items-center min-w-12 max-w-[30%] justify-center flex\">\n {{item.datasource}}\n </div>\n <div class=\"inline-block \">\n <div class=\"flex flex-nowrap justify-center \">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-10 max-w-[20%] h-10 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [matTooltip]=\"'Record Date: ' + box.recordDate + '\\nRecharge Count: ' + box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n <div class=\"rounded-full\" [ngStyle]=\"{\n 'background-color': box.isHovered ? 'rgb(135, 184, 106)' : box.color,\n 'width.px': box.size,\n 'hover': box.hover,\n 'height.px': box.size\n }\" (mouseenter)=\"box.isHovered = true\"\n (mouseleave)=\"box.isHovered = false\">\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-12 max-w-[20%] h-full flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 w-10 max-w-[20%] min-h-14 flex text-sm items-center justify-center my-1\"\n [ngStyle]=\"{'height': 'auto'}\">\n <span class=\"text-rotate\">\n {{item}}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n\n </div>\n\n <button *ngIf=\"isFullScreen\" class=\"close-button\" (click)=\"toggleFullScreen()\">Close</button>\n</div>", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i5.DxTemplateDirective, selector: "[dxTemplate]", inputs: ["dxTemplateOf"] }, { kind: "component", type: i6.DxoExportComponent, selector: "dxo-export", inputs: ["backgroundColor", "enabled", "fileName", "formats", "margin", "printingEnabled", "proxyUrl", "svgToCanvas", "allowExportSelectedData", "customizeExcelCell", "excelFilterEnabled", "excelWrapTextEnabled", "ignoreExcelErrors", "texts"] }, { kind: "component", type: i6.DxoLabelComponent, selector: "dxo-label", inputs: ["connectorColor", "connectorWidth", "customizeText", "font", "format", "indent", "visible", "horizontalAlignment", "position", "text", "verticalAlignment", "alignment", "customizeHint", "displayMode", "indentFromAxis", "overlappingBehavior", "rotationAngle", "staggeringSpacing", "template", "textOverflow", "wordWrap", "argumentFormat", "backgroundColor", "border", "connector", "displayFormat", "horizontalOffset", "showForZeroValues", "verticalOffset", "hideFirstOrLast", "indentFromTick", "useRangeColors", "location", "showColon", "radialOffset", "topIndent", "shadow", "useNodeColors", "dataField", "enabled"] }, { kind: "component", type: i6.DxoLegendComponent, selector: "dxo-legend", inputs: ["backgroundColor", "border", "columnCount", "columnItemSpacing", "customizeHint", "customizeItems", "customizeText", "font", "horizontalAlignment", "itemsAlignment", "itemTextFormat", "itemTextPosition", "margin", "markerSize", "markerTemplate", "orientation", "paddingLeftRight", "paddingTopBottom", "rowCount", "rowItemSpacing", "title", "verticalAlignment", "visible", "hoverMode", "position"] }, { kind: "component", type: i6.DxoBorderComponent, selector: "dxo-border", inputs: ["color", "cornerRadius", "dashStyle", "opacity", "visible", "width", "bottom", "left", "right", "top"] }, { kind: "component", type: i6.DxoTitleComponent, selector: "dxo-title", inputs: ["font", "horizontalAlignment", "margin", "placeholderSize", "subtitle", "text", "verticalAlignment", "textOverflow", "wordWrap", "alignment"] }, { kind: "component", type: i6.DxoSizeComponent, selector: "dxo-size", inputs: ["height", "width"] }, { kind: "component", type: i6.DxoTooltipComponent, selector: "dxo-tooltip", inputs: ["arrowLength", "border", "color", "container", "contentTemplate", "cornerRadius", "customizeTooltip", "enabled", "font", "format", "interactive", "opacity", "paddingLeftRight", "paddingTopBottom", "shadow", "zIndex", "argumentFormat", "location", "shared", "isShown", "text", "position", "showMode", "customizeLinkTooltip", "customizeNodeTooltip", "linkTooltipTemplate", "nodeTooltipTemplate"] }, { kind: "component", type: i7.DxChartComponent, selector: "dx-chart", inputs: ["adaptiveLayout", "adjustOnZoom", "animation", "annotations", "argumentAxis", "autoHidePointMarkers", "barGroupPadding", "barGroupWidth", "commonAnnotationSettings", "commonAxisSettings", "commonPaneSettings", "commonSeriesSettings", "containerBackgroundColor", "crosshair", "customizeAnnotation", "customizeLabel", "customizePoint", "dataPrepareSettings", "dataSource", "defaultPane", "disabled", "elementAttr", "export", "legend", "loadingIndicator", "margin", "maxBubbleSize", "minBubbleSize", "negativesAsZeroes", "palette", "paletteExtensionMode", "panes", "pathModified", "pointSelectionMode", "redrawOnResize", "resizePanesOnZoom", "resolveLabelOverlapping", "rotated", "rtlEnabled", "scrollBar", "series", "seriesSelectionMode", "seriesTemplate", "size", "stickyHovering", "synchronizeMultiAxes", "theme", "title", "tooltip", "valueAxis", "zoomAndPan"], outputs: ["onArgumentAxisClick", "onDisposing", "onDone", "onDrawn", "onExported", "onExporting", "onFileSaving", "onIncidentOccurred", "onInitialized", "onLegendClick", "onOptionChanged", "onPointClick", "onPointHoverChanged", "onPointSelectionChanged", "onSeriesClick", "onSeriesHoverChanged", "onSeriesSelectionChanged", "onTooltipHidden", "onTooltipShown", "onZoomEnd", "onZoomStart", "adaptiveLayoutChange", "adjustOnZoomChange", "animationChange", "annotationsChange", "argumentAxisChange", "autoHidePointMarkersChange", "barGroupPaddingChange", "barGroupWidthChange", "commonAnnotationSettingsChange", "commonAxisSettingsChange", "commonPaneSettingsChange", "commonSeriesSettingsChange", "containerBackgroundColorChange", "crosshairChange", "customizeAnnotationChange", "customizeLabelChange", "customizePointChange", "dataPrepareSettingsChange", "dataSourceChange", "defaultPaneChange", "disabledChange", "elementAttrChange", "exportChange", "legendChange", "loadingIndicatorChange", "marginChange", "maxBubbleSizeChange", "minBubbleSizeChange", "negativesAsZeroesChange", "paletteChange", "paletteExtensionModeChange", "panesChange", "pathModifiedChange", "pointSelectionModeChange", "redrawOnResizeChange", "resizePanesOnZoomChange", "resolveLabelOverlappingChange", "rotatedChange", "rtlEnabledChange", "scrollBarChange", "seriesChange", "seriesSelectionModeChange", "seriesTemplateChange", "sizeChange", "stickyHoveringChange", "synchronizeMultiAxesChange", "themeChange", "titleChange", "tooltipChange", "valueAxisChange", "zoomAndPanChange"] }, { kind: "component", type: i6.DxoArgumentAxisComponent, selector: "dxo-argument-axis", inputs: ["aggregateByCategory", "aggregatedPointsPosition", "aggregationGroupWidth", "aggregationInterval", "allowDecimals", "argumentType", "axisDivisionFactor", "breaks", "breakStyle", "categories", "color", "constantLines", "constantLineStyle", "customPosition", "customPositionAxis", "discreteAxisDivisionMode", "endOnTick", "grid", "holidays", "hoverMode", "inverted", "label", "linearThreshold", "logarithmBase", "maxValueMargin", "minorGrid", "minorTick", "minorTickCount", "minorTickInterval", "minValueMargin", "minVisualRangeLength", "offset", "opacity", "placeholderSize", "position", "singleWorkdays", "strips", "stripStyle", "tick", "tickInterval", "title", "type", "valueMarginsEnabled", "visible", "visualRange", "visualRangeUpdateMode", "wholeRange", "width", "workdaysOnly", "workWeek", "firstPointOnStartAngle", "originValue", "period", "startAngle"], outputs: ["visualRangeChange"] }, { kind: "component", type: i6.DxoCommonSeriesSettingsComponent, selector: "dxo-common-series-settings", inputs: ["aggregation", "area", "argumentField", "axis", "bar", "barOverlapGroup", "barPadding", "barWidth", "border", "bubble", "candlestick", "closeValueField", "color", "cornerRadius", "dashStyle", "fullstackedarea", "fullstackedbar", "fullstackedline", "fullstackedspline", "fullstackedsplinearea", "highValueField", "hoverMode", "hoverStyle", "ignoreEmptyPoints", "innerColor", "label", "line", "lowValueField", "maxLabelCount", "minBarSize", "opacity", "openValueField", "pane", "point", "rangearea", "rangebar", "rangeValue1Field", "rangeValue2Field", "reduction", "scatter", "selectionMode", "selectionStyle", "showInLegend", "sizeField", "spline", "splinearea", "stack", "stackedarea", "stackedbar", "stackedline", "stackedspline", "stackedsplinearea", "steparea", "stepline", "stock", "tagField", "type", "valueErrorBar", "valueField", "visible", "width", "argumentType", "minSegmentSize", "smallValuesGrouping", "closed"] }, { kind: "component", type: i6.DxoConnectorComponent, selector: "dxo-connector", inputs: ["color", "visible", "width", "opacity"] }, { kind: "component", type: i6.DxiSeriesComponent, selector: "dxi-series", inputs: ["aggregation", "argumentField", "axis", "barOverlapGroup", "barPadding", "barWidth", "border", "closeValueField", "color", "cornerRadius", "dashStyle", "highValueField", "hoverMode", "hoverStyle", "ignoreEmptyPoints", "innerColor", "label", "lowValueField", "maxLabelCount", "minBarSize", "name", "opacity", "openValueField", "pane", "point", "rangeValue1Field", "rangeValue2Field", "reduction", "selectionMode", "selectionStyle", "showInLegend", "sizeField", "stack", "tag", "tagField", "type", "valueErrorBar", "valueField", "visible", "width", "argumentType", "minSegmentSize", "smallValuesGrouping", "closed"] }, { kind: "component", type: i6.DxiValueAxisComponent, selector: "dxi-value-axis", inputs: ["aggregatedPointsPosition", "allowDecimals", "autoBreaksEnabled", "axisDivisionFactor", "breaks", "breakStyle", "categories", "color", "constantLines", "constantLineStyle", "customPosition", "discreteAxisDivisionMode", "endOnTick", "grid", "inverted", "label", "linearThreshold", "logarithmBase", "maxAutoBreakCount", "maxValueMargin", "minorGrid", "minorTick", "minorTickCount", "minorTickInterval", "minValueMargin", "minVisualRangeLength", "multipleAxesSpacing", "name", "offset", "opacity", "pane", "placeholderSize", "position", "showZero", "strips", "stripStyle", "synchronizedValue", "tick", "tickInterval", "title", "type", "valueMarginsEnabled", "valueType", "visible", "visualRange", "visualRangeUpdateMode", "wholeRange", "width"], outputs: ["visualRangeChange"] }, { kind: "component", type: i8.DxFunnelComponent, selector: "dx-funnel", inputs: ["adaptiveLayout", "algorithm", "argumentField", "colorField", "dataSource", "disabled", "elementAttr", "export", "hoverEnabled", "inverted", "item", "label", "legend", "loadingIndicator", "margin", "neckHeight", "neckWidth", "palette", "paletteExtensionMode", "pathModified", "redrawOnResize", "resolveLabelOverlapping", "rtlEnabled", "selectionMode", "size", "sortData", "theme", "title", "tooltip", "valueField"], outputs: ["onDisposing", "onDrawn", "onExported", "onExporting", "onFileSaving", "onHoverChanged", "onIncidentOccurred", "onInitialized", "onItemClick", "onLegendClick", "onOptionChanged", "onSelectionChanged", "adaptiveLayoutChange", "algorithmChange", "argumentFieldChange", "colorFieldChange", "dataSourceChange", "disabledChange", "elementAttrChange", "exportChange", "hoverEnabledChange", "invertedChange", "itemChange", "labelChange", "legendChange", "loadingIndicatorChange", "marginChange", "neckHeightChange", "neckWidthChange", "paletteChange", "paletteExtensionModeChange", "pathModifiedChange", "redrawOnResizeChange", "resolveLabelOverlappingChange", "rtlEnabledChange", "selectionModeChange", "sizeChange", "sortDataChange", "themeChange", "titleChange", "tooltipChange", "valueFieldChange"] }, { kind: "component", type: i6.DxoItemComponent, selector: "dxo-item", inputs: ["border", "hoverStyle", "selectionStyle"] }, { kind: "component", type: i9.DxPieChartComponent, selector: "dx-pie-chart", inputs: ["adaptiveLayout", "animation", "annotations", "centerTemplate", "commonAnnotationSettings", "commonSeriesSettings", "customizeAnnotation", "customizeLabel", "customizePoint", "dataSource", "diameter", "disabled", "elementAttr", "export", "innerRadius", "legend", "loadingIndicator", "margin", "minDiameter", "palette", "paletteExtensionMode", "pathModified", "pointSelectionMode", "redrawOnResize", "resolveLabelOverlapping", "rtlEnabled", "segmentsDirection", "series", "seriesTemplate", "size", "sizeGroup", "startAngle", "theme", "title", "tooltip", "type"], outputs: ["onDisposing", "onDone", "onDrawn", "onExported", "onExporting", "onFileSaving", "onIncidentOccurred", "onInitialized", "onLegendClick", "onOptionChanged", "onPointClick", "onPointHoverChanged", "onPointSelectionChanged", "onTooltipHidden", "onTooltipShown", "adaptiveLayoutChange", "animationChange", "annotationsChange", "centerTemplateChange", "commonAnnotationSettingsChange", "commonSeriesSettingsChange", "customizeAnnotationChange", "customizeLabelChange", "customizePointChange", "dataSourceChange", "diameterChange", "disabledChange", "elementAttrChange", "exportChange", "innerRadiusChange", "legendChange", "loadingIndicatorChange", "marginChange", "minDiameterChange", "paletteChange", "paletteExtensionModeChange", "pathModifiedChange", "pointSelectionModeChange", "redrawOnResizeChange", "resolveLabelOverlappingChange", "rtlEnabledChange", "segmentsDirectionChange", "seriesChange", "seriesTemplateChange", "sizeChange", "sizeGroupChange", "startAngleChange", "themeChange", "titleChange", "tooltipChange", "typeChange"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i11.AppTitleComponent, selector: "app-title", inputs: ["title", "multiple", "isFilterDisplay", "icon", "iconName", "displayType", "keyToPass", "fixOperationLevles", "operators"], outputs: ["onOperatorClick"] }, { kind: "component", type: i12.LoaderComponent, selector: "app-loader" }] });
368
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaAdvanceChartComponent, decorators: [{
369
+ type: Component,
370
+ args: [{ selector: 'app-gamma-advance-chart', template: "<div class=\"not-full-screen\" (dblclick)=\"toggleFullScreen()\">\n <ng-container *ngIf=\"page_config?.widGetConfig?.display\">\n <app-title [title]=\"page_config.widGetConfig.widgetTitle\" [operators]=\"page_config.operations\"\n [displayType]=\"'chart'\"></app-title>\n </ng-container>\n <div class=\"mx-2 p-2 bg-gray-800\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n <ng-container\n *ngIf=\"chartConfig.chartType !== 'doughnut' && chartConfig.chartType !== 'pie' && chartConfig.chartType !== 'funnel' && chartConfig.chartType !== 'bubble'\">\n \n <dx-chart id=\"chart\" [dataSource]=\"finalChartDataSource\"\n [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\" *ngIf=\"!isLoader\"\n [valueAxis]=\"chartConfig.valueAxisConfig\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.axis\">\n <dxi-value-axis name=\"{{item.axis}}\" position=\"{{item.position}}\">\n <dxo-title text=\"{{item.name}}\"></dxo-title>\n </dxi-value-axis>\n </ng-container>\n\n </ng-container>\n <dxo-argument-axis>\n <dxo-label overlappingBehavior=\"rotate\" [rotationAngle]=\"270\"></dxo-label>\n </dxo-argument-axis>\n <dxo-tooltip [enabled]=\"true\" [shared]=\"true\" [customizeTooltip]=\"customizeTooltip\">\n </dxo-tooltip>\n <dxo-common-series-settings argumentField=\"{{chartConfig.argumentField}}\">\n </dxo-common-series-settings>\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"item && !item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\">\n </dxi-series>\n </ng-container>\n\n </ng-container>\n <dxo-size [height]=\"chartHeight\">\n </dxo-size>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\" verticalAlignment=\"{{chartConfig.verticalAlignment}}\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\">\n </dxo-legend>\n </dx-chart>\n </ng-container>\n\n\n\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut' || chartConfig.chartType == 'pie'\">\n\n <dx-pie-chart id=\"pie\" [type]=\"chartConfig.chartType\" [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\"\n [dataSource]=\"finalChartDataSource\" centerTemplate=\"centerTemplate\"\n (onPointClick)=\"pointClickHandler($event)\" [palette]=\"chartConfig.palette\">\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"!item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\"\n verticalAlignment=\"{{chartConfig.verticalAlignment}}\"></dxo-legend>\n <!-- <dxo-export [enabled]=\"true\"></dxo-export> -->\n <dxo-tooltip [enabled]=\"true\" [customizeTooltip]=\"customizeTooltip\" format=\"currency\">\n </dxo-tooltip>\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut'\">\n <svg *dxTemplate=\"let pieChart of 'centerTemplate'\">\n <circle cx=\"100\" cy=\"100\" [attr.r]=\"pieChart.getInnerRadius() - 6\" fill=\"gray\" opacity=\"0.0001\">\n </circle>\n \n <text text-anchor=\"middle\" style=\"font-size: 15px\" x=\"100\" y=\"100\" fill=\"#eee\">\n <tspan x=\"100\">{{ calculateTotal(pieChart) }}</tspan>\n <!-- display: inline -->\n <!-- <tspan x=\"100\" dy=\"20px\" style=\"font-weight: 600\"></tspan> -->\n </text>\n </svg>\n </ng-container>\n </dx-pie-chart>\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'funnel'\">\n <dx-funnel id=\"funnel\" [dataSource]=\"finalChartDataSource\" argumentField=\"argument\" valueField=\"value\"\n palette=\"Soft Pastel\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-export [enabled]=\"false\"></dxo-export>\n <dxo-tooltip [enabled]=\"true\"> </dxo-tooltip>\n <dxo-item>\n <dxo-border [visible]=\"true\"> </dxo-border>\n </dxo-item>\n <dxo-label [visible]=\"true\" position=\"inside\" backgroundColor=\"none\"\n [customizeText]=\"customizeText\"></dxo-label>\n </dx-funnel>\n\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'bubble'\">\n <div class=\"mx-5 overflow-x-auto\">\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-10 text-sm items-center min-w-12 max-w-[30%] justify-center flex\">\n {{item.datasource}}\n </div>\n <div class=\"inline-block \">\n <div class=\"flex flex-nowrap justify-center \">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-10 max-w-[20%] h-10 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [matTooltip]=\"'Record Date: ' + box.recordDate + '\\nRecharge Count: ' + box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n <div class=\"rounded-full\" [ngStyle]=\"{\n 'background-color': box.isHovered ? 'rgb(135, 184, 106)' : box.color,\n 'width.px': box.size,\n 'hover': box.hover,\n 'height.px': box.size\n }\" (mouseenter)=\"box.isHovered = true\"\n (mouseleave)=\"box.isHovered = false\">\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-12 max-w-[20%] h-full flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 w-10 max-w-[20%] min-h-14 flex text-sm items-center justify-center my-1\"\n [ngStyle]=\"{'height': 'auto'}\">\n <span class=\"text-rotate\">\n {{item}}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n\n </div>\n\n <button *ngIf=\"isFullScreen\" class=\"close-button\" (click)=\"toggleFullScreen()\">Close</button>\n</div>" }]
371
+ }], ctorParameters: function () { return [{ type: i1.CommonService }, { type: i2.ToastrService }, { type: i3.kpicommonService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { componentId: [{
372
+ type: Input
373
+ }], kpi_name: [{
374
+ type: Input
375
+ }], chartDataSource: [{
376
+ type: Input,
377
+ args: ['chartDataSource']
378
+ }] } });
379
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FtbWEtYWR2YW5jZS1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW1tYS1hcHAtY29udHJvbGxlci9zcmMvbGliL3NoYXJlZC9hZHZhbmNlZC1jb21wb25lbnQvZ2FtbWEtYWR2YW5jZS1jaGFydC9nYW1tYS1hZHZhbmNlLWNoYXJ0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dhbW1hLWFwcC1jb250cm9sbGVyL3NyYy9saWIvc2hhcmVkL2FkdmFuY2VkLWNvbXBvbmVudC9nYW1tYS1hZHZhbmNlLWNoYXJ0L2dhbW1hLWFkdmFuY2UtY2hhcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFvQyxTQUFTLEVBQWMsS0FBSyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUdsSCxPQUFPLE1BQU0sTUFBTSwrQ0FBK0MsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7QUFPbkUsTUFBTSxPQUFPLDBCQUEwQjtJQWtCckMsWUFDVSxhQUE0QixFQUM1QixNQUFxQixFQUNyQixVQUE0QixFQUM1QixRQUFtQixFQUFVLEVBQWMsRUFDM0MsR0FBc0I7UUFKdEIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsV0FBTSxHQUFOLE1BQU0sQ0FBZTtRQUNyQixlQUFVLEdBQVYsVUFBVSxDQUFrQjtRQUM1QixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQVUsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUMzQyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQXRCaEMsZ0JBQVcsR0FBUSxFQUFFLENBQUM7UUFDdEIsZ0JBQVcsR0FBUSxFQUFFLENBQUM7UUFDdEIsYUFBUSxHQUFZLElBQUksQ0FBQztRQU96Qix5QkFBb0IsR0FBRyxTQUFTLENBQUM7UUFDakMseUJBQW9CLEdBQVEsRUFBRSxDQUFDO1FBRy9CLGlCQUFZLEdBQVksS0FB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QU07UUFDMUMsT0FBTyxDQUFDLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsTUFBTSxDQUFDO0lBQzFFLENBQUM7O3VIQXhhVSwwQkFBMEI7MkdBQTFCLDBCQUEwQixpS0NYdkMsbW5UQXlLTTsyRkQ5Sk8sMEJBQTBCO2tCQUp0QyxTQUFTOytCQUNFLHlCQUF5QjtnUEFPMUIsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQTJCRixlQUFlO3NCQURsQixLQUFLO3VCQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE9uSW5pdCwgUmVuZGVyZXIyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUb2FzdHJTZXJ2aWNlIH0gZnJvbSAnbmd4LXRvYXN0cic7XG5pbXBvcnQgeyBrcGljb21tb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4va3BpLWNvbW9uLXNlcnZpY2UnO1xuaW1wb3J0IG1vbWVudCBmcm9tICcuLi8uLi8uLi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL21vbWVudC1oZWxwZXInO1xuaW1wb3J0IHsgQ29tbW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvY29tbW9uJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWdhbW1hLWFkdmFuY2UtY2hhcnQnLFxuICB0ZW1wbGF0ZVVybDogJy4vZ2FtbWEtYWR2YW5jZS1jaGFydC5jb21wb25lbnQuaHRtbCcsXG59KVxuZXhwb3J0IGNsYXNzIEdhbW1hQWR2YW5jZUNoYXJ0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgY2hhcnRDb25maWc6IGFueSA9IHt9O1xuICBwYWdlX2NvbmZpZzogYW55ID0ge307XG4gIGlzTG9hZGVyOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgY29tcG9uZW50SWQ6IGFueTtcbiAgLy8gQElucHV0KCkgY2FwdGlvbjogYW55O1xuICBASW5wdXQoKSBrcGlfbmFtZTogYW55O1xuICAvLyBASW5wdXQoKSBjaGFydERhdGFTb3VyY2U6YW55O1xuICBjYXB0aW9uOiBhbnk7XG4gIGlzQ2hhcnR2aXNpYmxlOiBib29sZWFuO1xuICBjcmVhdENoYXJ0RGF0YVNvdXJjZSA9IHVuZGVmaW5lZDtcbiAgZmluYWxDaGFydERhdGFTb3VyY2U6IGFueSA9IFtdO1xuICBjaGFydEhlaWdodDogYW55O1xuXG4gIGlzRnVsbFNjcmVlbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGhlYXRDaGFydERhdGFTb3VyY2U6IGFueTtcbiAgYnViYmxlQ2hhcnREYXRhOiBhbnk7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY29tbW9uU2VydmljZTogQ29tbW9uU2VydmljZSxcbiAgICBwcml2YXRlIHRvYXN0cjogVG9hc3RyU2VydmljZSxcbiAgICBwcml2YXRlIGtwaVNlcnZpY2U6IGtwaWNvbW1vblNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLCBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHtcblxuICB9XG5cbiAgLy8gY2hhcnRfYXR0ci5sZWdlbmRbMF1cbiAgY2hhcnRPcmRlckJ5OiBib29sZWFuO1xuICBjaGFydERpc3BsYXlEYXRlRm9ybWF0OiBhbnk7XG5cbiAgQElucHV0KCdjaGFydERhdGFTb3VyY2UnKVxuICBzZXQgY2hhcnREYXRhU291cmNlKHZhbHVlKSB7XG4gICAgdGhpcy5jcmVhdENoYXJ0RGF0YVNvdXJjZSA9IHZhbHVlO1xuICAgIC8vIGNvbnNvbGUubG9nKHZhbHVlKTtcbiAgICBpZiAodGhpcy5jcmVhdENoYXJ0RGF0YVNvdXJjZSA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuY3JlYXRDaGFydERhdGFTb3VyY2UubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmlzQ2hhcnR2aXNpYmxlID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNMb2FkZXIgPSB0cnVlO1xuICAgICAgdGhpcy5wYWdlX2NvbmZpZyA9IHZhbHVlO1xuICAgICAgdGhpcy5jaGFydE9yZGVyQnkgPSAodmFsdWUua3BpQ29uZmlnLmRlc2NlbmRpbmdPcmRlcikgPyB2YWx1ZS5rcGlDb25maWcuZGVzY2VuZGluZ09yZGVyIDogZmFsc2U7XG4gICAgICB0aGlzLmNoYXJ0RGlzcGxheURhdGVGb3JtYXQgPSAodmFsdWUua3BpQ29uZmlnLmRpc3BsYXlEYXRlRm9ybWF0KSA/IHZhbHVlLmtwaUNvbmZpZy5kaXNwbGF5RGF0ZUZvcm1hdCA6IFwiTU0tRERcIjtcbiAgICAgIGlmICh2YWx1ZS5rcGlDb25maWcuZGF0YVNvdXJjZSAmJiB2YWx1ZS5rcGlDb25maWcuZGF0YVNvdXJjZS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgdGhpcy5jaGFydENvbmZpZyA9IHZhbHVlLmtwaUNvbmZpZy5kYXRhQ29uZmlnO1xuICAgICAgICBpZiAodmFsdWUua3BpQ29uZmlnLmZvcm1hdGUgPT0gXCJkYWlseVwiKSB7XG5cbiAgICAgICAgICBjb25zdCBzb3J0ZWREYXRhID0gdmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2VcbiAgICAgICAgICAgIC5maWx0ZXIocmVjb3JkID0+IHJlY29yZC5yZWNvcmREYXRlKVxuICAgICAgICAgICAgLnNvcnQoKGEsIGIpID0+IG1vbWVudChiLnJlY29yZERhdGUpLmRpZmYobW9tZW50KGEucmVjb3JkRGF0ZSkpKTtcblxuICAgICAgICAgIGNvbnN0IG1vc3RSZWNlbnRSZWNvcmQgPSBzb3J0ZWREYXRhWzBdO1xuICAgICAgICAgIGNvbnN0IGZpbHRlcmVkT2JqZWN0cyA9IHNvcnRlZERhdGEuZmlsdGVyKGRhdGEgPT4gZGF0YS5yZWNvcmREYXRlID09PSB2YWx1ZS5lbmREYXRlKTtcbiAgICAgICAgICBpZiAodGhpcy5jaGFydENvbmZpZy5jaGFydFR5cGUgPT0gJ2Z1bm5lbCcpIHtcbiAgICAgICAgICAgIHRoaXMuZmluYWxDaGFydERhdGFTb3VyY2UgPSBPYmplY3Qua2V5cyhtb3N0UmVjZW50UmVjb3JkKS5maWx0ZXIoa2V5ID0+IGtleSAhPT0gJ3JlY29yZERhdGUnKS5tYXAoa2V5ID0+ICh7XG4gICAgICAgICAgICAgIGFyZ3VtZW50OiBrZXksXG4gICAgICAgICAgICAgIHZhbHVlOiBNYXRoLmFicyhwYXJzZUludChtb3N0UmVjZW50UmVjb3JkW2tleV0pKVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5maW5hbENoYXJ0RGF0YVNvdXJjZSlcbiAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICB0aGlzLmdldERhaWx5Q2hhcnQoZmlsdGVyZWRPYmplY3RzLCB2YWx1ZS5rcGlDb25maWcuZGF0YUNvbmZpZyk7XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmlzTG9hZGVyID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUua3BpQ29uZmlnLmZvcm1hdGUgPT0gXCJtb250aGx5XCIpIHtcbiAgICAgICAgICBpZiAodmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2UgJiYgdmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2UubGVuZ3RoICE9PSAwKSB7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAnYnViYmxlJykge1xuICAgICAgICAgICAgICB0aGlzLmJ1YmJsZUNoYXJ0RGF0YSA9IHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlO1xuICAgICAgICAgICAgICB0aGlzLmdldEJ1YmJsZUNoYXJ0RGF0YSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuY2hhcnRPcmRlckJ5KSB7XG4gICAgICAgICAgICAgICAgbGV0IHNob3J0TmFtZSA9IHZhbHVlLmtwaUNvbmZpZy5kYXRhQ29uZmlnWydhcmd1bWVudEZpZWxkJ10udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICBpZiAoc2hvcnROYW1lLmluY2x1ZGVzKCdkYXRlJykpIHtcbiAgICAgICAgICAgICAgICAgIHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlID0gdmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2VcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihyZWNvcmQgPT4gcmVjb3JkW3ZhbHVlLmtwaUNvbmZpZy5kYXRhQ29uZmlnWydhcmd1bWVudEZpZWxkJ11dKVxuICAgICAgICAgICAgICAgICAgICAuc29ydCgoYSwgYikgPT4gbW9tZW50KGJbdmFsdWUua3BpQ29uZmlnLmRhdGFDb25maWdbJ2FyZ3VtZW50RmllbGQnXV0pLmRpZmYobW9tZW50KGFbdmFsdWUua3BpQ29uZmlnLmRhdGFDb25maWdbJ2FyZ3VtZW50RmllbGQnXV0pKSk7XG5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHRoaXMuZ2V0TW9udGhseUNoYXJ0KHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlLCB2YWx1ZS5rcGlDb25maWcuZGF0YUNvbmZpZylcbiAgICAgICAgICAgICAgdGhpcy5pc0NoYXJ0dmlzaWJsZSA9PSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmlzTG9hZGVyID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUua3BpQ29uZmlnLmZvcm1hdGUgPT0gXCJob3VybHlcIikge1xuICAgICAgICAgIGRlYnVnZ2VyXG4gICAgICAgICAgaWYgKHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlICYmIHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgY29uc3Qgc29ydGVkRGF0YSA9IHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlXG4gICAgICAgICAgICAgIC5maWx0ZXIocmVjb3JkID0+IHJlY29yZC5ob3VyKVxuICAgICAgICAgICAgICAuc29ydCgoYSwgYikgPT4gbW9tZW50KGEuaG91ciwgJ2hoJykuZGlmZihtb21lbnQoYi5ob3VyLCAnaGgnKSkpO1xuICAgICAgICAgICAgY29uc3QgbW9zdFJlY2VudFJlY29yZCA9IHNvcnRlZERhdGFbMF07XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJlZE9iamVjdHMgPSBzb3J0ZWREYXRhLmZpbHRlcihkYXRhID0+IGRhdGEucmVjb3JkRGF0ZSA9PT0gbW9zdFJlY2VudFJlY29yZC5yZWNvcmREYXRlKTtcblxuICAgICAgICAgICAgdGhpcy5nZXRIb3VyQ2hhcnQoZmlsdGVyZWRPYmplY3RzLCB2YWx1ZS5rcGlDb25maWcuZGF0YUNvbmZpZylcbiAgICAgICAgICAgIHRoaXMuaXNDaGFydHZpc2libGUgPT0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuY2hhcnRDb25maWcuY2FwdGlvbiA9IHNvcnRlZERhdGFbMF0ucmVjb3JkRGF0ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuaXNMb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICB9XG4gICAgICAvLyBlbHNlIHtcbiAgICAgIC8vICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgLy8gfVxuXG4gICAgfVxuXG5cblxuICB9XG5cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcblxuICB9XG5cbiAgZ2V0SG91ckNoYXJ0KGRhdGEsIGRhdGFDb25maWcpIHtcbiAgICAvLyBjb25zdCB2YWx1ZUZpZWxkcyA9IGRhdGFDb25maWcuY2hhcnRfY29uZmlnLm1hcChjb25maWcgPT4gY29uZmlnLnZhbHVlRmllbGQpO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBkYXRhLmZvckVhY2godmFsID0+IHtcbiAgICAgICAgaWYgKHZhbFtkYXRhQ29uZmlnLmFyZ3VtZW50RmllbGRdLnRvU3RyaW5nKCkubGVuZ3RoID09IDEpIHtcbiAgICAgICAgICB2YWxbZGF0YUNvbmZpZy5hcmd1bWVudEZpZWxkXSA9ICcwJyArIHZhbFtkYXRhQ29uZmlnLmFyZ3VtZW50RmllbGRdO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsYWJlbCA9IHZhbFtkYXRhQ29uZmlnLmFyZ3VtZW50RmllbGRdLnRvU3RyaW5nKCk7XG4gICAgICAgIHZhbFtkYXRhQ29uZmlnLmFyZ3VtZW50RmllbGRdID0gbGFiZWxcbiAgICAgIH0pO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZmluYWxDaGFydERhdGFTb3VyY2UgPSBkYXRhO1xuICAgICAgfSwgNTAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b2FzdHIuZXJyb3IodGhpcy5rcGlfbmFtZSArICdDaGFydCBFcnJvcicpO1xuXG4gICAgfVxuICB9XG4gIGdldE1vbnRobHlDaGFydChkYXRhLCBkYXRhQ29uZmlnKSB7XG4gICAgY29uc3QgdmFsdWVGaWVsZHMgPSBkYXRhQ29uZmlnLmNoYXJ0X2NvbmZpZy5tYXAoY29uZmlnID0+IGNvbmZpZy52YWx1ZUZpZWxkKTtcbiAgICBkYXRhLmZvckVhY2goKGVudHJ5OiBhbnkpID0+IHtcbiAgICAgIHZhbHVlRmllbGRzLmZvckVhY2goKGZpZWxkOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKGVudHJ5Lmhhc093blByb3BlcnR5KGZpZWxkKSkge1xuICAgICAgICAgIGlmICh0eXBlb2YgZW50cnlbZmllbGRdID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBlbnRyeVtmaWVsZF0gPSBOdW1iZXIoZW50cnlbZmllbGRdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBsZXQgY29udGVudCA9IHRoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoJ2RhdGUnKSkge1xuICAgICAgICBjb25zdCBkYXRhU291cmNlID0gZGF0YS5tYXAob2JqID0+IHtcbiAgICAgICAgICBjb25zdCBuZXdPYmogPSB7IC4uLm9iaiB9O1xuICAgICAgICAgIGlmIChuZXdPYmouaGFzT3duUHJvcGVydHkodGhpcy5jaGFydENvbmZpZy5hcmd1bWVudEZpZWxkKSkge1xuICAgICAgICAgICAgbmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0gPSBtb21lbnQobmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0pLmZvcm1hdCh0aGlzLmNoYXJ0RGlzcGxheURhdGVGb3JtYXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3T2JqO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5maW5hbENoYXJ0RGF0YVNvdXJjZSA9IGRhdGFTb3VyY2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlID0gZGF0YTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b2FzdHIuZXJyb3IodGhpcy5rcGlfbmFtZSArICdDaGFydCBFcnJvcicpO1xuICAgIH1cbiAgfVxuICBnZXREYWlseUNoYXJ0KGRhdGEsIGRhdGFDb25maWcpIHtcbiAgICBjb25zdCB2YWx1ZUZpZWxkcyA9IGRhdGFDb25maWcuY2hhcnRfY29uZmlnLm1hcChjb25maWcgPT4gY29uZmlnLnZhbHVlRmllbGQpO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBsZXQgY29udGVudCA9IHRoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoJ2RhdGUnKSkge1xuICAgICAgICBjb25zdCBkYXRhU291cmNlID0gZGF0YS5tYXAob2JqID0+IHtcbiAgICAgICAgICBjb25zdCBuZXdPYmogPSB7IC4uLm9iaiB9O1xuICAgICAgICAgIGlmIChuZXdPYmouaGFzT3duUHJvcGVydHkodGhpcy5jaGFydENvbmZpZy5hcmd1bWVudEZpZWxkKSkge1xuICAgICAgICAgICAgbmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0gPSBtb21lbnQobmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0pLmZvcm1hdCh0aGlzLmNoYXJ0RGlzcGxheURhdGVGb3JtYXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3T2JqO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5maW5hbENoYXJ0RGF0YVNvdXJjZSA9IGRhdGFTb3VyY2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlID0gZGF0YTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b2FzdHIuZXJyb3IodGhpcy5rcGlfbmFtZSArICcgQ2hhcnQgRXJyb3InKTtcbiAgICB9XG4gIH1cblxuXG4gIGdldFJlY29uRGFpbHlDaGFydChkYXRhLCBkYXRhQ29uZmlnKSB7XG5cbiAgICB0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlID0gW107XG4gICAgY29uc3QgcmVjb25fa2V5ID0gZGF0YUNvbmZpZy5yZWNvbktleTtcbiAgICBjb25zdCByZWNvbl9jb2x1bW4gPSBkYXRhQ29uZmlnLnJlY29uQ29sdW1ucztcbiAgICB0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlID0gdGhpcy5nZXRGaW5hbERhdGEoZGF0YSwgcmVjb25fY29sdW1uKTtcblxuICB9XG5cbiAgZ2V0RmluYWxEYXRhKG1haW5EYXRhOiBhbnlbXSwgcmVjb25Db2x1bW46IGFueVtdKTogYW55W10ge1xuICAgIG1haW5EYXRhLmZvckVhY2goZGF0YSA9PiB7XG4gICAgICByZWNvbkNvbHVtbi5mb3JFYWNoKGNvbHVtbiA9PiB7XG4gICAgICAgIGNvbnN0IGZpcnN0S2V5VmFsdWUgPSBkYXRhW2NvbHVtbi5maXJzdEtleV07XG4gICAgICAgIGNvbnN0IHNlY29uZEtleVZhbHVlID0gZGF0YVtjb2x1bW4uc2Vjb25kS2V5XTtcbiAgICAgICAgY29uc3QgbW91RGlmZiA9IE1hdGguYWJzKGZpcnN0S2V5VmFsdWUgLSBzZWNvbmRLZXlWYWx1ZSk7XG4gICAgICAgIGRhdGFbY29sdW1uLmZpbmFsS2V5XSA9IG1vdURpZmY7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBtYWluRGF0YTtcbiAgfVxuXG4gIGN1c3RvbWl6ZVRvb2x0aXAgPSAoaW5mbzogYW55KSA9PiAoXG4gICAge1xuXG4gICAgICBodG1sOiBgPHRhYmxlIHdpZHRoPTEwMCUgaGVpZ2h0PTMwIGJvcmRlcj0wICBzdHlsZT1cXCdmb250LXNpemU6IDEzcHhcXCc+XG4gICAgPHRyPjx0ZCBzdHlsZT1cXCd0ZXh0LWFsaWduOiBsZWZ0OyBjb2xvcjogd2hpdGVcXCc+ICR7dGhpcy5jb21tb25TZXJ2aWNlLmNvbnZlcnRUb1RpdGxlQ2FzZSh0aGlzLmNoYXJ0Q29uZmlnLmFyZ3VtZW50RmllbGQpfSA6ICAke2luZm8uYXJndW1lbnRUZXh0fSA8L3RkPjwvdHI+XG4gICAgPHRyPjx0ZCBzdHlsZT1cXCd0ZXh0LWFsaWduOiBsZWZ0OyBjb2xvcjogd2hpdGU7IHBhZGRpbmctdG9wOiA1cHhcXCc+ICR7aW5mby5zZXJpZXNOYW1lfSA6XG4gICAgJHt0aGlzLmdldFZhbHVlKGluZm8uc2VyaWVzTmFtZSwgaW5mby52YWx1ZSl9ICA8L3RkPjwvdHI+XG4gICAgPC90YWJsZT5gLFxuICAgIH0pO1xuXG4gIC8vIGN1c3RvbWl6ZVRvb2x0aXAoYXJnKSB7XG4gIC8vICAgcmV0dXJuIHsgdGV4dDogYCR7YXJnLmFyZ3VtZW50VGV4dH08YnI+JHthcmcuc2VyaWVzTmFtZX06ICR7YXJnLnZhbHVlVGV4dH1CYCB9O1xuICAvLyB9XG5cbiAgY2FsY3VsYXRlVG90YWwocGllQ2hhcnQpIHtcbiAgICBjb25zdCB0b3RhbFZhbHVlID0gcGllQ2hhcnQuZ2V0QWxsU2VyaWVzKClbMF0uZ2V0VmlzaWJsZVBvaW50cygpLnJlZHVjZSgocywgcCkgPT4gcyArIHAub3JpZ2luYWxWYWx1ZSwgMCk7XG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0TnVtYmVyKHRvdGFsVmFsdWUpO1xuICB9XG5cbiAgZm9ybWF0TnVtYmVyKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID49IDFlOSkge1xuICAgICAgcmV0dXJuICh2YWx1ZSAvIDFlOSkudG9GaXhlZCgyKSArICdCJztcbiAgICB9IGVsc2UgaWYgKHZhbHVlID49IDFlNikge1xuICAgICAgcmV0dXJuICh2YWx1ZSAvIDFlNikudG9GaXhlZCgyKSArICdNJztcbiAgICB9IGVsc2UgaWYgKHZhbHVlID49IDFlMykge1xuICAgICAgcmV0dXJuICh2YWx1ZSAvIDFlMykudG9GaXhlZCgyKSArICdLJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHZhbHVlLnRvRml4ZWQoMik7XG4gICAgfVxuICB9XG5cbiAgcG9pbnRDbGlja0hhbmRsZXIoYXJnKSB7XG4gICAgYXJnLnRhcmdldC5zZWxlY3QoKTtcbiAgfVxuXG4gIGdldFZhbHVlKGNvbnRleHRLZXksIHZhbHVlKSB7XG5cbiAgICBsZXQgY29udGV4dF9kYXRhOiBhbnk7XG4gICAgY29uc3Qgc21sX2tleSA9IGNvbnRleHRLZXkudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIGlmIChzbWxfa2V5ID09PSBcImNvdW50XCIgfHwgc21sX2tleSA9PT0gXCJob3VyXCIgfHwgc21sX2tleSA9PT0gXCJkZW5vbWluYXRpb25cIiB8fCBzbWxfa2V5LmluY2x1ZGVzKFwiY291bnRcIikpIHtcbiAgICAgICAgY29udGV4dF9kYXRhID0gdGhpcy5jb21tb25TZXJ2aWNlLnJlZm9ybWF0TnVtYmVyV2l0aFRob3VzYW5kU2VwYXJhdG9yVjModmFsdWUsIDApO1xuICAgICAgfSBlbHNlIGlmIChzbWxfa2V5LmluY2x1ZGVzKCd2b2x1bWUnKSB8fCBzbWxfa2V5LmluY2x1ZGVzKCd1cGxvYWQnKSB8fCBzbWxfa2V5LmluY2x1ZGVzKCdkb3dubG9hZCcpKSB7XG4gICAgICAgIGlmIChzbWxfa2V5ID09ICdiaWxsYWJsZXZvbHVtZScpIHtcbiAgICAgICAgICBjb250ZXh0X2RhdGEgPSB0aGlzLmNvbW1vblNlcnZpY2UuZm9ybWF0Qnl0c1RvR2IodmFsdWUgKiAxMDI0LCAyKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnRleHRfZGF0YSA9IHRoaXMuY29tbW9uU2VydmljZS5mb3JtYXRCeXRzVG9HYih2YWx1ZSAqIDEwMjQsIDIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNtbF9rZXkgPT0gXCJ1cGxpbmtcIiB8fCBzbWxfa2V5ID09IFwiZG93bmxpbmtcIikge1xuICAgICAgICBjb250ZXh0X2RhdGEgPSB0aGlzLmNvbW1vblNlcnZpY2UuZm9ybWF0Qnl0c1RvR2IodmFsdWUsIDIpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmhhc0RlY2ltYWwodmFsdWUpKSB7XG4gICAgICAgIGNvbnRleHRfZGF0YSA9IHRoaXMuY29tbW9uU2VydmljZS5yZWZvcm1hdE51bWJlcldpdGhUaG91c2FuZFNlcGFyYXRvclYzKHZhbHVlLCAyKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuaGFzRGVjaW1hbCh2YWx1ZSkpIHtcbiAgICAgICAgY29udGV4dF9kYXRhID0gdGhpcy5jb21tb25TZXJ2aWNlLnJlZm9ybWF0TnVtYmVyV2l0aFRob3VzYW5kU2VwYXJhdG9yVjModmFsdWUsIDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGV4dF9kYXRhID0gdGhpcy5jb21tb25TZXJ2aWNlLnJlZm9ybWF0TnVtYmVyV2l0aFRob3VzYW5kU2VwYXJhdG9yVjModmFsdWUsIDIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0X2RhdGEgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGV4dF9kYXRhO1xuICB9XG5cblxuICBoYXNEZWNpbWFsKG51bWJlcikge1xuICAgIHJldHVybiBudW1iZXIgJSAxICE9PSAwO1xuICB9XG5cbiAgdG9nZ2xlRnVsbFNjcmVlbigpIHtcbiAgICB0aGlzLmlzTG9hZGVyID0gdHJ1ZTtcbiAgICB0aGlzLmlzRnVsbFNjcmVlbiA9ICF0aGlzLmlzRnVsbFNjcmVlbjtcbiAgICBjb25zdCBkaXYgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLm5vdC1mdWxsLXNjcmVlbicpO1xuICAgIGlmICh0aGlzLmlzRnVsbFNjcmVlbikge1xuICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhkaXYsICdmdWxsLXNjcmVlbicpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNMb2FkZXIgPSBmYWxzZTtcbiAgICAgIH0sIDEwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhkaXYsICdmdWxsLXNjcmVlbicpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNMb2FkZXIgPSBmYWxzZTtcbiAgICAgIH0sIDEwKTtcbiAgICB9XG4gIH1cblxuXG5cblxuXG4gIGN1c3RvbWl6ZVRleHQgPSAoeyBwZXJjZW50VGV4dCwgaXRlbTogeyBhcmd1bWVudCB9IH0pID0+IGA8c3BhbiBzdHlsZT0nZm9udC1zaXplOiAyOHB4Jz4ke3BlcmNlbnRUZXh0fTwvc3Bhbj48YnIvPiR7YXJndW1lbnR9YDtcblxuXG4gIC8vIGJ1YmJsZSBjaGFydFxuXG4gIGdldEJ1YmJsZUNoYXJ0RGF0YSgpIHtcbiAgICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2UgPSB7fTtcbiAgICBjb25zdCB7IHJlc3VsdCwgdW5pcXVlRGF0ZXMgfSA9IHRoaXMuZ2VuZXJhdGVEYXRhKHRoaXMuYnViYmxlQ2hhcnREYXRhLCB0aGlzLmNoYXJ0Q29uZmlnKVxuICAgIC8vIHJlc3VsdC5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgIC8vICAgZWxlbWVudC5kYXRhc2V0LnNvcnQoKGEsIGIpID0+IG1vbWVudChhLnJlY29yZERhdGUsICdZWVlZTU1ERCcpLmRpZmYobW9tZW50KGIucmVjb3JkRGF0ZSwgJ1lZWVlNTUREJykpKTtcbiAgICAvLyB9KTtcbiAgICAvLyB1bmlxdWVEYXRlcy5zb3J0KCk7XG4gICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlW1wiZGF0YVNldFwiXSA9IHJlc3VsdDtcbiAgICB0aGlzLmhlYXRDaGFydERhdGFTb3VyY2VbXCJhcmd1bWVudFZhbHVlXCJdID0gdW5pcXVlRGF0ZXM7XG4gIH1cblxuICBnZW5lcmF0ZURhdGEoZGF0YSwgY2hhcnRDb25maWcpIHtcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBjb25zdCB1bmlxdWVEYXRlcyA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBkYXRhU291cmNlTWFwID0ge307XG5cbiAgICBjb25zdCBzb3VyY2VGaWVsZCA9IGNoYXJ0Q29uZmlnLnNvdXJjZUZpZWxkO1xuICAgIGNvbnN0IGFyZ3VtZW50RmllbGQgPSBjaGFydENvbmZpZy5hcmd1bWVudEZpZWxkO1xuICAgIGNvbnN0IHZhbHVlRmllbGQgPSBjaGFydENvbmZpZy5jaGFydF9jb25maWdbMF0udmFsdWVGaWVsZDtcbiAgICBjb25zdCBtaW5CdWJibGVTaXplID0gKHRoaXMuY2hhcnRDb25maWcubWluQnViYmxlU2l6ZSkgPyBwYXJzZUludCh0aGlzLmNoYXJ0Q29uZmlnLm1pbkJ1YmJsZVNpemUpIDogODtcbiAgICBjb25zdCBtYXhCdWJibGVTaXplID0gKHRoaXMuY2hhcnRDb25maWcubWF4QnViYmxlU2l6ZSkgPyBwYXJzZUludCh0aGlzLmNoYXJ0Q29uZmlnLm1heEJ1YmJsZVNpemUpIDogMjA7XG5cbiAgICBkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VGaWVsZFZhbHVlID0gaXRlbVtzb3VyY2VGaWVsZF07XG4gICAgICBjb25zdCBhcmd1bWVudEZpZWxkVmFsdWUgPSBpdGVtW2FyZ3VtZW50RmllbGRdO1xuICAgICAgY29uc3QgeyBbc291cmNlRmllbGRdOiBfLCBbYXJndW1lbnRGaWVsZF06IF9fLCAuLi5yZXN0IH0gPSBpdGVtO1xuXG4gICAgICBpZiAoIWRhdGFTb3VyY2VNYXBbc291cmNlRmllbGRWYWx1ZV0pIHtcbiAgICAgICAgZGF0YVNvdXJjZU1hcFtzb3VyY2VGaWVsZFZhbHVlXSA9IHtcbiAgICAgICAgICBkYXRhc291cmNlOiBzb3VyY2VGaWVsZFZhbHVlLFxuICAgICAgICAgIGRhdGFzZXQ6IFtdXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBkYXRhU291cmNlTWFwW3NvdXJjZUZpZWxkVmFsdWVdLmRhdGFzZXQucHVzaCh7XG4gICAgICAgIC4uLnJlc3QsXG4gICAgICAgIFthcmd1bWVudEZpZWxkXTogbW9tZW50KGFyZ3VtZW50RmllbGRWYWx1ZSkuZm9ybWF0KHRoaXMuY2hhcnREaXNwbGF5RGF0ZUZvcm1hdClcbiAgICAgIH0pO1xuICAgICAgdW5pcXVlRGF0ZXMuYWRkKG1vbWVudChhcmd1bWVudEZpZWxkVmFsdWUpLmZvcm1hdCh0aGlzLmNoYXJ0RGlzcGxheURhdGVGb3JtYXQpKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHVuaXF1ZURhdGVzQXJyYXkgPSBBcnJheS5mcm9tKHVuaXF1ZURhdGVzKTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGFTb3VyY2VNYXApIHtcbiAgICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhU291cmNlTWFwW2tleV0uZGF0YXNldDtcbiAgICAgIGNvbnN0IGZvcm1hdHRlZERhdGFzZXQgPSB0aGlzLmdldEZvcm1hdGVEYXRhQnlDb2xvckNvZGUoZGF0YXNldCwgdmFsdWVGaWVsZCwgbWluQnViYmxlU2l6ZSwgbWF4QnViYmxlU2l6ZSk7XG5cbiAgICAgIGNvbnN0IGRhdGVUb0l0ZW1NYXAgPSB7fTtcbiAgICAgIGZvcm1hdHRlZERhdGFzZXQuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgZGF0ZVRvSXRlbU1hcFtpdGVtW2FyZ3VtZW50RmllbGRdXSA9IGl0ZW07XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgY29tcGxldGVEYXRhc2V0ID0gdW5pcXVlRGF0ZXNBcnJheS5tYXAoKGRhdGU6IGFueSkgPT4ge1xuXG4gICAgICAgIGlmIChkYXRlVG9JdGVtTWFwW2RhdGVdKSB7XG4gICAgICAgICAgcmV0dXJuIGRhdGVUb0l0ZW1NYXBbZGF0ZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZpbGVDb3VudDogMCxcbiAgICAgICAgICAgIFthcmd1bWVudEZpZWxkXTogZGF0ZSxcbiAgICAgICAgICAgIFt2YWx1ZUZpZWxkXTogMCxcbiAgICAgICAgICAgIGNvbG9yOiBcInJnYigyNDIsIDExOCwgMTA5KVwiXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgZGF0YXNvdXJjZToga2V5LFxuICAgICAgICBkYXRhc2V0OiBjb21wbGV0ZURhdGFzZXRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZXN1bHQ6IHJlc3VsdCxcbiAgICAgIHVuaXF1ZURhdGVzOiB1bmlxdWVEYXRlc0FycmF5XG4gICAgfTtcbiAgfVxuXG5cblxuICBnZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlKGZpbGVkYXRhLCB2YWx1ZUZpZWxkLCBtaW5CdWJibGVTaXplLCBtYXhCdWJibGVTaXplKSB7XG4gICAgZmlsZWRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGl0ZW1bdmFsdWVGaWVsZF0gPSBwYXJzZUZsb2F0KGl0ZW1bdmFsdWVGaWVsZF0pO1xuICAgIH0pO1xuXG4gICAgbGV0IG1heFJlY2hhcmdlQ291bnQgPSBNYXRoLm1heCguLi5maWxlZGF0YS5tYXAoaXRlbSA9PiBpdGVtW3ZhbHVlRmllbGRdKSk7XG4gICAgbGV0IG1pblJlY2hhcmdlQ291bnQgPSBNYXRoLm1pbiguLi5maWxlZGF0YS5tYXAoaXRlbSA9PiBpdGVtW3ZhbHVlRmllbGRdKSk7XG5cbiAgICBsZXQgbWluQ29sb3IgPSBbNDMsIDIyNCwgOTFdO1xuICAgIGxldCBtYXhDb2xvciA9IFs2NSwgMTM1LCAyNF07XG4gICAgbGV0IGhvdmVyID0gWzEzNSwgMTg0LCAxMDZdO1xuXG4gICAgZmlsZWRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGxldCBzaXplID0gdGhpcy5tYXBSYW5nZShpdGVtW3ZhbHVlRmllbGRdLCBtaW5SZWNoYXJnZUNvdW50LCBtYXhSZWNoYXJnZUNvdW50LCBtaW5CdWJibGVTaXplLCBtYXhCdWJibGVTaXplKTtcbiAgICAgIGl0ZW0uc2l6ZSA9IHNpemU7XG4gICAgICBpdGVtLnRvb2xUaXAgPSAoaXRlbVt2YWx1ZUZpZWxkXSkgPyBpdGVtW3ZhbHVlRmllbGRdIDogJzAnO1xuICAgICAgaXRlbS5ob3ZlciA9IGByZ2IoJHtob3Zlci5qb2luKCcsJyl9KWA7XG4gICAgICBpZiAoaXRlbVt2YWx1ZUZpZWxkXSA9PSAwIHx8IGl0ZW1bdmFsdWVGaWVsZF0gPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGl0ZW0uY29sb3IgPSBgcmdiKCR7bWluQ29sb3Iuam9pbignLCcpfSlgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbS5jb2xvciA9IGByZ2IoJHttYXhDb2xvci5qb2luKCcsJyl9KWA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmlsZWRhdGE7XG4gIH1cblxuICBtYXBSYW5nZSh2YWx1ZSwgaW5NaW4sIGluTWF4LCBvdXRNaW4sIG91dE1heCkge1xuICAgIHJldHVybiAoKHZhbHVlIC0gaW5NaW4pICogKG91dE1heCAtIG91dE1pbikpIC8gKGluTWF4IC0gaW5NaW4pICsgb3V0TWluO1xuICB9XG5cblxuICAvLyBjdXN0b21pemVMYWJlbFRleHQgPSAoaW5mbzogYW55KSA9PiBgJHtpbmZvLnZhbHVlVGV4dH1gO1xuXG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJub3QtZnVsbC1zY3JlZW5cIiAoZGJsY2xpY2spPVwidG9nZ2xlRnVsbFNjcmVlbigpXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhZ2VfY29uZmlnPy53aWRHZXRDb25maWc/LmRpc3BsYXlcIj5cbiAgICAgICAgPGFwcC10aXRsZSBbdGl0bGVdPVwicGFnZV9jb25maWcud2lkR2V0Q29uZmlnLndpZGdldFRpdGxlXCIgW29wZXJhdG9yc109XCJwYWdlX2NvbmZpZy5vcGVyYXRpb25zXCJcbiAgICAgICAgICAgIFtkaXNwbGF5VHlwZV09XCInY2hhcnQnXCI+PC9hcHAtdGl0bGU+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGRpdiBjbGFzcz1cIm14LTIgcC0yIGJnLWdyYXktODAwXCI+XG4gICAgICAgIDxhcHAtbG9hZGVyICpuZ0lmPVwiaXNMb2FkZXJcIj48L2FwcC1sb2FkZXI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICpuZ0lmPVwiY2hhcnRDb25maWcuY2hhcnRUeXBlICE9PSAnZG91Z2hudXQnICYmIGNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSAhPT0gJ3BpZScgJiYgY2hhcnRDb25maWcuY2hhcnRUeXBlICE9PSAnZnVubmVsJyAmJiBjaGFydENvbmZpZy5jaGFydFR5cGUgIT09ICdidWJibGUnXCI+XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIDxkeC1jaGFydCBpZD1cImNoYXJ0XCIgIFtkYXRhU291cmNlXT1cImZpbmFsQ2hhcnREYXRhU291cmNlXCJcbiAgICAgICAgICAgICAgICBbdGl0bGVdPVwieyB0ZXh0OiBjaGFydENvbmZpZy5jYXB0aW9uLCBmb250OiB7IHNpemU6IDE0IH0gfVwiICpuZ0lmPVwiIWlzTG9hZGVyXCJcbiAgICAgICAgICAgICAgICBbdmFsdWVBeGlzXT1cImNoYXJ0Q29uZmlnLnZhbHVlQXhpc0NvbmZpZ1wiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjaGFydENvbmZpZy5zaXplXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkeG8tc2l6ZSBbaGVpZ2h0XT1cImNoYXJ0Q29uZmlnLnNpemVcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9keG8tc2l6ZT5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgY2hhcnRDb25maWcuY2hhcnRfY29uZmlnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtICYmIGl0ZW0uYXhpc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4aS12YWx1ZS1heGlzIG5hbWU9XCJ7e2l0ZW0uYXhpc319XCIgcG9zaXRpb249XCJ7e2l0ZW0ucG9zaXRpb259fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeG8tdGl0bGUgdGV4dD1cInt7aXRlbS5uYW1lfX1cIj48L2R4by10aXRsZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZHhpLXZhbHVlLWF4aXM+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGR4by1hcmd1bWVudC1heGlzPlxuICAgICAgICAgICAgICAgICAgICA8ZHhvLWxhYmVsIG92ZXJsYXBwaW5nQmVoYXZpb3I9XCJyb3RhdGVcIiBbcm90YXRpb25BbmdsZV09XCIyNzBcIj48L2R4by1sYWJlbD5cbiAgICAgICAgICAgICAgICA8L2R4by1hcmd1bWVudC1heGlzPlxuICAgICAgICAgICAgICAgIDxkeG8tdG9vbHRpcCBbZW5hYmxlZF09XCJ0cnVlXCIgW3NoYXJlZF09XCJ0cnVlXCIgW2N1c3RvbWl6ZVRvb2x0aXBdPVwiY3VzdG9taXplVG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgIDwvZHhvLXRvb2x0aXA+XG4gICAgICAgICAgICAgICAgPGR4by1jb21tb24tc2VyaWVzLXNldHRpbmdzIGFyZ3VtZW50RmllbGQ9XCJ7e2NoYXJ0Q29uZmlnLmFyZ3VtZW50RmllbGR9fVwiPlxuICAgICAgICAgICAgICAgIDwvZHhvLWNvbW1vbi1zZXJpZXMtc2V0dGluZ3M+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBjaGFydENvbmZpZy5jaGFydF9jb25maWdcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0gJiYgaXRlbS5jb2xvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4aS1zZXJpZXMgdHlwZT1cInt7aXRlbS50eXBlfX1cIiB2YWx1ZUZpZWxkPVwie3tpdGVtLnZhbHVlRmllbGR9fVwiIGF4aXM9XCJ7e2l0ZW0uYXhpc319XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwie3tpdGVtLm5hbWV9fVwiIGNvbG9yPVwie3tpdGVtLmNvbG9yfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZHhpLXNlcmllcz5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtICYmICFpdGVtLmNvbG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHhpLXNlcmllcyB0eXBlPVwie3tpdGVtLnR5cGV9fVwiIHZhbHVlRmllbGQ9XCJ7e2l0ZW0udmFsdWVGaWVsZH19XCIgYXhpcz1cInt7aXRlbS5heGlzfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ7e2l0ZW0ubmFtZX19XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2R4aS1zZXJpZXM+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGR4by1zaXplIFtoZWlnaHRdPVwiY2hhcnRIZWlnaHRcIj5cbiAgICAgICAgICAgICAgICA8L2R4by1zaXplPlxuICAgICAgICAgICAgICAgIDxkeG8tbGVnZW5kIFt2aXNpYmxlXT1cImNoYXJ0Q29uZmlnLmxlZ2VuZERpc3BsYXlcIiB2ZXJ0aWNhbEFsaWdubWVudD1cInt7Y2hhcnRDb25maWcudmVydGljYWxBbGlnbm1lbnR9fVwiXG4gICAgICAgICAgICAgICAgICAgIGhvcml6b250YWxBbGlnbm1lbnQ9XCJ7e2NoYXJ0Q29uZmlnLmhvcml6b250YWxBbGlnbm1lbnR9fVwiPlxuICAgICAgICAgICAgICAgIDwvZHhvLWxlZ2VuZD5cbiAgICAgICAgICAgIDwvZHgtY2hhcnQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hhcnRDb25maWcuY2hhcnRUeXBlID09ICdkb3VnaG51dCcgfHwgY2hhcnRDb25maWcuY2hhcnRUeXBlID09ICdwaWUnXCI+XG5cbiAgICAgICAgICAgIDxkeC1waWUtY2hhcnQgaWQ9XCJwaWVcIiBbdHlwZV09XCJjaGFydENvbmZpZy5jaGFydFR5cGVcIiBbdGl0bGVdPVwieyB0ZXh0OiBjaGFydENvbmZpZy5jYXB0aW9uLCBmb250OiB7IHNpemU6IDE0IH0gfVwiXG4gICAgICAgICAgICAgICAgW2RhdGFTb3VyY2VdPVwiZmluYWxDaGFydERhdGFTb3VyY2VcIiBjZW50ZXJUZW1wbGF0ZT1cImNlbnRlclRlbXBsYXRlXCJcbiAgICAgICAgICAgICAgICAob25Qb2ludENsaWNrKT1cInBvaW50Q2xpY2tIYW5kbGVyKCRldmVudClcIiBbcGFsZXR0ZV09XCJjaGFydENvbmZpZy5wYWxldHRlXCI+XG5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGNoYXJ0Q29uZmlnLmNoYXJ0X2NvbmZpZ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS5jb2xvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4aS1zZXJpZXMgYXJndW1lbnRGaWVsZD17e2NoYXJ0Q29uZmlnLmFyZ3VtZW50RmllbGR9fSB2YWx1ZUZpZWxkPVwie3tpdGVtLnZhbHVlRmllbGR9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInt7aXRlbS5uYW1lfX1cIiBjb2xvcj1cInt7aXRlbS5jb2xvcn19XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4by1sYWJlbCBbdmlzaWJsZV09XCJjaGFydENvbmZpZy5sYWJlbERpc3BsYXlcIiBmb3JtYXQ9XCJjdXJyZW5jeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHhvLWNvbm5lY3RvciBbdmlzaWJsZV09XCJ0cnVlXCI+PC9keG8tY29ubmVjdG9yPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZHhvLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9keGktc2VyaWVzPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpdGVtLmNvbG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHhpLXNlcmllcyBhcmd1bWVudEZpZWxkPXt7Y2hhcnRDb25maWcuYXJndW1lbnRGaWVsZH19IHZhbHVlRmllbGQ9XCJ7e2l0ZW0udmFsdWVGaWVsZH19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwie3tpdGVtLm5hbWV9fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeG8tbGFiZWwgW3Zpc2libGVdPVwiY2hhcnRDb25maWcubGFiZWxEaXNwbGF5XCIgZm9ybWF0PVwiY3VycmVuY3lcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4by1jb25uZWN0b3IgW3Zpc2libGVdPVwidHJ1ZVwiPjwvZHhvLWNvbm5lY3Rvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2R4by1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZHhpLXNlcmllcz5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoYXJ0Q29uZmlnLnNpemVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGR4by1zaXplIFtoZWlnaHRdPVwiY2hhcnRDb25maWcuc2l6ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8L2R4by1zaXplPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxkeG8tbGVnZW5kIFt2aXNpYmxlXT1cImNoYXJ0Q29uZmlnLmxlZ2VuZERpc3BsYXlcIlxuICAgICAgICAgICAgICAgICAgICBob3Jpem9udGFsQWxpZ25tZW50PVwie3tjaGFydENvbmZpZy5ob3Jpem9udGFsQWxpZ25tZW50fX1cIlxuICAgICAgICAgICAgICAgICAgICB2ZXJ0aWNhbEFsaWdubWVudD1cInt7Y2hhcnRDb25maWcudmVydGljYWxBbGlnbm1lbnR9fVwiPjwvZHhvLWxlZ2VuZD5cbiAgICAgICAgICAgICAgICA8IS0tIDxkeG8tZXhwb3J0IFtlbmFibGVkXT1cInRydWVcIj48L2R4by1leHBvcnQ+IC0tPlxuICAgICAgICAgICAgICAgIDxkeG8tdG9vbHRpcCBbZW5hYmxlZF09XCJ0cnVlXCIgW2N1c3RvbWl6ZVRvb2x0aXBdPVwiY3VzdG9taXplVG9vbHRpcFwiIGZvcm1hdD1cImN1cnJlbmN5XCI+XG4gICAgICAgICAgICAgICAgPC9keG8tdG9vbHRpcD5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hhcnRDb25maWcuY2hhcnRUeXBlID09ICdkb3VnaG51dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgPHN2ZyAqZHhUZW1wbGF0ZT1cImxldCBwaWVDaGFydCBvZiAnY2VudGVyVGVtcGxhdGUnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiMTAwXCIgY3k9XCIxMDBcIiBbYXR0ci5yXT1cInBpZUNoYXJ0LmdldElubmVyUmFkaXVzKCkgLSA2XCIgZmlsbD1cImdyYXlcIiBvcGFjaXR5PVwiMC4wMDAxXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZT5cbiAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0IHRleHQtYW5jaG9yPVwibWlkZGxlXCIgc3R5bGU9XCJmb250LXNpemU6IDE1cHhcIiB4PVwiMTAwXCIgeT1cIjEwMFwiIGZpbGw9XCIjZWVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRzcGFuIHg9XCIxMDBcIj57eyBjYWxjdWxhdGVUb3RhbChwaWVDaGFydCkgfX08L3RzcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gZGlzcGxheTogaW5saW5lIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHRzcGFuIHg9XCIxMDBcIiBkeT1cIjIwcHhcIiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDBcIj48L3RzcGFuPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGV4dD5cbiAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2R4LXBpZS1jaGFydD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAnZnVubmVsJ1wiPlxuICAgICAgICAgICAgPGR4LWZ1bm5lbCBpZD1cImZ1bm5lbFwiIFtkYXRhU291cmNlXT1cImZpbmFsQ2hhcnREYXRhU291cmNlXCIgYXJndW1lbnRGaWVsZD1cImFyZ3VtZW50XCIgdmFsdWVGaWVsZD1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICBwYWxldHRlPVwiU29mdCBQYXN0ZWxcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hhcnRDb25maWcuc2l6ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZHhvLXNpemUgW2hlaWdodF09XCJjaGFydENvbmZpZy5zaXplXCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZHhvLXNpemU+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGR4by1leHBvcnQgW2VuYWJsZWRdPVwiZmFsc2VcIj48L2R4by1leHBvcnQ+XG4gICAgICAgICAgICAgICAgPGR4by10b29sdGlwIFtlbmFibGVkXT1cInRydWVcIj4gPC9keG8tdG9vbHRpcD5cbiAgICAgICAgICAgICAgICA8ZHhvLWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgIDxkeG8tYm9yZGVyIFt2aXNpYmxlXT1cInRydWVcIj4gPC9keG8tYm9yZGVyPlxuICAgICAgICAgICAgICAgIDwvZHhvLWl0ZW0+XG4gICAgICAgICAgICAgICAgPGR4by1sYWJlbCBbdmlzaWJsZV09XCJ0cnVlXCIgcG9zaXRpb249XCJpbnNpZGVcIiBiYWNrZ3JvdW5kQ29sb3I9XCJub25lXCJcbiAgICAgICAgICAgICAgICAgICAgW2N1c3RvbWl6ZVRleHRdPVwiY3VzdG9taXplVGV4dFwiPjwvZHhvLWxhYmVsPlxuICAgICAgICAgICAgPC9keC1mdW5uZWw+XG5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAnYnViYmxlJ1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm14LTUgb3ZlcmZsb3cteC1hdXRvXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBoZWF0Q2hhcnREYXRhU291cmNlLmRhdGFTZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLTEwIHRleHQtc20gaXRlbXMtY2VudGVyIG1pbi13LTEyIG1heC13LVszMCVdIGp1c3RpZnktY2VudGVyIGZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2l0ZW0uZGF0YXNvdXJjZX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbmxpbmUtYmxvY2sgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1ub3dyYXAganVzdGlmeS1jZW50ZXIgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGJveCBvZiBpdGVtLmRhdGFzZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXNocmluay0wIG1pbi13LTEwIG1heC13LVsyMCVdIGgtMTAgdGV4dC1zbSBjdXJzb3ItcG9pbnRlciBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciB0ZXh0LWdyYXktODAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCInUmVjb3JkIERhdGU6ICcgKyBib3gucmVjb3JkRGF0ZSArICdcXG5SZWNoYXJnZSBDb3VudDogJyArIGJveC50b29sVGlwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwQ2xhc3M9XCJjdXN0b20tdG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3VuZGVkLWZ1bGxcIiBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6IGJveC5pc0hvdmVyZWQgPyAncmdiKDEzNSwgMTg0LCAxMDYpJyA6IGJveC5jb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aC5weCc6IGJveC5zaXplLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2hvdmVyJzogYm94LmhvdmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2hlaWdodC5weCc6IGJveC5zaXplXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiIChtb3VzZWVudGVyKT1cImJveC5pc0hvdmVyZWQgPSB0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1vdXNlbGVhdmUpPVwiYm94LmlzSG92ZXJlZCA9IGZhbHNlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlubGluZS1ibG9ja1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LW5vd3JhcCBqdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTAgdy0xMiBtYXgtdy1bMjAlXSBoLWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaGVhdENoYXJ0RGF0YVNvdXJjZS5hcmd1bWVudFZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtc2hyaW5rLTAgdy0xMCBtYXgtdy1bMjAlXSBtaW4taC0xNCBmbGV4IHRleHQtc20gaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIG15LTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsnaGVpZ2h0JzogJ2F1dG8nfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1yb3RhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpdGVtfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cblxuICAgIDwvZGl2PlxuXG4gICAgPGJ1dHRvbiAqbmdJZj1cImlzRnVsbFNjcmVlblwiIGNsYXNzPVwiY2xvc2UtYnV0dG9uXCIgKGNsaWNrKT1cInRvZ2dsZUZ1bGxTY3JlZW4oKVwiPkNsb3NlPC9idXR0b24+XG48L2Rpdj4iXX0=