@c8y/ngx-components 1021.50.0 → 1021.51.1

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 (92) hide show
  1. package/core/aggregation/aggregation.model.d.ts.map +1 -0
  2. package/core/aggregation/aggregation.service.d.ts +44 -0
  3. package/core/aggregation/aggregation.service.d.ts.map +1 -0
  4. package/core/aggregation/index.d.ts +3 -0
  5. package/core/aggregation/index.d.ts.map +1 -0
  6. package/core/common/index.d.ts +0 -2
  7. package/core/common/index.d.ts.map +1 -1
  8. package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts +2 -2
  9. package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts.map +1 -1
  10. package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts +1 -1
  11. package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts.map +1 -1
  12. package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts +1 -1
  13. package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts.map +1 -1
  14. package/core/index.d.ts +1 -0
  15. package/core/index.d.ts.map +1 -1
  16. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts +54 -42
  17. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts.map +1 -1
  18. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts +28 -8
  19. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts.map +1 -1
  20. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts +3 -52
  21. package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts.map +1 -1
  22. package/datapoints-export-selector/datapoints-export-selector.model.d.ts +5 -14
  23. package/datapoints-export-selector/datapoints-export-selector.model.d.ts.map +1 -1
  24. package/device-grid/device-grid.component.d.ts.map +1 -1
  25. package/device-grid/device-grid.service.d.ts +2 -0
  26. package/device-grid/device-grid.service.d.ts.map +1 -1
  27. package/esm2022/core/aggregation/aggregation.model.mjs +46 -0
  28. package/esm2022/core/aggregation/aggregation.service.mjs +76 -0
  29. package/esm2022/core/aggregation/index.mjs +3 -0
  30. package/esm2022/core/common/index.mjs +1 -3
  31. package/esm2022/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.mjs +2 -2
  32. package/esm2022/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.mjs +2 -2
  33. package/esm2022/core/dashboard/wiget-time-context/widget-time-context.component.mjs +4 -4
  34. package/esm2022/core/index.mjs +2 -1
  35. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.mjs +165 -163
  36. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.mjs +82 -48
  37. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.mjs +5 -95
  38. package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.mjs +3 -3
  39. package/esm2022/datapoints-export-selector/datapoints-export-selector.component.mjs +3 -3
  40. package/esm2022/datapoints-export-selector/datapoints-export-selector.model.mjs +1 -9
  41. package/esm2022/device-grid/device-grid.component.mjs +3 -3
  42. package/esm2022/device-grid/device-grid.service.mjs +16 -1
  43. package/esm2022/interval-picker/interval-picker.model.mjs +5 -1
  44. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.mjs +25 -41
  45. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.mjs +3 -3
  46. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.mjs +55 -49
  47. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.mjs +25 -73
  48. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-widget.model.mjs +20 -20
  49. package/esm2022/widgets/implementations/datapoints-table/datapoints-table.service.mjs +19 -19
  50. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +247 -307
  51. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
  52. package/fesm2022/c8y-ngx-components-device-grid.mjs +17 -2
  53. package/fesm2022/c8y-ngx-components-device-grid.mjs.map +1 -1
  54. package/fesm2022/c8y-ngx-components-interval-picker.mjs +5 -1
  55. package/fesm2022/c8y-ngx-components-interval-picker.mjs.map +1 -1
  56. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +1075 -1253
  57. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
  58. package/fesm2022/c8y-ngx-components.mjs +118 -76
  59. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  60. package/interval-picker/interval-picker.model.d.ts +6 -0
  61. package/interval-picker/interval-picker.model.d.ts.map +1 -1
  62. package/locales/de.po +40 -27
  63. package/locales/es.po +40 -27
  64. package/locales/fr.po +40 -27
  65. package/locales/ja_JP.po +40 -26
  66. package/locales/ko.po +38 -24
  67. package/locales/locales.pot +23 -25
  68. package/locales/nl.po +40 -27
  69. package/locales/pl.po +40 -26
  70. package/locales/pt_BR.po +40 -27
  71. package/locales/zh_CN.po +38 -24
  72. package/locales/zh_TW.po +38 -24
  73. package/package.json +1 -1
  74. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts +3 -5
  75. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts.map +1 -1
  76. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts +7 -2
  77. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts.map +1 -1
  78. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts +7 -27
  79. package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts.map +1 -1
  80. package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts +4 -3
  81. package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts.map +1 -1
  82. package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts +5 -5
  83. package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts.map +1 -1
  84. package/core/common/aggregation/aggregation.model.d.ts.map +0 -1
  85. package/core/common/aggregation/aggregation.service.d.ts +0 -17
  86. package/core/common/aggregation/aggregation.service.d.ts.map +0 -1
  87. package/esm2022/core/common/aggregation/aggregation.model.mjs +0 -46
  88. package/esm2022/core/common/aggregation/aggregation.service.mjs +0 -34
  89. package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.mjs +0 -124
  90. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts +0 -56
  91. package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts.map +0 -1
  92. /package/core/{common/aggregation → aggregation}/aggregation.model.d.ts +0 -0
@@ -1,5 +1,4 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { DomSanitizer } from '@angular/platform-browser';
3
2
  import { MeasurementService } from '@c8y/client';
4
3
  import { AGGREGATION_VALUES, AlertService, gettext } from '@c8y/ngx-components';
5
4
  import { TranslateService } from '@ngx-translate/core';
@@ -8,14 +7,12 @@ import { UtilsService } from './utils.service';
8
7
  import * as i0 from "@angular/core";
9
8
  import * as i1 from "@c8y/ngx-components";
10
9
  import * as i2 from "@c8y/client";
11
- import * as i3 from "@angular/platform-browser";
12
- import * as i4 from "@ngx-translate/core";
13
- import * as i5 from "./utils.service";
10
+ import * as i3 from "@ngx-translate/core";
11
+ import * as i4 from "./utils.service";
14
12
  export class DataFetchingService {
15
- constructor(alertService, measurementService, sanitizer, translateService, utilsService) {
13
+ constructor(alertService, measurementService, translateService, utilsService) {
16
14
  this.alertService = alertService;
17
15
  this.measurementService = measurementService;
18
- this.sanitizer = sanitizer;
19
16
  this.translateService = translateService;
20
17
  this.utilsService = utilsService;
21
18
  }
@@ -58,6 +55,7 @@ export class DataFetchingService {
58
55
  }
59
56
  catch (error) {
60
57
  this.alertService.addServerFailure(error);
58
+ return null;
61
59
  }
62
60
  });
63
61
  const results = await Promise.all(promises);
@@ -100,6 +98,33 @@ export class DataFetchingService {
100
98
  ]);
101
99
  return trimmedMessage;
102
100
  }
101
+ /**
102
+ * Trims the given HTML message by removing list items that correspond to zero counts.
103
+ *
104
+ * @param message - The HTML string containing the message with list items.
105
+ * @param counts - An array of number values corresponding to each list item.
106
+ * @param countToTrim - A count that will be trimmed with corresponding list item.
107
+ * @returns A trimmed HTML string with list items removed where the corresponding count is zero.
108
+ *
109
+ * Example:
110
+ * ```typescript
111
+ * const message = '<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>';
112
+ * const counts = [1, 0, 2];
113
+ * const trimmedMessage = this.removeZeroCountListItems(message, counts);
114
+ * // Result: '<ul><li>Item 1</li><li>Item 3</li></ul>'
115
+ * ```
116
+ */
117
+ removeZeroCountListItems(message, counts, countToTrim = 0) {
118
+ const parser = new DOMParser();
119
+ const doc = parser.parseFromString(message, 'text/html');
120
+ const listItems = doc.querySelectorAll('ul li');
121
+ listItems.forEach((item, index) => {
122
+ if (counts[index] === countToTrim) {
123
+ item.remove();
124
+ }
125
+ });
126
+ return doc.body.innerHTML;
127
+ }
103
128
  /**
104
129
  * Displays an information alert about sending data via email.
105
130
  *
@@ -123,8 +148,8 @@ export class DataFetchingService {
123
148
  const filePromises = exportConfig.datapointDetails.map(details => this.fetchAndProcessMeasurementFile(details, measurementFileConfig));
124
149
  return Promise.all(filePromises);
125
150
  }
126
- async fetchAndProcessMeasurementFile(details, measurementFileConfig) {
127
- const filter = this.prepareMeasurementsFilter(details, measurementFileConfig.exportConfig);
151
+ async fetchAndProcessMeasurementFile(details, measurementFileConfig, roundSeconds = false) {
152
+ const filter = this.prepareMeasurementsFilter(details, measurementFileConfig.exportConfig, roundSeconds);
128
153
  const header = { accept: measurementFileConfig.acceptFileType };
129
154
  try {
130
155
  const measurementFileResponse = await this.measurementService.getMeasurementsFile(filter, header);
@@ -151,6 +176,77 @@ export class DataFetchingService {
151
176
  ? await this.fetchAndPrepareMeasurementDataToExportForPreview(exportConfig)
152
177
  : await this.fetchAndPrepareSeriesDataToExport(exportConfig);
153
178
  }
179
+ prepareMeasurementsFilter(details, exportConfig, roundSeconds, pageSize) {
180
+ const filter = {
181
+ dateFrom: this.adjustDate(exportConfig.dateFrom, 0, roundSeconds),
182
+ dateTo: this.adjustDate(exportConfig.dateTo, 0, roundSeconds),
183
+ source: details.source,
184
+ valueFragmentSeries: details.valueFragmentSeries,
185
+ valueFragmentType: details.valueFragmentType
186
+ };
187
+ if (pageSize) {
188
+ filter.pageSize = pageSize;
189
+ }
190
+ return filter;
191
+ }
192
+ processMeasurementDataForPreview(details, data) {
193
+ const unit = data[0][details.valueFragmentType][details.valueFragmentSeries]?.unit || '';
194
+ const values = {};
195
+ data.forEach(measurement => {
196
+ values[measurement.time] =
197
+ measurement[details.valueFragmentType][details.valueFragmentSeries].value;
198
+ });
199
+ return { ...details, unit, timeValueMap: values };
200
+ }
201
+ /**
202
+ * Returns a map of active data points device IDs with their corresponding series.
203
+ *
204
+ * Example output:
205
+ * ```typescript
206
+ * new Map([
207
+ * ['844657202', ['c8y_Temperature.T']],
208
+ * ['32666427', ['c8y_Battery.Battery']]
209
+ * ]);
210
+ * ```
211
+ * @param datapointDetails - An array of data points details.
212
+ * @returns A map where the key is the data point ID and the value is an array of data point series.
213
+ */
214
+ groupSeriesByDeviceId(datapointDetails) {
215
+ return datapointDetails.reduce((map, { valueFragmentType, valueFragmentSeries, source }) => {
216
+ const value = `${valueFragmentType}.${valueFragmentSeries}`;
217
+ const existingValue = map.get(source) ?? [];
218
+ map.set(source, [...existingValue, value]);
219
+ return map;
220
+ }, new Map());
221
+ }
222
+ /**
223
+ * Processes the fetched series data and prepares it for export.
224
+ *
225
+ * @param datapointDetails - An array of data point details.
226
+ * @param fetchedDataMap - A map of fetched series data grouped by source.
227
+ * @returns An array of DataToExport objects.
228
+ */
229
+ processSeriesData(datapointDetails, fetchedDataMap) {
230
+ const valuesGroupedBySource = this.utilsService.transformDataStructure(fetchedDataMap);
231
+ return datapointDetails.map((details) => {
232
+ let unit;
233
+ let data;
234
+ /**
235
+ * Unique key to distinguish between different series from same source,
236
+ * e.g.: c8y_Acceleration.accelerationX, c8y_Acceleration.accelerationY, c8y_Acceleration.accelerationZ
237
+ */
238
+ const seriesKey = `${details.valueFragmentType}.${details.valueFragmentSeries}`;
239
+ if (valuesGroupedBySource[details.source][seriesKey]) {
240
+ unit = valuesGroupedBySource[details.source][seriesKey].seriesDetails.unit;
241
+ data = valuesGroupedBySource[details.source][seriesKey].values;
242
+ }
243
+ return {
244
+ ...details,
245
+ unit,
246
+ timeValueMap: data
247
+ };
248
+ });
249
+ }
154
250
  async getSourcesWithPermissionsToRead(datapointDetails) {
155
251
  const dateFrom = new Date();
156
252
  const dateTo = new Date(dateFrom);
@@ -175,6 +271,56 @@ export class DataFetchingService {
175
271
  const fetchedSources = await Promise.all(fetchedDataPromises);
176
272
  return fetchedSources.filter((source) => source !== null);
177
273
  }
274
+ /**
275
+ * Adjusts the given date by adding the specified number of minutes and setting seconds to 0.
276
+ *
277
+ * @param date - The date to be adjusted in string format.
278
+ * @param minutes - The number of minutes to add to the date.
279
+ * @param roundSeconds - Whether to round the seconds or not.
280
+ * If true, the seconds will be rounded to 0.
281
+ * If false, the seconds will be displayed as they are.
282
+ * @returns The adjusted date in ISO string format.
283
+ */
284
+ adjustDate(date, minutes, roundSeconds = true) {
285
+ const dateTime = new Date(date);
286
+ if (isNaN(dateTime.getTime())) {
287
+ throw new Error('Invalid date');
288
+ }
289
+ dateTime.setUTCMinutes(dateTime.getUTCMinutes() + minutes);
290
+ if (roundSeconds) {
291
+ dateTime.setUTCSeconds(0, 0);
292
+ }
293
+ return dateTime.toISOString();
294
+ }
295
+ /**
296
+ * Asynchronously loads series data based on the provided parameters.
297
+ *
298
+ * This method constructs a filter for retrieving series data within a specified date range,
299
+ * from a specific source, and optionally applying an aggregation type.
300
+ *
301
+ * @param rawFilter - The parameters for loading series data, including date range, source, series names, and aggregation type.
302
+ * @param roundSeconds - Indicates whether to round the seconds in the date range to the nearest whole number.
303
+ * @returns A promise that resolves to series data wrapped in result object.
304
+ */
305
+ async fetchSeriesData(rawFilter, roundSeconds = false) {
306
+ let seriesData;
307
+ const filter = this.prepareSeriesFilter({
308
+ dateFrom: rawFilter.dateFrom,
309
+ dateTo: rawFilter.dateTo,
310
+ source: rawFilter.source,
311
+ series: rawFilter.series,
312
+ aggregationType: rawFilter.aggregationType
313
+ }, roundSeconds);
314
+ try {
315
+ // TODO: consider adding a cache mechanism -> MTM-60289, MTM-59233
316
+ // When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
317
+ seriesData = await this.measurementService.listSeries(filter);
318
+ }
319
+ catch (error) {
320
+ this.alertService.addServerFailure(error);
321
+ }
322
+ return seriesData;
323
+ }
178
324
  /**
179
325
  * Fetches and prepares measurement data for preview.
180
326
  *
@@ -183,11 +329,12 @@ export class DataFetchingService {
183
329
  * CSV/Excel files are generated by the backend for measurements.
184
330
  *
185
331
  * @param exportConfig - The export configuration.
332
+ * @param roundSeconds - Indicates whether to round the seconds in the date range to the nearest whole number.
186
333
  * @returns A promise that resolves to an array of DataToExport objects or null when no data is fetched.
187
334
  */
188
- async fetchAndPrepareMeasurementDataToExportForPreview(exportConfig) {
335
+ async fetchAndPrepareMeasurementDataToExportForPreview(exportConfig, roundSeconds = false) {
189
336
  const dataToExportPromises = exportConfig.datapointDetails.map(async (details) => {
190
- const fetchedMeasurementData = await this.fetchMeasurementDataForPreview(details, exportConfig);
337
+ const fetchedMeasurementData = await this.fetchMeasurementDataForPreview(details, exportConfig, roundSeconds);
191
338
  if (fetchedMeasurementData?.data?.length) {
192
339
  return this.processMeasurementDataForPreview(details, fetchedMeasurementData.data);
193
340
  }
@@ -195,9 +342,9 @@ export class DataFetchingService {
195
342
  });
196
343
  return await Promise.all(dataToExportPromises);
197
344
  }
198
- async fetchMeasurementDataForPreview(details, exportConfig) {
345
+ async fetchMeasurementDataForPreview(details, exportConfig, roundSeconds) {
199
346
  let measurements;
200
- const filter = this.prepareMeasurementsFilter(details, exportConfig, MEASUREMENTS_PREVIEW_ITEMS_LIMIT);
347
+ const filter = this.prepareMeasurementsFilter(details, exportConfig, roundSeconds, MEASUREMENTS_PREVIEW_ITEMS_LIMIT);
201
348
  try {
202
349
  // TODO: consider adding a cache mechanism -> MTM-60289
203
350
  // When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
@@ -208,30 +355,6 @@ export class DataFetchingService {
208
355
  }
209
356
  return measurements;
210
357
  }
211
- prepareMeasurementsFilter(details, exportConfig, pageSize) {
212
- const filter = {
213
- // Round the 'from' time to the previous full minute.
214
- dateFrom: this.adjustDate(exportConfig.dateFrom, -1),
215
- // Round the 'to' time to the nearest full minute.
216
- dateTo: this.adjustDate(exportConfig.dateTo, 1),
217
- source: details.source,
218
- valueFragmentSeries: details.valueFragmentSeries,
219
- valueFragmentType: details.valueFragmentType
220
- };
221
- if (pageSize) {
222
- filter.pageSize = pageSize;
223
- }
224
- return filter;
225
- }
226
- processMeasurementDataForPreview(details, data) {
227
- const unit = data[0][details.valueFragmentType][details.valueFragmentSeries]?.unit || '';
228
- const values = {};
229
- data.forEach(measurement => {
230
- values[measurement.time] =
231
- measurement[details.valueFragmentType][details.valueFragmentSeries].value;
232
- });
233
- return { ...details, unit, timeValueMap: values };
234
- }
235
358
  async fetchAndPrepareSeriesDataToExport(exportConfig) {
236
359
  const datapointsValuesDataMap = this.groupSeriesByDeviceId(exportConfig.datapointDetails);
237
360
  const fetchedDataPromises = Array.from(datapointsValuesDataMap).map(async ([source, series]) => {
@@ -249,52 +372,10 @@ export class DataFetchingService {
249
372
  const fetchedDataGroupedBySource = await Promise.all(fetchedDataPromises);
250
373
  return this.processSeriesData(exportConfig.datapointDetails, fetchedDataGroupedBySource);
251
374
  }
252
- /**
253
- * Returns a map of active data points device IDs with their corresponding series.
254
- *
255
- * Example output:
256
- * ```typescript
257
- * new Map([
258
- * ['844657202', ['c8y_Temperature.T']],
259
- * ['32666427', ['c8y_Battery.Battery']]
260
- * ]);
261
- * ```
262
- * @param datapointDetails - An array of data points details.
263
- * @returns A map where the key is the data point ID and the value is an array of data point series.
264
- */
265
- groupSeriesByDeviceId(datapointDetails) {
266
- return datapointDetails.reduce((map, { valueFragmentType, valueFragmentSeries, source }) => {
267
- const value = `${valueFragmentType}.${valueFragmentSeries}`;
268
- const existingValue = map.get(source) ?? [];
269
- map.set(source, [...existingValue, value]);
270
- return map;
271
- }, new Map());
272
- }
273
- async fetchSeriesData(rawFilter) {
274
- let seriesData;
275
- const filter = this.prepareSeriesFilter({
276
- dateFrom: rawFilter.dateFrom,
277
- dateTo: rawFilter.dateTo,
278
- source: rawFilter.source,
279
- series: rawFilter.series,
280
- aggregationType: rawFilter.aggregationType
281
- });
282
- try {
283
- // TODO: consider adding a cache mechanism -> MTM-60289
284
- // When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
285
- seriesData = await this.measurementService.listSeries(filter);
286
- }
287
- catch (error) {
288
- this.alertService.addServerFailure(error);
289
- }
290
- return seriesData;
291
- }
292
- prepareSeriesFilter(filters) {
375
+ prepareSeriesFilter(filters, roundSeconds) {
293
376
  const { dateFrom, dateTo, source, series, aggregationType } = filters;
294
- // Round the 'from' time to the previous full minute.
295
- const from = this.adjustDate(dateFrom, -1);
296
- // Round the 'to' time to the nearest full minute.
297
- const to = this.adjustDate(dateTo, 1);
377
+ const from = this.adjustDate(dateFrom, 0, roundSeconds);
378
+ const to = this.adjustDate(dateTo, 0, roundSeconds);
298
379
  const filter = {
299
380
  dateFrom: from,
300
381
  dateTo: to,
@@ -316,86 +397,7 @@ export class DataFetchingService {
316
397
  }
317
398
  return filter;
318
399
  }
319
- /**
320
- * Processes the fetched series data and prepares it for export.
321
- *
322
- * @param datapointDetails - An array of data point details.
323
- * @param fetchedDataMap - A map of fetched series data grouped by source.
324
- * @returns An array of DataToExport objects.
325
- */
326
- processSeriesData(datapointDetails, fetchedDataMap) {
327
- const valuesGroupedBySource = this.utilsService.transformDataStructure(fetchedDataMap);
328
- return datapointDetails.map((details) => {
329
- let unit;
330
- let data;
331
- /**
332
- * Unique key to distinguish between different series from same source,
333
- * e.g.: c8y_Acceleration.accelerationX, c8y_Acceleration.accelerationY, c8y_Acceleration.accelerationZ
334
- */
335
- const seriesKey = `${details.valueFragmentType}.${details.valueFragmentSeries}`;
336
- if (valuesGroupedBySource[details.source][seriesKey]) {
337
- unit = valuesGroupedBySource[details.source][seriesKey].seriesDetails.unit;
338
- data = valuesGroupedBySource[details.source][seriesKey].values;
339
- }
340
- return {
341
- ...details,
342
- unit,
343
- timeValueMap: data
344
- };
345
- });
346
- }
347
- /**
348
- * Adjusts the given date by adding the specified number of minutes and setting seconds to 0.
349
- *
350
- * @param date - The date to be adjusted in string format.
351
- * @param minutes - The number of minutes to add to the date.
352
- * @returns The adjusted date in the format 'YYYY-MM-DDTHH:mm:ss+HH:MM'.
353
- */
354
- adjustDate(date, minutes) {
355
- const dateTime = new Date(date);
356
- dateTime.setMinutes(dateTime.getMinutes() + minutes);
357
- dateTime.setSeconds(0);
358
- const offset = -dateTime.getTimezoneOffset();
359
- const offsetSign = offset >= 0 ? '+' : '-';
360
- const pad = (num) => (num < 10 ? '0' + num : num.toString());
361
- const offsetHours = pad(Math.floor(Math.abs(offset) / 60));
362
- const offsetMinutes = pad(Math.abs(offset) % 60);
363
- const year = dateTime.getFullYear();
364
- const month = pad(dateTime.getMonth() + 1);
365
- const day = pad(dateTime.getDate());
366
- const hours = pad(dateTime.getHours());
367
- const minutesString = pad(dateTime.getMinutes());
368
- const seconds = '00';
369
- return `${year}-${month}-${day}T${hours}:${minutesString}:${seconds}${offsetSign}${offsetHours}:${offsetMinutes}`;
370
- }
371
- /**
372
- * Trims the given HTML message by removing list items that correspond to zero counts.
373
- *
374
- * @param message - The HTML string containing the message with list items.
375
- * @param counts - An array of number values corresponding to each list item.
376
- * @param countToTrim - A count that will be trimmed with corresponding list item.
377
- * @returns A trimmed HTML string with list items removed where the corresponding count is zero.
378
- *
379
- * Example:
380
- * ```typescript
381
- * const message = '<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>';
382
- * const counts = [1, 0, 2];
383
- * const trimmedMessage = this.removeZeroCountListItems(message, counts);
384
- * // Result: '<ul><li>Item 1</li><li>Item 3</li></ul>'
385
- * ```
386
- */
387
- removeZeroCountListItems(message, counts, countToTrim = 0) {
388
- const parser = new DOMParser();
389
- const doc = parser.parseFromString(message, 'text/html');
390
- const listItems = doc.querySelectorAll('ul li');
391
- listItems.forEach((item, index) => {
392
- if (counts[index] === countToTrim) {
393
- item.remove();
394
- }
395
- });
396
- return doc.body.innerHTML;
397
- }
398
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, deps: [{ token: i1.AlertService }, { token: i2.MeasurementService }, { token: i3.DomSanitizer }, { token: i4.TranslateService }, { token: i5.UtilsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
400
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, deps: [{ token: i1.AlertService }, { token: i2.MeasurementService }, { token: i3.TranslateService }, { token: i4.UtilsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
399
401
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, providedIn: 'root' }); }
400
402
  }
401
403
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, decorators: [{
@@ -403,5 +405,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
403
405
  args: [{
404
406
  providedIn: 'root'
405
407
  }]
406
- }], ctorParameters: () => [{ type: i1.AlertService }, { type: i2.MeasurementService }, { type: i3.DomSanitizer }, { type: i4.TranslateService }, { type: i5.UtilsService }] });
407
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mZXRjaGluZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3IvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItbW9kYWwvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItZmlsZS1leHBvcnRlci9kYXRhLWZldGNoaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQVNMLGtCQUFrQixFQUNuQixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFRTCxnQ0FBZ0MsRUFFakMsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRCxPQUFPLEVBQWMsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7Ozs7QUFLM0QsTUFBTSxPQUFPLG1CQUFtQjtJQUM5QixZQUNVLFlBQTBCLEVBQzFCLGtCQUFzQyxFQUN0QyxTQUF1QixFQUN2QixnQkFBa0MsRUFDbEMsWUFBMEI7UUFKMUIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxjQUFTLEdBQVQsU0FBUyxDQUFjO1FBQ3ZCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWM7SUFDakMsQ0FBQztJQUVKOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLDJCQUEyQixDQUMvQixZQUEwQjtRQUUxQixNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FB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QUssSUFBSSxhQUFhLElBQUksT0FBTyxHQUFHLFVBQVUsR0FBRyxXQUFXLElBQUksYUFBYSxFQUFFLENBQUM7SUFDcEgsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNLLHdCQUF3QixDQUFDLE9BQWUsRUFBRSxNQUFnQixFQUFFLFdBQVcsR0FBRyxDQUFDO1FBQ2pGLE1BQU0sTUFBTSxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7UUFDL0IsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDekQsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWhELFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDaEMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzVCLENBQUM7OEdBcmdCVSxtQkFBbUI7a0hBQW5CLG1CQUFtQixjQUZsQixNQUFNOzsyRkFFUCxtQkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQge1xuICBhZ2dyZWdhdGlvblR5cGUsXG4gIElGZXRjaFJlc3BvbnNlLFxuICBJTWVhc3VyZW1lbnQsXG4gIElNZWFzdXJlbWVudEZpbHRlcixcbiAgSVJlc3VsdCxcbiAgSVJlc3VsdExpc3QsXG4gIElTZXJpZXMsXG4gIElTZXJpZXNGaWx0ZXIsXG4gIE1lYXN1cmVtZW50U2VydmljZVxufSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBBR0dSRUdBVElPTl9WQUxVRVMsIEFsZXJ0U2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtcbiAgRGF0YXBvaW50RGV0YWlscyxcbiAgRGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0LFxuICBEYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCxcbiAgRGF0YVRvRXhwb3J0LFxuICBEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlLFxuICBFeHBvcnRDb25maWcsXG4gIE1lYXN1cmVtZW50RmlsZUNvbmZpZyxcbiAgTUVBU1VSRU1FTlRTX1BSRVZJRVdfSVRFTVNfTElNSVQsXG4gIFRpbWVTZXJpZXNEYXRhXG59IGZyb20gJy4uLy4uL2RhdGFwb2ludHMtZXhwb3J0LXNlbGVjdG9yLm1vZGVsJztcbmltcG9ydCB7IFNvdXJjZUl0ZW0sIFV0aWxzU2VydmljZSB9IGZyb20gJy4vdXRpbHMuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIERhdGFGZXRjaGluZ1NlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFsZXJ0U2VydmljZTogQWxlcnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgbWVhc3VyZW1lbnRTZXJ2aWNlOiBNZWFzdXJlbWVudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBwcml2YXRlIHRyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB1dGlsc1NlcnZpY2U6IFV0aWxzU2VydmljZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhbnkgb2YgbWVhc3VyZW1lbnRzIHJlcXVlc3RzIG1heSBleGNlZWRlZCB0aGUgbGltaXQsXG4gICAqIGFmdGVyIHdoaWNoIHRoZSBleHBvcnQgZGF0YSBpcyBwcm9jZXNzZWQgYnkgdGhlIGJhY2tlbmQgYW5kIHRoZSBnZW5lcmF0ZWQgQ1NWL0V4Y2VsIGZpbGUgaXMgc2VudCBieSBlbWFpbC5cbiAgICpcbiAgICogVGhlIHRocmVzaG9sZCBpcyBzZXQgdG8gNTBfMDAwIHJlY29yZHMgaW4gYXBwbGljYXRpb24ncyBjb3JlIHByb3BlcnRpZXMgKGV4cG9ydC5kYXRhLnN5bmNocm9ub3VzLmxpbWl0KS5cbiAgICpcbiAgICogQHBhcmFtIGV4cG9ydENvbmZpZyAtIFRoZSBleHBvcnQgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmV0dXJucyBhbiBhcnJheSBvZiBvYmplY3RzIHJlcHJlc2VudGluZyBkYXRhcG9pbnRzIGZpbGVzIHRoYXQgd2lsbCBiZSBzZW50IGJ5IGVtYWlsLlxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0KFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0W10+IHtcbiAgICBjb25zdCBiYWNrZW5kUHJvY2Vzc2luZ0xpbWl0ID0gNTBfMDAwO1xuXG4gICAgY29uc3QgcHJvbWlzZXM6IFByb21pc2U8RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0PltdID0gZXhwb3J0Q29uZmlnLmRhdGFwb2ludERldGFpbHMubWFwKFxuICAgICAgYXN5bmMgZGV0YWlscyA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB7XG4gICAgICAgICAgICBkYXRlRnJvbTogZXhwb3J0Q29uZmlnLmRhdGVGcm9tLFxuICAgICAgICAgICAgZGF0ZVRvOiBleHBvcnRDb25maWcuZGF0ZVRvLFxuICAgICAgICAgICAgcGFnZVNpemU6IDEsXG4gICAgICAgICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgICAgICAgdmFsdWVGcmFnbWVudFNlcmllczogZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzLFxuICAgICAgICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGUsXG4gICAgICAgICAgICB3aXRoVG90YWxFbGVtZW50czogdHJ1ZVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMubWVhc3VyZW1lbnRTZXJ2aWNlLmxpc3QoZmlsdGVyKTtcblxuICAgICAgICAgIGlmIChyZXNwb25zZT8ucGFnaW5nPy50b3RhbEVsZW1lbnRzID4gYmFja2VuZFByb2Nlc3NpbmdMaW1pdCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZGF0YXBvaW50RGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgc291cmNlOiBkZXRhaWxzLnNvdXJjZSxcbiAgICAgICAgICAgICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICAgICAgICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGVcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdG90YWxFbGVtZW50czogcmVzcG9uc2UucGFnaW5nLnRvdGFsRWxlbWVudHNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHRzOiBEYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRbXSA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcblxuICAgIGNvbnN0IGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdCA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiByZXN1bHQgIT09IG51bGwpO1xuXG4gICAgcmV0dXJuIGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkIHdoZW4gdGhlIGxpbWl0IG9mIGRhdGFwb2ludHMgaXMgZXhjZWVkZWQgZHVyaW5nIGZpbGUgZXhwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0gaGFzTm9FeHBvcnRhYmxlRGF0YSAtIEluZGljYXRlcyBpZiB0aGVyZSBpcyBubyBleHBvcnRhYmxlIGRhdGEgYmVjYXVzZSB0aGUgZGF0ZSByYW5nZSBvZiBhbGwgc2VsZWN0ZWQgZGF0YXBvaW50cyBleGNlZWRzIDEsMDAwLDAwMCByZWNvcmRzLlxuICAgKiBAcGFyYW0gZW1haWxEZWxpdmVyYWJsZUNvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyB0aGF0IGV4Y2VlZCB0aGUgbGltaXQsIHdpbGwgYmUgcHJvY2VlZGVkIGJ5IHRoZSBiYWNrZW5kIGFuZCBzZW50IGJ5IGVtYWlsLlxuICAgKiBAcGFyYW0gYnJvd3NlckRvd25sb2FkYWJsZUNvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyB0aGF0IGNhbiBiZSBkb3dubG9hZGVkIGRpcmVjdGx5LlxuICAgKiBAcGFyYW0gc2tpcHBlZERhdGFwb2ludENvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyBza2lwcGVkIGR1ZSB0byBleGNlZWRpbmcgdGhlIG1lYXN1cmVtZW50cyBBUEkgbGltaXQgb2YgMSwwMDAsMDAwIHJlY29yZHMuXG4gICAqIEBwYXJhbSB0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50IC0gVG90YWwgbnVtYmVyIG9mIGRhdGFwb2ludCBzZWxlY3RlZCBmb3IgZXhwb3J0cy5cbiAgICogQHJldHVybnMgVGhlIG1lc3NhZ2UgdGhhdCBjYW4gYmUgaW5qZWN0ZWQuXG4gICAqL1xuICBnZXRMaW1pdEV4Y2VlZGVkTWVzc2FnZShcbiAgICBoYXNOb0V4cG9ydGFibGVEYXRhOiBib29sZWFuLFxuICAgIGVtYWlsRGVsaXZlcmFibGVDb3VudD86IG51bWJlcixcbiAgICBicm93c2VyRG93bmxvYWRhYmxlQ291bnQ/OiBudW1iZXIsXG4gICAgbm9uUmV0cmlldmFibGVDb3VudD86IG51bWJlcixcbiAgICB0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50PzogbnVtYmVyXG4gICk6IHN0cmluZyB7XG4gICAgaWYgKGhhc05vRXhwb3J0YWJsZURhdGEpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgICAgZ2V0dGV4dChcbiAgICAgICAgICBgVGhlIGRhdGEgZm9yIHNlbGVjdGVkIGRhdGFwb2ludChzKSBleGNlZWQgMSwwMDAsMDAwIHJlY29yZHMsIHdoaWNoIGlzIHRoZSBsaW1pdCBmb3IgYmFja2VuZCBwcm9jZXNzaW5nLiBUbyBleHBvcnQgdGhpcyBkYXRhLCBwbGVhc2UgcmVkdWNlIHRoZSBkYXRlIHJhbmdlLmBcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgIGdldHRleHQoXG4gICAgICAgIGBBZnRlciBjbGlja2luZyBcIkRvd25sb2FkXCI6PGJyPlxuICAgICAgICA8dWw+XG4gICAgICAgICAgPGxpPjxzdHJvbmc+e3skYnJvd3NlckRvd25sb2FkYWJsZUNvdW50fX08L3N0cm9uZz4gZGF0YXBvaW50KHMpIGV4cG9ydHMgd2lsbCBiZSBkb3dubG9hZGVkIGRpcmVjdGx5IHdpdGhpbiBvbmUgZmlsZTogPGVtPmV4cG9ydGVkX1tjc3YvZXhjZWxdLnppcDwvZW0+PC9saT5cbiAgICAgICAgICA8bGk+PHN0cm9uZz57eyRlbWFpbERlbGl2ZXJhYmxlQ291bnR9fTwvc3Ryb25nPiBkYXRhcG9pbnQocykgZXhwb3J0cyByZXF1aXJlIGZ1cnRoZXIgcHJvY2Vzc2luZy4gVGhlIGZpbGVzIHdpbGwgYmUgc2VudCB0byB5b3UgdmlhIHNlcGFyYXRlIGVtYWlscyBvbmNlIGNvbXBsZXRlZCwgd2hpY2ggbWF5IHRha2Ugc29tZSB0aW1lLjwvbGk+XG4gICAgICAgICAgPGxpPjxzdHJvbmc+e3skbm9uUmV0cmlldmFibGVDb3VudH19PC9zdHJvbmc+IGRhdGFwb2ludChzKSBleHBvcnRzIGV4Y2VlZGVkIDEsMDAwLDAwMCByZWNvcmRzLCB3aGljaCBpcyB0aGUgbGltaXQgZm9yIGJhY2tlbmQgcHJvY2Vzc2luZy4gVG8gZXhwb3J0IHRoZXNlIGRhdGEsIHBsZWFzZSByZWR1Y2UgdGhlIGRhdGUgcmFuZ2UuIE90aGVyd2lzZSwgdGhlIGRhdGEgd2lsbCBuZWl0aGVyIGJlIGRvd25sb2FkZWQgbm9yIHNlbnQgdmlhIGVtYWlsLjwvbGk+XG4gICAgICAgIDwvdWw+XG4gICAgICAgIDxwPlRoZSB0b3RhbCBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBjYW4gYmUgZXhwb3J0ZWQgaXM6IDxzdHJvbmc+e3skdG90YWxFeHBvcnRhYmxlRGF0YXBvaW50c0NvdW50fX0gb3V0IG9mIHt7JHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnR9fTwvc3Ryb25nPi48L3A+XG4gICAgICAgIDxwPjxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGZpbGUgbmFtZSBjb252ZW50aW9uIG9mIGZpbGVzIHdpdGhpbiB6aXAgZmlsZSBpczogPGNvZGU+W3NvdXJjZV1fW2ZyYWdtZW50X3Nlcmllc10uW2Nzdi94bHNdPC9jb2RlPjwvcD5gXG4gICAgICApLFxuICAgICAge1xuICAgICAgICAkYnJvd3NlckRvd25sb2FkYWJsZUNvdW50OiBicm93c2VyRG93bmxvYWRhYmxlQ291bnQsXG4gICAgICAgICRlbWFpbERlbGl2ZXJhYmxlQ291bnQ6IGVtYWlsRGVsaXZlcmFibGVDb3VudCxcbiAgICAgICAgJG5vblJldHJpZXZhYmxlQ291bnQ6IG5vblJldHJpZXZhYmxlQ291bnQsXG4gICAgICAgICR0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50OiB0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50LFxuICAgICAgICAkdG90YWxFeHBvcnRhYmxlRGF0YXBvaW50c0NvdW50OiBicm93c2VyRG93bmxvYWRhYmxlQ291bnQgKyBlbWFpbERlbGl2ZXJhYmxlQ291bnRcbiAgICAgIH1cbiAgICApO1xuXG4gICAgY29uc3QgdHJpbW1lZE1lc3NhZ2UgPSB0aGlzLnJlbW92ZVplcm9Db3VudExpc3RJdGVtcyhtZXNzYWdlLCBbXG4gICAgICBicm93c2VyRG93bmxvYWRhYmxlQ291bnQsXG4gICAgICBlbWFpbERlbGl2ZXJhYmxlQ291bnQsXG4gICAgICBub25SZXRyaWV2YWJsZUNvdW50XG4gICAgXSk7XG5cbiAgICByZXR1cm4gdHJpbW1lZE1lc3NhZ2U7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGxheXMgYW4gaW5mb3JtYXRpb24gYWxlcnQgYWJvdXQgc2VuZGluZyBkYXRhIHZpYSBlbWFpbC5cbiAgICpcbiAgICogT25seSBtZWFzdXJlbWVudHMgQVBJIGNhbiBzZW5kIGZpbGVzIHZpYSBlbWFpbC5cbiAgICpcbiAgICogQHBhcmFtIGZpbGVUeXBlIC0gVGhlIHR5cGUgb2YgZmlsZSB0byBiZSBzZW50LlxuICAgKiBAcGFyYW0gZGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0IC0gVGhlIGFycmF5IG9mIGRhdGFwb2ludHMgZXhjZWVkaW5nIHRoZSBsaW1pdC5cbiAgICovXG4gIHNob3dTZW5kVmlhRW1haWxJbmZvQWxlcnQoXG4gICAgZmlsZVR5cGU6IHN0cmluZyxcbiAgICBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQ6IERhdGFwb2ludHNFeGNlZWRpbmdMaW1pdFtdXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IG1lc3NhZ2VUZW1wbGF0ZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgZ2V0dGV4dChgWW91IHdpbGwgZ2V0IHt7JGZpbGVUeXBlVGV4dH19IGZpbGUocykgZm9yIHt7JGNvdW50fX0gc2VyaWVzIHZpYSBlbWFpbC5gKSxcbiAgICAgIHsgJGNvdW50OiBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQubGVuZ3RoLCAkZmlsZVR5cGVUZXh0OiBmaWxlVHlwZSB9XG4gICAgKTtcbiAgICBjb25zdCBmb3JtYXR0ZWRMaXN0ID0gZGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0XG4gICAgICAubWFwKFxuICAgICAgICBkYXRhcG9pbnQgPT5cbiAgICAgICAgICBg4oCiICR7ZGF0YXBvaW50LmRhdGFwb2ludERldGFpbC5zb3VyY2V9XyR7ZGF0YXBvaW50LmRhdGFwb2ludERldGFpbC52YWx1ZUZyYWdtZW50VHlwZX1fJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnZhbHVlRnJhZ21lbnRTZXJpZXN9YFxuICAgICAgKVxuICAgICAgLmpvaW4oJ1xcbicpO1xuXG4gICAgdGhpcy5hbGVydFNlcnZpY2UuaW5mbyhtZXNzYWdlVGVtcGxhdGUsIGZvcm1hdHRlZExpc3QpO1xuICB9XG5cbiAgYXN5bmMgZmV0Y2hNZWFzdXJlbWVudERhdGFGaWxlc0FuZFBhaXJXaXRoU291cmNlRGV0YWlscyhcbiAgICBhY2NlcHRGaWxlVHlwZTogc3RyaW5nLFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8RGF0YVRvRXhwb3J0V2l0aEJhY2tlbmRDcmVhdGVkRmlsZVtdPiB7XG4gICAgY29uc3QgbWVhc3VyZW1lbnRGaWxlQ29uZmlnOiBNZWFzdXJlbWVudEZpbGVDb25maWcgPSB7XG4gICAgICBleHBvcnRDb25maWcsXG4gICAgICBhY2NlcHRGaWxlVHlwZVxuICAgIH07XG4gICAgY29uc3QgZmlsZVByb21pc2VzID0gZXhwb3J0Q29uZmlnLmRhdGFwb2ludERldGFpbHMubWFwKGRldGFpbHMgPT5cbiAgICAgIHRoaXMuZmV0Y2hBbmRQcm9jZXNzTWVhc3VyZW1lbnRGaWxlKGRldGFpbHMsIG1lYXN1cmVtZW50RmlsZUNvbmZpZylcbiAgICApO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChmaWxlUHJvbWlzZXMpO1xuICB9XG5cbiAgYXN5bmMgZmV0Y2hBbmRQcm9jZXNzTWVhc3VyZW1lbnRGaWxlKFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgbWVhc3VyZW1lbnRGaWxlQ29uZmlnOiBNZWFzdXJlbWVudEZpbGVDb25maWdcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB0aGlzLnByZXBhcmVNZWFzdXJlbWVudHNGaWx0ZXIoXG4gICAgICBkZXRhaWxzLFxuICAgICAgbWVhc3VyZW1lbnRGaWxlQ29uZmlnLmV4cG9ydENvbmZpZ1xuICAgICk7XG4gICAgY29uc3QgaGVhZGVyID0geyBhY2NlcHQ6IG1lYXN1cmVtZW50RmlsZUNvbmZpZy5hY2NlcHRGaWxlVHlwZSB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG1lYXN1cmVtZW50RmlsZVJlc3BvbnNlOiBJRmV0Y2hSZXNwb25zZSA9XG4gICAgICAgIGF3YWl0IHRoaXMubWVhc3VyZW1lbnRTZXJ2aWNlLmdldE1lYXN1cmVtZW50c0ZpbGUoZmlsdGVyLCBoZWFkZXIpO1xuXG4gICAgICAvLyBJZiB0aGUgc3RhdHVzIGlzIDIwMCwgdGhlbiB0aGUgZmlsZSBpcyBpbiB0aGUgcmVzcG9uc2UuXG4gICAgICAvLyBJZiB0aGUgc3RhdHVzIGlzIDIwMiwgdGhlbiB0aGUgZmlsZSBpcyBiZWluZyBwcm9jZXNzZWQgYnkgdGhlIGJhY2tlbmQgYW5kIHdpbGwgYmUgc2VudCBieSBlbWFpbC5cbiAgICAgIGlmIChtZWFzdXJlbWVudEZpbGVSZXNwb25zZS5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXJnZU1lYXN1cmVtZW50c1dpdGhJdHNTb3VyY2VEZXRhaWxzKGRldGFpbHMsIG1lYXN1cmVtZW50RmlsZVJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbWVyZ2VNZWFzdXJlbWVudHNXaXRoSXRzU291cmNlRGV0YWlscyhcbiAgICBkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzLFxuICAgIG1lYXN1cmVtZW50RmlsZTogSUZldGNoUmVzcG9uc2VcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNvdXJjZTogZGV0YWlscy5zb3VyY2UsXG4gICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICB2YWx1ZUZyYWdtZW50VHlwZTogZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZSxcbiAgICAgIGZldGNoZWRNZWFzdXJlbWVudHNCbG9iRmlsZTogYXdhaXQgbWVhc3VyZW1lbnRGaWxlLmJsb2IoKVxuICAgIH07XG4gIH1cblxuICBhc3luYyBmZXRjaEFuZFByZXBhcmVEYXRhVG9FeHBvcnQoXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcsXG4gICAgaXNNZWFzdXJlbWVudDogYm9vbGVhblxuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFtdPiB7XG4gICAgcmV0dXJuIGlzTWVhc3VyZW1lbnRcbiAgICAgID8gYXdhaXQgdGhpcy5mZXRjaEFuZFByZXBhcmVNZWFzdXJlbWVudERhdGFUb0V4cG9ydEZvclByZXZpZXcoZXhwb3J0Q29uZmlnKVxuICAgICAgOiBhd2FpdCB0aGlzLmZldGNoQW5kUHJlcGFyZVNlcmllc0RhdGFUb0V4cG9ydChleHBvcnRDb25maWcpO1xuICB9XG5cbiAgYXN5bmMgZ2V0U291cmNlc1dpdGhQZXJtaXNzaW9uc1RvUmVhZChkYXRhcG9pbnREZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgZGF0ZUZyb20gPSBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IGRhdGVUbyA9IG5ldyBEYXRlKGRhdGVGcm9tKTtcblxuICAgIGNvbnN0IGZldGNoZWREYXRhUHJvbWlzZXMgPSBkYXRhcG9pbnREZXRhaWxzLm1hcChhc3luYyBkYXRhcG9pbnQgPT4ge1xuICAgICAgY29uc3QgcmF3RmlsdGVyOiBJU2VyaWVzRmlsdGVyID0ge1xuICAgICAgICBkYXRlRnJvbSxcbiAgICAgICAgZGF0ZVRvLFxuICAgICAgICBzb3VyY2U6IGRhdGFwb2ludC5zb3VyY2VcbiAgICAgIH07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgcmVzIH06IElSZXN1bHQ8SVNlcmllcz4gPSBhd2FpdCB0aGlzLmZldGNoU2VyaWVzRGF0YShyYXdGaWx0ZXIpO1xuICAgICAgICBpZiAocmVzPy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgIHJldHVybiBkYXRhcG9pbnQuc291cmNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gSWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBmZXRjaCwgcmV0dXJuIG51bGwgdG8gcHJldmVudCBwcm9taXNlIHJlamVjdGlvblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IGZldGNoZWRTb3VyY2VzID0gYXdhaXQgUHJvbWlzZS5hbGwoZmV0Y2hlZERhdGFQcm9taXNlcyk7XG4gICAgcmV0dXJuIGZldGNoZWRTb3VyY2VzLmZpbHRlcigoc291cmNlKTogc291cmNlIGlzIHN0cmluZyA9PiBzb3VyY2UgIT09IG51bGwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgYW5kIHByZXBhcmVzIG1lYXN1cmVtZW50IGRhdGEgZm9yIHByZXZpZXcuXG4gICAqXG4gICAqIEVtcHR5IERhdGFUb0V4cG9ydCBvYmplY3QgY2FuIGJlIHJldHVybmVkLCBiZWNhdXNlIHVubGlrZSBzZXJpZXMgZGF0YSxcbiAgICogbWVhc3VyZW1lbnQgZGF0YSBpcyBub3QgZnVydGhlciBwcm9jZXNzZWQgYmVzaWRlcyBzaG93aW5nIG9ubHkgaW4gdGhlIHByZXZpZXcuXG4gICAqIENTVi9FeGNlbCBmaWxlcyBhcmUgZ2VuZXJhdGVkIGJ5IHRoZSBiYWNrZW5kIGZvciBtZWFzdXJlbWVudHMuXG4gICAqXG4gICAqIEBwYXJhbSBleHBvcnRDb25maWcgLSBUaGUgZXhwb3J0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IG9mIERhdGFUb0V4cG9ydCBvYmplY3RzIG9yIG51bGwgd2hlbiBubyBkYXRhIGlzIGZldGNoZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZldGNoQW5kUHJlcGFyZU1lYXN1cmVtZW50RGF0YVRvRXhwb3J0Rm9yUHJldmlldyhcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZ1xuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFtdPiB8IG51bGwge1xuICAgIGNvbnN0IGRhdGFUb0V4cG9ydFByb21pc2VzOiBQcm9taXNlPERhdGFUb0V4cG9ydD5bXSA9IGV4cG9ydENvbmZpZy5kYXRhcG9pbnREZXRhaWxzLm1hcChcbiAgICAgIGFzeW5jIGRldGFpbHMgPT4ge1xuICAgICAgICBjb25zdCBmZXRjaGVkTWVhc3VyZW1lbnREYXRhOiBJUmVzdWx0TGlzdDxJTWVhc3VyZW1lbnQ+ID1cbiAgICAgICAgICBhd2FpdCB0aGlzLmZldGNoTWVhc3VyZW1lbnREYXRhRm9yUHJldmlldyhkZXRhaWxzLCBleHBvcnRDb25maWcpO1xuXG4gICAgICAgIGlmIChmZXRjaGVkTWVhc3VyZW1lbnREYXRhPy5kYXRhPy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzTWVhc3VyZW1lbnREYXRhRm9yUHJldmlldyhkZXRhaWxzLCBmZXRjaGVkTWVhc3VyZW1lbnREYXRhLmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICk7XG5cbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoZGF0YVRvRXhwb3J0UHJvbWlzZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaE1lYXN1cmVtZW50RGF0YUZvclByZXZpZXcoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZ1xuICApOiBQcm9taXNlPElSZXN1bHRMaXN0PElNZWFzdXJlbWVudD4+IHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgbWVhc3VyZW1lbnRzOiBJUmVzdWx0TGlzdDxJTWVhc3VyZW1lbnQ+IHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB0aGlzLnByZXBhcmVNZWFzdXJlbWVudHNGaWx0ZXIoXG4gICAgICBkZXRhaWxzLFxuICAgICAgZXhwb3J0Q29uZmlnLFxuICAgICAgTUVBU1VSRU1FTlRTX1BSRVZJRVdfSVRFTVNfTElNSVRcbiAgICApO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFRPRE86IGNvbnNpZGVyIGFkZGluZyBhIGNhY2hlIG1lY2hhbmlzbSAtPiBNVE0tNjAyODlcbiAgICAgIC8vIFdoZW4gdXNlciBzd2l0Y2hlcyBiZXR3ZWVuIHJlcG9ydCB0eXBlcywgYW5kIHJlc3Qgb2YgdGhlIHNldHRpbmdzIGFyZSB0aGUgc2FtZSwgdGhlbiB0aGUgZGF0YSBzaG91bGQgbm90IGJlIGZldGNoZWQgYWdhaW4/XG4gICAgICBtZWFzdXJlbWVudHMgPSBhd2FpdCB0aGlzLm1lYXN1cmVtZW50U2VydmljZS5saXN0KGZpbHRlcik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZFNlcnZlckZhaWx1cmUoZXJyb3IpO1xuICAgIH1cblxuICAgIHJldHVybiBtZWFzdXJlbWVudHM7XG4gIH1cblxuICBwcml2YXRlIHByZXBhcmVNZWFzdXJlbWVudHNGaWx0ZXIoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZyxcbiAgICBwYWdlU2l6ZT86IG51bWJlclxuICApOiBJTWVhc3VyZW1lbnRGaWx0ZXIge1xuICAgIGNvbnN0IGZpbHRlcjogSU1lYXN1cmVtZW50RmlsdGVyID0ge1xuICAgICAgLy8gUm91bmQgdGhlICdmcm9tJyB0aW1lIHRvIHRoZSBwcmV2aW91cyBmdWxsIG1pbnV0ZS5cbiAgICAgIGRhdGVGcm9tOiB0aGlzLmFkanVzdERhdGUoZXhwb3J0Q29uZmlnLmRhdGVGcm9tLCAtMSksXG4gICAgICAvLyBSb3VuZCB0aGUgJ3RvJyB0aW1lIHRvIHRoZSBuZWFyZXN0IGZ1bGwgbWludXRlLlxuICAgICAgZGF0ZVRvOiB0aGlzLmFkanVzdERhdGUoZXhwb3J0Q29uZmlnLmRhdGVUbywgMSksXG4gICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgdmFsdWVGcmFnbWVudFNlcmllczogZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzLFxuICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGVcbiAgICB9O1xuXG4gICAgaWYgKHBhZ2VTaXplKSB7XG4gICAgICBmaWx0ZXIucGFnZVNpemUgPSBwYWdlU2l6ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzTWVhc3VyZW1lbnREYXRhRm9yUHJldmlldyhcbiAgICBkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzLFxuICAgIGRhdGE6IElNZWFzdXJlbWVudFtdXG4gICk6IERhdGFUb0V4cG9ydCB7XG4gICAgY29uc3QgdW5pdCA9IGRhdGFbMF1bZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZV1bZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzXT8udW5pdCB8fCAnJztcblxuICAgIGNvbnN0IHZhbHVlczogeyBbdGltZXN0YW1wOiBzdHJpbmddOiBudW1iZXIgfSA9IHt9O1xuICAgIGRhdGEuZm9yRWFjaChtZWFzdXJlbWVudCA9PiB7XG4gICAgICB2YWx1ZXNbbWVhc3VyZW1lbnQudGltZV0gPVxuICAgICAgICBtZWFzdXJlbWVudFtkZXRhaWxzLnZhbHVlRnJhZ21lbnRUeXBlXVtkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXNdLnZhbHVlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgLi4uZGV0YWlscywgdW5pdCwgdGltZVZhbHVlTWFwOiB2YWx1ZXMgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hBbmRQcmVwYXJlU2VyaWVzRGF0YVRvRXhwb3J0KGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnKSB7XG4gICAgY29uc3QgZGF0YXBvaW50c1ZhbHVlc0RhdGFNYXA6IERhdGFwb2ludHNWYWx1ZXNEYXRhTWFwID0gdGhpcy5ncm91cFNlcmllc0J5RGV2aWNlSWQoXG4gICAgICBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlsc1xuICAgICk7XG5cbiAgICBjb25zdCBmZXRjaGVkRGF0YVByb21pc2VzID0gQXJyYXkuZnJvbShkYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCkubWFwKFxuICAgICAgYXN5bmMgKFtzb3VyY2UsIHNlcmllc10pID0+IHtcbiAgICAgICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvLCBhZ2dyZWdhdGlvbiB9ID0gZXhwb3J0Q29uZmlnO1xuXG4gICAgICAgIGNvbnN0IHJhd0ZpbHRlcjogSVNlcmllc0ZpbHRlciA9IHtcbiAgICAgICAgICBkYXRlRnJvbSxcbiAgICAgICAgICBkYXRlVG8sXG4gICAgICAgICAgc291cmNlLFxuICAgICAgICAgIHNlcmllcyxcbiAgICAgICAgICBhZ2dyZWdhdGlvblR5cGU6IGFnZ3JlZ2F0aW9uIGFzIGFnZ3JlZ2F0aW9uVHlwZVxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHsgZGF0YSB9OiBJUmVzdWx0PElTZXJpZXM+ID0gYXdhaXQgdGhpcy5mZXRjaFNlcmllc0RhdGEocmF3RmlsdGVyKTtcblxuICAgICAgICByZXR1cm4geyBzb3VyY2UsIGRhdGEgfTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgY29uc3QgZmV0Y2hlZERhdGFHcm91cGVkQnlTb3VyY2U6IFNvdXJjZUl0ZW1bXSA9IGF3YWl0IFByb21pc2UuYWxsKGZldGNoZWREYXRhUHJvbWlzZXMpO1xuXG4gICAgcmV0dXJuIHRoaXMucHJvY2Vzc1Nlcmllc0RhdGEoZXhwb3J0Q29uZmlnLmRhdGFwb2ludERldGFpbHMsIGZldGNoZWREYXRhR3JvdXBlZEJ5U291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbWFwIG9mIGFjdGl2ZSBkYXRhIHBvaW50cyBkZXZpY2UgSURzIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyBzZXJpZXMuXG4gICAqXG4gICAqIEV4YW1wbGUgb3V0cHV0OlxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIG5ldyBNYXAoW1xuICAgKiAgIFsnODQ0NjU3MjAyJywgWydjOHlfVGVtcGVyYXR1cmUuVCddXSxcbiAgICogICBbJzMyNjY2NDI3JywgWydjOHlfQmF0dGVyeS5CYXR0ZXJ5J11dXG4gICAqIF0pO1xuICAgKiBgYGBcbiAgICogQHBhcmFtIGRhdGFwb2ludERldGFpbHMgLSBBbiBhcnJheSBvZiBkYXRhIHBvaW50cyBkZXRhaWxzLlxuICAgKiBAcmV0dXJucyBBIG1hcCB3aGVyZSB0aGUga2V5IGlzIHRoZSBkYXRhIHBvaW50IElEIGFuZCB0aGUgdmFsdWUgaXMgYW4gYXJyYXkgb2YgZGF0YSBwb2ludCBzZXJpZXMuXG4gICAqL1xuICBwcml2YXRlIGdyb3VwU2VyaWVzQnlEZXZpY2VJZChkYXRhcG9pbnREZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzW10pOiBEYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCB7XG4gICAgcmV0dXJuIGRhdGFwb2ludERldGFpbHMucmVkdWNlKFxuICAgICAgKFxuICAgICAgICBtYXA6IERhdGFwb2ludHNWYWx1ZXNEYXRhTWFwLFxuICAgICAgICB7IHZhbHVlRnJhZ21lbnRUeXBlLCB2YWx1ZUZyYWdtZW50U2VyaWVzLCBzb3VyY2UgfTogRGF0YXBvaW50RGV0YWlsc1xuICAgICAgKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYCR7dmFsdWVGcmFnbWVudFR5cGV9LiR7dmFsdWVGcmFnbWVudFNlcmllc31gO1xuICAgICAgICBjb25zdCBleGlzdGluZ1ZhbHVlID0gbWFwLmdldChzb3VyY2UpID8/IFtdO1xuICAgICAgICBtYXAuc2V0KHNvdXJjZSwgWy4uLmV4aXN0aW5nVmFsdWUsIHZhbHVlXSk7XG4gICAgICAgIHJldHVybiBtYXA7XG4gICAgICB9LFxuICAgICAgbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hTZXJpZXNEYXRhKHJhd0ZpbHRlcjogSVNlcmllc0ZpbHRlcik6IFByb21pc2U8SVJlc3VsdDxJU2VyaWVzPj4gfCB1bmRlZmluZWQge1xuICAgIGxldCBzZXJpZXNEYXRhOiBJUmVzdWx0PElTZXJpZXM+IHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgZmlsdGVyOiBJU2VyaWVzRmlsdGVyID0gdGhpcy5wcmVwYXJlU2VyaWVzRmlsdGVyKHtcbiAgICAgIGRhdGVGcm9tOiByYXdGaWx0ZXIuZGF0ZUZyb20sXG4gICAgICBkYXRlVG86IHJhd0ZpbHRlci5kYXRlVG8sXG4gICAgICBzb3VyY2U6IHJhd0ZpbHRlci5zb3VyY2UsXG4gICAgICBzZXJpZXM6IHJhd0ZpbHRlci5zZXJpZXMsXG4gICAgICBhZ2dyZWdhdGlvblR5cGU6IHJhd0ZpbHRlci5hZ2dyZWdhdGlvblR5cGVcbiAgICB9KTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBUT0RPOiBjb25zaWRlciBhZGRpbmcgYSBjYWNoZSBtZWNoYW5pc20gLT4gTVRNLTYwMjg5XG4gICAgICAvLyBXaGVuIHVzZXIgc3dpdGNoZXMgYmV0d2VlbiByZXBvcnQgdHlwZXMsIGFuZCByZXN0IG9mIHRoZSBzZXR0aW5ncyBhcmUgdGhlIHNhbWUsIHRoZW4gdGhlIGRhdGEgc2hvdWxkIG5vdCBiZSBmZXRjaGVkIGFnYWluP1xuICAgICAgc2VyaWVzRGF0YSA9IGF3YWl0IHRoaXMubWVhc3VyZW1lbnRTZXJ2aWNlLmxpc3RTZXJpZXMoZmlsdGVyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShlcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlcmllc0RhdGE7XG4gIH1cblxuICBwcml2YXRlIHByZXBhcmVTZXJpZXNGaWx0ZXIoZmlsdGVyczogSVNlcmllc0ZpbHRlcik6IElTZXJpZXNGaWx0ZXIge1xuICAgIGNvbnN0IHsgZGF0ZUZyb20sIGRhdGVUbywgc291cmNlLCBzZXJpZXMsIGFnZ3JlZ2F0aW9uVHlwZSB9ID0gZmlsdGVycztcbiAgICAvLyBSb3VuZCB0aGUgJ2Zyb20nIHRpbWUgdG8gdGhlIHByZXZpb3VzIGZ1bGwgbWludXRlLlxuICAgIGNvbnN0IGZyb20gPSB0aGlzLmFkanVzdERhdGUoZGF0ZUZyb20sIC0xKTtcbiAgICAvLyBSb3VuZCB0aGUgJ3RvJyB0aW1lIHRvIHRoZSBuZWFyZXN0IGZ1bGwgbWludXRlLlxuICAgIGNvbnN0IHRvID0gdGhpcy5hZGp1c3REYXRlKGRhdGVUbywgMSk7XG5cbiAgICBjb25zdCBmaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB7XG4gICAgICBkYXRlRnJvbTogZnJvbSxcbiAgICAgIGRhdGVUbzogdG8sXG4gICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgIHJldmVydDogdHJ1ZVxuICAgIH07XG5cbiAgICAvLyBUaGUgJ05PTkUnIGFnZ3JlZ2F0aW9uIHR5cGUgaXMgbm90IGhhbmRsZWQgYnkgYSBiYWNrZW5kLCBzbyBldmVuIHdoZW4gaXMgc2VsZWN0ZWQsIGl0IGlzIG5vdCBwYXNzZWQgYXMgYSBmaWx0ZXIgcGFyYW1ldGVyLlxuICAgIGlmIChhZ2dyZWdhdGlvblR5cGUgJiYgYWdncmVnYXRpb25UeXBlICE9PSAoQUdHUkVHQVRJT05fVkFMVUVTLm5vbmUgYXMgYWdncmVnYXRpb25UeXBlKSkge1xuICAgICAgZmlsdGVyLmFnZ3JlZ2F0aW9uVHlwZSA9IGFnZ3JlZ2F0aW9uVHlwZTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBpdCBpcyBhIHRlbXBvcmFsIHdvcmthcm91bmQgZm9yIGEgYnVnIGluIHRoZSBiYWNrZW5kLFxuICAgIC8vIHdoZXJlIHRoZSBzZXJpZXMgd2l0aCBtb3JlIHRoYW4gb25lIGRvdCBhcmUgaW1wb3NzaWJsZSB0byByZXRyaWV2ZTpcbiAgICAvLyBodHRwczovL2N1bXVsb2NpdHkuYXRsYXNzaWFuLm5ldC9icm93c2UvTVRNLTU5Mjc3XG4gICAgaWYgKHNlcmllcykge1xuICAgICAgY29uc3QgaGFzTW9yZVRoYW5PbmVEb3QgPSAoc2VyaWVzIGFzIHN0cmluZ1tdKS5zb21lKHMgPT4gcy5zcGxpdCgnLicpLmxlbmd0aCA+IDIpO1xuICAgICAgaWYgKCFoYXNNb3JlVGhhbk9uZURvdCkge1xuICAgICAgICBmaWx0ZXIuc2VyaWVzID0gc2VyaWVzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXI7XG4gIH1cblxuICAvKipcbiAgICogUHJvY2Vzc2VzIHRoZSBmZXRjaGVkIHNlcmllcyBkYXRhIGFuZCBwcmVwYXJlcyBpdCBmb3IgZXhwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YXBvaW50RGV0YWlscyAtIEFuIGFycmF5IG9mIGRhdGEgcG9pbnQgZGV0YWlscy5cbiAgICogQHBhcmFtIGZldGNoZWREYXRhTWFwIC0gQSBtYXAgb2YgZmV0Y2hlZCBzZXJpZXMgZGF0YSBncm91cGVkIGJ5IHNvdXJjZS5cbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgRGF0YVRvRXhwb3J0IG9iamVjdHMuXG4gICAqL1xuICBwcml2YXRlIHByb2Nlc3NTZXJpZXNEYXRhKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSwgZmV0Y2hlZERhdGFNYXA6IFNvdXJjZUl0ZW1bXSkge1xuICAgIGNvbnN0IHZhbHVlc0dyb3VwZWRCeVNvdXJjZSA9IHRoaXMudXRpbHNTZXJ2aWNlLnRyYW5zZm9ybURhdGFTdHJ1Y3R1cmUoZmV0Y2hlZERhdGFNYXApO1xuXG4gICAgcmV0dXJuIGRhdGFwb2ludERldGFpbHMubWFwKChkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzKSA9PiB7XG4gICAgICBsZXQgdW5pdDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgbGV0IGRhdGE6IFRpbWVTZXJpZXNEYXRhO1xuXG4gICAgICAvKipcbiAgICAgICAqIFVuaXF1ZSBrZXkgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBkaWZmZXJlbnQgc2VyaWVzIGZyb20gc2FtZSBzb3VyY2UsXG4gICAgICAgKiBlLmcuOiBjOHlfQWNjZWxlcmF0aW9uLmFjY2VsZXJhdGlvblgsIGM4eV9BY2NlbGVyYXRpb24uYWNjZWxlcmF0aW9uWSwgYzh5X0FjY2VsZXJhdGlvbi5hY2NlbGVyYXRpb25aXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHNlcmllc0tleSA9IGAke2RldGFpbHMudmFsdWVGcmFnbWVudFR5cGV9LiR7ZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzfWA7XG5cbiAgICAgIGlmICh2YWx1ZXNHcm91cGVkQnlTb3VyY2VbZGV0YWlscy5zb3VyY2VdW3Nlcmllc0tleV0pIHtcbiAgICAgICAgdW5pdCA9IHZhbHVlc0dyb3VwZWRCeVNvdXJjZVtkZXRhaWxzLnNvdXJjZV1bc2VyaWVzS2V5XS5zZXJpZXNEZXRhaWxzLnVuaXQ7XG4gICAgICAgIGRhdGEgPSB2YWx1ZXNHcm91cGVkQnlTb3VyY2VbZGV0YWlscy5zb3VyY2VdW3Nlcmllc0tleV0udmFsdWVzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5kZXRhaWxzLFxuICAgICAgICB1bml0LFxuICAgICAgICB0aW1lVmFsdWVNYXA6IGRhdGFcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRqdXN0cyB0aGUgZ2l2ZW4gZGF0ZSBieSBhZGRpbmcgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgbWludXRlcyBhbmQgc2V0dGluZyBzZWNvbmRzIHRvIDAuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRlIC0gVGhlIGRhdGUgdG8gYmUgYWRqdXN0ZWQgaW4gc3RyaW5nIGZvcm1hdC5cbiAgICogQHBhcmFtIG1pbnV0ZXMgLSBUaGUgbnVtYmVyIG9mIG1pbnV0ZXMgdG8gYWRkIHRvIHRoZSBkYXRlLlxuICAgKiBAcmV0dXJucyBUaGUgYWRqdXN0ZWQgZGF0ZSBpbiB0aGUgZm9ybWF0ICdZWVlZLU1NLUREVEhIOm1tOnNzK0hIOk1NJy5cbiAgICovXG4gIHByaXZhdGUgYWRqdXN0RGF0ZShkYXRlOiBzdHJpbmcgfCBEYXRlLCBtaW51dGVzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRhdGVUaW1lID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgZGF0ZVRpbWUuc2V0TWludXRlcyhkYXRlVGltZS5nZXRNaW51dGVzKCkgKyBtaW51dGVzKTtcbiAgICBkYXRlVGltZS5zZXRTZWNvbmRzKDApO1xuXG4gICAgY29uc3Qgb2Zmc2V0ID0gLWRhdGVUaW1lLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgY29uc3Qgb2Zmc2V0U2lnbiA9IG9mZnNldCA+PSAwID8gJysnIDogJy0nO1xuICAgIGNvbnN0IHBhZCA9IChudW06IG51bWJlcik6IHN0cmluZyA9PiAobnVtIDwgMTAgPyAnMCcgKyBudW0gOiBudW0udG9TdHJpbmcoKSk7XG4gICAgY29uc3Qgb2Zmc2V0SG91cnMgPSBwYWQoTWF0aC5mbG9vcihNYXRoLmFicyhvZmZzZXQpIC8gNjApKTtcbiAgICBjb25zdCBvZmZzZXRNaW51dGVzID0gcGFkKE1hdGguYWJzKG9mZnNldCkgJSA2MCk7XG5cbiAgICBjb25zdCB5ZWFyID0gZGF0ZVRpbWUuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtb250aCA9IHBhZChkYXRlVGltZS5nZXRNb250aCgpICsgMSk7XG4gICAgY29uc3QgZGF5ID0gcGFkKGRhdGVUaW1lLmdldERhdGUoKSk7XG4gICAgY29uc3QgaG91cnMgPSBwYWQoZGF0ZVRpbWUuZ2V0SG91cnMoKSk7XG4gICAgY29uc3QgbWludXRlc1N0cmluZyA9IHBhZChkYXRlVGltZS5nZXRNaW51dGVzKCkpO1xuICAgIGNvbnN0IHNlY29uZHMgPSAnMDAnO1xuXG4gICAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9LSR7ZGF5fVQke2hvdXJzfToke21pbnV0ZXNTdHJpbmd9OiR7c2Vjb25kc30ke29mZnNldFNpZ259JHtvZmZzZXRIb3Vyc306JHtvZmZzZXRNaW51dGVzfWA7XG4gIH1cblxuICAvKipcbiAgICogVHJpbXMgdGhlIGdpdmVuIEhUTUwgbWVzc2FnZSBieSByZW1vdmluZyBsaXN0IGl0ZW1zIHRoYXQgY29ycmVzcG9uZCB0byB6ZXJvIGNvdW50cy5cbiAgICpcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgSFRNTCBzdHJpbmcgY29udGFpbmluZyB0aGUgbWVzc2FnZSB3aXRoIGxpc3QgaXRlbXMuXG4gICAqIEBwYXJhbSBjb3VudHMgLSBBbiBhcnJheSBvZiBudW1iZXIgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gZWFjaCBsaXN0IGl0ZW0uXG4gICAqIEBwYXJhbSBjb3VudFRvVHJpbSAtIEEgY291bnQgdGhhdCB3aWxsIGJlIHRyaW1tZWQgd2l0aCBjb3JyZXNwb25kaW5nIGxpc3QgaXRlbS5cbiAgICogQHJldHVybnMgQSB0cmltbWVkIEhUTUwgc3RyaW5nIHdpdGggbGlzdCBpdGVtcyByZW1vdmVkIHdoZXJlIHRoZSBjb3JyZXNwb25kaW5nIGNvdW50IGlzIHplcm8uXG4gICAqXG4gICAqIEV4YW1wbGU6XG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgbWVzc2FnZSA9ICc8dWw+PGxpPkl0ZW0gMTwvbGk+PGxpPkl0ZW0gMjwvbGk+PGxpPkl0ZW0gMzwvbGk+PC91bD4nO1xuICAgKiBjb25zdCBjb3VudHMgPSBbMSwgMCwgMl07XG4gICAqIGNvbnN0IHRyaW1tZWRNZXNzYWdlID0gdGhpcy5yZW1vdmVaZXJvQ291bnRMaXN0SXRlbXMobWVzc2FnZSwgY291bnRzKTtcbiAgICogLy8gUmVzdWx0OiAnPHVsPjxsaT5JdGVtIDE8L2xpPjxsaT5JdGVtIDM8L2xpPjwvdWw+J1xuICAgKiBgYGBcbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlWmVyb0NvdW50TGlzdEl0ZW1zKG1lc3NhZ2U6IHN0cmluZywgY291bnRzOiBudW1iZXJbXSwgY291bnRUb1RyaW0gPSAwKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCk7XG4gICAgY29uc3QgZG9jID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLCAndGV4dC9odG1sJyk7XG4gICAgY29uc3QgbGlzdEl0ZW1zID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoJ3VsIGxpJyk7XG5cbiAgICBsaXN0SXRlbXMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChjb3VudHNbaW5kZXhdID09PSBjb3VudFRvVHJpbSkge1xuICAgICAgICBpdGVtLnJlbW92ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRvYy5ib2R5LmlubmVySFRNTDtcbiAgfVxufVxuIl19
408
+ }], ctorParameters: () => [{ type: i1.AlertService }, { type: i2.MeasurementService }, { type: i3.TranslateService }, { type: i4.UtilsService }] });
409
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mZXRjaGluZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3IvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItbW9kYWwvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItZmlsZS1leHBvcnRlci9kYXRhLWZldGNoaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBU0wsa0JBQWtCLEVBQ25CLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQVFMLGdDQUFnQyxFQUVqQyxNQUFNLHdDQUF3QyxDQUFDO0FBQ2hELE9BQU8sRUFBYyxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7O0FBSzNELE1BQU0sT0FBTyxtQkFBbUI7SUFDOUIsWUFDVSxZQUEwQixFQUMxQixrQkFBc0MsRUFDdEMsZ0JBQWtDLEVBQ2xDLFlBQTBCO1FBSDFCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztJQUNqQyxDQUFDO0lBRUo7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsMkJBQTJCLENBQy9CLFlBQTBCO1FBRTFCLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDO1FBRXRDLE1BQU0sUUFBUSxHQUF3QyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUNyRixLQUFLLEVBQUMsT0FBTyxFQUFDLEVBQUU7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VSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgYWdncmVnYXRpb25UeXBlLFxuICBJRmV0Y2hSZXNwb25zZSxcbiAgSU1lYXN1cmVtZW50LFxuICBJTWVhc3VyZW1lbnRGaWx0ZXIsXG4gIElSZXN1bHQsXG4gIElSZXN1bHRMaXN0LFxuICBJU2VyaWVzLFxuICBJU2VyaWVzRmlsdGVyLFxuICBNZWFzdXJlbWVudFNlcnZpY2Vcbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQUdHUkVHQVRJT05fVkFMVUVTLCBBbGVydFNlcnZpY2UsIGdldHRleHQgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7XG4gIERhdGFwb2ludERldGFpbHMsXG4gIERhdGFwb2ludHNFeGNlZWRpbmdMaW1pdCxcbiAgRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAsXG4gIERhdGFUb0V4cG9ydCxcbiAgRGF0YVRvRXhwb3J0V2l0aEJhY2tlbmRDcmVhdGVkRmlsZSxcbiAgRXhwb3J0Q29uZmlnLFxuICBNZWFzdXJlbWVudEZpbGVDb25maWcsXG4gIE1FQVNVUkVNRU5UU19QUkVWSUVXX0lURU1TX0xJTUlULFxuICBUaW1lU2VyaWVzRGF0YVxufSBmcm9tICcuLi8uLi9kYXRhcG9pbnRzLWV4cG9ydC1zZWxlY3Rvci5tb2RlbCc7XG5pbXBvcnQgeyBTb3VyY2VJdGVtLCBVdGlsc1NlcnZpY2UgfSBmcm9tICcuL3V0aWxzLnNlcnZpY2UnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBEYXRhRmV0Y2hpbmdTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhbGVydFNlcnZpY2U6IEFsZXJ0U2VydmljZSxcbiAgICBwcml2YXRlIG1lYXN1cmVtZW50U2VydmljZTogTWVhc3VyZW1lbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcml2YXRlIHV0aWxzU2VydmljZTogVXRpbHNTZXJ2aWNlXG4gICkge31cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGFueSBvZiBtZWFzdXJlbWVudHMgcmVxdWVzdHMgbWF5IGV4Y2VlZGVkIHRoZSBsaW1pdCxcbiAgICogYWZ0ZXIgd2hpY2ggdGhlIGV4cG9ydCBkYXRhIGlzIHByb2Nlc3NlZCBieSB0aGUgYmFja2VuZCBhbmQgdGhlIGdlbmVyYXRlZCBDU1YvRXhjZWwgZmlsZSBpcyBzZW50IGJ5IGVtYWlsLlxuICAgKlxuICAgKiBUaGUgdGhyZXNob2xkIGlzIHNldCB0byA1MF8wMDAgcmVjb3JkcyBpbiBhcHBsaWNhdGlvbidzIGNvcmUgcHJvcGVydGllcyAoZXhwb3J0LmRhdGEuc3luY2hyb25vdXMubGltaXQpLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwb3J0Q29uZmlnIC0gVGhlIGV4cG9ydCBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXR1cm5zIGFuIGFycmF5IG9mIG9iamVjdHMgcmVwcmVzZW50aW5nIGRhdGFwb2ludHMgZmlsZXMgdGhhdCB3aWxsIGJlIHNlbnQgYnkgZW1haWwuXG4gICAqL1xuICBhc3luYyBnZXREYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQoXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWdcbiAgKTogUHJvbWlzZTxEYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRbXT4ge1xuICAgIGNvbnN0IGJhY2tlbmRQcm9jZXNzaW5nTGltaXQgPSA1MF8wMDA7XG5cbiAgICBjb25zdCBwcm9taXNlczogUHJvbWlzZTxEYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQ+W10gPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoXG4gICAgICBhc3luYyBkZXRhaWxzID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHtcbiAgICAgICAgICAgIGRhdGVGcm9tOiBleHBvcnRDb25maWcuZGF0ZUZyb20sXG4gICAgICAgICAgICBkYXRlVG86IGV4cG9ydENvbmZpZy5kYXRlVG8sXG4gICAgICAgICAgICBwYWdlU2l6ZTogMSxcbiAgICAgICAgICAgIHNvdXJjZTogZGV0YWlscy5zb3VyY2UsXG4gICAgICAgICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICAgICAgICB2YWx1ZUZyYWdtZW50VHlwZTogZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZSxcbiAgICAgICAgICAgIHdpdGhUb3RhbEVsZW1lbnRzOiB0cnVlXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdChmaWx0ZXIpO1xuXG4gICAgICAgICAgaWYgKHJlc3BvbnNlPy5wYWdpbmc/LnRvdGFsRWxlbWVudHMgPiBiYWNrZW5kUHJvY2Vzc2luZ0xpbWl0KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBkYXRhcG9pbnREZXRhaWw6IHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgICAgICAgICAgIHZhbHVlRnJhZ21lbnRTZXJpZXM6IGRldGFpbHMudmFsdWVGcmFnbWVudFNlcmllcyxcbiAgICAgICAgICAgICAgICB2YWx1ZUZyYWdtZW50VHlwZTogZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0b3RhbEVsZW1lbnRzOiByZXNwb25zZS5wYWdpbmcudG90YWxFbGVtZW50c1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZFNlcnZlckZhaWx1cmUoZXJyb3IpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdHM6IERhdGFwb2ludHNFeGNlZWRpbmdMaW1pdFtdID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXG4gICAgY29uc3QgZGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0ID0gcmVzdWx0cy5maWx0ZXIocmVzdWx0ID0+IHJlc3VsdCAhPT0gbnVsbCk7XG5cbiAgICByZXR1cm4gZGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgd2hlbiB0aGUgbGltaXQgb2YgZGF0YXBvaW50cyBpcyBleGNlZWRlZCBkdXJpbmcgZmlsZSBleHBvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBoYXNOb0V4cG9ydGFibGVEYXRhIC0gSW5kaWNhdGVzIGlmIHRoZXJlIGlzIG5vIGV4cG9ydGFibGUgZGF0YSBiZWNhdXNlIHRoZSBkYXRlIHJhbmdlIG9mIGFsbCBzZWxlY3RlZCBkYXRhcG9pbnRzIGV4Y2VlZHMgMSwwMDAsMDAwIHJlY29yZHMuXG4gICAqIEBwYXJhbSBlbWFpbERlbGl2ZXJhYmxlQ291bnQgLSBUaGUgbnVtYmVyIG9mIGRhdGFwb2ludCBleHBvcnRzIHRoYXQgZXhjZWVkIHRoZSBsaW1pdCwgd2lsbCBiZSBwcm9jZWVkZWQgYnkgdGhlIGJhY2tlbmQgYW5kIHNlbnQgYnkgZW1haWwuXG4gICAqIEBwYXJhbSBicm93c2VyRG93bmxvYWRhYmxlQ291bnQgLSBUaGUgbnVtYmVyIG9mIGRhdGFwb2ludCBleHBvcnRzIHRoYXQgY2FuIGJlIGRvd25sb2FkZWQgZGlyZWN0bHkuXG4gICAqIEBwYXJhbSBza2lwcGVkRGF0YXBvaW50Q291bnQgLSBUaGUgbnVtYmVyIG9mIGRhdGFwb2ludCBleHBvcnRzIHNraXBwZWQgZHVlIHRvIGV4Y2VlZGluZyB0aGUgbWVhc3VyZW1lbnRzIEFQSSBsaW1pdCBvZiAxLDAwMCwwMDAgcmVjb3Jkcy5cbiAgICogQHBhcmFtIHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQgLSBUb3RhbCBudW1iZXIgb2YgZGF0YXBvaW50IHNlbGVjdGVkIGZvciBleHBvcnRzLlxuICAgKiBAcmV0dXJucyBUaGUgbWVzc2FnZSB0aGF0IGNhbiBiZSBpbmplY3RlZC5cbiAgICovXG4gIGdldExpbWl0RXhjZWVkZWRNZXNzYWdlKFxuICAgIGhhc05vRXhwb3J0YWJsZURhdGE6IGJvb2xlYW4sXG4gICAgZW1haWxEZWxpdmVyYWJsZUNvdW50PzogbnVtYmVyLFxuICAgIGJyb3dzZXJEb3dubG9hZGFibGVDb3VudD86IG51bWJlcixcbiAgICBub25SZXRyaWV2YWJsZUNvdW50PzogbnVtYmVyLFxuICAgIHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQ/OiBudW1iZXJcbiAgKTogc3RyaW5nIHtcbiAgICBpZiAoaGFzTm9FeHBvcnRhYmxlRGF0YSkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgICBnZXR0ZXh0KFxuICAgICAgICAgIGBUaGUgZGF0YSBmb3Igc2VsZWN0ZWQgZGF0YXBvaW50KHMpIGV4Y2VlZCAxLDAwMCwwMDAgcmVjb3Jkcywgd2hpY2ggaXMgdGhlIGxpbWl0IGZvciBiYWNrZW5kIHByb2Nlc3NpbmcuIFRvIGV4cG9ydCB0aGlzIGRhdGEsIHBsZWFzZSByZWR1Y2UgdGhlIGRhdGUgcmFuZ2UuYFxuICAgICAgICApXG4gICAgICApO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuXG4gICAgY29uc3QgbWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgZ2V0dGV4dChcbiAgICAgICAgYEFmdGVyIGNsaWNraW5nIFwiRG93bmxvYWRcIjo8YnI+XG4gICAgICAgIDx1bD5cbiAgICAgICAgICA8bGk+PHN0cm9uZz57eyRicm93c2VyRG93bmxvYWRhYmxlQ291bnR9fTwvc3Ryb25nPiBkYXRhcG9pbnQocykgZXhwb3J0cyB3aWxsIGJlIGRvd25sb2FkZWQgZGlyZWN0bHkgd2l0aGluIG9uZSBmaWxlOiA8ZW0+ZXhwb3J0ZWRfW2Nzdi9leGNlbF0uemlwPC9lbT48L2xpPlxuICAgICAgICAgIDxsaT48c3Ryb25nPnt7JGVtYWlsRGVsaXZlcmFibGVDb3VudH19PC9zdHJvbmc+IGRhdGFwb2ludChzKSBleHBvcnRzIHJlcXVpcmUgZnVydGhlciBwcm9jZXNzaW5nLiBUaGUgZmlsZXMgd2lsbCBiZSBzZW50IHRvIHlvdSB2aWEgc2VwYXJhdGUgZW1haWxzIG9uY2UgY29tcGxldGVkLCB3aGljaCBtYXkgdGFrZSBzb21lIHRpbWUuPC9saT5cbiAgICAgICAgICA8bGk+PHN0cm9uZz57eyRub25SZXRyaWV2YWJsZUNvdW50fX08L3N0cm9uZz4gZGF0YXBvaW50KHMpIGV4cG9ydHMgZXhjZWVkZWQgMSwwMDAsMDAwIHJlY29yZHMsIHdoaWNoIGlzIHRoZSBsaW1pdCBmb3IgYmFja2VuZCBwcm9jZXNzaW5nLiBUbyBleHBvcnQgdGhlc2UgZGF0YSwgcGxlYXNlIHJlZHVjZSB0aGUgZGF0ZSByYW5nZS4gT3RoZXJ3aXNlLCB0aGUgZGF0YSB3aWxsIG5laXRoZXIgYmUgZG93bmxvYWRlZCBub3Igc2VudCB2aWEgZW1haWwuPC9saT5cbiAgICAgICAgPC91bD5cbiAgICAgICAgPHA+VGhlIHRvdGFsIG51bWJlciBvZiBkYXRhIHBvaW50cyB0aGF0IGNhbiBiZSBleHBvcnRlZCBpczogPHN0cm9uZz57eyR0b3RhbEV4cG9ydGFibGVEYXRhcG9pbnRzQ291bnR9fSBvdXQgb2Yge3skdG90YWxEYXRhcG9pbnRzU2VsZWN0ZWRGb3JFeHBvcnRDb3VudH19PC9zdHJvbmc+LjwvcD5cbiAgICAgICAgPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZmlsZSBuYW1lIGNvbnZlbnRpb24gb2YgZmlsZXMgd2l0aGluIHppcCBmaWxlIGlzOiA8Y29kZT5bc291cmNlXV9bZnJhZ21lbnRfc2VyaWVzXS5bY3N2L3hsc108L2NvZGU+PC9wPmBcbiAgICAgICksXG4gICAgICB7XG4gICAgICAgICRicm93c2VyRG93bmxvYWRhYmxlQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgICAgJGVtYWlsRGVsaXZlcmFibGVDb3VudDogZW1haWxEZWxpdmVyYWJsZUNvdW50LFxuICAgICAgICAkbm9uUmV0cmlldmFibGVDb3VudDogbm9uUmV0cmlldmFibGVDb3VudCxcbiAgICAgICAgJHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQ6IHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQsXG4gICAgICAgICR0b3RhbEV4cG9ydGFibGVEYXRhcG9pbnRzQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCArIGVtYWlsRGVsaXZlcmFibGVDb3VudFxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCB0cmltbWVkTWVzc2FnZSA9IHRoaXMucmVtb3ZlWmVyb0NvdW50TGlzdEl0ZW1zKG1lc3NhZ2UsIFtcbiAgICAgIGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgIGVtYWlsRGVsaXZlcmFibGVDb3VudCxcbiAgICAgIG5vblJldHJpZXZhYmxlQ291bnRcbiAgICBdKTtcblxuICAgIHJldHVybiB0cmltbWVkTWVzc2FnZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmltcyB0aGUgZ2l2ZW4gSFRNTCBtZXNzYWdlIGJ5IHJlbW92aW5nIGxpc3QgaXRlbXMgdGhhdCBjb3JyZXNwb25kIHRvIHplcm8gY291bnRzLlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBIVE1MIHN0cmluZyBjb250YWluaW5nIHRoZSBtZXNzYWdlIHdpdGggbGlzdCBpdGVtcy5cbiAgICogQHBhcmFtIGNvdW50cyAtIEFuIGFycmF5IG9mIG51bWJlciB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byBlYWNoIGxpc3QgaXRlbS5cbiAgICogQHBhcmFtIGNvdW50VG9UcmltIC0gQSBjb3VudCB0aGF0IHdpbGwgYmUgdHJpbW1lZCB3aXRoIGNvcnJlc3BvbmRpbmcgbGlzdCBpdGVtLlxuICAgKiBAcmV0dXJucyBBIHRyaW1tZWQgSFRNTCBzdHJpbmcgd2l0aCBsaXN0IGl0ZW1zIHJlbW92ZWQgd2hlcmUgdGhlIGNvcnJlc3BvbmRpbmcgY291bnQgaXMgemVyby5cbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBtZXNzYWdlID0gJzx1bD48bGk+SXRlbSAxPC9saT48bGk+SXRlbSAyPC9saT48bGk+SXRlbSAzPC9saT48L3VsPic7XG4gICAqIGNvbnN0IGNvdW50cyA9IFsxLCAwLCAyXTtcbiAgICogY29uc3QgdHJpbW1lZE1lc3NhZ2UgPSB0aGlzLnJlbW92ZVplcm9Db3VudExpc3RJdGVtcyhtZXNzYWdlLCBjb3VudHMpO1xuICAgKiAvLyBSZXN1bHQ6ICc8dWw+PGxpPkl0ZW0gMTwvbGk+PGxpPkl0ZW0gMzwvbGk+PC91bD4nXG4gICAqIGBgYFxuICAgKi9cbiAgcmVtb3ZlWmVyb0NvdW50TGlzdEl0ZW1zKG1lc3NhZ2U6IHN0cmluZywgY291bnRzOiBudW1iZXJbXSwgY291bnRUb1RyaW0gPSAwKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCk7XG4gICAgY29uc3QgZG9jID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLCAndGV4dC9odG1sJyk7XG4gICAgY29uc3QgbGlzdEl0ZW1zID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoJ3VsIGxpJyk7XG5cbiAgICBsaXN0SXRlbXMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChjb3VudHNbaW5kZXhdID09PSBjb3VudFRvVHJpbSkge1xuICAgICAgICBpdGVtLnJlbW92ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRvYy5ib2R5LmlubmVySFRNTDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwbGF5cyBhbiBpbmZvcm1hdGlvbiBhbGVydCBhYm91dCBzZW5kaW5nIGRhdGEgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBPbmx5IG1lYXN1cmVtZW50cyBBUEkgY2FuIHNlbmQgZmlsZXMgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZVR5cGUgLSBUaGUgdHlwZSBvZiBmaWxlIHRvIGJlIHNlbnQuXG4gICAqIEBwYXJhbSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQgLSBUaGUgYXJyYXkgb2YgZGF0YXBvaW50cyBleGNlZWRpbmcgdGhlIGxpbWl0LlxuICAgKi9cbiAgc2hvd1NlbmRWaWFFbWFpbEluZm9BbGVydChcbiAgICBmaWxlVHlwZTogc3RyaW5nLFxuICAgIGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdDogRGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0W11cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZVRlbXBsYXRlID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICBnZXR0ZXh0KGBZb3Ugd2lsbCBnZXQge3skZmlsZVR5cGVUZXh0fX0gZmlsZShzKSBmb3Ige3skY291bnR9fSBzZXJpZXMgdmlhIGVtYWlsLmApLFxuICAgICAgeyAkY291bnQ6IGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdC5sZW5ndGgsICRmaWxlVHlwZVRleHQ6IGZpbGVUeXBlIH1cbiAgICApO1xuICAgIGNvbnN0IGZvcm1hdHRlZExpc3QgPSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRcbiAgICAgIC5tYXAoXG4gICAgICAgIGRhdGFwb2ludCA9PlxuICAgICAgICAgIGDigKIgJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnNvdXJjZX1fJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnZhbHVlRnJhZ21lbnRUeXBlfV8ke2RhdGFwb2ludC5kYXRhcG9pbnREZXRhaWwudmFsdWVGcmFnbWVudFNlcmllc31gXG4gICAgICApXG4gICAgICAuam9pbignXFxuJyk7XG5cbiAgICB0aGlzLmFsZXJ0U2VydmljZS5pbmZvKG1lc3NhZ2VUZW1wbGF0ZSwgZm9ybWF0dGVkTGlzdCk7XG4gIH1cblxuICBhc3luYyBmZXRjaE1lYXN1cmVtZW50RGF0YUZpbGVzQW5kUGFpcldpdGhTb3VyY2VEZXRhaWxzKFxuICAgIGFjY2VwdEZpbGVUeXBlOiBzdHJpbmcsXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWdcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlW10+IHtcbiAgICBjb25zdCBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZyA9IHtcbiAgICAgIGV4cG9ydENvbmZpZyxcbiAgICAgIGFjY2VwdEZpbGVUeXBlXG4gICAgfTtcbiAgICBjb25zdCBmaWxlUHJvbWlzZXMgPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoZGV0YWlscyA9PlxuICAgICAgdGhpcy5mZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlQ29uZmlnKVxuICAgICk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGZpbGVQcm9taXNlcyk7XG4gIH1cblxuICBhc3luYyBmZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZyxcbiAgICByb3VuZFNlY29uZHMgPSBmYWxzZVxuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGUgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHRoaXMucHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICAgIGRldGFpbHMsXG4gICAgICBtZWFzdXJlbWVudEZpbGVDb25maWcuZXhwb3J0Q29uZmlnLFxuICAgICAgcm91bmRTZWNvbmRzXG4gICAgKTtcbiAgICBjb25zdCBoZWFkZXIgPSB7IGFjY2VwdDogbWVhc3VyZW1lbnRGaWxlQ29uZmlnLmFjY2VwdEZpbGVUeXBlIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2U6IElGZXRjaFJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UuZ2V0TWVhc3VyZW1lbnRzRmlsZShmaWx0ZXIsIGhlYWRlcik7XG5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAwLCB0aGVuIHRoZSBmaWxlIGlzIGluIHRoZSByZXNwb25zZS5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAyLCB0aGVuIHRoZSBmaWxlIGlzIGJlaW5nIHByb2Nlc3NlZCBieSB0aGUgYmFja2VuZCBhbmQgd2lsbCBiZSBzZW50IGJ5IGVtYWlsLlxuICAgICAgaWYgKG1lYXN1cmVtZW50RmlsZVJlc3BvbnNlLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lcmdlTWVhc3VyZW1lbnRzV2l0aEl0c1NvdXJjZURldGFpbHMoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBtZXJnZU1lYXN1cmVtZW50c1dpdGhJdHNTb3VyY2VEZXRhaWxzKFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgbWVhc3VyZW1lbnRGaWxlOiBJRmV0Y2hSZXNwb25zZVxuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGU+IHtcbiAgICByZXR1cm4ge1xuICAgICAgc291cmNlOiBkZXRhaWxzLnNvdXJjZSxcbiAgICAgIHZhbHVlRnJhZ21lbnRTZXJpZXM6IGRldGFpbHMudmFsdWVGcmFnbWVudFNlcmllcyxcbiAgICAgIHZhbHVlRnJhZ21lbnRUeXBlOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRUeXBlLFxuICAgICAgZmV0Y2hlZE1lYXN1cmVtZW50c0Jsb2JGaWxlOiBhd2FpdCBtZWFzdXJlbWVudEZpbGUuYmxvYigpXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoQW5kUHJlcGFyZURhdGFUb0V4cG9ydChcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZyxcbiAgICBpc01lYXN1cmVtZW50OiBib29sZWFuXG4gICk6IFByb21pc2U8RGF0YVRvRXhwb3J0W10+IHtcbiAgICByZXR1cm4gaXNNZWFzdXJlbWVudFxuICAgICAgPyBhd2FpdCB0aGlzLmZldGNoQW5kUHJlcGFyZU1lYXN1cmVtZW50RGF0YVRvRXhwb3J0Rm9yUHJldmlldyhleHBvcnRDb25maWcpXG4gICAgICA6IGF3YWl0IHRoaXMuZmV0Y2hBbmRQcmVwYXJlU2VyaWVzRGF0YVRvRXhwb3J0KGV4cG9ydENvbmZpZyk7XG4gIH1cblxuICBwcmVwYXJlTWVhc3VyZW1lbnRzRmlsdGVyKFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcsXG4gICAgcm91bmRTZWNvbmRzOiBib29sZWFuLFxuICAgIHBhZ2VTaXplPzogbnVtYmVyXG4gICk6IElNZWFzdXJlbWVudEZpbHRlciB7XG4gICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB7XG4gICAgICBkYXRlRnJvbTogdGhpcy5hZGp1c3REYXRlKGV4cG9ydENvbmZpZy5kYXRlRnJvbSwgMCwgcm91bmRTZWNvbmRzKSxcbiAgICAgIGRhdGVUbzogdGhpcy5hZGp1c3REYXRlKGV4cG9ydENvbmZpZy5kYXRlVG8sIDAsIHJvdW5kU2Vjb25kcyksXG4gICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgdmFsdWVGcmFnbWVudFNlcmllczogZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzLFxuICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGVcbiAgICB9O1xuXG4gICAgaWYgKHBhZ2VTaXplKSB7XG4gICAgICBmaWx0ZXIucGFnZVNpemUgPSBwYWdlU2l6ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyO1xuICB9XG5cbiAgcHJvY2Vzc01lYXN1cmVtZW50RGF0YUZvclByZXZpZXcoZGV0YWlsczogRGF0YXBvaW50RGV0YWlscywgZGF0YTogSU1lYXN1cmVtZW50W10pOiBEYXRhVG9FeHBvcnQge1xuICAgIGNvbnN0IHVuaXQgPSBkYXRhWzBdW2RldGFpbHMudmFsdWVGcmFnbWVudFR5cGVdW2RldGFpbHMudmFsdWVGcmFnbWVudFNlcmllc10/LnVuaXQgfHwgJyc7XG5cbiAgICBjb25zdCB2YWx1ZXM6IHsgW3RpbWVzdGFtcDogc3RyaW5nXTogbnVtYmVyIH0gPSB7fTtcbiAgICBkYXRhLmZvckVhY2gobWVhc3VyZW1lbnQgPT4ge1xuICAgICAgdmFsdWVzW21lYXN1cmVtZW50LnRpbWVdID1cbiAgICAgICAgbWVhc3VyZW1lbnRbZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZV1bZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzXS52YWx1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IC4uLmRldGFpbHMsIHVuaXQsIHRpbWVWYWx1ZU1hcDogdmFsdWVzIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIG1hcCBvZiBhY3RpdmUgZGF0YSBwb2ludHMgZGV2aWNlIElEcyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgc2VyaWVzLlxuICAgKlxuICAgKiBFeGFtcGxlIG91dHB1dDpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBuZXcgTWFwKFtcbiAgICogICBbJzg0NDY1NzIwMicsIFsnYzh5X1RlbXBlcmF0dXJlLlQnXV0sXG4gICAqICAgWyczMjY2NjQyNycsIFsnYzh5X0JhdHRlcnkuQmF0dGVyeSddXVxuICAgKiBdKTtcbiAgICogYGBgXG4gICAqIEBwYXJhbSBkYXRhcG9pbnREZXRhaWxzIC0gQW4gYXJyYXkgb2YgZGF0YSBwb2ludHMgZGV0YWlscy5cbiAgICogQHJldHVybnMgQSBtYXAgd2hlcmUgdGhlIGtleSBpcyB0aGUgZGF0YSBwb2ludCBJRCBhbmQgdGhlIHZhbHVlIGlzIGFuIGFycmF5IG9mIGRhdGEgcG9pbnQgc2VyaWVzLlxuICAgKi9cbiAgZ3JvdXBTZXJpZXNCeURldmljZUlkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IERhdGFwb2ludHNWYWx1ZXNEYXRhTWFwIHtcbiAgICByZXR1cm4gZGF0YXBvaW50RGV0YWlscy5yZWR1Y2UoXG4gICAgICAoXG4gICAgICAgIG1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAsXG4gICAgICAgIHsgdmFsdWVGcmFnbWVudFR5cGUsIHZhbHVlRnJhZ21lbnRTZXJpZXMsIHNvdXJjZSB9OiBEYXRhcG9pbnREZXRhaWxzXG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBgJHt2YWx1ZUZyYWdtZW50VHlwZX0uJHt2YWx1ZUZyYWdtZW50U2VyaWVzfWA7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nVmFsdWUgPSBtYXAuZ2V0KHNvdXJjZSkgPz8gW107XG4gICAgICAgIG1hcC5zZXQoc291cmNlLCBbLi4uZXhpc3RpbmdWYWx1ZSwgdmFsdWVdKTtcbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgIH0sXG4gICAgICBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3NlcyB0aGUgZmV0Y2hlZCBzZXJpZXMgZGF0YSBhbmQgcHJlcGFyZXMgaXQgZm9yIGV4cG9ydC5cbiAgICpcbiAgICogQHBhcmFtIGRhdGFwb2ludERldGFpbHMgLSBBbiBhcnJheSBvZiBkYXRhIHBvaW50IGRldGFpbHMuXG4gICAqIEBwYXJhbSBmZXRjaGVkRGF0YU1hcCAtIEEgbWFwIG9mIGZldGNoZWQgc2VyaWVzIGRhdGEgZ3JvdXBlZCBieSBzb3VyY2UuXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIERhdGFUb0V4cG9ydCBvYmplY3RzLlxuICAgKi9cbiAgcHJvY2Vzc1Nlcmllc0RhdGEoXG4gICAgZGF0YXBvaW50RGV0YWlsczogRGF0YXBvaW50RGV0YWlsc1tdLFxuICAgIGZldGNoZWREYXRhTWFwOiBTb3VyY2VJdGVtW11cbiAgKTogRGF0YVRvRXhwb3J0W10ge1xuICAgIGNvbnN0IHZhbHVlc0dyb3VwZWRCeVNvdXJjZSA9IHRoaXMudXRpbHNTZXJ2aWNlLnRyYW5zZm9ybURhdGFTdHJ1Y3R1cmUoZmV0Y2hlZERhdGFNYXApO1xuXG4gICAgcmV0dXJuIGRhdGFwb2ludERldGFpbHMubWFwKChkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzKSA9PiB7XG4gICAgICBsZXQgdW5pdDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgbGV0IGRhdGE6IFRpbWVTZXJpZXNEYXRhO1xuXG4gICAgICAvKipcbiAgICAgICAqIFVuaXF1ZSBrZXkgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBkaWZmZXJlbnQgc2VyaWVzIGZyb20gc2FtZSBzb3VyY2UsXG4gICAgICAgKiBlLmcuOiBjOHlfQWNjZWxlcmF0aW9uLmFjY2VsZXJhdGlvblgsIGM4eV9BY2NlbGVyYXRpb24uYWNjZWxlcmF0aW9uWSwgYzh5X0FjY2VsZXJhdGlvbi5hY2NlbGVyYXRpb25aXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHNlcmllc0tleSA9IGAke2RldGFpbHMudmFsdWVGcmFnbWVudFR5cGV9LiR7ZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzfWA7XG5cbiAgICAgIGlmICh2YWx1ZXNHcm91cGVkQnlTb3VyY2VbZGV0YWlscy5zb3VyY2VdW3Nlcmllc0tleV0pIHtcbiAgICAgICAgdW5pdCA9IHZhbHVlc0dyb3VwZWRCeVNvdXJjZVtkZXRhaWxzLnNvdXJjZV1bc2VyaWVzS2V5XS5zZXJpZXNEZXRhaWxzLnVuaXQ7XG4gICAgICAgIGRhdGEgPSB2YWx1ZXNHcm91cGVkQnlTb3VyY2VbZGV0YWlscy5zb3VyY2VdW3Nlcmllc0tleV0udmFsdWVzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5kZXRhaWxzLFxuICAgICAgICB1bml0LFxuICAgICAgICB0aW1lVmFsdWVNYXA6IGRhdGFcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBnZXRTb3VyY2VzV2l0aFBlcm1pc3Npb25zVG9SZWFkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCBkYXRlRnJvbSA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgZGF0ZVRvID0gbmV3IERhdGUoZGF0ZUZyb20pO1xuXG4gICAgY29uc3QgZmV0Y2hlZERhdGFQcm9taXNlcyA9IGRhdGFwb2ludERldGFpbHMubWFwKGFzeW5jIGRhdGFwb2ludCA9PiB7XG4gICAgICBjb25zdCByYXdGaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB7XG4gICAgICAgIGRhdGVGcm9tLFxuICAgICAgICBkYXRlVG8sXG4gICAgICAgIHNvdXJjZTogZGF0YXBvaW50LnNvdXJjZVxuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyByZXMgfTogSVJlc3VsdDxJU2VyaWVzPiA9IGF3YWl0IHRoaXMuZmV0Y2hTZXJpZXNEYXRhKHJhd0ZpbHRlcik7XG4gICAgICAgIGlmIChyZXM/LnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgcmV0dXJuIGRhdGFwb2ludC5zb3VyY2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBJZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGZldGNoLCByZXR1cm4gbnVsbCB0byBwcmV2ZW50IHByb21pc2UgcmVqZWN0aW9uXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgZmV0Y2hlZFNvdXJjZXMgPSBhd2FpdCBQcm9taXNlLmFsbChmZXRjaGVkRGF0YVByb21pc2VzKTtcbiAgICByZXR1cm4gZmV0Y2hlZFNvdXJjZXMuZmlsdGVyKChzb3VyY2UpOiBzb3VyY2UgaXMgc3RyaW5nID0+IHNvdXJjZSAhPT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogQWRqdXN0cyB0aGUgZ2l2ZW4gZGF0ZSBieSBhZGRpbmcgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgbWludXRlcyBhbmQgc2V0dGluZyBzZWNvbmRzIHRvIDAuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRlIC0gVGhlIGRhdGUgdG8gYmUgYWRqdXN0ZWQgaW4gc3RyaW5nIGZvcm1hdC5cbiAgICogQHBhcmFtIG1pbnV0ZXMgLSBUaGUgbnVtYmVyIG9mIG1pbnV0ZXMgdG8gYWRkIHRvIHRoZSBkYXRlLlxuICAgKiBAcGFyYW0gcm91bmRTZWNvbmRzIC0gV2hldGhlciB0byByb3VuZCB0aGUgc2Vjb25kcyBvciBub3QuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICBJZiB0cnVlLCB0aGUgc2Vjb25kcyB3aWxsIGJlIHJvdW5kZWQgdG8gMC5cbiAgICogICAgICAgICAgICAgICAgICAgICAgIElmIGZhbHNlLCB0aGUgc2Vjb25kcyB3aWxsIGJlIGRpc3BsYXllZCBhcyB0aGV5IGFyZS5cbiAgICogQHJldHVybnMgVGhlIGFkanVzdGVkIGRhdGUgaW4gSVNPIHN0cmluZyBmb3JtYXQuXG4gICAqL1xuICBhZGp1c3REYXRlKGRhdGU6IHN0cmluZyB8IERhdGUsIG1pbnV0ZXM6IG51bWJlciwgcm91bmRTZWNvbmRzID0gdHJ1ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgZGF0ZVRpbWUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICBpZiAoaXNOYU4oZGF0ZVRpbWUuZ2V0VGltZSgpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGUnKTtcbiAgICB9XG5cbiAgICBkYXRlVGltZS5zZXRVVENNaW51dGVzKGRhdGVUaW1lLmdldFVUQ01pbnV0ZXMoKSArIG1pbnV0ZXMpO1xuICAgIGlmIChyb3VuZFNlY29uZHMpIHtcbiAgICAgIGRhdGVUaW1lLnNldFVUQ1NlY29uZHMoMCwgMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGVUaW1lLnRvSVNPU3RyaW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogQXN5bmNocm9ub3VzbHkgbG9hZHMgc2VyaWVzIGRhdGEgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhcmFtZXRlcnMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNvbnN0cnVjdHMgYSBmaWx0ZXIgZm9yIHJldHJpZXZpbmcgc2VyaWVzIGRhdGEgd2l0aGluIGEgc3BlY2lmaWVkIGRhdGUgcmFuZ2UsXG4gICAqIGZyb20gYSBzcGVjaWZpYyBzb3VyY2UsIGFuZCBvcHRpb25hbGx5IGFwcGx5aW5nIGFuIGFnZ3JlZ2F0aW9uIHR5cGUuXG4gICAqXG4gICAqIEBwYXJhbSByYXdGaWx0ZXIgLSBUaGUgcGFyYW1ldGVycyBmb3IgbG9hZGluZyBzZXJpZXMgZGF0YSwgaW5jbHVkaW5nIGRhdGUgcmFuZ2UsIHNvdXJjZSwgc2VyaWVzIG5hbWVzLCBhbmQgYWdncmVnYXRpb24gdHlwZS5cbiAgICogQHBhcmFtIHJvdW5kU2Vjb25kcyAtIEluZGljYXRlcyB3aGV0aGVyIHRvIHJvdW5kIHRoZSBzZWNvbmRzIGluIHRoZSBkYXRlIHJhbmdlIHRvIHRoZSBuZWFyZXN0IHdob2xlIG51bWJlci5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gc2VyaWVzIGRhdGEgd3JhcHBlZCBpbiByZXN1bHQgb2JqZWN0LlxuICAgKi9cbiAgYXN5bmMgZmV0Y2hTZXJpZXNEYXRhKFxuICAgIHJhd0ZpbHRlcjogSVNlcmllc0ZpbHRlcixcbiAgICByb3VuZFNlY29uZHMgPSBmYWxzZVxuICApOiBQcm9taXNlPElSZXN1bHQ8SVNlcmllcz4+IHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgc2VyaWVzRGF0YTogSVJlc3VsdDxJU2VyaWVzPiB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGZpbHRlcjogSVNlcmllc0ZpbHRlciA9IHRoaXMucHJlcGFyZVNlcmllc0ZpbHRlcihcbiAgICAgIHtcbiAgICAgICAgZGF0ZUZyb206IHJhd0ZpbHRlci5kYXRlRnJvbSxcbiAgICAgICAgZGF0ZVRvOiByYXdGaWx0ZXIuZGF0ZVRvLFxuICAgICAgICBzb3VyY2U6IHJhd0ZpbHRlci5zb3VyY2UsXG4gICAgICAgIHNlcmllczogcmF3RmlsdGVyLnNlcmllcyxcbiAgICAgICAgYWdncmVnYXRpb25UeXBlOiByYXdGaWx0ZXIuYWdncmVnYXRpb25UeXBlXG4gICAgICB9LFxuICAgICAgcm91bmRTZWNvbmRzXG4gICAgKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBUT0RPOiBjb25zaWRlciBhZGRpbmcgYSBjYWNoZSBtZWNoYW5pc20gLT4gTVRNLTYwMjg5LCBNVE0tNTkyMzNcbiAgICAgIC8vIFdoZW4gdXNlciBzd2l0Y2hlcyBiZXR3ZWVuIHJlcG9ydCB0eXBlcywgYW5kIHJlc3Qgb2YgdGhlIHNldHRpbmdzIGFyZSB0aGUgc2FtZSwgdGhlbiB0aGUgZGF0YSBzaG91bGQgbm90IGJlIGZldGNoZWQgYWdhaW4/XG4gICAgICBzZXJpZXNEYXRhID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdFNlcmllcyhmaWx0ZXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWVzRGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIGFuZCBwcmVwYXJlcyBtZWFzdXJlbWVudCBkYXRhIGZvciBwcmV2aWV3LlxuICAgKlxuICAgKiBFbXB0eSBEYXRhVG9FeHBvcnQgb2JqZWN0IGNhbiBiZSByZXR1cm5lZCwgYmVjYXVzZSB1bmxpa2Ugc2VyaWVzIGRhdGEsXG4gICAqIG1lYXN1cmVtZW50IGRhdGEgaXMgbm90IGZ1cnRoZXIgcHJvY2Vzc2VkIGJlc2lkZXMgc2hvd2luZyBvbmx5IGluIHRoZSBwcmV2aWV3LlxuICAgKiBDU1YvRXhjZWwgZmlsZXMgYXJlIGdlbmVyYXRlZCBieSB0aGUgYmFja2VuZCBmb3IgbWVhc3VyZW1lbnRzLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwb3J0Q29uZmlnIC0gVGhlIGV4cG9ydCBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gcm91bmRTZWNvbmRzIC0gSW5kaWNhdGVzIHdoZXRoZXIgdG8gcm91bmQgdGhlIHNlY29uZHMgaW4gdGhlIGRhdGUgcmFuZ2UgdG8gdGhlIG5lYXJlc3Qgd2hvbGUgbnVtYmVyLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiBEYXRhVG9FeHBvcnQgb2JqZWN0cyBvciBudWxsIHdoZW4gbm8gZGF0YSBpcyBmZXRjaGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFuZFByZXBhcmVNZWFzdXJlbWVudERhdGFUb0V4cG9ydEZvclByZXZpZXcoXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcsXG4gICAgcm91bmRTZWNvbmRzID0gZmFsc2VcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRbXT4gfCBudWxsIHtcbiAgICBjb25zdCBkYXRhVG9FeHBvcnRQcm9taXNlczogUHJvbWlzZTxEYXRhVG9FeHBvcnQ+W10gPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoXG4gICAgICBhc3luYyBkZXRhaWxzID0+IHtcbiAgICAgICAgY29uc3QgZmV0Y2hlZE1lYXN1cmVtZW50RGF0YTogSVJlc3VsdExpc3Q8SU1lYXN1cmVtZW50PiA9XG4gICAgICAgICAgYXdhaXQgdGhpcy5mZXRjaE1lYXN1cmVtZW50RGF0YUZvclByZXZpZXcoZGV0YWlscywgZXhwb3J0Q29uZmlnLCByb3VuZFNlY29uZHMpO1xuXG4gICAgICAgIGlmIChmZXRjaGVkTWVhc3VyZW1lbnREYXRhPy5kYXRhPy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzTWVhc3VyZW1lbnREYXRhRm9yUHJldmlldyhkZXRhaWxzLCBmZXRjaGVkTWVhc3VyZW1lbnREYXRhLmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICk7XG5cbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoZGF0YVRvRXhwb3J0UHJvbWlzZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaE1lYXN1cmVtZW50RGF0YUZvclByZXZpZXcoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZyxcbiAgICByb3VuZFNlY29uZHM6IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxJUmVzdWx0TGlzdDxJTWVhc3VyZW1lbnQ+PiB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IG1lYXN1cmVtZW50czogSVJlc3VsdExpc3Q8SU1lYXN1cmVtZW50PiB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGZpbHRlcjogSU1lYXN1cmVtZW50RmlsdGVyID0gdGhpcy5wcmVwYXJlTWVhc3VyZW1lbnRzRmlsdGVyKFxuICAgICAgZGV0YWlscyxcbiAgICAgIGV4cG9ydENvbmZpZyxcbiAgICAgIHJvdW5kU2Vjb25kcyxcbiAgICAgIE1FQVNVUkVNRU5UU19QUkVWSUVXX0lURU1TX0xJTUlUXG4gICAgKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBUT0RPOiBjb25zaWRlciBhZGRpbmcgYSBjYWNoZSBtZWNoYW5pc20gLT4gTVRNLTYwMjg5XG4gICAgICAvLyBXaGVuIHVzZXIgc3dpdGNoZXMgYmV0d2VlbiByZXBvcnQgdHlwZXMsIGFuZCByZXN0IG9mIHRoZSBzZXR0aW5ncyBhcmUgdGhlIHNhbWUsIHRoZW4gdGhlIGRhdGEgc2hvdWxkIG5vdCBiZSBmZXRjaGVkIGFnYWluP1xuICAgICAgbWVhc3VyZW1lbnRzID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdChmaWx0ZXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWVhc3VyZW1lbnRzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFuZFByZXBhcmVTZXJpZXNEYXRhVG9FeHBvcnQoZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcpIHtcbiAgICBjb25zdCBkYXRhcG9pbnRzVmFsdWVzRGF0YU1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAgPSB0aGlzLmdyb3VwU2VyaWVzQnlEZXZpY2VJZChcbiAgICAgIGV4cG9ydENvbmZpZy5kYXRhcG9pbnREZXRhaWxzXG4gICAgKTtcblxuICAgIGNvbnN0IGZldGNoZWREYXRhUHJvbWlzZXMgPSBBcnJheS5mcm9tKGRhdGFwb2ludHNWYWx1ZXNEYXRhTWFwKS5tYXAoXG4gICAgICBhc3luYyAoW3NvdXJjZSwgc2VyaWVzXSkgPT4ge1xuICAgICAgICBjb25zdCB7IGRhdGVGcm9tLCBkYXRlVG8sIGFnZ3JlZ2F0aW9uIH0gPSBleHBvcnRDb25maWc7XG5cbiAgICAgICAgY29uc3QgcmF3RmlsdGVyOiBJU2VyaWVzRmlsdGVyID0ge1xuICAgICAgICAgIGRhdGVGcm9tLFxuICAgICAgICAgIGRhdGVUbyxcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgc2VyaWVzLFxuICAgICAgICAgIGFnZ3JlZ2F0aW9uVHlwZTogYWdncmVnYXRpb24gYXMgYWdncmVnYXRpb25UeXBlXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgeyBkYXRhIH06IElSZXN1bHQ8SVNlcmllcz4gPSBhd2FpdCB0aGlzLmZldGNoU2VyaWVzRGF0YShyYXdGaWx0ZXIpO1xuXG4gICAgICAgIHJldHVybiB7IHNvdXJjZSwgZGF0YSB9O1xuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCBmZXRjaGVkRGF0YUdyb3VwZWRCeVNvdXJjZTogU291cmNlSXRlbVtdID0gYXdhaXQgUHJvbWlzZS5hbGwoZmV0Y2hlZERhdGFQcm9taXNlcyk7XG5cbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzU2VyaWVzRGF0YShleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscywgZmV0Y2hlZERhdGFHcm91cGVkQnlTb3VyY2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlU2VyaWVzRmlsdGVyKGZpbHRlcnM6IElTZXJpZXNGaWx0ZXIsIHJvdW5kU2Vjb25kczogYm9vbGVhbik6IElTZXJpZXNGaWx0ZXIge1xuICAgIGNvbnN0IHsgZGF0ZUZyb20sIGRhdGVUbywgc291cmNlLCBzZXJpZXMsIGFnZ3JlZ2F0aW9uVHlwZSB9ID0gZmlsdGVycztcbiAgICBjb25zdCBmcm9tID0gdGhpcy5hZGp1c3REYXRlKGRhdGVGcm9tLCAwLCByb3VuZFNlY29uZHMpO1xuICAgIGNvbnN0IHRvID0gdGhpcy5hZGp1c3REYXRlKGRhdGVUbywgMCwgcm91bmRTZWNvbmRzKTtcblxuICAgIGNvbnN0IGZpbHRlcjogSVNlcmllc0ZpbHRlciA9IHtcbiAgICAgIGRhdGVGcm9tOiBmcm9tLFxuICAgICAgZGF0ZVRvOiB0byxcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgcmV2ZXJ0OiB0cnVlXG4gICAgfTtcblxuICAgIC8vIFRoZSAnTk9ORScgYWdncmVnYXRpb24gdHlwZSBpcyBub3QgaGFuZGxlZCBieSBhIGJhY2tlbmQsIHNvIGV2ZW4gd2hlbiBpcyBzZWxlY3RlZCwgaXQgaXMgbm90IHBhc3NlZCBhcyBhIGZpbHRlciBwYXJhbWV0ZXIuXG4gICAgaWYgKGFnZ3JlZ2F0aW9uVHlwZSAmJiBhZ2dyZWdhdGlvblR5cGUgIT09IChBR0dSRUdBVElPTl9WQUxVRVMubm9uZSBhcyBhZ2dyZWdhdGlvblR5cGUpKSB7XG4gICAgICBmaWx0ZXIuYWdncmVnYXRpb25UeXBlID0gYWdncmVnYXRpb25UeXBlO1xuICAgIH1cblxuICAgIC8vIFRPRE86IGl0IGlzIGEgdGVtcG9yYWwgd29ya2Fyb3VuZCBmb3IgYSBidWcgaW4gdGhlIGJhY2tlbmQsXG4gICAgLy8gd2hlcmUgdGhlIHNlcmllcyB3aXRoIG1vcmUgdGhhbiBvbmUgZG90IGFyZSBpbXBvc3NpYmxlIHRvIHJldHJpZXZlOlxuICAgIC8vIGh0dHBzOi8vY3VtdWxvY2l0eS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9NVE0tNTkyNzdcbiAgICBpZiAoc2VyaWVzKSB7XG4gICAgICBjb25zdCBoYXNNb3JlVGhhbk9uZURvdCA9IChzZXJpZXMgYXMgc3RyaW5nW10pLnNvbWUocyA9PiBzLnNwbGl0KCcuJykubGVuZ3RoID4gMik7XG4gICAgICBpZiAoIWhhc01vcmVUaGFuT25lRG90KSB7XG4gICAgICAgIGZpbHRlci5zZXJpZXMgPSBzZXJpZXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcjtcbiAgfVxufVxuIl19