@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,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/LnByb3BzLm9uTWV0YWRhdGFMb2FkRXJyb3IoZXJyb3IgYXMgRXJyb3IpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnN0YXRlLmxvYWRDb3VudGVyLS07XG4gICAgfVxuICB9XG5cbiAgLyoqIExvYWQgYW4gaW1hZ2UgKi9cbiAgYXN5bmMgbG9hZEltYWdlKHZpZXdwb3J0OiBWaWV3cG9ydCwgX3JlYXNvbjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qge2xheWVycywgc2VydmljZVR5cGUsIHRyYW5zcGFyZW50fSA9IHRoaXMucHJvcHM7XG5cbiAgICAvLyBUT0RPIC0gbW92ZSB0byBJbWFnZVNvdXJjZT9cbiAgICBpZiAoc2VydmljZVR5cGUgPT09ICd3bXMnICYmIGxheWVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJbiBnbG9iZSBtb2RlIGRlY2sncyBHbG9iZVZpZXdwb3J0LmdldEJvdW5kcygpIG9ubHkgdW5wcm9qZWN0cyA0IGVkZ2VcbiAgICAvLyBtaWRwb2ludHMgYW5kIHRha2VzIHRoZWlyIG1pbi9tYXguIFRoYXQgbWlzc2VzIHRoZSBzY3JlZW4gY29ybmVycywgdGhlXG4gICAgLy8gY3VydmVkIGxpbWIsIGFuZCAobW9zdCBpbXBvcnRhbnRseSkgdGhlIGNhc2Ugd2hlcmUgYSBwb2xlIGlzIGluIHZpZXcgd2hlblxuICAgIC8vIGxvb2tpbmcgZnJvbSBhIGhpZ2ggbGF0aXR1ZGUg4oCUIHdoZXJlIGV2ZXJ5IG1lcmlkaWFuIGFuZCBwYXJ0IG9mIHRoZSBmYXJcbiAgICAvLyBoZW1pc3BoZXJlIGJlY29tZSB2aXNpYmxlLiBDb21wdXRlIGEgZnVsbGVyIHZpc2libGUgYm91bmRpbmcgYm94IGluc3RlYWQgc29cbiAgICAvLyB0aGUgcmVxdWVzdGVkIFdNUyBpbWFnZSBjb3ZlcnMgZXZlcnl0aGluZyBvbiBzY3JlZW4uXG4gICAgY29uc3QgYm91bmRzID0gdmlld3BvcnQucmVzb2x1dGlvbiA/IGdldEdsb2JlVmlzaWJsZUJvdW5kcyh2aWV3cG9ydCkgOiB2aWV3cG9ydC5nZXRCb3VuZHMoKTtcbiAgICBjb25zdCB7d2lkdGgsIGhlaWdodH0gPSB2aWV3cG9ydDtcblxuICAgIC8vIEVkZ2UgY2FzZTogd2hlbiBib3VuZHMgYXJlIHBlcmZlY3RseSBzeW1tZXRyaWMgYXJvdW5kIDDCsCAoYm90aCBsb25naXR1ZGUgYW5kIGxhdGl0dWRlKSxcbiAgICAvLyBpdCBjYW4gY2F1c2UgcmVuZGVyaW5nIGFydGlmYWN0cyB3aXRoIEVQU0c6NDMyNiBvbiB0aGUgZ2xvYmUuXG4gICAgLy8gQWRkIGFzeW1tZXRyeSB0byBhdm9pZCB0aGlzIGlzc3VlLlxuICAgIGlmICh2aWV3cG9ydC5yZXNvbHV0aW9uICYmIGJvdW5kcykge1xuICAgICAgY29uc3QgbWluTGF0ID0gYm91bmRzWzFdO1xuICAgICAgY29uc3QgbWF4TGF0ID0gYm91bmRzWzNdO1xuICAgICAgLy8gQ2hlY2sgaWYgbGF0aXR1ZGUgYm91bmRzIGFyZSBzeW1tZXRyaWMgYXJvdW5kIDDCsCAod2l0aGluIDAuMcKwIHRvbGVyYW5jZSlcbiAgICAgIGlmIChNYXRoLmFicyhtaW5MYXQgKyBtYXhMYXQpIDwgMC4xICYmIE1hdGguYWJzKG1pbkxhdCkgPiAxKSB7XG4gICAgICAgIGJvdW5kc1szXSArPSAwLjE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHtzcnN9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoc3JzID09PSAnYXV0bycpIHtcbiAgICAgIC8vIEJpdG1hcExheWVyIG9ubHkgc3VwcG9ydHMgTE5HTEFUIG9yIENBUlRFU0lBTiAoV2ViLU1lcmNhdG9yKVxuICAgICAgc3JzID0gdmlld3BvcnQucmVzb2x1dGlvbiA/ICdFUFNHOjQzMjYnIDogJ0VQU0c6Mzg1Nyc7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RQYXJhbXMgPSB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIC8vIFRPRE86IHJlbW92ZSBiYm94IG9uY2UgZGVjay5nbCBpcyB1cGdyYWRlZCB0byBeOC4xMCB3aXRoIGxvYWRlcnMuZ2wgXjRcbiAgICAgIGJib3g6IGJvdW5kcyxcbiAgICAgIGJvdW5kaW5nQm94OiBbXG4gICAgICAgIFtib3VuZHNbMF0sIGJvdW5kc1sxXV0sXG4gICAgICAgIFtib3VuZHNbMl0sIGJvdW5kc1szXV1cbiAgICAgIF0gYXMgW1tudW1iZXIsIG51bWJlcl0sIFtudW1iZXIsIG51bWJlcl1dLFxuICAgICAgbGF5ZXJzLFxuICAgICAgc3JzLFxuICAgICAgdHJhbnNwYXJlbnRcbiAgICB9O1xuICAgIGlmIChzcnMgPT09ICdFUFNHOjM4NTcnKSB7XG4gICAgICBjb25zdCBbbWluWCwgbWluWV0gPSBXR1M4NFRvUHNldWRvTWVyY2F0b3IoW2JvdW5kc1swXSwgYm91bmRzWzFdXSk7XG4gICAgICBjb25zdCBbbWF4WCwgbWF4WV0gPSBXR1M4NFRvUHNldWRvTWVyY2F0b3IoW2JvdW5kc1syXSwgYm91bmRzWzNdXSk7XG4gICAgICByZXF1ZXN0UGFyYW1zLmJvdW5kaW5nQm94ID0gW1xuICAgICAgICBbbWluWCwgbWluWV0sXG4gICAgICAgIFttYXhYLCBtYXhZXVxuICAgICAgXTtcbiAgICAgIC8vIFRPRE86IHJlbW92ZSBiYm94IG9uY2UgZGVjay5nbCBpcyB1cGdyYWRlZCB0byBeOC4xMCB3aXRoIGxvYWRlcnMuZ2wgXjRcbiAgICAgIHJlcXVlc3RQYXJhbXMuYmJveCA9IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXTtcbiAgICB9XG5cbiAgICAvLyBTa2lwIHJlcXVlc3QgaWYgcGFyYW1ldGVycyBoYXZlbid0IG1lYW5pbmdmdWxseSBjaGFuZ2VkIGZyb20gYW4gaW4tZmxpZ2h0IHJlcXVlc3RcbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmluRmxpZ2h0UmVxdWVzdFBhcmFtZXRlcnMgJiZcbiAgICAgIHRoaXMuX2FyZVJlcXVlc3RQYXJhbXNFcXVhbCh0aGlzLnN0YXRlLmluRmxpZ2h0UmVxdWVzdFBhcmFtZXRlcnMsIHJlcXVlc3RQYXJhbXMpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2tpcCByZXF1ZXN0IGlmIHRoZSBuZXcgdmlldyBpcyBhbHJlYWR5IGZ1bGx5IGNvdmVyZWQgYnkgdGhlIGxhc3QgQ09NUExFVEVEIHJlcXVlc3RcbiAgICAvLyBhdCBjb21wYXJhYmxlIHJlc29sdXRpb24uIFRoaXMgaXMgdmVyeSBjb21tb24gd2hpbGUgcGFubmluZyAoYW5kIHNtYWxsXG4gICAgLy8gem9vbS1pbnMpIHdpdGhpbiBhIGxhcmdlciwgcmVjZW50bHkgZmV0Y2hlZCBleHRlbnQg4oCUIGUuZy4gb24gdGhlIGdsb2JlIGFcbiAgICAvLyBzaW5nbGUgcmVxdWVzdCBjYW4gY292ZXIgdGhlIHdob2xlIHZpc2libGUgaGVtaXNwaGVyZSwgc28gcm90YXRpbmcgYXJvdW5kIGl0XG4gICAgLy8gc2hvdWxkbid0IGhpdCB0aGUgbmV0d29yayBhZ2Fpbi4gVGhlIGV4aXN0aW5nIGltYWdlIGlzIHNpbXBseSByZXBvc2l0aW9uZWQgYnlcbiAgICAvLyB0aGUgQml0bWFwTGF5ZXIuIFdlIHN0aWxsIHJlZmV0Y2ggb25jZSB0aGUgdXNlciB6b29tcyBpbiBlbm91Z2ggdGhhdCB0aGVcbiAgICAvLyBjYWNoZWQgaW1hZ2Ugd291bGQgYmUgdmlzaWJseSBzdHJldGNoZWQgKHNlZSBDT1ZFUkFHRV9SRUZFVENIX1pPT01fRkFDVE9SKS5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmxhc3RSZXF1ZXN0UGFyYW1ldGVycyAmJlxuICAgICAgdGhpcy5faXNWaWV3Q292ZXJlZEJ5TGFzdFJlcXVlc3QodGhpcy5zdGF0ZS5sYXN0UmVxdWVzdFBhcmFtZXRlcnMsIHJlcXVlc3RQYXJhbXMpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRHVyaW5nIHZpZGVvIGV4cG9ydCwgdGhyb3R0bGUgem9vbS1pbiByZXF1ZXN0cyB0byBvbmx5IGZpcmUgb24gem9vbSBsZXZlbCBjcm9zc2luZ3MuXG4gICAgLy8gVGhlIGV4aXN0aW5nIGltYWdlIGlzIHN0cmV0Y2hlZCBieSB0aGUgQml0bWFwTGF5ZXIgdW50aWwgdGhlIG5leHQgbGV2ZWwgaXMgcmVhY2hlZC5cbiAgICAvLyBIb3dldmVyLCBhbHdheXMgYWxsb3cgcmVxdWVzdHMgaWYgdGhlIG5ldyB2aWV3IGlzbid0IGZ1bGx5IGNvdmVyZWQgYnkgdGhlIGxhc3QgaW1hZ2UuXG4gICAgY29uc3QgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG4gICAgY29uc3QgaXNFeHBvcnRpbmcgPSBnbD8uZ2V0Q29udGV4dEF0dHJpYnV0ZXM/LigpPy5wcmVzZXJ2ZURyYXdpbmdCdWZmZXI7XG5cbiAgICBpZiAoaXNFeHBvcnRpbmcgJiYgdGhpcy5zdGF0ZS5fbGFzdFJlcXVlc3Rab29tID49IDApIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRab29tID0gdmlld3BvcnQuem9vbTtcbiAgICAgIGNvbnN0IGxhc3Rab29tID0gdGhpcy5zdGF0ZS5fbGFzdFJlcXVlc3Rab29tO1xuICAgICAgY29uc3QgaXNab29taW5nSW4gPSBjdXJyZW50Wm9vbSA+IGxhc3Rab29tO1xuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgbmV3IHZpZXcgaXMgZnVsbHkgY292ZXJlZCBieSB0aGUgbGFzdCBsb2FkZWQgaW1hZ2VcbiAgICAgIGNvbnN0IGxhc3RCYm94ID0gdGhpcy5zdGF0ZS5sYXN0UmVxdWVzdFBhcmFtZXRlcnM/LmJib3g7XG4gICAgICBjb25zdCBjdXJyZW50QmJveCA9IHJlcXVlc3RQYXJhbXMuYmJveDtcbiAgICAgIGxldCBmdWxseUNvbnRhaW5lZCA9IGZhbHNlO1xuXG4gICAgICBpZiAobGFzdEJib3ggJiYgY3VycmVudEJib3gpIHtcbiAgICAgICAgLy8gTmV3IGJib3ggbXVzdCBiZSBmdWxseSBpbnNpZGUgdGhlIHByZXZpb3VzIGJib3hcbiAgICAgICAgZnVsbHlDb250YWluZWQgPVxuICAgICAgICAgIGN1cnJlbnRCYm94WzBdID49IGxhc3RCYm94WzBdICYmXG4gICAgICAgICAgY3VycmVudEJib3hbMV0gPj0gbGFzdEJib3hbMV0gJiZcbiAgICAgICAgICBjdXJyZW50QmJveFsyXSA8PSBsYXN0QmJveFsyXSAmJlxuICAgICAgICAgIGN1cnJlbnRCYm94WzNdIDw9IGxhc3RCYm94WzNdO1xuICAgICAgfVxuXG4gICAgICAvLyBPbmx5IHRocm90dGxlIGlmOlxuICAgICAgLy8gMS4gWm9vbWluZyBpbiAobm90IHpvb21pbmcgb3V0IG9yIHBhbm5pbmcgYXQgc2FtZSB6b29tKVxuICAgICAgLy8gMi4gU2FtZSB6b29tIGZsb29yIChoYXZlbid0IGNyb3NzZWQgYW4gaW50ZWdlciB6b29tIGxldmVsKVxuICAgICAgLy8gMy4gTmV3IHZpZXcgaXMgZnVsbHkgY29udGFpbmVkIGluIHRoZSBsYXN0IGxvYWRlZCBpbWFnZSAobm8gdW5jb3ZlcmVkIGFyZWFzKVxuICAgICAgaWYgKGlzWm9vbWluZ0luICYmIE1hdGguZmxvb3IoY3VycmVudFpvb20pID09PSBNYXRoLmZsb29yKGxhc3Rab29tKSAmJiBmdWxseUNvbnRhaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWFyayByZXF1ZXN0IGFzIGluLWZsaWdodCB0byBwcmV2ZW50IGR1cGxpY2F0ZSByZXF1ZXN0c1xuICAgIHRoaXMuc3RhdGUuaW5GbGlnaHRSZXF1ZXN0UGFyYW1ldGVycyA9IHJlcXVlc3RQYXJhbXM7XG5cbiAgICBjb25zdCByZXF1ZXN0SWQgPSB0aGlzLmdldFJlcXVlc3RJZCgpO1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnN0YXRlLmxvYWRDb3VudGVyKys7XG4gICAgICAvLyBUcmlnZ2VyIGEgcmVkcmF3IHRvIHVwZGF0ZSB0aGUgVUkgbG9hZGluZyBpbmRpY2F0b3JcbiAgICAgIHRoaXMuc2V0TmVlZHNSZWRyYXcoKTtcbiAgICAgIHRoaXMucHJvcHMub25JbWFnZUxvYWRTdGFydChyZXF1ZXN0SWQpO1xuXG4gICAgICBjb25zdCBpbWFnZSA9IGF3YWl0IHRoaXMuc3RhdGUuaW1hZ2VTb3VyY2UuZ2V0SW1hZ2UocmVxdWVzdFBhcmFtcyk7XG5cbiAgICAgIC8vIElmIGEgcmVxdWVzdCB0YWtlcyBhIGxvbmcgdGltZSwgbGF0ZXIgcmVxdWVzdHMgbWF5IGhhdmUgYWxyZWFkeSBsb2FkZWQuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5sYXN0UmVxdWVzdElkIDwgcmVxdWVzdElkKSB7XG4gICAgICAgIHRoaXMuZ2V0Q3VycmVudExheWVyKCk/LnByb3BzLm9uSW1hZ2VMb2FkKHJlcXVlc3RJZCk7XG4gICAgICAgIC8vIFVwZGF0ZSBsYXN0UmVxdWVzdFBhcmFtZXRlcnMgb25seSBhZnRlciBzdWNjZXNzZnVsIGxvYWRcbiAgICAgICAgLy8gVGhpcyBlbnN1cmVzIGNvdmVyYWdlIGNoZWNrcyBvbmx5IHVzZSBzdWNjZXNzZnVsbHkgbG9hZGVkIGltYWdlc1xuICAgICAgICB0aGlzLnN0YXRlLmxhc3RSZXF1ZXN0UGFyYW1ldGVycyA9IHJlcXVlc3RQYXJhbXM7XG4gICAgICAgIHRoaXMuc3RhdGUuX2xhc3RSZXF1ZXN0Wm9vbSA9IHZpZXdwb3J0Lnpvb207XG4gICAgICAgIC8vIE5vdCB0eXBlIHNhZmUuLi5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgaW1hZ2UsXG4gICAgICAgICAgYm91bmRzLFxuICAgICAgICAgIGxhc3RSZXF1ZXN0SWQ6IHJlcXVlc3RJZFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5jb250ZXh0Lm9uRXJyb3I/LihlcnJvciBhcyBFcnJvciwgdGhpcyk7XG4gICAgICB0aGlzLmdldEN1cnJlbnRMYXllcigpPy5wcm9wcy5vbkltYWdlTG9hZEVycm9yKHJlcXVlc3RJZCwgZXJyb3IgYXMgRXJyb3IpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAvLyBDbGVhciBpbi1mbGlnaHQgbWFya2VyIHdoZW4gcmVxdWVzdCBjb21wbGV0ZXMgKHN1Y2Nlc3Mgb3IgZXJyb3IpXG4gICAgICB0aGlzLnN0YXRlLmluRmxpZ2h0UmVxdWVzdFBhcmFtZXRlcnMgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnN0YXRlLmxvYWRDb3VudGVyLS07XG4gICAgICAvLyBUcmlnZ2VyIGEgcmVkcmF3IHRvIHVwZGF0ZSB0aGUgVUkgbG9hZGluZyBpbmRpY2F0b3JcbiAgICAgIHRoaXMuc2V0TmVlZHNSZWRyYXcoKTtcbiAgICB9XG4gIH1cblxuICAvLyBIRUxQRVJTXG5cbiAgLyoqIEdsb2JhbCBjb3VudGVyIGZvciBpc3N1aW5nIHVuaXF1ZSByZXF1ZXN0IGlkcyAqL1xuICBwcml2YXRlIGdldFJlcXVlc3RJZCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLl9uZXh0UmVxdWVzdElkKys7XG4gIH1cblxuICAvKiogUnVucyBhbiBhY3Rpb24gaW4gdGhlIGZ1dHVyZSwgY2FuY2VscyBpdCBpZiB0aGUgbmV3IGFjdGlvbiBpcyBpc3N1ZWQgYmVmb3JlIGl0IGV4ZWN1dGVzICovXG4gIHByaXZhdGUgZGVib3VuY2UoZm46ICgpID0+IHZvaWQsIG1zID0gNTAwKTogdm9pZCB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuc3RhdGUuX3RpbWVvdXRJZCk7XG4gICAgdGhpcy5zdGF0ZS5fdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiBmbigpLCBtcyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIHdoZW4gdGhlIGBuZXh0YCB2aWV3IGlzIGZ1bGx5IGluc2lkZSB0aGUgYHByZXZgIChsYXN0IHJlcXVlc3RlZClcbiAgICogZXh0ZW50IEFORCBub3QgbWVhbmluZ2Z1bGx5IGhpZ2hlciByZXNvbHV0aW9uLCBzbyB0aGUgY2FjaGVkIGltYWdlIGFscmVhZHlcbiAgICogY292ZXJzIHRoZSBzY3JlZW4gYW5kIG5vIG5ldyByZXF1ZXN0IGlzIG5lZWRlZC5cbiAgICovXG4gIHByaXZhdGUgX2lzVmlld0NvdmVyZWRCeUxhc3RSZXF1ZXN0KHByZXY6IGFueSwgbmV4dDogYW55KTogYm9vbGVhbiB7XG4gICAgLy8gQ292ZXJhZ2Ugb25seSBtYWtlcyBzZW5zZSB3aXRoaW4gdGhlIHNhbWUgcHJvamVjdGlvbiAvIGRhdGFzZXQgLyBjYW52YXMgc2l6ZS5cbiAgICBpZiAoXG4gICAgICBwcmV2LnNycyAhPT0gbmV4dC5zcnMgfHxcbiAgICAgIHByZXYud2lkdGggIT09IG5leHQud2lkdGggfHxcbiAgICAgIHByZXYuaGVpZ2h0ICE9PSBuZXh0LmhlaWdodCB8fFxuICAgICAgcHJldi50cmFuc3BhcmVudCAhPT0gbmV4dC50cmFuc3BhcmVudCB8fFxuICAgICAgIWRlZXBFcXVhbChwcmV2LmxheWVycywgbmV4dC5sYXllcnMpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgcCA9IHByZXYuYmJveDtcbiAgICBjb25zdCBuID0gbmV4dC5iYm94O1xuICAgIGlmICghcCB8fCAhbikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIElzIHRoZSBuZXcgYmJveCBmdWxseSBjb250YWluZWQgd2l0aGluIHRoZSBwcmV2aW91c2x5IHJlcXVlc3RlZCBiYm94P1xuICAgIGNvbnN0IGNvbnRhaW5lZCA9IG5bMF0gPj0gcFswXSAmJiBuWzFdID49IHBbMV0gJiYgblsyXSA8PSBwWzJdICYmIG5bM10gPD0gcFszXTtcblxuICAgIGlmICghY29udGFpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gR3JvdW5kIHJlc29sdXRpb24gaXMgcHJvcG9ydGlvbmFsIHRvIGJib3ggc3BhbiAvIHBpeGVsIGNvdW50LiBUaGUgZ3VhcmRcbiAgICAvLyBhYm92ZSBhbHJlYWR5IGVuc3VyZWQgcHJldiBhbmQgbmV4dCBzaGFyZSB0aGUgc2FtZSB3aWR0aC9oZWlnaHQsIHNvIGVxdWFsXG4gICAgLy8gcGl4ZWwgY291bnRzIGxldCB1cyBjb21wYXJlIHNwYW5zIGRpcmVjdGx5LiBPbmx5IHNraXAgd2hpbGUgdGhlIG5ldyB2aWV3XG4gICAgLy8gaXNuJ3QgbXVjaCBmaW5lciB0aGFuIHdoYXQgd2UgYWxyZWFkeSBmZXRjaGVkLCBvdGhlcndpc2UgdGhlIGNhY2hlZCBpbWFnZVxuICAgIC8vIHdvdWxkIGxvb2sgc3RyZXRjaGVkL2JsdXJyeS5cbiAgICBjb25zdCBwcmV2U3BhblggPSBwWzJdIC0gcFswXTtcbiAgICBjb25zdCBuZXh0U3BhblggPSBuWzJdIC0gblswXTtcbiAgICBjb25zdCBwcmV2U3BhblkgPSBwWzNdIC0gcFsxXTtcbiAgICBjb25zdCBuZXh0U3BhblkgPSBuWzNdIC0gblsxXTtcblxuICAgIHJldHVybiAoXG4gICAgICBuZXh0U3BhblggPj0gcHJldlNwYW5YIC8gQ09WRVJBR0VfUkVGRVRDSF9aT09NX0ZBQ1RPUiAmJlxuICAgICAgbmV4dFNwYW5ZID49IHByZXZTcGFuWSAvIENPVkVSQUdFX1JFRkVUQ0hfWk9PTV9GQUNUT1JcbiAgICApO1xuICB9XG5cbiAgLyoqIENvbXBhcmUgcmVxdWVzdCBwYXJhbWV0ZXJzIHRvIGRldGVybWluZSBpZiBhIG5ldyByZXF1ZXN0IGlzIG5lZWRlZCAqL1xuICBwcml2YXRlIF9hcmVSZXF1ZXN0UGFyYW1zRXF1YWwocHJldjogYW55LCBuZXh0OiBhbnkpOiBib29sZWFuIHtcbiAgICAvLyBDb21wYXJlIGRpbWVuc2lvbnNcbiAgICBpZiAocHJldi53aWR0aCAhPT0gbmV4dC53aWR0aCB8fCBwcmV2LmhlaWdodCAhPT0gbmV4dC5oZWlnaHQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBDb21wYXJlIFNSU1xuICAgIGlmIChwcmV2LnNycyAhPT0gbmV4dC5zcnMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBDb21wYXJlIGxheWVyc1xuICAgIGlmICghZGVlcEVxdWFsKHByZXYubGF5ZXJzLCBuZXh0LmxheWVycykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBDb21wYXJlIHRyYW5zcGFyZW50XG4gICAgaWYgKHByZXYudHJhbnNwYXJlbnQgIT09IG5leHQudHJhbnNwYXJlbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBDb21wYXJlIGJvdW5kcyB3aXRoIHRvbGVyYW5jZSBmb3IgZmxvYXRpbmcgcG9pbnQgcHJlY2lzaW9uXG4gICAgY29uc3QgdG9sZXJhbmNlID0gMWUtMTA7XG4gICAgY29uc3QgcHJldkJib3ggPSBwcmV2LmJib3g7XG4gICAgY29uc3QgbmV4dEJib3ggPSBuZXh0LmJib3g7XG5cbiAgICBpZiAocHJldkJib3ggJiYgbmV4dEJib3gpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgIGlmIChNYXRoLmFicyhwcmV2QmJveFtpXSAtIG5leHRCYm94W2ldKSA+IHRvbGVyYW5jZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgW21pbkxuZywgbWluTGF0LCBtYXhMbmcsIG1heExhdF0gYm91bmRpbmcgYm94IG9mIHRoZSBwYXJ0IG9mIHRoZVxuICogZ2xvYmUgdGhhdCBpcyBhY3R1YWxseSB2aXNpYmxlIG9uIHNjcmVlbi5cbiAqXG4gKiBVbmxpa2UgYEdsb2JlVmlld3BvcnQuZ2V0Qm91bmRzKClgICg0IGVkZ2UgbWlkcG9pbnRzKSwgdGhpcyBzYW1wbGVzIGEgZ3JpZCBvZlxuICogc2NyZWVuIHBpeGVscywgdW5wcm9qZWN0cyBlYWNoIG9udG8gdGhlIHNwaGVyZSAoZGVjay5nbCBjbGFtcHMgcmF5cyB0aGF0IG1pc3NcbiAqIHRoZSBnbG9iZSB0byB0aGUgc2lsaG91ZXR0ZS9saW1iLCB3aGljaCBpcyBleGFjdGx5IHRoZSBib3VuZGFyeSB3ZSB3YW50KSwgYW5kXG4gKiB0YWtlcyB0aGUgZXh0ZW50LiBJdCBhZGRpdGlvbmFsbHkgZGV0ZWN0cyB3aGVuIGEgcG9sZSBpcyBpbiB2aWV3OiBhdCBhIHBvbGUgYWxsXG4gKiBtZXJpZGlhbnMgY29udmVyZ2UsIHNvIHdlIHdpZGVuIHRoZSBib3ggdG8gdGhlIGZ1bGwgbG9uZ2l0dWRlIHJhbmdlIGFuZCBleHRlbmRcbiAqIHRoZSBsYXRpdHVkZSB1cCB0byB0aGUgcG9sZSwgd2hpY2ggaXMgd2hhdCBtYWtlcyB2aWV3aW5nIGZyb20gbmVhciBhIHBvbGVcbiAqIChzZWVpbmcgYWNyb3NzIHRvIHRoZSBmYXIgaGVtaXNwaGVyZSkgd29yay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdsb2JlVmlzaWJsZUJvdW5kcyh2aWV3cG9ydDogVmlld3BvcnQpOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHZpZXdwb3J0O1xuICBjb25zdCBjZW50ZXJMbmcgPSAodmlld3BvcnQgYXMgYW55KS5sb25naXR1ZGUgPz8gMDtcblxuICBjb25zdCBTQU1QTEVTID0gODsgLy8gOHg4IGNlbGxzID0+IDl4OSA9IDgxIHNhbXBsZSBwb2ludHNcbiAgY29uc3QgbGF0czogbnVtYmVyW10gPSBbXTtcbiAgLy8gTG9uZ2l0dWRlcyB0cmFja2VkIGFzIHNpZ25lZCBvZmZzZXRzIGZyb20gdGhlIGNlbnRlciBsb25naXR1ZGUsIHVud3JhcHBlZCB0b1xuICAvLyAoLTE4MCwgMTgwXSwgc28gYW4gYW50aW1lcmlkaWFuLWNyb3NzaW5nIHZpZXcgc3RheXMgYSBjb250aWd1b3VzIHJhbmdlLlxuICBjb25zdCBsbmdPZmZzZXRzOiBudW1iZXJbXSA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDw9IFNBTVBMRVM7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDw9IFNBTVBMRVM7IGorKykge1xuICAgICAgY29uc3QgcHggPSAoaSAvIFNBTVBMRVMpICogd2lkdGg7XG4gICAgICBjb25zdCBweSA9IChqIC8gU0FNUExFUykgKiBoZWlnaHQ7XG4gICAgICBjb25zdCBjb29yZCA9IHZpZXdwb3J0LnVucHJvamVjdChbcHgsIHB5XSk7XG4gICAgICBjb25zdCBsbmcgPSBjb29yZFswXTtcbiAgICAgIGNvbnN0IGxhdCA9IGNvb3JkWzFdO1xuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobG5nKSB8fCAhTnVtYmVyLmlzRmluaXRlKGxhdCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBsYXRzLnB1c2gobGF0KTtcbiAgICAgIC8vIFdyYXAgdGhlIG9mZnNldCBpbnRvICgtMTgwLCAxODBdLlxuICAgICAgY29uc3Qgb2Zmc2V0ID0gKChsbmcgLSBjZW50ZXJMbmcgKyA1NDApICUgMzYwKSAtIDE4MDtcbiAgICAgIGxuZ09mZnNldHMucHVzaChvZmZzZXQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEV4dHJlbWVseSBkZWdlbmVyYXRlIHZpZXdwb3J0OiBmYWxsIGJhY2sgdG8gZGVjaydzIGRlZmF1bHQuXG4gIGlmIChsYXRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB2aWV3cG9ydC5nZXRCb3VuZHMoKTtcbiAgfVxuXG4gIGxldCBtaW5MYXQgPSBNYXRoLm1pbiguLi5sYXRzKTtcbiAgbGV0IG1heExhdCA9IE1hdGgubWF4KC4uLmxhdHMpO1xuXG4gIGNvbnN0IG5vcnRoUG9sZVZpc2libGUgPSBpc0dsb2JlU3VyZmFjZVBvaW50VmlzaWJsZSh2aWV3cG9ydCwgOTApO1xuICBjb25zdCBzb3V0aFBvbGVWaXNpYmxlID0gaXNHbG9iZVN1cmZhY2VQb2ludFZpc2libGUodmlld3BvcnQsIC05MCk7XG5cbiAgbGV0IG1pbkxuZzogbnVtYmVyO1xuICBsZXQgbWF4TG5nOiBudW1iZXI7XG5cbiAgaWYgKG5vcnRoUG9sZVZpc2libGUgfHwgc291dGhQb2xlVmlzaWJsZSkge1xuICAgIC8vIEEgcG9sZSBpcyBvbiBzY3JlZW46IGV2ZXJ5IG1lcmlkaWFuIGlzIHZpc2libGUsIHNvIGNvdmVyIGFsbCBsb25naXR1ZGVzIGFuZFxuICAgIC8vIGV4dGVuZCBsYXRpdHVkZSB1cCB0byB0aGUgdmlzaWJsZSBwb2xlLlxuICAgIG1pbkxuZyA9IC0xODA7XG4gICAgbWF4TG5nID0gMTgwO1xuICAgIGlmIChub3J0aFBvbGVWaXNpYmxlKSB7XG4gICAgICBtYXhMYXQgPSA5MDtcbiAgICB9XG4gICAgaWYgKHNvdXRoUG9sZVZpc2libGUpIHtcbiAgICAgIG1pbkxhdCA9IC05MDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbWluTG5nID0gY2VudGVyTG5nICsgTWF0aC5taW4oLi4ubG5nT2Zmc2V0cyk7XG4gICAgbWF4TG5nID0gY2VudGVyTG5nICsgTWF0aC5tYXgoLi4ubG5nT2Zmc2V0cyk7XG4gIH1cblxuICAvLyBQYWQgc2xpZ2h0bHkgc28gdGhlIGRpc2NyZXRlIHNhbXBsaW5nIGRvZXNuJ3QgY2xpcCB0aGUgdHJ1ZSBsaW1iLlxuICBjb25zdCBsYXRQYWQgPSBNYXRoLm1pbig1LCAobWF4TGF0IC0gbWluTGF0KSAqIDAuMDUgKyAwLjUpO1xuICBtaW5MYXQgPSBNYXRoLm1heCgtOTAsIG1pbkxhdCAtIGxhdFBhZCk7XG4gIG1heExhdCA9IE1hdGgubWluKDkwLCBtYXhMYXQgKyBsYXRQYWQpO1xuXG4gIGlmIChtYXhMbmcgLSBtaW5MbmcgPCAzNjApIHtcbiAgICBjb25zdCBsbmdQYWQgPSBNYXRoLm1pbig1LCAobWF4TG5nIC0gbWluTG5nKSAqIDAuMDUgKyAwLjUpO1xuICAgIG1pbkxuZyAtPSBsbmdQYWQ7XG4gICAgbWF4TG5nICs9IGxuZ1BhZDtcbiAgfVxuXG4gIC8vIEEgc2luZ2xlIEVQU0c6NDMyNiByZWN0YW5nbGUgY2FuJ3QgY3Jvc3MgdGhlIGFudGltZXJpZGlhbiwgc28gaWYgdGhlIHZpc2libGVcbiAgLy8gc3BhbiB3cmFwcyBwYXN0IMKxMTgwIChvciBjb3ZlcnMgdGhlIHdob2xlIHdvcmxkKSByZXF1ZXN0IHRoZSBmdWxsIGxvbmdpdHVkZVxuICAvLyByYW5nZS4gVGhpcyBvdmVyLWNvdmVycyBvbmx5IG5lYXIgdGhlIGRhdGVsaW5lLCB3aGljaCBpcyBhbiBhY2NlcHRhYmxlXG4gIC8vIHRyYWRlLW9mZiBmb3IgYSB2YWxpZCwgZ2FwLWZyZWUgcmVxdWVzdC5cbiAgaWYgKG1heExuZyAtIG1pbkxuZyA+PSAzNjAgfHwgbWluTG5nIDwgLTE4MCB8fCBtYXhMbmcgPiAxODApIHtcbiAgICBtaW5MbmcgPSAtMTgwO1xuICAgIG1heExuZyA9IDE4MDtcbiAgfVxuXG4gIHJldHVybiBbbWluTG5nLCBtaW5MYXQsIG1heExuZywgbWF4TGF0XTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGEgcG9pbnQgb24gdGhlIGdsb2JlIHN1cmZhY2UgYXQgdGhlIGdpdmVuIGxhdGl0dWRlIChsb25naXR1ZGUgaXNcbiAqIGlycmVsZXZhbnQgYXQgdGhlIHBvbGVzKSBpcyBib3RoIGZyb250LWZhY2luZyAobm90IG9jY2x1ZGVkIGJ5IHRoZSBnbG9iZSkgYW5kXG4gKiBpbnNpZGUgdGhlIHNjcmVlbi4gVXNlcyB0aGUgc3BoZXJlLWhvcml6b24gdGVzdCBpbiBkZWNrLmdsIGNvbW1vbiBzcGFjZTpcbiAqIGEgc3VyZmFjZSBwb2ludCBpcyBmcm9udC1mYWNpbmcgd2hlbiB0aGUgYW5nbGUgYmV0d2VlbiBpdHMgb3V0d2FyZCBub3JtYWwgYW5kXG4gKiB0aGUgY2FtZXJhIGRpcmVjdGlvbiBpcyB3aXRoaW4gdGhlIGhvcml6b24gaGFsZi1hbmdsZSwgaS5lLlxuICogICBkb3Qobm9ybWFsaXplKHBvaW50Q29tbW9uKSwgbm9ybWFsaXplKGNhbWVyYVBvc2l0aW9uKSkgPj0gcmFkaXVzIC8gY2FtZXJhRGlzdFxuICovXG5mdW5jdGlvbiBpc0dsb2JlU3VyZmFjZVBvaW50VmlzaWJsZSh2aWV3cG9ydDogVmlld3BvcnQsIGxhdDogbnVtYmVyKTogYm9vbGVhbiB7XG4gIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHZpZXdwb3J0O1xuICBjb25zdCBwb2ludCA9IHZpZXdwb3J0LnByb2plY3RQb3NpdGlvbihbMCwgbGF0LCAwXSk7XG4gIGNvbnN0IGNhbWVyYSA9IHZpZXdwb3J0LmNhbWVyYVBvc2l0aW9uO1xuXG4gIGNvbnN0IHJQb2ludCA9IE1hdGguaHlwb3QocG9pbnRbMF0sIHBvaW50WzFdLCBwb2ludFsyXSk7XG4gIGNvbnN0IHJDYW0gPSBNYXRoLmh5cG90KGNhbWVyYVswXSwgY2FtZXJhWzFdLCBjYW1lcmFbMl0pO1xuICBpZiAoclBvaW50ID09PSAwIHx8IHJDYW0gPT09IDAgfHwgckNhbSA8PSByUG9pbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBjb3NTdXJmYWNlID1cbiAgICAocG9pbnRbMF0gKiBjYW1lcmFbMF0gKyBwb2ludFsxXSAqIGNhbWVyYVsxXSArIHBvaW50WzJdICogY2FtZXJhWzJdKSAvIChyUG9pbnQgKiByQ2FtKTtcbiAgY29uc3QgY29zSG9yaXpvbiA9IHJQb2ludCAvIHJDYW07XG4gIGlmIChjb3NTdXJmYWNlIDwgY29zSG9yaXpvbikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHNjcmVlbiA9IHZpZXdwb3J0LnByb2plY3QoWzAsIGxhdCwgMF0pO1xuICByZXR1cm4gc2NyZWVuWzBdID49IDAgJiYgc2NyZWVuWzBdIDw9IHdpZHRoICYmIHNjcmVlblsxXSA+PSAwICYmIHNjcmVlblsxXSA8PSBoZWlnaHQ7XG59XG5cbi8vIGh0dHBzOi8vZXBzZy5pby8zODU3XG4vLyArcHJvaj1tZXJjICthPTYzNzgxMzcgK2I9NjM3ODEzNyArbGF0X3RzPTAgK2xvbl8wPTAgK3hfMD0wICt5XzA9MCAraz0xICt1bml0cz1tICtuYWRncmlkcz1AbnVsbCArd2t0ZXh0ICtub19kZWZzICt0eXBlPWNyc1xuY29uc3QgSEFMRl9FQVJUSF9DSVJDVU1GRVJFTkNFID0gNjM3ODEzNyAqIE1hdGguUEk7XG5cbi8qKiBQcm9qZWN0cyBFUFNHOjQzMjYgdG8gRVBTRzozODU3XG4gKiBUaGlzIGlzIGEgbGlnaHR3ZWlnaHQgcmVwbGFjZW1lbnQgb2YgcHJvajQuIFVzZSB0ZXN0cyB0byBlbnN1cmUgY29uZm9ybWFuY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXR1M4NFRvUHNldWRvTWVyY2F0b3IoY29vcmQ6IFtudW1iZXIsIG51bWJlcl0pOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgY29uc3QgbWVyY2F0b3IgPSBsbmdMYXRUb1dvcmxkKGNvb3JkKTtcbiAgbWVyY2F0b3JbMF0gPSAobWVyY2F0b3JbMF0gLyAyNTYgLSAxKSAqIEhBTEZfRUFSVEhfQ0lSQ1VNRkVSRU5DRTtcbiAgbWVyY2F0b3JbMV0gPSAobWVyY2F0b3JbMV0gLyAyNTYgLSAxKSAqIEhBTEZfRUFSVEhfQ0lSQ1VNRkVSRU5DRTtcbiAgcmV0dXJuIG1lcmNhdG9yO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBLFNBQVFBLGFBQWEsUUFBTyx1QkFBdUI7QUFFbkQsU0FFRUMsY0FBYyxFQUtkQyxpQkFBaUIsRUFDakJDLFVBQVUsSUFBSUMsU0FBUyxRQUNsQixlQUFlO0FBQ3RCLFNBQVFDLFdBQVcsUUFBTyxpQkFBaUI7QUFDM0MsU0FBUUMs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