@kepler.gl/deckgl-layers 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.
- package/dist/cjs/3d-building-layer/3d-building-layer.js +66 -0
- package/dist/cjs/3d-building-layer/3d-building-utils.js +166 -0
- package/dist/cjs/3d-building-layer/types.js +6 -0
- package/dist/cjs/cluster-layer/cluster-layer.js +292 -0
- package/dist/cjs/column-layer/enhanced-column-layer.js +160 -0
- package/dist/{deckgl-extensions → cjs/deckgl-extensions}/filter-arrow-layer.js +1 -1
- package/dist/cjs/deckgl-extensions/filter-shader-module.js +26 -0
- package/dist/cjs/globe/atmosphere-layer.js +220 -0
- package/dist/cjs/globe/enhanced-multi-icon-layer.js +63 -0
- package/dist/cjs/globe/globe-depth-disk-layer.js +145 -0
- package/dist/cjs/globe/globe-layers.js +569 -0
- package/dist/cjs/globe/globe-stars-layer.js +69 -0
- package/dist/cjs/globe/globe-view.js +407 -0
- package/dist/{globe → cjs/globe}/index.js +1 -1
- package/dist/cjs/globe/mvt-label-layer.js +190 -0
- package/dist/cjs/grid-layer/enhanced-cpu-grid-layer.js +116 -0
- package/dist/cjs/hexagon-layer/enhanced-hexagon-layer.js +134 -0
- package/dist/{index.js → cjs/index.js} +1 -1
- package/dist/cjs/layer-utils/aggregation-utils.js +181 -0
- package/dist/cjs/layer-utils/cluster-utils.js +93 -0
- package/dist/cjs/layer-utils/cpu-aggregator.js +798 -0
- package/dist/cjs/layer-utils/globe-cell-utils.js +173 -0
- package/dist/cjs/layer-utils/shader-utils.js +38 -0
- package/dist/cjs/line-layer/line-layer.js +95 -0
- package/dist/cjs/raster/images.js +271 -0
- package/dist/cjs/raster/pipeline-validation-patch.js +101 -0
- package/dist/cjs/raster/raster-layer/raster-layer-shaders.js +163 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl1.fs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl1.vs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl2.fs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl2.vs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer.js +287 -0
- package/dist/cjs/raster/raster-mesh-layer/matrix.js +18 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +38 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer.js +321 -0
- package/dist/cjs/raster/raster-processing-uniforms.js +124 -0
- package/dist/cjs/raster/types.js +6 -0
- package/dist/cjs/raster/util.js +139 -0
- package/dist/cjs/raster/webgl/color/colormap.js +45 -0
- package/dist/cjs/raster/webgl/color/filter.js +58 -0
- package/dist/cjs/raster/webgl/color/gamma-contrast.js +68 -0
- package/dist/cjs/raster/webgl/color/linear-rescale.js +35 -0
- package/dist/cjs/raster/webgl/color/saturation.js +42 -0
- package/dist/cjs/raster/webgl/color/sigmoidal-contrast.js +68 -0
- package/dist/{raster → cjs/raster}/webgl/index.js +1 -1
- package/dist/cjs/raster/webgl/pansharpen/pansharpen-brovey.js +46 -0
- package/dist/cjs/raster/webgl/spectral-indices/evi.js +26 -0
- package/dist/cjs/raster/webgl/spectral-indices/msavi.js +25 -0
- package/dist/cjs/raster/webgl/spectral-indices/normalized-difference.js +19 -0
- package/dist/cjs/raster/webgl/spectral-indices/savi.js +21 -0
- package/dist/cjs/raster/webgl/texture/combine-bands.js +65 -0
- package/dist/cjs/raster/webgl/texture/mask.js +50 -0
- package/dist/cjs/raster/webgl/texture/reorder-bands.js +72 -0
- package/dist/cjs/raster/webgl/texture/rgba-image.js +34 -0
- package/dist/cjs/raster/webgl/types.js +6 -0
- package/dist/cjs/svg-icon-layer/scatterplot-icon-layer.js +88 -0
- package/dist/cjs/svg-icon-layer/svg-icon-layer.js +104 -0
- package/dist/cjs/wms/wms-layer.js +624 -0
- package/dist/esm/3d-building-layer/3d-building-layer.js +62 -0
- package/dist/esm/3d-building-layer/3d-building-utils.js +157 -0
- package/dist/esm/3d-building-layer/types.js +3 -0
- package/dist/esm/cluster-layer/cluster-layer.js +286 -0
- package/dist/esm/column-layer/enhanced-column-layer.js +156 -0
- package/dist/esm/deckgl-extensions/filter-arrow-layer.js +64 -0
- package/dist/esm/deckgl-extensions/filter-shader-module.js +20 -0
- package/dist/esm/globe/atmosphere-layer.js +214 -0
- package/dist/esm/globe/enhanced-multi-icon-layer.js +60 -0
- package/dist/esm/globe/globe-depth-disk-layer.js +140 -0
- package/dist/esm/globe/globe-layers.js +561 -0
- package/dist/esm/globe/globe-stars-layer.js +63 -0
- package/dist/esm/globe/globe-view.js +401 -0
- package/dist/esm/globe/index.js +26 -0
- package/dist/esm/globe/mvt-label-layer.js +187 -0
- package/dist/esm/grid-layer/enhanced-cpu-grid-layer.js +112 -0
- package/dist/esm/hexagon-layer/enhanced-hexagon-layer.js +130 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/layer-utils/aggregation-utils.js +172 -0
- package/dist/esm/layer-utils/cluster-utils.js +86 -0
- package/dist/esm/layer-utils/cpu-aggregator.js +788 -0
- package/dist/esm/layer-utils/globe-cell-utils.js +167 -0
- package/dist/esm/layer-utils/shader-utils.js +32 -0
- package/dist/esm/line-layer/line-layer.js +91 -0
- package/dist/esm/raster/images.js +267 -0
- package/dist/esm/raster/pipeline-validation-patch.js +94 -0
- package/dist/esm/raster/raster-layer/raster-layer-shaders.js +153 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl1.fs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl1.vs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl2.fs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl2.vs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer.js +283 -0
- package/dist/esm/raster/raster-mesh-layer/matrix.js +12 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +30 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer.js +318 -0
- package/dist/esm/raster/raster-processing-uniforms.js +118 -0
- package/dist/esm/raster/types.js +3 -0
- package/dist/esm/raster/util.js +134 -0
- package/dist/esm/raster/webgl/color/colormap.js +39 -0
- package/dist/esm/raster/webgl/color/filter.js +52 -0
- package/dist/esm/raster/webgl/color/gamma-contrast.js +62 -0
- package/dist/esm/raster/webgl/color/linear-rescale.js +29 -0
- package/dist/esm/raster/webgl/color/saturation.js +36 -0
- package/dist/esm/raster/webgl/color/sigmoidal-contrast.js +62 -0
- package/dist/esm/raster/webgl/index.js +26 -0
- package/dist/esm/raster/webgl/pansharpen/pansharpen-brovey.js +40 -0
- package/dist/esm/raster/webgl/spectral-indices/evi.js +20 -0
- package/dist/esm/raster/webgl/spectral-indices/msavi.js +19 -0
- package/dist/esm/raster/webgl/spectral-indices/normalized-difference.js +13 -0
- package/dist/esm/raster/webgl/spectral-indices/savi.js +15 -0
- package/dist/esm/raster/webgl/texture/combine-bands.js +58 -0
- package/dist/esm/raster/webgl/texture/mask.js +44 -0
- package/dist/esm/raster/webgl/texture/reorder-bands.js +65 -0
- package/dist/esm/raster/webgl/texture/rgba-image.js +28 -0
- package/dist/esm/raster/webgl/types.js +3 -0
- package/dist/esm/svg-icon-layer/scatterplot-icon-layer.js +84 -0
- package/dist/esm/svg-icon-layer/svg-icon-layer.js +101 -0
- package/dist/esm/wms/wms-layer.js +619 -0
- package/dist/globe/atmosphere-layer.d.ts +13 -2
- package/dist/globe/globe-depth-disk-layer.d.ts +1 -0
- package/dist/globe/globe-layers.d.ts +8 -2
- package/dist/raster/images.d.ts +10 -1
- package/dist/raster/raster-layer/raster-layer.d.ts +4 -0
- package/dist/raster/raster-mesh-layer/raster-mesh-layer.d.ts +4 -0
- package/dist/wms/wms-layer.d.ts +8 -0
- package/package.json +18 -11
- package/dist/3d-building-layer/3d-building-layer.js +0 -66
- package/dist/3d-building-layer/3d-building-utils.js +0 -166
- package/dist/3d-building-layer/types.js +0 -6
- package/dist/cluster-layer/cluster-layer.js +0 -292
- package/dist/column-layer/enhanced-column-layer.js +0 -160
- package/dist/deckgl-extensions/filter-shader-module.js +0 -26
- package/dist/globe/atmosphere-layer.js +0 -184
- package/dist/globe/enhanced-multi-icon-layer.js +0 -63
- package/dist/globe/globe-depth-disk-layer.js +0 -145
- package/dist/globe/globe-layers.js +0 -565
- package/dist/globe/globe-stars-layer.js +0 -69
- package/dist/globe/globe-view.js +0 -316
- package/dist/globe/mvt-label-layer.js +0 -190
- package/dist/grid-layer/enhanced-cpu-grid-layer.js +0 -116
- package/dist/hexagon-layer/enhanced-hexagon-layer.js +0 -134
- package/dist/layer-utils/aggregation-utils.js +0 -181
- package/dist/layer-utils/cluster-utils.js +0 -93
- package/dist/layer-utils/cpu-aggregator.js +0 -798
- package/dist/layer-utils/globe-cell-utils.js +0 -173
- package/dist/layer-utils/shader-utils.js +0 -38
- package/dist/line-layer/line-layer.js +0 -95
- package/dist/raster/images.js +0 -259
- package/dist/raster/pipeline-validation-patch.js +0 -101
- package/dist/raster/raster-layer/raster-layer-shaders.js +0 -163
- package/dist/raster/raster-layer/raster-layer-webgl1.fs.js +0 -10
- package/dist/raster/raster-layer/raster-layer-webgl1.vs.js +0 -10
- package/dist/raster/raster-layer/raster-layer-webgl2.fs.js +0 -10
- package/dist/raster/raster-layer/raster-layer-webgl2.vs.js +0 -10
- package/dist/raster/raster-layer/raster-layer.js +0 -237
- package/dist/raster/raster-mesh-layer/matrix.js +0 -18
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +0 -38
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer.js +0 -271
- package/dist/raster/raster-processing-uniforms.js +0 -124
- package/dist/raster/types.js +0 -6
- package/dist/raster/util.js +0 -139
- package/dist/raster/webgl/color/colormap.js +0 -45
- package/dist/raster/webgl/color/filter.js +0 -58
- package/dist/raster/webgl/color/gamma-contrast.js +0 -68
- package/dist/raster/webgl/color/linear-rescale.js +0 -35
- package/dist/raster/webgl/color/saturation.js +0 -42
- package/dist/raster/webgl/color/sigmoidal-contrast.js +0 -68
- package/dist/raster/webgl/pansharpen/pansharpen-brovey.js +0 -46
- package/dist/raster/webgl/spectral-indices/evi.js +0 -26
- package/dist/raster/webgl/spectral-indices/msavi.js +0 -25
- package/dist/raster/webgl/spectral-indices/normalized-difference.js +0 -19
- package/dist/raster/webgl/spectral-indices/savi.js +0 -21
- package/dist/raster/webgl/texture/combine-bands.js +0 -65
- package/dist/raster/webgl/texture/mask.js +0 -50
- package/dist/raster/webgl/texture/reorder-bands.js +0 -72
- package/dist/raster/webgl/texture/rgba-image.js +0 -34
- package/dist/raster/webgl/types.js +0 -6
- package/dist/svg-icon-layer/scatterplot-icon-layer.js +0 -88
- package/dist/svg-icon-layer/svg-icon-layer.js +0 -104
- package/dist/wms/wms-layer.js +0 -594
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
4
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
5
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
|
|
6
|
+
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
|
|
7
|
+
import _get from "@babel/runtime/helpers/esm/get";
|
|
8
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
9
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
10
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
11
|
+
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; }
|
|
12
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
14
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
15
|
+
function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; }
|
|
16
|
+
// SPDX-License-Identifier: MIT
|
|
17
|
+
// Copyright contributors to the kepler.gl project
|
|
18
|
+
|
|
19
|
+
import { lngLatToWorld } from '@math.gl/web-mercator';
|
|
20
|
+
import { CompositeLayer, COORDINATE_SYSTEM, _deepEqual as deepEqual } from '@deck.gl/core';
|
|
21
|
+
import { BitmapLayer } from '@deck.gl/layers';
|
|
22
|
+
import { ImageSource, WMSImageSource } from '@loaders.gl/wms';
|
|
23
|
+
|
|
24
|
+
// TODO: This is a modified copy of WMSLayer from deck.gl. Remove this once we upgrade deck.gl and loaders.gl.
|
|
25
|
+
|
|
26
|
+
/** All props supported by the TileLayer */
|
|
27
|
+
|
|
28
|
+
/** Props added by the TileLayer */
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* How much the user may zoom in (shrinking the visible span) before a view that
|
|
32
|
+
* is still contained in the last requested extent triggers a fresh, higher
|
|
33
|
+
* resolution request. `2` means the cached image may be stretched up to ~2x
|
|
34
|
+
* before refetching; higher values mean fewer requests but blurrier zoom-ins.
|
|
35
|
+
*/
|
|
36
|
+
var COVERAGE_REFETCH_ZOOM_FACTOR = 2;
|
|
37
|
+
var defaultProps = {
|
|
38
|
+
id: 'imagery-layer',
|
|
39
|
+
data: '',
|
|
40
|
+
serviceType: 'auto',
|
|
41
|
+
srs: 'auto',
|
|
42
|
+
layers: {
|
|
43
|
+
type: 'array',
|
|
44
|
+
compare: true,
|
|
45
|
+
value: []
|
|
46
|
+
},
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
48
|
+
onMetadataLoad: {
|
|
49
|
+
type: 'function',
|
|
50
|
+
value: function value() {}
|
|
51
|
+
},
|
|
52
|
+
// eslint-disable-next-line
|
|
53
|
+
onMetadataLoadError: {
|
|
54
|
+
type: 'function',
|
|
55
|
+
value: console.error
|
|
56
|
+
},
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
58
|
+
onImageLoadStart: {
|
|
59
|
+
type: 'function',
|
|
60
|
+
value: function value() {}
|
|
61
|
+
},
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
63
|
+
onImageLoad: {
|
|
64
|
+
type: 'function',
|
|
65
|
+
value: function value() {}
|
|
66
|
+
},
|
|
67
|
+
onImageLoadError: {
|
|
68
|
+
type: 'function',
|
|
69
|
+
compare: false,
|
|
70
|
+
// eslint-disable-next-line
|
|
71
|
+
value: function value(requestId, error) {
|
|
72
|
+
return console.error(error, requestId);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var WMSLayer = /*#__PURE__*/function (_CompositeLayer) {
|
|
77
|
+
function WMSLayer() {
|
|
78
|
+
_classCallCheck(this, WMSLayer);
|
|
79
|
+
return _callSuper(this, WMSLayer, arguments);
|
|
80
|
+
}
|
|
81
|
+
_inherits(WMSLayer, _CompositeLayer);
|
|
82
|
+
return _createClass(WMSLayer, [{
|
|
83
|
+
key: "isLoaded",
|
|
84
|
+
get: /** Returns true if all async resources are loaded */
|
|
85
|
+
function get() {
|
|
86
|
+
// Track the explicit loading done by this layer
|
|
87
|
+
return Boolean(this.state) && this.state.loadCounter === 0 && _superPropGet(WMSLayer, "isLoaded", this, 1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Lets deck.gl know that we want viewport change events */
|
|
91
|
+
}, {
|
|
92
|
+
key: "shouldUpdateState",
|
|
93
|
+
value: function shouldUpdateState() {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}, {
|
|
97
|
+
key: "initializeState",
|
|
98
|
+
value: function initializeState() {
|
|
99
|
+
// intentionally empty, initialization is done in updateState
|
|
100
|
+
this.state._nextRequestId = 0;
|
|
101
|
+
this.state.lastRequestId = -1;
|
|
102
|
+
this.state.loadCounter = 0;
|
|
103
|
+
this.state._lastRequestZoom = -1;
|
|
104
|
+
}
|
|
105
|
+
}, {
|
|
106
|
+
key: "updateState",
|
|
107
|
+
value: function updateState(_ref) {
|
|
108
|
+
var _this = this;
|
|
109
|
+
var changeFlags = _ref.changeFlags,
|
|
110
|
+
props = _ref.props,
|
|
111
|
+
oldProps = _ref.oldProps;
|
|
112
|
+
var viewport = this.context.viewport;
|
|
113
|
+
|
|
114
|
+
// Check if data source has changed
|
|
115
|
+
if (changeFlags.dataChanged || props.serviceType !== oldProps.serviceType) {
|
|
116
|
+
this.state.imageSource = this._createImageSource(props);
|
|
117
|
+
this._loadMetadata();
|
|
118
|
+
this.debounce(function () {
|
|
119
|
+
return _this.loadImage(viewport, 'image source changed');
|
|
120
|
+
}, 0);
|
|
121
|
+
} else if (!deepEqual(props.layers, oldProps.layers, 1)) {
|
|
122
|
+
this.debounce(function () {
|
|
123
|
+
return _this.loadImage(viewport, 'layers changed');
|
|
124
|
+
}, 0);
|
|
125
|
+
} else if (changeFlags.viewportChanged) {
|
|
126
|
+
var _gl$getContextAttribu;
|
|
127
|
+
// Check if preserveDrawingBuffer is enabled (indicates video recording or image export)
|
|
128
|
+
// Use minimal debounce (10ms) during export for responsive frame capture
|
|
129
|
+
// Request deduplication in loadImage prevents spam from redundant viewport updates
|
|
130
|
+
var gl = this.context.gl;
|
|
131
|
+
var isPreservingBuffer = gl === null || gl === void 0 || (_gl$getContextAttribu = gl.getContextAttributes) === null || _gl$getContextAttribu === void 0 || (_gl$getContextAttribu = _gl$getContextAttribu.call(gl)) === null || _gl$getContextAttribu === void 0 ? void 0 : _gl$getContextAttribu.preserveDrawingBuffer;
|
|
132
|
+
var debounceDelay = isPreservingBuffer ? 10 : undefined;
|
|
133
|
+
this.debounce(function () {
|
|
134
|
+
return _this.loadImage(viewport, 'viewport changed');
|
|
135
|
+
}, debounceDelay);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}, {
|
|
139
|
+
key: "renderLayers",
|
|
140
|
+
value: function renderLayers() {
|
|
141
|
+
var _this$state = this.state,
|
|
142
|
+
bounds = _this$state.bounds,
|
|
143
|
+
image = _this$state.image,
|
|
144
|
+
lastRequestParameters = _this$state.lastRequestParameters;
|
|
145
|
+
return image && new BitmapLayer(_objectSpread(_objectSpread({}, this.getSubLayerProps({
|
|
146
|
+
id: 'bitmap'
|
|
147
|
+
})), {}, {
|
|
148
|
+
_imageCoordinateSystem: lastRequestParameters.srs === 'EPSG:4326' ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN,
|
|
149
|
+
bounds: bounds,
|
|
150
|
+
image: image,
|
|
151
|
+
pickable: this.props.pickable
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
}, {
|
|
155
|
+
key: "getFeatureInfoText",
|
|
156
|
+
value: function () {
|
|
157
|
+
var _getFeatureInfoText = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(x, y) {
|
|
158
|
+
var lastRequestParameters, _this$state$imageSour, _this$state$imageSour2, featureInfo;
|
|
159
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
160
|
+
while (1) switch (_context.prev = _context.next) {
|
|
161
|
+
case 0:
|
|
162
|
+
lastRequestParameters = this.state.lastRequestParameters;
|
|
163
|
+
if (!lastRequestParameters) {
|
|
164
|
+
_context.next = 6;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
_context.next = 4;
|
|
168
|
+
return (_this$state$imageSour = (_this$state$imageSour2 = this.state.imageSource).getFeatureInfoText) === null || _this$state$imageSour === void 0 ? void 0 : _this$state$imageSour.call(_this$state$imageSour2, _objectSpread(_objectSpread({}, lastRequestParameters), {}, {
|
|
169
|
+
query_layers: lastRequestParameters.layers,
|
|
170
|
+
x: x,
|
|
171
|
+
y: y,
|
|
172
|
+
info_format: 'application/vnd.ogc.gml'
|
|
173
|
+
}));
|
|
174
|
+
case 4:
|
|
175
|
+
featureInfo = _context.sent;
|
|
176
|
+
return _context.abrupt("return", featureInfo);
|
|
177
|
+
case 6:
|
|
178
|
+
return _context.abrupt("return", '');
|
|
179
|
+
case 7:
|
|
180
|
+
case "end":
|
|
181
|
+
return _context.stop();
|
|
182
|
+
}
|
|
183
|
+
}, _callee, this);
|
|
184
|
+
}));
|
|
185
|
+
function getFeatureInfoText(_x, _x2) {
|
|
186
|
+
return _getFeatureInfoText.apply(this, arguments);
|
|
187
|
+
}
|
|
188
|
+
return getFeatureInfoText;
|
|
189
|
+
}()
|
|
190
|
+
}, {
|
|
191
|
+
key: "_createImageSource",
|
|
192
|
+
value: function _createImageSource(props) {
|
|
193
|
+
if (props.data instanceof ImageSource) {
|
|
194
|
+
return props.data;
|
|
195
|
+
}
|
|
196
|
+
if (typeof props.data === 'string') {
|
|
197
|
+
return new WMSImageSource(props.data, {
|
|
198
|
+
loadOptions: props.loadOptions
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
throw new Error('invalid image source in props.data');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Run a getMetadata on the image service */
|
|
205
|
+
}, {
|
|
206
|
+
key: "_loadMetadata",
|
|
207
|
+
value: (function () {
|
|
208
|
+
var _loadMetadata2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
209
|
+
var imageSource, metadata, _this$getCurrentLayer, _this$getCurrentLayer2;
|
|
210
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
211
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
212
|
+
case 0:
|
|
213
|
+
imageSource = this.state.imageSource;
|
|
214
|
+
_context2.prev = 1;
|
|
215
|
+
this.state.loadCounter++;
|
|
216
|
+
_context2.next = 5;
|
|
217
|
+
return imageSource.getMetadata();
|
|
218
|
+
case 5:
|
|
219
|
+
metadata = _context2.sent;
|
|
220
|
+
// If a request takes a long time, it may no longer be expected
|
|
221
|
+
if (this.state.imageSource === imageSource) {
|
|
222
|
+
(_this$getCurrentLayer = this.getCurrentLayer()) === null || _this$getCurrentLayer === void 0 || _this$getCurrentLayer.props.onMetadataLoad(metadata);
|
|
223
|
+
}
|
|
224
|
+
_context2.next = 12;
|
|
225
|
+
break;
|
|
226
|
+
case 9:
|
|
227
|
+
_context2.prev = 9;
|
|
228
|
+
_context2.t0 = _context2["catch"](1);
|
|
229
|
+
(_this$getCurrentLayer2 = this.getCurrentLayer()) === null || _this$getCurrentLayer2 === void 0 || _this$getCurrentLayer2.props.onMetadataLoadError(_context2.t0);
|
|
230
|
+
case 12:
|
|
231
|
+
_context2.prev = 12;
|
|
232
|
+
this.state.loadCounter--;
|
|
233
|
+
return _context2.finish(12);
|
|
234
|
+
case 15:
|
|
235
|
+
case "end":
|
|
236
|
+
return _context2.stop();
|
|
237
|
+
}
|
|
238
|
+
}, _callee2, this, [[1, 9, 12, 15]]);
|
|
239
|
+
}));
|
|
240
|
+
function _loadMetadata() {
|
|
241
|
+
return _loadMetadata2.apply(this, arguments);
|
|
242
|
+
}
|
|
243
|
+
return _loadMetadata;
|
|
244
|
+
}() /** Load an image */)
|
|
245
|
+
}, {
|
|
246
|
+
key: "loadImage",
|
|
247
|
+
value: (function () {
|
|
248
|
+
var _loadImage = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(viewport, _reason) {
|
|
249
|
+
var _gl$getContextAttribu2;
|
|
250
|
+
var _this$props, layers, serviceType, transparent, bounds, width, height, minLat, maxLat, srs, requestParams, _WGS84ToPseudoMercato, _WGS84ToPseudoMercato2, minX, minY, _WGS84ToPseudoMercato3, _WGS84ToPseudoMercato4, maxX, maxY, gl, isExporting, _this$state$lastReque, currentZoom, lastZoom, isZoomingIn, lastBbox, currentBbox, fullyContained, requestId, image, _this$getCurrentLayer3, _this$context$onError, _this$context, _this$getCurrentLayer4;
|
|
251
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
252
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
253
|
+
case 0:
|
|
254
|
+
_this$props = this.props, layers = _this$props.layers, serviceType = _this$props.serviceType, transparent = _this$props.transparent; // TODO - move to ImageSource?
|
|
255
|
+
if (!(serviceType === 'wms' && layers.length === 0)) {
|
|
256
|
+
_context3.next = 3;
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
return _context3.abrupt("return");
|
|
260
|
+
case 3:
|
|
261
|
+
// In globe mode deck's GlobeViewport.getBounds() only unprojects 4 edge
|
|
262
|
+
// midpoints and takes their min/max. That misses the screen corners, the
|
|
263
|
+
// curved limb, and (most importantly) the case where a pole is in view when
|
|
264
|
+
// looking from a high latitude — where every meridian and part of the far
|
|
265
|
+
// hemisphere become visible. Compute a fuller visible bounding box instead so
|
|
266
|
+
// the requested WMS image covers everything on screen.
|
|
267
|
+
bounds = viewport.resolution ? getGlobeVisibleBounds(viewport) : viewport.getBounds();
|
|
268
|
+
width = viewport.width, height = viewport.height; // Edge case: when bounds are perfectly symmetric around 0° (both longitude and latitude),
|
|
269
|
+
// it can cause rendering artifacts with EPSG:4326 on the globe.
|
|
270
|
+
// Add asymmetry to avoid this issue.
|
|
271
|
+
if (viewport.resolution && bounds) {
|
|
272
|
+
minLat = bounds[1];
|
|
273
|
+
maxLat = bounds[3]; // Check if latitude bounds are symmetric around 0° (within 0.1° tolerance)
|
|
274
|
+
if (Math.abs(minLat + maxLat) < 0.1 && Math.abs(minLat) > 1) {
|
|
275
|
+
bounds[3] += 0.1;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
srs = this.props.srs;
|
|
279
|
+
if (srs === 'auto') {
|
|
280
|
+
// BitmapLayer only supports LNGLAT or CARTESIAN (Web-Mercator)
|
|
281
|
+
srs = viewport.resolution ? 'EPSG:4326' : 'EPSG:3857';
|
|
282
|
+
}
|
|
283
|
+
requestParams = {
|
|
284
|
+
width: width,
|
|
285
|
+
height: height,
|
|
286
|
+
// TODO: remove bbox once deck.gl is upgraded to ^8.10 with loaders.gl ^4
|
|
287
|
+
bbox: bounds,
|
|
288
|
+
boundingBox: [[bounds[0], bounds[1]], [bounds[2], bounds[3]]],
|
|
289
|
+
layers: layers,
|
|
290
|
+
srs: srs,
|
|
291
|
+
transparent: transparent
|
|
292
|
+
};
|
|
293
|
+
if (srs === 'EPSG:3857') {
|
|
294
|
+
_WGS84ToPseudoMercato = WGS84ToPseudoMercator([bounds[0], bounds[1]]), _WGS84ToPseudoMercato2 = _slicedToArray(_WGS84ToPseudoMercato, 2), minX = _WGS84ToPseudoMercato2[0], minY = _WGS84ToPseudoMercato2[1];
|
|
295
|
+
_WGS84ToPseudoMercato3 = WGS84ToPseudoMercator([bounds[2], bounds[3]]), _WGS84ToPseudoMercato4 = _slicedToArray(_WGS84ToPseudoMercato3, 2), maxX = _WGS84ToPseudoMercato4[0], maxY = _WGS84ToPseudoMercato4[1];
|
|
296
|
+
requestParams.boundingBox = [[minX, minY], [maxX, maxY]];
|
|
297
|
+
// TODO: remove bbox once deck.gl is upgraded to ^8.10 with loaders.gl ^4
|
|
298
|
+
requestParams.bbox = [minX, minY, maxX, maxY];
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Skip request if parameters haven't meaningfully changed from an in-flight request
|
|
302
|
+
if (!(this.state.inFlightRequestParameters && this._areRequestParamsEqual(this.state.inFlightRequestParameters, requestParams))) {
|
|
303
|
+
_context3.next = 12;
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
return _context3.abrupt("return");
|
|
307
|
+
case 12:
|
|
308
|
+
if (!(this.state.lastRequestParameters && this._isViewCoveredByLastRequest(this.state.lastRequestParameters, requestParams))) {
|
|
309
|
+
_context3.next = 14;
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
return _context3.abrupt("return");
|
|
313
|
+
case 14:
|
|
314
|
+
// During video export, throttle zoom-in requests to only fire on zoom level crossings.
|
|
315
|
+
// The existing image is stretched by the BitmapLayer until the next level is reached.
|
|
316
|
+
// However, always allow requests if the new view isn't fully covered by the last image.
|
|
317
|
+
gl = this.context.gl;
|
|
318
|
+
isExporting = gl === null || gl === void 0 || (_gl$getContextAttribu2 = gl.getContextAttributes) === null || _gl$getContextAttribu2 === void 0 || (_gl$getContextAttribu2 = _gl$getContextAttribu2.call(gl)) === null || _gl$getContextAttribu2 === void 0 ? void 0 : _gl$getContextAttribu2.preserveDrawingBuffer;
|
|
319
|
+
if (!(isExporting && this.state._lastRequestZoom >= 0)) {
|
|
320
|
+
_context3.next = 26;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
currentZoom = viewport.zoom;
|
|
324
|
+
lastZoom = this.state._lastRequestZoom;
|
|
325
|
+
isZoomingIn = currentZoom > lastZoom; // Check if the new view is fully covered by the last loaded image
|
|
326
|
+
lastBbox = (_this$state$lastReque = this.state.lastRequestParameters) === null || _this$state$lastReque === void 0 ? void 0 : _this$state$lastReque.bbox;
|
|
327
|
+
currentBbox = requestParams.bbox;
|
|
328
|
+
fullyContained = false;
|
|
329
|
+
if (lastBbox && currentBbox) {
|
|
330
|
+
// New bbox must be fully inside the previous bbox
|
|
331
|
+
fullyContained = currentBbox[0] >= lastBbox[0] && currentBbox[1] >= lastBbox[1] && currentBbox[2] <= lastBbox[2] && currentBbox[3] <= lastBbox[3];
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Only throttle if:
|
|
335
|
+
// 1. Zooming in (not zooming out or panning at same zoom)
|
|
336
|
+
// 2. Same zoom floor (haven't crossed an integer zoom level)
|
|
337
|
+
// 3. New view is fully contained in the last loaded image (no uncovered areas)
|
|
338
|
+
if (!(isZoomingIn && Math.floor(currentZoom) === Math.floor(lastZoom) && fullyContained)) {
|
|
339
|
+
_context3.next = 26;
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
return _context3.abrupt("return");
|
|
343
|
+
case 26:
|
|
344
|
+
// Mark request as in-flight to prevent duplicate requests
|
|
345
|
+
this.state.inFlightRequestParameters = requestParams;
|
|
346
|
+
requestId = this.getRequestId();
|
|
347
|
+
_context3.prev = 28;
|
|
348
|
+
this.state.loadCounter++;
|
|
349
|
+
// Trigger a redraw to update the UI loading indicator
|
|
350
|
+
this.setNeedsRedraw();
|
|
351
|
+
this.props.onImageLoadStart(requestId);
|
|
352
|
+
_context3.next = 34;
|
|
353
|
+
return this.state.imageSource.getImage(requestParams);
|
|
354
|
+
case 34:
|
|
355
|
+
image = _context3.sent;
|
|
356
|
+
// If a request takes a long time, later requests may have already loaded.
|
|
357
|
+
if (this.state.lastRequestId < requestId) {
|
|
358
|
+
(_this$getCurrentLayer3 = this.getCurrentLayer()) === null || _this$getCurrentLayer3 === void 0 || _this$getCurrentLayer3.props.onImageLoad(requestId);
|
|
359
|
+
// Update lastRequestParameters only after successful load
|
|
360
|
+
// This ensures coverage checks only use successfully loaded images
|
|
361
|
+
this.state.lastRequestParameters = requestParams;
|
|
362
|
+
this.state._lastRequestZoom = viewport.zoom;
|
|
363
|
+
// Not type safe...
|
|
364
|
+
this.setState({
|
|
365
|
+
image: image,
|
|
366
|
+
bounds: bounds,
|
|
367
|
+
lastRequestId: requestId
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
_context3.next = 42;
|
|
371
|
+
break;
|
|
372
|
+
case 38:
|
|
373
|
+
_context3.prev = 38;
|
|
374
|
+
_context3.t0 = _context3["catch"](28);
|
|
375
|
+
(_this$context$onError = (_this$context = this.context).onError) === null || _this$context$onError === void 0 || _this$context$onError.call(_this$context, _context3.t0, this);
|
|
376
|
+
(_this$getCurrentLayer4 = this.getCurrentLayer()) === null || _this$getCurrentLayer4 === void 0 || _this$getCurrentLayer4.props.onImageLoadError(requestId, _context3.t0);
|
|
377
|
+
case 42:
|
|
378
|
+
_context3.prev = 42;
|
|
379
|
+
// Clear in-flight marker when request completes (success or error)
|
|
380
|
+
this.state.inFlightRequestParameters = undefined;
|
|
381
|
+
this.state.loadCounter--;
|
|
382
|
+
// Trigger a redraw to update the UI loading indicator
|
|
383
|
+
this.setNeedsRedraw();
|
|
384
|
+
return _context3.finish(42);
|
|
385
|
+
case 47:
|
|
386
|
+
case "end":
|
|
387
|
+
return _context3.stop();
|
|
388
|
+
}
|
|
389
|
+
}, _callee3, this, [[28, 38, 42, 47]]);
|
|
390
|
+
}));
|
|
391
|
+
function loadImage(_x3, _x4) {
|
|
392
|
+
return _loadImage.apply(this, arguments);
|
|
393
|
+
}
|
|
394
|
+
return loadImage;
|
|
395
|
+
}() // HELPERS
|
|
396
|
+
/** Global counter for issuing unique request ids */
|
|
397
|
+
)
|
|
398
|
+
}, {
|
|
399
|
+
key: "getRequestId",
|
|
400
|
+
value: function getRequestId() {
|
|
401
|
+
return this.state._nextRequestId++;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/** Runs an action in the future, cancels it if the new action is issued before it executes */
|
|
405
|
+
}, {
|
|
406
|
+
key: "debounce",
|
|
407
|
+
value: function debounce(fn) {
|
|
408
|
+
var ms = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 500;
|
|
409
|
+
clearTimeout(this.state._timeoutId);
|
|
410
|
+
this.state._timeoutId = setTimeout(function () {
|
|
411
|
+
return fn();
|
|
412
|
+
}, ms);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Returns true when the `next` view is fully inside the `prev` (last requested)
|
|
417
|
+
* extent AND not meaningfully higher resolution, so the cached image already
|
|
418
|
+
* covers the screen and no new request is needed.
|
|
419
|
+
*/
|
|
420
|
+
}, {
|
|
421
|
+
key: "_isViewCoveredByLastRequest",
|
|
422
|
+
value: function _isViewCoveredByLastRequest(prev, next) {
|
|
423
|
+
// Coverage only makes sense within the same projection / dataset / canvas size.
|
|
424
|
+
if (prev.srs !== next.srs || prev.width !== next.width || prev.height !== next.height || prev.transparent !== next.transparent || !deepEqual(prev.layers, next.layers)) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
var p = prev.bbox;
|
|
428
|
+
var n = next.bbox;
|
|
429
|
+
if (!p || !n) {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Is the new bbox fully contained within the previously requested bbox?
|
|
434
|
+
var contained = n[0] >= p[0] && n[1] >= p[1] && n[2] <= p[2] && n[3] <= p[3];
|
|
435
|
+
if (!contained) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Ground resolution is proportional to bbox span / pixel count. The guard
|
|
440
|
+
// above already ensured prev and next share the same width/height, so equal
|
|
441
|
+
// pixel counts let us compare spans directly. Only skip while the new view
|
|
442
|
+
// isn't much finer than what we already fetched, otherwise the cached image
|
|
443
|
+
// would look stretched/blurry.
|
|
444
|
+
var prevSpanX = p[2] - p[0];
|
|
445
|
+
var nextSpanX = n[2] - n[0];
|
|
446
|
+
var prevSpanY = p[3] - p[1];
|
|
447
|
+
var nextSpanY = n[3] - n[1];
|
|
448
|
+
return nextSpanX >= prevSpanX / COVERAGE_REFETCH_ZOOM_FACTOR && nextSpanY >= prevSpanY / COVERAGE_REFETCH_ZOOM_FACTOR;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** Compare request parameters to determine if a new request is needed */
|
|
452
|
+
}, {
|
|
453
|
+
key: "_areRequestParamsEqual",
|
|
454
|
+
value: function _areRequestParamsEqual(prev, next) {
|
|
455
|
+
// Compare dimensions
|
|
456
|
+
if (prev.width !== next.width || prev.height !== next.height) {
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Compare SRS
|
|
461
|
+
if (prev.srs !== next.srs) {
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Compare layers
|
|
466
|
+
if (!deepEqual(prev.layers, next.layers)) {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// Compare transparent
|
|
471
|
+
if (prev.transparent !== next.transparent) {
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Compare bounds with tolerance for floating point precision
|
|
476
|
+
var tolerance = 1e-10;
|
|
477
|
+
var prevBbox = prev.bbox;
|
|
478
|
+
var nextBbox = next.bbox;
|
|
479
|
+
if (prevBbox && nextBbox) {
|
|
480
|
+
for (var i = 0; i < 4; i++) {
|
|
481
|
+
if (Math.abs(prevBbox[i] - nextBbox[i]) > tolerance) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return true;
|
|
487
|
+
}
|
|
488
|
+
}]);
|
|
489
|
+
}(CompositeLayer);
|
|
490
|
+
/**
|
|
491
|
+
* Compute the [minLng, minLat, maxLng, maxLat] bounding box of the part of the
|
|
492
|
+
* globe that is actually visible on screen.
|
|
493
|
+
*
|
|
494
|
+
* Unlike `GlobeViewport.getBounds()` (4 edge midpoints), this samples a grid of
|
|
495
|
+
* screen pixels, unprojects each onto the sphere (deck.gl clamps rays that miss
|
|
496
|
+
* the globe to the silhouette/limb, which is exactly the boundary we want), and
|
|
497
|
+
* takes the extent. It additionally detects when a pole is in view: at a pole all
|
|
498
|
+
* meridians converge, so we widen the box to the full longitude range and extend
|
|
499
|
+
* the latitude up to the pole, which is what makes viewing from near a pole
|
|
500
|
+
* (seeing across to the far hemisphere) work.
|
|
501
|
+
*/
|
|
502
|
+
_defineProperty(WMSLayer, "layerName", 'WMSLayer');
|
|
503
|
+
_defineProperty(WMSLayer, "defaultProps", defaultProps);
|
|
504
|
+
export { WMSLayer as default };
|
|
505
|
+
export function getGlobeVisibleBounds(viewport) {
|
|
506
|
+
var _longitude;
|
|
507
|
+
var width = viewport.width,
|
|
508
|
+
height = viewport.height;
|
|
509
|
+
var centerLng = (_longitude = viewport.longitude) !== null && _longitude !== void 0 ? _longitude : 0;
|
|
510
|
+
var SAMPLES = 8; // 8x8 cells => 9x9 = 81 sample points
|
|
511
|
+
var lats = [];
|
|
512
|
+
// Longitudes tracked as signed offsets from the center longitude, unwrapped to
|
|
513
|
+
// (-180, 180], so an antimeridian-crossing view stays a contiguous range.
|
|
514
|
+
var lngOffsets = [];
|
|
515
|
+
for (var i = 0; i <= SAMPLES; i++) {
|
|
516
|
+
for (var j = 0; j <= SAMPLES; j++) {
|
|
517
|
+
var px = i / SAMPLES * width;
|
|
518
|
+
var py = j / SAMPLES * height;
|
|
519
|
+
var coord = viewport.unproject([px, py]);
|
|
520
|
+
var lng = coord[0];
|
|
521
|
+
var lat = coord[1];
|
|
522
|
+
if (!Number.isFinite(lng) || !Number.isFinite(lat)) {
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
lats.push(lat);
|
|
526
|
+
// Wrap the offset into (-180, 180].
|
|
527
|
+
var offset = (lng - centerLng + 540) % 360 - 180;
|
|
528
|
+
lngOffsets.push(offset);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Extremely degenerate viewport: fall back to deck's default.
|
|
533
|
+
if (lats.length === 0) {
|
|
534
|
+
return viewport.getBounds();
|
|
535
|
+
}
|
|
536
|
+
var minLat = Math.min.apply(Math, lats);
|
|
537
|
+
var maxLat = Math.max.apply(Math, lats);
|
|
538
|
+
var northPoleVisible = isGlobeSurfacePointVisible(viewport, 90);
|
|
539
|
+
var southPoleVisible = isGlobeSurfacePointVisible(viewport, -90);
|
|
540
|
+
var minLng;
|
|
541
|
+
var maxLng;
|
|
542
|
+
if (northPoleVisible || southPoleVisible) {
|
|
543
|
+
// A pole is on screen: every meridian is visible, so cover all longitudes and
|
|
544
|
+
// extend latitude up to the visible pole.
|
|
545
|
+
minLng = -180;
|
|
546
|
+
maxLng = 180;
|
|
547
|
+
if (northPoleVisible) {
|
|
548
|
+
maxLat = 90;
|
|
549
|
+
}
|
|
550
|
+
if (southPoleVisible) {
|
|
551
|
+
minLat = -90;
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
minLng = centerLng + Math.min.apply(Math, lngOffsets);
|
|
555
|
+
maxLng = centerLng + Math.max.apply(Math, lngOffsets);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Pad slightly so the discrete sampling doesn't clip the true limb.
|
|
559
|
+
var latPad = Math.min(5, (maxLat - minLat) * 0.05 + 0.5);
|
|
560
|
+
minLat = Math.max(-90, minLat - latPad);
|
|
561
|
+
maxLat = Math.min(90, maxLat + latPad);
|
|
562
|
+
if (maxLng - minLng < 360) {
|
|
563
|
+
var lngPad = Math.min(5, (maxLng - minLng) * 0.05 + 0.5);
|
|
564
|
+
minLng -= lngPad;
|
|
565
|
+
maxLng += lngPad;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// A single EPSG:4326 rectangle can't cross the antimeridian, so if the visible
|
|
569
|
+
// span wraps past ±180 (or covers the whole world) request the full longitude
|
|
570
|
+
// range. This over-covers only near the dateline, which is an acceptable
|
|
571
|
+
// trade-off for a valid, gap-free request.
|
|
572
|
+
if (maxLng - minLng >= 360 || minLng < -180 || maxLng > 180) {
|
|
573
|
+
minLng = -180;
|
|
574
|
+
maxLng = 180;
|
|
575
|
+
}
|
|
576
|
+
return [minLng, minLat, maxLng, maxLat];
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Whether a point on the globe surface at the given latitude (longitude is
|
|
581
|
+
* irrelevant at the poles) is both front-facing (not occluded by the globe) and
|
|
582
|
+
* inside the screen. Uses the sphere-horizon test in deck.gl common space:
|
|
583
|
+
* a surface point is front-facing when the angle between its outward normal and
|
|
584
|
+
* the camera direction is within the horizon half-angle, i.e.
|
|
585
|
+
* dot(normalize(pointCommon), normalize(cameraPosition)) >= radius / cameraDist
|
|
586
|
+
*/
|
|
587
|
+
function isGlobeSurfacePointVisible(viewport, lat) {
|
|
588
|
+
var width = viewport.width,
|
|
589
|
+
height = viewport.height;
|
|
590
|
+
var point = viewport.projectPosition([0, lat, 0]);
|
|
591
|
+
var camera = viewport.cameraPosition;
|
|
592
|
+
var rPoint = Math.hypot(point[0], point[1], point[2]);
|
|
593
|
+
var rCam = Math.hypot(camera[0], camera[1], camera[2]);
|
|
594
|
+
if (rPoint === 0 || rCam === 0 || rCam <= rPoint) {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
var cosSurface = (point[0] * camera[0] + point[1] * camera[1] + point[2] * camera[2]) / (rPoint * rCam);
|
|
598
|
+
var cosHorizon = rPoint / rCam;
|
|
599
|
+
if (cosSurface < cosHorizon) {
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
var screen = viewport.project([0, lat, 0]);
|
|
603
|
+
return screen[0] >= 0 && screen[0] <= width && screen[1] >= 0 && screen[1] <= height;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// https://epsg.io/3857
|
|
607
|
+
// +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs +type=crs
|
|
608
|
+
var HALF_EARTH_CIRCUMFERENCE = 6378137 * Math.PI;
|
|
609
|
+
|
|
610
|
+
/** Projects EPSG:4326 to EPSG:3857
|
|
611
|
+
* This is a lightweight replacement of proj4. Use tests to ensure conformance.
|
|
612
|
+
*/
|
|
613
|
+
export function WGS84ToPseudoMercator(coord) {
|
|
614
|
+
var mercator = lngLatToWorld(coord);
|
|
615
|
+
mercator[0] = (mercator[0] / 256 - 1) * HALF_EARTH_CIRCUMFERENCE;
|
|
616
|
+
mercator[1] = (mercator[1] / 256 - 1) * HALF_EARTH_CIRCUMFERENCE;
|
|
617
|
+
return mercator;
|
|
618
|
+
}
|
|
619
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJsbmdMYXRUb1dvcmxkIiwiQ29tcG9zaXRlTGF5ZXIiLCJDT09SRElOQVRFX1NZU1RFTSIsIl9kZWVwRXF1YWwiLCJkZWVwRXF1YWwiLCJCaXRtYXBMYXllciIsIkltYWdlU291cmNlIiwiV01TSW1hZ2VTb3VyY2UiLCJDT1ZFUkFHRV9SRUZFVENIX1pPT01fRkFDVE9SIiwiZGVmYXVsdFByb3BzIiwiaWQiLCJkYXRhIiwic2VydmljZVR5cGUiLCJzcnMiLCJsYXllcnMiLCJ0eXBlIiwiY29tcGFyZSIsInZhbHVlIiwib25NZXRhZGF0YUxvYWQiLCJvbk1ldGFkYXRhTG9hZEVycm9yIiwiY29uc29sZSIsImVycm9yIiwib25JbWFnZUxvYWRTdGFydCIsIm9uSW1hZ2VMb2FkIiwib25JbWFnZUxvYWRFcnJvciIsInJlcXVlc3RJZCIsIldNU0xheWVyIiwiX0NvbXBvc2l0ZUxheWVyIiwiX2NsYXNzQ2FsbENoZWNrIiwiX2NhbGxTdXBlciIsImFyZ3VtZW50cyIsIl9pbmhlcml0cyIsIl9jcmVhdGVDbGFzcyIsImtleSIsImdldCIsIkJvb2xlYW4iLCJzdGF0ZSIsImxvYWRDb3VudGVyIiwiX3N1cGVyUHJvcEdldCIsInNob3VsZFVwZGF0ZVN0YXRlIiwiaW5pdGlhbGl6ZVN0YXRlIiwiX25leHRSZXF1ZXN0SWQiLCJsYXN0UmVxdWVzdElkIiwiX2xhc3RSZXF1ZXN0Wm9vbSIsInVwZGF0ZVN0YXRlIiwiX3JlZiIsIl90aGlzIiwiY2hhbmdlRmxhZ3MiLCJwcm9wcyIsIm9sZFByb3BzIiwidmlld3BvcnQiLCJjb250ZXh0IiwiZGF0YUNoYW5nZWQiLCJpbWFnZVNvdXJjZSIsIl9jcmVhdGVJbWFnZVNvdXJjZSIsIl9sb2FkTWV0YWRhdGEiLCJkZWJvdW5jZSIsImxvYWRJbWFnZSIsInZpZXdwb3J0Q2hhbmdlZCIsIl9nbCRnZXRDb250ZXh0QXR0cmlidSIsImdsIiwiaXNQcmVzZXJ2aW5nQnVmZmVyIiwiZ2V0Q29udGV4dEF0dHJpYnV0ZXMiLCJjYWxsIiwicHJlc2VydmVEcmF3aW5nQnVmZmVyIiwiZGVib3VuY2VEZWxheSIsInVuZGVmaW5lZCIsInJlbmRlckxheWVycyIsIl90aGlzJHN0YXRlIiwiYm91bmRzIiwiaW1hZ2UiLCJsYXN0UmVxdWVzdFBhcmFtZXRlcnMiLCJfb2JqZWN0U3ByZWFkIiwiZ2V0U3ViTGF5ZXJQcm9wcyIsIl9pbWFnZUNvb3JkaW5hdGVTeXN0ZW0iLCJMTkdMQVQiLCJDQVJURVNJQU4iLCJwaWNrYWJsZSIsIl9nZXRGZWF0dXJlSW5mb1RleHQiLCJfYXN5bmNUb0dlbmVyYXRvciIsIl9yZWdlbmVyYXRvclJ1bnRpbWUiLCJtYXJrIiwiX2NhbGxlZSIsIngiLCJ5IiwiX3RoaXMkc3RhdGUkaW1hZ2VTb3VyIiwiX3RoaXMkc3RhdGUkaW1hZ2VTb3VyMiIsImZlYXR1cmVJbmZvIiwid3JhcCIsIl9jYWxsZWUkIiwiX2NvbnRleHQiLCJwcmV2IiwibmV4dCIsImdldEZlYXR1cmVJbmZvVGV4dCIsInF1ZXJ5X2xheWVycyIsImluZm9fZm9ybWF0Iiwic2VudCIsImFicnVwdCIsInN0b3AiLCJfeCIsIl94MiIsImFwcGx5IiwibG9hZE9wdGlvbnMiLCJFcnJvciIsIl9sb2FkTWV0YWRhdGEyIiwiX2NhbGxlZTIiLCJtZXRhZGF0YSIsIl90aGlzJGdldEN1cnJlbnRMYXllciIsIl90aGlzJGdldEN1cnJlbnRMYXllcjIiLCJfY2FsbGVlMiQiLCJfY29udGV4dDIiLCJnZXRNZXRhZGF0YSIsImdldEN1cnJlbnRMYXllciIsInQwIiwiZmluaXNoIiwiX2xvYWRJbWFnZSIsIl9jYWxsZWUzIiwiX3JlYXNvbiIsIl9nbCRnZXRDb250ZXh0QXR0cmlidTIiLCJfdGhpcyRwcm9wcyIsInRyYW5zcGFyZW50Iiwid2lkdGgiLCJoZWlnaHQiLCJtaW5MYXQiLCJtYXhMYXQiLCJyZXF1ZXN0UGFyYW1zIiwiX1dHUzg0VG9Qc2V1ZG9NZXJjYXRvIiwiX1dHUzg0VG9Qc2V1ZG9NZXJjYXRvMiIsIm1pblgiLCJtaW5ZIiwiX1dHUzg0VG9Qc2V1ZG9NZXJjYXRvMyIsIl9XR1M4NFRvUHNldWRvTWVyY2F0bzQiLCJtYXhYIiwibWF4WSIsImlzRXhwb3J0aW5nIiwiX3RoaXMkc3RhdGUkbGFzdFJlcXVlIiwiY3VycmVudFpvb20iLCJsYXN0Wm9vbSIsImlzWm9vbWluZ0luIiwibGFzdEJib3giLCJjdXJyZW50QmJveCIsImZ1bGx5Q29udGFpbmVkIiwiX3RoaXMkZ2V0Q3VycmVudExheWVyMyIsIl90aGlzJGNvbnRleHQkb25FcnJvciIsIl90aGlzJGNvbnRleHQiLCJfdGhpcyRnZXRDdXJyZW50TGF5ZXI0IiwiX2NhbGxlZTMkIiwiX2NvbnRleHQzIiwibGVuZ3RoIiwicmVzb2x1dGlvbiIsImdldEdsb2JlVmlzaWJsZUJvdW5kcyIsImdldEJvdW5kcyIsIk1hdGgiLCJhYnMiLCJiYm94IiwiYm91bmRpbmdCb3giLCJXR1M4NFRvUHNldWRvTWVyY2F0b3IiLCJfc2xpY2VkVG9BcnJheSIsImluRmxpZ2h0UmVxdWVzdFBhcmFtZXRlcnMiLCJfYXJlUmVxdWVzdFBhcmFtc0VxdWFsIiwiX2lzVmlld0NvdmVyZWRCeUxhc3RSZXF1ZXN0Iiwiem9vbSIsImZsb29yIiwiZ2V0UmVxdWVzdElkIiwic2V0TmVlZHNSZWRyYXciLCJnZXRJbWFnZSIsInNldFN0YXRlIiwib25FcnJvciIsIl94MyIsIl94NCIsImZuIiwibXMiLCJjbGVhclRpbWVvdXQiLCJfdGltZW91dElkIiwic2V0VGltZW91dCIsInAiLCJuIiwiY29udGFpbmVkIiwicHJldlNwYW5YIiwibmV4dFNwYW5YIiwicHJldlNwYW5ZIiwibmV4dFNwYW5ZIiwidG9sZXJhbmNlIiwicHJldkJib3giLCJuZXh0QmJveCIsImkiLCJfZGVmaW5lUHJvcGVydHkiLCJkZWZhdWx0IiwiX2xvbmdpdHVkZSIsImNlbnRlckxuZyIsImxvbmdpdHVkZSIsIlNBTVBMRVMiLCJsYXRzIiwibG5nT2Zmc2V0cyIsImoiLCJweCIsInB5IiwiY29vcmQiLCJ1bnByb2plY3QiLCJsbmciLCJsYXQiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsInB1c2giLCJvZmZzZXQiLCJtaW4iLCJtYXgiLCJub3J0aFBvbGVWaXNpYmxlIiwiaXNHbG9iZVN1cmZhY2VQb2ludFZpc2libGUiLCJzb3V0aFBvbGVWaXNpYmxlIiwibWluTG5nIiwibWF4TG5nIiwibGF0UGFkIiwibG5nUGFkIiwicG9pbnQiLCJwcm9qZWN0UG9zaXRpb24iLCJjYW1lcmEiLCJjYW1lcmFQb3NpdGlvbiIsInJQb2ludCIsImh5cG90IiwickNhbSIsImNvc1N1cmZhY2UiLCJjb3NIb3Jpem9uIiwic2NyZWVuIiwicHJvamVjdCIsIkhBTEZfRUFSVEhfQ0lSQ1VNRkVSRU5DRSIsIlBJIiwibWVyY2F0b3IiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd21zL3dtcy1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge2xuZ0xhdFRvV29ybGR9IGZyb20gJ0BtYXRoLmdsL3dlYi1tZXJjYXRvcic7XG5cbmltcG9ydCB7XG4gIExheWVyLFxuICBDb21wb3NpdGVMYXllcixcbiAgQ29tcG9zaXRlTGF5ZXJQcm9wcyxcbiAgVXBkYXRlUGFyYW1ldGVycyxcbiAgRGVmYXVsdFByb3BzLFxuICBWaWV3cG9ydCxcbiAgQ09PUkRJTkFURV9TWVNURU0sXG4gIF9kZWVwRXF1YWwgYXMgZGVlcEVxdWFsXG59IGZyb20gJ0BkZWNrLmdsL2NvcmUnO1xuaW1wb3J0IHtCaXRtYXBMYXllcn0gZnJvbSAnQGRlY2suZ2wvbGF5ZXJzJztcbmltcG9ydCB7SW1hZ2VTb3VyY2UsIFdNU0ltYWdlU291cmNlfSBmcm9tICdAbG9hZGVycy5nbC93bXMnO1xuXG5pbXBvcnQgdHlwZSB7SW1hZ2VTb3VyY2VNZXRhZGF0YX0gZnJvbSAnQGxvYWRlcnMuZ2wvbG9hZGVyLXV0aWxzJztcbmltcG9ydCB0eXBlIHtJbWFnZVR5cGV9IGZyb20gJ0Bsb2FkZXJzLmdsL3dtcyc7XG5cbi8vIFRPRE86IFRoaXMgaXMgYSBtb2RpZmllZCBjb3B5IG9mIFdNU0xheWVyIGZyb20gZGVjay5nbC4gUmVtb3ZlIHRoaXMgb25jZSB3ZSB1cGdyYWRlIGRlY2suZ2wgYW5kIGxvYWRlcnMuZ2wuXG5cbi8qKiBBbGwgcHJvcHMgc3VwcG9ydGVkIGJ5IHRoZSBUaWxlTGF5ZXIgKi9cbmV4cG9ydCB0eXBlIFdNU0xheWVyUHJvcHMgPSBDb21wb3NpdGVMYXllclByb3BzICYgX1dNU0xheWVyUHJvcHM7XG5cbi8qKiBQcm9wcyBhZGRlZCBieSB0aGUgVGlsZUxheWVyICovXG50eXBlIF9XTVNMYXllclByb3BzID0ge1xuICBkYXRhOiBzdHJpbmcgfCBJbWFnZVNvdXJjZTtcbiAgc2VydmljZVR5cGU/OiBzdHJpbmcgfCAnYXV0byc7XG4gIGxheWVycz86IHN0cmluZ1tdO1xuICBzcnM/OiAnRVBTRzo0MzI2JyB8ICdFUFNHOjM4NTcnIHwgJ2F1dG8nO1xuICB0cmFuc3BhcmVudD86IGJvb2xlYW47XG4gIG9uTWV0YWRhdGFMb2FkPzogKG1ldGFkYXRhOiBJbWFnZVNvdXJjZU1ldGFkYXRhKSA9PiB2b2lkO1xuICBvbk1ldGFkYXRhTG9hZEVycm9yPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZDtcbiAgb25JbWFnZUxvYWRTdGFydD86IChyZXF1ZXN0SWQ6IHVua25vd24pID0+IHZvaWQ7XG4gIG9uSW1hZ2VMb2FkPzogKHJlcXVlc3RJZDogdW5rbm93bikgPT4gdm9pZDtcbiAgb25JbWFnZUxvYWRFcnJvcj86IChyZXF1ZXN0SWQ6IHVua25vd24sIGVycm9yOiBFcnJvcikgPT4gdm9pZDtcbn07XG5cbi8qKlxuICogSG93IG11Y2ggdGhlIHVzZXIgbWF5IHpvb20gaW4gKHNocmlua2luZyB0aGUgdmlzaWJsZSBzcGFuKSBiZWZvcmUgYSB2aWV3IHRoYXRcbiAqIGlzIHN0aWxsIGNvbnRhaW5lZCBpbiB0aGUgbGFzdCByZXF1ZXN0ZWQgZXh0ZW50IHRyaWdnZXJzIGEgZnJlc2gsIGhpZ2hlclxuICogcmVzb2x1dGlvbiByZXF1ZXN0LiBgMmAgbWVhbnMgdGhlIGNhY2hlZCBpbWFnZSBtYXkgYmUgc3RyZXRjaGVkIHVwIHRvIH4yeFxuICogYmVmb3JlIHJlZmV0Y2hpbmc7IGhpZ2hlciB2YWx1ZXMgbWVhbiBmZXdlciByZXF1ZXN0cyBidXQgYmx1cnJpZXIgem9vbS1pbnMuXG4gKi9cbmNvbnN0IENPVkVSQUdFX1JFRkVUQ0hfWk9PTV9GQUNUT1IgPSAyO1xuXG5jb25zdCBkZWZhdWx0UHJvcHM6IERlZmF1bHRQcm9wczxXTVNMYXllclByb3BzPiA9IHtcbiAgaWQ6ICdpbWFnZXJ5LWxheWVyJyxcbiAgZGF0YTogJycsXG4gIHNlcnZpY2VUeXBlOiAnYXV0bycsXG4gIHNyczogJ2F1dG8nLFxuICBsYXllcnM6IHt0eXBlOiAnYXJyYXknLCBjb21wYXJlOiB0cnVlLCB2YWx1ZTogW119LFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIG9uTWV0YWRhdGFMb2FkOiB7dHlwZTogJ2Z1bmN0aW9uJywgdmFsdWU6ICgpID0+IHt9fSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIG9uTWV0YWRhdGFMb2FkRXJyb3I6IHt0eXBlOiAnZnVuY3Rpb24nLCB2YWx1ZTogY29uc29sZS5lcnJvcn0sXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgb25JbWFnZUxvYWRTdGFydDoge3R5cGU6ICdmdW5jdGlvbicsIHZhbHVlOiAoKSA9PiB7fX0sXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgb25JbWFnZUxvYWQ6IHt0eXBlOiAnZnVuY3Rpb24nLCB2YWx1ZTogKCkgPT4ge319LFxuICBvbkltYWdlTG9hZEVycm9yOiB7XG4gICAgdHlwZTogJ2Z1bmN0aW9uJyxcbiAgICBjb21wYXJlOiBmYWxzZSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICB2YWx1ZTogKHJlcXVlc3RJZDogdW5rbm93biwgZXJyb3I6IEVycm9yKSA9PiBjb25zb2xlLmVycm9yKGVycm9yLCByZXF1ZXN0SWQpXG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFdNU0xheWVyIGV4dGVuZHMgQ29tcG9zaXRlTGF5ZXI8UmVxdWlyZWQ8X1dNU0xheWVyUHJvcHM+PiB7XG4gIHN0YXRpYyBsYXllck5hbWUgPSAnV01TTGF5ZXInO1xuICBzdGF0aWMgZGVmYXVsdFByb3BzOiBEZWZhdWx0UHJvcHMgPSBkZWZhdWx0UHJvcHM7XG5cbiAgZGVjbGFyZSBzdGF0ZToge1xuICAgIGltYWdlU291cmNlOiBJbWFnZVNvdXJjZTtcbiAgICBpbWFnZTogSW1hZ2VUeXBlO1xuICAgIGJvdW5kczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgbGFzdFJlcXVlc3RQYXJhbWV0ZXJzOiB7XG4gICAgICAvLyBUT0RPOiByZW1vdmUgYmJveCBvbmNlIGRlY2suZ2wgaXMgdXBncmFkZWQgdG8gXjguMTAgd2l0aCBsb2FkZXJzLmdsIF40XG4gICAgICBiYm94OiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICAgIGJvdW5kaW5nQm94OiBbW251bWJlciwgbnVtYmVyXSwgW251bWJlciwgbnVtYmVyXV07XG4gICAgICBsYXllcnM6IHN0cmluZ1tdO1xuICAgICAgc3JzOiAnRVBTRzo0MzI2JyB8ICdFUFNHOjM4NTcnO1xuICAgICAgd2lkdGg6IG51bWJlcjtcbiAgICAgIGhlaWdodDogbnVtYmVyO1xuICAgIH07XG4gICAgaW5GbGlnaHRSZXF1ZXN0UGFyYW1ldGVycz86IHtcbiAgICAgIGJib3g6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgICAgYm91bmRpbmdCb3g6IFtbbnVtYmVyLCBudW1iZXJdLCBbbnVtYmVyLCBudW1iZXJdXTtcbiAgICAgIGxheWVyczogc3RyaW5nW107XG4gICAgICBzcnM6ICdFUFNHOjQzMjYnIHwgJ0VQU0c6Mzg1Nyc7XG4gICAgICB3aWR0aDogbnVtYmVyO1xuICAgICAgaGVpZ2h0OiBudW1iZXI7XG4gICAgfTtcbiAgICBsYXN0UmVxdWVzdElkOiBudW1iZXI7XG4gICAgX25leHRSZXF1ZXN0SWQ6IG51bWJlcjtcbiAgICAvKiogVE9ETzogQ2hhbmdlIGFueSA9PiBzZXRUaW1lb3V0IHJldHVybiB0eXBlLiBEaWZmZXJlbnQgYmV0d2VlbiBOb2RlIGFuZCBicm93c2VyLi4uICovXG4gICAgX3RpbWVvdXRJZDogYW55O1xuICAgIGxvYWRDb3VudGVyOiBudW1iZXI7XG4gICAgX2xhc3RSZXF1ZXN0Wm9vbTogbnVtYmVyO1xuICB9O1xuXG4gIC8qKiBSZXR1cm5zIHRydWUgaWYgYWxsIGFzeW5jIHJlc291cmNlcyBhcmUgbG9hZGVkICovXG4gIGdldCBpc0xvYWRlZCgpOiBib29sZWFuIHtcbiAgICAvLyBUcmFjayB0aGUgZXhwbGljaXQgbG9hZGluZyBkb25lIGJ5IHRoaXMgbGF5ZXJcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLnN0YXRlKSAmJiB0aGlzLnN0YXRlLmxvYWRDb3VudGVyID09PSAwICYmIHN1cGVyLmlzTG9hZGVkO1xuICB9XG5cbiAgLyoqIExldHMgZGVjay5nbCBrbm93IHRoYXQgd2Ugd2FudCB2aWV3cG9ydCBjaGFuZ2UgZXZlbnRzICovXG4gIG92ZXJyaWRlIHNob3VsZFVwZGF0ZVN0YXRlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgb3ZlcnJpZGUgaW5pdGlhbGl6ZVN0YXRlKCk6IHZvaWQge1xuICAgIC8vIGludGVudGlvbmFsbHkgZW1wdHksIGluaXRpYWxpemF0aW9uIGlzIGRvbmUgaW4gdXBkYXRlU3RhdGVcbiAgICB0aGlzLnN0YXRlLl9uZXh0UmVxdWVzdElkID0gMDtcbiAgICB0aGlzLnN0YXRlLmxhc3RSZXF1ZXN0SWQgPSAtMTtcbiAgICB0aGlzLnN0YXRlLmxvYWRDb3VudGVyID0gMDtcbiAgICB0aGlzLnN0YXRlLl9sYXN0UmVxdWVzdFpvb20gPSAtMTtcbiAgfVxuXG4gIG92ZXJyaWRlIHVwZGF0ZVN0YXRlKHtjaGFuZ2VGbGFncywgcHJvcHMsIG9sZFByb3BzfTogVXBkYXRlUGFyYW1ldGVyczx0aGlzPik6IHZvaWQge1xuICAgIGNvbnN0IHt2aWV3cG9ydH0gPSB0aGlzLmNvbnRleHQ7XG5cbiAgICAvLyBDaGVjayBpZiBkYXRhIHNvdXJjZSBoYXMgY2hhbmdlZFxuICAgIGlmIChjaGFuZ2VGbGFncy5kYXRhQ2hhbmdlZCB8fCBwcm9wcy5zZXJ2aWNlVHlwZSAhPT0gb2xkUHJvcHMuc2VydmljZVR5cGUpIHtcbiAgICAgIHRoaXMuc3RhdGUuaW1hZ2VTb3VyY2UgPSB0aGlzLl9jcmVhdGVJbWFnZVNvdXJjZShwcm9wcyk7XG5cbiAgICAgIHRoaXMuX2xvYWRNZXRhZGF0YSgpO1xuICAgICAgdGhpcy5kZWJvdW5jZSgoKSA9PiB0aGlzLmxvYWRJbWFnZSh2aWV3cG9ydCwgJ2ltYWdlIHNvdXJjZSBjaGFuZ2VkJyksIDApO1xuICAgIH0gZWxzZSBpZiAoIWRlZXBFcXVhbChwcm9wcy5sYXllcnMsIG9sZFByb3BzLmxheWVycywgMSkpIHtcbiAgICAgIHRoaXMuZGVib3VuY2UoKCkgPT4gdGhpcy5sb2FkSW1hZ2Uodmlld3BvcnQsICdsYXllcnMgY2hhbmdlZCcpLCAwKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZUZsYWdzLnZpZXdwb3J0Q2hhbmdlZCkge1xuICAgICAgLy8gQ2hlY2sgaWYgcHJlc2VydmVEcmF3aW5nQnVmZmVyIGlzIGVuYWJsZWQgKGluZGljYXRlcyB2aWRlbyByZWNvcmRpbmcgb3IgaW1hZ2UgZXhwb3J0KVxuICAgICAgLy8gVXNlIG1pbmltYWwgZGVib3VuY2UgKDEwbXMpIGR1cmluZyBleHBvcnQgZm9yIHJlc3BvbnNpdmUgZnJhbWUgY2FwdHVyZVxuICAgICAgLy8gUmVxdWVzdCBkZWR1cGxpY2F0aW9uIGluIGxvYWRJbWFnZSBwcmV2ZW50cyBzcGFtIGZyb20gcmVkdW5kYW50IHZpZXdwb3J0IHVwZGF0ZXNcbiAgICAgIGNvbnN0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuICAgICAgY29uc3QgaXNQcmVzZXJ2aW5nQnVmZmVyID0gZ2w/LmdldENvbnRleHRBdHRyaWJ1dGVzPy4oKT8ucHJlc2VydmVEcmF3aW5nQnVmZmVyO1xuXG4gICAgICBjb25zdCBkZWJvdW5jZURlbGF5ID0gaXNQcmVzZXJ2aW5nQnVmZmVyID8gMTAgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmRlYm91bmNlKCgpID0+IHRoaXMubG9hZEltYWdlKHZpZXdwb3J0LCAndmlld3BvcnQgY2hhbmdlZCcpLCBkZWJvdW5jZURlbGF5KTtcbiAgICB9XG4gIH1cblxuICBvdmVycmlkZSByZW5kZXJMYXllcnMoKTogTGF5ZXI8YW55PiB7XG4gICAgY29uc3Qge2JvdW5kcywgaW1hZ2UsIGxhc3RSZXF1ZXN0UGFyYW1ldGVyc30gPSB0aGlzLnN0YXRlO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIGltYWdlICYmXG4gICAgICBuZXcgQml0bWFwTGF5ZXIoe1xuICAgICAgICAuLi50aGlzLmdldFN1YkxheWVyUHJvcHMoe2lkOiAnYml0bWFwJ30pLFxuICAgICAgICBfaW1hZ2VDb29yZGluYXRlU3lzdGVtOlxuICAgICAgICAgIGxhc3RSZXF1ZXN0UGFyYW1ldGVycy5zcnMgPT09ICdFUFNHOjQzMjYnXG4gICAgICAgICAgICA/IENPT1JESU5BVEVfU1lTVEVNLkxOR0xBVFxuICAgICAgICAgICAgOiBDT09SRElOQVRFX1NZU1RFTS5DQVJURVNJQU4sXG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgaW1hZ2UsXG4gICAgICAgIHBpY2thYmxlOiB0aGlzLnByb3BzLnBpY2thYmxlXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBhc3luYyBnZXRGZWF0dXJlSW5mb1RleHQoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICBjb25zdCB7bGFzdFJlcXVlc3RQYXJhbWV0ZXJzfSA9IHRoaXMuc3RhdGU7XG4gICAgaWYgKGxhc3RSZXF1ZXN0UGFyYW1ldGVycykge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBVbmRvY3VtZW50ZWQgbWV0aG9kXG4gICAgICBjb25zdCBmZWF0dXJlSW5mbyA9IGF3YWl0IHRoaXMuc3RhdGUuaW1hZ2VTb3VyY2UuZ2V0RmVhdHVyZUluZm9UZXh0Py4oe1xuICAgICAgICAuLi5sYXN0UmVxdWVzdFBhcmFtZXRlcnMsXG4gICAgICAgIHF1ZXJ5X2xheWVyczogbGFzdFJlcXVlc3RQYXJhbWV0ZXJzLmxheWVycyxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgICAgaW5mb19mb3JtYXQ6ICdhcHBsaWNhdGlvbi92bmQub2djLmdtbCdcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGZlYXR1cmVJbmZvO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBfY3JlYXRlSW1hZ2VTb3VyY2UocHJvcHM6IFdNU0xheWVyUHJvcHMpOiBJbWFnZVNvdXJjZSB7XG4gICAgaWYgKHByb3BzLmRhdGEgaW5zdGFuY2VvZiBJbWFnZVNvdXJjZSkge1xuICAgICAgcmV0dXJuIHByb3BzLmRhdGE7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwcm9wcy5kYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIG5ldyBXTVNJbWFnZVNvdXJjZShwcm9wcy5kYXRhLCB7XG4gICAgICAgIGxvYWRPcHRpb25zOiBwcm9wcy5sb2FkT3B0aW9uc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGltYWdlIHNvdXJjZSBpbiBwcm9wcy5kYXRhJyk7XG4gIH1cblxuICAvKiogUnVuIGEgZ2V0TWV0YWRhdGEgb24gdGhlIGltYWdlIHNlcnZpY2UgKi9cbiAgYXN5bmMgX2xvYWRNZXRhZGF0YSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7aW1hZ2VTb3VyY2V9ID0gdGhpcy5zdGF0ZTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5zdGF0ZS5sb2FkQ291bnRlcisrO1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCBpbWFnZVNvdXJjZS5nZXRNZXRhZGF0YSgpO1xuXG4gICAgICAvLyBJZiBhIHJlcXVlc3QgdGFrZXMgYSBsb25nIHRpbWUsIGl0IG1heSBubyBsb25nZXIgYmUgZXhwZWN0ZWRcbiAgICAgIGlmICh0aGlzLnN0YXRlLmltYWdlU291cmNlID09PSBpbWFnZVNvdXJjZSkge1xuICAgICAgICB0aGlzLmdldEN1cnJlbnRMYXllcigpPy5wcm9wcy5vbk1ldGFkYXRhTG9hZChtZXRhZGF0YSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuZ2V0Q3VycmVudExheWVyKCk/LnByb3BzLm9uTWV0YWRhdGFMb2FkRXJyb3IoZXJyb3IgYXMgRXJyb3IpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnN0YXRlLmxvYWRDb3VudGVyLS07XG4gICAgfVxuICB9XG5cbiAgLyoqIExvYWQgYW4gaW1hZ2UgKi9cbiAgYXN5bmMgbG9hZEltYWdlKHZpZXdwb3J0OiBWaWV3cG9ydCwgX3JlYXNvbjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qge2xheWVycywgc2VydmljZVR5cGUsIHRyYW5zcGFyZW50fSA9IHRoaXMucHJvcHM7XG5cbiAgICAvLyBUT0RPIC0gbW92ZSB0byBJbWFnZVNvdXJjZT9cbiAgICBpZiAoc2VydmljZVR5cGUgPT09ICd3bXMnICYmIGxheWVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJbiBnbG9iZSBtb2RlIGRlY2sncyBHbG9iZVZpZXdwb3J0LmdldEJvdW5kcygpIG9ubHkgdW5wcm9qZWN0cyA0IGVkZ2VcbiAgICAvLyBtaWRwb2ludHMgYW5kIHRha2VzIHRoZWlyIG1pbi9tYXguIFRoYXQgbWlzc2VzIHRoZSBzY3JlZW4gY29ybmVycywgdGhlXG4gICAgLy8gY3VydmVkIGxpbWIsIGFuZCAobW9zdCBpbXBvcnRhbnRseSkgdGhlIGNhc2Ugd2hlcmUgYSBwb2xlIGlzIGluIHZpZXcgd2hlblxuICAgIC8vIGxvb2tpbmcgZnJvbSBhIGhpZ2ggbGF0aXR1ZGUg4oCUIHdoZXJlIGV2ZXJ5IG1lcmlkaWFuIGFuZCBwYXJ0IG9mIHRoZSBmYXJcbiAgICAvLyBoZW1pc3BoZXJlIGJlY29tZSB2aXNpYmxlLiBDb21wdXRlIGEgZnVsbGVyIHZpc2libGUgYm91bmRpbmcgYm94IGluc3RlYWQgc29cbiAgICAvLyB0aGUgcmVxdWVzdGVkIFdNUyBpbWFnZSBjb3ZlcnMgZXZlcnl0aGluZyBvbiBzY3JlZW4uXG4gICAgY29uc3QgYm91bmRzID0gdmlld3BvcnQucmVzb2x1dGlvblxuICAgICAgPyBnZXRHbG9iZVZpc2libGVCb3VuZHModmlld3BvcnQpXG4gICAgICA6IHZpZXdwb3J0LmdldEJvdW5kcygpO1xuICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHZpZXdwb3J0O1xuICAgIFxuICAgIC8vIEVkZ2UgY2FzZTogd2hlbiBib3VuZHMgYXJlIHBlcmZlY3RseSBzeW1tZXRyaWMgYXJvdW5kIDDCsCAoYm90aCBsb25naXR1ZGUgYW5kIGxhdGl0dWRlKSxcbiAgICAvLyBpdCBjYW4gY2F1c2UgcmVuZGVyaW5nIGFydGlmYWN0cyB3aXRoIEVQU0c6NDMyNiBvbiB0aGUgZ2xvYmUuXG4gICAgLy8gQWRkIGFzeW1tZXRyeSB0byBhdm9pZCB0aGlzIGlzc3VlLlxuICAgIGlmICh2aWV3cG9ydC5yZXNvbHV0aW9uICYmIGJvdW5kcykge1xuICAgICAgY29uc3QgbWluTGF0ID0gYm91bmRzWzFdO1xuICAgICAgY29uc3QgbWF4TGF0ID0gYm91bmRzWzNdO1xuICAgICAgLy8gQ2hlY2sgaWYgbGF0aXR1ZGUgYm91bmRzIGFyZSBzeW1tZXRyaWMgYXJvdW5kIDDCsCAod2l0aGluIDAuMcKwIHRvbGVyYW5jZSlcbiAgICAgIGlmIChNYXRoLmFicyhtaW5MYXQgKyBtYXhMYXQpIDwgMC4xICYmIE1hdGguYWJzKG1pbkxhdCkgPiAxKSB7XG4gICAgICAgIGJvdW5kc1szXSArPSAwLjE7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIGxldCB7c3JzfSA9IHRoaXMucHJvcHM7XG4gICAgaWYgKHNycyA9PT0gJ2F1dG8nKSB7XG4gICAgICAvLyBCaXRtYXBMYXllciBvbmx5IHN1cHBvcnRzIExOR0xBVCBvciBDQVJURVNJQU4gKFdlYi1NZXJjYXRvcilcbiAgICAgIHNycyA9IHZpZXdwb3J0LnJlc29sdXRpb24gPyAnRVBTRzo0MzI2JyA6ICdFUFNHOjM4NTcnO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0UGFyYW1zID0ge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICAvLyBUT0RPOiByZW1vdmUgYmJveCBvbmNlIGRlY2suZ2wgaXMgdXBncmFkZWQgdG8gXjguMTAgd2l0aCBsb2FkZXJzLmdsIF40XG4gICAgICBiYm94OiBib3VuZHMsXG4gICAgICBib3VuZGluZ0JveDogW1xuICAgICAgICBbYm91bmRzWzBdLCBib3VuZHNbMV1dLFxuICAgICAgICBbYm91bmRzWzJdLCBib3VuZHNbM11dXG4gICAgICBdIGFzIFtbbnVtYmVyLCBudW1iZXJdLCBbbnVtYmVyLCBudW1iZXJdXSxcbiAgICAgIGxheWVycyxcbiAgICAgIHNycyxcbiAgICAgIHRyYW5zcGFyZW50XG4gICAgfTtcbiAgICBpZiAoc3JzID09PSAnRVBTRzozODU3Jykge1xuICAgICAgY29uc3QgW21pblgsIG1pblldID0gV0dTODRUb1BzZXVkb01lcmNhdG9yKFtib3VuZHNbMF0sIGJvdW5kc1sxXV0pO1xuICAgICAgY29uc3QgW21heFgsIG1heFldID0gV0dTODRUb1BzZXVkb01lcmNhdG9yKFtib3VuZHNbMl0sIGJvdW5kc1szXV0pO1xuICAgICAgcmVxdWVzdFBhcmFtcy5ib3VuZGluZ0JveCA9IFtcbiAgICAgICAgW21pblgsIG1pblldLFxuICAgICAgICBbbWF4WCwgbWF4WV1cbiAgICAgIF07XG4gICAgICAvLyBUT0RPOiByZW1vdmUgYmJveCBvbmNlIGRlY2suZ2wgaXMgdXBncmFkZWQgdG8gXjguMTAgd2l0aCBsb2FkZXJzLmdsIF40XG4gICAgICByZXF1ZXN0UGFyYW1zLmJib3ggPSBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV07XG4gICAgfVxuXG4gICAgLy8gU2tpcCByZXF1ZXN0IGlmIHBhcmFtZXRlcnMgaGF2ZW4ndCBtZWFuaW5nZnVsbHkgY2hhbmdlZCBmcm9tIGFuIGluLWZsaWdodCByZXF1ZXN0XG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5pbkZsaWdodFJlcXVlc3RQYXJhbWV0ZXJzICYmXG4gICAgICB0aGlzLl9hcmVSZXF1ZXN0UGFyYW1zRXF1YWwodGhpcy5zdGF0ZS5pbkZsaWdodFJlcXVlc3RQYXJhbWV0ZXJzLCByZXF1ZXN0UGFyYW1zKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNraXAgcmVxdWVzdCBpZiB0aGUgbmV3IHZpZXcgaXMgYWxyZWFkeSBmdWxseSBjb3ZlcmVkIGJ5IHRoZSBsYXN0IENPTVBMRVRFRCByZXF1ZXN0XG4gICAgLy8gYXQgY29tcGFyYWJsZSByZXNvbHV0aW9uLiBUaGlzIGlzIHZlcnkgY29tbW9uIHdoaWxlIHBhbm5pbmcgKGFuZCBzbWFsbFxuICAgIC8vIHpvb20taW5zKSB3aXRoaW4gYSBsYXJnZXIsIHJlY2VudGx5IGZldGNoZWQgZXh0ZW50IOKAlCBlLmcuIG9uIHRoZSBnbG9iZSBhXG4gICAgLy8gc2luZ2xlIHJlcXVlc3QgY2FuIGNvdmVyIHRoZSB3aG9sZSB2aXNpYmxlIGhlbWlzcGhlcmUsIHNvIHJvdGF0aW5nIGFyb3VuZCBpdFxuICAgIC8vIHNob3VsZG4ndCBoaXQgdGhlIG5ldHdvcmsgYWdhaW4uIFRoZSBleGlzdGluZyBpbWFnZSBpcyBzaW1wbHkgcmVwb3NpdGlvbmVkIGJ5XG4gICAgLy8gdGhlIEJpdG1hcExheWVyLiBXZSBzdGlsbCByZWZldGNoIG9uY2UgdGhlIHVzZXIgem9vbXMgaW4gZW5vdWdoIHRoYXQgdGhlXG4gICAgLy8gY2FjaGVkIGltYWdlIHdvdWxkIGJlIHZpc2libHkgc3RyZXRjaGVkIChzZWUgQ09WRVJBR0VfUkVGRVRDSF9aT09NX0ZBQ1RPUikuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5sYXN0UmVxdWVzdFBhcmFtZXRlcnMgJiZcbiAgICAgIHRoaXMuX2lzVmlld0NvdmVyZWRCeUxhc3RSZXF1ZXN0KHRoaXMuc3RhdGUubGFzdFJlcXVlc3RQYXJhbWV0ZXJzLCByZXF1ZXN0UGFyYW1zKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIER1cmluZyB2aWRlbyBleHBvcnQsIHRocm90dGxlIHpvb20taW4gcmVxdWVzdHMgdG8gb25seSBmaXJlIG9uIHpvb20gbGV2ZWwgY3Jvc3NpbmdzLlxuICAgIC8vIFRoZSBleGlzdGluZyBpbWFnZSBpcyBzdHJldGNoZWQgYnkgdGhlIEJpdG1hcExheWVyIHVudGlsIHRoZSBuZXh0IGxldmVsIGlzIHJlYWNoZWQuXG4gICAgLy8gSG93ZXZlciwgYWx3YXlzIGFsbG93IHJlcXVlc3RzIGlmIHRoZSBuZXcgdmlldyBpc24ndCBmdWxseSBjb3ZlcmVkIGJ5IHRoZSBsYXN0IGltYWdlLlxuICAgIGNvbnN0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuICAgIGNvbnN0IGlzRXhwb3J0aW5nID0gZ2w/LmdldENvbnRleHRBdHRyaWJ1dGVzPy4oKT8ucHJlc2VydmVEcmF3aW5nQnVmZmVyO1xuICAgIFxuICAgIGlmIChpc0V4cG9ydGluZyAmJiB0aGlzLnN0YXRlLl9sYXN0UmVxdWVzdFpvb20gPj0gMCkge1xuICAgICAgY29uc3QgY3VycmVudFpvb20gPSB2aWV3cG9ydC56b29tO1xuICAgICAgY29uc3QgbGFzdFpvb20gPSB0aGlzLnN0YXRlLl9sYXN0UmVxdWVzdFpvb207XG4gICAgICBjb25zdCBpc1pvb21pbmdJbiA9IGN1cnJlbnRab29tID4gbGFzdFpvb207XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIHRoZSBuZXcgdmlldyBpcyBmdWxseSBjb3ZlcmVkIGJ5IHRoZSBsYXN0IGxvYWRlZCBpbWFnZVxuICAgICAgY29uc3QgbGFzdEJib3ggPSB0aGlzLnN0YXRlLmxhc3RSZXF1ZXN0UGFyYW1ldGVycz8uYmJveDtcbiAgICAgIGNvbnN0IGN1cnJlbnRCYm94ID0gcmVxdWVzdFBhcmFtcy5iYm94O1xuICAgICAgbGV0IGZ1bGx5Q29udGFpbmVkID0gZmFsc2U7XG4gICAgICBcbiAgICAgIGlmIChsYXN0QmJveCAmJiBjdXJyZW50QmJveCkge1xuICAgICAgICAvLyBOZXcgYmJveCBtdXN0IGJlIGZ1bGx5IGluc2lkZSB0aGUgcHJldmlvdXMgYmJveFxuICAgICAgICBmdWxseUNvbnRhaW5lZCA9IFxuICAgICAgICAgIGN1cnJlbnRCYm94WzBdID49IGxhc3RCYm94WzBdICYmIFxuICAgICAgICAgIGN1cnJlbnRCYm94WzFdID49IGxhc3RCYm94WzFdICYmIFxuICAgICAgICAgIGN1cnJlbnRCYm94WzJdIDw9IGxhc3RCYm94WzJdICYmIFxuICAgICAgICAgIGN1cnJlbnRCYm94WzNdIDw9IGxhc3RCYm94WzNdO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBPbmx5IHRocm90dGxlIGlmOlxuICAgICAgLy8gMS4gWm9vbWluZyBpbiAobm90IHpvb21pbmcgb3V0IG9yIHBhbm5pbmcgYXQgc2FtZSB6b29tKVxuICAgICAgLy8gMi4gU2FtZSB6b29tIGZsb29yIChoYXZlbid0IGNyb3NzZWQgYW4gaW50ZWdlciB6b29tIGxldmVsKVxuICAgICAgLy8gMy4gTmV3IHZpZXcgaXMgZnVsbHkgY29udGFpbmVkIGluIHRoZSBsYXN0IGxvYWRlZCBpbWFnZSAobm8gdW5jb3ZlcmVkIGFyZWFzKVxuICAgICAgaWYgKGlzWm9vbWluZ0luICYmIE1hdGguZmxvb3IoY3VycmVudFpvb20pID09PSBNYXRoLmZsb29yKGxhc3Rab29tKSAmJiBmdWxseUNvbnRhaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWFyayByZXF1ZXN0IGFzIGluLWZsaWdodCB0byBwcmV2ZW50IGR1cGxpY2F0ZSByZXF1ZXN0c1xuICAgIHRoaXMuc3RhdGUuaW5GbGlnaHRSZXF1ZXN0UGFyYW1ldGVycyA9IHJlcXVlc3RQYXJhbXM7XG5cbiAgICBjb25zdCByZXF1ZXN0SWQgPSB0aGlzLmdldFJlcXVlc3RJZCgpO1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnN0YXRlLmxvYWRDb3VudGVyKys7XG4gICAgICAvLyBUcmlnZ2VyIGEgcmVkcmF3IHRvIHVwZGF0ZSB0aGUgVUkgbG9hZGluZyBpbmRpY2F0b3JcbiAgICAgIHRoaXMuc2V0TmVlZHNSZWRyYXcoKTtcbiAgICAgIHRoaXMucHJvcHMub25JbWFnZUxvYWRTdGFydChyZXF1ZXN0SWQpO1xuXG4gICAgICBjb25zdCBpbWFnZSA9IGF3YWl0IHRoaXMuc3RhdGUuaW1hZ2VTb3VyY2UuZ2V0SW1hZ2UocmVxdWVzdFBhcmFtcyk7XG5cbiAgICAgIC8vIElmIGEgcmVxdWVzdCB0YWtlcyBhIGxvbmcgdGltZSwgbGF0ZXIgcmVxdWVzdHMgbWF5IGhhdmUgYWxyZWFkeSBsb2FkZWQuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5sYXN0UmVxdWVzdElkIDwgcmVxdWVzdElkKSB7XG4gICAgICAgIHRoaXMuZ2V0Q3VycmVudExheWVyKCk/LnByb3BzLm9uSW1hZ2VMb2FkKHJlcXVlc3RJZCk7XG4gICAgICAgIC8vIFVwZGF0ZSBsYXN0UmVxdWVzdFBhcmFtZXRlcnMgb25seSBhZnRlciBzdWNjZXNzZnVsIGxvYWRcbiAgICAgICAgLy8gVGhpcyBlbnN1cmVzIGNvdmVyYWdlIGNoZWNrcyBvbmx5IHVzZSBzdWNjZXNzZnVsbHkgbG9hZGVkIGltYWdlc1xuICAgICAgICB0aGlzLnN0YXRlLmxhc3RSZXF1ZXN0UGFyYW1ldGVycyA9IHJlcXVlc3RQYXJhbXM7XG4gICAgICAgIHRoaXMuc3RhdGUuX2xhc3RSZXF1ZXN0Wm9vbSA9IHZpZXdwb3J0Lnpvb207XG4gICAgICAgIC8vIE5vdCB0eXBlIHNhZmUuLi5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgaW1hZ2UsXG4gICAgICAgICAgYm91bmRzLFxuICAgICAgICAgIGxhc3RSZXF1ZXN0SWQ6IHJlcXVlc3RJZFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5jb250ZXh0Lm9uRXJyb3I/LihlcnJvciBhcyBFcnJvciwgdGhpcyk7XG4gICAgICB0aGlzLmdldEN1cnJlbnRMYXllcigpPy5wcm9wcy5vbkltYWdlTG9hZEVycm9yKHJlcXVlc3RJZCwgZXJyb3IgYXMgRXJyb3IpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAvLyBDbGVhciBpbi1mbGlnaHQgbWFya2VyIHdoZW4gcmVxdWVzdCBjb21wbGV0ZXMgKHN1Y2Nlc3Mgb3IgZXJyb3IpXG4gICAgICB0aGlzLnN0YXRlLmluRmxpZ2h0UmVxdWVzdFBhcmFtZXRlcnMgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnN0YXRlLmxvYWRDb3VudGVyLS07XG4gICAgICAvLyBUcmlnZ2VyIGEgcmVkcmF3IHRvIHVwZGF0ZSB0aGUgVUkgbG9hZGluZyBpbmRpY2F0b3JcbiAgICAgIHRoaXMuc2V0TmVlZHNSZWRyYXcoKTtcbiAgICB9XG4gIH1cblxuICAvLyBIRUxQRVJTXG5cbiAgLyoqIEdsb2JhbCBjb3VudGVyIGZvciBpc3N1aW5nIHVuaXF1ZSByZXF1ZXN0IGlkcyAqL1xuICBwcml2YXRlIGdldFJlcXVlc3RJZCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLl9uZXh0UmVxdWVzdElkKys7XG4gIH1cblxuICAvKiogUnVucyBhbiBhY3Rpb24gaW4gdGhlIGZ1dHVyZSwgY2FuY2VscyBpdCBpZiB0aGUgbmV3IGFjdGlvbiBpcyBpc3N1ZWQgYmVmb3JlIGl0IGV4ZWN1dGVzICovXG4gIHByaXZhdGUgZGVib3VuY2UoZm46ICgpID0+IHZvaWQsIG1zID0gNTAwKTogdm9pZCB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuc3RhdGUuX3RpbWVvdXRJZCk7XG4gICAgdGhpcy5zdGF0ZS5fdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiBmbigpLCBtcyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIHdoZW4gdGhlIGBuZXh0YCB2aWV3IGlzIGZ1bGx5IGluc2lkZSB0aGUgYHByZXZgIChsYXN0IHJlcXVlc3RlZClcbiAgICogZXh0ZW50IEFORCBub3QgbWVhbmluZ2Z1bGx5IGhpZ2hlciByZXNvbHV0aW9uLCBzbyB0aGUgY2FjaGVkIGltYWdlIGFscmVhZHlcbiAgICogY292ZXJzIHRoZSBzY3JlZW4gYW5kIG5vIG5ldyByZXF1ZXN0IGlzIG5lZWRlZC5cbiAgICovXG4gIHByaXZhdGUgX2lzVmlld0NvdmVyZWRCeUxhc3RSZXF1ZXN0KHByZXY6IGFueSwgbmV4dDogYW55KTogYm9vbGVhbiB7XG4gICAgLy8gQ292ZXJhZ2Ugb25seSBtYWtlcyBzZW5zZSB3aXRoaW4gdGhlIHNhbWUgcHJvamVjdGlvbiAvIGRhdGFzZXQgLyBjYW52YXMgc2l6ZS5cbiAgICBpZiAoXG4gICAgICBwcmV2LnNycyAhPT0gbmV4dC5zcnMgfHxcbiAgICAgIHByZXYud2lkdGggIT09IG5leHQud2lkdGggfHxcbiAgICAgIHByZXYuaGVpZ2h0ICE9PSBuZXh0LmhlaWdodCB8fFxuICAgICAgcHJldi50cmFuc3BhcmVudCAhPT0gbmV4dC50cmFuc3BhcmVudCB8fFxuICAgICAgIWRlZXBFcXVhbChwcmV2LmxheWVycywgbmV4dC5sYXllcnMpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgcCA9IHByZXYuYmJveDtcbiAgICBjb25zdCBuID0gbmV4dC5iYm94O1xuICAgIGlmICghcCB8fCAhbikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIElzIHRoZSBuZXcgYmJveCBmdWxseSBjb250YWluZWQgd2l0aGluIHRoZSBwcmV2aW91c2x5IHJlcXVlc3RlZCBiYm94P1xuICAgIGNvbnN0IGNvbnRhaW5lZCA9IG5bMF0gPj0gcFswXSAmJiBuWzFdID49IHBbMV0gJiYgblsyXSA8PSBwWzJdICYmIG5bM10gPD0gcFszXTtcbiAgICBcbiAgICBpZiAoIWNvbnRhaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEdyb3VuZCByZXNvbHV0aW9uIGlzIHByb3BvcnRpb25hbCB0byBiYm94IHNwYW4gLyBwaXhlbCBjb3VudC4gVGhlIGd1YXJkXG4gICAgLy8gYWJvdmUgYWxyZWFkeSBlbnN1cmVkIHByZXYgYW5kIG5leHQgc2hhcmUgdGhlIHNhbWUgd2lkdGgvaGVpZ2h0LCBzbyBlcXVhbFxuICAgIC8vIHBpeGVsIGNvdW50cyBsZXQgdXMgY29tcGFyZSBzcGFucyBkaXJlY3RseS4gT25seSBza2lwIHdoaWxlIHRoZSBuZXcgdmlld1xuICAgIC8vIGlzbid0IG11Y2ggZmluZXIgdGhhbiB3aGF0IHdlIGFscmVhZHkgZmV0Y2hlZCwgb3RoZXJ3aXNlIHRoZSBjYWNoZWQgaW1hZ2VcbiAgICAvLyB3b3VsZCBsb29rIHN0cmV0Y2hlZC9ibHVycnkuXG4gICAgY29uc3QgcHJldlNwYW5YID0gcFsyXSAtIHBbMF07XG4gICAgY29uc3QgbmV4dFNwYW5YID0gblsyXSAtIG5bMF07XG4gICAgY29uc3QgcHJldlNwYW5ZID0gcFszXSAtIHBbMV07XG4gICAgY29uc3QgbmV4dFNwYW5ZID0gblszXSAtIG5bMV07XG5cbiAgICByZXR1cm4gKFxuICAgICAgbmV4dFNwYW5YID49IHByZXZTcGFuWCAvIENPVkVSQUdFX1JFRkVUQ0hfWk9PTV9GQUNUT1IgJiZcbiAgICAgIG5leHRTcGFuWSA+PSBwcmV2U3BhblkgLyBDT1ZFUkFHRV9SRUZFVENIX1pPT01fRkFDVE9SXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBDb21wYXJlIHJlcXVlc3QgcGFyYW1ldGVycyB0byBkZXRlcm1pbmUgaWYgYSBuZXcgcmVxdWVzdCBpcyBuZWVkZWQgKi9cbiAgcHJpdmF0ZSBfYXJlUmVxdWVzdFBhcmFtc0VxdWFsKHByZXY6IGFueSwgbmV4dDogYW55KTogYm9vbGVhbiB7XG4gICAgLy8gQ29tcGFyZSBkaW1lbnNpb25zXG4gICAgaWYgKHByZXYud2lkdGggIT09IG5leHQud2lkdGggfHwgcHJldi5oZWlnaHQgIT09IG5leHQuaGVpZ2h0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ29tcGFyZSBTUlNcbiAgICBpZiAocHJldi5zcnMgIT09IG5leHQuc3JzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ29tcGFyZSBsYXllcnNcbiAgICBpZiAoIWRlZXBFcXVhbChwcmV2LmxheWVycywgbmV4dC5sYXllcnMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ29tcGFyZSB0cmFuc3BhcmVudFxuICAgIGlmIChwcmV2LnRyYW5zcGFyZW50ICE9PSBuZXh0LnRyYW5zcGFyZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ29tcGFyZSBib3VuZHMgd2l0aCB0b2xlcmFuY2UgZm9yIGZsb2F0aW5nIHBvaW50IHByZWNpc2lvblxuICAgIGNvbnN0IHRvbGVyYW5jZSA9IDFlLTEwO1xuICAgIGNvbnN0IHByZXZCYm94ID0gcHJldi5iYm94O1xuICAgIGNvbnN0IG5leHRCYm94ID0gbmV4dC5iYm94O1xuXG4gICAgaWYgKHByZXZCYm94ICYmIG5leHRCYm94KSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgICBpZiAoTWF0aC5hYnMocHJldkJib3hbaV0gLSBuZXh0QmJveFtpXSkgPiB0b2xlcmFuY2UpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vKipcbiAqIENvbXB1dGUgdGhlIFttaW5MbmcsIG1pbkxhdCwgbWF4TG5nLCBtYXhMYXRdIGJvdW5kaW5nIGJveCBvZiB0aGUgcGFydCBvZiB0aGVcbiAqIGdsb2JlIHRoYXQgaXMgYWN0dWFsbHkgdmlzaWJsZSBvbiBzY3JlZW4uXG4gKlxuICogVW5saWtlIGBHbG9iZVZpZXdwb3J0LmdldEJvdW5kcygpYCAoNCBlZGdlIG1pZHBvaW50cyksIHRoaXMgc2FtcGxlcyBhIGdyaWQgb2ZcbiAqIHNjcmVlbiBwaXhlbHMsIHVucHJvamVjdHMgZWFjaCBvbnRvIHRoZSBzcGhlcmUgKGRlY2suZ2wgY2xhbXBzIHJheXMgdGhhdCBtaXNzXG4gKiB0aGUgZ2xvYmUgdG8gdGhlIHNpbGhvdWV0dGUvbGltYiwgd2hpY2ggaXMgZXhhY3RseSB0aGUgYm91bmRhcnkgd2Ugd2FudCksIGFuZFxuICogdGFrZXMgdGhlIGV4dGVudC4gSXQgYWRkaXRpb25hbGx5IGRldGVjdHMgd2hlbiBhIHBvbGUgaXMgaW4gdmlldzogYXQgYSBwb2xlIGFsbFxuICogbWVyaWRpYW5zIGNvbnZlcmdlLCBzbyB3ZSB3aWRlbiB0aGUgYm94IHRvIHRoZSBmdWxsIGxvbmdpdHVkZSByYW5nZSBhbmQgZXh0ZW5kXG4gKiB0aGUgbGF0aXR1ZGUgdXAgdG8gdGhlIHBvbGUsIHdoaWNoIGlzIHdoYXQgbWFrZXMgdmlld2luZyBmcm9tIG5lYXIgYSBwb2xlXG4gKiAoc2VlaW5nIGFjcm9zcyB0byB0aGUgZmFyIGhlbWlzcGhlcmUpIHdvcmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbG9iZVZpc2libGVCb3VuZHModmlld3BvcnQ6IFZpZXdwb3J0KTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICBjb25zdCB7d2lkdGgsIGhlaWdodH0gPSB2aWV3cG9ydDtcbiAgY29uc3QgY2VudGVyTG5nID0gKHZpZXdwb3J0IGFzIGFueSkubG9uZ2l0dWRlID8/IDA7XG5cbiAgY29uc3QgU0FNUExFUyA9IDg7IC8vIDh4OCBjZWxscyA9PiA5eDkgPSA4MSBzYW1wbGUgcG9pbnRzXG4gIGNvbnN0IGxhdHM6IG51bWJlcltdID0gW107XG4gIC8vIExvbmdpdHVkZXMgdHJhY2tlZCBhcyBzaWduZWQgb2Zmc2V0cyBmcm9tIHRoZSBjZW50ZXIgbG9uZ2l0dWRlLCB1bndyYXBwZWQgdG9cbiAgLy8gKC0xODAsIDE4MF0sIHNvIGFuIGFudGltZXJpZGlhbi1jcm9zc2luZyB2aWV3IHN0YXlzIGEgY29udGlndW91cyByYW5nZS5cbiAgY29uc3QgbG5nT2Zmc2V0czogbnVtYmVyW10gPSBbXTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8PSBTQU1QTEVTOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8PSBTQU1QTEVTOyBqKyspIHtcbiAgICAgIGNvbnN0IHB4ID0gKGkgLyBTQU1QTEVTKSAqIHdpZHRoO1xuICAgICAgY29uc3QgcHkgPSAoaiAvIFNBTVBMRVMpICogaGVpZ2h0O1xuICAgICAgY29uc3QgY29vcmQgPSB2aWV3cG9ydC51bnByb2plY3QoW3B4LCBweV0pO1xuICAgICAgY29uc3QgbG5nID0gY29vcmRbMF07XG4gICAgICBjb25zdCBsYXQgPSBjb29yZFsxXTtcbiAgICAgIGlmICghTnVtYmVyLmlzRmluaXRlKGxuZykgfHwgIU51bWJlci5pc0Zpbml0ZShsYXQpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbGF0cy5wdXNoKGxhdCk7XG4gICAgICAvLyBXcmFwIHRoZSBvZmZzZXQgaW50byAoLTE4MCwgMTgwXS5cbiAgICAgIGNvbnN0IG9mZnNldCA9ICgobG5nIC0gY2VudGVyTG5nICsgNTQwKSAlIDM2MCkgLSAxODA7XG4gICAgICBsbmdPZmZzZXRzLnB1c2gob2Zmc2V0KTtcbiAgICB9XG4gIH1cblxuICAvLyBFeHRyZW1lbHkgZGVnZW5lcmF0ZSB2aWV3cG9ydDogZmFsbCBiYWNrIHRvIGRlY2sncyBkZWZhdWx0LlxuICBpZiAobGF0cy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gdmlld3BvcnQuZ2V0Qm91bmRzKCk7XG4gIH1cblxuICBsZXQgbWluTGF0ID0gTWF0aC5taW4oLi4ubGF0cyk7XG4gIGxldCBtYXhMYXQgPSBNYXRoLm1heCguLi5sYXRzKTtcblxuICBjb25zdCBub3J0aFBvbGVWaXNpYmxlID0gaXNHbG9iZVN1cmZhY2VQb2ludFZpc2libGUodmlld3BvcnQsIDkwKTtcbiAgY29uc3Qgc291dGhQb2xlVmlzaWJsZSA9IGlzR2xvYmVTdXJmYWNlUG9pbnRWaXNpYmxlKHZpZXdwb3J0LCAtOTApO1xuXG4gIGxldCBtaW5Mbmc6IG51bWJlcjtcbiAgbGV0IG1heExuZzogbnVtYmVyO1xuXG4gIGlmIChub3J0aFBvbGVWaXNpYmxlIHx8IHNvdXRoUG9sZVZpc2libGUpIHtcbiAgICAvLyBBIHBvbGUgaXMgb24gc2NyZWVuOiBldmVyeSBtZXJpZGlhbiBpcyB2aXNpYmxlLCBzbyBjb3ZlciBhbGwgbG9uZ2l0dWRlcyBhbmRcbiAgICAvLyBleHRlbmQgbGF0aXR1ZGUgdXAgdG8gdGhlIHZpc2libGUgcG9sZS5cbiAgICBtaW5MbmcgPSAtMTgwO1xuICAgIG1heExuZyA9IDE4MDtcbiAgICBpZiAobm9ydGhQb2xlVmlzaWJsZSkge1xuICAgICAgbWF4TGF0ID0gOTA7XG4gICAgfVxuICAgIGlmIChzb3V0aFBvbGVWaXNpYmxlKSB7XG4gICAgICBtaW5MYXQgPSAtOTA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG1pbkxuZyA9IGNlbnRlckxuZyArIE1hdGgubWluKC4uLmxuZ09mZnNldHMpO1xuICAgIG1heExuZyA9IGNlbnRlckxuZyArIE1hdGgubWF4KC4uLmxuZ09mZnNldHMpO1xuICB9XG5cbiAgLy8gUGFkIHNsaWdodGx5IHNvIHRoZSBkaXNjcmV0ZSBzYW1wbGluZyBkb2Vzbid0IGNsaXAgdGhlIHRydWUgbGltYi5cbiAgY29uc3QgbGF0UGFkID0gTWF0aC5taW4oNSwgKG1heExhdCAtIG1pbkxhdCkgKiAwLjA1ICsgMC41KTtcbiAgbWluTGF0ID0gTWF0aC5tYXgoLTkwLCBtaW5MYXQgLSBsYXRQYWQpO1xuICBtYXhMYXQgPSBNYXRoLm1pbig5MCwgbWF4TGF0ICsgbGF0UGFkKTtcblxuICBpZiAobWF4TG5nIC0gbWluTG5nIDwgMzYwKSB7XG4gICAgY29uc3QgbG5nUGFkID0gTWF0aC5taW4oNSwgKG1heExuZyAtIG1pbkxuZykgKiAwLjA1ICsgMC41KTtcbiAgICBtaW5MbmcgLT0gbG5nUGFkO1xuICAgIG1heExuZyArPSBsbmdQYWQ7XG4gIH1cblxuICAvLyBBIHNpbmdsZSBFUFNHOjQzMjYgcmVjdGFuZ2xlIGNhbid0IGNyb3NzIHRoZSBhbnRpbWVyaWRpYW4sIHNvIGlmIHRoZSB2aXNpYmxlXG4gIC8vIHNwYW4gd3JhcHMgcGFzdCDCsTE4MCAob3IgY292ZXJzIHRoZSB3aG9sZSB3b3JsZCkgcmVxdWVzdCB0aGUgZnVsbCBsb25naXR1ZGVcbiAgLy8gcmFuZ2UuIFRoaXMgb3Zlci1jb3ZlcnMgb25seSBuZWFyIHRoZSBkYXRlbGluZSwgd2hpY2ggaXMgYW4gYWNjZXB0YWJsZVxuICAvLyB0cmFkZS1vZmYgZm9yIGEgdmFsaWQsIGdhcC1mcmVlIHJlcXVlc3QuXG4gIGlmIChtYXhMbmcgLSBtaW5MbmcgPj0gMzYwIHx8IG1pbkxuZyA8IC0xODAgfHwgbWF4TG5nID4gMTgwKSB7XG4gICAgbWluTG5nID0gLTE4MDtcbiAgICBtYXhMbmcgPSAxODA7XG4gIH1cblxuICByZXR1cm4gW21pbkxuZywgbWluTGF0LCBtYXhMbmcsIG1heExhdF07XG59XG5cbi8qKlxuICogV2hldGhlciBhIHBvaW50IG9uIHRoZSBnbG9iZSBzdXJmYWNlIGF0IHRoZSBnaXZlbiBsYXRpdHVkZSAobG9uZ2l0dWRlIGlzXG4gKiBpcnJlbGV2YW50IGF0IHRoZSBwb2xlcykgaXMgYm90aCBmcm9udC1mYWNpbmcgKG5vdCBvY2NsdWRlZCBieSB0aGUgZ2xvYmUpIGFuZFxuICogaW5zaWRlIHRoZSBzY3JlZW4uIFVzZXMgdGhlIHNwaGVyZS1ob3Jpem9uIHRlc3QgaW4gZGVjay5nbCBjb21tb24gc3BhY2U6XG4gKiBhIHN1cmZhY2UgcG9pbnQgaXMgZnJvbnQtZmFjaW5nIHdoZW4gdGhlIGFuZ2xlIGJldHdlZW4gaXRzIG91dHdhcmQgbm9ybWFsIGFuZFxuICogdGhlIGNhbWVyYSBkaXJlY3Rpb24gaXMgd2l0aGluIHRoZSBob3Jpem9uIGhhbGYtYW5nbGUsIGkuZS5cbiAqICAgZG90KG5vcm1hbGl6ZShwb2ludENvbW1vbiksIG5vcm1hbGl6ZShjYW1lcmFQb3NpdGlvbikpID49IHJhZGl1cyAvIGNhbWVyYURpc3RcbiAqL1xuZnVuY3Rpb24gaXNHbG9iZVN1cmZhY2VQb2ludFZpc2libGUodmlld3BvcnQ6IFZpZXdwb3J0LCBsYXQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICBjb25zdCB7d2lkdGgsIGhlaWdodH0gPSB2aWV3cG9ydDtcbiAgY29uc3QgcG9pbnQgPSB2aWV3cG9ydC5wcm9qZWN0UG9zaXRpb24oWzAsIGxhdCwgMF0pO1xuICBjb25zdCBjYW1lcmEgPSB2aWV3cG9ydC5jYW1lcmFQb3NpdGlvbjtcblxuICBjb25zdCByUG9pbnQgPSBNYXRoLmh5cG90KHBvaW50WzBdLCBwb2ludFsxXSwgcG9pbnRbMl0pO1xuICBjb25zdCByQ2FtID0gTWF0aC5oeXBvdChjYW1lcmFbMF0sIGNhbWVyYVsxXSwgY2FtZXJhWzJdKTtcbiAgaWYgKHJQb2ludCA9PT0gMCB8fCByQ2FtID09PSAwIHx8IHJDYW0gPD0gclBvaW50KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgY29zU3VyZmFjZSA9XG4gICAgKHBvaW50WzBdICogY2FtZXJhWzBdICsgcG9pbnRbMV0gKiBjYW1lcmFbMV0gKyBwb2ludFsyXSAqIGNhbWVyYVsyXSkgLyAoclBvaW50ICogckNhbSk7XG4gIGNvbnN0IGNvc0hvcml6b24gPSByUG9pbnQgLyByQ2FtO1xuICBpZiAoY29zU3VyZmFjZSA8IGNvc0hvcml6b24pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBzY3JlZW4gPSB2aWV3cG9ydC5wcm9qZWN0KFswLCBsYXQsIDBdKTtcbiAgcmV0dXJuIHNjcmVlblswXSA+PSAwICYmIHNjcmVlblswXSA8PSB3aWR0aCAmJiBzY3JlZW5bMV0gPj0gMCAmJiBzY3JlZW5bMV0gPD0gaGVpZ2h0O1xufVxuXG4vLyBodHRwczovL2Vwc2cuaW8vMzg1N1xuLy8gK3Byb2o9bWVyYyArYT02Mzc4MTM3ICtiPTYzNzgxMzcgK2xhdF90cz0wICtsb25fMD0wICt4XzA9MCAreV8wPTAgK2s9MSArdW5pdHM9bSArbmFkZ3JpZHM9QG51bGwgK3drdGV4dCArbm9fZGVmcyArdHlwZT1jcnNcbmNvbnN0IEhBTEZfRUFSVEhfQ0lSQ1VNRkVSRU5DRSA9IDYzNzgxMzcgKiBNYXRoLlBJO1xuXG4vKiogUHJvamVjdHMgRVBTRzo0MzI2IHRvIEVQU0c6Mzg1N1xuICogVGhpcyBpcyBhIGxpZ2h0d2VpZ2h0IHJlcGxhY2VtZW50IG9mIHByb2o0LiBVc2UgdGVzdHMgdG8gZW5zdXJlIGNvbmZvcm1hbmNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gV0dTODRUb1BzZXVkb01lcmNhdG9yKGNvb3JkOiBbbnVtYmVyLCBudW1iZXJdKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IG1lcmNhdG9yID0gbG5nTGF0VG9Xb3JsZChjb29yZCk7XG4gIG1lcmNhdG9yWzBdID0gKG1lcmNhdG9yWzBdIC8gMjU2IC0gMSkgKiBIQUxGX0VBUlRIX0NJUkNVTUZFUkVOQ0U7XG4gIG1lcmNhdG9yWzFdID0gKG1lcmNhdG9yWzFdIC8gMjU2IC0gMSkgKiBIQUxGX0VBUlRIX0NJUkNVTUZFUkVOQ0U7XG4gIHJldHVybiBtZXJjYXRvcjtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTs7QUFFQSxTQUFRQSxhQUFhLFFBQU8sdUJBQXVCO0FBRW5ELFNBRUVDLGNBQWMsRUFLZEMsaUJBQWlCLEVBQ2pCQyxVQUFVLElBQUlDLFNBQVMsUUFDbEIsZUFBZTtBQUN0QixTQUFRQyxXQUFXLFFBQU8saUJBQWlCO0FBQzNDLFNBQVFDLFdBQVcsRUFBRUMsY0FBYyxRQUFPLGlCQUFpQjs7QUFLM0Q7O0FBRUE7O0FBR0E7O0FBY0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBTUMsNEJBQTRCLEdBQUcsQ0FBQztBQUV0QyxJQUFNQyxZQUF5QyxHQUFHO0VBQ2hEQyxFQUFFLEVBQUUsZUFBZTtFQUNuQkMsSUFBSSxFQUFFLEVBQUU7RUFDUkMsV0FBVyxFQUFFLE1BQU07RUFDbkJDLEdBQUcsRUFBRSxNQUFNO0VBQ1hDLE1BQU0sRUFBRTtJQUFDQyxJQUFJLEVBQUUsT0FBTztJQUFFQyxPQUFPLEVBQUUsSUFBSTtJQUFFQyxLQUFLLEVBQUU7RUFBRSxDQUFDO0VBQ2pEO0VBQ0FDLGNBQWMsRUFBRTtJQUFDSCxJQUFJLEVBQUUsVUFBVTtJQUFFRSxLQUFLLEVBQUUsU0FBUEEsS0FBS0EsQ0FBQSxFQUFRLENBQUM7RUFBQyxDQUFDO0VBQ25EO0VBQ0FFLG1CQUFtQixFQUFFO0lBQUNKLElBQUksRUFBRSxVQUFVO0lBQUVFLEtBQUssRUFBRUcsT0FBTyxDQUFDQztFQUFLLENBQUM7RUFDN0Q7RUFDQUMsZ0JBQWdCLEVBQUU7SUFBQ1AsSUFBSSxFQUFFLFVBQVU7SUFBRUUsS0FBSyxFQUFFLFNBQVBBLEtBQUtBLENBQUEsRUFBUSxDQUFDO0VBQUMsQ0FBQztFQUNyRDtFQUNBTSxXQUFXLEVBQUU7SUFBQ1IsSUFBSSxFQUFFLFVBQVU7SUFBRUUsS0FBSyxFQUFFLFNBQVBBLEtBQUtBLENBQUEsRUFBUSxDQUFDO0VBQUMsQ0FBQztFQUNoRE8sZ0JBQWdCLEVBQUU7SUFDaEJULElBQUksRUFBRSxVQUFVO0lBQ2hCQyxPQUFPLEVBQUUsS0FBSztJQUNkO0lBQ0FDLEtBQUssRUFBRSxTQUFQQSxLQUFLQSxDQUFHUSxTQUFrQixFQUFFSixLQUFZO01BQUEsT0FBS0QsT0FBTyxDQUFDQyxLQUFLLENBQUNBLEtBQUssRUFBRUksU0FBUyxDQUFDO0lBQUE7RUFDOUU7QUFDRixDQUFDO0FBQUMsSUFFbUJDLFFBQVEsMEJBQUFDLGVBQUE7RUFBQSxTQUFBRCxTQUFBO0lBQUFFLGVBQUEsT0FBQUYsUUFBQTtJQUFBLE9BQUFHLFVBQUEsT0FBQUgsUUFBQSxFQUFBSSxTQUFBO0VBQUE7RUFBQUMsU0FBQSxDQUFBTCxRQUFBLEVBQUFDLGVBQUE7RUFBQSxPQUFBSyxZQUFBLENBQUFOLFFBQUE7SUFBQU8sR0FBQTtJQUFBQyxHQUFBLEVBaUMzQjtJQUNBLFNBQUFBLElBQUEsRUFBd0I7TUFDdEI7TUFDQSxPQUFPQyxPQUFPLENBQUMsSUFBSSxDQUFDQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUNBLEtBQUssQ0FBQ0MsV0FBVyxLQUFLLENBQUMsSUFBQUMsYUFBQSxDQUFBWixRQUFBLHNCQUFrQjtJQUM5RTs7SUFFQTtFQUFBO0lBQUFPLEdBQUE7SUFBQWhCLEtBQUEsRUFDQSxTQUFTc0IsaUJBQWlCQSxDQUFBLEVBQVk7TUFDcEMsT0FBTyxJQUFJO0lBQ2I7RUFBQztJQUFBTixHQUFBO0lBQUFoQixLQUFBLEVBRUQsU0FBU3VCLGVBQWVBLENBQUEsRUFBUztNQUMvQjtNQUNBLElBQUksQ0FBQ0osS0FBSyxDQUFDSyxjQUFjLEdBQUcsQ0FBQztNQUM3QixJQUFJLENBQUNMLEtBQUssQ0FBQ00sYUFBYSxHQUFHLENBQUMsQ0FBQztNQUM3QixJQUFJLENBQUNOLEtBQUssQ0FBQ0MsV0FBVyxHQUFHLENBQUM7TUFDMUIsSUFBSSxDQUFDRCxLQUFLLENBQUNPLGdCQUFnQixHQUFHLENBQUMsQ0FBQztJQUNsQztFQUFDO0lBQUFWLEdBQUE7SUFBQWhCLEtBQUEsRUFFRCxTQUFTMkIsV0FBV0EsQ0FBQUMsSUFBQSxFQUErRDtNQUFBLElBQUFDLEtBQUE7TUFBQSxJQUE3REMsV0FBVyxHQUFBRixJQUFBLENBQVhFLFdBQVc7UUFBRUMsS0FBSyxHQUFBSCxJQUFBLENBQUxHLEtBQUs7UUFBRUMsUUFBUSxHQUFBSixJQUFBLENBQVJJLFFBQVE7TUFDaEQsSUFBT0MsUUFBUSxHQUFJLElBQUksQ0FBQ0MsT0FBTyxDQUF4QkQsUUFBUTs7TUFFZjtNQUNBLElBQUlILFdBQVcsQ0FBQ0ssV0FBVyxJQUFJSixLQUFLLENBQUNwQyxXQUFXLEtBQUtxQyxRQUFRLENBQUNyQyxXQUFXLEVBQUU7UUFDekUsSUFBSSxDQUFDd0IsS0FBSyxDQUFDaUIsV0FBVyxHQUFHLElBQUksQ0FBQ0Msa0JBQWtCLENBQUNOLEtBQUssQ0FBQztRQUV2RCxJQUFJLENBQUNPLGFBQWEsQ0FBQyxDQUFDO1FBQ3BCLElBQUksQ0FBQ0MsUUFBUSxDQUFDO1VBQUEsT0FBTVYsS0FBSSxDQUFDVyxTQUFTLENBQUNQLFFBQVEsRUFBRSxzQkFBc0IsQ0FBQztRQUFBLEdBQUUsQ0FBQyxDQUFDO01BQzFFLENBQUMsTUFBTSxJQUFJLENBQUM5QyxTQUFTLENBQUM0QyxLQUFLLENBQUNsQyxNQUFNLEVBQUVtQyxRQUFRLENBQUNuQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUU7UUFDdkQsSUFBSSxDQUFDMEMsUUFBUSxDQUFDO1VBQUEsT0FBTVYsS0FBSSxDQUFDVyxTQUFTLENBQUNQLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQztRQUFBLEdBQUUsQ0FBQyxDQUFDO01BQ3BFLENBQUMsTUFBTSxJQUFJSCxXQUFXLENBQUNXLGVBQWUsRUFBRTtRQUFBLElBQUFDLHFCQUFBO1FBQ3RDO1FBQ0E7UUFDQTtRQUNBLElBQU1DLEVBQUUsR0FBRyxJQUFJLENBQUNULE9BQU8sQ0FBQ1MsRUFBRTtRQUMxQixJQUFNQyxrQkFBa0IsR0FBR0QsRUFBRSxhQUFGQSxFQUFFLGdCQUFBRCxxQkFBQSxHQUFGQyxFQUFFLENBQUVFLG9CQUFvQixjQUFBSCxxQkFBQSxnQkFBQUEscUJBQUEsR0FBeEJBLHFCQUFBLENBQUFJLElBQUEsQ0FBQUgsRUFBMkIsQ0FBQyxjQUFBRCxxQkFBQSx1QkFBNUJBLHFCQUFBLENBQThCSyxxQkFBcUI7UUFFOUUsSUFBTUMsYUFBYSxHQUFHSixrQkFBa0IsR0FBRyxFQUFFLEdBQUdLLFNBQVM7UUFDekQsSUFBSSxDQUFDVixRQUFRLENBQUM7VUFBQSxPQUFNVixLQUFJLENBQUNXLFNBQVMsQ0FBQ1AsUUFBUSxFQUFFLGtCQUFrQixDQUFDO1FBQUEsR0FBRWUsYUFBYSxDQUFDO01BQ2xGO0lBQ0Y7RUFBQztJQUFBaEMsR0FBQTtJQUFBaEIsS0FBQSxFQUVELFNBQVNrRCxZQUFZQSxDQUFBLEVBQWU7TUFDbEMsSUFBQUMsV0FBQSxHQUErQyxJQUFJLENBQUNoQyxLQUFLO1FBQWxEaUMsTUFBTSxHQUFBRCxXQUFBLENBQU5DLE1BQU07UUFBRUMsS0FBSyxHQUFBRixXQUFBLENBQUxFLEtBQUs7UUFBRUMscUJBQXFCLEdBQUFILFdBQUEsQ0FBckJHLHFCQUFxQjtNQUUzQyxPQUNFRCxLQUFLLElBQ0wsSUFBSWpFLFdBQVcsQ0FBQW1FLGFBQUEsQ0FBQUEsYUFBQSxLQUNWLElBQUksQ0FBQ0MsZ0JBQWdCLENBQUM7UUFBQy9ELEVBQUUsRUFBRTtNQUFRLENBQUMsQ0FBQztRQUN4Q2dFLHNCQUFzQixFQUNwQkgscUJBQXFCLENBQUMxRCxHQUFHLEtBQUssV0FBVyxHQUNyQ1gsaUJBQWlCLENBQUN5RSxNQUFNLEdBQ3hCekUsaUJBQWlCLENBQUMwRSxTQUFTO1FBQ2pDUCxNQUFNLEVBQU5BLE1BQU07UUFDTkMsS0FBSyxFQUFMQSxLQUFLO1FBQ0xPLFFBQVEsRUFBRSxJQUFJLENBQUM3QixLQUFLLENBQUM2QjtNQUFRLEVBQzlCLENBQUM7SUFFTjtFQUFDO0lBQUE1QyxHQUFBO0lBQUFoQixLQUFBO01BQUEsSUFBQTZELG1CQUFBLEdBQUFDLGlCQUFBLGNBQUFDLG1CQUFBLENBQUFDLElBQUEsQ0FFRCxTQUFBQyxRQUF5QkMsQ0FBUyxFQUFFQyxDQUFTO1FBQUEsSUFBQWIscUJBQUEsRUFBQWMscUJBQUEsRUFBQUMsc0JBQUEsRUFBQUMsV0FBQTtRQUFBLE9BQUFQLG1CQUFBLENBQUFRLElBQUEsVUFBQUMsU0FBQUMsUUFBQTtVQUFBLGtCQUFBQSxRQUFBLENBQUFDLElBQUEsR0FBQUQsUUFBQSxDQUFBRSxJQUFBO1lBQUE7Y0FDcENyQixxQkFBcUIsR0FBSSxJQUFJLENBQUNuQyxLQUFLLENBQW5DbUMscUJBQXFCO2NBQUEsS0FDeEJBLHFCQUFxQjtnQkFBQW1CLFFBQUEsQ0FBQUUsSUFBQTtnQkFBQTtjQUFBO2NBQUFGLFFBQUEsQ0FBQUUsSUFBQTtjQUFBLFFBQUFQLHFCQUFBLEdBRUcsQ0FBQUMsc0JBQUEsT0FBSSxDQUFDbEQsS0FBSyxDQUFDaUIsV0FBVyxFQUFDd0Msa0JBQWtCLGNBQUFSLHFCQUFBLHVCQUF6Q0EscUJBQUEsQ0FBQXRCLElBQUEsQ0FBQXVCLHNCQUFBLEVBQUFkLGFBQUEsQ0FBQUEsYUFBQSxLQUNyQkQscUJBQXFCO2dCQUN4QnVCLFlBQVksRUFBRXZCLHFCQUFxQixDQUFDekQsTUFBTTtnQkFDMUNxRSxDQUFDLEVBQURBLENBQUM7Z0JBQ0RDLENBQUMsRUFBREEsQ0FBQztnQkFDRFcsV0FBVyxFQUFFO2NBQXlCLEVBQ3ZDLENBQUM7WUFBQTtjQU5JUixXQUFXLEdBQUFHLFFBQUEsQ0FBQU0sSUFBQTtjQUFBLE9BQUFOLFFBQUEsQ0FBQU8sTUFBQSxXQU9WVixXQUFXO1lBQUE7Y0FBQSxPQUFBRyxRQUFBLENBQUFPLE1BQUEsV0FFYixFQUFFO1lBQUE7WUFBQTtjQUFBLE9BQUFQLFFBQUEsQ0FBQVEsSUFBQTtVQUFBO1FBQUEsR0FBQWhCLE9BQUE7TUFBQSxDQUNWO01BQUEsU0FkS1csa0JBQWtCQSxDQUFBTSxFQUFBLEVBQUFDLEdBQUE7UUFBQSxPQUFBdEIsbUJBQUEsQ0FBQXVCLEtBQUEsT0FBQXZFLFNBQUE7TUFBQTtNQUFBLE9BQWxCK0Qsa0JBQWtCO0lBQUE7RUFBQTtJQUFBNUQsR0FBQTtJQUFBaEIsS0FBQSxFQWdCeEIsU0FBQXFDLGtCQUFrQkEsQ0FBQ04sS0FBb0IsRUFBZTtNQUNwRCxJQUFJQSxLQUFLLENBQUNyQyxJQUFJLFlBQVlMLFdBQVcsRUFBRTtRQUNyQyxPQUFPMEMsS0FBSyxDQUFDckMsSUFBSTtNQUNuQjtNQUVBLElBQUksT0FBT3FDLEtBQUssQ0FBQ3JDLElBQUksS0FBSyxRQUFRLEVBQUU7UUFDbEMsT0FBTyxJQUFJSixjQUFjLENBQUN5QyxLQUFLLENBQUNyQyxJQUFJLEVBQUU7VUFDcEMyRixXQUFXLEVBQUV0RCxLQUFLLENBQUNzRDtRQUNyQixDQUFDLENBQUM7TUFDSjtNQUVBLE1BQU0sSUFBSUMsS0FBSyxDQUFDLG9DQUFvQyxDQUFDO0lBQ3ZEOztJQUVBO0VBQUE7SUFBQXRFLEdBQUE7SUFBQWhCLEtBQUE7TUFBQSxJQUFBdUYsY0FBQSxHQUFBekIsaUJBQUEsY0FBQUMsbUJBQUEsQ0FBQUMsSUFBQSxDQUNBLFNBQUF3QixTQUFBO1FBQUEsSUFBQXBELFdBQUEsRUFBQXFELFFBQUEsRUFBQUMscUJBQUEsRUFBQUMsc0JBQUE7UUFBQSxPQUFBNUIsbUJBQUEsQ0FBQVEsSUFBQSxVQUFBcUIsVUFBQUMsU0FBQTtVQUFBLGtCQUFBQSxTQUFBLENBQUFuQixJQUFBLEdBQUFtQixTQUFBLENBQUFsQixJQUFBO1lBQUE7Y0FDU3ZDLFdBQVcsR0FBSSxJQUFJLENBQUNqQixLQUFLLENBQXpCaUIsV0FBVztjQUFBeUQsU0FBQSxDQUFBbkIsSUFBQTtjQUVoQixJQUFJLENBQUN2RCxLQUFLLENBQUNDLFdBQVcsRUFBRTtjQUFDeUUsU0FBQSxDQUFBbEIsSUFBQTtjQUFBLE9BQ0Z2QyxXQUFXLENBQUMwRCxXQUFXLENBQUMsQ0FBQztZQUFBO2NBQTFDTCxRQUFRLEdBQUFJLFNBQUEsQ0FBQWQsSUFBQTtjQUVkO2NBQ0EsSUFBSSxJQUFJLENBQUM1RCxLQUFLLENBQUNpQixXQUFXLEtBQUtBLFdBQVcsRUFBRTtnQkFDMUMsQ0FBQXNELHFCQUFBLE9BQUksQ0FBQ0ssZUFBZSxDQUFDLENBQUMsY0FBQUwscUJBQUEsZUFBdEJBLHFCQUFBLENBQXdCM0QsS0FBSyxDQUFDOUIsY0FBYyxDQUFDd0YsUUFBUSxDQUFDO2NBQ3hEO2NBQUNJLFNBQUEsQ0FBQWxCLElBQUE7Y0FBQTtZQUFBO2NBQUFrQixTQUFBLENBQUFuQixJQUFBO2NBQUFtQixTQUFBLENBQUFHLEVBQUEsR0FBQUgsU0FBQTtjQUVELENBQUFGLHNCQUFBLE9BQUksQ0FBQ0ksZUFBZSxDQUFDLENBQUMsY0FBQUosc0JBQUEsZUFBdEJBLHNCQUFBLENBQXdCNUQsS0FBSyxDQUFDN0IsbUJBQW1CLENBQUEyRixTQUFBLENBQUFHLEVBQWUsQ0FBQztZQUFDO2NBQUFILFNBQUEsQ0FBQW5CLElBQUE7Y0FFbEUsSUFBSSxDQUFDdkQsS0FBSyxDQUFDQyxXQUFXLEVBQUU7Y0FBQyxPQUFBeUUsU0FBQSxDQUFBSSxNQUFBO1lBQUE7WUFBQTtjQUFBLE9BQUFKLFNBQUEsQ0FBQVosSUFBQTtVQUFBO1FBQUEsR0FBQU8sUUFBQTtNQUFBLENBRTVCO01BQUEsU0FmS2xELGFBQWFBLENBQUE7UUFBQSxPQUFBaUQsY0FBQSxDQUFBSCxLQUFBLE9BQUF2RSxTQUFBO01BQUE7TUFBQSxPQUFieUIsYUFBYTtJQUFBLElBaUJuQjtFQUFBO0lBQUF0QixHQUFBO0lBQUFoQixLQUFBO01BQUEsSUFBQWtHLFVBQUEsR0FBQXBDLGlCQUFBLGNBQUFDLG1CQUFBLENBQUFDLElBQUEsQ0FDQSxTQUFBbUMsU0FBZ0JsRSxRQUFrQixFQUFFbUUsT0FBZTtRQUFBLElBQUFDLHNCQUFBO1FBQUEsSUFBQUMsV0FBQSxFQUFBekcsTUFBQSxFQUFBRixXQUFBLEVBQUE0RyxXQUFBLEVBQUFuRCxNQUFBLEVBQUFvRCxLQUFBLEVBQUFDLE1BQUEsRUFBQUMsTUFBQSxFQUFBQyxNQUFBLEVBQUEvRyxHQUFBLEVBQUFnSCxhQUFBLEVBQUFDLHFCQUFBLEVBQUFDLHNCQUFBLEVBQUFDLElBQUEsRUFBQUMsSUFBQSxFQUFBQyxzQkFBQSxFQUFBQyxzQkFBQSxFQUFBQyxJQUFBLEVBQUFDLElBQUEsRUFBQXpFLEVBQUEsRUFBQTBFLFdBQUEsRUFBQUMscUJBQUEsRUFBQUMsV0FBQSxFQUFBQyxRQUFBLEVBQUFDLFdBQUEsRUFBQUMsUUFBQSxFQUFBQyxXQUFBLEVBQUFDLGNBQUEsRUFBQXBILFNBQUEsRUFBQTZDLEtBQUEsRUFBQXdFLHNCQUFBLEVBQUFDLHFCQUFBLEVBQUFDLGFBQUEsRUFBQUMsc0JBQUE7UUFBQSxPQUFBakUsbUJBQUEsQ0FBQVEsSUFBQSxVQUFBMEQsVUFBQUMsU0FBQTtVQUFBLGtCQUFBQSxTQUFBLENBQUF4RCxJQUFBLEdBQUF3RCxTQUFBLENBQUF2RCxJQUFBO1lBQUE7Y0FBQTJCLFdBQUEsR0FDTixJQUFJLENBQUN2RSxLQUFLLEVBQTlDbEMsTUFBTSxHQUFBeUcsV0FBQSxDQUFOekcsTUFBTSxFQUFFRixXQUFXLEdBQUEyRyxXQUFBLENBQVgzRyxXQUFXLEVBQUU0RyxXQUFXLEdBQUFELFdBQUEsQ0FBWEMsV0FBVyxFQUV2QztjQUFBLE1BQ0k1RyxXQUFXLEtBQUssS0FBSyxJQUFJRSxNQUFNLENBQUNzSSxNQUFNLEtBQUssQ0FBQztnQkFBQUQsU0FBQSxDQUFBdkQsSUFBQTtnQkFBQTtjQUFBO2NBQUEsT0FBQXVELFNBQUEsQ0FBQWxELE1BQUE7WUFBQTtjQUloRDtjQUNBO2NBQ0E7Y0FDQTtjQUNBO2NBQ0E7Y0FDTTVCLE1BQU0sR0FBR25CLFFBQVEsQ0FBQ21HLFVBQVUsR0FDOUJDLHFCQUFxQixDQUFDcEcsUUFBUSxDQUFDLEdBQy9CQSxRQUFRLENBQUNxRyxTQUFTLENBQUMsQ0FBQztjQUNqQjlCLEtBQUssR0FBWXZFLFFBQVEsQ0FBekJ1RSxLQUFLLEVBQUVDLE1BQU0sR0FBSXhFLFFBQVEsQ0FBbEJ3RSxNQUFNLEVBRXBCO2NBQ0E7Y0FDQTtjQUNBLElBQUl4RSxRQUFRLENBQUNtRyxVQUFVLElBQUloRixNQUFNLEVBQUU7Z0JBQzNCc0QsTUFBTSxHQUFHdEQsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDbEJ1RCxNQUFNLEdBQUd2RCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ3hCO2dCQUNBLElBQUltRixJQUFJLENBQUNDLEdBQUcsQ0FBQzlCLE1BQU0sR0FBR0MsTUFBTSxDQUFDLEdBQUcsR0FBRyxJQUFJNEIsSUFBSSxDQUFDQyxHQUFHLENBQUM5QixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUU7a0JBQzNEdEQsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUc7Z0JBQ2xCO2NBQ0Y7Y0FFS3hELEdBQUcsR0FBSSxJQUFJLENBQUNtQyxLQUFLLENBQWpCbkMsR0FBRztjQUNSLElBQUlBLEdBQUcsS0FBSyxNQUFNLEVBQUU7Z0JBQ2xCO2dCQUNBQSxHQUFHLEdBQUdxQyxRQUFRLENBQUNtRyxVQUFVLEdBQUcsV0FBVyxHQUFHLFdBQVc7Y0FDdkQ7Y0FDTXhCLGFBQWEsR0FBRztnQkFDcEJKLEtBQUssRUFBTEEsS0FBSztnQkFDTEMsTUFBTSxFQUFOQSxNQUFNO2dCQUNOO2dCQUNBZ0MsSUFBSSxFQUFFckYsTUFBTTtnQkFDWnNGLFdBQVcsRUFBRSxDQUNYLENBQUN0RixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUVBLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUN0QixDQUFDQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUVBLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNpQjtnQkFDekN2RCxNQUFNLEVBQU5BLE1BQU07Z0JBQ05ELEdBQUcsRUFBSEEsR0FBRztnQkFDSDJHLFdBQVcsRUFBWEE7Y0FDRixDQUFDO2NBQ0QsSUFBSTNHLEdBQUcsS0FBSyxXQUFXLEVBQUU7Z0JBQUFpSCxxQkFBQSxHQUNGOEIscUJBQXFCLENBQUMsQ0FBQ3ZGLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBQTBELHNCQUFBLEdBQUE4QixjQUFBLENBQUEvQixxQkFBQSxNQUEzREUsSUFBSSxHQUFBRCxzQkFBQSxLQUFFRSxJQUFJLEdBQUFGLHNCQUFBO2dCQUFBRyxzQkFBQSxHQUNJMEIscUJBQXFCLENBQUMsQ0FBQ3ZGLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBQThELHNCQUFBLEdBQUEwQixjQUFBLENBQUEzQixzQkFBQSxNQUEzREUsSUFBSSxHQUFBRCxzQkFBQSxLQUFFRSxJQUFJLEdBQUFGLHNCQUFBO2dCQUNqQk4sYUFBYSxDQUFDOEIsV0FBVyxHQUFHLENBQzFCLENBQUMzQixJQUFJLEVBQUVDLElBQUksQ0FBQyxFQUNaLENBQUNHLElBQUksRUFBRUMsSUFBSSxDQUFDLENBQ2I7Z0JBQ0Q7Z0JBQ0FSLGFBQWEsQ0FBQzZCLElBQUksR0FBRyxDQUFDMUIsSUFBSSxFQUFFQyxJQUFJLEVBQUVHLElBQUksRUFBRUMsSUFBSSxDQUFDO2NBQy9DOztjQUVBO2NBQUEsTUFFRSxJQUFJLENBQUNqRyxLQUFLLENBQUMwSCx5QkFBeUIsSUFDcEMsSUFBSSxDQUFDQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMzSCxLQUFLLENBQUMwSCx5QkFBeUIsRUFBRWpDLGFBQWEsQ0FBQztnQkFBQXNCLFNBQUEsQ0FBQXZELElBQUE7Z0JBQUE7Y0FBQTtjQUFBLE9BQUF1RCxTQUFBLENBQUFsRCxNQUFBO1lBQUE7Y0FBQSxNQWFoRixJQUFJLENBQUM3RCxLQUFLLENBQUNtQyxxQkFBcUIsSUFDaEMsSUFBSSxDQUFDeUYsMkJBQTJCLENBQUMsSUFBSSxDQUFDNUgsS0FBSyxDQUFDbUMscUJBQXFCLEVBQUVzRCxhQUFhLENBQUM7Z0JBQUFzQixTQUFBLENBQUF2RCxJQUFBO2dCQUFBO2NBQUE7Y0FBQSxPQUFBdUQsU0FBQSxDQUFBbEQsTUFBQTtZQUFBO2NBS25GO2NBQ0E7Y0FDQTtjQUNNckMsRUFBRSxHQUFHLElBQUksQ0FBQ1QsT0FBTyxDQUFDUyxFQUFFO2NBQ3BCMEUsV0FBVyxHQUFHMUUsRUFBRSxhQUFGQSxFQUFFLGdCQUFBMEQsc0JBQUEsR0FBRjFELEVBQUUsQ0FBRUUsb0JBQW9CLGNBQUF3RCxzQkFBQSxnQkFBQUEsc0JBQUEsR0FBeEJBLHNCQUFBLENBQUF2RCxJQUFBLENBQUFILEVBQTJCLENBQUMsY0FBQTBELHNCQUFBLHVCQUE1QkEsc0JBQUEsQ0FBOEJ0RCxxQkFBcUI7Y0FBQSxNQUVuRXNFLFdBQVcsSUFBSSxJQUFJLENBQUNsRyxLQUFLLENBQUNPLGdCQUFnQixJQUFJLENBQUM7Z0JBQUF3RyxTQUFBLENBQUF2RCxJQUFBO2dCQUFBO2NBQUE7Y0FDM0M0QyxXQUFXLEdBQUd0RixRQUFRLENBQUMrRyxJQUFJO2NBQzNCeEIsUUFBUSxHQUFHLElBQUksQ0FBQ3JHLEtBQUssQ0FBQ08sZ0JBQWdCO2NBQ3RDK0YsV0FBVyxHQUFHRixXQUFXLEdBQUdDLFFBQVEsRUFFMUM7Y0FDTUUsUUFBUSxJQUFBSixxQkFBQSxHQUFHLElBQUksQ0FBQ25HLEtBQUssQ0FBQ21DLHFCQUFxQixjQUFBZ0UscUJBQUEsdUJBQWhDQSxxQkFBQSxDQUFrQ21CLElBQUk7Y0FDakRkLFdBQVcsR0FBR2YsYUFBYSxDQUFDNkIsSUFBSTtjQUNsQ2IsY0FBYyxHQUFHLEtBQUs7Y0FFMUIsSUFBSUYsUUFBUSxJQUFJQyxXQUFXLEVBQUU7Z0JBQzNCO2dCQUNBQyxjQUFjLEdBQ1pELFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSUQsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUM3QkMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJRCxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQzdCQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUlELFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFDN0JDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSUQsUUFBUSxDQUFDLENBQUMsQ0FBQztjQUNqQzs7Y0FFQTtjQUNBO2NBQ0E7Y0FDQTtjQUFBLE1BQ0lELFdBQVcsSUFBSWMsSUFBSSxDQUFDVSxLQUFLLENBQUMxQixXQUFXLENBQUMsS0FBS2dCLElBQUksQ0FBQ1UsS0FBSyxDQUFDekIsUUFBUSxDQUFDLElBQUlJLGNBQWM7Z0JBQUFNLFNBQUEsQ0FBQXZELElBQUE7Z0JBQUE7Y0FBQTtjQUFBLE9BQUF1RCxTQUFBLENBQUFsRCxNQUFBO1lBQUE7Y0FLdkY7Y0FDQSxJQUFJLENBQUM3RCxLQUFLLENBQUMwSCx5QkFBeUIsR0FBR2pDLGFBQWE7Y0FFOUNwRyxTQUFTLEdBQUcsSUFBSSxDQUFDMEksWUFBWSxDQUFDLENBQUM7Y0FBQWhCLFNBQUEsQ0FBQXhELElBQUE7Y0FFbkMsSUFBSSxDQUFDdkQsS0FBSyxDQUFDQyxXQUFXLEVBQUU7Y0FDeEI7Y0FDQSxJQUFJLENBQUMrSCxjQUFjLENBQUMsQ0FBQztjQUNyQixJQUFJLENBQUNwSCxLQUFLLENBQUMxQixnQkFBZ0IsQ0FBQ0csU0FBUyxDQUFDO2NBQUMwSCxTQUFBLENBQUF2RCxJQUFBO2NBQUEsT0FFbkIsSUFBSSxDQUFDeEQsS0FBSyxDQUFDaUIsV0FBVyxDQUFDZ0gsUUFBUSxDQUFDeEMsYUFBYSxDQUFDO1lBQUE7Y0FBNUR2RCxLQUFLLEdBQUE2RSxTQUFBLENBQUFuRCxJQUFBO2NBRVg7Y0FDQSxJQUFJLElBQUksQ0FBQzVELEtBQUssQ0FBQ00sYUFBYSxHQUFHakIsU0FBUyxFQUFFO2dCQUN4QyxDQUFBcUgsc0JBQUEsT0FBSSxDQUFDOUIsZUFBZSxDQUFDLENBQUMsY0FBQThCLHNCQUFBLGVBQXRCQSxzQkFBQSxDQUF3QjlGLEtBQUssQ0FBQ3pCLFdBQVcsQ0FBQ0UsU0FBUyxDQUFDO2dCQUNwRDtnQkFDQTtnQkFDQSxJQUFJLENBQUNXLEtBQUssQ0FBQ21DLHFCQUFxQixHQUFHc0QsYUFBYTtnQkFDaEQsSUFBSSxDQUFDekYsS0FBSyxDQUFDTyxnQkFBZ0IsR0FBR08sUUFBUSxDQUFDK0csSUFBSTtnQkFDM0M7Z0JBQ0EsSUFBSSxDQUFDSyxRQUFRLENBQUM7a0JBQ1poRyxLQUFLLEVBQUxBLEtBQUs7a0JBQ0xELE1BQU0sRUFBTkEsTUFBTTtrQkFDTjNCLGFBQWEsRUFBRWpCO2dCQUNqQixDQUFDLENBQUM7Y0FDSjtjQUFDMEgsU0FBQSxDQUFBdkQsSUFBQTtjQUFBO1lBQUE7Y0FBQXVELFNBQUEsQ0FBQXhELElBQUE7Y0FBQXdELFNBQUEsQ0FBQWxDLEVBQUEsR0FBQWtDLFNBQUE7Y0FFRCxDQUFBSixxQkFBQSxJQUFBQyxhQUFBLE9BQUksQ0FBQzdGLE9BQU8sRUFBQ29ILE9BQU8sY0FBQXhCLHFCQUFBLGVBQXBCQSxxQkFBQSxDQUFBaEYsSUFBQSxDQUFBaUYsYUFBQSxFQUFBRyxTQUFBLENBQUFsQyxFQUFBLEVBQXVDLElBQUksQ0FBQztjQUM1QyxDQUFBZ0Msc0JBQUEsT0FBSSxDQUFDakMsZUFBZSxDQUFDLENBQUMsY0FBQWlDLHNCQUFBLGVBQXRCQSxzQkFBQSxDQUF3QmpHLEtBQUssQ0FBQ3hCLGdCQUFnQixDQUFDQyxTQUFTLEVBQUEwSCxTQUFBLENBQUFsQyxFQUFnQixDQUFDO1lBQUM7Y0FBQWtDLFNBQUEsQ0FBQXhELElBQUE7Y0FFMUU7Y0FDQSxJQUFJLENBQUN2RCxLQUFLLENBQUMwSCx5QkFBeUIsR0FBRzVGLFNBQVM7Y0FDaEQsSUFBSSxDQUFDOUIsS0FBSyxDQUFDQyxXQUFXLEVBQUU7Y0FDeEI7Y0FDQSxJQUFJLENBQUMrSCxjQUFjLENBQUMsQ0FBQztjQUFDLE9BQUFqQixTQUFBLENBQUFqQyxNQUFBO1lBQUE7WUFBQTtjQUFBLE9BQUFpQyxTQUFBLENBQUFqRCxJQUFBO1VBQUE7UUFBQSxHQUFBa0IsUUFBQTtNQUFBLENBRXpCO01BQUEsU0F4SkszRCxTQUFTQSxDQUFBK0csR0FBQSxFQUFBQyxHQUFBO1FBQUEsT0FBQXRELFVBQUEsQ0FBQWQsS0FBQSxPQUFBdkUsU0FBQTtNQUFBO01BQUEsT0FBVDJCLFNBQVM7SUFBQSxJQTBKZjtJQUVBO0lBQUE7RUFBQTtJQUFBeEIsR0FBQTtJQUFBaEIsS0FBQSxFQUNBLFNBQVFrSixZQUFZQSxDQUFBLEVBQVc7TUFDN0IsT0FBTyxJQUFJLENBQUMvSCxLQUFLLENBQUNLLGNBQWMsRUFBRTtJQUNwQzs7SUFFQTtFQUFBO0lBQUFSLEdBQUE7SUFBQWhCLEtBQUEsRUFDQSxTQUFRdUMsUUFBUUEsQ0FBQ2tILEVBQWMsRUFBa0I7TUFBQSxJQUFoQkMsRUFBRSxHQUFBN0ksU0FBQSxDQUFBc0gsTUFBQSxRQUFBdEgsU0FBQSxRQUFBb0MsU0FBQSxHQUFBcEMsU0FBQSxNQUFHLEdBQUc7TUFDdkM4SSxZQUFZLENBQUMsSUFBSSxDQUFDeEksS0FBSyxDQUFDeUksVUFBVSxDQUFDO01BQ25DLElBQUksQ0FBQ3pJLEtBQUssQ0FBQ3lJLFVBQVUsR0FBR0MsVUFBVSxDQUFDO1FBQUEsT0FBTUosRUFBRSxDQUFDLENBQUM7TUFBQSxHQUFFQyxFQUFFLENBQUM7SUFDcEQ7O0lBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtFQUpFO0lBQUExSSxHQUFBO0lBQUFoQixLQUFBLEVBS0EsU0FBUStJLDJCQUEyQkEsQ0FBQ3JFLElBQVMsRUFBRUMsSUFBUyxFQUFXO01BQ2pFO01BQ0EsSUFDRUQsSUFBSSxDQUFDOUUsR0FBRyxLQUFLK0UsSUFBSSxDQUFDL0UsR0FBRyxJQUNyQjhFLElBQUksQ0FBQzhCLEtBQUssS0FBSzdCLElBQUksQ0FBQzZCLEtBQUssSUFDekI5QixJQUFJLENBQUMrQixNQUFNLEtBQUs5QixJQUFJLENBQUM4QixNQUFNLElBQzNCL0IsSUFBSSxDQUFDNkIsV0FBVyxLQUFLNUIsSUFBSSxDQUFDNEIsV0FBVyxJQUNyQyxDQUFDcEgsU0FBUyxDQUFDdUYsSUFBSSxDQUFDN0UsTUFBTSxFQUFFOEUsSUFBSSxDQUFDOUUsTUFBTSxDQUFDLEVBQ3BDO1FBQ0EsT0FBTyxLQUFLO01BQ2Q7TUFFQSxJQUFNaUssQ0FBQyxHQUFHcEYsSUFBSSxDQUFDK0QsSUFBSTtNQUNuQixJQUFNc0IsQ0FBQyxHQUFHcEYsSUFBSSxDQUFDOEQsSUFBSTtNQUNuQixJQUFJLENBQUNxQixDQUFDLElBQUksQ0FBQ0MsQ0FBQyxFQUFFO1FBQ1osT0FBTyxLQUFLO01BQ2Q7O01BRUE7TUFDQSxJQUFNQyxTQUFTLEdBQUdELENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSUQsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUlELENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJRCxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUlDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSUQsQ0FBQyxDQUFDLENBQUMsQ0FBQztNQUU5RSxJQUFJLENBQUNFLFNBQVMsRUFBRTtRQUNkLE9BQU8sS0FBSztNQUNkOztNQUVBO01BQ0E7TUFDQTtNQUNBO01BQ0E7TUFDQSxJQUFNQyxTQUFTLEdBQUdILENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBR0EsQ0FBQyxDQUFDLENBQUMsQ0FBQztNQUM3QixJQUFNSSxTQUFTLEdBQUdILENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBR0EsQ0FBQyxDQUFDLENBQUMsQ0FBQztNQUM3QixJQUFNSSxTQUFTLEdBQUdMLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBR0EsQ0FBQyxDQUFDLENBQUMsQ0FBQztNQUM3QixJQUFNTSxTQUFTLEdBQUdMLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBR0EsQ0FBQyxDQUFDLENBQUMsQ0FBQztNQUU3QixPQUNFRyxTQUFTLElBQUlELFNBQVMsR0FBRzFLLDRCQUE0QixJQUNyRDZLLFNBQVMsSUFBSUQsU0FBUyxHQUFHNUssNEJBQTRCO0lBRXpEOztJQUVBO0VBQUE7SUFBQXlCLEdBQUE7SUFBQWhCLEtBQUEsRUFDQSxTQUFROEksc0JBQXNCQSxDQUFDcEUsSUFBUyxFQUFFQyxJQUFTLEVBQVc7TUFDNUQ7TUFDQSxJQUFJRCxJQUFJLENBQUM4QixLQUFLLEtBQUs3QixJQUFJLENBQUM2QixLQUFLLElBQUk5QixJQUFJLENBQUMrQixNQUFNLEtBQUs5QixJQUFJLENBQUM4QixNQUFNLEVBQUU7UUFDNUQsT0FBTyxLQUFLO01BQ2Q7O01BRUE7TUFDQSxJQUFJL0IsSUFBSSxDQUFDOUUsR0FBRyxLQUFLK0UsSUFBSSxDQUFDL0UsR0FBRyxFQUFFO1FBQ3pCLE9BQU8sS0FBSztNQUNkOztNQUVBO01BQ0EsSUFBSSxDQUFDVCxTQUFTLENBQUN1RixJQUFJLENBQUM3RSxNQUFNLEVBQUU4RSxJQUFJLENBQUM5RSxNQUFNLENBQUMsRUFBRTtRQUN4QyxPQUFPLEtBQUs7TUFDZDs7TUFFQTtNQUNBLElBQUk2RSxJQUFJLENBQUM2QixXQUFXLEtBQUs1QixJQUFJLENBQUM0QixXQUFXLEVBQUU7UUFDekMsT0FBTyxLQUFLO01BQ2Q7O01BRUE7TUFDQSxJQUFNOEQsU0FBUyxHQUFHLEtBQUs7TUFDdkIsSUFBTUMsUUFBUSxHQUFHNUYsSUFBSSxDQUFDK0QsSUFBSTtNQUMxQixJQUFNOEIsUUFBUSxHQUFHNUYsSUFBSSxDQUFDOEQsSUFBSTtNQUUxQixJQUFJNkIsUUFBUSxJQUFJQyxRQUFRLEVBQUU7UUFDeEIsS0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEVBQUUsRUFBRTtVQUMxQixJQUFJakMsSUFBSSxDQUFDQyxHQUFHLENBQUM4QixRQUFRLENBQUNFLENBQUMsQ0FBQyxHQUFHRCxRQUFRLENBQUNDLENBQUMsQ0FBQyxDQUFDLEdBQUdILFNBQVMsRUFBRTtZQUNuRCxPQUFPLEtBQUs7VUFDZDtRQUNGO01BQ0Y7TUFFQSxPQUFPLElBQUk7SUFDYjtFQUFDO0FBQUEsRUF2WW1DckwsY0FBYztBQTBZcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBWEF5TCxlQUFBLENBMVlxQmhLLFFBQVEsZUFDUixVQUFVO0FBQUFnSyxlQUFBLENBRFZoSyxRQUFRLGtCQUVTakIsWUFBWTtBQUFBLFNBRjdCaUIsUUFBUSxJQUFBaUssT0FBQTtBQXNaN0IsT0FBTyxTQUFTckMscUJBQXFCQSxDQUFDcEcsUUFBa0IsRUFBb0M7RUFBQSxJQUFBMEksVUFBQTtFQUMxRixJQUFPbkUsS0FBSyxHQUFZdkUsUUFBUSxDQUF6QnVFLEtBQUs7SUFBRUMsTUFBTSxHQUFJeEUsUUFBUSxDQUFsQndFLE1BQU07RUFDcEIsSUFBTW1FLFNBQVMsSUFBQUQsVUFBQSxHQUFJMUksUUFBUSxDQUFTNEksU0FBUyxjQUFBRixVQUFBLGNBQUFBLFVBQUEsR0FBSSxDQUFDO0VBRWxELElBQU1HLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQztFQUNuQixJQUFNQyxJQUFjLEdBQUcsRUFBRTtFQUN6QjtFQUNBO0VBQ0EsSUFBTUMsVUFBb0IsR0FBRyxFQUFFO0VBRS9CLEtBQUssSUFBSVIsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxJQUFJTSxPQUFPLEVBQUVOLENBQUMsRUFBRSxFQUFFO0lBQ2pDLEtBQUssSUFBSVMsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxJQUFJSCxPQUFPLEVBQUVHLENBQUMsRUFBRSxFQUFFO01BQ2pDLElBQU1DLEVBQUUsR0FBSVYsQ0FBQyxHQUFHTSxPQUFPLEdBQUl0RSxLQUFLO01BQ2hDLElBQU0yRSxFQUFFLEdBQUlGLENBQUMsR0FBR0gsT0FBTyxHQUFJckUsTUFBTTtNQUNqQyxJQUFNMkUsS0FBSyxHQUFHbkosUUFBUSxDQUFDb0osU0FBUyxDQUFDLENBQUNILEVBQUUsRUFBRUMsRUFBRSxDQUFDLENBQUM7TUFDMUMsSUFBTUcsR0FBRyxHQUFHRixLQUFLLENBQUMsQ0FBQyxDQUFDO01BQ3BCLElBQU1HLEdBQUcsR0FBR0gsS0FBSyxDQUFDLENBQUMsQ0FBQztNQUNwQixJQUFJLENBQUNJLE1BQU0sQ0FBQ0MsUUFBUSxDQUFDSCxHQUFHLENBQUMsSUFBSSxDQUFDRSxNQUFNLENBQUNDLFFBQVEsQ0FBQ0YsR0FBRyxDQUFDLEVBQUU7UUFDbEQ7TUFDRjtNQUNBUixJQUFJLENBQUNXLElBQUksQ0FBQ0gsR0FBRyxDQUFDO01BQ2Q7TUFDQSxJQUFNSSxNQUFNLEdBQUksQ0FBQ0wsR0FBRyxHQUFHVixTQUFTLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBSSxHQUFHO01BQ3BESSxVQUFVLENBQUNVLElBQUksQ0FBQ0MsTUFBTSxDQUFDO0lBQ3pCO0VBQ0Y7O0VBRUE7RUFDQSxJQUFJWixJQUFJLENBQUM1QyxNQUFNLEtBQUssQ0FBQyxFQUFFO0lBQ3JCLE9BQU9sRyxRQUFRLENBQUNxRyxTQUFTLENBQUMsQ0FBQztFQUM3QjtFQUVBLElBQUk1QixNQUFNLEdBQUc2QixJQUFJLENBQUNxRCxHQUFHLENBQUF4RyxLQUFBLENBQVJtRCxJQUFJLEVBQVF3QyxJQUFJLENBQUM7RUFDOUIsSUFBSXBFLE1BQU0sR0FBRzRCLElBQUksQ0FBQ3NELEdBQUcsQ0FBQXpHLEtBQUEsQ0FBUm1ELElBQUksRUFBUXdDLElBQUksQ0FBQztFQUU5QixJQUFNZSxnQkFBZ0IsR0FBR0MsMEJBQTBCLENBQUM5SixRQUFRLEVBQUUsRUFBRSxDQUFDO0VBQ2pFLElBQU0rSixnQkFBZ0IsR0FBR0QsMEJBQTBCLENBQUM5SixRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFFbEUsSUFBSWdLLE1BQWM7RUFDbEIsSUFBSUMsTUFBYztFQUVsQixJQUFJSixnQkFBZ0IsSUFBSUUsZ0JBQWdCLEVBQUU7SUFDeEM7SUFDQTtJQUNBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHO0lBQ2JDLE1BQU0sR0FBRyxHQUFHO0lBQ1osSUFBSUosZ0JBQWdCLEVBQUU7TUFDcEJuRixNQUFNLEdBQUcsRUFBRTtJQUNiO0lBQ0EsSUFBSXFGLGdCQUFnQixFQUFFO01BQ3BCdEYsTUFBTSxHQUFHLENBQUMsRUFBRTtJQUNkO0VBQ0YsQ0FBQyxNQUFNO0lBQ0x1RixNQUFNLEdBQUdyQixTQUFTLEdBQUdyQyxJQUFJLENBQUNxRCxHQUFHLENBQUF4RyxLQUFBLENBQVJtRCxJQUFJLEVBQVF5QyxVQUFVLENBQUM7SUFDNUNrQixNQUFNLEdBQUd0QixTQUFTLEdBQUdyQyxJQUFJLENBQUNzRCxHQUFHLENBQUF6RyxLQUFBLENBQVJtRCxJQUFJLEVBQVF5QyxVQUFVLENBQUM7RUFDOUM7O0VBRUE7RUFDQSxJQUFNbUIsTUFBTSxHQUFHNUQsSUFBSSxDQUFDcUQsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDakYsTUFBTSxHQUFHRCxNQUFNLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQztFQUMxREEsTUFBTSxHQUFHNkIsSUFBSSxDQUFDc0QsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFbkYsTUFBTSxHQUFHeUYsTUFBTSxDQUFDO0VBQ3ZDeEYsTUFBTSxHQUFHNEIsSUFBSSxDQUFDcUQsR0FBRyxDQUFDLEVBQUUsRUFBRWpGLE1BQU0sR0FBR3dGLE1BQU0sQ0FBQztFQUV0QyxJQUFJRCxNQUFNLEdBQUdELE1BQU0sR0FBRyxHQUFHLEVBQUU7SUFDekIsSUFBTUcsTUFBTSxHQUFHN0QsSUFBSSxDQUFDcUQsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDTSxNQUFNLEdBQUdELE1BQU0sSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQzFEQSxNQUFNLElBQUlHLE1BQU07SUFDaEJGLE1BQU0sSUFBSUUsTUFBTTtFQUNsQjs7RUFFQTtFQUNBO0VBQ0E7RUFDQTtFQUNBLElBQUlGLE1BQU0sR0FBR0QsTUFBTSxJQUFJLEdBQUcsSUFBSUEsTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJQyxNQUFNLEdBQUcsR0FBRyxFQUFFO0lBQzNERCxNQUFNLEdBQUcsQ0FBQyxHQUFHO0lBQ2JDLE1BQU0sR0FBRyxHQUFHO0VBQ2Q7RUFFQSxPQUFPLENBQUNELE1BQU0sRUFBRXZGLE1BQU0sRUFBRXdGLE1BQU0sRUFBRXZGLE1BQU0sQ0FBQztBQUN6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBU29GLDBCQUEwQkEsQ0FBQzlKLFFBQWtCLEVBQUVzSixHQUFXLEVBQVc7RUFDNUUsSUFBTy9FLEtBQUssR0FBWXZFLFFBQVEsQ0FBekJ1RSxLQUFLO0lBQUVDLE1BQU0sR0FBSXhFLFFBQVEsQ0FBbEJ3RSxNQUFNO0VBQ3BCLElBQU00RixLQUFLLEdBQUdwSyxRQUFRLENBQUNxSyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUVmLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztFQUNuRCxJQUFNZ0IsTUFBTSxHQUFHdEssUUFBUSxDQUFDdUssY0FBYztFQUV0QyxJQUFNQyxNQUFNLEdBQUdsRSxJQUFJLENBQUNtRSxLQUFLLENBQUNMLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRUEsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFQSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDdkQsSUFBTU0sSUFBSSxHQUFHcEUsSUFBSSxDQUFDbUUsS0FBSyxDQUFDSCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUVBLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQ3hELElBQUlFLE1BQU0sS0FBSyxDQUFDLElBQUlFLElBQUksS0FBSyxDQUFDLElBQUlBLElBQUksSUFBSUYsTUFBTSxFQUFFO0lBQ2hELE9BQU8sS0FBSztFQUNkO0VBRUEsSUFBTUcsVUFBVSxHQUNkLENBQUNQLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBR0UsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHRixLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUdFLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBR0YsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUtFLE1BQU0sR0FBR0UsSUFBSSxDQUFDO0VBQ3hGLElBQU1FLFVBQVUsR0FBR0osTUFBTSxHQUFHRSxJQUFJO0VBQ2hDLElBQUlDLFVBQVUsR0FBR0MsVUFBVSxFQUFFO0lBQzNCLE9BQU8sS0FBSztFQUNkO0VBRUEsSUFBTUMsTUFBTSxHQUFHN0ssUUFBUSxDQUFDOEssT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFeEIsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0VBQzVDLE9BQU91QixNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJQSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUl0RyxLQUFLLElBQUlzRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJQSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUlyRyxNQUFNO0FBQ3RGOztBQUVBO0FBQ0E7QUFDQSxJQUFNdUcsd0JBQXdCLEdBQUcsT0FBTyxHQUFHekUsSUFBSSxDQUFDMEUsRUFBRTs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTdEUscUJBQXFCQSxDQUFDeUMsS0FBdUIsRUFBb0I7RUFDL0UsSUFBTThCLFFBQVEsR0FBR25PLGFBQWEsQ0FBQ3FNLEtBQUssQ0FBQztFQUNyQzhCLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDQSxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSUYsd0JBQXdCO0VBQ2hFRSxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQ0EsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUlGLHdCQUF3QjtFQUNoRSxPQUFPRSxRQUFRO0FBQ2pCIiwiaWdub3JlTGlzdCI6W119
|