@kepler.gl/reducers 3.3.0-alpha.4 → 3.3.0-alpha.6

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 (71) 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} +1 -1
  8. package/dist/cjs/interaction-utils.js +105 -0
  9. package/dist/cjs/layer-utils.js +635 -0
  10. package/dist/cjs/map-state-updaters.js +654 -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 +905 -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 +4114 -0
  24. package/dist/cjs/vis-state.js +35 -0
  25. package/dist/{combined-updaters.js → esm/combined-updaters.js} +74 -81
  26. package/dist/esm/composer-helpers.js +85 -0
  27. package/dist/esm/composers.js +14 -0
  28. package/dist/esm/core.js +101 -0
  29. package/dist/esm/data-utils.js +47 -0
  30. package/dist/esm/export-utils.js +86 -0
  31. package/dist/esm/index.js +62 -0
  32. package/dist/esm/interaction-utils.js +96 -0
  33. package/dist/esm/layer-utils.js +602 -0
  34. package/dist/esm/map-state-updaters.js +646 -0
  35. package/dist/esm/map-state.js +29 -0
  36. package/dist/esm/map-style-updaters.js +652 -0
  37. package/dist/esm/map-style.js +27 -0
  38. package/dist/esm/merger-handler.js +96 -0
  39. package/dist/esm/middleware.js +19 -0
  40. package/dist/esm/provider-state-updaters.js +458 -0
  41. package/dist/esm/provider-state.js +28 -0
  42. package/dist/esm/root.js +201 -0
  43. package/dist/esm/ui-state-updaters.js +900 -0
  44. package/dist/esm/ui-state.js +30 -0
  45. package/dist/esm/vis-state-merger.js +1161 -0
  46. package/dist/esm/vis-state-selectors.js +24 -0
  47. package/dist/esm/vis-state-updaters.js +4035 -0
  48. package/dist/esm/vis-state.js +29 -0
  49. package/package.json +31 -24
  50. package/dist/composer-helpers.js +0 -101
  51. package/dist/composers.js +0 -22
  52. package/dist/core.js +0 -105
  53. package/dist/data-utils.js +0 -53
  54. package/dist/export-utils.js +0 -91
  55. package/dist/interaction-utils.js +0 -105
  56. package/dist/layer-utils.js +0 -635
  57. package/dist/map-state-updaters.js +0 -649
  58. package/dist/map-state.js +0 -35
  59. package/dist/map-style-updaters.js +0 -660
  60. package/dist/map-style.js +0 -33
  61. package/dist/merger-handler.js +0 -105
  62. package/dist/middleware.js +0 -27
  63. package/dist/provider-state-updaters.js +0 -465
  64. package/dist/provider-state.js +0 -34
  65. package/dist/root.js +0 -207
  66. package/dist/ui-state-updaters.js +0 -905
  67. package/dist/ui-state.js +0 -36
  68. package/dist/vis-state-merger.js +0 -1193
  69. package/dist/vis-state-selectors.js +0 -30
  70. package/dist/vis-state-updaters.js +0 -4114
  71. package/dist/vis-state.js +0 -35
@@ -1,649 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.fitBoundsUpdater = exports.INITIAL_MAP_STATE = void 0;
8
- exports.getMapDimForSplitMap = getMapDimForSplitMap;
9
- exports.globeConfigChangeUpdater = void 0;
10
- exports.pickViewportPropsFromMapState = pickViewportPropsFromMapState;
11
- exports.updateMapUpdater = exports.toggleSplitMapViewportUpdater = exports.toggleSplitMapUpdater = exports.togglePerspectiveUpdater = exports.setSwipeComparePercentageUpdater = exports.setMapViewModeUpdater = exports.setMapSplitModeUpdater = exports.resetMapConfigUpdater = exports.receiveMapConfigUpdater = void 0;
12
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
- var _geoViewport = _interopRequireDefault(require("@mapbox/geo-viewport"));
15
- var _booleanWithin = require("@turf/boolean-within");
16
- var _bboxPolygon = require("@turf/bbox-polygon");
17
- var _webMercator = require("@math.gl/web-mercator");
18
- var _deepmerge = _interopRequireDefault(require("deepmerge"));
19
- var _pick = _interopRequireDefault(require("lodash/pick"));
20
- var _utils = require("@kepler.gl/utils");
21
- var _constants = require("@kepler.gl/constants");
22
- 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; }
23
- 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) { (0, _defineProperty2["default"])(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; } // SPDX-License-Identifier: MIT
24
- // Copyright contributors to the kepler.gl project
25
- /**
26
- * Updaters for `mapState` reducer. Can be used in your root reducer to directly modify kepler.gl's state.
27
- * Read more about [Using updaters](../advanced-usage/using-updaters.md)
28
- * @public
29
- * @example
30
- *
31
- * import keplerGlReducer, {mapStateUpdaters} from '@kepler.gl/reducers';
32
- * // Root Reducer
33
- * const reducers = combineReducers({
34
- * keplerGl: keplerGlReducer,
35
- * app: appReducer
36
- * });
37
- *
38
- * const composedReducer = (state, action) => {
39
- * switch (action.type) {
40
- * // click button to close side panel
41
- * case 'CLICK_BUTTON':
42
- * return {
43
- * ...state,
44
- * keplerGl: {
45
- * ...state.keplerGl,
46
- * foo: {
47
- * ...state.keplerGl.foo,
48
- * mapState: mapStateUpdaters.fitBoundsUpdater(
49
- * mapState, {payload: [127.34, 31.09, 127.56, 31.59]]}
50
- * )
51
- * }
52
- * }
53
- * };
54
- * }
55
- * return reducers(state, action);
56
- * };
57
- *
58
- * export default composedReducer;
59
- */
60
-
61
- /* eslint-disable @typescript-eslint/no-unused-vars */
62
- // @ts-ignore
63
- var mapStateUpdaters = null;
64
- /* eslint-enable @typescript-eslint/no-unused-vars */
65
- /**
66
- * Default initial `mapState`
67
- * @memberof mapStateUpdaters
68
- * @constant
69
- * @property pitch Default: `0`
70
- * @property bearing Default: `0`
71
- * @property latitude Default: `37.75043`
72
- * @property longitude Default: `-122.34679`
73
- * @property zoom Default: `9`
74
- * @property dragRotate Default: `false`
75
- * @property width Default: `800`
76
- * @property height Default: `800`
77
- * @property minZoom: `undefined`,
78
- * @property maxZoom: `undefined`,
79
- * @property maxPitch: `undefined` (defaults to application config value, deck.gl default is 60)
80
- * @property maxBounds: `undefined`,
81
- * @property isSplit: `false`,
82
- * @property isViewportSynced: `true`,
83
- * @property isZoomLocked: `false`,
84
- * @property splitMapViewports: `[]`
85
- * @public
86
- */
87
- var INITIAL_MAP_STATE = exports.INITIAL_MAP_STATE = {
88
- pitch: 0,
89
- bearing: 0,
90
- latitude: 37.75043,
91
- longitude: -122.34679,
92
- zoom: 9,
93
- dragRotate: false,
94
- width: 800,
95
- height: 800,
96
- minZoom: undefined,
97
- maxZoom: undefined,
98
- maxPitch: undefined,
99
- maxBounds: undefined,
100
- isSplit: false,
101
- isViewportSynced: true,
102
- isZoomLocked: false,
103
- splitMapViewports: [],
104
- mapViewMode: _constants.MapViewMode.MODE_2D,
105
- globe: {
106
- enabled: false,
107
- config: _constants.DEFAULT_GLOBE_CONFIG
108
- },
109
- mapSplitMode: _constants.MapSplitMode.SINGLE_MAP,
110
- swipeComparePercentage: 50
111
- };
112
-
113
- /* Updaters */
114
- /**
115
- * Update map viewport
116
- * @memberof mapStateUpdaters
117
- * @public
118
- */
119
- var updateMapUpdater = exports.updateMapUpdater = function updateMapUpdater(state, action) {
120
- var _action$payload = action.payload,
121
- inputViewport = _action$payload.viewport,
122
- _action$payload$mapIn = _action$payload.mapIndex,
123
- mapIndex = _action$payload$mapIn === void 0 ? 0 : _action$payload$mapIn;
124
- var viewport = (0, _utils.validateViewPort)(inputViewport);
125
- if (state.isViewportSynced) {
126
- // The `updateViewport` function is typed as (Viewport, Viewport) -> Viewport but here the
127
- // expected typing is (MapState, Viewport) -> MapState.
128
- // this could be a potential bug as we treat Viewport and MapState as equal seemingly
129
- // @ts-expect-error Type 'Viewport' is missing the following properties from type 'MapState': isSplit, isViewportSynced, isZoomLocked, splitMapViewports
130
- return updateViewport(state, viewport);
131
- }
132
- var otherViewportMapIndex = -1;
133
- var splitMapViewports = state.splitMapViewports.map(function (currentViewport, i) {
134
- if (i === mapIndex) {
135
- // update the matching viewport with the newViewport info in the action payload
136
- return updateViewport(currentViewport, viewport);
137
- }
138
- otherViewportMapIndex = i;
139
- // make no changes to the other viewport (yet)
140
- return currentViewport;
141
- });
142
-
143
- // make conditional updates to the other viewport not matching this payload's `mapIndex`
144
- if (Number.isFinite(otherViewportMapIndex) && otherViewportMapIndex > -1) {
145
- // width and height are a special case and are always updated
146
- splitMapViewports[otherViewportMapIndex] = _objectSpread(_objectSpread({}, splitMapViewports[otherViewportMapIndex]), {}, {
147
- width: splitMapViewports[mapIndex].width,
148
- height: splitMapViewports[mapIndex].height
149
- });
150
- if (state.isZoomLocked) {
151
- // update the other viewport with the new zoom from the split viewport that was updated with this payload's `mapIndex`
152
- splitMapViewports[otherViewportMapIndex] = _objectSpread(_objectSpread({}, splitMapViewports[otherViewportMapIndex]), {}, {
153
- zoom: splitMapViewports[mapIndex].zoom
154
- });
155
- }
156
- }
157
- return _objectSpread(_objectSpread(_objectSpread({}, state), splitMapViewports[mapIndex]), {}, {
158
- // update the mapState with the new array of split viewports
159
- splitMapViewports: splitMapViewports
160
- });
161
- };
162
-
163
- /**
164
- * Fit map viewport to bounds
165
- * @memberof mapStateUpdaters
166
- * @public
167
- */
168
- var fitBoundsUpdater = exports.fitBoundsUpdater = function fitBoundsUpdater(state, action) {
169
- var centerAndZoom = (0, _utils.getCenterAndZoomFromBounds)(action.payload, {
170
- width: state.width,
171
- height: state.height
172
- });
173
- if (!centerAndZoom) {
174
- // bounds is invalid
175
- return state;
176
- }
177
- var newState = _objectSpread(_objectSpread({}, state), {}, {
178
- latitude: centerAndZoom.center[1],
179
- longitude: centerAndZoom.center[0]
180
- }, Number.isFinite(centerAndZoom.zoom) ? {
181
- zoom: centerAndZoom.zoom
182
- } : {});
183
-
184
- // if fitting to bounds while split and unsynced
185
- // copy the new latitude, longitude, and zoom values to each split viewport
186
- if (newState.splitMapViewports.length) {
187
- newState.splitMapViewports = newState.splitMapViewports.map(function (currentViewport) {
188
- return _objectSpread(_objectSpread({}, currentViewport), {}, {
189
- latitude: newState.latitude,
190
- longitude: newState.longitude,
191
- zoom: newState.zoom
192
- });
193
- });
194
- }
195
- return newState;
196
- };
197
-
198
- /**
199
- * Toggle between 3d and 2d map.
200
- * @memberof mapStateUpdaters
201
- * @public
202
- */
203
- var togglePerspectiveUpdater = exports.togglePerspectiveUpdater = function togglePerspectiveUpdater(state) {
204
- var _state$globe;
205
- // Only drop min/maxZoom when we're actually leaving globe mode, where those
206
- // bounds are set to globe-only values. If globe was never enabled these are
207
- // the app's own custom bounds and must be preserved.
208
- var wasGlobeEnabled = Boolean((_state$globe = state.globe) === null || _state$globe === void 0 ? void 0 : _state$globe.enabled);
209
- var newState = _objectSpread(_objectSpread(_objectSpread({}, state), {
210
- pitch: state.dragRotate ? 0 : 50,
211
- bearing: state.dragRotate ? 0 : 24
212
- }), {}, {
213
- dragRotate: !state.dragRotate,
214
- mapViewMode: state.dragRotate ? _constants.MapViewMode.MODE_2D : _constants.MapViewMode.MODE_3D,
215
- globe: _objectSpread(_objectSpread({}, state.globe), {}, {
216
- enabled: false
217
- })
218
- }, wasGlobeEnabled ? {
219
- minZoom: undefined,
220
- maxZoom: undefined
221
- } : {});
222
-
223
- // if toggling 3d and 2d while split and unsynced
224
- // copy the new pitch, bearing, and dragRotate values to each split viewport
225
- if (newState.splitMapViewports.length) {
226
- newState.splitMapViewports = newState.splitMapViewports.map(function (currentViewport) {
227
- return _objectSpread(_objectSpread({}, currentViewport), {}, {
228
- pitch: newState.pitch,
229
- bearing: newState.bearing,
230
- dragRotate: newState.dragRotate
231
- });
232
- });
233
- }
234
- return newState;
235
- };
236
-
237
- /**
238
- * Set map view mode (2D, 3D, Globe)
239
- * @memberof mapStateUpdaters
240
- * @public
241
- */
242
- var setMapViewModeUpdater = exports.setMapViewModeUpdater = function setMapViewModeUpdater(state, action) {
243
- var _state$globe2;
244
- var mapViewMode = action.payload.mapViewMode;
245
- var nextState;
246
-
247
- // Only clear min/maxZoom when leaving globe mode (where they hold globe-only
248
- // bounds). Otherwise preserve the app's custom bounds.
249
- var wasGlobeEnabled = Boolean((_state$globe2 = state.globe) === null || _state$globe2 === void 0 ? void 0 : _state$globe2.enabled);
250
- switch (mapViewMode) {
251
- case _constants.MapViewMode.MODE_2D:
252
- nextState = _objectSpread(_objectSpread(_objectSpread({}, state), {}, {
253
- globe: _objectSpread(_objectSpread({}, state.globe), {}, {
254
- enabled: false
255
- }),
256
- pitch: 0,
257
- bearing: 0,
258
- dragRotate: false
259
- }, wasGlobeEnabled ? {
260
- minZoom: undefined,
261
- maxZoom: undefined
262
- } : {}), {}, {
263
- mapViewMode: mapViewMode
264
- });
265
- break;
266
- case _constants.MapViewMode.MODE_3D:
267
- nextState = _objectSpread(_objectSpread(_objectSpread({}, state), {}, {
268
- globe: _objectSpread(_objectSpread({}, state.globe), {}, {
269
- enabled: false
270
- }),
271
- pitch: 50,
272
- bearing: 24,
273
- dragRotate: true
274
- }, wasGlobeEnabled ? {
275
- minZoom: undefined,
276
- maxZoom: undefined
277
- } : {}), {}, {
278
- mapViewMode: mapViewMode
279
- });
280
- break;
281
- case _constants.MapViewMode.MODE_GLOBE:
282
- nextState = _objectSpread(_objectSpread({}, state), {}, {
283
- globe: _objectSpread(_objectSpread({}, state.globe), {}, {
284
- enabled: true
285
- }),
286
- dragRotate: true,
287
- pitch: 0,
288
- bearing: 0,
289
- // Allow zooming out further than the default so the whole globe can be
290
- // pulled back on screen. Cap the max zoom so the basemap tiles stay
291
- // coherent (they break down at high globe zoom in deck.gl 9.x).
292
- minZoom: _constants.GLOBE_MIN_ZOOM,
293
- maxZoom: _constants.GLOBE_MAX_ZOOM,
294
- zoom: Math.min(Math.max(state.zoom, _constants.GLOBE_MIN_ZOOM), _constants.GLOBE_MAX_ZOOM),
295
- mapViewMode: mapViewMode
296
- });
297
- break;
298
- default:
299
- return state;
300
- }
301
- if (nextState.splitMapViewports.length) {
302
- nextState.splitMapViewports = nextState.splitMapViewports.map(function (currentViewport) {
303
- return _objectSpread(_objectSpread({}, currentViewport), {}, {
304
- pitch: nextState.pitch,
305
- bearing: nextState.bearing,
306
- dragRotate: nextState.dragRotate
307
- });
308
- });
309
- }
310
- return nextState;
311
- };
312
-
313
- /**
314
- * Update globe config
315
- * @memberof mapStateUpdaters
316
- * @public
317
- */
318
- var globeConfigChangeUpdater = exports.globeConfigChangeUpdater = function globeConfigChangeUpdater(state, action) {
319
- return _objectSpread(_objectSpread({}, state), {}, {
320
- globe: _objectSpread(_objectSpread({}, state.globe), {}, {
321
- config: _objectSpread(_objectSpread({}, state.globe.config), action.payload)
322
- })
323
- });
324
- };
325
-
326
- /**
327
- * reset mapState to initial State
328
- * @memberof mapStateUpdaters
329
- * @public
330
- */
331
- var resetMapConfigUpdater = exports.resetMapConfigUpdater = function resetMapConfigUpdater(state) {
332
- return _objectSpread(_objectSpread(_objectSpread({}, INITIAL_MAP_STATE), state.initialState), {}, {
333
- initialState: state.initialState
334
- });
335
- };
336
-
337
- // consider case where you have a split map and user wants to reset
338
- /**
339
- * Update `mapState` to propagate a new config
340
- * @memberof mapStateUpdaters
341
- * @public
342
- */
343
- var receiveMapConfigUpdater = exports.receiveMapConfigUpdater = function receiveMapConfigUpdater(state, _ref) {
344
- var _ref$payload = _ref.payload,
345
- _ref$payload$config = _ref$payload.config,
346
- config = _ref$payload$config === void 0 ? {} : _ref$payload$config,
347
- _ref$payload$options = _ref$payload.options,
348
- options = _ref$payload$options === void 0 ? {} : _ref$payload$options,
349
- _ref$payload$bounds = _ref$payload.bounds,
350
- bounds = _ref$payload$bounds === void 0 ? null : _ref$payload$bounds;
351
- /**
352
- * @type {Partial<MapState>}
353
- */
354
- var mapState = (config || {}).mapState || {};
355
- // merged received mapState with previous state
356
- // state also may include properties that are new to an existing, saved project's mapState
357
-
358
- var mergedState = (0, _deepmerge["default"])(state, mapState, {
359
- // note: deepmerge by default will merge arrays by concatenating them
360
- // but we need to overwrite destination arrays with source arrays, if present
361
- // https://github.com/TehShrike/deepmerge#arraymerge-example-overwrite-target-array
362
- arrayMerge: function arrayMerge(_destinationArray, sourceArray) {
363
- return sourceArray;
364
- }
365
- });
366
-
367
- // if center map
368
- // center map will override mapState config
369
- if (options.centerMap && bounds) {
370
- mergedState = fitBoundsUpdater(mergedState, {
371
- payload: bounds
372
- });
373
- }
374
-
375
- // make sure we validate map state before we merge
376
- mergedState = (0, _utils.validateViewPort)(mergedState);
377
- return _objectSpread(_objectSpread({}, mergedState), getMapDimForSplitMap(mergedState.isSplit, state));
378
- };
379
-
380
- /**
381
- * Toggle between one or split maps
382
- * @memberof mapStateUpdaters
383
- * @public
384
- */
385
- var toggleSplitMapUpdater = exports.toggleSplitMapUpdater = function toggleSplitMapUpdater(state) {
386
- return _objectSpread(_objectSpread(_objectSpread({}, state), getMapDimForSplitMap(!state.isSplit, state)), {}, {
387
- isSplit: !state.isSplit,
388
- mapSplitMode: !state.isSplit ? _constants.MapSplitMode.DUAL_MAP : _constants.MapSplitMode.SINGLE_MAP
389
- }, !state.isSplit === false ? {
390
- // if toggling to no longer split (single mode) then reset a few properties
391
- isViewportSynced: true,
392
- isZoomLocked: false,
393
- splitMapViewports: []
394
- } : {});
395
- };
396
-
397
- /**
398
- * Set the map split mode (single, dual, or swipe)
399
- * @memberof mapStateUpdaters
400
- * @public
401
- */
402
- var setMapSplitModeUpdater = exports.setMapSplitModeUpdater = function setMapSplitModeUpdater(state, action) {
403
- var mapSplitMode = action.payload.mapSplitMode;
404
- var prevMode = state.mapSplitMode;
405
- if (mapSplitMode === prevMode) {
406
- return state;
407
- }
408
- switch (mapSplitMode) {
409
- case _constants.MapSplitMode.SINGLE_MAP:
410
- return _objectSpread(_objectSpread(_objectSpread({}, state), {}, {
411
- mapSplitMode: mapSplitMode,
412
- isSplit: false
413
- }, prevMode === _constants.MapSplitMode.DUAL_MAP && {
414
- width: state.width * 2
415
- }), {}, {
416
- isViewportSynced: true,
417
- isZoomLocked: false,
418
- splitMapViewports: []
419
- });
420
- case _constants.MapSplitMode.DUAL_MAP:
421
- return _objectSpread(_objectSpread(_objectSpread({}, state), {}, {
422
- mapSplitMode: mapSplitMode,
423
- isSplit: true
424
- }, prevMode === _constants.MapSplitMode.SINGLE_MAP && {
425
- width: state.width / 2
426
- }), prevMode === _constants.MapSplitMode.SWIPE_COMPARE && {
427
- width: state.width / 2
428
- });
429
- case _constants.MapSplitMode.SWIPE_COMPARE:
430
- return _objectSpread(_objectSpread(_objectSpread({}, state), {}, {
431
- mapSplitMode: mapSplitMode,
432
- isSplit: true
433
- }, prevMode === _constants.MapSplitMode.DUAL_MAP && {
434
- width: state.width * 2
435
- }), {}, {
436
- isViewportSynced: true,
437
- isZoomLocked: false,
438
- splitMapViewports: []
439
- });
440
- default:
441
- return state;
442
- }
443
- };
444
-
445
- /**
446
- * Set the swipe compare percentage
447
- * @memberof mapStateUpdaters
448
- * @public
449
- */
450
- var setSwipeComparePercentageUpdater = exports.setSwipeComparePercentageUpdater = function setSwipeComparePercentageUpdater(state, action) {
451
- var percentage = action.payload.percentage;
452
- var clamped = Math.min(100, Math.max(0, percentage));
453
- if (clamped === state.swipeComparePercentage) {
454
- return state;
455
- }
456
- return _objectSpread(_objectSpread({}, state), {}, {
457
- swipeComparePercentage: clamped
458
- });
459
- };
460
-
461
- /**
462
- * Toggle between locked and unlocked split viewports
463
- * @memberof mapStateUpdaters
464
- * @public
465
- */
466
- var toggleSplitMapViewportUpdater = exports.toggleSplitMapViewportUpdater = function toggleSplitMapViewportUpdater(state, action) {
467
- // Swipe mode always uses synced viewports
468
- if (state.mapSplitMode === _constants.MapSplitMode.SWIPE_COMPARE) {
469
- return state;
470
- }
471
-
472
- // new map state immediately gets the new, optional payload values for isViewportSynced and/or isZoomLocked
473
- var newMapState = _objectSpread(_objectSpread({}, state), action.payload || {});
474
- if (newMapState.isViewportSynced) {
475
- // switching from unsynced to synced viewports
476
- newMapState.splitMapViewports = [];
477
- } else {
478
- // switching from synced to unsynced viewports
479
- // or already in unsynced mode and toggling locked zoom
480
-
481
- if (state.isZoomLocked && !newMapState.isZoomLocked) {
482
- // switching off locked zoom while unsynced
483
- // don't copy the mapStates to left and right viewports because there will be zoom "jumping"
484
- return newMapState;
485
- }
486
- if (!state.isZoomLocked && newMapState.isZoomLocked) {
487
- // switching on locked zoom while unsynced
488
- // only copy zoom viewport property from the most recently interacted-with viewport to the other
489
- // TODO: do we want to check for a match a different way, such as a combo of `latitude` and `longitude`?
490
- var lastUpdatedViewportIndex = newMapState.splitMapViewports.findIndex(function (v) {
491
- return newMapState.zoom === v.zoom;
492
- });
493
- var splitMapViewports = newMapState.splitMapViewports.map(function (currentViewport, i) {
494
- if (i === lastUpdatedViewportIndex) {
495
- // no zoom to modify here
496
- return currentViewport;
497
- }
498
- // the other viewport gets the most recently interacted-with viewport's zoom
499
- // WHY? the viewport the user was last interacting with will set zoom across the board for smooth UX
500
- return _objectSpread(_objectSpread({}, currentViewport), {}, {
501
- zoom: newMapState.splitMapViewports[lastUpdatedViewportIndex].zoom
502
- });
503
- });
504
- newMapState.splitMapViewports = splitMapViewports;
505
- return newMapState;
506
- }
507
-
508
- // if current viewport is synced, and we are unsyncing it
509
- // or already in unsynced mode and NOT toggling locked zoom
510
- // make a fresh copy of the current viewport object, assign it to splitMapViewports[]
511
- // pickViewportPropsFromMapState is called twice to avoid memory allocation conflicts
512
- var leftViewport = pickViewportPropsFromMapState(newMapState);
513
- var rightViewport = pickViewportPropsFromMapState(newMapState);
514
- newMapState.splitMapViewports = [leftViewport, rightViewport];
515
- }
516
-
517
- // return new state
518
- return newMapState;
519
- };
520
-
521
- // Helpers
522
- function getMapDimForSplitMap(isSplit, state) {
523
- // cases:
524
- // 1. state split: true - isSplit: true
525
- // do nothing
526
- // 2. state split: false - isSplit: false
527
- // do nothing
528
- if (state.isSplit === isSplit) {
529
- return {};
530
- }
531
-
532
- // In swipe mode, both maps use full width (overlapping with clip)
533
- if (state.mapSplitMode === _constants.MapSplitMode.SWIPE_COMPARE) {
534
- return {};
535
- }
536
- var width = state.isSplit && !isSplit ?
537
- // 3. state split: true - isSplit: false
538
- // double width
539
- state.width * 2 :
540
- // 4. state split: false - isSplit: true
541
- // split width
542
- state.width / 2;
543
- return {
544
- width: width
545
- };
546
- }
547
- function updateViewportBasedOnBounds(state, newMapState) {
548
- // Get the new viewport bounds
549
- var viewportBounds = _geoViewport["default"].bounds([newMapState.longitude, newMapState.latitude], newMapState.zoom, [newMapState.width, newMapState.height], _utils.MAPBOX_TILE_SIZE);
550
- // Generate turf Polygon from bounds for comparison
551
- var viewportBoundsPolygon = (0, _bboxPolygon.bboxPolygon)(viewportBounds);
552
- // @ts-ignore
553
- var newStateMaxBounds = newMapState.maxBounds;
554
- // @ts-ignore
555
- var maxBoundsPolygon = (0, _bboxPolygon.bboxPolygon)(newStateMaxBounds);
556
-
557
- // If maxBounds has changed reset the viewport to snap to bounds
558
- var hasMaxBoundsChanged = !state.maxBounds || !state.maxBounds.every(function (val, idx) {
559
- return val === newStateMaxBounds[idx];
560
- });
561
- if (hasMaxBoundsChanged) {
562
- // Check if the newMapState viewport is within maxBounds
563
- if (!(0, _booleanWithin.booleanWithin)(viewportBoundsPolygon, maxBoundsPolygon)) {
564
- var _fitBounds = (0, _webMercator.fitBounds)({
565
- width: newMapState.width,
566
- height: newMapState.height,
567
- bounds: [[newStateMaxBounds[0], newStateMaxBounds[1]], [newStateMaxBounds[2], newStateMaxBounds[3]]]
568
- }),
569
- latitude = _fitBounds.latitude,
570
- longitude = _fitBounds.longitude,
571
- zoom = _fitBounds.zoom;
572
- newMapState = _objectSpread(_objectSpread({}, newMapState), {}, {
573
- latitude: latitude,
574
- longitude: longitude
575
- }, Number.isFinite(zoom) ? {
576
- zoom: zoom
577
- } : {});
578
- }
579
- return newMapState;
580
- }
581
-
582
- // Check if the newMapState viewport is within maxBounds
583
- if (!(0, _booleanWithin.booleanWithin)(viewportBoundsPolygon, maxBoundsPolygon)) {
584
- newMapState = _objectSpread(_objectSpread({}, newMapState), {}, {
585
- longitude: state.longitude,
586
- latitude: state.latitude,
587
- zoom: state.zoom
588
- });
589
- }
590
- return newMapState;
591
- }
592
- function pickViewportPropsFromMapState(state) {
593
- return (0, _pick["default"])(state, ['width', 'height', 'zoom', 'pitch', 'bearing', 'latitude', 'longitude', 'dragRotate', 'minZoom', 'maxZoom', 'maxPitch', 'maxBounds']);
594
- }
595
-
596
- /** Select items from object whose value is not undefined */
597
- var definedProps = function definedProps(obj) {
598
- return Object.entries(obj).reduce(function (accu, _ref2) {
599
- var _ref3 = (0, _slicedToArray2["default"])(_ref2, 2),
600
- k = _ref3[0],
601
- v = _ref3[1];
602
- return _objectSpread(_objectSpread({}, accu), v !== undefined ? (0, _defineProperty2["default"])({}, k, v) : {});
603
- }, {});
604
- };
605
- function updateViewport(originalViewport, viewportUpdates) {
606
- var _globe;
607
- var newViewport = _objectSpread(_objectSpread({}, originalViewport), definedProps(viewportUpdates) || {});
608
-
609
- // deck.gl's globe controller applies a latitude-dependent adjustment to the
610
- // zoom range (see KeplerGlobeView._constrainZoom). If we clamp the propagated
611
- // zoom here against the raw minZoom/maxZoom (without that adjustment), Redux
612
- // ends up disagreeing with the controller: the controller lets the user pull
613
- // the globe further out, but this clamp snaps zoom back to `minZoom` when the
614
- // interaction's inertia transition ends. Apply the same adjustment in globe
615
- // mode so Redux stays consistent with the controller and there's no snap-back.
616
- var isGlobe = (_globe = newViewport.globe) === null || _globe === void 0 ? void 0 : _globe.enabled;
617
- if (isGlobe) {
618
- var _newViewport$latitude;
619
- // Keep the camera target within a latitude band around the equator so the
620
- // stored viewport can't be centered on the poles (matches the globe
621
- // controller's applyConstraints so geocoder/programmatic updates agree).
622
- if (typeof newViewport.latitude === 'number') {
623
- newViewport.latitude = Math.min(_constants.GLOBE_MAX_LATITUDE, Math.max(-_constants.GLOBE_MAX_LATITUDE, newViewport.latitude));
624
- }
625
- var zoomAdjustment = Math.log2(Math.cos(((_newViewport$latitude = newViewport.latitude) !== null && _newViewport$latitude !== void 0 ? _newViewport$latitude : 0) * Math.PI / 180));
626
- if (typeof newViewport.minZoom === 'number' && typeof newViewport.zoom === 'number' && newViewport.zoom < newViewport.minZoom + zoomAdjustment) {
627
- newViewport.zoom = newViewport.minZoom + zoomAdjustment;
628
- }
629
- if (typeof newViewport.maxZoom === 'number' && typeof newViewport.zoom === 'number' && newViewport.zoom > newViewport.maxZoom + zoomAdjustment) {
630
- newViewport.zoom = newViewport.maxZoom + zoomAdjustment;
631
- }
632
- } else {
633
- // Make sure zoom level doesn't go bellow minZoom if defined
634
- if (newViewport.minZoom && newViewport.zoom && newViewport.zoom < newViewport.minZoom) {
635
- newViewport.zoom = newViewport.minZoom;
636
- }
637
- // Make sure zoom level doesn't go above maxZoom if defined
638
- if (newViewport.maxZoom && newViewport.zoom && newViewport.zoom > newViewport.maxZoom) {
639
- newViewport.zoom = newViewport.maxZoom;
640
- }
641
- }
642
- // Limit viewport update based on maxBounds
643
- if (newViewport.maxBounds && (0, _utils.validateBounds)(newViewport.maxBounds)) {
644
- // @ts-expect-error Type 'Viewport' is missing the following properties from type 'MapState': isSplit, isViewportSynced, isZoomLocked, splitMapViewports
645
- newViewport = updateViewportBasedOnBounds(originalViewport, newViewport);
646
- }
647
- return newViewport;
648
- }
649
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZ2VvVmlld3BvcnQiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9ib29sZWFuV2l0aGluIiwiX2Jib3hQb2x5Z29uIiwiX3dlYk1lcmNhdG9yIiwiX2RlZXBtZXJnZSIsIl9waWNrIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwibWFwU3RhdGVVcGRhdGVycyIsIklOSVRJQUxfTUFQX1NUQVRFIiwiZXhwb3J0cyIsInBpdGNoIiwiYmVhcmluZyIsImxhdGl0dWRlIiwibG9uZ2l0dWRlIiwiem9vbSIsImRyYWdSb3RhdGUiLCJ3aWR0aCIsImhlaWdodCIsIm1pblpvb20iLCJ1bmRlZmluZWQiLCJtYXhab29tIiwibWF4UGl0Y2giLCJtYXhCb3VuZHMiLCJpc1NwbGl0IiwiaXNWaWV3cG9ydFN5bmNlZCIsImlzWm9vbUxvY2tlZCIsInNwbGl0TWFwVmlld3BvcnRzIiwibWFwVmlld01vZGUiLCJNYXBWaWV3TW9kZSIsIk1PREVfMkQiLCJnbG9iZSIsImVuYWJsZWQiLCJjb25maWciLCJERUZBVUxUX0dMT0JFX0NPTkZJRyIsIm1hcFNwbGl0TW9kZSIsIk1hcFNwbGl0TW9kZSIsIlNJTkdMRV9NQVAiLCJzd2lwZUNvbXBhcmVQZXJjZW50YWdlIiwidXBkYXRlTWFwVXBkYXRlciIsInN0YXRlIiwiYWN0aW9uIiwiX2FjdGlvbiRwYXlsb2FkIiwicGF5bG9hZCIsImlucHV0Vmlld3BvcnQiLCJ2aWV3cG9ydCIsIl9hY3Rpb24kcGF5bG9hZCRtYXBJbiIsIm1hcEluZGV4IiwidmFsaWRhdGVWaWV3UG9ydCIsInVwZGF0ZVZpZXdwb3J0Iiwib3RoZXJWaWV3cG9ydE1hcEluZGV4IiwibWFwIiwiY3VycmVudFZpZXdwb3J0IiwiaSIsIk51bWJlciIsImlzRmluaXRlIiwiZml0Qm91bmRzVXBkYXRlciIsImNlbnRlckFuZFpvb20iLCJnZXRDZW50ZXJBbmRab29tRnJvbUJvdW5kcyIsIm5ld1N0YXRlIiwiY2VudGVyIiwidG9nZ2xlUGVyc3BlY3RpdmVVcGRhdGVyIiwiX3N0YXRlJGdsb2JlIiwid2FzR2xvYmVFbmFibGVkIiwiQm9vbGVhbiIsIk1PREVfM0QiLCJzZXRNYXBWaWV3TW9kZVVwZGF0ZXIiLCJfc3RhdGUkZ2xvYmUyIiwibmV4dFN0YXRlIiwiTU9ERV9HTE9CRSIsIkdMT0JFX01JTl9aT09NIiwiR0xPQkVfTUFYX1pPT00iLCJNYXRoIiwibWluIiwibWF4IiwiZ2xvYmVDb25maWdDaGFuZ2VVcGRhdGVyIiwicmVzZXRNYXBDb25maWdVcGRhdGVyIiwiaW5pdGlhbFN0YXRlIiwicmVjZWl2ZU1hcENvbmZpZ1VwZGF0ZXIiLCJfcmVmIiwiX3JlZiRwYXlsb2FkIiwiX3JlZiRwYXlsb2FkJGNvbmZpZyIsIl9yZWYkcGF5bG9hZCRvcHRpb25zIiwib3B0aW9ucyIsIl9yZWYkcGF5bG9hZCRib3VuZHMiLCJib3VuZHMiLCJtYXBTdGF0ZSIsIm1lcmdlZFN0YXRlIiwiZGVlcG1lcmdlIiwiYXJyYXlNZXJnZSIsIl9kZXN0aW5hdGlvbkFycmF5Iiwic291cmNlQXJyYXkiLCJjZW50ZXJNYXAiLCJnZXRNYXBEaW1Gb3JTcGxpdE1hcCIsInRvZ2dsZVNwbGl0TWFwVXBkYXRlciIsIkRVQUxfTUFQIiwic2V0TWFwU3BsaXRNb2RlVXBkYXRlciIsInByZXZNb2RlIiwiU1dJUEVfQ09NUEFSRSIsInNldFN3aXBlQ29tcGFyZVBlcmNlbnRhZ2VVcGRhdGVyIiwicGVyY2VudGFnZSIsImNsYW1wZWQiLCJ0b2dnbGVTcGxpdE1hcFZpZXdwb3J0VXBkYXRlciIsIm5ld01hcFN0YXRlIiwibGFzdFVwZGF0ZWRWaWV3cG9ydEluZGV4IiwiZmluZEluZGV4IiwidiIsImxlZnRWaWV3cG9ydCIsInBpY2tWaWV3cG9ydFByb3BzRnJvbU1hcFN0YXRlIiwicmlnaHRWaWV3cG9ydCIsInVwZGF0ZVZpZXdwb3J0QmFzZWRPbkJvdW5kcyIsInZpZXdwb3J0Qm91bmRzIiwiZ2VvVmlld3BvcnQiLCJNQVBCT1hfVElMRV9TSVpFIiwidmlld3BvcnRCb3VuZHNQb2x5Z29uIiwiYmJveFBvbHlnb24iLCJuZXdTdGF0ZU1heEJvdW5kcyIsIm1heEJvdW5kc1BvbHlnb24iLCJoYXNNYXhCb3VuZHNDaGFuZ2VkIiwiZXZlcnkiLCJ2YWwiLCJpZHgiLCJib29sZWFuV2l0aGluIiwiX2ZpdEJvdW5kcyIsImZpdEJvdW5kcyIsInBpY2siLCJkZWZpbmVkUHJvcHMiLCJvYmoiLCJlbnRyaWVzIiwicmVkdWNlIiwiYWNjdSIsIl9yZWYyIiwiX3JlZjMiLCJfc2xpY2VkVG9BcnJheTIiLCJrIiwib3JpZ2luYWxWaWV3cG9ydCIsInZpZXdwb3J0VXBkYXRlcyIsIl9nbG9iZSIsIm5ld1ZpZXdwb3J0IiwiaXNHbG9iZSIsIl9uZXdWaWV3cG9ydCRsYXRpdHVkZSIsIkdMT0JFX01BWF9MQVRJVFVERSIsInpvb21BZGp1c3RtZW50IiwibG9nMiIsImNvcyIsIlBJIiwidmFsaWRhdGVCb3VuZHMiXSwic291cmNlcyI6WyIuLi9zcmMvbWFwLXN0YXRlLXVwZGF0ZXJzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCBnZW9WaWV3cG9ydCBmcm9tICdAbWFwYm94L2dlby12aWV3cG9ydCc7XG5pbXBvcnQge2Jvb2xlYW5XaXRoaW59IGZyb20gJ0B0dXJmL2Jvb2xlYW4td2l0aGluJztcbmltcG9ydCB7YmJveFBvbHlnb259IGZyb20gJ0B0dXJmL2Jib3gtcG9seWdvbic7XG5pbXBvcnQge2ZpdEJvdW5kc30gZnJvbSAnQG1hdGguZ2wvd2ViLW1lcmNhdG9yJztcbmltcG9ydCBkZWVwbWVyZ2UgZnJvbSAnZGVlcG1lcmdlJztcbmltcG9ydCBwaWNrIGZyb20gJ2xvZGFzaC9waWNrJztcblxuaW1wb3J0IHtcbiAgZ2V0Q2VudGVyQW5kWm9vbUZyb21Cb3VuZHMsXG4gIHZhbGlkYXRlQm91bmRzLFxuICBNQVBCT1hfVElMRV9TSVpFLFxuICB2YWxpZGF0ZVZpZXdQb3J0XG59IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuaW1wb3J0IHtNYXBTdGF0ZUFjdGlvbnMsIFJlY2VpdmVNYXBDb25maWdQYXlsb2FkLCBBY3Rpb25UeXBlc30gZnJvbSAnQGtlcGxlci5nbC9hY3Rpb25zJztcbmltcG9ydCB7TWFwU3RhdGUsIEJvdW5kcywgVmlld3BvcnR9IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtNYXBTcGxpdE1vZGUsIE1hcFZpZXdNb2RlLCBERUZBVUxUX0dMT0JFX0NPTkZJRywgR0xPQkVfTUlOX1pPT00sIEdMT0JFX01BWF9aT09NLCBHTE9CRV9NQVhfTEFUSVRVREV9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcblxuLyoqXG4gKiBVcGRhdGVycyBmb3IgYG1hcFN0YXRlYCByZWR1Y2VyLiBDYW4gYmUgdXNlZCBpbiB5b3VyIHJvb3QgcmVkdWNlciB0byBkaXJlY3RseSBtb2RpZnkga2VwbGVyLmdsJ3Mgc3RhdGUuXG4gKiBSZWFkIG1vcmUgYWJvdXQgW1VzaW5nIHVwZGF0ZXJzXSguLi9hZHZhbmNlZC11c2FnZS91c2luZy11cGRhdGVycy5tZClcbiAqIEBwdWJsaWNcbiAqIEBleGFtcGxlXG4gKlxuICogaW1wb3J0IGtlcGxlckdsUmVkdWNlciwge21hcFN0YXRlVXBkYXRlcnN9IGZyb20gJ0BrZXBsZXIuZ2wvcmVkdWNlcnMnO1xuICogLy8gUm9vdCBSZWR1Y2VyXG4gKiBjb25zdCByZWR1Y2VycyA9IGNvbWJpbmVSZWR1Y2Vycyh7XG4gKiAga2VwbGVyR2w6IGtlcGxlckdsUmVkdWNlcixcbiAqICBhcHA6IGFwcFJlZHVjZXJcbiAqIH0pO1xuICpcbiAqIGNvbnN0IGNvbXBvc2VkUmVkdWNlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiB7XG4gKiAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICogICAgLy8gY2xpY2sgYnV0dG9uIHRvIGNsb3NlIHNpZGUgcGFuZWxcbiAqICAgIGNhc2UgJ0NMSUNLX0JVVFRPTic6XG4gKiAgICAgIHJldHVybiB7XG4gKiAgICAgICAgLi4uc3RhdGUsXG4gKiAgICAgICAga2VwbGVyR2w6IHtcbiAqICAgICAgICAgIC4uLnN0YXRlLmtlcGxlckdsLFxuICogICAgICAgICAgZm9vOiB7XG4gKiAgICAgICAgICAgICAuLi5zdGF0ZS5rZXBsZXJHbC5mb28sXG4gKiAgICAgICAgICAgICBtYXBTdGF0ZTogbWFwU3RhdGVVcGRhdGVycy5maXRCb3VuZHNVcGRhdGVyKFxuICogICAgICAgICAgICAgICBtYXBTdGF0ZSwge3BheWxvYWQ6IFsxMjcuMzQsIDMxLjA5LCAxMjcuNTYsIDMxLjU5XV19XG4gKiAgICAgICAgICAgICApXG4gKiAgICAgICAgICB9XG4gKiAgICAgICAgfVxuICogICAgICB9O1xuICogIH1cbiAqICByZXR1cm4gcmVkdWNlcnMoc3RhdGUsIGFjdGlvbik7XG4gKiB9O1xuICpcbiAqIGV4cG9ydCBkZWZhdWx0IGNvbXBvc2VkUmVkdWNlcjtcbiAqL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbi8vIEB0cy1pZ25vcmVcbmNvbnN0IG1hcFN0YXRlVXBkYXRlcnMgPSBudWxsO1xuLyogZXNsaW50LWVuYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbi8qKlxuICogRGVmYXVsdCBpbml0aWFsIGBtYXBTdGF0ZWBcbiAqIEBtZW1iZXJvZiBtYXBTdGF0ZVVwZGF0ZXJzXG4gKiBAY29uc3RhbnRcbiAqIEBwcm9wZXJ0eSBwaXRjaCBEZWZhdWx0OiBgMGBcbiAqIEBwcm9wZXJ0eSBiZWFyaW5nIERlZmF1bHQ6IGAwYFxuICogQHByb3BlcnR5IGxhdGl0dWRlIERlZmF1bHQ6IGAzNy43NTA0M2BcbiAqIEBwcm9wZXJ0eSBsb25naXR1ZGUgRGVmYXVsdDogYC0xMjIuMzQ2NzlgXG4gKiBAcHJvcGVydHkgem9vbSBEZWZhdWx0OiBgOWBcbiAqIEBwcm9wZXJ0eSBkcmFnUm90YXRlIERlZmF1bHQ6IGBmYWxzZWBcbiAqIEBwcm9wZXJ0eSB3aWR0aCBEZWZhdWx0OiBgODAwYFxuICogQHByb3BlcnR5IGhlaWdodCBEZWZhdWx0OiBgODAwYFxuICogQHByb3BlcnR5IG1pblpvb206IGB1bmRlZmluZWRgLFxuICogQHByb3BlcnR5IG1heFpvb206IGB1bmRlZmluZWRgLFxuICogQHByb3BlcnR5IG1heFBpdGNoOiBgdW5kZWZpbmVkYCAoZGVmYXVsdHMgdG8gYXBwbGljYXRpb24gY29uZmlnIHZhbHVlLCBkZWNrLmdsIGRlZmF1bHQgaXMgNjApXG4gKiBAcHJvcGVydHkgbWF4Qm91bmRzOiBgdW5kZWZpbmVkYCxcbiAqIEBwcm9wZXJ0eSBpc1NwbGl0OiBgZmFsc2VgLFxuICogQHByb3BlcnR5IGlzVmlld3BvcnRTeW5jZWQ6IGB0cnVlYCxcbiAqIEBwcm9wZXJ0eSBpc1pvb21Mb2NrZWQ6IGBmYWxzZWAsXG4gKiBAcHJvcGVydHkgc3BsaXRNYXBWaWV3cG9ydHM6IGBbXWBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IElOSVRJQUxfTUFQX1NUQVRFOiBNYXBTdGF0ZSA9IHtcbiAgcGl0Y2g6IDAsXG4gIGJlYXJpbmc6IDAsXG4gIGxhdGl0dWRlOiAzNy43NTA0MyxcbiAgbG9uZ2l0dWRlOiAtMTIyLjM0Njc5LFxuICB6b29tOiA5LFxuICBkcmFnUm90YXRlOiBmYWxzZSxcbiAgd2lkdGg6IDgwMCxcbiAgaGVpZ2h0OiA4MDAsXG4gIG1pblpvb206IHVuZGVmaW5lZCxcbiAgbWF4Wm9vbTogdW5kZWZpbmVkLFxuICBtYXhQaXRjaDogdW5kZWZpbmVkLFxuICBtYXhCb3VuZHM6IHVuZGVmaW5lZCxcbiAgaXNTcGxpdDogZmFsc2UsXG4gIGlzVmlld3BvcnRTeW5jZWQ6IHRydWUsXG4gIGlzWm9vbUxvY2tlZDogZmFsc2UsXG4gIHNwbGl0TWFwVmlld3BvcnRzOiBbXSxcbiAgbWFwVmlld01vZGU6IE1hcFZpZXdNb2RlLk1PREVfMkQsXG4gIGdsb2JlOiB7XG4gICAgZW5hYmxlZDogZmFsc2UsXG4gICAgY29uZmlnOiBERUZBVUxUX0dMT0JFX0NPTkZJR1xuICB9LFxuICBtYXBTcGxpdE1vZGU6IE1hcFNwbGl0TW9kZS5TSU5HTEVfTUFQLFxuICBzd2lwZUNvbXBhcmVQZXJjZW50YWdlOiA1MFxufTtcblxuLyogVXBkYXRlcnMgKi9cbi8qKlxuICogVXBkYXRlIG1hcCB2aWV3cG9ydFxuICogQG1lbWJlcm9mIG1hcFN0YXRlVXBkYXRlcnNcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHVwZGF0ZU1hcFVwZGF0ZXIgPSAoXG4gIHN0YXRlOiBNYXBTdGF0ZSxcbiAgYWN0aW9uOiBNYXBTdGF0ZUFjdGlvbnMuVXBkYXRlTWFwVXBkYXRlckFjdGlvblxuKTogTWFwU3RhdGUgPT4ge1xuICBjb25zdCB7dmlld3BvcnQ6IGlucHV0Vmlld3BvcnQsIG1hcEluZGV4ID0gMH0gPSBhY3Rpb24ucGF5bG9hZDtcbiAgY29uc3Qgdmlld3BvcnQgPSB2YWxpZGF0ZVZpZXdQb3J0KGlucHV0Vmlld3BvcnQpO1xuXG4gIGlmIChzdGF0ZS5pc1ZpZXdwb3J0U3luY2VkKSB7XG4gICAgLy8gVGhlIGB1cGRhdGVWaWV3cG9ydGAgZnVuY3Rpb24gaXMgdHlwZWQgYXMgKFZpZXdwb3J0LCBWaWV3cG9ydCkgLT4gVmlld3BvcnQgYnV0IGhlcmUgdGhlXG4gICAgLy8gZXhwZWN0ZWQgdHlwaW5nIGlzIChNYXBTdGF0ZSwgVmlld3BvcnQpIC0+IE1hcFN0YXRlLlxuICAgIC8vIHRoaXMgY291bGQgYmUgYSBwb3RlbnRpYWwgYnVnIGFzIHdlIHRyZWF0IFZpZXdwb3J0IGFuZCBNYXBTdGF0ZSBhcyBlcXVhbCBzZWVtaW5nbHlcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFR5cGUgJ1ZpZXdwb3J0JyBpcyBtaXNzaW5nIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmcm9tIHR5cGUgJ01hcFN0YXRlJzogaXNTcGxpdCwgaXNWaWV3cG9ydFN5bmNlZCwgaXNab29tTG9ja2VkLCBzcGxpdE1hcFZpZXdwb3J0c1xuICAgIHJldHVybiB1cGRhdGVWaWV3cG9ydChzdGF0ZSwgdmlld3BvcnQpO1xuICB9XG5cbiAgbGV0IG90aGVyVmlld3BvcnRNYXBJbmRleCA9IC0xO1xuICBjb25zdCBzcGxpdE1hcFZpZXdwb3J0cyA9IHN0YXRlLnNwbGl0TWFwVmlld3BvcnRzLm1hcCgoY3VycmVudFZpZXdwb3J0LCBpKSA9PiB7XG4gICAgaWYgKGkgPT09IG1hcEluZGV4KSB7XG4gICAgICAvLyB1cGRhdGUgdGhlIG1hdGNoaW5nIHZpZXdwb3J0IHdpdGggdGhlIG5ld1ZpZXdwb3J0IGluZm8gaW4gdGhlIGFjdGlvbiBwYXlsb2FkXG4gICAgICByZXR1cm4gdXBkYXRlVmlld3BvcnQoY3VycmVudFZpZXdwb3J0LCB2aWV3cG9ydCk7XG4gICAgfVxuXG4gICAgb3RoZXJWaWV3cG9ydE1hcEluZGV4ID0gaTtcbiAgICAvLyBtYWtlIG5vIGNoYW5nZXMgdG8gdGhlIG90aGVyIHZpZXdwb3J0ICh5ZXQpXG4gICAgcmV0dXJuIGN1cnJlbnRWaWV3cG9ydDtcbiAgfSk7XG5cbiAgLy8gbWFrZSBjb25kaXRpb25hbCB1cGRhdGVzIHRvIHRoZSBvdGhlciB2aWV3cG9ydCBub3QgbWF0Y2hpbmcgdGhpcyBwYXlsb2FkJ3MgYG1hcEluZGV4YFxuICBpZiAoTnVtYmVyLmlzRmluaXRlKG90aGVyVmlld3BvcnRNYXBJbmRleCkgJiYgb3RoZXJWaWV3cG9ydE1hcEluZGV4ID4gLTEpIHtcbiAgICAvLyB3aWR0aCBhbmQgaGVpZ2h0IGFyZSBhIHNwZWNpYWwgY2FzZSBhbmQgYXJlIGFsd2F5cyB1cGRhdGVkXG4gICAgc3BsaXRNYXBWaWV3cG9ydHNbb3RoZXJWaWV3cG9ydE1hcEluZGV4XSA9IHtcbiAgICAgIC4uLnNwbGl0TWFwVmlld3BvcnRzW290aGVyVmlld3BvcnRNYXBJbmRleF0sXG4gICAgICB3aWR0aDogc3BsaXRNYXBWaWV3cG9ydHNbbWFwSW5kZXhdLndpZHRoLFxuICAgICAgaGVpZ2h0OiBzcGxpdE1hcFZpZXdwb3J0c1ttYXBJbmRleF0uaGVpZ2h0XG4gICAgfTtcblxuICAgIGlmIChzdGF0ZS5pc1pvb21Mb2NrZWQpIHtcbiAgICAgIC8vIHVwZGF0ZSB0aGUgb3RoZXIgdmlld3BvcnQgd2l0aCB0aGUgbmV3IHpvb20gZnJvbSB0aGUgc3BsaXQgdmlld3BvcnQgdGhhdCB3YXMgdXBkYXRlZCB3aXRoIHRoaXMgcGF5bG9hZCdzIGBtYXBJbmRleGBcbiAgICAgIHNwbGl0TWFwVmlld3BvcnRzW290aGVyVmlld3BvcnRNYXBJbmRleF0gPSB7XG4gICAgICAgIC4uLnNwbGl0TWFwVmlld3BvcnRzW290aGVyVmlld3BvcnRNYXBJbmRleF0sXG4gICAgICAgIHpvb206IHNwbGl0TWFwVmlld3BvcnRzW21hcEluZGV4XS56b29tXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLy8gdXBkYXRlIHRoZSB0b3AtbGV2ZWwgbWFwU3RhdGUgdmlld3BvcnQgd2l0aCB0aGUgbW9zdCByZWNlbnRseSBpbnRlcmFjdGVkLXdpdGggc3BsaXQgdmlld3BvcnRcbiAgICAvLyBXSFk/IHRoaXMgYXZvaWRzIHpvb20gYW5kIGJvdW5kcyBcImp1bXBpbmdcIiBkdWUgdG8gYSBcInN0YWxlXCIgdG9wLWxldmVsIG1hcFN0YXRlIHZpZXdwb3J0IHdoZW46XG4gICAgLy8gIDEuIHRvZ2dsaW5nIG9mZiB0aGUgdW5zeW5jZWQgdmlld3BvcnRzIG1vZGUgdG8gc3dpdGNoIHRvIHRoZSBzeW5jZWQgdmlld3BvcnRzIG1vZGVcbiAgICAvLyAgMi4gdG9nZ2xpbmcgb24gdGhlIHpvb20gbG9jayBkdXJpbmcgYW4gdW5zeW5jZWQgdmlld3BvcnRzIG1vZGVcbiAgICAuLi5zdGF0ZSxcbiAgICAuLi5zcGxpdE1hcFZpZXdwb3J0c1ttYXBJbmRleF0sXG4gICAgLy8gdXBkYXRlIHRoZSBtYXBTdGF0ZSB3aXRoIHRoZSBuZXcgYXJyYXkgb2Ygc3BsaXQgdmlld3BvcnRzXG4gICAgc3BsaXRNYXBWaWV3cG9ydHNcbiAgfTtcbn07XG5cbi8qKlxuICogRml0IG1hcCB2aWV3cG9ydCB0byBib3VuZHNcbiAqIEBtZW1iZXJvZiBtYXBTdGF0ZVVwZGF0ZXJzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBmaXRCb3VuZHNVcGRhdGVyID0gKFxuICBzdGF0ZTogTWFwU3RhdGUsXG4gIGFjdGlvbjogTWFwU3RhdGVBY3Rpb25zLkZpdEJvdW5kc1VwZGF0ZXJBY3Rpb25cbik6IE1hcFN0YXRlID0+IHtcbiAgY29uc3QgY2VudGVyQW5kWm9vbSA9IGdldENlbnRlckFuZFpvb21Gcm9tQm91bmRzKGFjdGlvbi5wYXlsb2FkLCB7XG4gICAgd2lkdGg6IHN0YXRlLndpZHRoLFxuICAgIGhlaWdodDogc3RhdGUuaGVpZ2h0XG4gIH0pO1xuICBpZiAoIWNlbnRlckFuZFpvb20pIHtcbiAgICAvLyBib3VuZHMgaXMgaW52YWxpZFxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxhdGl0dWRlOiBjZW50ZXJBbmRab29tLmNlbnRlclsxXSxcbiAgICBsb25naXR1ZGU6IGNlbnRlckFuZFpvb20uY2VudGVyWzBdLFxuICAgIC8vIEZvciBtYXJnaW5hbCBvciBpbnZhbGlkIGJvdW5kcywgem9vbSBtYXkgYmUgTmFOLiBNYWtlIHN1cmUgdG8gcHJvdmlkZSBhIHZhbGlkIHZhbHVlIGluIG9yZGVyXG4gICAgLy8gdG8gYXZvaWQgY29ycnVwdCBzdGF0ZSBhbmQgcG90ZW50aWFsIGNyYXNoZXMgYXMgem9vbSBpcyBleHBlY3RlZCB0byBiZSBhIG51bWJlclxuICAgIC4uLihOdW1iZXIuaXNGaW5pdGUoY2VudGVyQW5kWm9vbS56b29tKSA/IHt6b29tOiBjZW50ZXJBbmRab29tLnpvb219IDoge30pXG4gIH07XG5cbiAgLy8gaWYgZml0dGluZyB0byBib3VuZHMgd2hpbGUgc3BsaXQgYW5kIHVuc3luY2VkXG4gIC8vIGNvcHkgdGhlIG5ldyBsYXRpdHVkZSwgbG9uZ2l0dWRlLCBhbmQgem9vbSB2YWx1ZXMgdG8gZWFjaCBzcGxpdCB2aWV3cG9ydFxuICBpZiAobmV3U3RhdGUuc3BsaXRNYXBWaWV3cG9ydHMubGVuZ3RoKSB7XG4gICAgbmV3U3RhdGUuc3BsaXRNYXBWaWV3cG9ydHMgPSBuZXdTdGF0ZS5zcGxpdE1hcFZpZXdwb3J0cy5tYXAoY3VycmVudFZpZXdwb3J0ID0+ICh7XG4gICAgICAuLi5jdXJyZW50Vmlld3BvcnQsXG4gICAgICBsYXRpdHVkZTogbmV3U3RhdGUubGF0aXR1ZGUsXG4gICAgICBsb25naXR1ZGU6IG5ld1N0YXRlLmxvbmdpdHVkZSxcbiAgICAgIHpvb206IG5ld1N0YXRlLnpvb21cbiAgICB9KSk7XG4gIH1cblxuICByZXR1cm4gbmV3U3RhdGU7XG59O1xuXG4vKipcbiAqIFRvZ2dsZSBiZXR3ZWVuIDNkIGFuZCAyZCBtYXAuXG4gKiBAbWVtYmVyb2YgbWFwU3RhdGVVcGRhdGVyc1xuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlUGVyc3BlY3RpdmVVcGRhdGVyID0gKHN0YXRlOiBNYXBTdGF0ZSk6IE1hcFN0YXRlID0+IHtcbiAgLy8gT25seSBkcm9wIG1pbi9tYXhab29tIHdoZW4gd2UncmUgYWN0dWFsbHkgbGVhdmluZyBnbG9iZSBtb2RlLCB3aGVyZSB0aG9zZVxuICAvLyBib3VuZHMgYXJlIHNldCB0byBnbG9iZS1vbmx5IHZhbHVlcy4gSWYgZ2xvYmUgd2FzIG5ldmVyIGVuYWJsZWQgdGhlc2UgYXJlXG4gIC8vIHRoZSBhcHAncyBvd24gY3VzdG9tIGJvdW5kcyBhbmQgbXVzdCBiZSBwcmVzZXJ2ZWQuXG4gIGNvbnN0IHdhc0dsb2JlRW5hYmxlZCA9IEJvb2xlYW4oc3RhdGUuZ2xvYmU/LmVuYWJsZWQpO1xuXG4gIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIC4uLntcbiAgICAgIHBpdGNoOiBzdGF0ZS5kcmFnUm90YXRlID8gMCA6IDUwLFxuICAgICAgYmVhcmluZzogc3RhdGUuZHJhZ1JvdGF0ZSA/IDAgOiAyNFxuICAgIH0sXG4gICAgZHJhZ1JvdGF0ZTogIXN0YXRlLmRyYWdSb3RhdGUsXG4gICAgbWFwVmlld01vZGU6IHN0YXRlLmRyYWdSb3RhdGUgPyBNYXBWaWV3TW9kZS5NT0RFXzJEIDogTWFwVmlld01vZGUuTU9ERV8zRCxcbiAgICBnbG9iZTogey4uLnN0YXRlLmdsb2JlISwgZW5hYmxlZDogZmFsc2V9LFxuICAgIC8vIExlYXZpbmcgZ2xvYmUgbW9kZTogZHJvcCBnbG9iZS1vbmx5IHpvb20gYm91bmRzIHNvIHRoZSBmbGF0IG1hcCAoYW5kXG4gICAgLy8gY29uc3VtZXJzIG9mIG1hcFN0YXRlIHN1Y2ggYXMgdmlkZW8gZXhwb3J0KSBhcmVuJ3QgbGVmdCBjbGFtcGVkLiBXaGVuXG4gICAgLy8gZ2xvYmUgd2FzIG5ldmVyIG9uLCBrZWVwIHdoYXRldmVyIG1pbi9tYXhab29tIHRoZSBhcHAgY29uZmlndXJlZC5cbiAgICAuLi4od2FzR2xvYmVFbmFibGVkID8ge21pblpvb206IHVuZGVmaW5lZCwgbWF4Wm9vbTogdW5kZWZpbmVkfSA6IHt9KVxuICB9O1xuXG4gIC8vIGlmIHRvZ2dsaW5nIDNkIGFuZCAyZCB3aGlsZSBzcGxpdCBhbmQgdW5zeW5jZWRcbiAgLy8gY29weSB0aGUgbmV3IHBpdGNoLCBiZWFyaW5nLCBhbmQgZHJhZ1JvdGF0ZSB2YWx1ZXMgdG8gZWFjaCBzcGxpdCB2aWV3cG9ydFxuICBpZiAobmV3U3RhdGUuc3BsaXRNYXBWaWV3cG9ydHMubGVuZ3RoKSB7XG4gICAgbmV3U3RhdGUuc3BsaXRNYXBWaWV3cG9ydHMgPSBuZXdTdGF0ZS5zcGxpdE1hcFZpZXdwb3J0cy5tYXAoY3VycmVudFZpZXdwb3J0ID0+ICh7XG4gICAgICAuLi5jdXJyZW50Vmlld3BvcnQsXG4gICAgICBwaXRjaDogbmV3U3RhdGUucGl0Y2gsXG4gICAgICBiZWFyaW5nOiBuZXdTdGF0ZS5iZWFyaW5nLFxuICAgICAgZHJhZ1JvdGF0ZTogbmV3U3RhdGUuZHJhZ1JvdGF0ZVxuICAgIH0pKTtcbiAgfVxuXG4gIHJldHVybiBuZXdTdGF0ZTtcbn07XG5cbi8qKlxuICogU2V0IG1hcCB2aWV3IG1vZGUgKDJELCAzRCwgR2xvYmUpXG4gKiBAbWVtYmVyb2YgbWFwU3RhdGVVcGRhdGVyc1xuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3Qgc2V0TWFwVmlld01vZGVVcGRhdGVyID0gKFxuICBzdGF0ZTogTWFwU3RhdGUsXG4gIGFjdGlvbjogTWFwU3RhdGVBY3Rpb25zLlNldE1hcFZpZXdNb2RlVXBkYXRlckFjdGlvblxuKTogTWFwU3RhdGUgPT4ge1xuICBjb25zdCB7bWFwVmlld01vZGV9ID0gYWN0aW9uLnBheWxvYWQ7XG4gIGxldCBuZXh0U3RhdGU6IE1hcFN0YXRlO1xuXG4gIC8vIE9ubHkgY2xlYXIgbWluL21heFpvb20gd2hlbiBsZWF2aW5nIGdsb2JlIG1vZGUgKHdoZXJlIHRoZXkgaG9sZCBnbG9iZS1vbmx5XG4gIC8vIGJvdW5kcykuIE90aGVyd2lzZSBwcmVzZXJ2ZSB0aGUgYXBwJ3MgY3VzdG9tIGJvdW5kcy5cbiAgY29uc3Qgd2FzR2xvYmVFbmFibGVkID0gQm9vbGVhbihzdGF0ZS5nbG9iZT8uZW5hYmxlZCk7XG5cbiAgc3dpdGNoIChtYXBWaWV3TW9kZSkge1xuICAgIGNhc2UgTWFwVmlld01vZGUuTU9ERV8yRDpcbiAgICAgIG5leHRTdGF0ZSA9IHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIGdsb2JlOiB7Li4uc3RhdGUuZ2xvYmUhLCBlbmFibGVkOiBmYWxzZX0sXG4gICAgICAgIHBpdGNoOiAwLFxuICAgICAgICBiZWFyaW5nOiAwLFxuICAgICAgICBkcmFnUm90YXRlOiBmYWxzZSxcbiAgICAgICAgLy8gQ2xlYXIgdGhlIGdsb2JlLW9ubHkgem9vbSBib3VuZHMgc28gdGhlIGZsYXQgbWFwIChhbmQgYW55dGhpbmcgdGhhdFxuICAgICAgICAvLyByZWFkcyBtYXBTdGF0ZSwgZS5nLiB2aWRlbyBleHBvcnQpIGlzIG5vdCBsZWZ0IHdpdGggZ2xvYmUnc1xuICAgICAgICAvLyBtaW4vbWF4Wm9vbSBhZnRlciBsZWF2aW5nIGdsb2JlIG1vZGUuIE9ubHkgd2hlbiBnbG9iZSB3YXMgYWN0dWFsbHkgb24uXG4gICAgICAgIC4uLih3YXNHbG9iZUVuYWJsZWQgPyB7bWluWm9vbTogdW5kZWZpbmVkLCBtYXhab29tOiB1bmRlZmluZWR9IDoge30pLFxuICAgICAgICBtYXBWaWV3TW9kZVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgTWFwVmlld01vZGUuTU9ERV8zRDpcbiAgICAgIG5leHRTdGF0ZSA9IHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIGdsb2JlOiB7Li4uc3RhdGUuZ2xvYmUhLCBlbmFibGVkOiBmYWxzZX0sXG4gICAgICAgIHBpdGNoOiA1MCxcbiAgICAgICAgYmVhcmluZzogMjQsXG4gICAgICAgIGRyYWdSb3RhdGU6IHRydWUsXG4gICAgICAgIC4uLih3YXNHbG9iZUVuYWJsZWQgPyB7bWluWm9vbTogdW5kZWZpbmVkLCBtYXhab29tOiB1bmRlZmluZWR9IDoge30pLFxuICAgICAgICBtYXBWaWV3TW9kZVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgTWFwVmlld01vZGUuTU9ERV9HTE9CRTpcbiAgICAgIG5leHRTdGF0ZSA9IHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIGdsb2JlOiB7Li4uc3RhdGUuZ2xvYmUhLCBlbmFibGVkOiB0cnVlfSxcbiAgICAgICAgZHJhZ1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgcGl0Y2g6IDAsXG4gICAgICAgIGJlYXJpbmc6IDAsXG4gICAgICAgIC8vIEFsbG93IHpvb21pbmcgb3V0IGZ1cnRoZXIgdGhhbiB0aGUgZGVmYXVsdCBzbyB0aGUgd2hvbGUgZ2xvYmUgY2FuIGJlXG4gICAgICAgIC8vIHB1bGxlZCBiYWNrIG9uIHNjcmVlbi4gQ2FwIHRoZSBtYXggem9vbSBzbyB0aGUgYmFzZW1hcCB0aWxlcyBzdGF5XG4gICAgICAgIC8vIGNvaGVyZW50ICh0aGV5IGJyZWFrIGRvd24gYXQgaGlnaCBnbG9iZSB6b29tIGluIGRlY2suZ2wgOS54KS5cbiAgICAgICAgbWluWm9vbTogR0xPQkVfTUlOX1pPT00sXG4gICAgICAgIG1heFpvb206IEdMT0JFX01BWF9aT09NLFxuICAgICAgICB6b29tOiBNYXRoLm1pbihNYXRoLm1heChzdGF0ZS56b29tLCBHTE9CRV9NSU5fWk9PTSksIEdMT0JFX01BWF9aT09NKSxcbiAgICAgICAgbWFwVmlld01vZGVcbiAgICAgIH07XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgaWYgKG5leHRTdGF0ZS5zcGxpdE1hcFZpZXdwb3J0cy5sZW5ndGgpIHtcbiAgICBuZXh0U3RhdGUuc3BsaXRNYXBWaWV3cG9ydHMgPSBuZXh0U3RhdGUuc3BsaXRNYXBWaWV3cG9ydHMubWFwKGN1cnJlbnRWaWV3cG9ydCA9PiAoe1xuICAgICAgLi4uY3VycmVudFZpZXdwb3J0LFxuICAgICAgcGl0Y2g6IG5leHRTdGF0ZS5waXRjaCxcbiAgICAgIGJlYXJpbmc6IG5leHRTdGF0ZS5iZWFyaW5nLFxuICAgICAgZHJhZ1JvdGF0ZTogbmV4dFN0YXRlLmRyYWdSb3RhdGVcbiAgICB9KSk7XG4gIH1cblxuICByZXR1cm4gbmV4dFN0YXRlO1xufTtcblxuLyoqXG4gKiBVcGRhdGUgZ2xvYmUgY29uZmlnXG4gKiBAbWVtYmVyb2YgbWFwU3RhdGVVcGRhdGVyc1xuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgZ2xvYmVDb25maWdDaGFuZ2VVcGRhdGVyID0gKFxuICBzdGF0ZTogTWFwU3RhdGUsXG4gIGFjdGlvbjogTWFwU3RhdGVBY3Rpb25zLkdsb2JlQ29uZmlnQ2hhbmdlVXBkYXRlckFjdGlvblxuKTogTWFwU3RhdGUgPT4ge1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGdsb2JlOiB7XG4gICAgICAuLi5zdGF0ZS5nbG9iZSEsXG4gICAgICBjb25maWc6IHtcbiAgICAgICAgLi4uc3RhdGUuZ2xvYmUhLmNvbmZpZyxcbiAgICAgICAgLi4uYWN0aW9uLnBheWxvYWRcbiAgICAgIH1cbiAgICB9XG4gIH07XG59O1xuXG4vKipcbiAqIHJlc2V0IG1hcFN0YXRlIHRvIGluaXRpYWwgU3RhdGVcbiAqIEBtZW1iZXJvZiBtYXBTdGF0ZVVwZGF0ZXJzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCByZXNldE1hcENvbmZpZ1VwZGF0ZXIgPSAoc3RhdGU6IE1hcFN0YXRlKTogTWFwU3RhdGUgPT4gKHtcbiAgLi4uSU5JVElBTF9NQVBfU1RBVEUsXG4gIC4uLnN0YXRlLmluaXRpYWxTdGF0ZSxcbiAgaW5pdGlhbFN0YXRlOiBzdGF0ZS5pbml0aWFsU3RhdGVcbn0pO1xuXG4vLyBjb25zaWRlciBjYXNlIHdoZXJlIHlvdSBoYXZlIGEgc3BsaXQgbWFwIGFuZCB1c2VyIHdhbnRzIHRvIHJlc2V0XG4vKipcbiAqIFVwZGF0ZSBgbWFwU3RhdGVgIHRvIHByb3BhZ2F0ZSBhIG5ldyBjb25maWdcbiAqIEBtZW1iZXJvZiBtYXBTdGF0ZVVwZGF0ZXJzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCByZWNlaXZlTWFwQ29uZmlnVXBkYXRlciA9IChcbiAgc3RhdGU6IE1hcFN0YXRlLFxuICB7XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgIHBheWxvYWQ6IHtjb25maWcgPSB7fSwgb3B0aW9ucyA9IHt9LCBib3VuZHMgPSBudWxsfVxuICB9OiB7XG4gICAgdHlwZT86IHR5cGVvZiBBY3Rpb25UeXBlcy5SRUNFSVZFX01BUF9DT05GSUc7XG4gICAgcGF5bG9hZDogUmVjZWl2ZU1hcENvbmZpZ1BheWxvYWQ7XG4gIH1cbik6IE1hcFN0YXRlID0+IHtcbiAgLyoqXG4gICAqIEB0eXBlIHtQYXJ0aWFsPE1hcFN0YXRlPn1cbiAgICovXG4gIGNvbnN0IG1hcFN0YXRlID0gKGNvbmZpZyB8fCB7fSkubWFwU3RhdGUgfHwge307XG4gIC8vIG1lcmdlZCByZWNlaXZlZCBtYXBTdGF0ZSB3aXRoIHByZXZpb3VzIHN0YXRlXG4gIC8vIHN0YXRlIGFsc28gbWF5IGluY2x1ZGUgcHJvcGVydGllcyB0aGF0IGFyZSBuZXcgdG8gYW4gZXhpc3RpbmcsIHNhdmVkIHByb2plY3QncyBtYXBTdGF0ZVxuXG4gIGxldCBtZXJnZWRTdGF0ZSA9IGRlZXBtZXJnZTxNYXBTdGF0ZT4oc3RhdGUsIG1hcFN0YXRlLCB7XG4gICAgLy8gbm90ZTogZGVlcG1lcmdlIGJ5IGRlZmF1bHQgd2lsbCBtZXJnZSBhcnJheXMgYnkgY29uY2F0ZW5hdGluZyB0aGVtXG4gICAgLy8gYnV0IHdlIG5lZWQgdG8gb3ZlcndyaXRlIGRlc3RpbmF0aW9uIGFycmF5cyB3aXRoIHNvdXJjZSBhcnJheXMsIGlmIHByZXNlbnRcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vVGVoU2hyaWtlL2RlZXBtZXJnZSNhcnJheW1lcmdlLWV4YW1wbGUtb3ZlcndyaXRlLXRhcmdldC1hcnJheVxuICAgIGFycmF5TWVyZ2U6IChfZGVzdGluYXRpb25BcnJheSwgc291cmNlQXJyYXkpID0+IHNvdXJjZUFycmF5XG4gIH0pO1xuXG4gIC8vIGlmIGNlbnRlciBtYXBcbiAgLy8gY2VudGVyIG1hcCB3aWxsIG92ZXJyaWRlIG1hcFN0YXRlIGNvbmZpZ1xuICBpZiAob3B0aW9ucy5jZW50ZXJNYXAgJiYgYm91bmRzKSB7XG4gICAgbWVyZ2VkU3RhdGUgPSBmaXRCb3VuZHNVcGRhdGVyKG1lcmdlZFN0YXRlLCB7XG4gICAgICBwYXlsb2FkOiBib3VuZHNcbiAgICB9KTtcbiAgfVxuXG4gIC8vIG1ha2Ugc3VyZSB3ZSB2YWxpZGF0ZSBtYXAgc3RhdGUgYmVmb3JlIHdlIG1lcmdlXG4gIG1lcmdlZFN0YXRlID0gdmFsaWRhdGVWaWV3UG9ydChtZXJnZWRTdGF0ZSk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5tZXJnZWRTdGF0ZSxcbiAgICAvLyB1cGRhdGUgd2lkdGggaWYgYGlzU3BsaXRgIGhhcyBjaGFuZ2VkXG4gICAgLi4uZ2V0TWFwRGltRm9yU3BsaXRNYXAobWVyZ2VkU3RhdGUuaXNTcGxpdCwgc3RhdGUpXG4gIH07XG59O1xuXG4vKipcbiAqIFRvZ2dsZSBiZXR3ZWVuIG9uZSBvciBzcGxpdCBtYXBzXG4gKiBAbWVtYmVyb2YgbWFwU3RhdGVVcGRhdGVyc1xuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlU3BsaXRNYXBVcGRhdGVyID0gKHN0YXRlOiBNYXBTdGF0ZSk6IE1hcFN0YXRlID0+ICh7XG4gIC4uLnN0YXRlLFxuICAuLi5nZXRNYXBEaW1Gb3JTcGxpdE1hcCghc3RhdGUuaXNTcGxpdCwgc3RhdGUpLFxuICBpc1NwbGl0OiAhc3RhdGUuaXNTcGxpdCxcbiAgbWFwU3BsaXRNb2RlOiAhc3RhdGUuaXNTcGxpdCA/IE1hcFNwbGl0TW9kZS5EVUFMX01BUCA6IE1hcFNwbGl0TW9kZS5TSU5HTEVfTUFQLFxuICAuLi4oIXN0YXRlLmlzU3BsaXQgPT09IGZhbHNlXG4gICAgPyB7XG4gICAgICAgIC8vIGlmIHRvZ2dsaW5nIHRvIG5vIGxvbmdlciBzcGxpdCAoc2luZ2xlIG1vZGUpIHRoZW4gcmVzZXQgYSBmZXcgcHJvcGVydGllc1xuICAgICAgICBpc1ZpZXdwb3J0U3luY2VkOiB0cnVlLFxuICAgICAgICBpc1pvb21Mb2NrZWQ6IGZhbHNlLFxuICAgICAgICBzcGxpdE1hcFZpZXdwb3J0czogW11cbiAgICAgIH1cbiAgICA6IHt9KVxufSk7XG5cbi8qKlxuICogU2V0IHRoZSBtYXAgc3BsaXQgbW9kZSAoc2luZ2xlLCBkdWFsLCBvciBzd2lwZSlcbiAqIEBtZW1iZXJvZiBtYXBTdGF0ZVVwZGF0ZXJzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBzZXRNYXBTcGxpdE1vZGVVcGRhdGVyID0gKFxuICBzdGF0ZTogTWFwU3RhdGUsXG4gIGFjdGlvbjogTWFwU3RhdGVBY3Rpb25zLlNldE1hcFNwbGl0TW9kZVVwZGF0ZXJBY3Rpb25cbik6IE1hcFN0YXRlID0+IHtcbiAgY29uc3Qge21hcFNwbGl0TW9kZX0gPSBhY3Rpb24ucGF5bG9hZDtcbiAgY29uc3QgcHJldk1vZGUgPSBzdGF0ZS5tYXBTcGxpdE1vZGU7XG5cbiAgaWYgKG1hcFNwbGl0TW9kZSA9PT0gcHJldk1vZGUpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICBzd2l0Y2ggKG1hcFNwbGl0TW9kZSkge1xuICAgIGNhc2UgTWFwU3BsaXRNb2RlLlNJTkdMRV9NQVA6XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgbWFwU3BsaXRNb2RlLFxuICAgICAgICBpc1NwbGl0OiBmYWxzZSxcbiAgICAgICAgLi4uKHByZXZNb2RlID09PSBNYXBTcGxpdE1vZGUuRFVBTF9NQVAgJiYge1xuICAgICAgICAgIHdpZHRoOiBzdGF0ZS53aWR0aCAqIDJcbiAgICAgICAgfSksXG4gICAgICAgIGlzVmlld3BvcnRTeW5jZWQ6IHRydWUsXG4gICAgICAgIGlzWm9vbUxvY2tlZDogZmFsc2UsXG4gICAgICAgIHNwbGl0TWFwVmlld3BvcnRzOiBbXVxuICAgICAgfTtcbiAgICBjYXNlIE1hcFNwbGl0TW9kZS5EVUFMX01BUDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICBtYXBTcGxpdE1vZGUsXG4gICAgICAgIGlzU3BsaXQ6IHRydWUsXG4gICAgICAgIC4uLihwcmV2TW9kZSA9PT0gTWFwU3BsaXRNb2RlLlNJTkdMRV9NQVAgJiYge1xuICAgICAgICAgIHdpZHRoOiBzdGF0ZS53aWR0aCAvIDJcbiAgICAgICAgfSksXG4gICAgICAgIC4uLihwcmV2TW9kZSA9PT0gTWFwU3BsaXRNb2RlLlNXSVBFX0NPTVBBUkUgJiYge1xuICAgICAgICAgIHdpZHRoOiBzdGF0ZS53aWR0aCAvIDJcbiAgICAgICAgfSlcbiAgICAgIH07XG4gICAgY2FzZSBNYXBTcGxpdE1vZGUuU1dJUEVfQ09NUEFSRTpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICBtYXBTcGxpdE1vZGUsXG4gICAgICAgIGlzU3BsaXQ6IHRydWUsXG4gICAgICAgIC4uLihwcmV2TW9kZSA9PT0gTWFwU3BsaXRNb2RlLkRVQUxfTUFQICYmIHtcbiAgICAgICAgICB3aWR0aDogc3RhdGUud2lkdGggKiAyXG4gICAgICAgIH0pLFxuICAgICAgICBpc1ZpZXdwb3J0U3luY2VkOiB0cnVlLFxuICAgICAgICBpc1pvb21Mb2NrZWQ6IGZhbHNlLFxuICAgICAgICBzcGxpdE1hcFZpZXdwb3J0czogW11cbiAgICAgIH07XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZXQgdGhlIHN3aXBlIGNvbXBhcmUgcGVyY2VudGFnZVxuICogQG1lbWJlcm9mIG1hcFN0YXRlVXBkYXRlcnNcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHNldFN3aXBlQ29tcGFyZVBlcmNlbnRhZ2VVcGRhdGVyID0gKFxuICBzdGF0ZTogTWFwU3RhdGUsXG4gIGFjdGlvbjogTWFwU3RhdGVBY3Rpb25zLlNldFN3aXBlQ29tcGFyZVBlcmNlbnRhZ2VVcGRhdGVyQWN0aW9uXG4pOiBNYXBTdGF0ZSA9PiB7XG4gIGNvbnN0IHtwZXJjZW50YWdlfSA9IGFjdGlvbi5wYXlsb2FkO1xuICBjb25zdCBjbGFtcGVkID0gTWF0aC5taW4oMTAwLCBNYXRoLm1heCgwLCBwZXJjZW50YWdlKSk7XG4gIGlmIChjbGFtcGVkID09PSBzdGF0ZS5zd2lwZUNvbXBhcmVQZXJjZW50YWdlKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgc3dpcGVDb21wYXJlUGVyY2VudGFnZTogY2xhbXBlZFxuICB9O1xufTtcblxuLyoqXG4gKiBUb2dnbGUgYmV0d2VlbiBsb2NrZWQgYW5kIHVubG9ja2VkIHNwbGl0IHZpZXdwb3J0c1xuICogQG1lbWJlcm9mIG1hcFN0YXRlVXBkYXRlcnNcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHRvZ2dsZVNwbGl0TWFwVmlld3BvcnRVcGRhdGVyID0gKFxuICBzdGF0ZTogTWFwU3RhdGUsXG4gIGFjdGlvbjogTWFwU3RhdGVBY3Rpb25zLlRvZ2dsZVNwbGl0TWFwVmlld3BvcnRVcGRhdGVyQWN0aW9uXG4pID0+IHtcbiAgLy8gU3dpcGUgbW9kZSBhbHdheXMgdXNlcyBzeW5jZWQgdmlld3BvcnRzXG4gIGlmIChzdGF0ZS5tYXBTcGxpdE1vZGUgPT09IE1hcFNwbGl0TW9kZS5TV0lQRV9DT01QQVJFKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgLy8gbmV3IG1hcCBzdGF0ZSBpbW1lZGlhdGVseSBnZXRzIHRoZSBuZXcsIG9wdGlvbmFsIHBheWxvYWQgdmFsdWVzIGZvciBpc1ZpZXdwb3J0U3luY2VkIGFuZC9vciBpc1pvb21Mb2NrZWRcbiAgY29uc3QgbmV3TWFwU3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgLi4uKGFjdGlvbi5wYXlsb2FkIHx8IHt9KVxuICB9O1xuXG4gIGlmIChuZXdNYXBTdGF0ZS5pc1ZpZXdwb3J0U3luY2VkKSB7XG4gICAgLy8gc3dpdGNoaW5nIGZyb20gdW5zeW5jZWQgdG8gc3luY2VkIHZpZXdwb3J0c1xuICAgIG5ld01hcFN0YXRlLnNwbGl0TWFwVmlld3BvcnRzID0gW107XG4gIH0gZWxzZSB7XG4gICAgLy8gc3dpdGNoaW5nIGZyb20gc3luY2VkIHRvIHVuc3luY2VkIHZpZXdwb3J0c1xuICAgIC8vIG9yIGFscmVhZHkgaW4gdW5zeW5jZWQgbW9kZSBhbmQgdG9nZ2xpbmcgbG9ja2VkIHpvb21cblxuICAgIGlmIChzdGF0ZS5pc1pvb21Mb2NrZWQgJiYgIW5ld01hcFN0YXRlLmlzWm9vbUxvY2tlZCkge1xuICAgICAgLy8gc3dpdGNoaW5nIG9mZiBsb2NrZWQgem9vbSB3aGlsZSB1bnN5bmNlZFxuICAgICAgLy8gZG9uJ3QgY29weSB0aGUgbWFwU3RhdGVzIHRvIGxlZnQgYW5kIHJpZ2h0IHZpZXdwb3J0cyBiZWNhdXNlIHRoZXJlIHdpbGwgYmUgem9vbSBcImp1bXBpbmdcIlxuICAgICAgcmV0dXJuIG5ld01hcFN0YXRlO1xuICAgIH1cblxuICAgIGlmICghc3RhdGUuaXNab29tTG9ja2VkICYmIG5ld01hcFN0YXRlLmlzWm9vbUxvY2tlZCkge1xuICAgICAgLy8gc3dpdGNoaW5nIG9uIGxvY2tlZCB6b29tIHdoaWxlIHVuc3luY2VkXG4gICAgICAvLyBvbmx5IGNvcHkgem9vbSB2aWV3cG9ydCBwcm9wZXJ0eSBmcm9tIHRoZSBtb3N0IHJlY2VudGx5IGludGVyYWN0ZWQtd2l0aCB2aWV3cG9ydCB0byB0aGUgb3RoZXJcbiAgICAgIC8vIFRPRE86IGRvIHdlIHdhbnQgdG8gY2hlY2sgZm9yIGEgbWF0Y2ggYSBkaWZmZXJlbnQgd2F5LCBzdWNoIGFzIGEgY29tYm8gb2YgYGxhdGl0dWRlYCBhbmQgYGxvbmdpdHVkZWA/XG4gICAgICBjb25zdCBsYXN0VXBkYXRlZFZpZXdwb3J0SW5kZXggPSBuZXdNYXBTdGF0ZS5zcGxpdE1hcFZpZXdwb3J0cy5maW5kSW5kZXgoXG4gICAgICAgIHYgPT4gbmV3TWFwU3RhdGUuem9vbSA9PT0gdi56b29tXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzcGxpdE1hcFZpZXdwb3J0cyA9IG5ld01hcFN0YXRlLnNwbGl0TWFwVmlld3BvcnRzLm1hcCgoY3VycmVudFZpZXdwb3J0LCBpKSA9PiB7XG4gICAgICAgIGlmIChpID09PSBsYXN0VXBkYXRlZFZpZXdwb3J0SW5kZXgpIHtcbiAgICAgICAgICAvLyBubyB6b29tIHRvIG1vZGlmeSBoZXJlXG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWaWV3cG9ydDtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGUgb3RoZXIgdmlld3BvcnQgZ2V0cyB0aGUgbW9zdCByZWNlbnRseSBpbnRlcmFjdGVkLXdpdGggdmlld3BvcnQncyB6b29tXG4gICAgICAgIC8vIFdIWT8gdGhlIHZpZXdwb3J0IHRoZSB1c2VyIHdhcyBsYXN0IGludGVyYWN0aW5nIHdpdGggd2lsbCBzZXQgem9vbSBhY3Jvc3MgdGhlIGJvYXJkIGZvciBzbW9vdGggVVhcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5jdXJyZW50Vmlld3BvcnQsXG4gICAgICAgICAgem9vbTogbmV3TWFwU3RhdGUuc3BsaXRNYXBWaWV3cG9ydHNbbGFzdFVwZGF0ZWRWaWV3cG9ydEluZGV4XS56b29tXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgbmV3TWFwU3RhdGUuc3BsaXRNYXBWaWV3cG9ydHMgPSBzcGxpdE1hcFZpZXdwb3J0cztcblxuICAgICAgcmV0dXJuIG5ld01hcFN0YXRlO1xuICAgIH1cblxuICAgIC8vIGlmIGN1cnJlbnQgdmlld3BvcnQgaXMgc3luY2VkLCBhbmQgd2UgYXJlIHVuc3luY2luZyBpdFxuICAgIC8vIG9yIGFscmVhZHkgaW4gdW5zeW5jZWQgbW9kZSBhbmQgTk9UIHRvZ2dsaW5nIGxvY2tlZCB6b29tXG4gICAgLy8gbWFrZSBhIGZyZXNoIGNvcHkgb2YgdGhlIGN1cnJlbnQgdmlld3BvcnQgb2JqZWN0LCBhc3NpZ24gaXQgdG8gc3BsaXRNYXBWaWV3cG9ydHNbXVxuICAgIC8vIHBpY2tWaWV3cG9ydFByb3BzRnJvbU1hcFN0YXRlIGlzIGNhbGxlZCB0d2ljZSB0byBhdm9pZCBtZW1vcnkgYWxsb2NhdGlvbiBjb25mbGljdHNcbiAgICBjb25zdCBsZWZ0Vmlld3BvcnQgPSBwaWNrVmlld3BvcnRQcm9wc0Zyb21NYXBTdGF0ZShuZXdNYXBTdGF0ZSk7XG4gICAgY29uc3QgcmlnaHRWaWV3cG9ydCA9IHBpY2tWaWV3cG9ydFByb3BzRnJvbU1hcFN0YXRlKG5ld01hcFN0YXRlKTtcbiAgICBuZXdNYXBTdGF0ZS5zcGxpdE1hcFZpZXdwb3J0cyA9IFtsZWZ0Vmlld3BvcnQsIHJpZ2h0Vmlld3BvcnRdO1xuICB9XG5cbiAgLy8gcmV0dXJuIG5ldyBzdGF0ZVxuICByZXR1cm4gbmV3TWFwU3RhdGU7XG59O1xuXG4vLyBIZWxwZXJzXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWFwRGltRm9yU3BsaXRNYXAoaXNTcGxpdCwgc3RhdGUpIHtcbiAgLy8gY2FzZXM6XG4gIC8vIDEuIHN0YXRlIHNwbGl0OiB0cnVlIC0gaXNTcGxpdDogdHJ1ZVxuICAvLyBkbyBub3RoaW5nXG4gIC8vIDIuIHN0YXRlIHNwbGl0OiBmYWxzZSAtIGlzU3BsaXQ6IGZhbHNlXG4gIC8vIGRvIG5vdGhpbmdcbiAgaWYgKHN0YXRlLmlzU3BsaXQgPT09IGlzU3BsaXQpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvLyBJbiBzd2lwZSBtb2RlLCBib3RoIG1hcHMgdXNlIGZ1bGwgd2lkdGggKG92ZXJsYXBwaW5nIHdpdGggY2xpcClcbiAgaWYgKHN0YXRlLm1hcFNwbGl0TW9kZSA9PT0gTWFwU3BsaXRNb2RlLlNXSVBFX0NPTVBBUkUpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBjb25zdCB3aWR0aCA9XG4gICAgc3RhdGUuaXNTcGxpdCAmJiAhaXNTcGxpdFxuICAgICAgPyAvLyAzLiBzdGF0ZSBzcGxpdDogdHJ1ZSAtIGlzU3BsaXQ6IGZhbHNlXG4gICAgICAgIC8vIGRvdWJsZSB3aWR0aFxuICAgICAgICBzdGF0ZS53aWR0aCAqIDJcbiAgICAgIDogLy8gNC4gc3RhdGUgc3BsaXQ6IGZhbHNlIC0gaXNTcGxpdDogdHJ1ZVxuICAgICAgICAvLyBzcGxpdCB3aWR0aFxuICAgICAgICBzdGF0ZS53aWR0aCAvIDI7XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aFxuICB9O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVWaWV3cG9ydEJhc2VkT25Cb3VuZHMoc3RhdGU6IE1hcFN0YXRlLCBuZXdNYXBTdGF0ZTogTWFwU3RhdGUpIHtcbiAgLy8gR2V0IHRoZSBuZXcgdmlld3BvcnQgYm91bmRzXG4gIGNvbnN0IHZpZXdwb3J0Qm91bmRzID0gZ2VvVmlld3BvcnQuYm91bmRzKFxuICAgIFtuZXdNYXBTdGF0ZS5sb25naXR1ZGUsIG5ld01hcFN0YXRlLmxhdGl0dWRlXSxcbiAgICBuZXdNYXBTdGF0ZS56b29tLFxuICAgIFtuZXdNYXBTdGF0ZS53aWR0aCwgbmV3TWFwU3RhdGUuaGVpZ2h0XSxcbiAgICBNQVBCT1hfVElMRV9TSVpFXG4gICk7XG4gIC8vIEdlbmVyYXRlIHR1cmYgUG9seWdvbiBmcm9tIGJvdW5kcyBmb3IgY29tcGFyaXNvblxuICBjb25zdCB2aWV3cG9ydEJvdW5kc1BvbHlnb24gPSBiYm94UG9seWdvbih2aWV3cG9ydEJvdW5kcyk7XG4gIC8vIEB0cy1pZ25vcmVcbiAgY29uc3QgbmV3U3RhdGVNYXhCb3VuZHM6IEJvdW5kcyA9IG5ld01hcFN0YXRlLm1heEJvdW5kcztcbiAgLy8gQHRzLWlnbm9yZVxuICBjb25zdCBtYXhCb3VuZHNQb2x5Z29uID0gYmJveFBvbHlnb24obmV3U3RhdGVNYXhCb3VuZHMpO1xuXG4gIC8vIElmIG1heEJvdW5kcyBoYXMgY2hhbmdlZCByZXNldCB0aGUgdmlld3BvcnQgdG8gc25hcCB0byBib3VuZHNcbiAgY29uc3QgaGFzTWF4Qm91bmRzQ2hhbmdlZCA9XG4gICAgIXN0YXRlLm1heEJvdW5kcyB8fCAhc3RhdGUubWF4Qm91bmRzLmV2ZXJ5KCh2YWwsIGlkeCkgPT4gdmFsID09PSBuZXdTdGF0ZU1heEJvdW5kc1tpZHhdKTtcbiAgaWYgKGhhc01heEJvdW5kc0NoYW5nZWQpIHtcbiAgICAvLyBDaGVjayBpZiB0aGUgbmV3TWFwU3RhdGUgdmlld3BvcnQgaXMgd2l0aGluIG1heEJvdW5kc1xuICAgIGlmICghYm9vbGVhbldpdGhpbih2aWV3cG9ydEJvdW5kc1BvbHlnb24sIG1heEJvdW5kc1BvbHlnb24pKSB7XG4gICAgICBjb25zdCB7bGF0aXR1ZGUsIGxvbmdpdHVkZSwgem9vbX0gPSBmaXRCb3VuZHMoe1xuICAgICAgICB3aWR0aDogbmV3TWFwU3RhdGUud2lkdGgsXG4gICAgICAgIGhlaWdodDogbmV3TWFwU3RhdGUuaGVpZ2h0LFxuICAgICAgICBib3VuZHM6IFtcbiAgICAgICAgICBbbmV3U3RhdGVNYXhCb3VuZHNbMF0sIG5ld1N0YXRlTWF4Qm91bmRzWzFdXSxcbiAgICAgICAgICBbbmV3U3RhdGVNYXhCb3VuZHNbMl0sIG5ld1N0YXRlTWF4Qm91bmRzWzNdXVxuICAgICAgICBdXG4gICAgICB9KTtcblxuICAgICAgbmV3TWFwU3RhdGUgPSB7XG4gICAgICAgIC4uLm5ld01hcFN0YXRlLFxuICAgICAgICBsYXRpdHVkZSxcbiAgICAgICAgbG9uZ2l0dWRlLFxuICAgICAgICAvLyBGb3IgbWFyZ2luYWwgb3IgaW52YWxpZCBib3VuZHMsIHpvb20gbWF5IGJlIE5hTi4gTWFrZSBzdXJlIHRvIHByb3ZpZGUgYSB2YWxpZCB2YWx1ZSBpbiBvcmRlclxuICAgICAgICAvLyB0byBhdm9pZCBjb3JydXB0IHN0YXRlIGFuZCBwb3RlbnRpYWwgY3Jhc2hlcyBhcyB6b29tIGlzIGV4cGVjdGVkIHRvIGJlIGEgbnVtYmVyXG4gICAgICAgIC4uLihOdW1iZXIuaXNGaW5pdGUoem9vbSkgPyB7em9vbX0gOiB7fSlcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBuZXdNYXBTdGF0ZTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIHRoZSBuZXdNYXBTdGF0ZSB2aWV3cG9ydCBpcyB3aXRoaW4gbWF4Qm91bmRzXG4gIGlmICghYm9vbGVhbldpdGhpbih2aWV3cG9ydEJvdW5kc1BvbHlnb24sIG1heEJvdW5kc1BvbHlnb24pKSB7XG4gICAgbmV3TWFwU3RhdGUgPSB7XG4gICAgICAuLi5uZXdNYXBTdGF0ZSxcbiAgICAgIGxvbmdpdHVkZTogc3RhdGUubG9uZ2l0dWRlLFxuICAgICAgbGF0aXR1ZGU6IHN0YXRlLmxhdGl0dWRlLFxuICAgICAgem9vbTogc3RhdGUuem9vbVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gbmV3TWFwU3RhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwaWNrVmlld3BvcnRQcm9wc0Zyb21NYXBTdGF0ZShzdGF0ZTogTWFwU3RhdGUpOiBWaWV3cG9ydCB7XG4gIHJldHVybiBwaWNrKHN0YXRlLCBbXG4gICAgJ3dpZHRoJyxcbiAgICAnaGVpZ2h0JyxcbiAgICAnem9vbScsXG4gICAgJ3BpdGNoJyxcbiAgICAnYmVhcmluZycsXG4gICAgJ2xhdGl0dWRlJyxcbiAgICAnbG9uZ2l0dWRlJyxcbiAgICAnZHJhZ1JvdGF0ZScsXG4gICAgJ21pblpvb20nLFxuICAgICdtYXhab29tJyxcbiAgICAnbWF4UGl0Y2gnLFxuICAgICdtYXhCb3VuZHMnXG4gIF0pO1xufVxuXG4vKiogU2VsZWN0IGl0ZW1zIGZyb20gb2JqZWN0IHdob3NlIHZhbHVlIGlzIG5vdCB1bmRlZmluZWQgKi9cbmNvbnN0IGRlZmluZWRQcm9wcyA9IG9iaiA9PlxuICBPYmplY3QuZW50cmllcyhvYmopLnJlZHVjZShcbiAgICAoYWNjdSwgW2ssIHZdKSA9PiAoey4uLmFjY3UsIC4uLih2ICE9PSB1bmRlZmluZWQgPyB7W2tdOiB2fSA6IHt9KX0pLFxuICAgIHt9XG4gICk7XG5cbmZ1bmN0aW9uIHVwZGF0ZVZpZXdwb3J0KG9yaWdpbmFsVmlld3BvcnQ6IFZpZXdwb3J0LCB2aWV3cG9ydFVwZGF0ZXM6IFZpZXdwb3J0KTogVmlld3BvcnQge1xuICBsZXQgbmV3Vmlld3BvcnQgPSB7XG4gICAgLi4ub3JpZ2luYWxWaWV3cG9ydCxcbiAgICAuLi4oZGVmaW5lZFByb3BzKHZpZXdwb3J0VXBkYXRlcykgfHwge30pXG4gIH07XG5cbiAgLy8gZGVjay5nbCdzIGdsb2JlIGNvbnRyb2xsZXIgYXBwbGllcyBhIGxhdGl0dWRlLWRlcGVuZGVudCBhZGp1c3RtZW50IHRvIHRoZVxuICAvLyB6b29tIHJhbmdlIChzZWUgS2VwbGVyR2xvYmVWaWV3Ll9jb25zdHJhaW5ab29tKS4gSWYgd2UgY2xhbXAgdGhlIHByb3BhZ2F0ZWRcbiAgLy8gem9vbSBoZXJlIGFnYWluc3QgdGhlIHJhdyBtaW5ab29tL21heFpvb20gKHdpdGhvdXQgdGhhdCBhZGp1c3RtZW50KSwgUmVkdXhcbiAgLy8gZW5kcyB1cCBkaXNhZ3JlZWluZyB3aXRoIHRoZSBjb250cm9sbGVyOiB0aGUgY29udHJvbGxlciBsZXRzIHRoZSB1c2VyIHB1bGxcbiAgLy8gdGhlIGdsb2JlIGZ1cnRoZXIgb3V0LCBidXQgdGhpcyBjbGFtcCBzbmFwcyB6b29tIGJhY2sgdG8gYG1pblpvb21gIHdoZW4gdGhlXG4gIC8vIGludGVyYWN0aW9uJ3MgaW5lcnRpYSB0cmFuc2l0aW9uIGVuZHMuIEFwcGx5IHRoZSBzYW1lIGFkanVzdG1lbnQgaW4gZ2xvYmVcbiAgLy8gbW9kZSBzbyBSZWR1eCBzdGF5cyBjb25zaXN0ZW50IHdpdGggdGhlIGNvbnRyb2xsZXIgYW5kIHRoZXJlJ3Mgbm8gc25hcC1iYWNrLlxuICBjb25zdCBpc0dsb2JlID0gKG5ld1ZpZXdwb3J0IGFzIGFueSkuZ2xvYmU/LmVuYWJsZWQ7XG5cbiAgaWYgKGlzR2xvYmUpIHtcbiAgICAvLyBLZWVwIHRoZSBjYW1lcmEgdGFyZ2V0IHdpdGhpbiBhIGxhdGl0dWRlIGJhbmQgYXJvdW5kIHRoZSBlcXVhdG9yIHNvIHRoZVxuICAgIC8vIHN0b3JlZCB2aWV3cG9ydCBjYW4ndCBiZSBjZW50ZXJlZCBvbiB0aGUgcG9sZXMgKG1hdGNoZXMgdGhlIGdsb2JlXG4gICAgLy8gY29udHJvbGxlcidzIGFwcGx5Q29uc3RyYWludHMgc28gZ2VvY29kZXIvcHJvZ3JhbW1hdGljIHVwZGF0ZXMgYWdyZWUpLlxuICAgIGlmICh0eXBlb2YgbmV3Vmlld3BvcnQubGF0aXR1ZGUgPT09ICdudW1iZXInKSB7XG4gICAgICBuZXdWaWV3cG9ydC5sYXRpdHVkZSA9IE1hdGgubWluKFxuICAgICAgICBHTE9CRV9NQVhfTEFUSVRVREUsXG4gICAgICAgIE1hdGgubWF4KC1HTE9CRV9NQVhfTEFUSVRVREUsIG5ld1ZpZXdwb3J0LmxhdGl0dWRlKVxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3Qgem9vbUFkanVzdG1lbnQgPSBNYXRoLmxvZzIoTWF0aC5jb3MoKChuZXdWaWV3cG9ydC5sYXRpdHVkZSA/PyAwKSAqIE1hdGguUEkpIC8gMTgwKSk7XG4gICAgaWYgKFxuICAgICAgdHlwZW9mIG5ld1ZpZXdwb3J0Lm1pblpvb20gPT09ICdudW1iZXInICYmXG4gICAgICB0eXBlb2YgbmV3Vmlld3BvcnQuem9vbSA9PT0gJ251bWJlcicgJiZcbiAgICAgIG5ld1ZpZXdwb3J0Lnpvb20gPCBuZXdWaWV3cG9ydC5taW5ab29tICsgem9vbUFkanVzdG1lbnRcbiAgICApIHtcbiAgICAgIG5ld1ZpZXdwb3J0Lnpvb20gPSBuZXdWaWV3cG9ydC5taW5ab29tICsgem9vbUFkanVzdG1lbnQ7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBuZXdWaWV3cG9ydC5tYXhab29tID09PSAnbnVtYmVyJyAmJlxuICAgICAgdHlwZW9mIG5ld1ZpZXdwb3J0Lnpvb20gPT09ICdudW1iZXInICYmXG4gICAgICBuZXdWaWV3cG9ydC56b29tID4gbmV3Vmlld3BvcnQubWF4Wm9vbSArIHpvb21BZGp1c3RtZW50XG4gICAgKSB7XG4gICAgICBuZXdWaWV3cG9ydC56b29tID0gbmV3Vmlld3BvcnQubWF4Wm9vbSArIHpvb21BZGp1c3RtZW50O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBNYWtlIHN1cmUgem9vbSBsZXZlbCBkb2Vzbid0IGdvIGJlbGxvdyBtaW5ab29tIGlmIGRlZmluZWRcbiAgICBpZiAobmV3Vmlld3BvcnQubWluWm9vbSAmJiBuZXdWaWV3cG9ydC56b29tICYmIG5ld1ZpZXdwb3J0Lnpvb20gPCBuZXdWaWV3cG9ydC5taW5ab29tKSB7XG4gICAgICBuZXdWaWV3cG9ydC56b29tID0gbmV3Vmlld3BvcnQubWluWm9vbTtcbiAgICB9XG4gICAgLy8gTWFrZSBzdXJlIHpvb20gbGV2ZWwgZG9lc24ndCBnbyBhYm92ZSBtYXhab29tIGlmIGRlZmluZWRcbiAgICBpZiAobmV3Vmlld3BvcnQubWF4Wm9vbSAmJiBuZXdWaWV3cG9ydC56b29tICYmIG5ld1ZpZXdwb3J0Lnpvb20gPiBuZXdWaWV3cG9ydC5tYXhab29tKSB7XG4gICAgICBuZXdWaWV3cG9ydC56b29tID0gbmV3Vmlld3BvcnQubWF4Wm9vbTtcbiAgICB9XG4gIH1cbiAgLy8gTGltaXQgdmlld3BvcnQgdXBkYXRlIGJhc2VkIG9uIG1heEJvdW5kc1xuICBpZiAobmV3Vmlld3BvcnQubWF4Qm91bmRzICYmIHZhbGlkYXRlQm91bmRzKG5ld1ZpZXdwb3J0Lm1heEJvdW5kcykpIHtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFR5cGUgJ1ZpZXdwb3J0JyBpcyBtaXNzaW5nIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmcm9tIHR5cGUgJ01hcFN0YXRlJzogaXNTcGxpdCwgaXNWaWV3cG9ydFN5bmNlZCwgaXNab29tTG9ja2VkLCBzcGxpdE1hcFZpZXdwb3J0c1xuICAgIG5ld1ZpZXdwb3J0ID0gdXBkYXRlVmlld3BvcnRCYXNlZE9uQm91bmRzKG9yaWdpbmFsVmlld3BvcnQsIG5ld1ZpZXdwb3J0KTtcbiAgfVxuXG4gIHJldHVybiBuZXdWaWV3cG9ydDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUdBLElBQUFBLFlBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLGNBQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLFlBQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLFlBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLFVBQUEsR0FBQUwsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFLLEtBQUEsR0FBQU4sc0JBQUEsQ0FBQUMsT0FBQTtBQUVBLElBQUFNLE1BQUEsR0FBQU4sT0FBQTtBQVFBLElBQUFPLFVBQUEsR0FBQVAsT0FBQTtBQUF5SSxTQUFB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