@kepler.gl/reducers 3.3.0-alpha.0 → 3.3.0-alpha.10

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 (84) hide show
  1. package/dist/cjs/combined-updaters.js +491 -0
  2. package/dist/cjs/composer-helpers.js +101 -0
  3. package/dist/cjs/composers.js +22 -0
  4. package/dist/cjs/core.js +105 -0
  5. package/dist/cjs/data-utils.js +53 -0
  6. package/dist/cjs/export-utils.js +91 -0
  7. package/dist/{index.js → cjs/index.js} +2 -3
  8. package/dist/cjs/interaction-utils.js +115 -0
  9. package/dist/cjs/layer-utils.js +635 -0
  10. package/dist/cjs/map-state-updaters.js +658 -0
  11. package/dist/cjs/map-state.js +35 -0
  12. package/dist/cjs/map-style-updaters.js +660 -0
  13. package/dist/cjs/map-style.js +33 -0
  14. package/dist/cjs/merger-handler.js +105 -0
  15. package/dist/cjs/middleware.js +27 -0
  16. package/dist/cjs/provider-state-updaters.js +465 -0
  17. package/dist/cjs/provider-state.js +34 -0
  18. package/dist/cjs/root.js +207 -0
  19. package/dist/cjs/ui-state-updaters.js +922 -0
  20. package/dist/cjs/ui-state.js +36 -0
  21. package/dist/cjs/vis-state-merger.js +1193 -0
  22. package/dist/cjs/vis-state-selectors.js +30 -0
  23. package/dist/cjs/vis-state-updaters.js +5100 -0
  24. package/dist/cjs/vis-state.js +35 -0
  25. package/dist/combined-updaters.d.ts +19 -2
  26. package/dist/composers.d.ts +2 -0
  27. package/dist/esm/combined-updaters.js +484 -0
  28. package/dist/esm/composer-helpers.js +85 -0
  29. package/dist/esm/composers.js +14 -0
  30. package/dist/esm/core.js +101 -0
  31. package/dist/esm/data-utils.js +47 -0
  32. package/dist/esm/export-utils.js +86 -0
  33. package/dist/esm/index.js +62 -0
  34. package/dist/esm/interaction-utils.js +106 -0
  35. package/dist/esm/layer-utils.js +602 -0
  36. package/dist/esm/map-state-updaters.js +650 -0
  37. package/dist/esm/map-state.js +29 -0
  38. package/dist/esm/map-style-updaters.js +652 -0
  39. package/dist/esm/map-style.js +27 -0
  40. package/dist/esm/merger-handler.js +96 -0
  41. package/dist/esm/middleware.js +19 -0
  42. package/dist/esm/provider-state-updaters.js +458 -0
  43. package/dist/esm/provider-state.js +28 -0
  44. package/dist/esm/root.js +201 -0
  45. package/dist/esm/ui-state-updaters.js +917 -0
  46. package/dist/esm/ui-state.js +30 -0
  47. package/dist/esm/vis-state-merger.js +1161 -0
  48. package/dist/esm/vis-state-selectors.js +24 -0
  49. package/dist/esm/vis-state-updaters.js +5006 -0
  50. package/dist/esm/vis-state.js +29 -0
  51. package/dist/interaction-utils.d.ts +1 -1
  52. package/dist/layer-utils.d.ts +30 -5
  53. package/dist/map-state-updaters.d.ts +27 -20
  54. package/dist/map-state.d.ts +2 -74
  55. package/dist/map-style-updaters.d.ts +1 -3
  56. package/dist/ui-state-updaters.d.ts +53 -3
  57. package/dist/vis-state-merger.d.ts +11 -0
  58. package/dist/vis-state-selectors.d.ts +42 -6
  59. package/dist/vis-state-updaters.d.ts +163 -2
  60. package/dist/vis-state.d.ts +24 -4
  61. package/package.json +43 -35
  62. package/dist/combined-updaters.js +0 -366
  63. package/dist/composer-helpers.js +0 -101
  64. package/dist/composers.js +0 -23
  65. package/dist/core.js +0 -105
  66. package/dist/data-utils.js +0 -53
  67. package/dist/export-utils.js +0 -91
  68. package/dist/interaction-utils.js +0 -105
  69. package/dist/layer-utils.js +0 -335
  70. package/dist/map-state-updaters.js +0 -436
  71. package/dist/map-state.js +0 -35
  72. package/dist/map-style-updaters.js +0 -661
  73. package/dist/map-style.js +0 -34
  74. package/dist/merger-handler.js +0 -105
  75. package/dist/middleware.js +0 -27
  76. package/dist/provider-state-updaters.js +0 -466
  77. package/dist/provider-state.js +0 -35
  78. package/dist/root.js +0 -207
  79. package/dist/ui-state-updaters.js +0 -803
  80. package/dist/ui-state.js +0 -37
  81. package/dist/vis-state-merger.js +0 -990
  82. package/dist/vis-state-selectors.js +0 -30
  83. package/dist/vis-state-updaters.js +0 -3611
  84. package/dist/vis-state.js +0 -36
@@ -0,0 +1,1161 @@
1
+ import _typeof from "@babel/runtime/helpers/esm/typeof";
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
5
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
6
+ var _excluded = ["enabled"];
7
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
8
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
9
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
10
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
11
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
12
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
13
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
14
+ // SPDX-License-Identifier: MIT
15
+ // Copyright contributors to the kepler.gl project
16
+
17
+ import uniq from 'es-toolkit/compat/uniq';
18
+ import pick from 'es-toolkit/compat/pick';
19
+ import flattenDeep from 'es-toolkit/compat/flattenDeep';
20
+ import deepmerge from 'deepmerge';
21
+ import { arrayInsert, getInitialMapLayersForSplitMap, applyFiltersToDatasets, validateFiltersUpdateDatasets, findById, aggregate, isPlainObject } from '@kepler.gl/utils';
22
+ import { createEffect } from '@kepler.gl/effects';
23
+ import { notNullorUndefined } from '@kepler.gl/common-utils';
24
+ import { AGGREGATION_TYPES, LAYER_BLENDINGS, OVERLAY_BLENDINGS, isAnnotationKind, INITIAL_ANNOTATION_LINE_COLOR, INITIAL_ANNOTATION_LINE_WIDTH } from '@kepler.gl/constants';
25
+ import { CURRENT_VERSION } from '@kepler.gl/schemas';
26
+ import { assignGpuChannels, resetFilterGpuMode } from '@kepler.gl/table';
27
+ import { getLayerOrderFromLayers } from './layer-utils';
28
+
29
+ /**
30
+ * Merge loaded filters with current state, if no fields or data are loaded
31
+ * save it for later
32
+ *
33
+ */
34
+ export function mergeFilters(state, filtersToMerge, fromConfig) {
35
+ var preserveFilterOrder = fromConfig ? filtersToMerge === null || filtersToMerge === void 0 ? void 0 : filtersToMerge.map(function (l) {
36
+ return l.id;
37
+ }) : state.preserveFilterOrder;
38
+ if (!Array.isArray(filtersToMerge) || !filtersToMerge.length) {
39
+ return state;
40
+ }
41
+ var _validateFiltersUpdat = validateFiltersUpdateDatasets(state, filtersToMerge),
42
+ validated = _validateFiltersUpdat.validated,
43
+ failed = _validateFiltersUpdat.failed,
44
+ updatedDatasets = _validateFiltersUpdat.updatedDatasets;
45
+ var updatedFilters = insertItemBasedOnPreservedOrder(state.filters, validated, preserveFilterOrder);
46
+
47
+ // merge filter with existing
48
+ updatedFilters = resetFilterGpuMode(updatedFilters);
49
+ updatedFilters = assignGpuChannels(updatedFilters);
50
+ // filter data
51
+ var datasetsToFilter = uniq(flattenDeep(validated.map(function (f) {
52
+ return f.dataId;
53
+ })));
54
+ var filtered = applyFiltersToDatasets(datasetsToFilter, updatedDatasets, updatedFilters, state.layers);
55
+ return _objectSpread(_objectSpread({}, state), {}, {
56
+ filters: updatedFilters,
57
+ datasets: filtered,
58
+ preserveFilterOrder: preserveFilterOrder,
59
+ filterToBeMerged: [].concat(_toConsumableArray(state.filterToBeMerged), _toConsumableArray(failed))
60
+ });
61
+ }
62
+
63
+ // replace dataId in saved Filter
64
+ export function replaceFilterDatasetIds(savedFilter, dataId, dataIdToUse) {
65
+ var replaced = [];
66
+ savedFilter.forEach(function (filter) {
67
+ if (filter.dataId.includes(dataId)) {
68
+ var _filter$plotType;
69
+ var newDataId = filter.dataId.map(function (d) {
70
+ return d === dataId ? dataIdToUse : d;
71
+ });
72
+ var plotType;
73
+ // TODO: more generic approach to save plotType.colorsByDataId
74
+ if ((_filter$plotType = filter.plotType) !== null && _filter$plotType !== void 0 && (_filter$plotType = _filter$plotType.colorsByDataId) !== null && _filter$plotType !== void 0 && _filter$plotType[dataId]) {
75
+ var _filter$plotType2;
76
+ // replace colorByDataId in filter.plotType
77
+ var _ref = ((_filter$plotType2 = filter.plotType) === null || _filter$plotType2 === void 0 ? void 0 : _filter$plotType2.colorsByDataId) || {},
78
+ color = _ref[dataId],
79
+ rest = _objectWithoutProperties(_ref, [dataId].map(_toPropertyKey));
80
+ plotType = _objectSpread(_objectSpread({}, filter.plotType), {}, {
81
+ colorsByDataId: _objectSpread(_objectSpread({}, rest), {}, _defineProperty({}, dataIdToUse, color))
82
+ });
83
+ }
84
+ replaced.push(_objectSpread(_objectSpread({}, filter), {}, {
85
+ dataId: newDataId
86
+ }, plotType ? {
87
+ plotType: plotType
88
+ } : {}));
89
+ }
90
+ });
91
+ return replaced.length ? replaced : null;
92
+ }
93
+ export function isSavedLayerConfigV1(layerConfig) {
94
+ // exported layer configuration contains visualChannels property
95
+ return layerConfig === null || layerConfig === void 0 ? void 0 : layerConfig.visualChannels;
96
+ }
97
+ export function parseLayerConfig(schema, layerConfig) {
98
+ var _schema$parseSavedCon;
99
+ // assume the layer config is current version
100
+ var savedConfig = {
101
+ version: CURRENT_VERSION,
102
+ config: {
103
+ visState: {
104
+ layers: [layerConfig],
105
+ layerOrder: [layerConfig.id]
106
+ }
107
+ }
108
+ };
109
+ return (_schema$parseSavedCon = schema.parseSavedConfig(savedConfig)) === null || _schema$parseSavedCon === void 0 || (_schema$parseSavedCon = _schema$parseSavedCon.visState) === null || _schema$parseSavedCon === void 0 || (_schema$parseSavedCon = _schema$parseSavedCon.layers) === null || _schema$parseSavedCon === void 0 ? void 0 : _schema$parseSavedCon[0];
110
+ }
111
+ function insertItemBasedOnPreservedOrder(currentItems, items) {
112
+ var preservedOrder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
113
+ var defaultStart = arguments.length > 3 ? arguments[3] : undefined;
114
+ var newItems = _toConsumableArray(currentItems);
115
+ var _iterator = _createForOfIteratorHelper(items),
116
+ _step;
117
+ try {
118
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
119
+ var item = _step.value;
120
+ var expectedIdx = preservedOrder.indexOf(item.id);
121
+ // insertAt the end by default
122
+ var insertAt = defaultStart ? 0 : newItems.length;
123
+ if (expectedIdx > 0) {
124
+ // look for layer to insert after
125
+ var i = expectedIdx + 1;
126
+ var preceedIdx = -1;
127
+ var _loop = function _loop() {
128
+ // keep looking for preceed layer that is already loaded
129
+ var preceedItemId = preservedOrder[i - 1];
130
+ preceedIdx = newItems.findIndex(function (d) {
131
+ return d.id === preceedItemId;
132
+ });
133
+ };
134
+ while (i-- > 0 && preceedIdx < 0) {
135
+ _loop();
136
+ }
137
+ if (preceedIdx > -1) {
138
+ // if found
139
+ insertAt = preceedIdx + 1;
140
+ }
141
+ }
142
+ newItems = arrayInsert(newItems, insertAt, item);
143
+ }
144
+ } catch (err) {
145
+ _iterator.e(err);
146
+ } finally {
147
+ _iterator.f();
148
+ }
149
+ return newItems;
150
+ }
151
+ export function createLayerFromConfig(state, layerConfig) {
152
+ // check if the layer config is parsed
153
+ var parsedLayerConfig = isSavedLayerConfigV1(layerConfig) ? parseLayerConfig(state.schema, layerConfig) : layerConfig;
154
+ if (!parsedLayerConfig) {
155
+ return null;
156
+ }
157
+ // first validate config against dataset
158
+ var _validateLayersByData = validateLayersByDatasets(state.datasets, state.layerClasses, [parsedLayerConfig], {
159
+ allowEmptyColumn: true
160
+ }),
161
+ validated = _validateLayersByData.validated,
162
+ failed = _validateLayersByData.failed;
163
+ if (failed !== null && failed !== void 0 && failed.length || !validated.length) {
164
+ // failed
165
+ return null;
166
+ }
167
+ var newLayer = validated[0];
168
+ newLayer.updateLayerDomain(state.datasets);
169
+ return newLayer;
170
+ }
171
+
172
+ /**
173
+ * Get loaded filter from state
174
+ */
175
+ export function serializeFilter(newFilter, schema) {
176
+ var _serializedVisState$f;
177
+ var serializedVisState = serializeVisState({
178
+ filters: [newFilter]
179
+ }, schema);
180
+ return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$f = serializedVisState.filters) === null || _serializedVisState$f === void 0 ? void 0 : _serializedVisState$f[0];
181
+ }
182
+
183
+ /**
184
+ * Get loaded layer from state
185
+ */
186
+ export function serializeLayer(newLayer, schema) {
187
+ var _serializedVisState$l;
188
+ var serializedVisState = serializeVisState({
189
+ layers: [newLayer],
190
+ layerOrder: [newLayer.id]
191
+ }, schema);
192
+ return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$l = serializedVisState.layers) === null || _serializedVisState$l === void 0 ? void 0 : _serializedVisState$l[0];
193
+ }
194
+
195
+ /**
196
+ * Get loaded effect from state
197
+ */
198
+ export function serializeEffect(newEffect, schema) {
199
+ var _serializedVisState$e;
200
+ var serializedVisState = serializeVisState({
201
+ effects: [newEffect],
202
+ effectOrder: [newEffect.id]
203
+ }, schema);
204
+ return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$e = serializedVisState.effects) === null || _serializedVisState$e === void 0 ? void 0 : _serializedVisState$e[0];
205
+ }
206
+
207
+ /**
208
+ * Get vis state config
209
+ */
210
+ export function serializeVisState(visState, schema) {
211
+ var _schema$parseSavedCon2;
212
+ var savedState = schema.getConfigToSave({
213
+ visState: visState
214
+ });
215
+ return savedState ? (_schema$parseSavedCon2 = schema.parseSavedConfig(savedState)) === null || _schema$parseSavedCon2 === void 0 ? void 0 : _schema$parseSavedCon2.visState : undefined;
216
+ }
217
+ /**
218
+ * Merge layers from de-serialized state, if no fields or data are loaded
219
+ * save it for later
220
+ *
221
+ */
222
+ export function mergeLayers(state) {
223
+ var layersToMerge = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
224
+ var fromConfig = arguments.length > 2 ? arguments[2] : undefined;
225
+ var preserveLayerOrder = fromConfig ? getLayerOrderFromLayers(layersToMerge) : state.preserveLayerOrder;
226
+ if (!Array.isArray(layersToMerge) || !layersToMerge.length) {
227
+ return state;
228
+ }
229
+ // don't merge layer if dataset is being merged
230
+ var unmerged = [];
231
+ var toMerge = [];
232
+ layersToMerge.forEach(function (l) {
233
+ var _l$config;
234
+ if (l !== null && l !== void 0 && (_l$config = l.config) !== null && _l$config !== void 0 && _l$config.dataId && state.isMergingDatasets[l.config.dataId]) {
235
+ unmerged.push(l);
236
+ } else {
237
+ toMerge.push(l);
238
+ }
239
+ });
240
+ var _validateLayersByData2 = validateLayersByDatasets(state.datasets, state.layerClasses, toMerge),
241
+ mergedLayer = _validateLayersByData2.validated,
242
+ failed = _validateLayersByData2.failed;
243
+ unmerged.push.apply(unmerged, _toConsumableArray(failed));
244
+ // put new layers in front of current layers
245
+ var _insertLayerAtRightOr = insertLayerAtRightOrder(state.layers, mergedLayer, state.layerOrder, preserveLayerOrder),
246
+ newLayerOrder = _insertLayerAtRightOr.newLayerOrder,
247
+ newLayers = _insertLayerAtRightOr.newLayers;
248
+ var mergedState = _objectSpread(_objectSpread({}, state), {}, {
249
+ layers: newLayers,
250
+ layerOrder: newLayerOrder,
251
+ preserveLayerOrder: preserveLayerOrder,
252
+ layerToBeMerged: [].concat(_toConsumableArray(state.layerToBeMerged), unmerged)
253
+ });
254
+
255
+ // Apply pending layerOrder with groups if layers are now available
256
+ if (mergedState.layerOrderToBeMerged && mergedState.layers.length > 0) {
257
+ var savedOrder = mergedState.layerOrderToBeMerged;
258
+ mergedState = mergeLayerOrder(mergedState, savedOrder);
259
+ // Keep savedLayerOrder available for future deferred layers
260
+ if (mergedState.layerToBeMerged.length > 0) {
261
+ mergedState = _objectSpread(_objectSpread({}, mergedState), {}, {
262
+ layerOrderToBeMerged: savedOrder
263
+ });
264
+ }
265
+ }
266
+ return mergedState;
267
+ }
268
+ export function insertLayerAtRightOrder(currentLayers, layersToInsert, currentOrder) {
269
+ var preservedOrder = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
270
+ if (!(layersToInsert !== null && layersToInsert !== void 0 && layersToInsert.length)) {
271
+ return {
272
+ newLayers: currentLayers,
273
+ newLayerOrder: currentOrder
274
+ };
275
+ }
276
+ var currentLayerQueue = currentOrder.filter(function (entry) {
277
+ return typeof entry === 'string';
278
+ }).map(function (id) {
279
+ return findById(id)(currentLayers);
280
+ }).filter(function (layer) {
281
+ return Boolean(layer);
282
+ });
283
+ var newLayers = currentLayers.concat(layersToInsert);
284
+ var newLayerOrderQueue = insertItemBasedOnPreservedOrder(currentLayerQueue, layersToInsert, preservedOrder, true);
285
+ var newFlatLayerOrder = getLayerOrderFromLayers(newLayerOrderQueue);
286
+
287
+ // If no groups exist in current order, just use the new flat order
288
+ var hasGroups = currentOrder.some(function (entry) {
289
+ return isPlainObject(entry);
290
+ });
291
+ if (!hasGroups) {
292
+ return {
293
+ newLayerOrder: newFlatLayerOrder,
294
+ newLayers: newLayers
295
+ };
296
+ }
297
+
298
+ // Rebuild layerOrder preserving groups in their relative positions.
299
+ // Replace each string entry with its updated position from newFlatLayerOrder,
300
+ // and keep groups as-is.
301
+ var existingFlatIds = new Set(currentOrder.filter(function (entry) {
302
+ return typeof entry === 'string';
303
+ }));
304
+ var newInsertedIds = newFlatLayerOrder.filter(function (id) {
305
+ return !existingFlatIds.has(id);
306
+ });
307
+
308
+ // Rebuild: walk through currentOrder, replace string entries with their
309
+ // new position equivalents from newFlatLayerOrder, then append any newly inserted layers
310
+ var result = [];
311
+ var flatQueue = _toConsumableArray(newFlatLayerOrder.filter(function (id) {
312
+ return existingFlatIds.has(id);
313
+ }));
314
+ var flatIdx = 0;
315
+ var _iterator2 = _createForOfIteratorHelper(currentOrder),
316
+ _step2;
317
+ try {
318
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
319
+ var entry = _step2.value;
320
+ if (isPlainObject(entry)) {
321
+ result.push(entry);
322
+ } else {
323
+ // Replace with corresponding entry from reordered flat list
324
+ if (flatIdx < flatQueue.length) {
325
+ result.push(flatQueue[flatIdx]);
326
+ flatIdx++;
327
+ }
328
+ }
329
+ }
330
+
331
+ // Append any newly inserted layers at the front (they are new)
332
+ } catch (err) {
333
+ _iterator2.e(err);
334
+ } finally {
335
+ _iterator2.f();
336
+ }
337
+ return {
338
+ newLayerOrder: [].concat(_toConsumableArray(newInsertedIds), result),
339
+ newLayers: newLayers
340
+ };
341
+ }
342
+
343
+ /**
344
+ * Merge saved layerOrder with current state to restore layer groups.
345
+ * Called after layers have been merged. If the saved config contains a layerOrder
346
+ * with groups, this replaces the flat layerOrder with the saved hierarchical one,
347
+ * filtering out any layer IDs that don't exist in the current state.
348
+ */
349
+ export function mergeLayerOrder(state, savedLayerOrder, fromConfig) {
350
+ if (!savedLayerOrder || !Array.isArray(savedLayerOrder) || savedLayerOrder.length === 0) {
351
+ return state;
352
+ }
353
+
354
+ // Check if the saved layerOrder contains any groups
355
+ var hasGroups = savedLayerOrder.some(function (entry) {
356
+ return isPlainObject(entry);
357
+ });
358
+ if (!hasGroups) {
359
+ // No groups - the layer merger already handled ordering via preserveLayerOrder
360
+ return state;
361
+ }
362
+
363
+ // If layers haven't been merged yet, store for later
364
+ if (state.layers.length === 0) {
365
+ return _objectSpread(_objectSpread({}, state), {}, {
366
+ layerOrderToBeMerged: savedLayerOrder
367
+ });
368
+ }
369
+
370
+ // Build a set of valid layer IDs from current state
371
+ var validLayerIds = new Set(state.layers.map(function (l) {
372
+ return l.id;
373
+ }));
374
+
375
+ // Recursively filter the saved layerOrder to only include valid layers
376
+ function filterLayerOrder(order) {
377
+ var result = [];
378
+ var _iterator3 = _createForOfIteratorHelper(order),
379
+ _step3;
380
+ try {
381
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
382
+ var entry = _step3.value;
383
+ if (isPlainObject(entry)) {
384
+ var group = entry;
385
+ var filteredGroupOrder = filterLayerOrder(group.layerOrder);
386
+ // Keep the group even if empty (user may want the empty group)
387
+ result.push(_objectSpread(_objectSpread({}, group), {}, {
388
+ layerOrder: filteredGroupOrder
389
+ }));
390
+ } else if (typeof entry === 'string' && validLayerIds.has(entry)) {
391
+ result.push(entry);
392
+ }
393
+ }
394
+ } catch (err) {
395
+ _iterator3.e(err);
396
+ } finally {
397
+ _iterator3.f();
398
+ }
399
+ return result;
400
+ }
401
+ var restoredLayerOrder = filterLayerOrder(savedLayerOrder);
402
+
403
+ // Find any layers in the current state that aren't in the restored order
404
+ // (could happen if layers were added between save and load)
405
+ var layerIdsInRestored = new Set();
406
+ function collectIds(order) {
407
+ var _iterator4 = _createForOfIteratorHelper(order),
408
+ _step4;
409
+ try {
410
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
411
+ var entry = _step4.value;
412
+ if (isPlainObject(entry)) {
413
+ collectIds(entry.layerOrder);
414
+ } else if (typeof entry === 'string') {
415
+ layerIdsInRestored.add(entry);
416
+ }
417
+ }
418
+ } catch (err) {
419
+ _iterator4.e(err);
420
+ } finally {
421
+ _iterator4.f();
422
+ }
423
+ }
424
+ collectIds(restoredLayerOrder);
425
+
426
+ // Add any missing layers at the top
427
+ var missingLayers = state.layers.filter(function (l) {
428
+ return !layerIdsInRestored.has(l.id);
429
+ }).map(function (l) {
430
+ return l.id;
431
+ });
432
+ return _objectSpread(_objectSpread({}, state), {}, {
433
+ layerOrder: [].concat(_toConsumableArray(missingLayers), _toConsumableArray(restoredLayerOrder)),
434
+ layerOrderToBeMerged: null
435
+ });
436
+ }
437
+
438
+ /**
439
+ * Merge interactions with saved config
440
+ *
441
+ */
442
+ export function mergeInteractions(state, interactionToBeMerged) {
443
+ var merged = {};
444
+ var unmerged = {};
445
+ if (interactionToBeMerged) {
446
+ Object.keys(interactionToBeMerged).forEach(function (key) {
447
+ if (!state.interactionConfig[key]) {
448
+ return;
449
+ }
450
+ var currentConfig = key === 'tooltip' || key === 'brush' || key === 'geocoder' ? state.interactionConfig[key].config : null;
451
+ var _ref2 = interactionToBeMerged[key] || {},
452
+ enabled = _ref2.enabled,
453
+ configSaved = _objectWithoutProperties(_ref2, _excluded);
454
+ var configToMerge = configSaved;
455
+ if (key === 'tooltip') {
456
+ var _mergeInteractionTool = mergeInteractionTooltipConfig(state, configSaved),
457
+ mergedTooltip = _mergeInteractionTool.mergedTooltip,
458
+ unmergedTooltip = _mergeInteractionTool.unmergedTooltip;
459
+
460
+ // merge new dataset tooltips with original dataset tooltips
461
+ configToMerge = {
462
+ fieldsToShow: _objectSpread(_objectSpread({}, currentConfig.fieldsToShow), mergedTooltip)
463
+ };
464
+ if (Object.keys(unmergedTooltip).length) {
465
+ // @ts-expect-error
466
+ unmerged.tooltip = {
467
+ fieldsToShow: unmergedTooltip,
468
+ enabled: Boolean(enabled)
469
+ };
470
+ }
471
+ }
472
+ merged[key] = _objectSpread(_objectSpread({}, state.interactionConfig[key]), {}, {
473
+ enabled: Boolean(enabled)
474
+ }, currentConfig ? {
475
+ config: pick(_objectSpread(_objectSpread({}, currentConfig), configToMerge), Object.keys(currentConfig))
476
+ } : {});
477
+ });
478
+ }
479
+ var nextState = _objectSpread(_objectSpread({}, state), {}, {
480
+ interactionConfig: _objectSpread(_objectSpread({}, state.interactionConfig), merged),
481
+ interactionToBeMerged: savedUnmergedInteraction(state, unmerged)
482
+ });
483
+ return nextState;
484
+ }
485
+ function combineInteractionConfigs(configs) {
486
+ var combined = _objectSpread({}, configs[0]);
487
+ // handle each property key of an `InteractionConfig`, e.g. tooltip, geocoder, brush, coordinate
488
+ // by combining values for each among all passed in configs
489
+ var _loop2 = function _loop2(key) {
490
+ var toBeCombinedProps = configs.map(function (c) {
491
+ return c[key];
492
+ });
493
+
494
+ // all of these have an enabled boolean
495
+ combined[key] = {
496
+ // are any of the configs' enabled values true?
497
+ enabled: toBeCombinedProps.some(function (p) {
498
+ return p === null || p === void 0 ? void 0 : p.enabled;
499
+ })
500
+ };
501
+ if (key === 'tooltip') {
502
+ // are any of the configs' compareMode values true?
503
+ combined[key].compareMode = toBeCombinedProps.some(function (p) {
504
+ return p === null || p === void 0 ? void 0 : p.compareMode;
505
+ });
506
+
507
+ // return the compare type mode, it will be either absolute or relative
508
+ combined[key].compareType = getValueWithHighestOccurrence(toBeCombinedProps.map(function (p) {
509
+ return p.compareType;
510
+ }));
511
+
512
+ // combine fieldsToShow among all dataset ids
513
+ combined[key].fieldsToShow = toBeCombinedProps.map(function (p) {
514
+ return p.fieldsToShow;
515
+ }).reduce(function (acc, nextFieldsToShow) {
516
+ var _loop3 = function _loop3(nextDataIdKey) {
517
+ var nextTooltipFields = nextFieldsToShow[nextDataIdKey];
518
+ if (!acc[nextDataIdKey]) {
519
+ // if the dataset id is not present in the accumulator
520
+ // then add it with its tooltip fields
521
+ acc[nextDataIdKey] = nextTooltipFields;
522
+ } else {
523
+ // otherwise the dataset id is already present in the accumulator
524
+ // so only add the next tooltip fields for this dataset's array if they are not already present,
525
+ // using the tooltipField.name property for uniqueness
526
+ nextTooltipFields.forEach(function (nextTF) {
527
+ if (!acc[nextDataIdKey].find(function (_ref3) {
528
+ var name = _ref3.name;
529
+ return nextTF.name === name;
530
+ })) {
531
+ acc[nextDataIdKey].push(nextTF);
532
+ }
533
+ });
534
+ }
535
+ };
536
+ for (var nextDataIdKey in nextFieldsToShow) {
537
+ _loop3(nextDataIdKey);
538
+ }
539
+ return acc;
540
+ }, {});
541
+ }
542
+ if (key === 'brush') {
543
+ var _aggregate;
544
+ // keep the biggest brush size
545
+ combined[key].size = (_aggregate = aggregate(toBeCombinedProps, AGGREGATION_TYPES.maximum, function (p) {
546
+ return p.size;
547
+ })) !== null && _aggregate !== void 0 ? _aggregate : null;
548
+ }
549
+ if (key === 'geocoder') {
550
+ combined[key].limitSearch = toBeCombinedProps.some(function (p) {
551
+ return p === null || p === void 0 ? void 0 : p.limitSearch;
552
+ });
553
+ }
554
+ };
555
+ for (var key in combined) {
556
+ _loop2(key);
557
+ }
558
+ return combined;
559
+ }
560
+ function savedUnmergedInteraction(state, unmerged) {
561
+ var _unmerged$tooltip, _unmerged$tooltip2, _state$interactionToB, _unmerged$tooltip3;
562
+ if (!(unmerged !== null && unmerged !== void 0 && (_unmerged$tooltip = unmerged.tooltip) !== null && _unmerged$tooltip !== void 0 && _unmerged$tooltip.fieldsToShow)) {
563
+ return state.interactionToBeMerged;
564
+ }
565
+ return {
566
+ tooltip: _objectSpread(_objectSpread(_objectSpread({}, state.interactionToBeMerged.tooltip), typeof (unmerged === null || unmerged === void 0 || (_unmerged$tooltip2 = unmerged.tooltip) === null || _unmerged$tooltip2 === void 0 ? void 0 : _unmerged$tooltip2.enabled) === 'boolean' ? {
567
+ enabled: unmerged.tooltip.enabled
568
+ } : {}), {}, {
569
+ fieldsToShow: _objectSpread(_objectSpread({}, (_state$interactionToB = state.interactionToBeMerged) === null || _state$interactionToB === void 0 || (_state$interactionToB = _state$interactionToB.tooltip) === null || _state$interactionToB === void 0 ? void 0 : _state$interactionToB.fieldsToShow), unmerged === null || unmerged === void 0 || (_unmerged$tooltip3 = unmerged.tooltip) === null || _unmerged$tooltip3 === void 0 ? void 0 : _unmerged$tooltip3.fieldsToShow)
570
+ })
571
+ };
572
+ }
573
+ function replaceInteractionDatasetIds(interactionConfig, dataId, dataIdToReplace) {
574
+ var _interactionConfig$to;
575
+ if (interactionConfig !== null && interactionConfig !== void 0 && (_interactionConfig$to = interactionConfig.tooltip) !== null && _interactionConfig$to !== void 0 && _interactionConfig$to.fieldsToShow[dataId]) {
576
+ var _interactionConfig$to2;
577
+ return _objectSpread(_objectSpread({}, interactionConfig), {}, {
578
+ tooltip: _objectSpread(_objectSpread({}, interactionConfig.tooltip), {}, {
579
+ fieldsToShow: _defineProperty({}, dataIdToReplace, interactionConfig === null || interactionConfig === void 0 || (_interactionConfig$to2 = interactionConfig.tooltip) === null || _interactionConfig$to2 === void 0 ? void 0 : _interactionConfig$to2.fieldsToShow[dataId])
580
+ })
581
+ });
582
+ }
583
+ return null;
584
+ }
585
+
586
+ /**
587
+ * Merge splitMaps config with current visStete.
588
+ * 1. if current map is split, but splitMap DOESNOT contain maps
589
+ * : don't merge anything
590
+ * 2. if current map is NOT split, but splitMaps contain maps
591
+ * : add to splitMaps, and add current layers to splitMaps
592
+ */
593
+ export function mergeSplitMaps(state) {
594
+ var splitMaps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
595
+ var merged = _toConsumableArray(state.splitMaps);
596
+ var unmerged = [];
597
+ splitMaps.forEach(function (sm, i) {
598
+ var entries = Object.entries(sm.layers);
599
+ if (entries.length > 0) {
600
+ entries.forEach(function (_ref4) {
601
+ var _ref5 = _slicedToArray(_ref4, 2),
602
+ id = _ref5[0],
603
+ value = _ref5[1];
604
+ // check if layer exists
605
+ var pushTo = state.layers.find(function (l) {
606
+ return l.id === id;
607
+ }) ? merged : unmerged;
608
+
609
+ // create map panel if current map is not split
610
+ pushTo[i] = pushTo[i] || _objectSpread(_objectSpread({}, sm), {}, {
611
+ layers: pushTo === merged ? getInitialMapLayersForSplitMap(state.layers) : []
612
+ });
613
+ pushTo[i].layers = _objectSpread(_objectSpread({}, pushTo[i].layers), {}, _defineProperty({}, id, value));
614
+ });
615
+ } else {
616
+ // We are merging if there are no layers in both split map
617
+ merged.push(sm);
618
+ }
619
+ });
620
+ return _objectSpread(_objectSpread({}, state), {}, {
621
+ splitMaps: merged,
622
+ splitMapsToBeMerged: [].concat(_toConsumableArray(state.splitMapsToBeMerged), unmerged)
623
+ });
624
+ }
625
+
626
+ /**
627
+ * Merge effects with saved config
628
+ */
629
+ export function mergeEffects(state, effects, fromConfig) {
630
+ var newEffects = [].concat(_toConsumableArray(state.effects), _toConsumableArray((effects || []).map(function (effect) {
631
+ return fromConfig ? createEffect(deepmerge.all([effect, {
632
+ // collapse all panels when loading effects
633
+ isConfigActive: false
634
+ }])) : effect;
635
+ }).filter(function (effect) {
636
+ return Boolean(effect && effect.isValidToSave());
637
+ })));
638
+ return _objectSpread(_objectSpread({}, state), {}, {
639
+ effects: newEffects,
640
+ effectOrder: newEffects.map(function (effect) {
641
+ return effect.id;
642
+ })
643
+ });
644
+ }
645
+
646
+ /**
647
+ * Merge annotations with saved config
648
+ */
649
+ export function mergeAnnotations(state, annotations) {
650
+ if (!annotations || !annotations.length) {
651
+ return state;
652
+ }
653
+ var existingIds = new Set(state.annotations.map(function (a) {
654
+ return a.id;
655
+ }));
656
+ var validAnnotations = annotations.filter(function (a) {
657
+ return a && a.id && !existingIds.has(a.id) && isAnnotationKind(a.kind) && Array.isArray(a.anchorPoint) && a.anchorPoint.length === 2;
658
+ }).map(function (a) {
659
+ return _objectSpread({
660
+ isVisible: true,
661
+ autoSize: true,
662
+ autoSizeY: true,
663
+ label: '',
664
+ lineColor: INITIAL_ANNOTATION_LINE_COLOR,
665
+ lineWidth: INITIAL_ANNOTATION_LINE_WIDTH,
666
+ textWidth: 0,
667
+ textHeight: 0
668
+ }, a);
669
+ });
670
+ if (!validAnnotations.length) {
671
+ return state;
672
+ }
673
+ return _objectSpread(_objectSpread({}, state), {}, {
674
+ annotations: [].concat(_toConsumableArray(state.annotations), _toConsumableArray(validAnnotations))
675
+ });
676
+ }
677
+
678
+ /**
679
+ * Merge interactionConfig.tooltip with saved config,
680
+ * validate fieldsToShow
681
+ *
682
+ * @param state
683
+ * @param tooltipConfig
684
+ * @return - {mergedTooltip: {}, unmergedTooltip: {}}
685
+ */
686
+ export function mergeInteractionTooltipConfig(state) {
687
+ var tooltipConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
688
+ var unmergedTooltip = {};
689
+ var mergedTooltip = {};
690
+ if (!tooltipConfig || !tooltipConfig.fieldsToShow || !Object.keys(tooltipConfig.fieldsToShow).length) {
691
+ return {
692
+ mergedTooltip: mergedTooltip,
693
+ unmergedTooltip: unmergedTooltip
694
+ };
695
+ }
696
+ var _loop4 = function _loop4() {
697
+ if (!state.datasets[dataId] || state.isMergingDatasets[dataId]) {
698
+ // is not yet loaded
699
+ unmergedTooltip[dataId] = tooltipConfig.fieldsToShow[dataId];
700
+ } else {
701
+ // if dataset is loaded
702
+ var allFields = state.datasets[dataId].fields.map(function (d) {
703
+ return d.name;
704
+ });
705
+ var foundFieldsToShow = tooltipConfig.fieldsToShow[dataId].filter(function (field) {
706
+ return allFields.includes(field.name);
707
+ });
708
+ mergedTooltip[dataId] = foundFieldsToShow;
709
+ }
710
+ };
711
+ for (var dataId in tooltipConfig.fieldsToShow) {
712
+ _loop4();
713
+ }
714
+ return {
715
+ mergedTooltip: mergedTooltip,
716
+ unmergedTooltip: unmergedTooltip
717
+ };
718
+ }
719
+ /**
720
+ * Merge layerBlending with saved
721
+ *
722
+ */
723
+ export function mergeLayerBlending(state, layerBlending) {
724
+ if (layerBlending && LAYER_BLENDINGS[layerBlending]) {
725
+ return _objectSpread(_objectSpread({}, state), {}, {
726
+ layerBlending: layerBlending
727
+ });
728
+ }
729
+ return state;
730
+ }
731
+
732
+ /**
733
+ * Combines multiple layer blending configs into a single string
734
+ * by returning the one with the highest occurrence
735
+ */
736
+ function combineLayerBlendingConfigs(configs) {
737
+ // return the mode of the layer blending type
738
+ return getValueWithHighestOccurrence(configs);
739
+ }
740
+
741
+ /**
742
+ * Merge overlayBlending with saved
743
+ */
744
+ export function mergeOverlayBlending(state, overlayBlending) {
745
+ if (overlayBlending && OVERLAY_BLENDINGS[overlayBlending]) {
746
+ return _objectSpread(_objectSpread({}, state), {}, {
747
+ overlayBlending: overlayBlending
748
+ });
749
+ }
750
+ return state;
751
+ }
752
+
753
+ /**
754
+ * Combines multiple overlay blending configs into a single string
755
+ * by returning the one with the highest occurrence
756
+ **/
757
+ function combineOverlayBlendingConfigs(configs) {
758
+ // return the mode of the overlay blending type
759
+ return getValueWithHighestOccurrence(configs);
760
+ }
761
+
762
+ /**
763
+ * Merge animation config
764
+ */
765
+ export function mergeAnimationConfig(state, animation) {
766
+ if (animation && animation.currentTime) {
767
+ return _objectSpread(_objectSpread({}, state), {}, {
768
+ animationConfig: _objectSpread(_objectSpread(_objectSpread({}, state.animationConfig), animation), {}, {
769
+ domain: null
770
+ })
771
+ });
772
+ }
773
+ return state;
774
+ }
775
+ function combineAnimationConfigs(configs) {
776
+ var _aggregate2, _aggregate3;
777
+ // get the smallest values of currentTime and speed among all configs
778
+ return {
779
+ currentTime: (_aggregate2 = aggregate(configs, AGGREGATION_TYPES.minimum, function (c) {
780
+ return c.currentTime;
781
+ })) !== null && _aggregate2 !== void 0 ? _aggregate2 : null,
782
+ speed: (_aggregate3 = aggregate(configs, AGGREGATION_TYPES.minimum, function (c) {
783
+ return c.speed;
784
+ })) !== null && _aggregate3 !== void 0 ? _aggregate3 : null
785
+ };
786
+ }
787
+
788
+ /**
789
+ * Validate saved layer columns with new data,
790
+ * update fieldIdx based on new fields
791
+ *
792
+ * @param fields
793
+ * @param savedCols
794
+ * @param emptyCols
795
+ * @param options
796
+ * @return - validated columns or null
797
+ */
798
+
799
+ export function validateSavedLayerColumns(fields) {
800
+ var savedCols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
801
+ var emptyCols = arguments.length > 2 ? arguments[2] : undefined;
802
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
803
+ // Prepare columns for the validator
804
+ var columns = {};
805
+ var _loop5 = function _loop5() {
806
+ var key = _Object$keys[_i];
807
+ columns[key] = _objectSpread({}, emptyCols[key]);
808
+ var saved = savedCols[key];
809
+ if (saved) {
810
+ var fieldIdx = fields.findIndex(function (_ref6) {
811
+ var name = _ref6.name;
812
+ return name === saved;
813
+ });
814
+ if (fieldIdx > -1) {
815
+ // update found columns
816
+ columns[key].fieldIdx = fieldIdx;
817
+ columns[key].value = saved;
818
+ }
819
+ }
820
+ };
821
+ for (var _i = 0, _Object$keys = Object.keys(emptyCols); _i < _Object$keys.length; _i++) {
822
+ _loop5();
823
+ }
824
+
825
+ // find actual column fieldIdx, in case it has changed
826
+ var allColFound = Object.keys(columns).every(function (key) {
827
+ return validateColumn(columns[key], columns, fields);
828
+ });
829
+ var rv = allColFound ? columns : null;
830
+ if (options.throwOnError) {
831
+ var requiredColumns = Object.keys(emptyCols).filter(function (k) {
832
+ return !emptyCols[k].optional;
833
+ });
834
+ var missingColumns = requiredColumns.filter(function (k) {
835
+ return !(columns !== null && columns !== void 0 && columns[k].value);
836
+ });
837
+ if (missingColumns.length) {
838
+ throw new Error("Layer has missing or invalid columns: ".concat(missingColumns.join(', ')));
839
+ }
840
+ var configColumns = Object.keys(savedCols);
841
+ var invalidColumns = configColumns.filter(function (k) {
842
+ var _columns$k;
843
+ return !(columns !== null && columns !== void 0 && (_columns$k = columns[k]) !== null && _columns$k !== void 0 && _columns$k.value);
844
+ });
845
+ if (invalidColumns.length) {
846
+ throw new Error("Layer has invalid columns: ".concat(invalidColumns.join(', ')));
847
+ }
848
+ }
849
+ return rv;
850
+ }
851
+
852
+ /**
853
+ * Validate layer column
854
+ */
855
+ export function validateColumn(column, columns, allFields) {
856
+ if (column.optional || column.value) {
857
+ return true;
858
+ }
859
+ if (column.validator) {
860
+ return column.validator(column, columns, allFields);
861
+ }
862
+ return false;
863
+ }
864
+
865
+ /**
866
+ * Validate saved text label config with new data
867
+ * refer to vis-state-schema.js TextLabelSchemaV1
868
+ *
869
+ * @param {Array<Object>} fields
870
+ * @param {Object} savedTextLabel
871
+ * @param {Object} options
872
+ * @return {Object} - validated textlabel
873
+ */
874
+ export function validateSavedTextLabel(fields, _ref7, savedTextLabel) {
875
+ var _ref8 = _slicedToArray(_ref7, 1),
876
+ layerTextLabel = _ref8[0];
877
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
878
+ var savedTextLabels = Array.isArray(savedTextLabel) ? savedTextLabel : [savedTextLabel];
879
+
880
+ // validate field
881
+ return savedTextLabels.map(function (textLabel) {
882
+ var field = textLabel.field ? fields.find(function (fd) {
883
+ return Object.keys(textLabel.field).every(function (key) {
884
+ return textLabel.field[key] === fd[key];
885
+ });
886
+ }) : null;
887
+ if (field === undefined && options.throwOnError) {
888
+ throw new Error("Layer has invalid text label field: ".concat(JSON.stringify(textLabel.field)));
889
+ }
890
+ return Object.keys(layerTextLabel).reduce(function (accu, key) {
891
+ return _objectSpread(_objectSpread({}, accu), {}, _defineProperty({}, key, key === 'field' ? field : textLabel[key] || layerTextLabel[key]));
892
+ }, {});
893
+ });
894
+ }
895
+
896
+ /**
897
+ * Validate saved visual channels config with new data,
898
+ * refer to vis-state-schema.js VisualChannelSchemaV1
899
+ */
900
+ export function validateSavedVisualChannels(fields, newLayer, savedLayer) {
901
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
902
+ Object.values(newLayer.visualChannels).forEach(function (_ref9) {
903
+ var field = _ref9.field,
904
+ scale = _ref9.scale,
905
+ key = _ref9.key;
906
+ var foundField;
907
+ if (savedLayer.config) {
908
+ if (savedLayer.config[field]) {
909
+ foundField = fields.find(function (fd) {
910
+ return savedLayer.config && fd.name === savedLayer.config[field].name;
911
+ });
912
+ }
913
+ var foundChannel = _objectSpread(_objectSpread({}, foundField ? _defineProperty({}, field, foundField) : {}), savedLayer.config[scale] ? _defineProperty({}, scale, savedLayer.config[scale]) : {});
914
+ if (Object.keys(foundChannel).length) {
915
+ newLayer.updateLayerConfig(foundChannel);
916
+ }
917
+ newLayer.validateVisualChannel(key);
918
+ if (options.throwOnError) {
919
+ var _savedLayer$config, _newLayer$config$fiel;
920
+ var fieldName = (_savedLayer$config = savedLayer.config) === null || _savedLayer$config === void 0 || (_savedLayer$config = _savedLayer$config[field]) === null || _savedLayer$config === void 0 ? void 0 : _savedLayer$config.name;
921
+ if (fieldName && fieldName !== ((_newLayer$config$fiel = newLayer.config[field]) === null || _newLayer$config$fiel === void 0 ? void 0 : _newLayer$config$fiel.name)) {
922
+ throw new Error("Layer has invalid visual channel field: ".concat(field));
923
+ }
924
+ }
925
+ }
926
+ });
927
+ return newLayer;
928
+ }
929
+ export function validateLayersByDatasets(datasets, layerClasses) {
930
+ var layers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
931
+ var options = arguments.length > 3 ? arguments[3] : undefined;
932
+ var validated = [];
933
+ var failed = [];
934
+ layers.forEach(function (layer) {
935
+ var _layer$config;
936
+ var validateLayer = null;
937
+ if (layer !== null && layer !== void 0 && (_layer$config = layer.config) !== null && _layer$config !== void 0 && _layer$config.dataId) {
938
+ if (datasets[layer.config.dataId]) {
939
+ // datasets are already loaded
940
+ validateLayer = validateLayerWithData(datasets[layer.config.dataId], layer, layerClasses, options);
941
+ }
942
+ }
943
+ if (validateLayer) {
944
+ validated.push(validateLayer);
945
+ } else {
946
+ // datasets not yet loaded
947
+ failed.push(layer);
948
+ }
949
+ });
950
+ return {
951
+ validated: validated,
952
+ failed: failed
953
+ };
954
+ }
955
+
956
+ /**
957
+ * Get required columns for validation based on column mode
958
+ */
959
+ function _getColumnConfigForValidation(newLayer) {
960
+ // find column fieldIdx
961
+ var columnConfig = newLayer.getLayerColumns();
962
+ // if columnMode is defined, find column mode config
963
+ var colModeConfig = newLayer.config.columnMode ? (newLayer.supportedColumnModes || []).find(function (colMode) {
964
+ return colMode.key === newLayer.config.columnMode;
965
+ }) : null;
966
+ if (colModeConfig) {
967
+ // only validate columns in column mode
968
+ columnConfig = [].concat(_toConsumableArray(colModeConfig.requiredColumns || []), _toConsumableArray(colModeConfig.optionalColumns || [])).reduce(function (accu, key) {
969
+ return _objectSpread(_objectSpread({}, accu), {}, _defineProperty({}, key, columnConfig[key]));
970
+ }, {});
971
+ }
972
+ return columnConfig;
973
+ }
974
+
975
+ /**
976
+ * Validate saved layer config with new data,
977
+ * update fieldIdx based on new fields
978
+ */
979
+ // eslint-disable-next-line complexity
980
+ export function validateLayerWithData(dataset, savedLayer, layerClasses) {
981
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
982
+ var fields = dataset.fields,
983
+ dataId = dataset.id;
984
+ var type = savedLayer.type;
985
+ var throwOnError = options.throwOnError;
986
+ // layer doesnt have a valid type
987
+ if (!type || !Object.prototype.hasOwnProperty.call(layerClasses, type) || !savedLayer.config) {
988
+ if (throwOnError) {
989
+ throw new Error("Layer has invalid type \"".concat(type, "\" or config is missing"));
990
+ }
991
+ return null;
992
+ }
993
+ var newLayer = new layerClasses[type]({
994
+ id: savedLayer.id,
995
+ dataId: dataId,
996
+ label: savedLayer.config.label,
997
+ color: savedLayer.config.color,
998
+ isVisible: savedLayer.config.isVisible,
999
+ hidden: savedLayer.config.hidden,
1000
+ columnMode: savedLayer.config.columnMode,
1001
+ highlightColor: savedLayer.config.highlightColor
1002
+ });
1003
+ var columnConfig = _getColumnConfigForValidation(newLayer);
1004
+ if (Object.keys(columnConfig)) {
1005
+ var columns = validateSavedLayerColumns(fields, savedLayer.config.columns, columnConfig, options);
1006
+ if (columns) {
1007
+ newLayer.updateLayerConfig({
1008
+ columns: _objectSpread(_objectSpread({}, newLayer.config.columns), columns)
1009
+ });
1010
+ } else if (!options.allowEmptyColumn) {
1011
+ return null;
1012
+ }
1013
+ }
1014
+ var textLabel = savedLayer.config.textLabel && newLayer.config.textLabel ? validateSavedTextLabel(fields, newLayer.config.textLabel, savedLayer.config.textLabel, options) : newLayer.config.textLabel;
1015
+
1016
+ // copy visConfig over to emptyLayer to make sure it has all the props
1017
+ var copiedVisConfig = newLayer.copyLayerConfig(newLayer.config.visConfig, savedLayer.config.visConfig || {}, {
1018
+ shallowCopy: ['colorRange', 'strokeColorRange']
1019
+ });
1020
+
1021
+ // call layer methods to validate visConfig when switching dataset
1022
+ var visConfig = newLayer.validateVisConfig ? newLayer.validateVisConfig(dataset, copiedVisConfig) : copiedVisConfig;
1023
+ newLayer.updateLayerConfig({
1024
+ visConfig: visConfig,
1025
+ textLabel: textLabel
1026
+ });
1027
+
1028
+ // visual channel field is saved to be {name, type}
1029
+ // find visual channel field by matching both name and type
1030
+ // refer to vis-state-schema.js VisualChannelSchemaV1
1031
+ newLayer = validateSavedVisualChannels(fields, newLayer, savedLayer, options);
1032
+ if (throwOnError) {
1033
+ if (!newLayer.isValidToSave()) {
1034
+ throw new Error("Layer is not valid to save: ".concat(newLayer.id));
1035
+ }
1036
+ }
1037
+ return newLayer;
1038
+ }
1039
+ export function mergeEditor(state, savedEditor) {
1040
+ var _savedEditor$visible;
1041
+ if (!savedEditor) {
1042
+ return state;
1043
+ }
1044
+ return _objectSpread(_objectSpread({}, state), {}, {
1045
+ editor: _objectSpread(_objectSpread({}, state.editor), {}, {
1046
+ features: [].concat(_toConsumableArray(state.editor.features), _toConsumableArray(savedEditor.features || [])),
1047
+ // if savedEditor.visible is undefined keep state.editor.visible
1048
+ visible: (_savedEditor$visible = savedEditor.visible) !== null && _savedEditor$visible !== void 0 ? _savedEditor$visible : state.editor.visible
1049
+ })
1050
+ });
1051
+ }
1052
+ function combineEditorConfigs(configs) {
1053
+ return configs.reduce(function (acc, nextConfig) {
1054
+ return _objectSpread(_objectSpread({}, acc), {}, {
1055
+ features: [].concat(_toConsumableArray(acc.features), _toConsumableArray(nextConfig.features || []))
1056
+ });
1057
+ }, {
1058
+ // start with:
1059
+ // - empty array for features accumulation
1060
+ // - and are any of the configs' visible values true?
1061
+ features: [],
1062
+ visible: configs.some(function (c) {
1063
+ return c === null || c === void 0 ? void 0 : c.visible;
1064
+ })
1065
+ });
1066
+ }
1067
+
1068
+ /**
1069
+ * Validate saved layer config with new data,
1070
+ * update fieldIdx based on new fields
1071
+ */
1072
+ export function mergeDatasetsByOrder(state, newDataEntries) {
1073
+ var merged = _objectSpread(_objectSpread({}, state.datasets), newDataEntries);
1074
+ if (Array.isArray(state.preserveDatasetOrder)) {
1075
+ // preserveDatasetOrder might not include the new datasets
1076
+ var newDatasetIds = Object.keys(merged).filter(function (id) {
1077
+ var _state$preserveDatase;
1078
+ return !((_state$preserveDatase = state.preserveDatasetOrder) !== null && _state$preserveDatase !== void 0 && _state$preserveDatase.includes(id));
1079
+ });
1080
+ return [].concat(_toConsumableArray(state.preserveDatasetOrder), _toConsumableArray(newDatasetIds)).reduce(function (accu, dataId) {
1081
+ return _objectSpread(_objectSpread({}, accu), merged[dataId] ? _defineProperty({}, dataId, merged[dataId]) : {});
1082
+ }, {});
1083
+ }
1084
+ return merged;
1085
+ }
1086
+
1087
+ /**
1088
+ * Simliar purpose to aggregation utils `getMode` function,
1089
+ * but returns the mode in the same value type without coercing to a string.
1090
+ * It ignores `undefined` or `null` values, but returns `null` if no mode could be calculated.
1091
+ */
1092
+ function getValueWithHighestOccurrence(arr) {
1093
+ var _ref11;
1094
+ var tallys = new Map();
1095
+ arr.forEach(function (value) {
1096
+ if (notNullorUndefined(value)) {
1097
+ if (!tallys.has(value)) {
1098
+ tallys.set(value, 1);
1099
+ } else {
1100
+ tallys.set(value, tallys.get(value) + 1);
1101
+ }
1102
+ }
1103
+ });
1104
+ // return the value with the highest total occurrence count
1105
+ if (tallys.size === 0) {
1106
+ return null;
1107
+ }
1108
+ return (_ref11 = _toConsumableArray(tallys.entries())) === null || _ref11 === void 0 ? void 0 : _ref11.reduce(function (acc, next) {
1109
+ return next[1] > acc[1] ? next : acc;
1110
+ })[0];
1111
+ }
1112
+ export var VIS_STATE_MERGERS = [{
1113
+ merge: mergeLayers,
1114
+ prop: 'layers',
1115
+ toMergeProp: 'layerToBeMerged',
1116
+ preserveOrder: 'preserveLayerOrder'
1117
+ }, {
1118
+ merge: mergeLayerOrder,
1119
+ prop: 'layerOrder'
1120
+ }, {
1121
+ merge: mergeFilters,
1122
+ prop: 'filters',
1123
+ toMergeProp: 'filterToBeMerged',
1124
+ preserveOrder: 'preserveFilterOrder',
1125
+ replaceParentDatasetIds: replaceFilterDatasetIds
1126
+ }, {
1127
+ merge: mergeEffects,
1128
+ prop: 'effects'
1129
+ }, {
1130
+ merge: mergeAnnotations,
1131
+ prop: 'annotations',
1132
+ toMergeProp: 'annotationsToBeMerged'
1133
+ }, {
1134
+ merge: mergeInteractions,
1135
+ prop: 'interactionConfig',
1136
+ toMergeProp: 'interactionToBeMerged',
1137
+ replaceParentDatasetIds: replaceInteractionDatasetIds,
1138
+ saveUnmerged: savedUnmergedInteraction,
1139
+ combineConfigs: combineInteractionConfigs
1140
+ }, {
1141
+ merge: mergeLayerBlending,
1142
+ prop: 'layerBlending',
1143
+ combineConfigs: combineLayerBlendingConfigs
1144
+ }, {
1145
+ merge: mergeOverlayBlending,
1146
+ prop: 'overlayBlending',
1147
+ combineConfigs: combineOverlayBlendingConfigs
1148
+ }, {
1149
+ merge: mergeSplitMaps,
1150
+ prop: 'splitMaps',
1151
+ toMergeProp: 'splitMapsToBeMerged'
1152
+ }, {
1153
+ merge: mergeAnimationConfig,
1154
+ prop: 'animationConfig',
1155
+ combineConfigs: combineAnimationConfigs
1156
+ }, {
1157
+ merge: mergeEditor,
1158
+ prop: 'editor',
1159
+ combineConfigs: combineEditorConfigs
1160
+ }];
1161
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1bmlxIiwicGljayIsImZsYXR0ZW5EZWVwIiwiZGVlcG1lcmdlIiwiYXJyYXlJbnNlcnQiLCJnZXRJbml0aWFsTWFwTGF5ZXJzRm9yU3BsaXRNYXAiLCJhcHBseUZpbHRlcnNUb0RhdGFzZXRzIiwidmFsaWRhdGVGaWx0ZXJzVXBkYXRlRGF0YXNldHMiLCJmaW5kQnlJZCIsImFnZ3JlZ2F0ZSIsImlzUGxhaW5PYmplY3QiLCJjcmVhdGVFZmZlY3QiLCJub3ROdWxsb3JVbmRlZmluZWQiLCJBR0dSRUdBVElPTl9UWVBFUyIsIkxBWUVSX0JMRU5ESU5HUyIsIk9WRVJMQVlfQkxFTkRJTkdTIiwiaXNBbm5vdGF0aW9uS2luZCIsIklOSVRJQUxfQU5OT1RBVElPTl9MSU5FX0NPTE9SIiwiSU5JVElBTF9BTk5PVEFUSU9OX0xJTkVfV0lEVEgiLCJDVVJSRU5UX1ZFUlNJT04iLCJhc3NpZ25HcHVDaGFubmVscyIsInJlc2V0RmlsdGVyR3B1TW9kZSIsImdldExheWVyT3JkZXJGcm9tTGF5ZXJzIiwibWVyZ2VGaWx0ZXJzIiwic3RhdGUiLCJmaWx0ZXJzVG9NZXJnZSIsImZyb21Db25maWciLCJwcmVzZXJ2ZUZpbHRlck9yZGVyIiwibWFwIiwibCIsImlkIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiX3ZhbGlkYXRlRmlsdGVyc1VwZGF0IiwidmFsaWRhdGVkIiwiZmFpbGVkIiwidXBkYXRlZERhdGFzZXRzIiwidXBkYXRlZEZpbHRlcnMiLCJpbnNlcnRJdGVtQmFzZWRPblByZXNlcnZlZE9yZGVyIiwiZmlsdGVycyIsImRhdGFzZXRzVG9GaWx0ZXIiLCJmIiwiZGF0YUlkIiwiZmlsdGVyZWQiLCJsYXllcnMiLCJfb2JqZWN0U3ByZWFkIiwiZGF0YXNldHMiLCJmaWx0ZXJUb0JlTWVyZ2VkIiwiY29uY2F0IiwiX3RvQ29uc3VtYWJsZUFycmF5IiwicmVwbGFjZUZpbHRlckRhdGFzZXRJZHMiLCJzYXZlZEZpbHRlciIsImRhdGFJZFRvVXNlIiwicmVwbGFjZWQiLCJmb3JFYWNoIiwiZmlsdGVyIiwiaW5jbHVkZXMiLCJfZmlsdGVyJHBsb3RUeXBlIiwibmV3RGF0YUlkIiwiZCIsInBsb3RUeXBlIiwiY29sb3JzQnlEYXRhSWQiLCJfZmlsdGVyJHBsb3RUeXBlMiIsIl9yZWYiLCJjb2xvciIsInJlc3QiLCJfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMiLCJfdG9Qcm9wZXJ0eUtleSIsIl9kZWZpbmVQcm9wZXJ0eSIsInB1c2giLCJpc1NhdmVkTGF5ZXJDb25maWdWMSIsImxheWVyQ29uZmlnIiwidmlzdWFsQ2hhbm5lbHMiLCJwYXJzZUxheWVyQ29uZmlnIiwic2NoZW1hIiwiX3NjaGVtYSRwYXJzZVNhdmVkQ29uIiwic2F2ZWRDb25maWciLCJ2ZXJzaW9uIiwiY29uZmlnIiwidmlzU3RhdGUiLCJsYXllck9yZGVyIiwicGFyc2VTYXZlZENvbmZpZyIsImN1cnJlbnRJdGVtcyIsIml0ZW1zIiwicHJlc2VydmVkT3JkZXIiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJkZWZhdWx0U3RhcnQiLCJuZXdJdGVtcyIsIl9pdGVyYXRvciIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiX3N0ZXAiLCJzIiwibiIsImRvbmUiLCJpdGVtIiwidmFsdWUiLCJleHBlY3RlZElkeCIsImluZGV4T2YiLCJpbnNlcnRBdCIsImkiLCJwcmVjZWVkSWR4IiwiX2xvb3AiLCJwcmVjZWVkSXRlbUlkIiwiZmluZEluZGV4IiwiZXJyIiwiZSIsImNyZWF0ZUxheWVyRnJvbUNvbmZpZyIsInBhcnNlZExheWVyQ29uZmlnIiwiX3ZhbGlkYXRlTGF5ZXJzQnlEYXRhIiwidmFsaWRhdGVMYXllcnNCeURhdGFzZXRzIiwibGF5ZXJDbGFzc2VzIiwiYWxsb3dFbXB0eUNvbHVtbiIsIm5ld0xheWVyIiwidXBkYXRlTGF5ZXJEb21haW4iLCJzZXJpYWxpemVGaWx0ZXIiLCJuZXdGaWx0ZXIiLCJfc2VyaWFsaXplZFZpc1N0YXRlJGYiLCJzZXJpYWxpemVkVmlzU3RhdGUiLCJzZXJpYWxpemVWaXNTdGF0ZSIsInNlcmlhbGl6ZUxheWVyIiwiX3NlcmlhbGl6ZWRWaXNTdGF0ZSRsIiwic2VyaWFsaXplRWZmZWN0IiwibmV3RWZmZWN0IiwiX3NlcmlhbGl6ZWRWaXNTdGF0ZSRlIiwiZWZmZWN0cyIsImVmZmVjdE9yZGVyIiwiX3NjaGVtYSRwYXJzZVNhdmVkQ29uMiIsInNhdmVkU3RhdGUiLCJnZXRDb25maWdUb1NhdmUiLCJtZXJnZUxheWVycyIsImxheWVyc1RvTWVyZ2UiLCJwcmVzZXJ2ZUxheWVyT3JkZXIiLCJ1bm1lcmdlZCIsInRvTWVyZ2UiLCJfbCRjb25maWciLCJpc01lcmdpbmdEYXRhc2V0cyIsIl92YWxpZGF0ZUxheWVyc0J5RGF0YTIiLCJtZXJnZWRMYXllciIsImFwcGx5IiwiX2luc2VydExheWVyQXRSaWdodE9yIiwiaW5zZXJ0TGF5ZXJBdFJpZ2h0T3JkZXIiLCJuZXdMYXllck9yZGVyIiwibmV3TGF5ZXJzIiwibWVyZ2VkU3RhdGUiLCJsYXllclRvQmVNZXJnZWQiLCJsYXllck9yZGVyVG9CZU1lcmdlZCIsInNhdmVkT3JkZXIiLCJtZXJnZUxheWVyT3JkZXIiLCJjdXJyZW50TGF5ZXJzIiwibGF5ZXJzVG9JbnNlcnQiLCJjdXJyZW50T3JkZXIiLCJjdXJyZW50TGF5ZXJRdWV1ZSIsImVudHJ5IiwibGF5ZXIiLCJCb29sZWFuIiwibmV3TGF5ZXJPcmRlclF1ZXVlIiwibmV3RmxhdExheWVyT3JkZXIiLCJoYXNHcm91cHMiLCJzb21lIiwiZXhpc3RpbmdGbGF0SWRzIiwiU2V0IiwibmV3SW5zZXJ0ZWRJZHMiLCJoYXMiLCJyZXN1bHQiLCJmbGF0UXVldWUiLCJmbGF0SWR4IiwiX2l0ZXJhdG9yMiIsIl9zdGVwMiIsInNhdmVkTGF5ZXJPcmRlciIsInZhbGlkTGF5ZXJJZHMiLCJmaWx0ZXJMYXllck9yZGVyIiwib3JkZXIiLCJfaXRlcmF0b3IzIiwiX3N0ZXAzIiwiZ3JvdXAiLCJmaWx0ZXJlZEdyb3VwT3JkZXIiLCJyZXN0b3JlZExheWVyT3JkZXIiLCJsYXllcklkc0luUmVzdG9yZWQiLCJjb2xsZWN0SWRzIiwiX2l0ZXJhdG9yNCIsIl9zdGVwNCIsImFkZCIsIm1pc3NpbmdMYXllcnMiLCJtZXJnZUludGVyYWN0aW9ucyIsImludGVyYWN0aW9uVG9CZU1lcmdlZCIsIm1lcmdlZCIsIk9iamVjdCIsImtleXMiLCJrZXkiLCJpbnRlcmFjdGlvbkNvbmZpZyIsImN1cnJlbnRDb25maWciLCJfcmVmMiIsImVuYWJsZWQiLCJjb25maWdTYXZlZCIsIl9leGNsdWRlZCIsImNvbmZpZ1RvTWVyZ2UiLCJfbWVyZ2VJbnRlcmFjdGlvblRvb2wiLCJtZXJnZUludGVyYWN0aW9uVG9vbHRpcENvbmZpZyIsIm1lcmdlZFRvb2x0aXAiLCJ1bm1lcmdlZFRvb2x0aXAiLCJmaWVsZHNUb1Nob3ciLCJ0b29sdGlwIiwibmV4dFN0YXRlIiwic2F2ZWRVbm1lcmdlZEludGVyYWN0aW9uIiwiY29tYmluZUludGVyYWN0aW9uQ29uZmlncyIsImNvbmZpZ3MiLCJjb21iaW5lZCIsIl9sb29wMiIsInRvQmVDb21iaW5lZFByb3BzIiwiYyIsInAiLCJjb21wYXJlTW9kZSIsImNvbXBhcmVUeXBlIiwiZ2V0VmFsdWVXaXRoSGlnaGVzdE9jY3VycmVuY2UiLCJyZWR1Y2UiLCJhY2MiLCJuZXh0RmllbGRzVG9TaG93IiwiX2xvb3AzIiwibmV4dERhdGFJZEtleSIsIm5leHRUb29sdGlwRmllbGRzIiwibmV4dFRGIiwiZmluZCIsIl9yZWYzIiwibmFtZSIsIl9hZ2dyZWdhdGUiLCJzaXplIiwibWF4aW11bSIsImxpbWl0U2VhcmNoIiwiX3VubWVyZ2VkJHRvb2x0aXAiLCJfdW5tZXJnZWQkdG9vbHRpcDIiLCJfc3RhdGUkaW50ZXJhY3Rpb25Ub0IiLCJfdW5tZXJnZWQkdG9vbHRpcDMiLCJyZXBsYWNlSW50ZXJhY3Rpb25EYXRhc2V0SWRzIiwiZGF0YUlkVG9SZXBsYWNlIiwiX2ludGVyYWN0aW9uQ29uZmlnJHRvIiwiX2ludGVyYWN0aW9uQ29uZmlnJHRvMiIsIm1lcmdlU3BsaXRNYXBzIiwic3BsaXRNYXBzIiwic20iLCJlbnRyaWVzIiwiX3JlZjQiLCJfcmVmNSIsIl9zbGljZWRUb0FycmF5IiwicHVzaFRvIiwic3BsaXRNYXBzVG9CZU1lcmdlZCIsIm1lcmdlRWZmZWN0cyIsIm5ld0VmZmVjdHMiLCJlZmZlY3QiLCJhbGwiLCJpc0NvbmZpZ0FjdGl2ZSIsImlzVmFsaWRUb1NhdmUiLCJtZXJnZUFubm90YXRpb25zIiwiYW5ub3RhdGlvbnMiLCJleGlzdGluZ0lkcyIsImEiLCJ2YWxpZEFubm90YXRpb25zIiwia2luZCIsImFuY2hvclBvaW50IiwiaXNWaXNpYmxlIiwiYXV0b1NpemUiLCJhdXRvU2l6ZVkiLCJsYWJlbCIsImxpbmVDb2xvciIsImxpbmVXaWR0aCIsInRleHRXaWR0aCIsInRleHRIZWlnaHQiLCJ0b29sdGlwQ29uZmlnIiwiX2xvb3A0IiwiYWxsRmllbGRzIiwiZmllbGRzIiwiZm91bmRGaWVsZHNUb1Nob3ciLCJmaWVsZCIsIm1lcmdlTGF5ZXJCbGVuZGluZyIsImxheWVyQmxlbmRpbmciLCJjb21iaW5lTGF5ZXJCbGVuZGluZ0NvbmZpZ3MiLCJtZXJnZU92ZXJsYXlCbGVuZGluZyIsIm92ZXJsYXlCbGVuZGluZyIsImNvbWJpbmVPdmVybGF5QmxlbmRpbmdDb25maWdzIiwibWVyZ2VBbmltYXRpb25Db25maWciLCJhbmltYXRpb24iLCJjdXJyZW50VGltZSIsImFuaW1hdGlvbkNvbmZpZyIsImRvbWFpbiIsImNvbWJpbmVBbmltYXRpb25Db25maWdzIiwiX2FnZ3JlZ2F0ZTIiLCJfYWdncmVnYXRlMyIsIm1pbmltdW0iLCJzcGVlZCIsInZhbGlkYXRlU2F2ZWRMYXllckNvbHVtbnMiLCJzYXZlZENvbHMiLCJlbXB0eUNvbHMiLCJvcHRpb25zIiwiY29sdW1ucyIsIl9sb29wNSIsIl9PYmplY3Qka2V5cyIsIl9pIiwic2F2ZWQiLCJmaWVsZElkeCIsIl9yZWY2IiwiYWxsQ29sRm91bmQiLCJldmVyeSIsInZhbGlkYXRlQ29sdW1uIiwicnYiLCJ0aHJvd09uRXJyb3IiLCJyZXF1aXJlZENvbHVtbnMiLCJrIiwib3B0aW9uYWwiLCJtaXNzaW5nQ29sdW1ucyIsIkVycm9yIiwiam9pbiIsImNvbmZpZ0NvbHVtbnMiLCJpbnZhbGlkQ29sdW1ucyIsIl9jb2x1bW5zJGsiLCJjb2x1bW4iLCJ2YWxpZGF0b3IiLCJ2YWxpZGF0ZVNhdmVkVGV4dExhYmVsIiwiX3JlZjciLCJzYXZlZFRleHRMYWJlbCIsIl9yZWY4IiwibGF5ZXJUZXh0TGFiZWwiLCJzYXZlZFRleHRMYWJlbHMiLCJ0ZXh0TGFiZWwiLCJmZCIsIkpTT04iLCJzdHJpbmdpZnkiLCJhY2N1IiwidmFsaWRhdGVTYXZlZFZpc3VhbENoYW5uZWxzIiwic2F2ZWRMYXllciIsInZhbHVlcyIsIl9yZWY5Iiwic2NhbGUiLCJmb3VuZEZpZWxkIiwiZm91bmRDaGFubmVsIiwidXBkYXRlTGF5ZXJDb25maWciLCJ2YWxpZGF0ZVZpc3VhbENoYW5uZWwiLCJfc2F2ZWRMYXllciRjb25maWciLCJfbmV3TGF5ZXIkY29uZmlnJGZpZWwiLCJmaWVsZE5hbWUiLCJfbGF5ZXIkY29uZmlnIiwidmFsaWRhdGVMYXllciIsInZhbGlkYXRlTGF5ZXJXaXRoRGF0YSIsIl9nZXRDb2x1bW5Db25maWdGb3JWYWxpZGF0aW9uIiwiY29sdW1uQ29uZmlnIiwiZ2V0TGF5ZXJDb2x1bW5zIiwiY29sTW9kZUNvbmZpZyIsImNvbHVtbk1vZGUiLCJzdXBwb3J0ZWRDb2x1bW5Nb2RlcyIsImNvbE1vZGUiLCJvcHRpb25hbENvbHVtbnMiLCJkYXRhc2V0IiwidHlwZSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhpZGRlbiIsImhpZ2hsaWdodENvbG9yIiwiY29waWVkVmlzQ29uZmlnIiwiY29weUxheWVyQ29uZmlnIiwidmlzQ29uZmlnIiwic2hhbGxvd0NvcHkiLCJ2YWxpZGF0ZVZpc0NvbmZpZyIsIm1lcmdlRWRpdG9yIiwic2F2ZWRFZGl0b3IiLCJfc2F2ZWRFZGl0b3IkdmlzaWJsZSIsImVkaXRvciIsImZlYXR1cmVzIiwidmlzaWJsZSIsImNvbWJpbmVFZGl0b3JDb25maWdzIiwibmV4dENvbmZpZyIsIm1lcmdlRGF0YXNldHNCeU9yZGVyIiwibmV3RGF0YUVudHJpZXMiLCJwcmVzZXJ2ZURhdGFzZXRPcmRlciIsIm5ld0RhdGFzZXRJZHMiLCJfc3RhdGUkcHJlc2VydmVEYXRhc2UiLCJhcnIiLCJfcmVmMTEiLCJ0YWxseXMiLCJNYXAiLCJzZXQiLCJnZXQiLCJuZXh0IiwiVklTX1NUQVRFX01FUkdFUlMiLCJtZXJnZSIsInByb3AiLCJ0b01lcmdlUHJvcCIsInByZXNlcnZlT3JkZXIiLCJyZXBsYWNlUGFyZW50RGF0YXNldElkcyIsInNhdmVVbm1lcmdlZCIsImNvbWJpbmVDb25maWdzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Zpcy1zdGF0ZS1tZXJnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHVuaXEgZnJvbSAnZXMtdG9vbGtpdC9jb21wYXQvdW5pcSc7XG5pbXBvcnQgcGljayBmcm9tICdlcy10b29sa2l0L2NvbXBhdC9waWNrJztcbmltcG9ydCBmbGF0dGVuRGVlcCBmcm9tICdlcy10b29sa2l0L2NvbXBhdC9mbGF0dGVuRGVlcCc7XG5pbXBvcnQgZGVlcG1lcmdlIGZyb20gJ2RlZXBtZXJnZSc7XG5pbXBvcnQge1xuICBhcnJheUluc2VydCxcbiAgZ2V0SW5pdGlhbE1hcExheWVyc0ZvclNwbGl0TWFwLFxuICBhcHBseUZpbHRlcnNUb0RhdGFzZXRzLFxuICB2YWxpZGF0ZUZpbHRlcnNVcGRhdGVEYXRhc2V0cyxcbiAgZmluZEJ5SWQsXG4gIGFnZ3JlZ2F0ZSxcbiAgaXNQbGFpbk9iamVjdFxufSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IHtMYXllcn0gZnJvbSAnQGtlcGxlci5nbC9sYXllcnMnO1xuaW1wb3J0IHtjcmVhdGVFZmZlY3R9IGZyb20gJ0BrZXBsZXIuZ2wvZWZmZWN0cyc7XG5pbXBvcnQge25vdE51bGxvclVuZGVmaW5lZH0gZnJvbSAnQGtlcGxlci5nbC9jb21tb24tdXRpbHMnO1xuaW1wb3J0IHtcbiAgQUdHUkVHQVRJT05fVFlQRVMsXG4gIExBWUVSX0JMRU5ESU5HUyxcbiAgT1ZFUkxBWV9CTEVORElOR1MsXG4gIGlzQW5ub3RhdGlvbktpbmQsXG4gIElOSVRJQUxfQU5OT1RBVElPTl9MSU5FX0NPTE9SLFxuICBJTklUSUFMX0FOTk9UQVRJT05fTElORV9XSURUSFxufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge0NVUlJFTlRfVkVSU0lPTiwgVmlzU3RhdGUsIFZpc1N0YXRlTWVyZ2VycywgS2VwbGVyR0xTY2hlbWFDbGFzc30gZnJvbSAnQGtlcGxlci5nbC9zY2hlbWFzJztcblxuaW1wb3J0IHtcbiAgUGFyc2VkTGF5ZXIsXG4gIFBhcnNlZFZpc1N0YXRlLFxuICBTYXZlZEludGVyYWN0aW9uQ29uZmlnLFxuICBUb29sdGlwSW5mbyxcbiAgU2F2ZWRFZGl0b3IsXG4gIFBhcnNlZENvbmZpZyxcbiAgRmlsdGVyLFxuICBFZmZlY3QgYXMgRWZmZWN0VHlwZSxcbiAgUGFyc2VkRWZmZWN0LFxuICBMYXllckNvbHVtbnMsXG4gIExheWVyQ29sdW1uLFxuICBQYXJzZWRGaWx0ZXIsXG4gIE5lc3RlZFBhcnRpYWwsXG4gIFNhdmVkQW5pbWF0aW9uQ29uZmlnLFxuICBMYXllck9yZGVyLFxuICBMYXllck9yZGVyR3JvdXBcbn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge0tlcGxlclRhYmxlLCBEYXRhc2V0cywgYXNzaWduR3B1Q2hhbm5lbHMsIHJlc2V0RmlsdGVyR3B1TW9kZX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5cbmltcG9ydCB7Z2V0TGF5ZXJPcmRlckZyb21MYXllcnN9IGZyb20gJy4vbGF5ZXItdXRpbHMnO1xuXG4vKipcbiAqIE1lcmdlIGxvYWRlZCBmaWx0ZXJzIHdpdGggY3VycmVudCBzdGF0ZSwgaWYgbm8gZmllbGRzIG9yIGRhdGEgYXJlIGxvYWRlZFxuICogc2F2ZSBpdCBmb3IgbGF0ZXJcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUZpbHRlcnM8UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIGZpbHRlcnNUb01lcmdlOiBOb25OdWxsYWJsZTxQYXJzZWRDb25maWdbJ3Zpc1N0YXRlJ10+WydmaWx0ZXJzJ10sXG4gIGZyb21Db25maWc/OiBib29sZWFuXG4pOiBTIHtcbiAgY29uc3QgcHJlc2VydmVGaWx0ZXJPcmRlciA9IGZyb21Db25maWdcbiAgICA/IGZpbHRlcnNUb01lcmdlPy5tYXAobCA9PiBsLmlkKVxuICAgIDogc3RhdGUucHJlc2VydmVGaWx0ZXJPcmRlcjtcblxuICBpZiAoIUFycmF5LmlzQXJyYXkoZmlsdGVyc1RvTWVyZ2UpIHx8ICFmaWx0ZXJzVG9NZXJnZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICBjb25zdCB7dmFsaWRhdGVkLCBmYWlsZWQsIHVwZGF0ZWREYXRhc2V0c30gPSB2YWxpZGF0ZUZpbHRlcnNVcGRhdGVEYXRhc2V0cyhzdGF0ZSwgZmlsdGVyc1RvTWVyZ2UpO1xuICBsZXQgdXBkYXRlZEZpbHRlcnMgPSBpbnNlcnRJdGVtQmFzZWRPblByZXNlcnZlZE9yZGVyKFxuICAgIHN0YXRlLmZpbHRlcnMsXG4gICAgdmFsaWRhdGVkLFxuICAgIHByZXNlcnZlRmlsdGVyT3JkZXJcbiAgKTtcblxuICAvLyBtZXJnZSBmaWx0ZXIgd2l0aCBleGlzdGluZ1xuICB1cGRhdGVkRmlsdGVycyA9IHJlc2V0RmlsdGVyR3B1TW9kZSh1cGRhdGVkRmlsdGVycyk7XG4gIHVwZGF0ZWRGaWx0ZXJzID0gYXNzaWduR3B1Q2hhbm5lbHModXBkYXRlZEZpbHRlcnMpO1xuICAvLyBmaWx0ZXIgZGF0YVxuICBjb25zdCBkYXRhc2V0c1RvRmlsdGVyID0gdW5pcShmbGF0dGVuRGVlcCh2YWxpZGF0ZWQubWFwKGYgPT4gZi5kYXRhSWQpKSk7XG5cbiAgY29uc3QgZmlsdGVyZWQgPSBhcHBseUZpbHRlcnNUb0RhdGFzZXRzKFxuICAgIGRhdGFzZXRzVG9GaWx0ZXIsXG4gICAgdXBkYXRlZERhdGFzZXRzLFxuICAgIHVwZGF0ZWRGaWx0ZXJzLFxuICAgIHN0YXRlLmxheWVyc1xuICApO1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgZmlsdGVyczogdXBkYXRlZEZpbHRlcnMsXG4gICAgZGF0YXNldHM6IGZpbHRlcmVkLFxuICAgIHByZXNlcnZlRmlsdGVyT3JkZXIsXG4gICAgZmlsdGVyVG9CZU1lcmdlZDogWy4uLnN0YXRlLmZpbHRlclRvQmVNZXJnZWQsIC4uLmZhaWxlZF1cbiAgfTtcbn1cblxuLy8gcmVwbGFjZSBkYXRhSWQgaW4gc2F2ZWQgRmlsdGVyXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZUZpbHRlckRhdGFzZXRJZHMoXG4gIHNhdmVkRmlsdGVyOiBGaWx0ZXJbXSxcbiAgZGF0YUlkOiBzdHJpbmcsXG4gIGRhdGFJZFRvVXNlOiBzdHJpbmdcbikge1xuICBjb25zdCByZXBsYWNlZDogRmlsdGVyW10gPSBbXTtcbiAgc2F2ZWRGaWx0ZXIuZm9yRWFjaChmaWx0ZXIgPT4ge1xuICAgIGlmIChmaWx0ZXIuZGF0YUlkLmluY2x1ZGVzKGRhdGFJZCkpIHtcbiAgICAgIGNvbnN0IG5ld0RhdGFJZCA9IGZpbHRlci5kYXRhSWQubWFwKGQgPT4gKGQgPT09IGRhdGFJZCA/IGRhdGFJZFRvVXNlIDogZCkpO1xuICAgICAgbGV0IHBsb3RUeXBlO1xuICAgICAgLy8gVE9ETzogbW9yZSBnZW5lcmljIGFwcHJvYWNoIHRvIHNhdmUgcGxvdFR5cGUuY29sb3JzQnlEYXRhSWRcbiAgICAgIGlmIChmaWx0ZXIucGxvdFR5cGU/LmNvbG9yc0J5RGF0YUlkPy5bZGF0YUlkXSkge1xuICAgICAgICAvLyByZXBsYWNlIGNvbG9yQnlEYXRhSWQgaW4gZmlsdGVyLnBsb3RUeXBlXG4gICAgICAgIGNvbnN0IHtbZGF0YUlkXTogY29sb3IsIC4uLnJlc3R9ID0gZmlsdGVyLnBsb3RUeXBlPy5jb2xvcnNCeURhdGFJZCB8fCB7fTtcbiAgICAgICAgcGxvdFR5cGUgPSB7XG4gICAgICAgICAgLi4uZmlsdGVyLnBsb3RUeXBlLFxuICAgICAgICAgIGNvbG9yc0J5RGF0YUlkOiB7XG4gICAgICAgICAgICAuLi5yZXN0LFxuICAgICAgICAgICAgW2RhdGFJZFRvVXNlXTogY29sb3JcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXBsYWNlZC5wdXNoKHtcbiAgICAgICAgLi4uZmlsdGVyLFxuICAgICAgICBkYXRhSWQ6IG5ld0RhdGFJZCxcbiAgICAgICAgLi4uKHBsb3RUeXBlID8ge3Bsb3RUeXBlfSA6IHt9KVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlcGxhY2VkLmxlbmd0aCA/IHJlcGxhY2VkIDogbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2F2ZWRMYXllckNvbmZpZ1YxKGxheWVyQ29uZmlnOiBhbnkpOiBib29sZWFuIHtcbiAgLy8gZXhwb3J0ZWQgbGF5ZXIgY29uZmlndXJhdGlvbiBjb250YWlucyB2aXN1YWxDaGFubmVscyBwcm9wZXJ0eVxuICByZXR1cm4gbGF5ZXJDb25maWc/LnZpc3VhbENoYW5uZWxzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VMYXllckNvbmZpZyhcbiAgc2NoZW1hOiBLZXBsZXJHTFNjaGVtYUNsYXNzLFxuICBsYXllckNvbmZpZzogYW55XG4pOiBQYXJzZWRMYXllciB8IHVuZGVmaW5lZCB7XG4gIC8vIGFzc3VtZSB0aGUgbGF5ZXIgY29uZmlnIGlzIGN1cnJlbnQgdmVyc2lvblxuICBjb25zdCBzYXZlZENvbmZpZyA9IHtcbiAgICB2ZXJzaW9uOiBDVVJSRU5UX1ZFUlNJT04sXG4gICAgY29uZmlnOiB7XG4gICAgICB2aXNTdGF0ZToge2xheWVyczogW2xheWVyQ29uZmlnXSwgbGF5ZXJPcmRlcjogW2xheWVyQ29uZmlnLmlkXX1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHNjaGVtYS5wYXJzZVNhdmVkQ29uZmlnKHNhdmVkQ29uZmlnKT8udmlzU3RhdGU/LmxheWVycz8uWzBdO1xufVxuXG5mdW5jdGlvbiBpbnNlcnRJdGVtQmFzZWRPblByZXNlcnZlZE9yZGVyKFxuICBjdXJyZW50SXRlbXM6IEZpbHRlcltdLFxuICBpdGVtczogRmlsdGVyW10sXG4gIHByZXNlcnZlZE9yZGVyOiBhbnlbXSA9IFtdLFxuICBkZWZhdWx0U3RhcnQ/OiBib29sZWFuXG4pIHtcbiAgbGV0IG5ld0l0ZW1zID0gWy4uLmN1cnJlbnRJdGVtc107XG5cbiAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7XG4gICAgY29uc3QgZXhwZWN0ZWRJZHggPSBwcmVzZXJ2ZWRPcmRlci5pbmRleE9mKGl0ZW0uaWQpO1xuICAgIC8vIGluc2VydEF0IHRoZSBlbmQgYnkgZGVmYXVsdFxuICAgIGxldCBpbnNlcnRBdCA9IGRlZmF1bHRTdGFydCA/IDAgOiBuZXdJdGVtcy5sZW5ndGg7XG4gICAgaWYgKGV4cGVjdGVkSWR4ID4gMCkge1xuICAgICAgLy8gbG9vayBmb3IgbGF5ZXIgdG8gaW5zZXJ0IGFmdGVyXG4gICAgICBsZXQgaSA9IGV4cGVjdGVkSWR4ICsgMTtcbiAgICAgIGxldCBwcmVjZWVkSWR4ID0gLTE7XG4gICAgICB3aGlsZSAoaS0tID4gMCAmJiBwcmVjZWVkSWR4IDwgMCkge1xuICAgICAgICAvLyBrZWVwIGxvb2tpbmcgZm9yIHByZWNlZWQgbGF5ZXIgdGhhdCBpcyBhbHJlYWR5IGxvYWRlZFxuICAgICAgICBjb25zdCBwcmVjZWVkSXRlbUlkID0gcHJlc2VydmVkT3JkZXJbaSAtIDFdO1xuICAgICAgICBwcmVjZWVkSWR4ID0gbmV3SXRlbXMuZmluZEluZGV4KGQgPT4gZC5pZCA9PT0gcHJlY2VlZEl0ZW1JZCk7XG4gICAgICB9XG4gICAgICBpZiAocHJlY2VlZElkeCA+IC0xKSB7XG4gICAgICAgIC8vIGlmIGZvdW5kXG4gICAgICAgIGluc2VydEF0ID0gcHJlY2VlZElkeCArIDE7XG4gICAgICB9XG4gICAgfVxuICAgIG5ld0l0ZW1zID0gYXJyYXlJbnNlcnQobmV3SXRlbXMsIGluc2VydEF0LCBpdGVtKTtcbiAgfVxuICByZXR1cm4gbmV3SXRlbXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMYXllckZyb21Db25maWcoc3RhdGU6IFZpc1N0YXRlLCBsYXllckNvbmZpZzogYW55KTogTGF5ZXIgfCBudWxsIHtcbiAgLy8gY2hlY2sgaWYgdGhlIGxheWVyIGNvbmZpZyBpcyBwYXJzZWRcbiAgY29uc3QgcGFyc2VkTGF5ZXJDb25maWcgPSBpc1NhdmVkTGF5ZXJDb25maWdWMShsYXllckNvbmZpZylcbiAgICA/IHBhcnNlTGF5ZXJDb25maWcoc3RhdGUuc2NoZW1hLCBsYXllckNvbmZpZylcbiAgICA6IGxheWVyQ29uZmlnO1xuXG4gIGlmICghcGFyc2VkTGF5ZXJDb25maWcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBmaXJzdCB2YWxpZGF0ZSBjb25maWcgYWdhaW5zdCBkYXRhc2V0XG4gIGNvbnN0IHt2YWxpZGF0ZWQsIGZhaWxlZH0gPSB2YWxpZGF0ZUxheWVyc0J5RGF0YXNldHMoXG4gICAgc3RhdGUuZGF0YXNldHMsXG4gICAgc3RhdGUubGF5ZXJDbGFzc2VzLFxuICAgIFtwYXJzZWRMYXllckNvbmZpZ10sXG4gICAge2FsbG93RW1wdHlDb2x1bW46IHRydWV9XG4gICk7XG5cbiAgaWYgKGZhaWxlZD8ubGVuZ3RoIHx8ICF2YWxpZGF0ZWQubGVuZ3RoKSB7XG4gICAgLy8gZmFpbGVkXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBuZXdMYXllciA9IHZhbGlkYXRlZFswXTtcbiAgbmV3TGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oc3RhdGUuZGF0YXNldHMpO1xuICByZXR1cm4gbmV3TGF5ZXI7XG59XG5cbi8qKlxuICogR2V0IGxvYWRlZCBmaWx0ZXIgZnJvbSBzdGF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplRmlsdGVyKFxuICBuZXdGaWx0ZXI6IEZpbHRlcixcbiAgc2NoZW1hOiBLZXBsZXJHTFNjaGVtYUNsYXNzXG4pOiBQYXJzZWRGaWx0ZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBzZXJpYWxpemVkVmlzU3RhdGUgPSBzZXJpYWxpemVWaXNTdGF0ZSh7ZmlsdGVyczogW25ld0ZpbHRlcl19LCBzY2hlbWEpO1xuICByZXR1cm4gc2VyaWFsaXplZFZpc1N0YXRlPy5maWx0ZXJzPy5bMF07XG59XG5cbi8qKlxuICogR2V0IGxvYWRlZCBsYXllciBmcm9tIHN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVMYXllcihcbiAgbmV3TGF5ZXI6IExheWVyLFxuICBzY2hlbWE6IEtlcGxlckdMU2NoZW1hQ2xhc3Ncbik6IFBhcnNlZExheWVyIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc2VyaWFsaXplZFZpc1N0YXRlID0gc2VyaWFsaXplVmlzU3RhdGUoXG4gICAge2xheWVyczogW25ld0xheWVyXSwgbGF5ZXJPcmRlcjogW25ld0xheWVyLmlkXX0sXG4gICAgc2NoZW1hXG4gICk7XG4gIHJldHVybiBzZXJpYWxpemVkVmlzU3RhdGU/LmxheWVycz8uWzBdO1xufVxuXG4vKipcbiAqIEdldCBsb2FkZWQgZWZmZWN0IGZyb20gc3RhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZUVmZmVjdChcbiAgbmV3RWZmZWN0OiBFZmZlY3RUeXBlLFxuICBzY2hlbWE6IEtlcGxlckdMU2NoZW1hQ2xhc3Ncbik6IFBhcnNlZEVmZmVjdCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNlcmlhbGl6ZWRWaXNTdGF0ZSA9IHNlcmlhbGl6ZVZpc1N0YXRlKFxuICAgIHtlZmZlY3RzOiBbbmV3RWZmZWN0XSwgZWZmZWN0T3JkZXI6IFtuZXdFZmZlY3QuaWRdfSxcbiAgICBzY2hlbWFcbiAgKTtcbiAgcmV0dXJuIHNlcmlhbGl6ZWRWaXNTdGF0ZT8uZWZmZWN0cz8uWzBdO1xufVxuXG4vKipcbiAqIEdldCB2aXMgc3RhdGUgY29uZmlnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVWaXNTdGF0ZShcbiAgdmlzU3RhdGU6IFBhcnRpYWw8VmlzU3RhdGU+LFxuICBzY2hlbWE6IEtlcGxlckdMU2NoZW1hQ2xhc3Ncbik6IFBhcnNlZFZpc1N0YXRlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc2F2ZWRTdGF0ZSA9IHNjaGVtYS5nZXRDb25maWdUb1NhdmUoe1xuICAgIHZpc1N0YXRlXG4gIH0pO1xuICByZXR1cm4gc2F2ZWRTdGF0ZSA/IHNjaGVtYS5wYXJzZVNhdmVkQ29uZmlnKHNhdmVkU3RhdGUpPy52aXNTdGF0ZSA6IHVuZGVmaW5lZDtcbn1cbi8qKlxuICogTWVyZ2UgbGF5ZXJzIGZyb20gZGUtc2VyaWFsaXplZCBzdGF0ZSwgaWYgbm8gZmllbGRzIG9yIGRhdGEgYXJlIGxvYWRlZFxuICogc2F2ZSBpdCBmb3IgbGF0ZXJcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUxheWVyczxTIGV4dGVuZHMgVmlzU3RhdGU+KFxuICBzdGF0ZTogUyxcbiAgbGF5ZXJzVG9NZXJnZTogTm9uTnVsbGFibGU8UGFyc2VkQ29uZmlnWyd2aXNTdGF0ZSddPlsnbGF5ZXJzJ10gPSBbXSxcbiAgZnJvbUNvbmZpZz86IGJvb2xlYW5cbik6IFMge1xuICBjb25zdCBwcmVzZXJ2ZUxheWVyT3JkZXIgPSBmcm9tQ29uZmlnXG4gICAgPyBnZXRMYXllck9yZGVyRnJvbUxheWVycyhsYXllcnNUb01lcmdlKVxuICAgIDogc3RhdGUucHJlc2VydmVMYXllck9yZGVyO1xuICBpZiAoIUFycmF5LmlzQXJyYXkobGF5ZXJzVG9NZXJnZSkgfHwgIWxheWVyc1RvTWVyZ2UubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIC8vIGRvbid0IG1lcmdlIGxheWVyIGlmIGRhdGFzZXQgaXMgYmVpbmcgbWVyZ2VkXG4gIGNvbnN0IHVubWVyZ2VkOiBQYXJzZWRMYXllcltdID0gW107XG4gIGNvbnN0IHRvTWVyZ2U6IFBhcnNlZExheWVyW10gPSBbXTtcbiAgbGF5ZXJzVG9NZXJnZS5mb3JFYWNoKChsOiBQYXJzZWRMYXllcikgPT4ge1xuICAgIGlmIChsPy5jb25maWc/LmRhdGFJZCAmJiBzdGF0ZS5pc01lcmdpbmdEYXRhc2V0c1tsLmNvbmZpZy5kYXRhSWRdKSB7XG4gICAgICB1bm1lcmdlZC5wdXNoKGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0b01lcmdlLnB1c2gobCk7XG4gICAgfVxuICB9KTtcblxuICBjb25zdCB7dmFsaWRhdGVkOiBtZXJnZWRMYXllciwgZmFpbGVkfSA9IHZhbGlkYXRlTGF5ZXJzQnlEYXRhc2V0cyhcbiAgICBzdGF0ZS5kYXRhc2V0cyxcbiAgICBzdGF0ZS5sYXllckNsYXNzZXMsXG4gICAgdG9NZXJnZVxuICApO1xuICB1bm1lcmdlZC5wdXNoKC4uLmZhaWxlZCk7XG4gIC8vIHB1dCBuZXcgbGF5ZXJzIGluIGZyb250IG9mIGN1cnJlbnQgbGF5ZXJzXG4gIGNvbnN0IHtuZXdMYXllck9yZGVyLCBuZXdMYXllcnN9ID0gaW5zZXJ0TGF5ZXJBdFJpZ2h0T3JkZXIoXG4gICAgc3RhdGUubGF5ZXJzLFxuICAgIG1lcmdlZExheWVyLFxuICAgIHN0YXRlLmxheWVyT3JkZXIsXG4gICAgcHJlc2VydmVMYXllck9yZGVyXG4gICk7XG5cbiAgbGV0IG1lcmdlZFN0YXRlOiBTID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyczogbmV3TGF5ZXJzLFxuICAgIGxheWVyT3JkZXI6IG5ld0xheWVyT3JkZXIsXG4gICAgcHJlc2VydmVMYXllck9yZGVyLFxuICAgIGxheWVyVG9CZU1lcmdlZDogWy4uLnN0YXRlLmxheWVyVG9CZU1lcmdlZCwgLi4udW5tZXJnZWRdXG4gIH07XG5cbiAgLy8gQXBwbHkgcGVuZGluZyBsYXllck9yZGVyIHdpdGggZ3JvdXBzIGlmIGxheWVycyBhcmUgbm93IGF2YWlsYWJsZVxuICBpZiAobWVyZ2VkU3RhdGUubGF5ZXJPcmRlclRvQmVNZXJnZWQgJiYgbWVyZ2VkU3RhdGUubGF5ZXJzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBzYXZlZE9yZGVyID0gbWVyZ2VkU3RhdGUubGF5ZXJPcmRlclRvQmVNZXJnZWQ7XG4gICAgbWVyZ2VkU3RhdGUgPSBtZXJnZUxheWVyT3JkZXIobWVyZ2VkU3RhdGUsIHNhdmVkT3JkZXIpO1xuICAgIC8vIEtlZXAgc2F2ZWRMYXllck9yZGVyIGF2YWlsYWJsZSBmb3IgZnV0dXJlIGRlZmVycmVkIGxheWVyc1xuICAgIGlmIChtZXJnZWRTdGF0ZS5sYXllclRvQmVNZXJnZWQubGVuZ3RoID4gMCkge1xuICAgICAgbWVyZ2VkU3RhdGUgPSB7Li4ubWVyZ2VkU3RhdGUsIGxheWVyT3JkZXJUb0JlTWVyZ2VkOiBzYXZlZE9yZGVyfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWVyZ2VkU3RhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRMYXllckF0UmlnaHRPcmRlcihcbiAgY3VycmVudExheWVycyxcbiAgbGF5ZXJzVG9JbnNlcnQsXG4gIGN1cnJlbnRPcmRlcixcbiAgcHJlc2VydmVkT3JkZXI6IHN0cmluZ1tdID0gW11cbikge1xuICBpZiAoIWxheWVyc1RvSW5zZXJ0Py5sZW5ndGgpIHtcbiAgICByZXR1cm4ge25ld0xheWVyczogY3VycmVudExheWVycywgbmV3TGF5ZXJPcmRlcjogY3VycmVudE9yZGVyfTtcbiAgfVxuXG4gIGNvbnN0IGN1cnJlbnRMYXllclF1ZXVlID0gY3VycmVudE9yZGVyXG4gICAgLmZpbHRlcihlbnRyeSA9PiB0eXBlb2YgZW50cnkgPT09ICdzdHJpbmcnKVxuICAgIC5tYXAoaWQgPT4gZmluZEJ5SWQoaWQpKGN1cnJlbnRMYXllcnMpKVxuICAgIC5maWx0ZXIobGF5ZXIgPT4gQm9vbGVhbihsYXllcikpO1xuICBjb25zdCBuZXdMYXllcnMgPSBjdXJyZW50TGF5ZXJzLmNvbmNhdChsYXllcnNUb0luc2VydCk7XG4gIGNvbnN0IG5ld0xheWVyT3JkZXJRdWV1ZSA9IGluc2VydEl0ZW1CYXNlZE9uUHJlc2VydmVkT3JkZXIoXG4gICAgY3VycmVudExheWVyUXVldWUsXG4gICAgbGF5ZXJzVG9JbnNlcnQsXG4gICAgcHJlc2VydmVkT3JkZXIsXG4gICAgdHJ1ZVxuICApO1xuXG4gIGNvbnN0IG5ld0ZsYXRMYXllck9yZGVyID0gZ2V0TGF5ZXJPcmRlckZyb21MYXllcnMobmV3TGF5ZXJPcmRlclF1ZXVlKTtcblxuICAvLyBJZiBubyBncm91cHMgZXhpc3QgaW4gY3VycmVudCBvcmRlciwganVzdCB1c2UgdGhlIG5ldyBmbGF0IG9yZGVyXG4gIGNvbnN0IGhhc0dyb3VwcyA9IGN1cnJlbnRPcmRlci5zb21lKGVudHJ5ID0+IGlzUGxhaW5PYmplY3QoZW50cnkpKTtcbiAgaWYgKCFoYXNHcm91cHMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmV3TGF5ZXJPcmRlcjogbmV3RmxhdExheWVyT3JkZXIsXG4gICAgICBuZXdMYXllcnNcbiAgICB9O1xuICB9XG5cbiAgLy8gUmVidWlsZCBsYXllck9yZGVyIHByZXNlcnZpbmcgZ3JvdXBzIGluIHRoZWlyIHJlbGF0aXZlIHBvc2l0aW9ucy5cbiAgLy8gUmVwbGFjZSBlYWNoIHN0cmluZyBlbnRyeSB3aXRoIGl0cyB1cGRhdGVkIHBvc2l0aW9uIGZyb20gbmV3RmxhdExheWVyT3JkZXIsXG4gIC8vIGFuZCBrZWVwIGdyb3VwcyBhcy1pcy5cbiAgY29uc3QgZXhpc3RpbmdGbGF0SWRzID0gbmV3IFNldChcbiAgICBjdXJyZW50T3JkZXIuZmlsdGVyKGVudHJ5ID0+IHR5cGVvZiBlbnRyeSA9PT0gJ3N0cmluZycpIGFzIHN0cmluZ1tdXG4gICk7XG4gIGNvbnN0IG5ld0luc2VydGVkSWRzID0gbmV3RmxhdExheWVyT3JkZXIuZmlsdGVyKGlkID0+ICFleGlzdGluZ0ZsYXRJZHMuaGFzKGlkKSk7XG5cbiAgLy8gUmVidWlsZDogd2FsayB0aHJvdWdoIGN1cnJlbnRPcmRlciwgcmVwbGFjZSBzdHJpbmcgZW50cmllcyB3aXRoIHRoZWlyXG4gIC8vIG5ldyBwb3NpdGlvbiBlcXVpdmFsZW50cyBmcm9tIG5ld0ZsYXRMYXllck9yZGVyLCB0aGVuIGFwcGVuZCBhbnkgbmV3bHkgaW5zZXJ0ZWQgbGF5ZXJzXG4gIGNvbnN0IHJlc3VsdDogTGF5ZXJPcmRlciA9IFtdO1xuICBjb25zdCBmbGF0UXVldWUgPSBbLi4ubmV3RmxhdExheWVyT3JkZXIuZmlsdGVyKGlkID0+IGV4aXN0aW5nRmxhdElkcy5oYXMoaWQpKV07XG4gIGxldCBmbGF0SWR4ID0gMDtcblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGN1cnJlbnRPcmRlcikge1xuICAgIGlmIChpc1BsYWluT2JqZWN0KGVudHJ5KSkge1xuICAgICAgcmVzdWx0LnB1c2goZW50cnkgYXMgTGF5ZXJPcmRlckdyb3VwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVwbGFjZSB3aXRoIGNvcnJlc3BvbmRpbmcgZW50cnkgZnJvbSByZW9yZGVyZWQgZmxhdCBsaXN0XG4gICAgICBpZiAoZmxhdElkeCA8IGZsYXRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goZmxhdFF1ZXVlW2ZsYXRJZHhdKTtcbiAgICAgICAgZmxhdElkeCsrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEFwcGVuZCBhbnkgbmV3bHkgaW5zZXJ0ZWQgbGF5ZXJzIGF0IHRoZSBmcm9udCAodGhleSBhcmUgbmV3KVxuICByZXR1cm4ge1xuICAgIG5ld0xheWVyT3JkZXI6IFsuLi5uZXdJbnNlcnRlZElkcywgLi4ucmVzdWx0XSxcbiAgICBuZXdMYXllcnNcbiAgfTtcbn1cblxuLyoqXG4gKiBNZXJnZSBzYXZlZCBsYXllck9yZGVyIHdpdGggY3VycmVudCBzdGF0ZSB0byByZXN0b3JlIGxheWVyIGdyb3Vwcy5cbiAqIENhbGxlZCBhZnRlciBsYXllcnMgaGF2ZSBiZWVuIG1lcmdlZC4gSWYgdGhlIHNhdmVkIGNvbmZpZyBjb250YWlucyBhIGxheWVyT3JkZXJcbiAqIHdpdGggZ3JvdXBzLCB0aGlzIHJlcGxhY2VzIHRoZSBmbGF0IGxheWVyT3JkZXIgd2l0aCB0aGUgc2F2ZWQgaGllcmFyY2hpY2FsIG9uZSxcbiAqIGZpbHRlcmluZyBvdXQgYW55IGxheWVyIElEcyB0aGF0IGRvbid0IGV4aXN0IGluIHRoZSBjdXJyZW50IHN0YXRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VMYXllck9yZGVyPFMgZXh0ZW5kcyBWaXNTdGF0ZT4oXG4gIHN0YXRlOiBTLFxuICBzYXZlZExheWVyT3JkZXI/OiBhbnlbXSxcbiAgZnJvbUNvbmZpZz86IGJvb2xlYW5cbik6IFMge1xuICBpZiAoIXNhdmVkTGF5ZXJPcmRlciB8fCAhQXJyYXkuaXNBcnJheShzYXZlZExheWVyT3JkZXIpIHx8IHNhdmVkTGF5ZXJPcmRlci5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICAvLyBDaGVjayBpZiB0aGUgc2F2ZWQgbGF5ZXJPcmRlciBjb250YWlucyBhbnkgZ3JvdXBzXG4gIGNvbnN0IGhhc0dyb3VwcyA9IHNhdmVkTGF5ZXJPcmRlci5zb21lKGVudHJ5ID0+IGlzUGxhaW5PYmplY3QoZW50cnkpKTtcbiAgaWYgKCFoYXNHcm91cHMpIHtcbiAgICAvLyBObyBncm91cHMgLSB0aGUgbGF5ZXIgbWVyZ2VyIGFscmVhZHkgaGFuZGxlZCBvcmRlcmluZyB2aWEgcHJlc2VydmVMYXllck9yZGVyXG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgLy8gSWYgbGF5ZXJzIGhhdmVuJ3QgYmVlbiBtZXJnZWQgeWV0LCBzdG9yZSBmb3IgbGF0ZXJcbiAgaWYgKHN0YXRlLmxheWVycy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBsYXllck9yZGVyVG9CZU1lcmdlZDogc2F2ZWRMYXllck9yZGVyXG4gICAgfTtcbiAgfVxuXG4gIC8vIEJ1aWxkIGEgc2V0IG9mIHZhbGlkIGxheWVyIElEcyBmcm9tIGN1cnJlbnQgc3RhdGVcbiAgY29uc3QgdmFsaWRMYXllcklkcyA9IG5ldyBTZXQoc3RhdGUubGF5ZXJzLm1hcChsID0+IGwuaWQpKTtcblxuICAvLyBSZWN1cnNpdmVseSBmaWx0ZXIgdGhlIHNhdmVkIGxheWVyT3JkZXIgdG8gb25seSBpbmNsdWRlIHZhbGlkIGxheWVyc1xuICBmdW5jdGlvbiBmaWx0ZXJMYXllck9yZGVyKG9yZGVyOiBhbnlbXSk6IExheWVyT3JkZXIge1xuICAgIGNvbnN0IHJlc3VsdDogTGF5ZXJPcmRlciA9IFtdO1xuICAgIGZvciAoY29uc3QgZW50cnkgb2Ygb3JkZXIpIHtcbiAgICAgIGlmIChpc1BsYWluT2JqZWN0KGVudHJ5KSkge1xuICAgICAgICBjb25zdCBncm91cCA9IGVudHJ5IGFzIExheWVyT3JkZXJHcm91cDtcbiAgICAgICAgY29uc3QgZmlsdGVyZWRHcm91cE9yZGVyID0gZmlsdGVyTGF5ZXJPcmRlcihncm91cC5sYXllck9yZGVyKTtcbiAgICAgICAgLy8gS2VlcCB0aGUgZ3JvdXAgZXZlbiBpZiBlbXB0eSAodXNlciBtYXkgd2FudCB0aGUgZW1wdHkgZ3JvdXApXG4gICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAuLi5ncm91cCxcbiAgICAgICAgICBsYXllck9yZGVyOiBmaWx0ZXJlZEdyb3VwT3JkZXJcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbnRyeSA9PT0gJ3N0cmluZycgJiYgdmFsaWRMYXllcklkcy5oYXMoZW50cnkpKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGVudHJ5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGNvbnN0IHJlc3RvcmVkTGF5ZXJPcmRlciA9IGZpbHRlckxheWVyT3JkZXIoc2F2ZWRMYXllck9yZGVyKTtcblxuICAvLyBGaW5kIGFueSBsYXllcnMgaW4gdGhlIGN1cnJlbnQgc3RhdGUgdGhhdCBhcmVuJ3QgaW4gdGhlIHJlc3RvcmVkIG9yZGVyXG4gIC8vIChjb3VsZCBoYXBwZW4gaWYgbGF5ZXJzIHdlcmUgYWRkZWQgYmV0d2VlbiBzYXZlIGFuZCBsb2FkKVxuICBjb25zdCBsYXllcklkc0luUmVzdG9yZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZnVuY3Rpb24gY29sbGVjdElkcyhvcmRlcjogYW55W10pIHtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIG9yZGVyKSB7XG4gICAgICBpZiAoaXNQbGFpbk9iamVjdChlbnRyeSkpIHtcbiAgICAgICAgY29sbGVjdElkcygoZW50cnkgYXMgTGF5ZXJPcmRlckdyb3VwKS5sYXllck9yZGVyKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGVudHJ5ID09PSAnc3RyaW5nJykge1xuICAgICAgICBsYXllcklkc0luUmVzdG9yZWQuYWRkKGVudHJ5KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29sbGVjdElkcyhyZXN0b3JlZExheWVyT3JkZXIpO1xuXG4gIC8vIEFkZCBhbnkgbWlzc2luZyBsYXllcnMgYXQgdGhlIHRvcFxuICBjb25zdCBtaXNzaW5nTGF5ZXJzID0gc3RhdGUubGF5ZXJzXG4gICAgLmZpbHRlcihsID0+ICFsYXllcklkc0luUmVzdG9yZWQuaGFzKGwuaWQpKVxuICAgIC5tYXAobCA9PiBsLmlkKTtcblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyT3JkZXI6IFsuLi5taXNzaW5nTGF5ZXJzLCAuLi5yZXN0b3JlZExheWVyT3JkZXJdLFxuICAgIGxheWVyT3JkZXJUb0JlTWVyZ2VkOiBudWxsXG4gIH07XG59XG5cbi8qKlxuICogTWVyZ2UgaW50ZXJhY3Rpb25zIHdpdGggc2F2ZWQgY29uZmlnXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJbnRlcmFjdGlvbnM8UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIGludGVyYWN0aW9uVG9CZU1lcmdlZDogUGFydGlhbDxTYXZlZEludGVyYWN0aW9uQ29uZmlnPiB8IHVuZGVmaW5lZFxuKTogUyB7XG4gIGNvbnN0IG1lcmdlZDogTmVzdGVkUGFydGlhbDxTYXZlZEludGVyYWN0aW9uQ29uZmlnPiA9IHt9O1xuICBjb25zdCB1bm1lcmdlZDogUGFydGlhbDxTYXZlZEludGVyYWN0aW9uQ29uZmlnPiA9IHt9O1xuXG4gIGlmIChpbnRlcmFjdGlvblRvQmVNZXJnZWQpIHtcbiAgICAoT2JqZWN0LmtleXMoaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkKSBhcyBBcnJheTxrZXlvZiBTYXZlZEludGVyYWN0aW9uQ29uZmlnPikuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgaWYgKCFzdGF0ZS5pbnRlcmFjdGlvbkNvbmZpZ1trZXldKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY3VycmVudENvbmZpZyA9XG4gICAgICAgIGtleSA9PT0gJ3Rvb2x0aXAnIHx8IGtleSA9PT0gJ2JydXNoJyB8fCBrZXkgPT09ICdnZW9jb2RlcidcbiAgICAgICAgICA/IHN0YXRlLmludGVyYWN0aW9uQ29uZmlnW2tleV0uY29uZmlnXG4gICAgICAgICAgOiBudWxsO1xuXG4gICAgICBjb25zdCB7ZW5hYmxlZCwgLi4uY29uZmlnU2F2ZWR9ID0gaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkW2tleV0gfHwge307XG5cbiAgICAgIGxldCBjb25maWdUb01lcmdlID0gY29uZmlnU2F2ZWQ7XG5cbiAgICAgIGlmIChrZXkgPT09ICd0b29sdGlwJykge1xuICAgICAgICBjb25zdCB7bWVyZ2VkVG9vbHRpcCwgdW5tZXJnZWRUb29sdGlwfSA9IG1lcmdlSW50ZXJhY3Rpb25Ub29sdGlwQ29uZmlnKFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICAgIGNvbmZpZ1NhdmVkIGFzIFNhdmVkSW50ZXJhY3Rpb25Db25maWdbJ3Rvb2x0aXAnXVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIG1lcmdlIG5ldyBkYXRhc2V0IHRvb2x0aXBzIHdpdGggb3JpZ2luYWwgZGF0YXNldCB0b29sdGlwc1xuICAgICAgICBjb25maWdUb01lcmdlID0ge1xuICAgICAgICAgIGZpZWxkc1RvU2hvdzoge1xuICAgICAgICAgICAgLi4uKGN1cnJlbnRDb25maWcgYXMgVG9vbHRpcEluZm9bJ2NvbmZpZyddKS5maWVsZHNUb1Nob3csXG4gICAgICAgICAgICAuLi5tZXJnZWRUb29sdGlwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyh1bm1lcmdlZFRvb2x0aXApLmxlbmd0aCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICB1bm1lcmdlZC50b29sdGlwID0ge2ZpZWxkc1RvU2hvdzogdW5tZXJnZWRUb29sdGlwLCBlbmFibGVkOiBCb29sZWFuKGVuYWJsZWQpfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBtZXJnZWRba2V5XSA9IHtcbiAgICAgICAgLi4uc3RhdGUuaW50ZXJhY3Rpb25Db25maWdba2V5XSxcbiAgICAgICAgZW5hYmxlZDogQm9vbGVhbihlbmFibGVkKSxcbiAgICAgICAgLi4uKGN1cnJlbnRDb25maWdcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgY29uZmlnOiBwaWNrKFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIC4uLmN1cnJlbnRDb25maWcsXG4gICAgICAgICAgICAgICAgICAuLi5jb25maWdUb01lcmdlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhjdXJyZW50Q29uZmlnKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiB7fSlcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBuZXh0U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgaW50ZXJhY3Rpb25Db25maWc6IHtcbiAgICAgIC4uLnN0YXRlLmludGVyYWN0aW9uQ29uZmlnLFxuICAgICAgLi4ubWVyZ2VkXG4gICAgfSxcbiAgICBpbnRlcmFjdGlvblRvQmVNZXJnZWQ6IHNhdmVkVW5tZXJnZWRJbnRlcmFjdGlvbihzdGF0ZSwgdW5tZXJnZWQpXG4gIH07XG4gIHJldHVybiBuZXh0U3RhdGU7XG59XG5cbmZ1bmN0aW9uIGNvbWJpbmVJbnRlcmFjdGlvbkNvbmZpZ3MoY29uZmlnczogU2F2ZWRJbnRlcmFjdGlvbkNvbmZpZ1tdKTogU2F2ZWRJbnRlcmFjdGlvbkNvbmZpZyB7XG4gIGNvbnN0IGNvbWJpbmVkID0gey4uLmNvbmZpZ3NbMF19O1xuICAvLyBoYW5kbGUgZWFjaCBwcm9wZXJ0eSBrZXkgb2YgYW4gYEludGVyYWN0aW9uQ29uZmlnYCwgZS5nLiB0b29sdGlwLCBnZW9jb2RlciwgYnJ1c2gsIGNvb3JkaW5hdGVcbiAgLy8gYnkgY29tYmluaW5nIHZhbHVlcyBmb3IgZWFjaCBhbW9uZyBhbGwgcGFzc2VkIGluIGNvbmZpZ3NcblxuICBmb3IgKGNvbnN0IGtleSBpbiBjb21iaW5lZCkge1xuICAgIGNvbnN0IHRvQmVDb21iaW5lZFByb3BzID0gY29uZmlncy5tYXAoYyA9PiBjW2tleV0pO1xuXG4gICAgLy8gYWxsIG9mIHRoZXNlIGhhdmUgYW4gZW5hYmxlZCBib29sZWFuXG4gICAgY29tYmluZWRba2V5XSA9IHtcbiAgICAgIC8vIGFyZSBhbnkgb2YgdGhlIGNvbmZpZ3MnIGVuYWJsZWQgdmFsdWVzIHRydWU/XG4gICAgICBlbmFibGVkOiB0b0JlQ29tYmluZWRQcm9wcy5zb21lKHAgPT4gcD8uZW5hYmxlZClcbiAgICB9O1xuXG4gICAgaWYgKGtleSA9PT0gJ3Rvb2x0aXAnKSB7XG4gICAgICAvLyBhcmUgYW55IG9mIHRoZSBjb25maWdzJyBjb21wYXJlTW9kZSB2YWx1ZXMgdHJ1ZT9cbiAgICAgIGNvbWJpbmVkW2tleV0uY29tcGFyZU1vZGUgPSB0b0JlQ29tYmluZWRQcm9wcy5zb21lKHAgPT4gcD8uY29tcGFyZU1vZGUpO1xuXG4gICAgICAvLyByZXR1cm4gdGhlIGNvbXBhcmUgdHlwZSBtb2RlLCBpdCB3aWxsIGJlIGVpdGhlciBhYnNvbHV0ZSBvciByZWxhdGl2ZVxuICAgICAgY29tYmluZWRba2V5XS5jb21wYXJlVHlwZSA9IGdldFZhbHVlV2l0aEhpZ2hlc3RPY2N1cnJlbmNlKFxuICAgICAgICB0b0JlQ29tYmluZWRQcm9wcy5tYXAocCA9PiBwLmNvbXBhcmVUeXBlKVxuICAgICAgKTtcblxuICAgICAgLy8gY29tYmluZSBmaWVsZHNUb1Nob3cgYW1vbmcgYWxsIGRhdGFzZXQgaWRzXG4gICAgICBjb21iaW5lZFtrZXldLmZpZWxkc1RvU2hvdyA9IHRvQmVDb21iaW5lZFByb3BzXG4gICAgICAgIC5tYXAocCA9PiBwLmZpZWxkc1RvU2hvdylcbiAgICAgICAgLnJlZHVjZSgoYWNjLCBuZXh0RmllbGRzVG9TaG93KSA9PiB7XG4gICAgICAgICAgZm9yIChjb25zdCBuZXh0RGF0YUlkS2V5IGluIG5leHRGaWVsZHNUb1Nob3cpIHtcbiAgICAgICAgICAgIGNvbnN0IG5leHRUb29sdGlwRmllbGRzID0gbmV4dEZpZWxkc1RvU2hvd1tuZXh0RGF0YUlkS2V5XTtcbiAgICAgICAgICAgIGlmICghYWNjW25leHREYXRhSWRLZXldKSB7XG4gICAgICAgICAgICAgIC8vIGlmIHRoZSBkYXRhc2V0IGlkIGlzIG5vdCBwcmVzZW50IGluIHRoZSBhY2N1bXVsYXRvclxuICAgICAgICAgICAgICAvLyB0aGVuIGFkZCBpdCB3aXRoIGl0cyB0b29sdGlwIGZpZWxkc1xuICAgICAgICAgICAgICBhY2NbbmV4dERhdGFJZEtleV0gPSBuZXh0VG9vbHRpcEZpZWxkcztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIG90aGVyd2lzZSB0aGUgZGF0YXNldCBpZCBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhlIGFjY3VtdWxhdG9yXG4gICAgICAgICAgICAgIC8vIHNvIG9ubHkgYWRkIHRoZSBuZXh0IHRvb2x0aXAgZmllbGRzIGZvciB0aGlzIGRhdGFzZXQncyBhcnJheSBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBwcmVzZW50LFxuICAgICAgICAgICAgICAvLyB1c2luZyB0aGUgdG9vbHRpcEZpZWxkLm5hbWUgcHJvcGVydHkgZm9yIHVuaXF1ZW5lc3NcbiAgICAgICAgICAgICAgbmV4dFRvb2x0aXBGaWVsZHMuZm9yRWFjaChuZXh0VEYgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghYWNjW25leHREYXRhSWRLZXldLmZpbmQoKHtuYW1lfSkgPT4gbmV4dFRGLm5hbWUgPT09IG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICBhY2NbbmV4dERhdGFJZEtleV0ucHVzaChuZXh0VEYpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIHt9KTtcbiAgICB9XG5cbiAgICBpZiAoa2V5ID09PSAnYnJ1c2gnKSB7XG4gICAgICAvLyBrZWVwIHRoZSBiaWdnZXN0IGJydXNoIHNpemVcbiAgICAgIGNvbWJpbmVkW2tleV0uc2l6ZSA9XG4gICAgICAgIGFnZ3JlZ2F0ZSh0b0JlQ29tYmluZWRQcm9wcywgQUdHUkVHQVRJT05fVFlQRVMubWF4aW11bSwgcCA9PiBwLnNpemUpID8/IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGtleSA9PT0gJ2dlb2NvZGVyJykge1xuICAgICAgY29tYmluZWRba2V5XS5saW1pdFNlYXJjaCA9IHRvQmVDb21iaW5lZFByb3BzLnNvbWUocCA9PiBwPy5saW1pdFNlYXJjaCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbWJpbmVkO1xufVxuXG5mdW5jdGlvbiBzYXZlZFVubWVyZ2VkSW50ZXJhY3Rpb248UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIHVubWVyZ2VkOiBQYXJ0aWFsPFNhdmVkSW50ZXJhY3Rpb25Db25maWc+XG4pIHtcbiAgaWYgKCF1bm1lcmdlZD8udG9vbHRpcD8uZmllbGRzVG9TaG93KSB7XG4gICAgcmV0dXJuIHN0YXRlLmludGVyYWN0aW9uVG9CZU1lcmdlZDtcbiAgfVxuICByZXR1cm4ge1xuICAgIHRvb2x0aXA6IHtcbiAgICAgIC4uLnN0YXRlLmludGVyYWN0aW9uVG9CZU1lcmdlZC50b29sdGlwLFxuICAgICAgLi4uKHR5cGVvZiB1bm1lcmdlZD8udG9vbHRpcD8uZW5hYmxlZCA9PT0gJ2Jvb2xlYW4nXG4gICAgICAgID8ge2VuYWJsZWQ6IHVubWVyZ2VkLnRvb2x0aXAuZW5hYmxlZH1cbiAgICAgICAgOiB7fSksXG4gICAgICBmaWVsZHNUb1Nob3c6IHtcbiAgICAgICAgLi4uc3RhdGUuaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkPy50b29sdGlwPy5maWVsZHNUb1Nob3csXG4gICAgICAgIC4uLnVubWVyZ2VkPy50b29sdGlwPy5maWVsZHNUb1Nob3dcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VJbnRlcmFjdGlvbkRhdGFzZXRJZHMoaW50ZXJhY3Rpb25Db25maWcsIGRhdGFJZDogc3RyaW5nLCBkYXRhSWRUb1JlcGxhY2U6IHN0cmluZykge1xuICBpZiAoaW50ZXJhY3Rpb25Db25maWc/LnRvb2x0aXA/LmZpZWxkc1RvU2hvd1tkYXRhSWRdKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmludGVyYWN0aW9uQ29uZmlnLFxuICAgICAgdG9vbHRpcDoge1xuICAgICAgICAuLi5pbnRlcmFjdGlvbkNvbmZpZy50b29sdGlwLFxuICAgICAgICBmaWVsZHNUb1Nob3c6IHtcbiAgICAgICAgICBbZGF0YUlkVG9SZXBsYWNlXTogaW50ZXJhY3Rpb25Db25maWc/LnRvb2x0aXA/LmZpZWxkc1RvU2hvd1tkYXRhSWRdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIE1lcmdlIHNwbGl0TWFwcyBjb25maWcgd2l0aCBjdXJyZW50IHZpc1N0ZXRlLlxuICogMS4gaWYgY3VycmVudCBtYXAgaXMgc3BsaXQsIGJ1dCBzcGxpdE1hcCBET0VTTk9UIGNvbnRhaW4gbWFwc1xuICogICAgOiBkb24ndCBtZXJnZSBhbnl0aGluZ1xuICogMi4gaWYgY3VycmVudCBtYXAgaXMgTk9UIHNwbGl0LCBidXQgc3BsaXRNYXBzIGNvbnRhaW4gbWFwc1xuICogICAgOiBhZGQgdG8gc3BsaXRNYXBzLCBhbmQgYWRkIGN1cnJlbnQgbGF5ZXJzIHRvIHNwbGl0TWFwc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VTcGxpdE1hcHM8UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIHNwbGl0TWFwczogTm9uTnVsbGFibGU8UGFyc2VkQ29uZmlnWyd2aXNTdGF0ZSddPlsnc3BsaXRNYXBzJ10gPSBbXVxuKTogUyB7XG4gIGNvbnN0IG1lcmdlZCA9IFsuLi5zdGF0ZS5zcGxpdE1hcHNdO1xuICBjb25zdCB1bm1lcmdlZCA9IFtdO1xuICBzcGxpdE1hcHMuZm9yRWFjaCgoc20sIGkpID0+IHtcbiAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoc20ubGF5ZXJzKTtcbiAgICBpZiAoZW50cmllcy5sZW5ndGggPiAwKSB7XG4gICAgICBlbnRyaWVzLmZvckVhY2goKFtpZCwgdmFsdWVdKSA9PiB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGxheWVyIGV4aXN0c1xuICAgICAgICBjb25zdCBwdXNoVG8gPSBzdGF0ZS5sYXllcnMuZmluZChsID0+IGwuaWQgPT09IGlkKSA/IG1lcmdlZCA6IHVubWVyZ2VkO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBtYXAgcGFuZWwgaWYgY3VycmVudCBtYXAgaXMgbm90IHNwbGl0XG4gICAgICAgIHB1c2hUb1tpXSA9IHB1c2hUb1tpXSB8fCB7XG4gICAgICAgICAgLy8ga2VlcCBpZFxuICAgICAgICAgIC4uLnNtLFxuICAgICAgICAgIGxheWVyczogcHVzaFRvID09PSBtZXJnZWQgPyBnZXRJbml0aWFsTWFwTGF5ZXJzRm9yU3BsaXRNYXAoc3RhdGUubGF5ZXJzKSA6IFtdXG4gICAgICAgIH07XG4gICAgICAgIHB1c2hUb1tpXS5sYXllcnMgPSB7XG4gICAgICAgICAgLi4ucHVzaFRvW2ldLmxheWVycyxcbiAgICAgICAgICBbaWRdOiB2YWx1ZVxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlIGFyZSBtZXJnaW5nIGlmIHRoZXJlIGFyZSBubyBsYXllcnMgaW4gYm90aCBzcGxpdCBtYXBcbiAgICAgIG1lcmdlZC5wdXNoKHNtKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgc3BsaXRNYXBzOiBtZXJnZWQsXG4gICAgc3BsaXRNYXBzVG9CZU1lcmdlZDogWy4uLnN0YXRlLnNwbGl0TWFwc1RvQmVNZXJnZWQsIC4uLnVubWVyZ2VkXVxuICB9O1xufVxuXG4vKipcbiAqIE1lcmdlIGVmZmVjdHMgd2l0aCBzYXZlZCBjb25maWdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlRWZmZWN0czxTIGV4dGVuZHMgVmlzU3RhdGU+KFxuICBzdGF0ZTogUyxcbiAgZWZmZWN0czogTm9uTnVsbGFibGU8UGFyc2VkQ29uZmlnWyd2aXNTdGF0ZSddPlsnZWZmZWN0cyddLFxuICBmcm9tQ29uZmlnPzogYm9vbGVhblxuKTogUyB7XG4gIGNvbnN0IG5ld0VmZmVjdHMgPSBbXG4gICAgLi4uc3RhdGUuZWZmZWN0cyxcbiAgICAuLi4oZWZmZWN0cyB8fCBbXSlcbiAgICAgIC5tYXAoZWZmZWN0ID0+IHtcbiAgICAgICAgcmV0dXJuIGZyb21Db25maWdcbiAgICAgICAgICA/IGNyZWF0ZUVmZmVjdChcbiAgICAgICAgICAgICAgZGVlcG1lcmdlLmFsbChbXG4gICAgICAgICAgICAgICAgZWZmZWN0LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIC8vIGNvbGxhcHNlIGFsbCBwYW5lbHMgd2hlbiBsb2FkaW5nIGVmZmVjdHNcbiAgICAgICAgICAgICAgICAgIGlzQ29uZmlnQWN0aXZlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgXSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IChlZmZlY3QgYXMgRWZmZWN0VHlwZSk7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcihlZmZlY3QgPT4ge1xuICAgICAgICByZXR1cm4gQm9vbGVhbihlZmZlY3QgJiYgZWZmZWN0LmlzVmFsaWRUb1NhdmUoKSk7XG4gICAgICB9KVxuICBdO1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGVmZmVjdHM6IG5ld0VmZmVjdHMsXG4gICAgZWZmZWN0T3JkZXI6IG5ld0VmZmVjdHMubWFwKGVmZmVjdCA9PiBlZmZlY3QuaWQpXG4gIH07XG59XG5cbi8qKlxuICogTWVyZ2UgYW5ub3RhdGlvbnMgd2l0aCBzYXZlZCBjb25maWdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlQW5ub3RhdGlvbnM8UyBleHRlbmRzIFZpc1N0YXRlPihzdGF0ZTogUywgYW5ub3RhdGlvbnM6IGFueVtdKTogUyB7XG4gIGlmICghYW5ub3RhdGlvbnMgfHwgIWFubm90YXRpb25zLmxlbmd0aCkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuICBjb25zdCBleGlzdGluZ0lkcyA9IG5ldyBTZXQoc3RhdGUuYW5ub3RhdGlvbnMubWFwKGEgPT4gYS5pZCkpO1xuICBjb25zdCB2YWxpZEFubm90YXRpb25zID0gYW5ub3RhdGlvbnNcbiAgICAuZmlsdGVyKFxuICAgICAgYSA9PlxuICAgICAgICBhICYmXG4gICAgICAgIGEuaWQgJiZcbiAgICAgICAgIWV4aXN0aW5nSWRzLmhhcyhhLmlkKSAmJlxuICAgICAgICBpc0Fubm90YXRpb25LaW5kKGEua2luZCkgJiZcbiAgICAgICAgQXJyYXkuaXNBcnJheShhLmFuY2hvclBvaW50KSAmJlxuICAgICAgICBhLmFuY2hvclBvaW50Lmxlbmd0aCA9PT0gMlxuICAgIClcbiAgICAubWFwKGEgPT4gKHtcbiAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgIGF1dG9TaXplOiB0cnVlLFxuICAgICAgYXV0b1NpemVZOiB0cnVlLFxuICAgICAgbGFiZWw6ICcnLFxuICAgICAgbGluZUNvbG9yOiBJTklUSUFMX0FOTk9UQVRJT05fTElORV9DT0xPUixcbiAgICAgIGxpbmVXaWR0aDogSU5JVElBTF9BTk5PVEFUSU9OX0xJTkVfV0lEVEgsXG4gICAgICB0ZXh0V2lkdGg6IDAsXG4gICAgICB0ZXh0SGVpZ2h0OiAwLFxuICAgICAgLi4uYVxuICAgIH0pKTtcbiAgaWYgKCF2YWxpZEFubm90YXRpb25zLmxlbmd0aCkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGFubm90YXRpb25zOiBbLi4uc3RhdGUuYW5ub3RhdGlvbnMsIC4uLnZhbGlkQW5ub3RhdGlvbnNdXG4gIH07XG59XG5cbi8qKlxuICogTWVyZ2UgaW50ZXJhY3Rpb25Db25maWcudG9vbHRpcCB3aXRoIHNhdmVkIGNvbmZpZyxcbiAqIHZhbGlkYXRlIGZpZWxkc1RvU2hvd1xuICpcbiAqIEBwYXJhbSBzdGF0ZVxuICogQHBhcmFtIHRvb2x0aXBDb25maWdcbiAqIEByZXR1cm4gLSB7bWVyZ2VkVG9vbHRpcDoge30sIHVubWVyZ2VkVG9vbHRpcDoge319XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUludGVyYWN0aW9uVG9vbHRpcENvbmZpZyhcbiAgc3RhdGU6IFZpc1N0YXRlLFxuICB0b29sdGlwQ29uZmlnOiBQaWNrPFRvb2x0aXBJbmZvWydjb25maWcnXSwgJ2ZpZWxkc1RvU2hvdyc+IHwgbnVsbCA9IG51bGxcbikge1xuICBjb25zdCB1bm1lcmdlZFRvb2x0aXA6IFRvb2x0aXBJbmZvWydjb25maWcnXVsnZmllbGRzVG9TaG93J10gPSB7fTtcbiAgY29uc3QgbWVyZ2VkVG9vbHRpcDogVG9vbHRpcEluZm9bJ2NvbmZpZyddWydmaWVsZHNUb1Nob3cnXSA9IHt9O1xuXG4gIGlmIChcbiAgICAhdG9vbHRpcENvbmZpZyB8fFxuICAgICF0b29sdGlwQ29uZmlnLmZpZWxkc1RvU2hvdyB8fFxuICAgICFPYmplY3Qua2V5cyh0b29sdGlwQ29uZmlnLmZpZWxkc1RvU2hvdykubGVuZ3RoXG4gICkge1xuICAgIHJldHVybiB7bWVyZ2VkVG9vbHRpcCwgdW5tZXJnZWRUb29sdGlwfTtcbiAgfVxuXG4gIGZvciAoY29uc3QgZGF0YUlkIGluIHRvb2x0aXBDb25maWcuZmllbGRzVG9TaG93KSB7XG4gICAgaWYgKCFzdGF0ZS5kYXRhc2V0c1tkYXRhSWRdIHx8IHN0YXRlLmlzTWVyZ2luZ0RhdGFzZXRzW2RhdGFJZF0pIHtcbiAgICAgIC8vIGlzIG5vdCB5ZXQgbG9hZGVkXG4gICAgICB1bm1lcmdlZFRvb2x0aXBbZGF0YUlkXSA9IHRvb2x0aXBDb25maWcuZmllbGRzVG9TaG93W2RhdGFJZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIGRhdGFzZXQgaXMgbG9hZGVkXG4gICAgICBjb25zdCBhbGxGaWVsZHMgPSBzdGF0ZS5kYXRhc2V0c1tkYXRhSWRdLmZpZWxkcy5tYXAoZCA9PiBkLm5hbWUpO1xuICAgICAgY29uc3QgZm91bmRGaWVsZHNUb1Nob3cgPSB0b29sdGlwQ29uZmlnLmZpZWxkc1RvU2hvd1tkYXRhSWRdLmZpbHRlcihmaWVsZCA9PlxuICAgICAgICBhbGxGaWVsZHMuaW5jbHVkZXMoZmllbGQubmFtZSlcbiAgICAgICk7XG5cbiAgICAgIG1lcmdlZFRvb2x0aXBbZGF0YUlkXSA9IGZvdW5kRmllbGRzVG9TaG93O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7bWVyZ2VkVG9vbHRpcCwgdW5tZXJnZWRUb29sdGlwfTtcbn1cbi8qKlxuICogTWVyZ2UgbGF5ZXJCbGVuZGluZyB3aXRoIHNhdmVkXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VMYXllckJsZW5kaW5nPFMgZXh0ZW5kcyBWaXNTdGF0ZT4oXG4gIHN0YXRlOiBTLFxuICBsYXllckJsZW5kaW5nOiBOb25OdWxsYWJsZTxQYXJzZWRDb25maWdbJ3Zpc1N0YXRlJ10+WydsYXllckJsZW5kaW5nJ11cbik6IFMge1xuICBpZiAobGF5ZXJCbGVuZGluZyAmJiBMQVlFUl9CTEVORElOR1NbbGF5ZXJCbGVuZGluZ10pIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBsYXllckJsZW5kaW5nXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBzdGF0ZTtcbn1cblxuLyoqXG4gKiBDb21iaW5lcyBtdWx0aXBsZSBsYXllciBibGVuZGluZyBjb25maWdzIGludG8gYSBzaW5nbGUgc3RyaW5nXG4gKiBieSByZXR1cm5pbmcgdGhlIG9uZSB3aXRoIHRoZSBoaWdoZXN0IG9jY3VycmVuY2VcbiAqL1xuZnVuY3Rpb24gY29tYmluZUxheWVyQmxlbmRpbmdDb25maWdzKGNvbmZpZ3M6IHN0cmluZ1tdKTogc3RyaW5nIHwgbnVsbCB7XG4gIC8vIHJldHVybiB0aGUgbW9kZSBvZiB0aGUgbGF5ZXIgYmxlbmRpbmcgdHlwZVxuICByZXR1cm4gZ2V0VmFsdWVXaXRoSGlnaGVzdE9jY3VycmVuY2UoY29uZmlncyk7XG59XG5cbi8qKlxuICogTWVyZ2Ugb3ZlcmxheUJsZW5kaW5nIHdpdGggc2F2ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlT3ZlcmxheUJsZW5kaW5nPFMgZXh0ZW5kcyBWaXNTdGF0ZT4oXG4gIHN0YXRlOiBTLFxuICBvdmVybGF5QmxlbmRpbmc6IE5vbk51bGxhYmxlPFBhcnNlZENvbmZpZ1sndmlzU3RhdGUnXT5bJ292ZXJsYXlCbGVuZGluZyddXG4pOiBTIHtcbiAgaWYgKG92ZXJsYXlCbGVuZGluZyAmJiBPVkVSTEFZX0JMRU5ESU5HU1tvdmVybGF5QmxlbmRpbmddKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN0YXRlLFxuICAgICAgb3ZlcmxheUJsZW5kaW5nXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBzdGF0ZTtcbn1cblxuLyoqXG4gKiBDb21iaW5lcyBtdWx0aXBsZSBvdmVybGF5IGJsZW5kaW5nIGNvbmZpZ3MgaW50byBhIHNpbmdsZSBzdHJpbmdcbiAqIGJ5IHJldHVybmluZyB0aGUgb25lIHdpdGggdGhlIGhpZ2hlc3Qgb2NjdXJyZW5jZVxuICoqL1xuZnVuY3Rpb24gY29tYmluZU92ZXJsYXlCbGVuZGluZ0NvbmZpZ3MoY29uZmlnczogc3RyaW5nW10pOiBzdHJpbmcgfCBudWxsIHtcbiAgLy8gcmV0dXJuIHRoZSBtb2RlIG9mIHRoZSBvdmVybGF5IGJsZW5kaW5nIHR5cGVcbiAgcmV0dXJuIGdldFZhbHVlV2l0aEhpZ2hlc3RPY2N1cnJlbmNlKGNvbmZpZ3MpO1xufVxuXG4vKipcbiAqIE1lcmdlIGFuaW1hdGlvbiBjb25maWdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlQW5pbWF0aW9uQ29uZmlnPFMgZXh0ZW5kcyBWaXNTdGF0ZT4oXG4gIHN0YXRlOiBTLFxuICBhbmltYXRpb246IE5vbk51bGxhYmxlPFBhcnNlZENvbmZpZ1sndmlzU3RhdGUnXT5bJ2FuaW1hdGlvbkNvbmZpZyddXG4pOiBTIHtcbiAgaWYgKGFuaW1hdGlvbiAmJiBhbmltYXRpb24uY3VycmVudFRpbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBhbmltYXRpb25Db25maWc6IHtcbiAgICAgICAgLi4uc3RhdGUuYW5pbWF0aW9uQ29uZmlnLFxuICAgICAgICAuLi5hbmltYXRpb24sXG4gICAgICAgIGRvbWFpbjogbnVsbFxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gc3RhdGU7XG59XG5cbmZ1bmN0aW9uIGNvbWJpbmVBbmltYXRpb25Db25maWdzKGNvbmZpZ3M6IFNhdmVkQW5pbWF0aW9uQ29uZmlnW10pOiBTYXZlZEFuaW1hdGlvbkNvbmZpZyB7XG4gIC8vIGdldCB0aGUgc21hbGxlc3QgdmFsdWVzIG9mIGN1cnJlbnRUaW1lIGFuZCBzcGVlZCBhbW9uZyBhbGwgY29uZmlnc1xuICByZXR1cm4ge1xuICAgIGN1cnJlbnRUaW1lOiBhZ2dyZWdhdGUoY29uZmlncywgQUdHUkVHQVRJT05fVFlQRVMubWluaW11bSwgYyA9PiBjLmN1cnJlbnRUaW1lKSA/PyBudWxsLFxuICAgIHNwZWVkOiBhZ2dyZWdhdGUoY29uZmlncywgQUdHUkVHQVRJT05fVFlQRVMubWluaW11bSwgYyA9PiBjLnNwZWVkKSA/PyBudWxsXG4gIH07XG59XG5cbi8qKlxuICogVmFsaWRhdGUgc2F2ZWQgbGF5ZXIgY29sdW1ucyB3aXRoIG5ldyBkYXRhLFxuICogdXBkYXRlIGZpZWxkSWR4IGJhc2VkIG9uIG5ldyBmaWVsZHNcbiAqXG4gKiBAcGFyYW0gZmllbGRzXG4gKiBAcGFyYW0gc2F2ZWRDb2xzXG4gKiBAcGFyYW0gZW1wdHlDb2xzXG4gKiBAcGFyYW0gb3B0aW9uc1xuICogQHJldHVybiAtIHZhbGlkYXRlZCBjb2x1bW5zIG9yIG51bGxcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVTYXZlZExheWVyQ29sdW1ucyhcbiAgZmllbGRzOiBLZXBsZXJUYWJsZVsnZmllbGRzJ10sXG4gIHNhdmVkQ29sczoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZztcbiAgfSA9IHt9LFxuICBlbXB0eUNvbHM6IExheWVyQ29sdW1ucyxcbiAgb3B0aW9uczoge3Rocm93T25FcnJvcj86IGJvb2xlYW59ID0ge31cbikge1xuICAvLyBQcmVwYXJlIGNvbHVtbnMgZm9yIHRoZSB2YWxpZGF0b3JcbiAgY29uc3QgY29sdW1uczogdHlwZW9mIGVtcHR5Q29scyA9IHt9O1xuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhlbXB0eUNvbHMpKSB7XG4gICAgY29sdW1uc1trZXldID0gey4uLmVtcHR5Q29sc1trZXldfTtcblxuICAgIGNvbnN0IHNhdmVkID0gc2F2ZWRDb2xzW2tleV07XG4gICAgaWYgKHNhdmVkKSB7XG4gICAgICBjb25zdCBmaWVsZElkeCA9IGZpZWxkcy5maW5kSW5kZXgoKHtuYW1lfSkgPT4gbmFtZSA9PT0gc2F2ZWQpO1xuXG4gICAgICBpZiAoZmllbGRJZHggPiAtMSkge1xuICAgICAgICAvLyB1cGRhdGUgZm91bmQgY29sdW1uc1xuICAgICAgICBjb2x1bW5zW2tleV0uZmllbGRJZHggPSBmaWVsZElkeDtcbiAgICAgICAgY29sdW1uc1trZXldLnZhbHVlID0gc2F2ZWQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gZmluZCBhY3R1YWwgY29sdW1uIGZpZWxkSWR4LCBpbiBjYXNlIGl0IGhhcyBjaGFuZ2VkXG4gIGNvbnN0IGFsbENvbEZvdW5kID0gT2JqZWN0LmtleXMoY29sdW1ucykuZXZlcnkoa2V5ID0+XG4gICAgdmFsaWRhdGVDb2x1bW4oY29sdW1uc1trZXldLCBjb2x1bW5zLCBmaWVsZHMpXG4gICk7XG5cbiAgY29uc3QgcnYgPSBhbGxDb2xGb3VuZCA/IGNvbHVtbnMgOiBudWxsO1xuICBpZiAob3B0aW9ucy50aHJvd09uRXJyb3IpIHtcbiAgICBjb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3Qua2V5cyhlbXB0eUNvbHMpLmZpbHRlcihrID0+ICFlbXB0eUNvbHNba10ub3B0aW9uYWwpO1xuICAgIGNvbnN0IG1pc3NpbmdDb2x1bW5zID0gcmVxdWlyZWRDb2x1bW5zLmZpbHRlcihrID0+ICFjb2x1bW5zPy5ba10udmFsdWUpO1xuICAgIGlmIChtaXNzaW5nQ29sdW1ucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTGF5ZXIgaGFzIG1pc3Npbmcgb3IgaW52YWxpZCBjb2x1bW5zOiAke21pc3NpbmdDb2x1bW5zLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZ0NvbHVtbnMgPSBPYmplY3Qua2V5cyhzYXZlZENvbHMpO1xuICAgIGNvbnN0IGludmFsaWRDb2x1bW5zID0gY29uZmlnQ29sdW1ucy5maWx0ZXIoayA9PiAhY29sdW1ucz8uW2tdPy52YWx1ZSk7XG4gICAgaWYgKGludmFsaWRDb2x1bW5zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMYXllciBoYXMgaW52YWxpZCBjb2x1bW5zOiAke2ludmFsaWRDb2x1bW5zLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJ2O1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIGxheWVyIGNvbHVtblxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVDb2x1bW4oXG4gIGNvbHVtbjogTGF5ZXJDb2x1bW4gJiB7dmFsaWRhdG9yPzogdHlwZW9mIHZhbGlkYXRlQ29sdW1ufSxcbiAgY29sdW1uczogTGF5ZXJDb2x1bW5zLFxuICBhbGxGaWVsZHM6IEtlcGxlclRhYmxlWydmaWVsZHMnXVxuKTogYm9vbGVhbiB7XG4gIGlmIChjb2x1bW4ub3B0aW9uYWwgfHwgY29sdW1uLnZhbHVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGNvbHVtbi52YWxpZGF0b3IpIHtcbiAgICByZXR1cm4gY29sdW1uLnZhbGlkYXRvcihjb2x1bW4sIGNvbHVtbnMsIGFsbEZpZWxkcyk7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHNhdmVkIHRleHQgbGFiZWwgY29uZmlnIHdpdGggbmV3IGRhdGFcbiAqIHJlZmVyIHRvIHZpcy1zdGF0ZS1zY2hlbWEuanMgVGV4dExhYmVsU2NoZW1hVjFcbiAqXG4gKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGZpZWxkc1xuICogQHBhcmFtIHtPYmplY3R9IHNhdmVkVGV4dExhYmVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7T2JqZWN0fSAtIHZhbGlkYXRlZCB0ZXh0bGFiZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlU2F2ZWRUZXh0TGFiZWwoXG4gIGZpZWxkcyxcbiAgW2xheWVyVGV4dExhYmVsXSxcbiAgc2F2ZWRUZXh0TGFiZWwsXG4gIG9wdGlvbnM6IHt0aHJvd09uRXJyb3I/OiBib29sZWFufSA9IHt9XG4pIHtcbiAgY29uc3Qgc2F2ZWRUZXh0TGFiZWxzID0gQXJyYXkuaXNBcnJheShzYXZlZFRleHRMYWJlbCkgPyBzYXZlZFRleHRMYWJlbCA6IFtzYXZlZFRleHRMYWJlbF07XG5cbiAgLy8gdmFsaWRhdGUgZmllbGRcbiAgcmV0dXJuIHNhdmVkVGV4dExhYmVscy5tYXAodGV4dExhYmVsID0+IHtcbiAgICBjb25zdCBmaWVsZCA9IHRleHRMYWJlbC5maWVsZFxuICAgICAgPyBmaWVsZHMuZmluZChmZCA9PlxuICAgICAgICAgIE9iamVjdC5rZXlzKHRleHRMYWJlbC5maWVsZCkuZXZlcnkoa2V5ID0+IHRleHRMYWJlbC5maWVsZFtrZXldID09PSBmZFtrZXldKVxuICAgICAgICApXG4gICAgICA6IG51bGw7XG5cbiAgICBpZiAoZmllbGQgPT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnRocm93T25FcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMYXllciBoYXMgaW52YWxpZCB0ZXh0IGxhYmVsIGZpZWxkOiAke0pTT04uc3RyaW5naWZ5KHRleHRMYWJlbC5maWVsZCl9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGxheWVyVGV4dExhYmVsKS5yZWR1Y2UoXG4gICAgICAoYWNjdSwga2V5KSA9PiAoe1xuICAgICAgICAuLi5hY2N1LFxuICAgICAgICBba2V5XToga2V5ID09PSAnZmllbGQnID8gZmllbGQgOiB0ZXh0TGFiZWxba2V5XSB8fCBsYXllclRleHRMYWJlbFtrZXldXG4gICAgICB9KSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfSk7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgc2F2ZWQgdmlzdWFsIGNoYW5uZWxzIGNvbmZpZyB3aXRoIG5ldyBkYXRhLFxuICogcmVmZXIgdG8gdmlzLXN0YXRlLXNjaGVtYS5qcyBWaXN1YWxDaGFubmVsU2NoZW1hVjFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlU2F2ZWRWaXN1YWxDaGFubmVscyhcbiAgZmllbGRzOiBLZXBsZXJUYWJsZVsnZmllbGRzJ10sXG4gIG5ld0xheWVyOiBMYXllcixcbiAgc2F2ZWRMYXllcjogUGFyc2VkTGF5ZXIsXG4gIG9wdGlvbnM6IHt0aHJvd09uRXJyb3I/OiBib29sZWFufSA9IHt9XG4pOiBudWxsIHwgTGF5ZXIge1xuICBPYmplY3QudmFsdWVzKG5ld0xheWVyLnZpc3VhbENoYW5uZWxzKS5mb3JFYWNoKCh7ZmllbGQsIHNjYWxlLCBrZXl9KSA9PiB7XG4gICAgbGV0IGZvdW5kRmllbGQ7XG4gICAgaWYgKHNhdmVkTGF5ZXIuY29uZmlnKSB7XG4gICAgICBpZiAoc2F2ZWRMYXllci5jb25maWdbZmllbGRdKSB7XG4gICAgICAgIGZvdW5kRmllbGQgPSBmaWVsZHMuZmluZChcbiAgICAgICAgICBmZCA9PiBzYXZlZExheWVyLmNvbmZpZyAmJiBmZC5uYW1lID09PSBzYXZlZExheWVyLmNvbmZpZ1tmaWVsZF0ubmFtZVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmb3VuZENoYW5uZWwgPSB7XG4gICAgICAgIC4uLihmb3VuZEZpZWxkID8ge1tmaWVsZF06IGZvdW5kRmllbGR9IDoge30pLFxuICAgICAgICAuLi4oc2F2ZWRMYXllci5jb25maWdbc2NhbGVdID8ge1tzY2FsZV06IHNhdmVkTGF5ZXIuY29uZmlnW3NjYWxlXX0gOiB7fSlcbiAgICAgIH07XG4gICAgICBpZiAoT2JqZWN0LmtleXMoZm91bmRDaGFubmVsKS5sZW5ndGgpIHtcbiAgICAgICAgbmV3TGF5ZXIudXBkYXRlTGF5ZXJDb25maWcoZm91bmRDaGFubmVsKTtcbiAgICAgIH1cblxuICAgICAgbmV3TGF5ZXIudmFsaWRhdGVWaXN1YWxDaGFubmVsKGtleSk7XG4gICAgICBpZiAob3B0aW9ucy50aHJvd09uRXJyb3IpIHtcbiAgICAgICAgY29uc3QgZmllbGROYW1lID0gc2F2ZWRMYXllci5jb25maWc/LltmaWVsZF0/Lm5hbWU7XG4gICAgICAgIGlmIChmaWVsZE5hbWUgJiYgZmllbGROYW1lICE9PSBuZXdMYXllci5jb25maWdbZmllbGRdPy5uYW1lKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBMYXllciBoYXMgaW52YWxpZCB2aXN1YWwgY2hhbm5lbCBmaWVsZDogJHtmaWVsZH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiBuZXdMYXllcjtcbn1cblxudHlwZSBWYWxpZGF0ZUxheWVyT3B0aW9uID0ge1xuICBhbGxvd0VtcHR5Q29sdW1uPzogYm9vbGVhbjtcbiAgdGhyb3dPbkVycm9yPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUxheWVyc0J5RGF0YXNldHMoXG4gIGRhdGFzZXRzOiBEYXRhc2V0cyxcbiAgbGF5ZXJDbGFzc2VzOiBWaXNTdGF0ZVsnbGF5ZXJDbGFzc2VzJ10sXG4gIGxheWVyczogTm9uTnVsbGFibGU8UGFyc2VkQ29uZmlnWyd2aXNTdGF0ZSddPlsnbGF5ZXJzJ10gPSBbXSxcbiAgb3B0aW9ucz86IFZhbGlkYXRlTGF5ZXJPcHRpb25cbikge1xuICBjb25zdCB2YWxpZGF0ZWQ6IExheWVyW10gPSBbXTtcbiAgY29uc3QgZmFpbGVkOiBOb25OdWxsYWJsZTxQYXJzZWRDb25maWdbJ3Zpc1N0YXRlJ10+WydsYXllcnMnXSA9IFtdO1xuXG4gIGxheWVycy5mb3JFYWNoKGxheWVyID0+IHtcbiAgICBsZXQgdmFsaWRhdGVMYXllcjogTGF5ZXIgfCBudWxsID0gbnVsbDtcblxuICAgIGlmIChsYXllcj8uY29uZmlnPy5kYXRhSWQpIHtcbiAgICAgIGlmIChkYXRhc2V0c1tsYXllci5jb25maWcuZGF0YUlkXSkge1xuICAgICAgICAvLyBkYXRhc2V0cyBhcmUgYWxyZWFkeSBsb2FkZWRcbiAgICAgICAgdmFsaWRhdGVMYXllciA9IHZhbGlkYXRlTGF5ZXJXaXRoRGF0YShcbiAgICAgICAgICBkYXRhc2V0c1tsYXllci5jb25maWcuZGF0YUlkXSxcbiAgICAgICAgICBsYXllcixcbiAgICAgICAgICBsYXllckNsYXNzZXMsXG4gICAgICAgICAgb3B0aW9uc1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh2YWxpZGF0ZUxheWVyKSB7XG4gICAgICB2YWxpZGF0ZWQucHVzaCh2YWxpZGF0ZUxheWVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZGF0YXNldHMgbm90IHlldCBsb2FkZWRcbiAgICAgIGZhaWxlZC5wdXNoKGxheWVyKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7dmFsaWRhdGVkLCBmYWlsZWR9O1xufVxuXG4vKipcbiAqIEdldCByZXF1aXJlZCBjb2x1bW5zIGZvciB2YWxpZGF0aW9uIGJhc2VkIG9uIGNvbHVtbiBtb2RlXG4gKi9cbmZ1bmN0aW9uIF9nZXRDb2x1bW5Db25maWdGb3JWYWxpZGF0aW9uKG5ld0xheWVyKSB7XG4gIC8vIGZpbmQgY29sdW1uIGZpZWxkSWR4XG4gIGxldCBjb2x1bW5Db25maWcgPSBuZXdMYXllci5nZXRMYXllckNvbHVtbnMoKTtcbiAgLy8gaWYgY29sdW1uTW9kZSBpcyBkZWZpbmVkLCBmaW5kIGNvbHVtbiBtb2RlIGNvbmZpZ1xuICBjb25zdCBjb2xNb2RlQ29uZmlnID0gbmV3TGF5ZXIuY29uZmlnLmNvbHVtbk1vZGVcbiAgICA/IChuZXdMYXllci5zdXBwb3J0ZWRDb2x1bW5Nb2RlcyB8fCBbXSkuZmluZChcbiAgICAgICAgY29sTW9kZSA9PiBjb2xNb2RlLmtleSA9PT0gbmV3TGF5ZXIuY29uZmlnLmNvbHVtbk1vZGVcbiAgICAgIClcbiAgICA6IG51bGw7XG5cbiAgaWYgKGNvbE1vZGVDb25maWcpIHtcbiAgICAvLyBvbmx5IHZhbGlkYXRlIGNvbHVtbnMgaW4gY29sdW1uIG1vZGVcbiAgICBjb2x1bW5Db25maWcgPSBbXG4gICAgICAuLi4oY29sTW9kZUNvbmZpZy5yZXF1aXJlZENvbHVtbnMgfHwgW10pLFxuICAgICAgLi4uKGNvbE1vZGVDb25maWcub3B0aW9uYWxDb2x1bW5zIHx8IFtdKVxuICAgIF0ucmVkdWNlKFxuICAgICAgKGFjY3UsIGtleSkgPT4gKHtcbiAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgW2tleV06IGNvbHVtbkNvbmZpZ1trZXldXG4gICAgICB9KSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBjb2x1bW5Db25maWc7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgc2F2ZWQgbGF5ZXIgY29uZmlnIHdpdGggbmV3IGRhdGEsXG4gKiB1cGRhdGUgZmllbGRJZHggYmFzZWQgb24gbmV3IGZpZWxkc1xuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlTGF5ZXJXaXRoRGF0YShcbiAgZGF0YXNldDogS2VwbGVyVGFibGUsXG4gIHNhdmVkTGF5ZXI6IFBhcnNlZExheWVyLFxuICBsYXllckNsYXNzZXM6IFZpc1N0YXRlWydsYXllckNsYXNzZXMnXSxcbiAgb3B0aW9uczogVmFsaWRhdGVMYXllck9wdGlvbiA9IHt9XG4pOiBMYXllciB8IG51bGwge1xuICBjb25zdCB7ZmllbGRzLCBpZDogZGF0YUlkfSA9IGRhdGFzZXQ7XG4gIGNvbnN0IHt0eXBlfSA9IHNhdmVkTGF5ZXI7XG4gIGNvbnN0IHt0aHJvd09uRXJyb3J9ID0gb3B0aW9ucztcbiAgLy8gbGF5ZXIgZG9lc250IGhhdmUgYSB2YWxpZCB0eXBlXG4gIGlmICghdHlwZSB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGxheWVyQ2xhc3NlcywgdHlwZSkgfHwgIXNhdmVkTGF5ZXIuY29uZmlnKSB7XG4gICAgaWYgKHRocm93T25FcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMYXllciBoYXMgaW52YWxpZCB0eXBlIFwiJHt0eXBlfVwiIG9yIGNvbmZpZyBpcyBtaXNzaW5nYCk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbGV0IG5ld0xheWVyID0gbmV3IGxheWVyQ2xhc3Nlc1t0eXBlXSh7XG4gICAgaWQ6IHNhdmVkTGF5ZXIuaWQsXG4gICAgZGF0YUlkLFxuICAgIGxhYmVsOiBzYXZlZExheWVyLmNvbmZpZy5sYWJlbCxcbiAgICBjb2xvcjogc2F2ZWRMYXllci5jb25maWcuY29sb3IsXG4gICAgaXNWaXNpYmxlOiBzYXZlZExheWVyLmNvbmZpZy5pc1Zpc2libGUsXG4gICAgaGlkZGVuOiBzYXZlZExheWVyLmNvbmZpZy5oaWRkZW4sXG4gICAgY29sdW1uTW9kZTogc2F2ZWRMYXllci5jb25maWcuY29sdW1uTW9kZSxcbiAgICBoaWdobGlnaHRDb2xvcjogc2F2ZWRMYXllci5jb25maWcuaGlnaGxpZ2h0Q29sb3JcbiAgfSk7XG5cbiAgY29uc3QgY29sdW1uQ29uZmlnID0gX2dldENvbHVtbkNvbmZpZ0ZvclZhbGlkYXRpb24obmV3TGF5ZXIpO1xuXG4gIGlmIChPYmplY3Qua2V5cyhjb2x1bW5Db25maWcpKSB7XG4gICAgY29uc3QgY29sdW1ucyA9IHZhbGlkYXRlU2F2ZWRMYXllckNvbHVtbnMoXG4gICAgICBmaWVsZHMsXG4gICAgICBzYXZlZExheWVyLmNvbmZpZy5jb2x1bW5zLFxuICAgICAgY29sdW1uQ29uZmlnLFxuICAgICAgb3B0aW9uc1xuICAgICk7XG4gICAgaWYgKGNvbHVtbnMpIHtcbiAgICAgIG5ld0xheWVyLnVwZGF0ZUxheWVyQ29uZmlnKHtcbiAgICAgICAgY29sdW1uczoge1xuICAgICAgICAgIC4uLm5ld0xheWVyLmNvbmZpZy5jb2x1bW5zLFxuICAgICAgICAgIC4uLmNvbHVtbnNcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICghb3B0aW9ucy5hbGxvd0VtcHR5Q29sdW1uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBjb25zdCB0ZXh0TGFiZWwgPVxuICAgIHNhdmVkTGF5ZXIuY29uZmlnLnRleHRMYWJlbCAmJiBuZXdMYXllci5jb25maWcudGV4dExhYmVsXG4gICAgICA/IHZhbGlkYXRlU2F2ZWRUZXh0TGFiZWwoXG4gICAgICAgICAgZmllbGRzLFxuICAgICAgICAgIG5ld0xheWVyLmNvbmZpZy50ZXh0TGFiZWwsXG4gICAgICAgICAgc2F2ZWRMYXllci5jb25maWcudGV4dExhYmVsLFxuICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgKVxuICAgICAgOiBuZXdMYXllci5jb25maWcudGV4dExhYmVsO1xuXG4gIC8vIGNvcHkgdmlzQ29uZmlnIG92ZXIgdG8gZW1wdHlMYXllciB0byBtYWtlIHN1cmUgaXQgaGFzIGFsbCB0aGUgcHJvcHNcbiAgY29uc3QgY29waWVkVmlzQ29uZmlnID0gbmV3TGF5ZXIuY29weUxheWVyQ29uZmlnKFxuICAgIG5ld0xheWVyLmNvbmZpZy52aXNDb25maWcsXG4gICAgc2F2ZWRMYXllci5jb25maWcudmlzQ29uZmlnIHx8IHt9LFxuICAgIHtcbiAgICAgIHNoYWxsb3dDb3B5OiBbJ2NvbG9yUmFuZ2UnLCAnc3Ryb2tlQ29sb3JSYW5nZSddXG4gICAgfVxuICApO1xuXG4gIC8vIGNhbGwgbGF5ZXIgbWV0aG9kcyB0byB2YWxpZGF0ZSB2aXNDb25maWcgd2hlbiBzd2l0Y2hpbmcgZGF0YXNldFxuICBjb25zdCB2aXNDb25maWcgPSBuZXdMYXllci52YWxpZGF0ZVZpc0NvbmZpZ1xuICAgID8gbmV3TGF5ZXIudmFsaWRhdGVWaXNDb25maWcoZGF0YXNldCwgY29waWVkVmlzQ29uZmlnKVxuICAgIDogY29waWVkVmlzQ29uZmlnO1xuXG4gIG5ld0xheWVyLnVwZGF0ZUxheWVyQ29uZmlnKHtcbiAgICB2aXNDb25maWcsXG4gICAgdGV4dExhYmVsXG4gIH0pO1xuXG4gIC8vIHZpc3VhbCBjaGFubmVsIGZpZWxkIGlzIHNhdmVkIHRvIGJlIHtuYW1lLCB0eXBlfVxuICAvLyBmaW5kIHZpc3VhbCBjaGFubmVsIGZpZWxkIGJ5IG1hdGNoaW5nIGJvdGggbmFtZSBhbmQgdHlwZVxuICAvLyByZWZlciB0byB2aXMtc3RhdGUtc2NoZW1hLmpzIFZpc3VhbENoYW5uZWxTY2hlbWFWMVxuICBuZXdMYXllciA9IHZhbGlkYXRlU2F2ZWRWaXN1YWxDaGFubmVscyhmaWVsZHMsIG5ld0xheWVyLCBzYXZlZExheWVyLCBvcHRpb25zKTtcblxuICBpZiAodGhyb3dPbkVycm9yKSB7XG4gICAgaWYgKCFuZXdMYXllci5pc1ZhbGlkVG9TYXZlKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTGF5ZXIgaXMgbm90IHZhbGlkIHRvIHNhdmU6ICR7bmV3TGF5ZXIuaWR9YCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ld0xheWVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VFZGl0b3I8UyBleHRlbmRzIFZpc1N0YXRlPihzdGF0ZTogUywgc2F2ZWRFZGl0b3I6IFNhdmVkRWRpdG9yKSB7XG4gIGlmICghc2F2ZWRFZGl0b3IpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBlZGl0b3I6IHtcbiAgICAgIC4uLnN0YXRlLmVkaXRvcixcbiAgICAgIGZlYXR1cmVzOiBbLi4uc3RhdGUuZWRpdG9yLmZlYXR1cmVzLCAuLi4oc2F2ZWRFZGl0b3IuZmVhdHVyZXMgfHwgW10pXSxcbiAgICAgIC8vIGlmIHNhdmVkRWRpdG9yLnZpc2libGUgaXMgdW5kZWZpbmVkIGtlZXAgc3RhdGUuZWRpdG9yLnZpc2libGVcbiAgICAgIHZpc2libGU6IHNhdmVkRWRpdG9yLnZpc2libGUgPz8gc3RhdGUuZWRpdG9yLnZpc2libGVcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbWJpbmVFZGl0b3JDb25maWdzKGNvbmZpZ3M6IFNhdmVkRWRpdG9yW10pOiBTYXZlZEVkaXRvciB7XG4gIHJldHVybiBjb25maWdzLnJlZHVjZShcbiAgICAoYWNjLCBuZXh0Q29uZmlnKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5hY2MsXG4gICAgICAgIGZlYXR1cmVzOiBbLi4uYWNjLmZlYXR1cmVzLCAuLi4obmV4dENvbmZpZy5mZWF0dXJlcyB8fCBbXSldXG4gICAgICB9O1xuICAgIH0sXG4gICAge1xuICAgICAgLy8gc3RhcnQgd2l0aDpcbiAgICAgIC8vIC0gZW1wdHkgYXJyYXkgZm9yIGZlYXR1cmVzIGFjY3VtdWxhdGlvblxuICAgICAgLy8gLSBhbmQgYXJlIGFueSBvZiB0aGUgY29uZmlncycgdmlzaWJsZSB2YWx1ZXMgdHJ1ZT9cbiAgICAgIGZlYXR1cmVzOiBbXSxcbiAgICAgIHZpc2libGU6IGNvbmZpZ3Muc29tZShjID0+IGM/LnZpc2libGUpXG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHNhdmVkIGxheWVyIGNvbmZpZyB3aXRoIG5ldyBkYXRhLFxuICogdXBkYXRlIGZpZWxkSWR4IGJhc2VkIG9uIG5ldyBmaWVsZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlRGF0YXNldHNCeU9yZGVyKHN0YXRlOiBWaXNTdGF0ZSwgbmV3RGF0YUVudHJpZXM6IERhdGFzZXRzKTogRGF0YXNldHMge1xuICBjb25zdCBtZXJnZWQgPSB7XG4gICAgLi4uc3RhdGUuZGF0YXNldHMsXG4gICAgLi4ubmV3RGF0YUVudHJpZXNcbiAgfTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzdGF0ZS5wcmVzZXJ2ZURhdGFzZXRPcmRlcikpIHtcbiAgICAvLyBwcmVzZXJ2ZURhdGFzZXRPcmRlciAgbWlnaHQgbm90IGluY2x1ZGUgdGhlICBuZXcgZGF0YXNldHNcbiAgICBjb25zdCBuZXdEYXRhc2V0SWRzID0gT2JqZWN0LmtleXMobWVyZ2VkKS5maWx0ZXIoXG4gICAgICBpZCA9PiAhc3RhdGUucHJlc2VydmVEYXRhc2V0T3JkZXI/LmluY2x1ZGVzKGlkKVxuICAgICk7XG4gICAgcmV0dXJuIFsuLi5zdGF0ZS5wcmVzZXJ2ZURhdGFzZXRPcmRlciwgLi4ubmV3RGF0YXNldElkc10ucmVkdWNlKFxuICAgICAgKGFjY3UsIGRhdGFJZCkgPT4gKHtcbiAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgLi4uKG1lcmdlZFtkYXRhSWRdID8ge1tkYXRhSWRdOiBtZXJnZWRbZGF0YUlkXX0gOiB7fSlcbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIG1lcmdlZDtcbn1cblxuLyoqXG4gKiBTaW1saWFyIHB1cnBvc2UgdG8gYWdncmVnYXRpb24gdXRpbHMgYGdldE1vZGVgIGZ1bmN0aW9uLFxuICogYnV0IHJldHVybnMgdGhlIG1vZGUgaW4gdGhlIHNhbWUgdmFsdWUgdHlwZSB3aXRob3V0IGNvZXJjaW5nIHRvIGEgc3RyaW5nLlxuICogSXQgaWdub3JlcyBgdW5kZWZpbmVkYCBvciBgbnVsbGAgdmFsdWVzLCBidXQgcmV0dXJucyBgbnVsbGAgaWYgbm8gbW9kZSBjb3VsZCBiZSBjYWxjdWxhdGVkLlxuICovXG5mdW5jdGlvbiBnZXRWYWx1ZVdpdGhIaWdoZXN0T2NjdXJyZW5jZTxUPihhcnI6IFRbXSk6IFQgfCBudWxsIHtcbiAgY29uc3QgdGFsbHlzID0gbmV3IE1hcCgpO1xuICBhcnIuZm9yRWFjaCh2YWx1ZSA9PiB7XG4gICAgaWYgKG5vdE51bGxvclVuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgIGlmICghdGFsbHlzLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgdGFsbHlzLnNldCh2YWx1ZSwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWxseXMuc2V0KHZhbHVlLCB0YWxseXMuZ2V0KHZhbHVlKSArIDEpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIC8vIHJldHVybiB0aGUgdmFsdWUgd2l0aCB0aGUgaGlnaGVzdCB0b3RhbCBvY2N1cnJlbmNlIGNvdW50XG4gIGlmICh0YWxseXMuc2l6ZSA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBbLi4udGFsbHlzLmVudHJpZXMoKV0/LnJlZHVjZSgoYWNjLCBuZXh0KSA9PiAobmV4dFsxXSA+IGFjY1sxXSA/IG5leHQgOiBhY2MpKVswXTtcbn1cblxuZXhwb3J0IGNvbnN0IFZJU19TVEFURV9NRVJHRVJTOiBWaXNTdGF0ZU1lcmdlcnM8YW55PiA9IFtcbiAge1xuICAgIG1lcmdlOiBtZXJnZUxheWVycyxcbiAgICBwcm9wOiAnbGF5ZXJzJyxcbiAgICB0b01lcmdlUHJvcDogJ2xheWVyVG9CZU1lcmdlZCcsXG4gICAgcHJlc2VydmVPcmRlcjogJ3ByZXNlcnZlTGF5ZXJPcmRlcidcbiAgfSxcbiAge1xuICAgIG1lcmdlOiBtZXJnZUxheWVyT3JkZXIsXG4gICAgcHJvcDogJ2xheWVyT3JkZXInXG4gIH0sXG4gIHtcbiAgICBtZXJnZTogbWVyZ2VGaWx0ZXJzLFxuICAgIHByb3A6ICdmaWx0ZXJzJyxcbiAgICB0b01lcmdlUHJvcDogJ2ZpbHRlclRvQmVNZXJnZWQnLFxuICAgIHByZXNlcnZlT3JkZXI6ICdwcmVzZXJ2ZUZpbHRlck9yZGVyJyxcbiAgICByZXBsYWNlUGFyZW50RGF0YXNldElkczogcmVwbGFjZUZpbHRlckRhdGFzZXRJZHNcbiAgfSxcbiAge1xuICAgIG1lcmdlOiBtZXJnZUVmZmVjdHMsXG4gICAgcHJvcDogJ2VmZmVjdHMnXG4gIH0sXG4gIHtcbiAgICBtZXJnZTogbWVyZ2VBbm5vdGF0aW9ucyxcbiAgICBwcm9wOiAnYW5ub3RhdGlvbnMnLFxuICAgIHRvTWVyZ2VQcm9wOiAnYW5ub3RhdGlvbnNUb0JlTWVyZ2VkJ1xuICB9LFxuICB7XG4gICAgbWVyZ2U6IG1lcmdlSW50ZXJhY3Rpb25zLFxuICAgIHByb3A6ICdpbnRlcmFjdGlvbkNvbmZpZycsXG4gICAgdG9NZXJnZVByb3A6ICdpbnRlcmFjdGlvblRvQmVNZXJnZWQnLFxuICAgIHJlcGxhY2VQYXJlbnREYXRhc2V0SWRzOiByZXBsYWNlSW50ZXJhY3Rpb25EYXRhc2V0SWRzLFxuICAgIHNhdmVVbm1lcmdlZDogc2F2ZWRVbm1lcmdlZEludGVyYWN0aW9uLFxuICAgIGNvbWJpbmVDb25maWdzOiBjb21iaW5lSW50ZXJhY3Rpb25Db25maWdzXG4gIH0sXG4gIHttZXJnZTogbWVyZ2VMYXllckJsZW5kaW5nLCBwcm9wOiAnbGF5ZXJCbGVuZGluZycsIGNvbWJpbmVDb25maWdzOiBjb21iaW5lTGF5ZXJCbGVuZGluZ0NvbmZpZ3N9LFxuICB7XG4gICAgbWVyZ2U6IG1lcmdlT3ZlcmxheUJsZW5kaW5nLFxuICAgIHByb3A6ICdvdmVybGF5QmxlbmRpbmcnLFxuICAgIGNvbWJpbmVDb25maWdzOiBjb21iaW5lT3ZlcmxheUJsZW5kaW5nQ29uZmlnc1xuICB9LFxuICB7bWVyZ2U6IG1lcmdlU3BsaXRNYXBzLCBwcm9wOiAnc3BsaXRNYXBzJywgdG9NZXJnZVByb3A6ICdzcGxpdE1hcHNUb0JlTWVyZ2VkJ30sXG4gIHttZXJnZTogbWVyZ2VBbmltYXRpb25Db25maWcsIHByb3A6ICdhbmltYXRpb25Db25maWcnLCBjb21iaW5lQ29uZmlnczogY29tYmluZUFuaW1hdGlvbkNvbmZpZ3N9LFxuICB7bWVyZ2U6IG1lcmdlRWRpdG9yLCBwcm9wOiAnZWRpdG9yJywgY29tYmluZUNvbmZpZ3M6IGNvbWJpbmVFZGl0b3JDb25maWdzfVxuXTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7O0FBRUEsT0FBT0EsSUFBSSxNQUFNLHdCQUF3QjtBQUN6QyxPQUFPQyxJQUFJLE1BQU0sd0JBQXdCO0FBQ3pDLE9BQU9DLFdBQVcsTUFBTSwrQkFBK0I7QUFDdkQsT0FBT0MsU0FBUyxNQUFNLFdBQVc7QUFDakMsU0FDRUMsV0FBVyxFQUNYQyw4QkFBOEIsRUFDOUJDLHNCQUFzQixFQUN0QkMsNkJBQTZCLEVBQzdCQyxRQUFRLEVBQ1JDLFNBQVMsRUFDVEMsYUFBYSxRQUNSLGtCQUFrQjtBQUd6QixTQUFRQyxZQUFZLFFBQU8sb0JBQW9CO0FBQy9DLFNBQVFDLGtCQUFrQixRQUFPLHlCQUF5QjtBQUMxRCxTQUNFQyxpQkFBaUIsRUFDakJDLGVBQWUsRUFDZkMsaUJBQWlCLEVBQ2pCQyxnQkFBZ0IsRUFDaEJDLDZCQUE2QixFQUM3QkMsNkJBQTZCLFFBQ3hCLHNCQUFzQjtBQUM3QixTQUFRQyxlQUFlLFFBQXVELG9CQUFvQjtBQW9CbEcsU0FBK0JDLGlCQUFpQixFQUFFQyxrQkFBa0IsUUFBTyxrQkFBa0I7QUFFN0YsU0FBUUMsdUJBQXVCLFFBQU8sZUFBZTs7QUFFckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU0MsWUFB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