@kepler.gl/deckgl-layers 3.3.0-alpha.1 → 3.3.0-alpha.11

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