@kepler.gl/reducers 3.0.0-alpha.0

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 (47) hide show
  1. package/dist/combined-updaters.d.ts +50 -0
  2. package/dist/combined-updaters.js +212 -0
  3. package/dist/composer-helpers.d.ts +21 -0
  4. package/dist/composer-helpers.js +133 -0
  5. package/dist/composers.d.ts +12 -0
  6. package/dist/composers.js +47 -0
  7. package/dist/core.d.ts +64 -0
  8. package/dist/core.js +149 -0
  9. package/dist/data-utils.d.ts +8 -0
  10. package/dist/data-utils.js +60 -0
  11. package/dist/export-utils.d.ts +21 -0
  12. package/dist/export-utils.js +124 -0
  13. package/dist/index.d.ts +36 -0
  14. package/dist/index.js +372 -0
  15. package/dist/interaction-utils.d.ts +35 -0
  16. package/dist/interaction-utils.js +149 -0
  17. package/dist/layer-utils.d.ts +66 -0
  18. package/dist/layer-utils.js +289 -0
  19. package/dist/map-state-updaters.d.ts +62 -0
  20. package/dist/map-state-updaters.js +250 -0
  21. package/dist/map-state.d.ts +3 -0
  22. package/dist/map-state.js +67 -0
  23. package/dist/map-style-updaters.d.ts +173 -0
  24. package/dist/map-style-updaters.js +538 -0
  25. package/dist/map-style.d.ts +4 -0
  26. package/dist/map-style.js +66 -0
  27. package/dist/middleware.d.ts +8 -0
  28. package/dist/middleware.js +46 -0
  29. package/dist/provider-state-updaters.d.ts +42 -0
  30. package/dist/provider-state-updaters.js +512 -0
  31. package/dist/provider-state.d.ts +4 -0
  32. package/dist/provider-state.js +66 -0
  33. package/dist/root.d.ts +31 -0
  34. package/dist/root.js +235 -0
  35. package/dist/ui-state-updaters.d.ts +355 -0
  36. package/dist/ui-state-updaters.js +866 -0
  37. package/dist/ui-state.d.ts +3 -0
  38. package/dist/ui-state.js +68 -0
  39. package/dist/vis-state-merger.d.ts +102 -0
  40. package/dist/vis-state-merger.js +635 -0
  41. package/dist/vis-state-selectors.d.ts +2 -0
  42. package/dist/vis-state-selectors.js +53 -0
  43. package/dist/vis-state-updaters.d.ts +419 -0
  44. package/dist/vis-state-updaters.js +2472 -0
  45. package/dist/vis-state.d.ts +3 -0
  46. package/dist/vis-state.js +66 -0
  47. package/package.json +83 -0
@@ -0,0 +1,512 @@
1
+ // Copyright (c) 2022 Uber Technologies, Inc.
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ "use strict";
22
+
23
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
24
+
25
+ Object.defineProperty(exports, "__esModule", {
26
+ value: true
27
+ });
28
+ exports.getSavedMapsErrorUpdater = exports.getSavedMapsSuccessUpdater = exports.getSavedMapsUpdater = exports.setCloudProviderUpdater = exports.resetProviderStatusUpdater = exports.loadCloudMapErrorUpdater = exports.loadCloudMapSuccessUpdater = exports.loadCloudMapUpdater = exports.exportFileErrorUpdater = exports.postSaveLoadSuccessUpdater = exports.exportFileSuccessUpdater = exports.exportFileToCloudUpdater = exports.INITIAL_PROVIDER_STATE = void 0;
29
+
30
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
31
+
32
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
33
+
34
+ var _tasks = require("react-palm/tasks");
35
+
36
+ var _console = _interopRequireDefault(require("global/console"));
37
+
38
+ var _utils = require("@kepler.gl/utils");
39
+
40
+ var _tasks2 = require("@kepler.gl/tasks");
41
+
42
+ var _actions = require("@kepler.gl/actions");
43
+
44
+ var _constants = require("@kepler.gl/constants");
45
+
46
+ var _cloudProviders = require("@kepler.gl/cloud-providers");
47
+
48
+ var _processors = require("@kepler.gl/processors");
49
+
50
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
51
+
52
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
53
+
54
+ var INITIAL_PROVIDER_STATE = {
55
+ isProviderLoading: false,
56
+ isCloudMapLoading: false,
57
+ providerError: null,
58
+ currentProvider: null,
59
+ successInfo: {},
60
+ mapSaved: null,
61
+ visualizations: []
62
+ };
63
+ exports.INITIAL_PROVIDER_STATE = INITIAL_PROVIDER_STATE;
64
+
65
+ function createActionTask(action, payload) {
66
+ if (typeof action === 'function') {
67
+ return (0, _tasks2.ACTION_TASK)().map(function (_) {
68
+ return action(payload);
69
+ });
70
+ }
71
+
72
+ return null;
73
+ }
74
+
75
+ function _validateProvider(provider, method) {
76
+ if (!provider) {
77
+ _console["default"].error("provider is not defined");
78
+
79
+ return false;
80
+ }
81
+
82
+ if (typeof provider[method] !== 'function') {
83
+ _console["default"].error("".concat(method, " is not a function of Cloud provider: ").concat(provider.name));
84
+
85
+ return false;
86
+ }
87
+
88
+ return true;
89
+ }
90
+
91
+ function createGlobalNotificationTasks(_ref) {
92
+ var type = _ref.type,
93
+ message = _ref.message,
94
+ _ref$delayClose = _ref.delayClose,
95
+ delayClose = _ref$delayClose === void 0 ? true : _ref$delayClose;
96
+ var id = (0, _utils.generateHashId)();
97
+ var successNote = {
98
+ id: id,
99
+ type: _constants.DEFAULT_NOTIFICATION_TYPES[type || ''] || _constants.DEFAULT_NOTIFICATION_TYPES.success,
100
+ topic: _constants.DEFAULT_NOTIFICATION_TOPICS.global,
101
+ message: message
102
+ };
103
+ var task = (0, _tasks2.ACTION_TASK)().map(function (_) {
104
+ return (0, _actions.addNotification)(successNote);
105
+ });
106
+ return delayClose ? [task, (0, _tasks2.DELAY_TASK)(3000).map(function (_) {
107
+ return (0, _actions.removeNotification)(id);
108
+ })] : [task];
109
+ }
110
+ /**
111
+ * This method will export the current kepler config file to the chosen cloud proder
112
+ * add returns a share URL
113
+ *
114
+ */
115
+
116
+
117
+ var exportFileToCloudUpdater = function exportFileToCloudUpdater(state, action) {
118
+ var _action$payload = action.payload,
119
+ mapData = _action$payload.mapData,
120
+ provider = _action$payload.provider,
121
+ _action$payload$optio = _action$payload.options,
122
+ options = _action$payload$optio === void 0 ? {} : _action$payload$optio,
123
+ onSuccess = _action$payload.onSuccess,
124
+ onError = _action$payload.onError,
125
+ closeModal = _action$payload.closeModal;
126
+
127
+ if (!_validateProvider(provider, 'uploadMap')) {
128
+ return state;
129
+ }
130
+
131
+ var newState = _objectSpread(_objectSpread({}, state), {}, {
132
+ isProviderLoading: true,
133
+ currentProvider: provider.name
134
+ }); // payload called by provider.uploadMap
135
+
136
+
137
+ var payload = {
138
+ mapData: mapData,
139
+ options: options
140
+ };
141
+ var uploadFileTask = (0, _tasks2.EXPORT_FILE_TO_CLOUD_TASK)({
142
+ provider: provider,
143
+ payload: payload
144
+ }).bimap( // success
145
+ function (response) {
146
+ return (0, _actions.exportFileSuccess)({
147
+ response: response,
148
+ provider: provider,
149
+ options: options,
150
+ onSuccess: onSuccess,
151
+ closeModal: closeModal
152
+ });
153
+ }, // error
154
+ function (error) {
155
+ return (0, _actions.exportFileError)({
156
+ error: error,
157
+ provider: provider,
158
+ options: options,
159
+ onError: onError
160
+ });
161
+ });
162
+ return (0, _tasks.withTask)(newState, uploadFileTask);
163
+ };
164
+
165
+ exports.exportFileToCloudUpdater = exportFileToCloudUpdater;
166
+
167
+ var exportFileSuccessUpdater = function exportFileSuccessUpdater(state, action) {
168
+ var _action$payload2 = action.payload,
169
+ response = _action$payload2.response,
170
+ provider = _action$payload2.provider,
171
+ _action$payload2$opti = _action$payload2.options,
172
+ options = _action$payload2$opti === void 0 ? {} : _action$payload2$opti,
173
+ onSuccess = _action$payload2.onSuccess,
174
+ closeModal = _action$payload2.closeModal;
175
+
176
+ var newState = _objectSpread(_objectSpread({}, state), {}, {
177
+ isProviderLoading: false,
178
+ // TODO: do we always have to store this?
179
+ successInfo: response
180
+ }, !options.isPublic ? {
181
+ mapSaved: provider.name
182
+ } : {});
183
+
184
+ var tasks = [createActionTask(onSuccess, {
185
+ response: response,
186
+ provider: provider,
187
+ options: options
188
+ }), closeModal && (0, _tasks2.ACTION_TASK)().map(function (_) {
189
+ return (0, _actions.postSaveLoadSuccess)("Map saved to ".concat(state.currentProvider, "!"));
190
+ })].filter(function (d) {
191
+ return d;
192
+ });
193
+ return tasks.length ? (0, _tasks.withTask)(newState, tasks) : newState;
194
+ };
195
+ /**
196
+ * Close modal on success and display notification
197
+ */
198
+
199
+
200
+ exports.exportFileSuccessUpdater = exportFileSuccessUpdater;
201
+
202
+ var postSaveLoadSuccessUpdater = function postSaveLoadSuccessUpdater(state, action) {
203
+ var message = action.payload || "Saved / Load to ".concat(state.currentProvider, " Success");
204
+ var tasks = [(0, _tasks2.ACTION_TASK)().map(function (_) {
205
+ return (0, _actions.toggleModal)(null);
206
+ }), (0, _tasks2.ACTION_TASK)().map(function (_) {
207
+ return (0, _actions.resetProviderStatus)();
208
+ })].concat((0, _toConsumableArray2["default"])(createGlobalNotificationTasks({
209
+ message: message
210
+ })));
211
+ return (0, _tasks.withTask)(state, tasks);
212
+ };
213
+
214
+ exports.postSaveLoadSuccessUpdater = postSaveLoadSuccessUpdater;
215
+
216
+ var exportFileErrorUpdater = function exportFileErrorUpdater(state, action) {
217
+ var _action$payload3 = action.payload,
218
+ error = _action$payload3.error,
219
+ provider = _action$payload3.provider,
220
+ onError = _action$payload3.onError;
221
+
222
+ var newState = _objectSpread(_objectSpread({}, state), {}, {
223
+ isProviderLoading: false
224
+ });
225
+
226
+ if (isFileConflict(error)) {
227
+ newState.mapSaved = provider.name;
228
+ return (0, _tasks.withTask)(newState, [(0, _tasks2.ACTION_TASK)().map(function (_) {
229
+ return (0, _actions.toggleModal)(_constants.OVERWRITE_MAP_ID);
230
+ })]);
231
+ }
232
+
233
+ newState.providerError = (0, _utils.getError)(error);
234
+ var task = createActionTask(onError, {
235
+ error: error,
236
+ provider: provider
237
+ });
238
+ return task ? (0, _tasks.withTask)(newState, task) : newState;
239
+ };
240
+
241
+ exports.exportFileErrorUpdater = exportFileErrorUpdater;
242
+
243
+ var loadCloudMapUpdater = function loadCloudMapUpdater(state, action) {
244
+ var _action$payload4 = action.payload,
245
+ loadParams = _action$payload4.loadParams,
246
+ provider = _action$payload4.provider,
247
+ onSuccess = _action$payload4.onSuccess,
248
+ onError = _action$payload4.onError;
249
+
250
+ if (!loadParams) {
251
+ _console["default"].warn('load map error: loadParams is undefined');
252
+
253
+ return state;
254
+ }
255
+
256
+ if (!_validateProvider(provider, 'downloadMap')) {
257
+ return state;
258
+ }
259
+
260
+ var newState = _objectSpread(_objectSpread({}, state), {}, {
261
+ isProviderLoading: true,
262
+ isCloudMapLoading: true
263
+ }); // payload called by provider.downloadMap
264
+
265
+
266
+ var uploadFileTask = (0, _tasks2.LOAD_CLOUD_MAP_TASK)({
267
+ provider: provider,
268
+ payload: loadParams
269
+ }).bimap( // success
270
+ // @ts-expect-error
271
+ function (response) {
272
+ return (0, _actions.loadCloudMapSuccess)({
273
+ response: response,
274
+ loadParams: loadParams,
275
+ provider: provider,
276
+ onSuccess: onSuccess,
277
+ onError: onError
278
+ });
279
+ }, // error
280
+ // @ts-expect-error
281
+ function (error) {
282
+ return (0, _actions.loadCloudMapError)({
283
+ error: error,
284
+ provider: provider,
285
+ onError: onError
286
+ });
287
+ });
288
+ return (0, _tasks.withTask)(newState, uploadFileTask);
289
+ };
290
+
291
+ exports.loadCloudMapUpdater = loadCloudMapUpdater;
292
+
293
+ function isFileConflict(error) {
294
+ return error && error.message === _cloudProviders.FILE_CONFLICT_MSG;
295
+ }
296
+
297
+ function checkLoadMapResponseError(response) {
298
+ if (!response || !(0, _utils.isPlainObject)(response)) {
299
+ return new Error('Load map response is empty');
300
+ }
301
+
302
+ if (!(0, _utils.isPlainObject)(response.map)) {
303
+ return new Error("Load map response should be an object property \"map\"");
304
+ }
305
+
306
+ if (!response.map.datasets || !response.map.config) {
307
+ return new Error("Load map response.map should be an object with property datasets or config");
308
+ }
309
+
310
+ return null;
311
+ }
312
+
313
+ function getDatasetHandler(format) {
314
+ var defaultHandler = _processors.DATASET_HANDLERS[_constants.DATASET_FORMATS.csv];
315
+
316
+ if (!format) {
317
+ _console["default"].warn('format is not provided in load map response, will use csv by default');
318
+
319
+ return defaultHandler;
320
+ }
321
+
322
+ if (!_processors.DATASET_HANDLERS[format]) {
323
+ var supportedFormat = Object.keys(_constants.DATASET_FORMATS).map(function (k) {
324
+ return "'".concat(k, "'");
325
+ }).join(', ');
326
+
327
+ _console["default"].warn("unknown format ".concat(format, ". Please use one of ").concat(supportedFormat, ", will use csv by default"));
328
+
329
+ return defaultHandler;
330
+ }
331
+
332
+ return _processors.DATASET_HANDLERS[format];
333
+ }
334
+
335
+ function parseLoadMapResponse(response, loadParams, provider) {
336
+ var map = response.map,
337
+ format = response.format;
338
+ var processorMethod = getDatasetHandler(format);
339
+ var parsedDatasets = (0, _utils.toArray)(map.datasets).map(function (ds, i) {
340
+ if (format === _constants.DATASET_FORMATS.keplergl) {
341
+ // no need to obtain id, directly pass them in
342
+ return processorMethod(ds);
343
+ }
344
+
345
+ var info = ds && ds.info || {
346
+ id: (0, _utils.generateHashId)(6)
347
+ };
348
+ var data = processorMethod(ds.data || ds);
349
+ return {
350
+ info: info,
351
+ data: data
352
+ };
353
+ });
354
+
355
+ var info = _objectSpread(_objectSpread({}, map.info), {}, {
356
+ provider: provider.name,
357
+ loadParams: loadParams
358
+ });
359
+
360
+ return _objectSpread({
361
+ datasets: parsedDatasets,
362
+ info: info
363
+ }, map.config ? {
364
+ config: map.config
365
+ } : {});
366
+ }
367
+
368
+ var loadCloudMapSuccessUpdater = function loadCloudMapSuccessUpdater(state, action) {
369
+ var _action$payload5 = action.payload,
370
+ response = _action$payload5.response,
371
+ loadParams = _action$payload5.loadParams,
372
+ provider = _action$payload5.provider,
373
+ onSuccess = _action$payload5.onSuccess,
374
+ onError = _action$payload5.onError;
375
+ var formatError = checkLoadMapResponseError(response);
376
+
377
+ if (formatError) {
378
+ // if response format is not correct
379
+ return exportFileErrorUpdater(state, {
380
+ payload: {
381
+ error: formatError,
382
+ provider: provider,
383
+ onError: onError
384
+ }
385
+ });
386
+ }
387
+
388
+ var newState = _objectSpread(_objectSpread({}, state), {}, {
389
+ mapSaved: provider.name,
390
+ currentProvider: provider.name,
391
+ isCloudMapLoading: false,
392
+ isProviderLoading: false
393
+ });
394
+
395
+ var payload = parseLoadMapResponse(response, loadParams, provider);
396
+ var tasks = [(0, _tasks2.ACTION_TASK)().map(function (_) {
397
+ return (0, _actions.addDataToMap)(payload);
398
+ }), createActionTask(onSuccess, {
399
+ response: response,
400
+ loadParams: loadParams,
401
+ provider: provider
402
+ }), (0, _tasks2.ACTION_TASK)().map(function (_) {
403
+ return (0, _actions.postSaveLoadSuccess)("Map from ".concat(provider.name, " loaded"));
404
+ })].filter(function (d) {
405
+ return d;
406
+ });
407
+ return tasks.length ? (0, _tasks.withTask)(newState, tasks) : newState;
408
+ };
409
+
410
+ exports.loadCloudMapSuccessUpdater = loadCloudMapSuccessUpdater;
411
+
412
+ var loadCloudMapErrorUpdater = function loadCloudMapErrorUpdater(state, action) {
413
+ var message = (0, _utils.getError)(action.payload.error) || "Error loading saved map";
414
+
415
+ _console["default"].warn(message);
416
+
417
+ var newState = _objectSpread(_objectSpread({}, state), {}, {
418
+ isProviderLoading: false,
419
+ isCloudMapLoading: false,
420
+ providerError: null
421
+ });
422
+
423
+ return (0, _tasks.withTask)(newState, createGlobalNotificationTasks({
424
+ type: 'error',
425
+ message: message,
426
+ delayClose: false
427
+ }));
428
+ };
429
+
430
+ exports.loadCloudMapErrorUpdater = loadCloudMapErrorUpdater;
431
+
432
+ var resetProviderStatusUpdater = function resetProviderStatusUpdater(state) {
433
+ return _objectSpread(_objectSpread({}, state), {}, {
434
+ isProviderLoading: false,
435
+ providerError: null,
436
+ isCloudMapLoading: false,
437
+ successInfo: {}
438
+ });
439
+ };
440
+ /**
441
+ * Set current cloudProvider
442
+ */
443
+
444
+
445
+ exports.resetProviderStatusUpdater = resetProviderStatusUpdater;
446
+
447
+ var setCloudProviderUpdater = function setCloudProviderUpdater(state, action) {
448
+ return _objectSpread(_objectSpread({}, state), {}, {
449
+ isProviderLoading: false,
450
+ providerError: null,
451
+ successInfo: {},
452
+ currentProvider: action.payload
453
+ });
454
+ };
455
+
456
+ exports.setCloudProviderUpdater = setCloudProviderUpdater;
457
+
458
+ var getSavedMapsUpdater = function getSavedMapsUpdater(state, action) {
459
+ var provider = action.payload;
460
+
461
+ if (!_validateProvider(provider, 'listMaps')) {
462
+ return state;
463
+ }
464
+
465
+ var getSavedMapsTask = (0, _tasks2.GET_SAVED_MAPS_TASK)(provider).bimap( // success
466
+ function (visualizations) {
467
+ return (0, _actions.getSavedMapsSuccess)({
468
+ visualizations: visualizations,
469
+ provider: provider
470
+ });
471
+ }, // error
472
+ function (error) {
473
+ return (0, _actions.getSavedMapsError)({
474
+ error: error,
475
+ provider: provider
476
+ });
477
+ });
478
+ return (0, _tasks.withTask)(_objectSpread(_objectSpread({}, state), {}, {
479
+ isProviderLoading: true
480
+ }), getSavedMapsTask);
481
+ };
482
+
483
+ exports.getSavedMapsUpdater = getSavedMapsUpdater;
484
+
485
+ var getSavedMapsSuccessUpdater = function getSavedMapsSuccessUpdater(state, action) {
486
+ return _objectSpread(_objectSpread({}, state), {}, {
487
+ isProviderLoading: false,
488
+ visualizations: action.payload.visualizations
489
+ });
490
+ };
491
+
492
+ exports.getSavedMapsSuccessUpdater = getSavedMapsSuccessUpdater;
493
+
494
+ var getSavedMapsErrorUpdater = function getSavedMapsErrorUpdater(state, action) {
495
+ var message = (0, _utils.getError)(action.payload.error) || "Error getting saved maps from ".concat(state.currentProvider);
496
+
497
+ _console["default"].warn(action.payload.error);
498
+
499
+ var newState = _objectSpread(_objectSpread({}, state), {}, {
500
+ currentProvider: null,
501
+ isProviderLoading: false
502
+ });
503
+
504
+ return (0, _tasks.withTask)(newState, createGlobalNotificationTasks({
505
+ type: 'error',
506
+ message: message,
507
+ delayClose: false
508
+ }));
509
+ };
510
+
511
+ exports.getSavedMapsErrorUpdater = getSavedMapsErrorUpdater;
512
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wcm92aWRlci1zdGF0ZS11cGRhdGVycy50cyJdLCJuYW1lcyI6WyJJTklUSUFMX1BST1ZJREVSX1NUQVRFIiwiaXNQcm92aWRlckxvYWRpbmciLCJpc0Nsb3VkTWFwTG9hZGluZyIsInByb3ZpZGVyRXJyb3IiLCJjdXJyZW50UHJvdmlkZXIiLCJzdWNjZXNzSW5mbyIsIm1hcFNhdmVkIiwidmlzdWFsaXphdGlvbnMiLCJjcmVhdGVBY3Rpb25UYXNrIiwiYWN0aW9uIiwicGF5bG9hZCIsIm1hcCIsIl8iLCJfdmFsaWRhdGVQcm92aWRlciIsInByb3ZpZGVyIiwibWV0aG9kIiwiQ29uc29sZSIsImVycm9yIiwibmFtZSIsImNyZWF0ZUdsb2JhbE5vdGlmaWNhdGlvblRhc2tzIiwidHlwZSIsIm1lc3NhZ2UiLCJkZWxheUNsb3NlIiwiaWQiLCJzdWNjZXNzTm90ZSIsIkRFRkFVTFRfTk9USUZJQ0FUSU9OX1RZUEVTIiwic3VjY2VzcyIsInRvcGljIiwiREVGQVVMVF9OT1RJRklDQVRJT05fVE9QSUNTIiwiZ2xvYmFsIiwidGFzayIsImV4cG9ydEZpbGVUb0Nsb3VkVXBkYXRlciIsInN0YXRlIiwibWFwRGF0YSIsIm9wdGlvbnMiLCJvblN1Y2Nlc3MiLCJvbkVycm9yIiwiY2xvc2VNb2RhbCIsIm5ld1N0YXRlIiwidXBsb2FkRmlsZVRhc2siLCJiaW1hcCIsInJlc3BvbnNlIiwiZXhwb3J0RmlsZVN1Y2Nlc3NVcGRhdGVyIiwiaXNQdWJsaWMiLCJ0YXNrcyIsImZpbHRlciIsImQiLCJsZW5ndGgiLCJwb3N0U2F2ZUxvYWRTdWNjZXNzVXBkYXRlciIsImV4cG9ydEZpbGVFcnJvclVwZGF0ZXIiLCJpc0ZpbGVDb25mbGljdCIsIk9WRVJXUklURV9NQVBfSUQiLCJsb2FkQ2xvdWRNYXBVcGRhdGVyIiwibG9hZFBhcmFtcyIsIndhcm4iLCJGSUxFX0NPTkZMSUNUX01TRyIsImNoZWNrTG9hZE1hcFJlc3BvbnNlRXJyb3IiLCJFcnJvciIsImRhdGFzZXRzIiwiY29uZmlnIiwiZ2V0RGF0YXNldEhhbmRsZXIiLCJmb3JtYXQiLCJkZWZhdWx0SGFuZGxlciIsIkRBVEFTRVRfSEFORExFUlMiLCJEQVRBU0VUX0ZPUk1BVFMiLCJjc3YiLCJzdXBwb3J0ZWRGb3JtYXQiLCJPYmplY3QiLCJrZXlzIiwiayIsImpvaW4iLCJwYXJzZUxvYWRNYXBSZXNwb25zZSIsInByb2Nlc3Nvck1ldGhvZCIsInBhcnNlZERhdGFzZXRzIiwiZHMiLCJpIiwia2VwbGVyZ2wiLCJpbmZvIiwiZGF0YSIsImxvYWRDbG91ZE1hcFN1Y2Nlc3NVcGRhdGVyIiwiZm9ybWF0RXJyb3IiLCJsb2FkQ2xvdWRNYXBFcnJvclVwZGF0ZXIiLCJyZXNldFByb3ZpZGVyU3RhdHVzVXBkYXRlciIsInNldENsb3VkUHJvdmlkZXJVcGRhdGVyIiwiZ2V0U2F2ZWRNYXBzVXBkYXRlciIsImdldFNhdmVkTWFwc1Rhc2siLCJnZXRTYXZlZE1hcHNTdWNjZXNzVXBkYXRlciIsImdldFNhdmVkTWFwc0Vycm9yVXBkYXRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFPQTs7QUFlQTs7QUFRQTs7QUFDQTs7Ozs7O0FBa0JPLElBQU1BLHNCQUFxQyxHQUFHO0FBQ25EQyxFQUFBQSxpQkFBaUIsRUFBRSxLQURnQztBQUVuREMsRUFBQUEsaUJBQWlCLEVBQUUsS0FGZ0M7QUFHbkRDLEVBQUFBLGFBQWEsRUFBRSxJQUhvQztBQUluREMsRUFBQUEsZUFBZSxFQUFFLElBSmtDO0FBS25EQyxFQUFBQSxXQUFXLEVBQUUsRUFMc0M7QUFNbkRDLEVBQUFBLFFBQVEsRUFBRSxJQU55QztBQU9uREMsRUFBQUEsY0FBYyxFQUFFO0FBUG1DLENBQTlDOzs7QUFVUCxTQUFTQyxnQkFBVCxDQUEwQkMsTUFBMUIsRUFBa0NDLE9BQWxDLEVBQTJDO0FBQ3pDLE1BQUksT0FBT0QsTUFBUCxLQUFrQixVQUF0QixFQUFrQztBQUNoQyxXQUFPLDJCQUFjRSxHQUFkLENBQWtCLFVBQUFD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QUEyQixDQUN0Q3ZELEtBRHNDLEVBRXRDdkIsTUFGc0MsRUFHcEI7QUFDbEIsTUFBTVksT0FBTyxHQUNYLHFCQUFTWixNQUFNLENBQUNDLE9BQVAsQ0FBZU8sS0FBeEIsNkNBQW1FZSxLQUFLLENBQUM1QixlQUF6RSxDQURGOztBQUdBWSxzQkFBUXNDLElBQVIsQ0FBYTdDLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlTyxLQUE1Qjs7QUFFQSxNQUFNcUIsUUFBUSxtQ0FDVE4sS0FEUztBQUVaNUIsSUFBQUEsZUFBZSxFQUFFLElBRkw7QUFHWkgsSUFBQUEsaUJBQWlCLEVBQUU7QUFIUCxJQUFkOztBQU1BLFNBQU8scUJBQ0xxQyxRQURLLEVBRUxuQiw2QkFBNkIsQ0FBQztBQUFDQyxJQUFBQSxJQUFJLEVBQUUsT0FBUDtBQUFnQkMsSUFBQUEsT0FBTyxFQUFQQSxPQUFoQjtBQUF5QkMsSUFBQUEsVUFBVSxFQUFFO0FBQXJDLEdBQUQsQ0FGeEIsQ0FBUDtBQUlELENBbkJNIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIyIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHt3aXRoVGFza30gZnJvbSAncmVhY3QtcGFsbS90YXNrcyc7XG5pbXBvcnQgQ29uc29sZSBmcm9tICdnbG9iYWwvY29uc29sZSc7XG5pbXBvcnQge2dlbmVyYXRlSGFzaElkLCBnZXRFcnJvciwgaXNQbGFpbk9iamVjdCwgdG9BcnJheX0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5pbXBvcnQge1xuICBFWFBPUlRfRklMRV9UT19DTE9VRF9UQVNLLFxuICBBQ1RJT05fVEFTSyxcbiAgREVMQVlfVEFTSyxcbiAgTE9BRF9DTE9VRF9NQVBfVEFTSyxcbiAgR0VUX1NBVkVEX01BUFNfVEFTS1xufSBmcm9tICdAa2VwbGVyLmdsL3Rhc2tzJztcbmltcG9ydCB7XG4gIGV4cG9ydEZpbGVTdWNjZXNzLFxuICBleHBvcnRGaWxlRXJyb3IsXG4gIHBvc3RTYXZlTG9hZFN1Y2Nlc3MsXG4gIGxvYWRDbG91ZE1hcFN1Y2Nlc3MsXG4gIGdldFNhdmVkTWFwc1N1Y2Nlc3MsXG4gIGdldFNhdmVkTWFwc0Vycm9yLFxuICBsb2FkQ2xvdWRNYXBFcnJvcixcbiAgcmVzZXRQcm92aWRlclN0YXR1cyxcbiAgcmVtb3ZlTm90aWZpY2F0aW9uLFxuICB0b2dnbGVNb2RhbCxcbiAgYWRkTm90aWZpY2F0aW9uLFxuICBhZGREYXRhVG9NYXAsXG4gIFByb3ZpZGVyQWN0aW9uc1xufSBmcm9tICdAa2VwbGVyLmdsL2FjdGlvbnMnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9OT1RJRklDQVRJT05fVFlQRVMsXG4gIERFRkFVTFRfTk9USUZJQ0FUSU9OX1RPUElDUyxcbiAgREFUQVNFVF9GT1JNQVRTLFxuICBPVkVSV1JJVEVfTUFQX0lEXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7RXhwb3J0RmlsZVRvQ2xvdWRQYXlsb2FkfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuaW1wb3J0IHtGSUxFX0NPTkZMSUNUX01TRywgTWFwTGlzdEl0ZW19IGZyb20gJ0BrZXBsZXIuZ2wvY2xvdWQtcHJvdmlkZXJzJztcbmltcG9ydCB7REFUQVNFVF9IQU5ETEVSU30gZnJvbSAnQGtlcGxlci5nbC9wcm9jZXNzb3JzJztcblxudHlwZSBBY3Rpb25QYXlsb2FkPFA+ID0ge1xuICB0eXBlPzogc3RyaW5nO1xuICBwYXlsb2FkOiBQO1xufTtcblxuZXhwb3J0IHR5cGUgUHJvdmlkZXJTdGF0ZSA9IHtcbiAgaXNQcm92aWRlckxvYWRpbmc6IGJvb2xlYW47XG4gIGlzQ2xvdWRNYXBMb2FkaW5nOiBib29sZWFuO1xuICBwcm92aWRlckVycm9yOiBhbnk7XG4gIGN1cnJlbnRQcm92aWRlcjogc3RyaW5nIHwgbnVsbDtcbiAgc3VjY2Vzc0luZm86IGFueTtcbiAgbWFwU2F2ZWQ6IG51bGwgfCBzdHJpbmc7XG4gIGluaXRpYWxTdGF0ZT86IGFueTtcbiAgdmlzdWFsaXphdGlvbnM6IE1hcExpc3RJdGVtW107XG59O1xuXG5leHBvcnQgY29uc3QgSU5JVElBTF9QUk9WSURFUl9TVEFURTogUHJvdmlkZXJTdGF0ZSA9IHtcbiAgaXNQcm92aWRlckxvYWRpbmc6IGZhbHNlLFxuICBpc0Nsb3VkTWFwTG9hZGluZzogZmFsc2UsXG4gIHByb3ZpZGVyRXJyb3I6IG51bGwsXG4gIGN1cnJlbnRQcm92aWRlcjogbnVsbCxcbiAgc3VjY2Vzc0luZm86IHt9LFxuICBtYXBTYXZlZDogbnVsbCxcbiAgdmlzdWFsaXphdGlvbnM6IFtdXG59O1xuXG5mdW5jdGlvbiBjcmVhdGVBY3Rpb25UYXNrKGFjdGlvbiwgcGF5bG9hZCkge1xuICBpZiAodHlwZW9mIGFjdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBBQ1RJT05fVEFTSygpLm1hcChfID0+IGFjdGlvbihwYXlsb2FkKSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gX3ZhbGlkYXRlUHJvdmlkZXIocHJvdmlkZXIsIG1ldGhvZCkge1xuICBpZiAoIXByb3ZpZGVyKSB7XG4gICAgQ29uc29sZS5lcnJvcihgcHJvdmlkZXIgaXMgbm90IGRlZmluZWRgKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIHByb3ZpZGVyW21ldGhvZF0gIT09ICdmdW5jdGlvbicpIHtcbiAgICBDb25zb2xlLmVycm9yKGAke21ldGhvZH0gaXMgbm90IGEgZnVuY3Rpb24gb2YgQ2xvdWQgcHJvdmlkZXI6ICR7cHJvdmlkZXIubmFtZX1gKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlR2xvYmFsTm90aWZpY2F0aW9uVGFza3Moe1xuICB0eXBlLFxuICBtZXNzYWdlLFxuICBkZWxheUNsb3NlID0gdHJ1ZVxufToge1xuICB0eXBlPzogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGRlbGF5Q2xvc2U/OiBib29sZWFuO1xufSkge1xuICBjb25zdCBpZCA9IGdlbmVyYXRlSGFzaElkKCk7XG4gIGNvbnN0IHN1Y2Nlc3NOb3RlID0ge1xuICAgIGlkLFxuICAgIHR5cGU6IERFRkFVTFRfTk9USUZJQ0FUSU9OX1RZUEVTW3R5cGUgfHwgJyddIHx8IERFRkFVTFRfTk9USUZJQ0FUSU9OX1RZUEVTLnN1Y2Nlc3MsXG4gICAgdG9waWM6IERFRkFVTFRfTk9USUZJQ0FUSU9OX1RPUElDUy5nbG9iYWwsXG4gICAgbWVzc2FnZVxuICB9O1xuICBjb25zdCB0YXNrID0gQUNUSU9OX1RBU0soKS5tYXAoXyA9PiBhZGROb3RpZmljYXRpb24oc3VjY2Vzc05vdGUpKTtcbiAgcmV0dXJuIGRlbGF5Q2xvc2UgPyBbdGFzaywgREVMQVlfVEFTSygzMDAwKS5tYXAoXyA9PiByZW1vdmVOb3RpZmljYXRpb24oaWQpKV0gOiBbdGFza107XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2Qgd2lsbCBleHBvcnQgdGhlIGN1cnJlbnQga2VwbGVyIGNvbmZpZyBmaWxlIHRvIHRoZSBjaG9zZW4gY2xvdWQgcHJvZGVyXG4gKiBhZGQgcmV0dXJucyBhIHNoYXJlIFVSTFxuICpcbiAqL1xuZXhwb3J0IGNvbnN0IGV4cG9ydEZpbGVUb0Nsb3VkVXBkYXRlciA9IChcbiAgc3RhdGU6IFByb3ZpZGVyU3RhdGUsXG4gIGFjdGlvbjogQWN0aW9uUGF5bG9hZDxFeHBvcnRGaWxlVG9DbG91ZFBheWxvYWQ+XG4pOiBQcm92aWRlclN0YXRlID0+IHtcbiAgY29uc3Qge21hcERhdGEsIHByb3ZpZGVyLCBvcHRpb25zID0ge30sIG9uU3VjY2Vzcywgb25FcnJvciwgY2xvc2VNb2RhbH0gPSBhY3Rpb24ucGF5bG9hZDtcblxuICBpZiAoIV92YWxpZGF0ZVByb3ZpZGVyKHByb3ZpZGVyLCAndXBsb2FkTWFwJykpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICBjb25zdCBuZXdTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBpc1Byb3ZpZGVyTG9hZGluZzogdHJ1ZSxcbiAgICBjdXJyZW50UHJvdmlkZXI6IHByb3ZpZGVyLm5hbWVcbiAgfTtcblxuICAvLyBwYXlsb2FkIGNhbGxlZCBieSBwcm92aWRlci51cGxvYWRNYXBcbiAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICBtYXBEYXRhLFxuICAgIG9wdGlvbnNcbiAgfTtcbiAgY29uc3QgdXBsb2FkRmlsZVRhc2sgPSBFWFBPUlRfRklMRV9UT19DTE9VRF9UQVNLKHtwcm92aWRlciwgcGF5bG9hZH0pLmJpbWFwKFxuICAgIC8vIHN1Y2Nlc3NcbiAgICByZXNwb25zZSA9PiBleHBvcnRGaWxlU3VjY2Vzcyh7cmVzcG9uc2UsIHByb3ZpZGVyLCBvcHRpb25zLCBvblN1Y2Nlc3MsIGNsb3NlTW9kYWx9KSxcbiAgICAvLyBlcnJvclxuICAgIGVycm9yID0+IGV4cG9ydEZpbGVFcnJvcih7ZXJyb3IsIHByb3ZpZGVyLCBvcHRpb25zLCBvbkVycm9yfSlcbiAgKTtcblxuICByZXR1cm4gd2l0aFRhc2sobmV3U3RhdGUsIHVwbG9hZEZpbGVUYXNrKTtcbn07XG5cbmV4cG9ydCBjb25zdCBleHBvcnRGaWxlU3VjY2Vzc1VwZGF0ZXIgPSAoXG4gIHN0YXRlOiBQcm92aWRlclN0YXRlLFxuICBhY3Rpb246IEFjdGlvblBheWxvYWQ8UHJvdmlkZXJBY3Rpb25zLkV4cG9ydEZpbGVTdWNjZXNzUGF5bG9hZD5cbik6IFByb3ZpZGVyU3RhdGUgPT4ge1xuICBjb25zdCB7cmVzcG9uc2UsIHByb3ZpZGVyLCBvcHRpb25zID0ge30sIG9uU3VjY2VzcywgY2xvc2VNb2RhbH0gPSBhY3Rpb24ucGF5bG9hZDtcblxuICBjb25zdCBuZXdTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBpc1Byb3ZpZGVyTG9hZGluZzogZmFsc2UsXG4gICAgLy8gVE9ETzogZG8gd2UgYWx3YXlzIGhhdmUgdG8gc3RvcmUgdGhpcz9cbiAgICBzdWNjZXNzSW5mbzogcmVzcG9uc2UsXG4gICAgLi4uKCFvcHRpb25zLmlzUHVibGljXG4gICAgICA/IHtcbiAgICAgICAgICBtYXBTYXZlZDogcHJvdmlkZXIubmFtZVxuICAgICAgICB9XG4gICAgICA6IHt9KVxuICB9O1xuXG4gIGNvbnN0IHRhc2tzID0gW1xuICAgIGNyZWF0ZUFjdGlvblRhc2sob25TdWNjZXNzLCB7cmVzcG9uc2UsIHByb3ZpZGVyLCBvcHRpb25zfSksXG4gICAgY2xvc2VNb2RhbCAmJlxuICAgICAgQUNUSU9OX1RBU0soKS5tYXAoXyA9PiBwb3N0U2F2ZUxvYWRTdWNjZXNzKGBNYXAgc2F2ZWQgdG8gJHtzdGF0ZS5jdXJyZW50UHJvdmlkZXJ9IWApKVxuICBdLmZpbHRlcihkID0+IGQpO1xuXG4gIHJldHVybiB0YXNrcy5sZW5ndGggPyB3aXRoVGFzayhuZXdTdGF0ZSwgdGFza3MpIDogbmV3U3RhdGU7XG59O1xuXG4vKipcbiAqIENsb3NlIG1vZGFsIG9uIHN1Y2Nlc3MgYW5kIGRpc3BsYXkgbm90aWZpY2F0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBwb3N0U2F2ZUxvYWRTdWNjZXNzVXBkYXRlciA9IChcbiAgc3RhdGU6IFByb3ZpZGVyU3RhdGUsXG4gIGFjdGlvbjogQWN0aW9uUGF5bG9hZDxQcm92aWRlckFjdGlvbnMuUG9zdFNhdmVMb2FkU3VjY2Vzc1BheWxvYWQ+XG4pOiBQcm92aWRlclN0YXRlID0+IHtcbiAgY29uc3QgbWVzc2FnZSA9IGFjdGlvbi5wYXlsb2FkIHx8IGBTYXZlZCAvIExvYWQgdG8gJHtzdGF0ZS5jdXJyZW50UHJvdmlkZXJ9IFN1Y2Nlc3NgO1xuXG4gIGNvbnN0IHRhc2tzID0gW1xuICAgIEFDVElPTl9UQVNLKCkubWFwKF8gPT4gdG9nZ2xlTW9kYWwobnVsbCkpLFxuICAgIEFDVElPTl9UQVNLKCkubWFwKF8gPT4gcmVzZXRQcm92aWRlclN0YXR1cygpKSxcbiAgICAuLi5jcmVhdGVHbG9iYWxOb3RpZmljYXRpb25UYXNrcyh7bWVzc2FnZX0pXG4gIF07XG5cbiAgcmV0dXJuIHdpdGhUYXNrKHN0YXRlLCB0YXNrcyk7XG59O1xuXG5leHBvcnQgY29uc3QgZXhwb3J0RmlsZUVycm9yVXBkYXRlciA9IChcbiAgc3RhdGU6IFByb3ZpZGVyU3RhdGUsXG4gIGFjdGlvbjogQWN0aW9uUGF5bG9hZDxQcm92aWRlckFjdGlvbnMuRXhwb3J0RmlsZUVycm9yUGF5bG9hZD5cbik6IFByb3ZpZGVyU3RhdGUgPT4ge1xuICBjb25zdCB7ZXJyb3IsIHByb3ZpZGVyLCBvbkVycm9yfSA9IGFjdGlvbi5wYXlsb2FkO1xuXG4gIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIGlzUHJvdmlkZXJMb2FkaW5nOiBmYWxzZVxuICB9O1xuXG4gIGlmIChpc0ZpbGVDb25mbGljdChlcnJvcikpIHtcbiAgICBuZXdTdGF0ZS5tYXBTYXZlZCA9IHByb3ZpZGVyLm5hbWU7XG4gICAgcmV0dXJuIHdpdGhUYXNrKG5ld1N0YXRlLCBbQUNUSU9OX1RBU0soKS5tYXAoXyA9PiB0b2dnbGVNb2RhbChPVkVSV1JJVEVfTUFQX0lEKSldKTtcbiAgfVxuXG4gIG5ld1N0YXRlLnByb3ZpZGVyRXJyb3IgPSBnZXRFcnJvcihlcnJvcik7XG4gIGNvbnN0IHRhc2sgPSBjcmVhdGVBY3Rpb25UYXNrKG9uRXJyb3IsIHtlcnJvciwgcHJvdmlkZXJ9KTtcblxuICByZXR1cm4gdGFzayA/IHdpdGhUYXNrKG5ld1N0YXRlLCB0YXNrKSA6IG5ld1N0YXRlO1xufTtcblxuZXhwb3J0IGNvbnN0IGxvYWRDbG91ZE1hcFVwZGF0ZXIgPSAoXG4gIHN0YXRlOiBQcm92aWRlclN0YXRlLFxuICBhY3Rpb246IEFjdGlvblBheWxvYWQ8UHJvdmlkZXJBY3Rpb25zLkxvYWRDbG91ZE1hcFBheWxvYWQ+XG4pOiBQcm92aWRlclN0YXRlID0+IHtcbiAgY29uc3Qge2xvYWRQYXJhbXMsIHByb3ZpZGVyLCBvblN1Y2Nlc3MsIG9uRXJyb3J9ID0gYWN0aW9uLnBheWxvYWQ7XG4gIGlmICghbG9hZFBhcmFtcykge1xuICAgIENvbnNvbGUud2FybignbG9hZCBtYXAgZXJyb3I6IGxvYWRQYXJhbXMgaXMgdW5kZWZpbmVkJyk7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIGlmICghX3ZhbGlkYXRlUHJvdmlkZXIocHJvdmlkZXIsICdkb3dubG9hZE1hcCcpKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgaXNQcm92aWRlckxvYWRpbmc6IHRydWUsXG4gICAgaXNDbG91ZE1hcExvYWRpbmc6IHRydWVcbiAgfTtcblxuICAvLyBwYXlsb2FkIGNhbGxlZCBieSBwcm92aWRlci5kb3dubG9hZE1hcFxuICBjb25zdCB1cGxvYWRGaWxlVGFzayA9IExPQURfQ0xPVURfTUFQX1RBU0soe3Byb3ZpZGVyLCBwYXlsb2FkOiBsb2FkUGFyYW1zfSkuYmltYXAoXG4gICAgLy8gc3VjY2Vzc1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICByZXNwb25zZSA9PiBsb2FkQ2xvdWRNYXBTdWNjZXNzKHtyZXNwb25zZSwgbG9hZFBhcmFtcywgcHJvdmlkZXIsIG9uU3VjY2Vzcywgb25FcnJvcn0pLFxuICAgIC8vIGVycm9yXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgIGVycm9yID0+IGxvYWRDbG91ZE1hcEVycm9yKHtlcnJvciwgcHJvdmlkZXIsIG9uRXJyb3J9KVxuICApO1xuXG4gIHJldHVybiB3aXRoVGFzayhuZXdTdGF0ZSwgdXBsb2FkRmlsZVRhc2spO1xufTtcblxuZnVuY3Rpb24gaXNGaWxlQ29uZmxpY3QoZXJyb3IpIHtcbiAgcmV0dXJuIGVycm9yICYmIGVycm9yLm1lc3NhZ2UgPT09IEZJTEVfQ09ORkxJQ1RfTVNHO1xufVxuXG5mdW5jdGlvbiBjaGVja0xvYWRNYXBSZXNwb25zZUVycm9yKHJlc3BvbnNlKSB7XG4gIGlmICghcmVzcG9uc2UgfHwgIWlzUGxhaW5PYmplY3QocmVzcG9uc2UpKSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcignTG9hZCBtYXAgcmVzcG9uc2UgaXMgZW1wdHknKTtcbiAgfVxuICBpZiAoIWlzUGxhaW5PYmplY3QocmVzcG9uc2UubWFwKSkge1xuICAgIHJldHVybiBuZXcgRXJyb3IoYExvYWQgbWFwIHJlc3BvbnNlIHNob3VsZCBiZSBhbiBvYmplY3QgcHJvcGVydHkgXCJtYXBcImApO1xuICB9XG4gIGlmICghcmVzcG9uc2UubWFwLmRhdGFzZXRzIHx8ICFyZXNwb25zZS5tYXAuY29uZmlnKSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihgTG9hZCBtYXAgcmVzcG9uc2UubWFwIHNob3VsZCBiZSBhbiBvYmplY3Qgd2l0aCBwcm9wZXJ0eSBkYXRhc2V0cyBvciBjb25maWdgKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBnZXREYXRhc2V0SGFuZGxlcihmb3JtYXQpIHtcbiAgY29uc3QgZGVmYXVsdEhhbmRsZXIgPSBEQVRBU0VUX0hBTkRMRVJTW0RBVEFTRVRfRk9STUFUUy5jc3ZdO1xuICBpZiAoIWZvcm1hdCkge1xuICAgIENvbnNvbGUud2FybignZm9ybWF0IGlzIG5vdCBwcm92aWRlZCBpbiBsb2FkIG1hcCByZXNwb25zZSwgd2lsbCB1c2UgY3N2IGJ5IGRlZmF1bHQnKTtcbiAgICByZXR1cm4gZGVmYXVsdEhhbmRsZXI7XG4gIH1cblxuICBpZiAoIURBVEFTRVRfSEFORExFUlNbZm9ybWF0XSkge1xuICAgIGNvbnN0IHN1cHBvcnRlZEZvcm1hdCA9IE9iamVjdC5rZXlzKERBVEFTRVRfRk9STUFUUylcbiAgICAgIC5tYXAoayA9PiBgJyR7a30nYClcbiAgICAgIC5qb2luKCcsICcpO1xuICAgIENvbnNvbGUud2FybihcbiAgICAgIGB1bmtub3duIGZvcm1hdCAke2Zvcm1hdH0uIFBsZWFzZSB1c2Ugb25lIG9mICR7c3VwcG9ydGVkRm9ybWF0fSwgd2lsbCB1c2UgY3N2IGJ5IGRlZmF1bHRgXG4gICAgKTtcbiAgICByZXR1cm4gZGVmYXVsdEhhbmRsZXI7XG4gIH1cblxuICByZXR1cm4gREFUQVNFVF9IQU5ETEVSU1tmb3JtYXRdO1xufVxuXG5mdW5jdGlvbiBwYXJzZUxvYWRNYXBSZXNwb25zZShyZXNwb25zZSwgbG9hZFBhcmFtcywgcHJvdmlkZXIpIHtcbiAgY29uc3Qge21hcCwgZm9ybWF0fSA9IHJlc3BvbnNlO1xuICBjb25zdCBwcm9jZXNzb3JNZXRob2QgPSBnZXREYXRhc2V0SGFuZGxlcihmb3JtYXQpO1xuXG4gIGNvbnN0IHBhcnNlZERhdGFzZXRzID0gdG9BcnJheShtYXAuZGF0YXNldHMpLm1hcCgoZHMsIGkpID0+IHtcbiAgICBpZiAoZm9ybWF0ID09PSBEQVRBU0VUX0ZPUk1BVFMua2VwbGVyZ2wpIHtcbiAgICAgIC8vIG5vIG5lZWQgdG8gb2J0YWluIGlkLCBkaXJlY3RseSBwYXNzIHRoZW0gaW5cbiAgICAgIHJldHVybiBwcm9jZXNzb3JNZXRob2QoZHMpO1xuICAgIH1cbiAgICBjb25zdCBpbmZvID0gKGRzICYmIGRzLmluZm8pIHx8IHtpZDogZ2VuZXJhdGVIYXNoSWQoNil9O1xuICAgIGNvbnN0IGRhdGEgPSBwcm9jZXNzb3JNZXRob2QoZHMuZGF0YSB8fCBkcyk7XG4gICAgcmV0dXJuIHtpbmZvLCBkYXRhfTtcbiAgfSk7XG5cbiAgY29uc3QgaW5mbyA9IHtcbiAgICAuLi5tYXAuaW5mbyxcbiAgICBwcm92aWRlcjogcHJvdmlkZXIubmFtZSxcbiAgICBsb2FkUGFyYW1zXG4gIH07XG4gIHJldHVybiB7XG4gICAgZGF0YXNldHM6IHBhcnNlZERhdGFzZXRzLFxuICAgIGluZm8sXG4gICAgLi4uKG1hcC5jb25maWcgPyB7Y29uZmlnOiBtYXAuY29uZmlnfSA6IHt9KVxuICB9O1xufVxuXG5leHBvcnQgY29uc3QgbG9hZENsb3VkTWFwU3VjY2Vzc1VwZGF0ZXIgPSAoXG4gIHN0YXRlOiBQcm92aWRlclN0YXRlLFxuICBhY3Rpb246IEFjdGlvblBheWxvYWQ8UHJvdmlkZXJBY3Rpb25zLkxvYWRDbG91ZE1hcFN1Y2Nlc3NQYXlsb2FkPlxuKTogUHJvdmlkZXJTdGF0ZSA9PiB7XG4gIGNvbnN0IHtyZXNwb25zZSwgbG9hZFBhcmFtcywgcHJvdmlkZXIsIG9uU3VjY2Vzcywgb25FcnJvcn0gPSBhY3Rpb24ucGF5bG9hZDtcblxuICBjb25zdCBmb3JtYXRFcnJvciA9IGNoZWNrTG9hZE1hcFJlc3BvbnNlRXJyb3IocmVzcG9uc2UpO1xuICBpZiAoZm9ybWF0RXJyb3IpIHtcbiAgICAvLyBpZiByZXNwb25zZSBmb3JtYXQgaXMgbm90IGNvcnJlY3RcbiAgICByZXR1cm4gZXhwb3J0RmlsZUVycm9yVXBkYXRlcihzdGF0ZSwge1xuICAgICAgcGF5bG9hZDoge2Vycm9yOiBmb3JtYXRFcnJvciwgcHJvdmlkZXIsIG9uRXJyb3J9XG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBuZXdTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBtYXBTYXZlZDogcHJvdmlkZXIubmFtZSxcbiAgICBjdXJyZW50UHJvdmlkZXI6IHByb3ZpZGVyLm5hbWUsXG4gICAgaXNDbG91ZE1hcExvYWRpbmc6IGZhbHNlLFxuICAgIGlzUHJvdmlkZXJMb2FkaW5nOiBmYWxzZVxuICB9O1xuXG4gIGNvbnN0IHBheWxvYWQgPSBwYXJzZUxvYWRNYXBSZXNwb25zZShyZXNwb25zZSwgbG9hZFBhcmFtcywgcHJvdmlkZXIpO1xuXG4gIGNvbnN0IHRhc2tzID0gW1xuICAgIEFDVElPTl9UQVNLKCkubWFwKF8gPT4gYWRkRGF0YVRvTWFwKHBheWxvYWQpKSxcbiAgICBjcmVhdGVBY3Rpb25UYXNrKG9uU3VjY2Vzcywge3Jlc3BvbnNlLCBsb2FkUGFyYW1zLCBwcm92aWRlcn0pLFxuICAgIEFDVElPTl9UQVNLKCkubWFwKF8gPT4gcG9zdFNhdmVMb2FkU3VjY2VzcyhgTWFwIGZyb20gJHtwcm92aWRlci5uYW1lfSBsb2FkZWRgKSlcbiAgXS5maWx0ZXIoZCA9PiBkKTtcblxuICByZXR1cm4gdGFza3MubGVuZ3RoID8gd2l0aFRhc2sobmV3U3RhdGUsIHRhc2tzKSA6IG5ld1N0YXRlO1xufTtcblxuZXhwb3J0IGNvbnN0IGxvYWRDbG91ZE1hcEVycm9yVXBkYXRlciA9IChcbiAgc3RhdGU6IFByb3ZpZGVyU3RhdGUsXG4gIGFjdGlvbjogQWN0aW9uUGF5bG9hZDxQcm92aWRlckFjdGlvbnMuTG9hZENsb3VkTWFwRXJyb3JQYXlsb2FkPlxuKTogUHJvdmlkZXJTdGF0ZSA9PiB7XG4gIGNvbnN0IG1lc3NhZ2UgPSBnZXRFcnJvcihhY3Rpb24ucGF5bG9hZC5lcnJvcikgfHwgYEVycm9yIGxvYWRpbmcgc2F2ZWQgbWFwYDtcblxuICBDb25zb2xlLndhcm4obWVzc2FnZSk7XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgaXNQcm92aWRlckxvYWRpbmc6IGZhbHNlLFxuICAgIGlzQ2xvdWRNYXBMb2FkaW5nOiBmYWxzZSxcbiAgICBwcm92aWRlckVycm9yOiBudWxsXG4gIH07XG5cbiAgcmV0dXJuIHdpdGhUYXNrKFxuICAgIG5ld1N0YXRlLFxuICAgIGNyZWF0ZUdsb2JhbE5vdGlmaWNhdGlvblRhc2tzKHt0eXBlOiAnZXJyb3InLCBtZXNzYWdlLCBkZWxheUNsb3NlOiBmYWxzZX0pXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVzZXRQcm92aWRlclN0YXR1c1VwZGF0ZXIgPSAoc3RhdGU6IFByb3ZpZGVyU3RhdGUpOiBQcm92aWRlclN0YXRlID0+ICh7XG4gIC4uLnN0YXRlLFxuICBpc1Byb3ZpZGVyTG9hZGluZzogZmFsc2UsXG4gIHByb3ZpZGVyRXJyb3I6IG51bGwsXG4gIGlzQ2xvdWRNYXBMb2FkaW5nOiBmYWxzZSxcbiAgc3VjY2Vzc0luZm86IHt9XG59KTtcblxuLyoqXG4gKiBTZXQgY3VycmVudCBjbG91ZFByb3ZpZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBzZXRDbG91ZFByb3ZpZGVyVXBkYXRlciA9IChcbiAgc3RhdGU6IFByb3ZpZGVyU3RhdGUsXG4gIGFjdGlvbjogQWN0aW9uUGF5bG9hZDxQcm92aWRlckFjdGlvbnMuU2V0Q2xvdWRQcm92aWRlclBheWxvYWQ+XG4pOiBQcm92aWRlclN0YXRlID0+ICh7XG4gIC4uLnN0YXRlLFxuICBpc1Byb3ZpZGVyTG9hZGluZzogZmFsc2UsXG4gIHByb3ZpZGVyRXJyb3I6IG51bGwsXG4gIHN1Y2Nlc3NJbmZvOiB7fSxcbiAgY3VycmVudFByb3ZpZGVyOiBhY3Rpb24ucGF5bG9hZFxufSk7XG5cbmV4cG9ydCBjb25zdCBnZXRTYXZlZE1hcHNVcGRhdGVyID0gKFxuICBzdGF0ZTogUHJvdmlkZXJTdGF0ZSxcbiAgYWN0aW9uOiBBY3Rpb25QYXlsb2FkPFByb3ZpZGVyQWN0aW9ucy5HZXRTYXZlZE1hcHNQYXlsb2FkPlxuKTogUHJvdmlkZXJTdGF0ZSA9PiB7XG4gIGNvbnN0IHByb3ZpZGVyID0gYWN0aW9uLnBheWxvYWQ7XG4gIGlmICghX3ZhbGlkYXRlUHJvdmlkZXIocHJvdmlkZXIsICdsaXN0TWFwcycpKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgY29uc3QgZ2V0U2F2ZWRNYXBzVGFzayA9IEdFVF9TQVZFRF9NQVBTX1RBU0socHJvdmlkZXIpLmJpbWFwKFxuICAgIC8vIHN1Y2Nlc3NcbiAgICB2aXN1YWxpemF0aW9ucyA9PiBnZXRTYXZlZE1hcHNTdWNjZXNzKHt2aXN1YWxpemF0aW9ucywgcHJvdmlkZXJ9KSxcbiAgICAvLyBlcnJvclxuICAgIGVycm9yID0+IGdldFNhdmVkTWFwc0Vycm9yKHtlcnJvciwgcHJvdmlkZXJ9KVxuICApO1xuXG4gIHJldHVybiB3aXRoVGFzayhcbiAgICB7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIGlzUHJvdmlkZXJMb2FkaW5nOiB0cnVlXG4gICAgfSxcbiAgICBnZXRTYXZlZE1hcHNUYXNrXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0U2F2ZWRNYXBzU3VjY2Vzc1VwZGF0ZXIgPSAoXG4gIHN0YXRlOiBQcm92aWRlclN0YXRlLFxuICBhY3Rpb246IEFjdGlvblBheWxvYWQ8UHJvdmlkZXJBY3Rpb25zLkdldFNhdmVkTWFwc1N1Y2Nlc3NQYXlsb2FkPlxuKTogUHJvdmlkZXJTdGF0ZSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgaXNQcm92aWRlckxvYWRpbmc6IGZhbHNlLFxuICB2aXN1YWxpemF0aW9uczogYWN0aW9uLnBheWxvYWQudmlzdWFsaXphdGlvbnNcbn0pO1xuXG5leHBvcnQgY29uc3QgZ2V0U2F2ZWRNYXBzRXJyb3JVcGRhdGVyID0gKFxuICBzdGF0ZTogUHJvdmlkZXJTdGF0ZSxcbiAgYWN0aW9uOiBBY3Rpb25QYXlsb2FkPFByb3ZpZGVyQWN0aW9ucy5HZXRTYXZlZE1hcHNFcnJvclBheWxvYWQ+XG4pOiBQcm92aWRlclN0YXRlID0+IHtcbiAgY29uc3QgbWVzc2FnZSA9XG4gICAgZ2V0RXJyb3IoYWN0aW9uLnBheWxvYWQuZXJyb3IpIHx8IGBFcnJvciBnZXR0aW5nIHNhdmVkIG1hcHMgZnJvbSAke3N0YXRlLmN1cnJlbnRQcm92aWRlcn1gO1xuXG4gIENvbnNvbGUud2FybihhY3Rpb24ucGF5bG9hZC5lcnJvcik7XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgY3VycmVudFByb3ZpZGVyOiBudWxsLFxuICAgIGlzUHJvdmlkZXJMb2FkaW5nOiBmYWxzZVxuICB9O1xuXG4gIHJldHVybiB3aXRoVGFzayhcbiAgICBuZXdTdGF0ZSxcbiAgICBjcmVhdGVHbG9iYWxOb3RpZmljYXRpb25UYXNrcyh7dHlwZTogJ2Vycm9yJywgbWVzc2FnZSwgZGVsYXlDbG9zZTogZmFsc2V9KVxuICApO1xufTtcbiJdfQ==
@@ -0,0 +1,4 @@
1
+ import * as providerStateUpdaters from './provider-state-updaters';
2
+ export declare const providerStateReducerFactory: (initialState?: {}) => import("redux-actions").ReduxCompatibleReducer<providerStateUpdaters.ProviderState, providerStateUpdaters.ProviderState>;
3
+ declare const _default: import("redux-actions").ReduxCompatibleReducer<providerStateUpdaters.ProviderState, providerStateUpdaters.ProviderState>;
4
+ export default _default;
@@ -0,0 +1,66 @@
1
+ // Copyright (c) 2022 Uber Technologies, Inc.
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ "use strict";
22
+
23
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
24
+
25
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
26
+
27
+ Object.defineProperty(exports, "__esModule", {
28
+ value: true
29
+ });
30
+ exports["default"] = exports.providerStateReducerFactory = void 0;
31
+
32
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
33
+
34
+ var _reduxActions = require("redux-actions");
35
+
36
+ var providerStateUpdaters = _interopRequireWildcard(require("./provider-state-updaters"));
37
+
38
+ var _actions = require("@kepler.gl/actions");
39
+
40
+ var _actionHandler;
41
+
42
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
43
+
44
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
45
+
46
+ /**
47
+ * Important: Do not rename `actionHandler` or the assignment pattern of property value.
48
+ * It is used to generate documentation
49
+ */
50
+ var actionHandler = (_actionHandler = {}, (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.EXPORT_FILE_TO_CLOUD, providerStateUpdaters.exportFileToCloudUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.EXPORT_FILE_SUCCESS, providerStateUpdaters.exportFileSuccessUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.EXPORT_FILE_ERROR, providerStateUpdaters.exportFileErrorUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.RESET_PROVIDER_STATUS, providerStateUpdaters.resetProviderStatusUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.SET_CLOUD_PROVIDER, providerStateUpdaters.setCloudProviderUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.POST_SAVE_LOAD_SUCCESS, providerStateUpdaters.postSaveLoadSuccessUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.LOAD_CLOUD_MAP, providerStateUpdaters.loadCloudMapUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.LOAD_CLOUD_MAP_SUCCESS, providerStateUpdaters.loadCloudMapSuccessUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.LOAD_CLOUD_MAP_ERROR, providerStateUpdaters.loadCloudMapErrorUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.GET_SAVED_MAPS, providerStateUpdaters.getSavedMapsUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.GET_SAVED_MAPS_SUCCESS, providerStateUpdaters.getSavedMapsSuccessUpdater), (0, _defineProperty2["default"])(_actionHandler, _actions.ProviderActionTypes.GET_SAVED_MAPS_ERROR, providerStateUpdaters.getSavedMapsErrorUpdater), _actionHandler); // construct provider-state reducer
51
+
52
+ var providerStateReducerFactory = function providerStateReducerFactory() {
53
+ var initialState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
54
+ return (// @ts-expect-error
55
+ (0, _reduxActions.handleActions)(actionHandler, _objectSpread(_objectSpread(_objectSpread({}, providerStateUpdaters.INITIAL_PROVIDER_STATE), initialState), {}, {
56
+ initialState: initialState
57
+ }))
58
+ );
59
+ };
60
+
61
+ exports.providerStateReducerFactory = providerStateReducerFactory;
62
+
63
+ var _default = providerStateReducerFactory();
64
+
65
+ exports["default"] = _default;
66
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wcm92aWRlci1zdGF0ZS50cyJdLCJuYW1lcyI6WyJhY3Rpb25IYW5kbGVyIiwiQWN0aW9uVHlwZXMiLCJFWFBPUlRfRklMRV9UT19DTE9VRCIsInByb3ZpZGVyU3RhdGVVcGRhdGVycyIsImV4cG9ydEZpbGVUb0Nsb3VkVXBkYXRlciIsIkVYUE9SVF9GSUxFX1NVQ0NFU1MiLCJleHBvcnRGaWxlU3VjY2Vzc1VwZGF0ZXIiLCJFWFBPUlRfRklMRV9FUlJPUiIsImV4cG9ydEZpbGVFcnJvclVwZGF0ZXIiLCJSRVNFVF9QUk9WSURFUl9TVEFUVVMiLCJyZXNldFByb3ZpZGVyU3RhdHVzVXBkYXRlciIsIlNFVF9DTE9VRF9QUk9WSURFUiIsInNldENsb3VkUHJvdmlkZXJVcGRhdGVyIiwiUE9TVF9TQVZFX0xPQURfU1VDQ0VTUyIsInBvc3RTYXZlTG9hZFN1Y2Nlc3NVcGRhdGVyIiwiTE9BRF9DTE9VRF9NQVAiLCJsb2FkQ2xvdWRNYXBVcGRhdGVyIiwiTE9BRF9DTE9VRF9NQVBfU1VDQ0VTUyIsImxvYWRDbG91ZE1hcFN1Y2Nlc3NVcGRhdGVyIiwiTE9BRF9DTE9VRF9NQVBfRVJST1IiLCJsb2FkQ2xvdWRNYXBFcnJvclVwZGF0ZXIiLCJHRVRfU0FWRURfTUFQUyIsImdldFNhdmVkTWFwc1VwZGF0ZXIiLCJHRVRfU0FWRURfTUFQU19TVUNDRVNTIiwiZ2V0U2F2ZWRNYXBzU3VjY2Vzc1VwZGF0ZXIiLCJHRVRfU0FWRURfTUFQU19FUlJPUiIsImdldFNhdmVkTWFwc0Vycm9yVXBkYXRlciIsInByb3ZpZGVyU3RhdGVSZWR1Y2VyRmFjdG9yeSIsImluaXRpYWxTdGF0ZSIsIklOSVRJQUxfUFJPVklERVJfU1RBVEUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFNQSxhQUFhLDBFQUNoQkMsNkJBQVlDLG9CQURJLEVBQ21CQyxxQkFBcUIsQ0FBQ0Msd0JBRHpDLG9EQUVoQkgsNkJBQVlJLG1CQUZJLEVBRWtCRixxQkFBcUIsQ0FBQ0csd0JBRnhDLG9EQUdoQkwsNkJBQVlNLGlCQUhJLEVBR2dCSixxQkFBcUIsQ0FBQ0ssc0JBSHRDLG9EQUloQlAsNkJBQVlRLHFCQUpJLEVBSW9CTixxQkFBcUIsQ0FBQ08sMEJBSjFDLG9EQUtoQlQsNkJBQVlVLGtCQUxJLEVBS2lCUixxQkFBcUIsQ0FBQ1MsdUJBTHZDLG9EQU1oQlgsNkJBQVlZLHNCQU5JLEVBTXFCVixxQkFBcUIsQ0FBQ1csMEJBTjNDLG9EQU9oQmIsNkJBQVljLGNBUEksRUFPYVoscUJBQXFCLENBQUNhLG1CQVBuQyxvREFRaEJmLDZCQUFZZ0Isc0JBUkksRUFRcUJkLHFCQUFxQixDQUFDZSwwQkFSM0Msb0RBU2hCakIsNkJBQVlrQixvQkFUSSxFQVNtQmhCLHFCQUFxQixDQUFDaUIsd0JBVHpDLG9EQVVoQm5CLDZCQUFZb0IsY0FWSSxFQVVhbEIscUJBQXFCLENBQUNtQixtQkFWbkMsb0RBV2hCckIsNkJBQVlzQixzQkFYSSxFQVdxQnBCLHFCQUFxQixDQUFDcUIsMEJBWDNDLG9EQVloQnZCLDZCQUFZd0Isb0JBWkksRUFZbUJ0QixxQkFBcUIsQ0FBQ3VCLHdCQVp6QyxrQkFBbkIsQyxDQWVBOztBQUNPLElBQU1DLDJCQUEyQixHQUFHLFNBQTlCQSwyQkFBOEI7QUFBQSxNQUFDQyxZQUFELHVFQUFnQixFQUFoQjtBQUFBLFNBQ3pDO0FBQ0EscUNBQWM1QixhQUFkLGdEQUNLRyxxQkFBcUIsQ0FBQzBCLHNCQUQzQixHQUVLRCxZQUZMO0FBR0VBLE1BQUFBLFlBQVksRUFBWkE7QUFIRjtBQUZ5QztBQUFBLENBQXBDOzs7O2VBUVFELDJCQUEyQixFIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIyIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHtoYW5kbGVBY3Rpb25zfSBmcm9tICdyZWR1eC1hY3Rpb25zJztcbmltcG9ydCAqIGFzIHByb3ZpZGVyU3RhdGVVcGRhdGVycyBmcm9tICcuL3Byb3ZpZGVyLXN0YXRlLXVwZGF0ZXJzJztcbmltcG9ydCB7UHJvdmlkZXJBY3Rpb25UeXBlcyBhcyBBY3Rpb25UeXBlc30gZnJvbSAnQGtlcGxlci5nbC9hY3Rpb25zJztcblxuLyoqXG4gKiBJbXBvcnRhbnQ6IERvIG5vdCByZW5hbWUgYGFjdGlvbkhhbmRsZXJgIG9yIHRoZSBhc3NpZ25tZW50IHBhdHRlcm4gb2YgcHJvcGVydHkgdmFsdWUuXG4gKiBJdCBpcyB1c2VkIHRvIGdlbmVyYXRlIGRvY3VtZW50YXRpb25cbiAqL1xuY29uc3QgYWN0aW9uSGFuZGxlciA9IHtcbiAgW0FjdGlvblR5cGVzLkVYUE9SVF9GSUxFX1RPX0NMT1VEXTogcHJvdmlkZXJTdGF0ZVVwZGF0ZXJzLmV4cG9ydEZpbGVUb0Nsb3VkVXBkYXRlcixcbiAgW0FjdGlvblR5cGVzLkVYUE9SVF9GSUxFX1NVQ0NFU1NdOiBwcm92aWRlclN0YXRlVXBkYXRlcnMuZXhwb3J0RmlsZVN1Y2Nlc3NVcGRhdGVyLFxuICBbQWN0aW9uVHlwZXMuRVhQT1JUX0ZJTEVfRVJST1JdOiBwcm92aWRlclN0YXRlVXBkYXRlcnMuZXhwb3J0RmlsZUVycm9yVXBkYXRlcixcbiAgW0FjdGlvblR5cGVzLlJFU0VUX1BST1ZJREVSX1NUQVRVU106IHByb3ZpZGVyU3RhdGVVcGRhdGVycy5yZXNldFByb3ZpZGVyU3RhdHVzVXBkYXRlcixcbiAgW0FjdGlvblR5cGVzLlNFVF9DTE9VRF9QUk9WSURFUl06IHByb3ZpZGVyU3RhdGVVcGRhdGVycy5zZXRDbG91ZFByb3ZpZGVyVXBkYXRlcixcbiAgW0FjdGlvblR5cGVzLlBPU1RfU0FWRV9MT0FEX1NVQ0NFU1NdOiBwcm92aWRlclN0YXRlVXBkYXRlcnMucG9zdFNhdmVMb2FkU3VjY2Vzc1VwZGF0ZXIsXG4gIFtBY3Rpb25UeXBlcy5MT0FEX0NMT1VEX01BUF06IHByb3ZpZGVyU3RhdGVVcGRhdGVycy5sb2FkQ2xvdWRNYXBVcGRhdGVyLFxuICBbQWN0aW9uVHlwZXMuTE9BRF9DTE9VRF9NQVBfU1VDQ0VTU106IHByb3ZpZGVyU3RhdGVVcGRhdGVycy5sb2FkQ2xvdWRNYXBTdWNjZXNzVXBkYXRlcixcbiAgW0FjdGlvblR5cGVzLkxPQURfQ0xPVURfTUFQX0VSUk9SXTogcHJvdmlkZXJTdGF0ZVVwZGF0ZXJzLmxvYWRDbG91ZE1hcEVycm9yVXBkYXRlcixcbiAgW0FjdGlvblR5cGVzLkdFVF9TQVZFRF9NQVBTXTogcHJvdmlkZXJTdGF0ZVVwZGF0ZXJzLmdldFNhdmVkTWFwc1VwZGF0ZXIsXG4gIFtBY3Rpb25UeXBlcy5HRVRfU0FWRURfTUFQU19TVUNDRVNTXTogcHJvdmlkZXJTdGF0ZVVwZGF0ZXJzLmdldFNhdmVkTWFwc1N1Y2Nlc3NVcGRhdGVyLFxuICBbQWN0aW9uVHlwZXMuR0VUX1NBVkVEX01BUFNfRVJST1JdOiBwcm92aWRlclN0YXRlVXBkYXRlcnMuZ2V0U2F2ZWRNYXBzRXJyb3JVcGRhdGVyXG59O1xuXG4vLyBjb25zdHJ1Y3QgcHJvdmlkZXItc3RhdGUgcmVkdWNlclxuZXhwb3J0IGNvbnN0IHByb3ZpZGVyU3RhdGVSZWR1Y2VyRmFjdG9yeSA9IChpbml0aWFsU3RhdGUgPSB7fSkgPT5cbiAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICBoYW5kbGVBY3Rpb25zKGFjdGlvbkhhbmRsZXIsIHtcbiAgICAuLi5wcm92aWRlclN0YXRlVXBkYXRlcnMuSU5JVElBTF9QUk9WSURFUl9TVEFURSxcbiAgICAuLi5pbml0aWFsU3RhdGUsXG4gICAgaW5pdGlhbFN0YXRlXG4gIH0pO1xuXG5leHBvcnQgZGVmYXVsdCBwcm92aWRlclN0YXRlUmVkdWNlckZhY3RvcnkoKTtcbiJdfQ==