@kepler.gl/deckgl-layers 3.3.0-alpha.5 → 3.3.0-alpha.7

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 (189) 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/{globe → cjs/globe}/index.js +19 -1
  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/{index.js → cjs/index.js} +1 -1
  20. package/dist/cjs/layer-utils/aggregation-utils.js +181 -0
  21. package/dist/cjs/layer-utils/cluster-utils.js +93 -0
  22. package/dist/cjs/layer-utils/cpu-aggregator.js +798 -0
  23. package/dist/cjs/layer-utils/globe-cell-utils.js +173 -0
  24. package/dist/cjs/layer-utils/shader-utils.js +38 -0
  25. package/dist/cjs/line-layer/line-layer.js +95 -0
  26. package/dist/cjs/raster/images.js +271 -0
  27. package/dist/cjs/raster/pipeline-validation-patch.js +101 -0
  28. package/dist/cjs/raster/raster-layer/raster-layer-shaders.js +163 -0
  29. package/dist/cjs/raster/raster-layer/raster-layer-webgl1.fs.js +10 -0
  30. package/dist/cjs/raster/raster-layer/raster-layer-webgl1.vs.js +10 -0
  31. package/dist/cjs/raster/raster-layer/raster-layer-webgl2.fs.js +10 -0
  32. package/dist/cjs/raster/raster-layer/raster-layer-webgl2.vs.js +10 -0
  33. package/dist/cjs/raster/raster-layer/raster-layer.js +287 -0
  34. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +38 -0
  35. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +10 -0
  36. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +10 -0
  37. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +10 -0
  38. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +10 -0
  39. package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer.js +321 -0
  40. package/dist/cjs/raster/raster-processing-uniforms.js +124 -0
  41. package/dist/cjs/raster/types.js +6 -0
  42. package/dist/cjs/raster/util.js +139 -0
  43. package/dist/cjs/raster/webgl/color/colormap.js +45 -0
  44. package/dist/cjs/raster/webgl/color/filter.js +58 -0
  45. package/dist/cjs/raster/webgl/color/gamma-contrast.js +68 -0
  46. package/dist/cjs/raster/webgl/color/linear-rescale.js +35 -0
  47. package/dist/cjs/raster/webgl/color/saturation.js +42 -0
  48. package/dist/cjs/raster/webgl/color/sigmoidal-contrast.js +68 -0
  49. package/dist/{raster → cjs/raster}/webgl/index.js +1 -1
  50. package/dist/cjs/raster/webgl/pansharpen/pansharpen-brovey.js +46 -0
  51. package/dist/cjs/raster/webgl/spectral-indices/evi.js +26 -0
  52. package/dist/cjs/raster/webgl/spectral-indices/msavi.js +25 -0
  53. package/dist/cjs/raster/webgl/spectral-indices/normalized-difference.js +19 -0
  54. package/dist/cjs/raster/webgl/spectral-indices/savi.js +21 -0
  55. package/dist/cjs/raster/webgl/texture/combine-bands.js +65 -0
  56. package/dist/cjs/raster/webgl/texture/mask.js +50 -0
  57. package/dist/cjs/raster/webgl/texture/reorder-bands.js +72 -0
  58. package/dist/cjs/raster/webgl/texture/rgba-image.js +34 -0
  59. package/dist/cjs/raster/webgl/types.js +6 -0
  60. package/dist/cjs/svg-icon-layer/scatterplot-icon-layer.js +88 -0
  61. package/dist/cjs/svg-icon-layer/svg-icon-layer.js +104 -0
  62. package/dist/cjs/wms/wms-layer.js +624 -0
  63. package/dist/esm/3d-building-layer/3d-building-layer.js +62 -0
  64. package/dist/esm/3d-building-layer/3d-building-utils.js +157 -0
  65. package/dist/esm/3d-building-layer/types.js +3 -0
  66. package/dist/esm/cluster-layer/cluster-layer.js +286 -0
  67. package/dist/esm/column-layer/enhanced-column-layer.js +156 -0
  68. package/dist/esm/deckgl-extensions/filter-arrow-layer.js +64 -0
  69. package/dist/esm/deckgl-extensions/filter-shader-module.js +20 -0
  70. package/dist/esm/globe/atmosphere-layer.js +335 -0
  71. package/dist/esm/globe/enhanced-multi-icon-layer.js +60 -0
  72. package/dist/esm/globe/globe-depth-disk-layer.js +140 -0
  73. package/dist/esm/globe/globe-layers.js +566 -0
  74. package/dist/esm/globe/globe-stars-layer.js +92 -0
  75. package/dist/esm/globe/globe-stars-layer.spec.js +40 -0
  76. package/dist/esm/globe/globe-view.js +398 -0
  77. package/dist/esm/globe/index.js +26 -0
  78. package/dist/esm/globe/mvt-label-layer.js +187 -0
  79. package/dist/esm/grid-layer/enhanced-cpu-grid-layer.js +112 -0
  80. package/dist/esm/hexagon-layer/enhanced-hexagon-layer.js +130 -0
  81. package/dist/esm/index.js +22 -0
  82. package/dist/esm/layer-utils/aggregation-utils.js +172 -0
  83. package/dist/esm/layer-utils/cluster-utils.js +86 -0
  84. package/dist/esm/layer-utils/cpu-aggregator.js +788 -0
  85. package/dist/esm/layer-utils/globe-cell-utils.js +167 -0
  86. package/dist/esm/layer-utils/shader-utils.js +32 -0
  87. package/dist/esm/line-layer/line-layer.js +91 -0
  88. package/dist/esm/raster/images.js +267 -0
  89. package/dist/esm/raster/pipeline-validation-patch.js +94 -0
  90. package/dist/esm/raster/raster-layer/raster-layer-shaders.js +153 -0
  91. package/dist/esm/raster/raster-layer/raster-layer-webgl1.fs.js +5 -0
  92. package/dist/esm/raster/raster-layer/raster-layer-webgl1.vs.js +5 -0
  93. package/dist/esm/raster/raster-layer/raster-layer-webgl2.fs.js +5 -0
  94. package/dist/esm/raster/raster-layer/raster-layer-webgl2.vs.js +5 -0
  95. package/dist/esm/raster/raster-layer/raster-layer.js +283 -0
  96. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +30 -0
  97. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +5 -0
  98. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +5 -0
  99. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +5 -0
  100. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +5 -0
  101. package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer.js +318 -0
  102. package/dist/esm/raster/raster-processing-uniforms.js +118 -0
  103. package/dist/esm/raster/types.js +3 -0
  104. package/dist/esm/raster/util.js +134 -0
  105. package/dist/esm/raster/webgl/color/colormap.js +39 -0
  106. package/dist/esm/raster/webgl/color/filter.js +52 -0
  107. package/dist/esm/raster/webgl/color/gamma-contrast.js +62 -0
  108. package/dist/esm/raster/webgl/color/linear-rescale.js +29 -0
  109. package/dist/esm/raster/webgl/color/saturation.js +36 -0
  110. package/dist/esm/raster/webgl/color/sigmoidal-contrast.js +62 -0
  111. package/dist/esm/raster/webgl/index.js +26 -0
  112. package/dist/esm/raster/webgl/pansharpen/pansharpen-brovey.js +40 -0
  113. package/dist/esm/raster/webgl/spectral-indices/evi.js +20 -0
  114. package/dist/esm/raster/webgl/spectral-indices/msavi.js +19 -0
  115. package/dist/esm/raster/webgl/spectral-indices/normalized-difference.js +13 -0
  116. package/dist/esm/raster/webgl/spectral-indices/savi.js +15 -0
  117. package/dist/esm/raster/webgl/texture/combine-bands.js +58 -0
  118. package/dist/esm/raster/webgl/texture/mask.js +44 -0
  119. package/dist/esm/raster/webgl/texture/reorder-bands.js +65 -0
  120. package/dist/esm/raster/webgl/texture/rgba-image.js +28 -0
  121. package/dist/esm/raster/webgl/types.js +3 -0
  122. package/dist/esm/svg-icon-layer/scatterplot-icon-layer.js +84 -0
  123. package/dist/esm/svg-icon-layer/svg-icon-layer.js +101 -0
  124. package/dist/esm/wms/wms-layer.js +619 -0
  125. package/dist/globe/atmosphere-layer.d.ts +22 -1
  126. package/dist/globe/globe-stars-layer.d.ts +5 -0
  127. package/dist/globe/globe-stars-layer.spec.d.ts +1 -0
  128. package/dist/globe/index.d.ts +2 -2
  129. package/dist/wms/wms-layer.d.ts +8 -0
  130. package/package.json +19 -10
  131. package/dist/3d-building-layer/3d-building-layer.js +0 -66
  132. package/dist/3d-building-layer/3d-building-utils.js +0 -166
  133. package/dist/3d-building-layer/types.js +0 -6
  134. package/dist/cluster-layer/cluster-layer.js +0 -292
  135. package/dist/column-layer/enhanced-column-layer.js +0 -160
  136. package/dist/deckgl-extensions/filter-shader-module.js +0 -26
  137. package/dist/globe/atmosphere-layer.js +0 -220
  138. package/dist/globe/enhanced-multi-icon-layer.js +0 -63
  139. package/dist/globe/globe-depth-disk-layer.js +0 -145
  140. package/dist/globe/globe-layers.js +0 -569
  141. package/dist/globe/globe-stars-layer.js +0 -69
  142. package/dist/globe/globe-view.js +0 -404
  143. package/dist/globe/mvt-label-layer.js +0 -190
  144. package/dist/grid-layer/enhanced-cpu-grid-layer.js +0 -116
  145. package/dist/hexagon-layer/enhanced-hexagon-layer.js +0 -134
  146. package/dist/layer-utils/aggregation-utils.js +0 -181
  147. package/dist/layer-utils/cluster-utils.js +0 -93
  148. package/dist/layer-utils/cpu-aggregator.js +0 -798
  149. package/dist/layer-utils/globe-cell-utils.js +0 -173
  150. package/dist/layer-utils/shader-utils.js +0 -38
  151. package/dist/line-layer/line-layer.js +0 -95
  152. package/dist/raster/images.js +0 -271
  153. package/dist/raster/pipeline-validation-patch.js +0 -101
  154. package/dist/raster/raster-layer/raster-layer-shaders.js +0 -163
  155. package/dist/raster/raster-layer/raster-layer-webgl1.fs.js +0 -10
  156. package/dist/raster/raster-layer/raster-layer-webgl1.vs.js +0 -10
  157. package/dist/raster/raster-layer/raster-layer-webgl2.fs.js +0 -10
  158. package/dist/raster/raster-layer/raster-layer-webgl2.vs.js +0 -10
  159. package/dist/raster/raster-layer/raster-layer.js +0 -287
  160. package/dist/raster/raster-mesh-layer/matrix.d.ts +0 -4
  161. package/dist/raster/raster-mesh-layer/matrix.js +0 -18
  162. package/dist/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +0 -38
  163. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +0 -10
  164. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +0 -10
  165. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +0 -10
  166. package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +0 -10
  167. package/dist/raster/raster-mesh-layer/raster-mesh-layer.js +0 -321
  168. package/dist/raster/raster-processing-uniforms.js +0 -124
  169. package/dist/raster/types.js +0 -6
  170. package/dist/raster/util.js +0 -139
  171. package/dist/raster/webgl/color/colormap.js +0 -45
  172. package/dist/raster/webgl/color/filter.js +0 -58
  173. package/dist/raster/webgl/color/gamma-contrast.js +0 -68
  174. package/dist/raster/webgl/color/linear-rescale.js +0 -35
  175. package/dist/raster/webgl/color/saturation.js +0 -42
  176. package/dist/raster/webgl/color/sigmoidal-contrast.js +0 -68
  177. package/dist/raster/webgl/pansharpen/pansharpen-brovey.js +0 -46
  178. package/dist/raster/webgl/spectral-indices/evi.js +0 -26
  179. package/dist/raster/webgl/spectral-indices/msavi.js +0 -25
  180. package/dist/raster/webgl/spectral-indices/normalized-difference.js +0 -19
  181. package/dist/raster/webgl/spectral-indices/savi.js +0 -21
  182. package/dist/raster/webgl/texture/combine-bands.js +0 -65
  183. package/dist/raster/webgl/texture/mask.js +0 -50
  184. package/dist/raster/webgl/texture/reorder-bands.js +0 -72
  185. package/dist/raster/webgl/texture/rgba-image.js +0 -34
  186. package/dist/raster/webgl/types.js +0 -6
  187. package/dist/svg-icon-layer/scatterplot-icon-layer.js +0 -88
  188. package/dist/svg-icon-layer/svg-icon-layer.js +0 -104
  189. package/dist/wms/wms-layer.js +0 -594
@@ -0,0 +1,574 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getGlobeBasemapAttributions = exports.getGlobeBaseLayers = exports.getBasemapColorsForStyle = exports.getBasemapColors = exports.DEFAULT_BASEMAP_COLOR = void 0;
7
+ exports.getGlobeClearColor = getGlobeClearColor;
8
+ exports.resolveGlobeBasemapProvider = exports.getGlobeTopLayers = void 0;
9
+ var _core = require("@deck.gl/core");
10
+ var _layers = require("@deck.gl/layers");
11
+ var _geoLayers = require("@deck.gl/geo-layers");
12
+ var _atmosphereLayer = require("./atmosphere-layer");
13
+ var _globeDepthDiskLayer = require("./globe-depth-disk-layer");
14
+ var _mvtLabelLayer = require("./mvt-label-layer");
15
+ // SPDX-License-Identifier: MIT
16
+ // Copyright contributors to the kepler.gl project
17
+
18
+ var devicePixelRatio = Math.min(2, typeof window !== 'undefined' && window.devicePixelRatio || 1);
19
+ var BACKGROUND_PARAMETERS = {
20
+ depthTest: true,
21
+ cull: true,
22
+ depthMask: false
23
+ };
24
+ var BASEMAP_RASTER_PARAMETERS = {
25
+ depthMask: false
26
+ };
27
+ var BACKGROUND_DATA = [[[-180, 90], [0, 90], [180, 90], [180, -90], [0, -90], [-180, -90]]];
28
+ var BACKGROUND_NORTH_POLE_DATA = [[[-180, 90], [0, 90], [180, 90], [180, 85], [0, 85], [-180, 85]]];
29
+ var DEFAULT_BASEMAP_COLOR = exports.DEFAULT_BASEMAP_COLOR = {
30
+ backgroundFillColor: [9, 16, 29],
31
+ basemapDefaultFillColor: [255, 255, 255],
32
+ basemapWaterFillColor: [17, 35, 48],
33
+ basemapDefaultLineColor: [40, 63, 93],
34
+ basemapAdminLineColor: [40, 63, 93],
35
+ basemapLabelColor: [114.75, 114.75, 114.75]
36
+ };
37
+ function getPaintColor(color) {
38
+ if (Array.isArray(color) && color[0] === 'interpolate') {
39
+ return color[4];
40
+ }
41
+ return color;
42
+ }
43
+ function colorStringToRGB(color) {
44
+ if (!color) return null;
45
+ if (typeof color !== 'string') return null;
46
+
47
+ // Handle hsl() format
48
+ var hslMatch = color.match(/hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/);
49
+ if (hslMatch) {
50
+ var h = parseInt(hslMatch[1], 10) / 360;
51
+ var s = parseInt(hslMatch[2], 10) / 100;
52
+ var l = parseInt(hslMatch[3], 10) / 100;
53
+ // HSL to RGB conversion
54
+ var r, g, b;
55
+ if (s === 0) {
56
+ r = g = b = l;
57
+ } else {
58
+ var hue2rgb = function hue2rgb(p, q, t) {
59
+ if (t < 0) t += 1;
60
+ if (t > 1) t -= 1;
61
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
62
+ if (t < 1 / 2) return q;
63
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
64
+ return p;
65
+ };
66
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
67
+ var p = 2 * l - q;
68
+ r = hue2rgb(p, q, h + 1 / 3);
69
+ g = hue2rgb(p, q, h);
70
+ b = hue2rgb(p, q, h - 1 / 3);
71
+ }
72
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
73
+ }
74
+
75
+ // Handle rgb() format
76
+ var rgbMatch = color.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
77
+ if (rgbMatch) {
78
+ return [parseInt(rgbMatch[1], 10), parseInt(rgbMatch[2], 10), parseInt(rgbMatch[3], 10)];
79
+ }
80
+
81
+ // Handle hex format
82
+ var hexMatch = color.match(/^#([0-9a-f]{6})$/i);
83
+ if (hexMatch) {
84
+ var hex = hexMatch[1];
85
+ return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)];
86
+ }
87
+ return null;
88
+ }
89
+ function findFirstLayerByGroup(layers, layerGroups, groupSlug) {
90
+ var layerGroup = layerGroups.find(function (group) {
91
+ return group.slug === groupSlug;
92
+ });
93
+ if (!layerGroup) return null;
94
+ return layers.find(function (layer) {
95
+ return layerGroup.filter(layer);
96
+ });
97
+ }
98
+ function findBackgroundColor(style) {
99
+ var _found;
100
+ var found = style.layers.find(function (l) {
101
+ return l.id === 'background' || l.id === 'land';
102
+ });
103
+ found = found || style.layers.find(function (l) {
104
+ return l.type === 'background';
105
+ });
106
+ return colorStringToRGB(getPaintColor((_found = found) === null || _found === void 0 || (_found = _found.paint) === null || _found === void 0 ? void 0 : _found['background-color']));
107
+ }
108
+ function findWaterColor(style, layerGroups) {
109
+ var _found$paint;
110
+ var found = style.layers.find(function (l) {
111
+ return l.id === 'water';
112
+ }) || findFirstLayerByGroup(style.layers, layerGroups, 'water');
113
+ return colorStringToRGB(found === null || found === void 0 || (_found$paint = found.paint) === null || _found$paint === void 0 ? void 0 : _found$paint['fill-color']);
114
+ }
115
+ function findAdminColor(style, layerGroups) {
116
+ var _borderLayers$paint;
117
+ var borderLayers = style.layers.find(function (lyr) {
118
+ return lyr.id === 'admin-3-4-boundaries';
119
+ }) || findFirstLayerByGroup(style.layers, layerGroups, 'border');
120
+ return colorStringToRGB(borderLayers === null || borderLayers === void 0 || (_borderLayers$paint = borderLayers.paint) === null || _borderLayers$paint === void 0 ? void 0 : _borderLayers$paint['line-color']);
121
+ }
122
+ function findLabelColor(style, layerGroups) {
123
+ var _labelLayer;
124
+ var labelLayer = style.layers.find(function (lyr) {
125
+ return lyr.id === 'country-label-lg' && lyr.type === 'symbol';
126
+ });
127
+ labelLayer = labelLayer || style.layers.find(function (lyr) {
128
+ return lyr.id === 'country-label' && lyr.type === 'symbol';
129
+ });
130
+ labelLayer = labelLayer || findFirstLayerByGroup(style.layers, layerGroups, 'label');
131
+ return colorStringToRGB((_labelLayer = labelLayer) === null || _labelLayer === void 0 || (_labelLayer = _labelLayer.paint) === null || _labelLayer === void 0 ? void 0 : _labelLayer['text-color']);
132
+ }
133
+ var getBasemapColors = exports.getBasemapColors = function getBasemapColors(mapStyle) {
134
+ var _findBackgroundColor, _findWaterColor, _findAdminColor, _findLabelColor;
135
+ var _mapStyle$style = mapStyle.style,
136
+ styleJson = _mapStyle$style === void 0 ? {
137
+ layers: []
138
+ } : _mapStyle$style,
139
+ _mapStyle$layerGroups = mapStyle.layerGroups,
140
+ layerGroups = _mapStyle$layerGroups === void 0 ? [] : _mapStyle$layerGroups;
141
+ return {
142
+ backgroundFillColor: (_findBackgroundColor = findBackgroundColor(styleJson)) !== null && _findBackgroundColor !== void 0 ? _findBackgroundColor : DEFAULT_BASEMAP_COLOR.backgroundFillColor,
143
+ basemapWaterFillColor: (_findWaterColor = findWaterColor(styleJson, layerGroups)) !== null && _findWaterColor !== void 0 ? _findWaterColor : DEFAULT_BASEMAP_COLOR.basemapWaterFillColor,
144
+ basemapAdminLineColor: (_findAdminColor = findAdminColor(styleJson, layerGroups)) !== null && _findAdminColor !== void 0 ? _findAdminColor : DEFAULT_BASEMAP_COLOR.basemapAdminLineColor,
145
+ basemapLabelColor: (_findLabelColor = findLabelColor(styleJson, layerGroups)) !== null && _findLabelColor !== void 0 ? _findLabelColor : DEFAULT_BASEMAP_COLOR.basemapLabelColor
146
+ };
147
+ };
148
+
149
+ // Predefined color schemes for well-known basemap styles
150
+ var KNOWN_STYLE_COLORS = {
151
+ dark: {
152
+ backgroundFillColor: [15, 15, 15],
153
+ basemapWaterFillColor: [10, 20, 35],
154
+ basemapAdminLineColor: [60, 60, 80],
155
+ basemapLabelColor: [150, 150, 150]
156
+ },
157
+ 'dark-matter': {
158
+ backgroundFillColor: [18, 18, 18],
159
+ basemapWaterFillColor: [14, 19, 29],
160
+ basemapAdminLineColor: [50, 50, 60],
161
+ basemapLabelColor: [130, 130, 130]
162
+ },
163
+ light: {
164
+ backgroundFillColor: [235, 233, 228],
165
+ basemapWaterFillColor: [170, 211, 223],
166
+ basemapAdminLineColor: [180, 175, 170],
167
+ basemapLabelColor: [80, 80, 80]
168
+ },
169
+ positron: {
170
+ backgroundFillColor: [242, 239, 233],
171
+ basemapWaterFillColor: [174, 209, 220],
172
+ basemapAdminLineColor: [190, 185, 180],
173
+ basemapLabelColor: [90, 90, 90]
174
+ },
175
+ voyager: {
176
+ backgroundFillColor: [234, 229, 220],
177
+ basemapWaterFillColor: [170, 211, 223],
178
+ basemapAdminLineColor: [180, 170, 160],
179
+ basemapLabelColor: [70, 70, 70]
180
+ },
181
+ muted: {
182
+ backgroundFillColor: [225, 225, 218],
183
+ basemapWaterFillColor: [180, 210, 220],
184
+ basemapAdminLineColor: [170, 165, 160],
185
+ basemapLabelColor: [90, 90, 90]
186
+ },
187
+ muted_night: {
188
+ backgroundFillColor: [22, 26, 30],
189
+ basemapWaterFillColor: [15, 25, 40],
190
+ basemapAdminLineColor: [55, 60, 70],
191
+ basemapLabelColor: [140, 140, 140]
192
+ }
193
+ };
194
+
195
+ /**
196
+ * Get basemap colors either from the style JSON or from known style presets.
197
+ * Falls back to default dark colors if style is unknown and no JSON is available.
198
+ */
199
+ var getBasemapColorsForStyle = exports.getBasemapColorsForStyle = function getBasemapColorsForStyle(styleType, mapStyle) {
200
+ var _mapStyle$style2;
201
+ // Try to extract from style JSON first
202
+ if (mapStyle !== null && mapStyle !== void 0 && (_mapStyle$style2 = mapStyle.style) !== null && _mapStyle$style2 !== void 0 && (_mapStyle$style2 = _mapStyle$style2.layers) !== null && _mapStyle$style2 !== void 0 && _mapStyle$style2.length) {
203
+ return getBasemapColors(mapStyle);
204
+ }
205
+ // Fall back to known style presets
206
+ if (KNOWN_STYLE_COLORS[styleType]) {
207
+ return KNOWN_STYLE_COLORS[styleType];
208
+ }
209
+ // Default dark colors
210
+ return {
211
+ backgroundFillColor: DEFAULT_BASEMAP_COLOR.backgroundFillColor,
212
+ basemapWaterFillColor: DEFAULT_BASEMAP_COLOR.basemapWaterFillColor,
213
+ basemapAdminLineColor: DEFAULT_BASEMAP_COLOR.basemapAdminLineColor,
214
+ basemapLabelColor: DEFAULT_BASEMAP_COLOR.basemapLabelColor
215
+ };
216
+ };
217
+
218
+ /**
219
+ * Clear color (background around the globe) for globe mode, in RGBA 0-255 as
220
+ * expected by deck.gl's View `clearColor` prop (deck.gl >= 9 no longer supports
221
+ * the global `parameters.clearColor`; it must be set per-view with `clear: true`).
222
+ */
223
+ function getGlobeClearColor(backgroundColor) {
224
+ if (backgroundColor) {
225
+ return [backgroundColor[0], backgroundColor[1], backgroundColor[2], 255];
226
+ }
227
+ // Default matches the previous hardcoded clear color [0.015, 0.035, 0.065] in 0-1 space.
228
+ return [4, 9, 17, 255];
229
+ }
230
+ var INVISIBLE_COLOR = [0, 0, 0, 0];
231
+ var BASEMAP_MVT_PARAMETERS = {
232
+ // Occlude the far side of the globe via the DEPTH DISK (getGlobeDepthDiskLayer)
233
+ // rather than back-face culling. Globe mode sets a global `cull: true` for the
234
+ // opaque sphere surface, but back-face culling relies on stable triangle
235
+ // winding — and deck.gl 9's globe projection loses precision at high zoom
236
+ // (float32), flipping the winding of the small admin/water triangles so they
237
+ // get wrongly culled and the geometry vanishes past ~zoom 12 (you then see
238
+ // through to the far side / "different geometry"). Depth testing against the disk
239
+ // is a precision-robust occluder that works at any zoom, so:
240
+ // - cull: false → don't winding-cull the near-side geometry
241
+ // - depthTest: true → far-side geometry (behind the disk) fails depth, hidden
242
+ // - depthMask: false → don't write depth (avoid self z-fighting on the shell)
243
+ // Raster tiles are unaffected (their 4-corner quads keep stable winding), which
244
+ // is why satellite already zooms to max cleanly. Labels disable cull for the
245
+ // same reason (see mvt-label-layer.ts).
246
+ depthTest: true,
247
+ depthMask: false,
248
+ cull: false
249
+ };
250
+
251
+ // deck.gl 9's globe selects finer tiles than needed for a given view (its
252
+ // GlobeViewport scale is ~3x smaller than the equivalent mercator zoom), so bias
253
+ // vector tile selection coarser to keep the tile count — and thus performance —
254
+ // in check. This trades a little detail for far fewer tiles; make it less negative
255
+ // (toward 0) for sharper detail, or more negative for more perf.
256
+ // These are *base* offsets: globeLatitudeZoomCompensation is added on top at draw
257
+ // time, so the effective zoomOffset only equals these exact values at the equator.
258
+ // Satellite raster uses base 0 — it doesn't need the vector bias (a coarser raster
259
+ // tile just looks softer rather than dropping features).
260
+ var MAPBOX_GLOBE_VECTOR_ZOOM_OFFSET = -2;
261
+ var CARTO_GLOBE_VECTOR_ZOOM_OFFSET = -2;
262
+ var GLOBE_SATELLITE_ZOOM_OFFSET = 0;
263
+
264
+ // Whole-world tile extent (Web Mercator latitude limit). Required whenever a
265
+ // negative `zoomOffset` is used: deck's `getTileIndices` returns NO tiles when
266
+ // the target zoom drops below `minZoom` *unless* an `extent` is set (in which
267
+ // case it clamps to `minZoom` instead). Without this, zooming out or panning
268
+ // toward the poles (where deck 9's globe controller lowers the effective zoom)
269
+ // makes the whole globe basemap disappear.
270
+ var GLOBE_TILE_EXTENT = [-180, -85.051129, 180, 85.051129];
271
+
272
+ // Max *native* zoom of each vector tile source. Set this (not an arbitrarily
273
+ // high number) so deck overzooms — i.e. keeps rendering the deepest real tile
274
+ // when the view zooms past it — instead of requesting tiles that don't exist
275
+ // and 404 (which shows up as empty rectangles). The raw `.vector.pbf` /`.mvt`
276
+ // endpoints do NOT auto-overzoom the way Mapbox GL does.
277
+ // - mapbox-streets-v8 has data up to z16
278
+ // - CARTO carto.streets v1 has data up to z14
279
+ var MAPBOX_VECTOR_MAX_DATA_ZOOM = 16;
280
+ var CARTO_VECTOR_MAX_DATA_ZOOM = 14;
281
+
282
+ /**
283
+ * deck.gl 9's globe couples zoom to latitude via `zoomAdjust` (see
284
+ * globe-viewport.js): `scale = 2^(zoom - zoomAdjust(lat))`, and its controller
285
+ * *lowers* the stored `zoom` as you pan toward the poles to keep the globe's
286
+ * on-screen size constant. Tile LOD, however, is selected from the raw `zoom`,
287
+ * so rotating toward a pole silently drops the LOD and thins out labels.
288
+ * Replicated from `@deck.gl/core` globe-viewport.js `zoomAdjust`.
289
+ */
290
+ function zoomAdjust(latitude) {
291
+ return Math.log2(Math.PI * Math.cos(latitude * Math.PI / 180));
292
+ }
293
+
294
+ /**
295
+ * Latitude compensation to add to a globe tile layer's `zoomOffset`, so tile LOD
296
+ * tracks the *visual* (on-screen) scale instead of the latitude-adjusted mercator
297
+ * zoom. This cancels the pan-induced zoom drop, keeping tile detail/labels
298
+ * constant while rotating toward the poles.
299
+ */
300
+ function globeLatitudeZoomCompensation(latitude) {
301
+ if (latitude == null || !Number.isFinite(latitude)) {
302
+ return 0;
303
+ }
304
+ // Clamp away from the poles to avoid log2(0) = -Infinity at |lat| = 90.
305
+ var clamped = Math.max(-85, Math.min(85, latitude));
306
+ return zoomAdjust(0) - zoomAdjust(clamped);
307
+ }
308
+
309
+ /**
310
+ * Globe basemap tile provider.
311
+ *
312
+ * - `mapbox` uses Mapbox vector/raster tiles and requires an access token.
313
+ * - `carto` uses CARTO's free OpenMapTiles vector tiles + Esri World Imagery
314
+ * raster, and needs no token. Used as an automatic fallback when no Mapbox
315
+ * token is available (e.g. MapLibre / CARTO basemap setups), so the globe
316
+ * basemap still renders instead of showing a solid-color sphere.
317
+ */
318
+
319
+ /**
320
+ * Resolve which globe basemap tile provider to use.
321
+ *
322
+ * The globe should follow the *selected basemap style's* rendering library so
323
+ * it stays consistent with the flat 2D map: a MapLibre/CARTO style uses the
324
+ * free CARTO tiles (even when a Mapbox token is available), and a Mapbox style
325
+ * uses Mapbox tiles. A Mapbox style with no token falls back to CARTO so the
326
+ * globe still renders instead of showing a bare colored sphere.
327
+ *
328
+ * @param baseMapLibrary the selected style's library ('mapbox' | 'maplibre'),
329
+ * e.g. from `getBaseMapLibrary(currentStyle)`.
330
+ */
331
+ var resolveGlobeBasemapProvider = exports.resolveGlobeBasemapProvider = function resolveGlobeBasemapProvider(baseMapLibrary, mapboxApiAccessToken) {
332
+ if (baseMapLibrary === 'maplibre') {
333
+ return 'carto';
334
+ }
335
+ if (baseMapLibrary === 'mapbox') {
336
+ return mapboxApiAccessToken ? 'mapbox' : 'carto';
337
+ }
338
+ // Unknown library: prefer Mapbox when a token exists, otherwise CARTO.
339
+ return mapboxApiAccessToken ? 'mapbox' : 'carto';
340
+ };
341
+
342
+ // CARTO free vector tiles (OpenMapTiles schema, no API key required).
343
+ var CARTO_VECTOR_TILE_URLS = ['https://tiles-a.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt', 'https://tiles-b.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt', 'https://tiles-c.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt', 'https://tiles-d.basemaps.cartocdn.com/vectortiles/carto.streets/v1/{z}/{x}/{y}.mvt'];
344
+
345
+ // Free satellite raster fallback (Esri World Imagery, no API key required).
346
+ var ESRI_WORLD_IMAGERY_URL = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}';
347
+
348
+ /**
349
+ * Maps a raw MVT source-layer name to a normalized semantic layer kind, so the
350
+ * fill/line/label accessors work across both the Mapbox (`mapbox-streets-v8`)
351
+ * and CARTO/OpenMapTiles schemas.
352
+ *
353
+ * | semantic | mapbox | openmaptiles |
354
+ * | -------- | ------------- | ------------ |
355
+ * | water | `water` | `water` |
356
+ * | admin | `admin` | `boundary` |
357
+ * | label | `place_label` | `place` |
358
+ */
359
+
360
+ function getBasemapLayerKind(layerName) {
361
+ switch (layerName) {
362
+ case 'water':
363
+ return 'water';
364
+ case 'admin':
365
+ case 'boundary':
366
+ return 'admin';
367
+ case 'place_label':
368
+ case 'place':
369
+ return 'label';
370
+ default:
371
+ return 'other';
372
+ }
373
+ }
374
+ var MAPBOX_ATTRIBUTION = {
375
+ label: '© Mapbox',
376
+ href: 'https://www.mapbox.com/about/maps/'
377
+ };
378
+ var OSM_ATTRIBUTION = {
379
+ label: '© OpenStreetMap',
380
+ href: 'https://www.openstreetmap.org/copyright'
381
+ };
382
+ var CARTO_ATTRIBUTION = {
383
+ label: '© CARTO',
384
+ href: 'https://carto.com/attributions'
385
+ };
386
+ var ESRI_ATTRIBUTION = {
387
+ label: 'Powered by Esri',
388
+ href: 'https://www.esri.com/'
389
+ };
390
+
391
+ /**
392
+ * Resolve the tile-source attribution entries for the globe basemap. deck.gl
393
+ * renders the globe basemap tiles itself (not the base Maplibre/Mapbox map), so
394
+ * the base map's attribution machinery never sees them. This lets the UI credit
395
+ * the actual tile provider(s) in globe mode.
396
+ */
397
+ var getGlobeBasemapAttributions = exports.getGlobeBasemapAttributions = function getGlobeBasemapAttributions(_ref) {
398
+ var _globe$config;
399
+ var globe = _ref.globe,
400
+ mapboxApiAccessToken = _ref.mapboxApiAccessToken,
401
+ mapStyleType = _ref.mapStyleType,
402
+ basemapProvider = _ref.basemapProvider;
403
+ if (!(globe !== null && globe !== void 0 && globe.enabled) || !((_globe$config = globe.config) !== null && _globe$config !== void 0 && _globe$config.basemap)) {
404
+ return [];
405
+ }
406
+ var provider = basemapProvider !== null && basemapProvider !== void 0 ? basemapProvider : resolveGlobeBasemapProvider(undefined, mapboxApiAccessToken);
407
+ if (provider === 'mapbox') {
408
+ return mapboxApiAccessToken ? [MAPBOX_ATTRIBUTION, OSM_ATTRIBUTION] : [];
409
+ }
410
+ var isSatellite = mapStyleType === 'satellite' || mapStyleType === 'satellite-street';
411
+ // CARTO vector tiles are OpenStreetMap-derived; Esri imagery is credited separately.
412
+ return isSatellite ? [ESRI_ATTRIBUTION, CARTO_ATTRIBUTION, OSM_ATTRIBUTION] : [CARTO_ATTRIBUTION, OSM_ATTRIBUTION];
413
+ };
414
+
415
+ // eslint-disable-next-line complexity
416
+ var getGlobeBaseLayers = exports.getGlobeBaseLayers = function getGlobeBaseLayers(_ref2) {
417
+ var mapboxApiAccessToken = _ref2.mapboxApiAccessToken,
418
+ globe = _ref2.globe,
419
+ mapStyleType = _ref2.mapStyleType,
420
+ basemapProvider = _ref2.basemapProvider,
421
+ latitude = _ref2.latitude,
422
+ zoom = _ref2.zoom;
423
+ var config = globe.config;
424
+ var isSatellite = mapStyleType === 'satellite';
425
+ var isSatelliteStreet = mapStyleType === 'satellite-street';
426
+ var latZoomCompensation = globeLatitudeZoomCompensation(latitude);
427
+
428
+ // Fall back to the free CARTO tiles whenever no Mapbox token is available so
429
+ // the globe basemap still renders (matches kepler's default token-free
430
+ // MapLibre/CARTO basemaps). Callers should pass an explicit `basemapProvider`
431
+ // (derived from the selected style) so the globe follows the 2D basemap.
432
+ var provider = basemapProvider !== null && basemapProvider !== void 0 ? basemapProvider : resolveGlobeBasemapProvider(undefined, mapboxApiAccessToken);
433
+ var useCarto = provider === 'carto';
434
+ var hasTileAccess = useCarto || Boolean(mapboxApiAccessToken);
435
+ return [
436
+ // Huge halo behind the thin realistic limb so both can be visible together.
437
+ config.atmosphere ? (0, _atmosphereLayer.getGlobeHugeHaloLayer)({
438
+ config: config,
439
+ zoom: zoom
440
+ }) : null, config.atmosphere ? (0, _atmosphereLayer.getGlobeAtmosphereSkyLayer)({
441
+ config: config,
442
+ zoom: zoom
443
+ }) : null,
444
+ // Depth-only cross-section disk: writes depth at the globe's silhouette so
445
+ // far-side geometry (arcs/lines) is occluded by the planet.
446
+ (0, _globeDepthDiskLayer.getGlobeDepthDiskLayer)({
447
+ fillColor: config.surfaceColor
448
+ }),
449
+ // Background surface polygon
450
+ (!config.basemap || !isSatellite && !isSatelliteStreet) && new _layers.SolidPolygonLayer({
451
+ id: 'globe-background',
452
+ data: BACKGROUND_DATA,
453
+ getPolygon: function getPolygon(d) {
454
+ return d;
455
+ },
456
+ filled: true,
457
+ getFillColor: config.surfaceColor,
458
+ parameters: BACKGROUND_PARAMETERS
459
+ }),
460
+ // Fill hole at north pole
461
+ config.basemap && new _layers.SolidPolygonLayer({
462
+ id: 'globe-background-north-pole',
463
+ data: BACKGROUND_NORTH_POLE_DATA,
464
+ getPolygon: function getPolygon(d) {
465
+ return d;
466
+ },
467
+ filled: true,
468
+ getFillColor: config.water ? config.waterColor : config.surfaceColor,
469
+ parameters: BACKGROUND_PARAMETERS
470
+ }),
471
+ // Satellite tiles
472
+ config.basemap && (isSatellite || isSatelliteStreet) && hasTileAccess && new _geoLayers.TileLayer({
473
+ id: "globe-satellite-tiles-".concat(provider),
474
+ data: useCarto ? [ESRI_WORLD_IMAGERY_URL] : ["https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}@2x.png?access_token=".concat(mapboxApiAccessToken)],
475
+ minZoom: 0,
476
+ maxZoom: useCarto ? 18 : 19,
477
+ zoomOffset: GLOBE_SATELLITE_ZOOM_OFFSET + latZoomCompensation,
478
+ extent: GLOBE_TILE_EXTENT,
479
+ // Esri tiles are 256px; Mapbox @2x tiles are 512px.
480
+ tileSize: useCarto ? 256 : 512 / devicePixelRatio,
481
+ renderSubLayers: function renderSubLayers(props) {
482
+ var _props$tile$bbox = props.tile.bbox,
483
+ west = _props$tile$bbox.west,
484
+ south = _props$tile$bbox.south,
485
+ east = _props$tile$bbox.east,
486
+ north = _props$tile$bbox.north;
487
+ return [new _layers.BitmapLayer(props, {
488
+ _imageCoordinateSystem: _core.COORDINATE_SYSTEM.CARTESIAN,
489
+ data: undefined,
490
+ image: props.data,
491
+ bounds: [west, south, east, north]
492
+ })];
493
+ },
494
+ parameters: BASEMAP_RASTER_PARAMETERS
495
+ }),
496
+ // Vector basemap (MVT labels/admin/water)
497
+ config.basemap && !isSatellite && hasTileAccess && new _geoLayers.MVTLayer({
498
+ // force the layer to update when the style/label/provider config changes
499
+ id: "globe-basemap-mvt-layer-".concat(provider, "-").concat(mapStyleType),
500
+ data: useCarto ? CARTO_VECTOR_TILE_URLS : "https://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v8/{z}/{x}/{y}.vector.pbf?access_token=".concat(mapboxApiAccessToken),
501
+ minZoom: 0,
502
+ // Overzoom past the source's native max instead of 404-ing on tiles that
503
+ // don't exist (which renders as empty rectangles at high zoom).
504
+ maxZoom: useCarto ? CARTO_VECTOR_MAX_DATA_ZOOM : MAPBOX_VECTOR_MAX_DATA_ZOOM,
505
+ zoomOffset: (useCarto ? CARTO_GLOBE_VECTOR_ZOOM_OFFSET : MAPBOX_GLOBE_VECTOR_ZOOM_OFFSET) + latZoomCompensation,
506
+ extent: GLOBE_TILE_EXTENT,
507
+ binary: false,
508
+ parameters: BASEMAP_MVT_PARAMETERS,
509
+ loadOptions: useCarto ? {
510
+ // OpenMapTiles schema: `boundary` = admin lines, `place` = labels.
511
+ mvt: {
512
+ layers: isSatelliteStreet ? ['place', 'boundary'] : ['place', 'boundary', 'water', 'transportation']
513
+ }
514
+ } : {
515
+ mvt: {
516
+ layers: isSatelliteStreet ? ['place_label', 'admin'] : ['place_label', 'admin', 'water', 'road']
517
+ }
518
+ },
519
+ // Render admin/water via GeoJsonLayer and place labels via TextLayer.
520
+ config: config,
521
+ renderSubLayers: function renderSubLayers(props) {
522
+ return new _mvtLabelLayer.MVTLabelLayer(props);
523
+ },
524
+ getFillColor: function getFillColor(f) {
525
+ switch (getBasemapLayerKind(f.properties.layerName)) {
526
+ case 'water':
527
+ return config.water ? config.waterColor : INVISIBLE_COLOR;
528
+ default:
529
+ return config.surfaceColor;
530
+ }
531
+ },
532
+ getLineColor: function getLineColor(f) {
533
+ switch (getBasemapLayerKind(f.properties.layerName)) {
534
+ case 'admin':
535
+ return config.adminLines ? config.adminLinesColor : INVISIBLE_COLOR;
536
+ default:
537
+ return config.surfaceColor;
538
+ }
539
+ },
540
+ getLineWidth: function getLineWidth(f) {
541
+ switch (getBasemapLayerKind(f.properties.layerName)) {
542
+ case 'admin':
543
+ switch (f.properties.admin_level) {
544
+ case 0:
545
+ case 2:
546
+ return 1;
547
+ default:
548
+ return 0.75;
549
+ }
550
+ default:
551
+ return 0;
552
+ }
553
+ },
554
+ updateTriggers: {
555
+ getFillColor: [config.waterColor, config.surfaceColor, config.water],
556
+ getLineColor: [config.adminLinesColor, config.surfaceColor, config.adminLines]
557
+ },
558
+ lineWidthUnits: 'pixels',
559
+ lineWidthMinPixels: 0,
560
+ lineWidthMaxPixels: 20,
561
+ getPointRadius: 0,
562
+ pointRadiusMinPixels: 0
563
+ })].filter(Boolean);
564
+ };
565
+ var getGlobeTopLayers = exports.getGlobeTopLayers = function getGlobeTopLayers(_ref3) {
566
+ var globe = _ref3.globe,
567
+ zoom = _ref3.zoom;
568
+ var config = globe.config;
569
+ return [config.atmosphere ? (0, _atmosphereLayer.getGlobeAtmosphereLayer)({
570
+ config: config,
571
+ zoom: zoom
572
+ }) : null].filter(Boolean);
573
+ };
574
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29yZSIsInJlcXVpcmUiLCJfbGF5ZXJzIiwiX2dlb0xheWVycyIsIl9hdG1vc3BoZXJlTGF5ZXIiLCJfZ2xvYmVEZXB0aERpc2tMYXllciIsIl9tdnRMYWJlbExheWVyIiwiZGV2aWNlUGl4ZWxSYXRpbyIsIk1hdGgiLCJtaW4iLCJ3aW5kb3ciLCJCQUNLR1JPVU5EX1BBUkFNRVRFUlMiLCJkZXB0aFRlc3QiLCJjdWxsIiwiZGVwdGhNYXNrIiwiQkFTRU1BUF9SQVNURVJfUEFSQU1FVEVSUyIsIkJBQ0tHUk9VTkRfREFUQSIsIkJBQ0tHUk9VTkRfTk9SVEhfUE9MRV9EQVRBIiwiREVGQVVMVF9CQVNFTUFQX0NPTE9SIiwiZXhwb3J0cyIsImJhY2tncm91bmRGaWxsQ29sb3IiLCJiYXNlbWFwRGVmYXVsdEZpbGxDb2xvciIsImJhc2VtYXBXYXRlckZpbGxDb2xvciIsImJhc2VtYXBEZWZhdWx0TGluZUNvbG9yIiwiYmFzZW1hcEFkbWluTGluZUNvbG9yIiwiYmFzZW1hcExhYmVsQ29sb3IiLCJnZXRQYWludENvbG9yIiwiY29sb3IiLCJBcnJheSIsImlzQXJyYXkiLCJjb2xvclN0cmluZ1RvUkdCIiwiaHNsTWF0Y2giLCJtYXRjaCIsImgiLCJwYXJzZUludCIsInMiLCJsIiwiciIsImciLCJiIiwiaHVlMnJnYiIsInAiLCJxIiwidCIsInJvdW5kIiwicmdiTWF0Y2giLCJoZXhNYXRjaCIsImhleCIsInNsaWNlIiwiZmluZEZpcnN0TGF5ZXJCeUdyb3VwIiwibGF5ZXJzIiwibGF5ZXJHcm91cHMiLCJncm91cFNsdWciLCJsYXllckdyb3VwIiwiZmluZCIsImdyb3VwIiwic2x1ZyIsImxheWVyIiwiZmlsdGVyIiwiZmluZEJhY2tncm91bmRDb2xvciIsInN0eWxlIiwiX2ZvdW5kIiwiZm91bmQiLCJpZCIsInR5cGUiLCJwYWludCIsImZpbmRXYXRlckNvbG9yIiwiX2ZvdW5kJHBhaW50IiwiZmluZEFkbWluQ29sb3IiLCJfYm9yZGVyTGF5ZXJzJHBhaW50IiwiYm9yZGVyTGF5ZXJzIiwibHlyIiwiZmluZExhYmVsQ29sb3IiLCJfbGFiZWxMYXllciIsImxhYmVsTGF5ZXIiLCJnZXRCYXNlbWFwQ29sb3JzIiwibWFwU3R5bGUiLCJfZmluZEJhY2tncm91bmRDb2xvciIsIl9maW5kV2F0ZXJDb2xvciIsIl9maW5kQWRtaW5Db2xvciIsIl9maW5kTGFiZWxDb2xvciIsIl9tYXBTdHlsZSRzdHlsZSIsInN0eWxlSnNvbiIsIl9tYXBTdHlsZSRsYXllckdyb3VwcyIsIktOT1dOX1NUWUxFX0NPTE9SUyIsImRhcmsiLCJsaWdodCIsInBvc2l0cm9uIiwidm95YWdlciIsIm11dGVkIiwibXV0ZWRfbmlnaHQiLCJnZXRCYXNlbWFwQ29sb3JzRm9yU3R5bGUiLCJzdHlsZVR5cGUiLCJfbWFwU3R5bGUkc3R5bGUyIiwibGVuZ3RoIiwiZ2V0R2xvYmVDbGVhckNvbG9yIiwiYmFja2dyb3VuZENvbG9yIiwiSU5WSVNJQkxFX0NPTE9SIiwiQkFTRU1BUF9NVlRfUEFSQU1FVEVSUyIsIk1BUEJPWF9HTE9CRV9WRUNUT1JfWk9PTV9PRkZTRVQiLCJDQVJUT19HTE9CRV9WRUNUT1JfWk9PTV9PRkZTRVQiLCJHTE9CRV9TQVRFTExJVEVfWk9PTV9PRkZTRVQiLCJHTE9CRV9USUxFX0VYVEVOVCIsIk1BUEJPWF9WRUNUT1JfTUFYX0RBVEFfWk9PTSIsIkNBUlRPX1ZFQ1RPUl9NQVhfREFUQV9aT09NIiwiem9vbUFkanVzdCIsImxhdGl0dWRlIiwibG9nMiIsIlBJIiwiY29zIiwiZ2xvYmVMYXRpdHVkZVpvb21Db21wZW5zYXRpb24iLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImNsYW1wZWQiLCJtYXgiLCJyZXNvbHZlR2xvYmVCYXNlbWFwUHJvdmlkZXIiLCJiYXNlTWFwTGlicmFyeSIsIm1hcGJveEFwaUFjY2Vzc1Rva2VuIiwiQ0FSVE9fVkVDVE9SX1RJTEVfVVJMUyIsIkVTUklfV09STERfSU1BR0VSWV9VUkwiLCJnZXRCYXNlbWFwTGF5ZXJLaW5kIiwibGF5ZXJOYW1lIiwiTUFQQk9YX0FUVFJJQlVUSU9OIiwibGFiZWwiLCJocmVmIiwiT1NNX0FUVFJJQlVUSU9OIiwiQ0FSVE9fQVRUUklCVVRJT04iLCJFU1JJX0FUVFJJQlVUSU9OIiwiZ2V0R2xvYmVCYXNlbWFwQXR0cmlidXRpb25zIiwiX3JlZiIsIl9nbG9iZSRjb25maWciLCJnbG9iZSIsIm1hcFN0eWxlVHlwZSIsImJhc2VtYXBQcm92aWRlciIsImVuYWJsZWQiLCJjb25maWciLCJiYXNlbWFwIiwicHJvdmlkZXIiLCJ1bmRlZmluZWQiLCJpc1NhdGVsbGl0ZSIsImdldEdsb2JlQmFzZUxheWVycyIsIl9yZWYyIiwiem9vbSIsImlzU2F0ZWxsaXRlU3RyZWV0IiwibGF0Wm9vbUNvbXBlbnNhdGlvbiIsInVzZUNhcnRvIiwiaGFzVGlsZUFjY2VzcyIsIkJvb2xlYW4iLCJhdG1vc3BoZXJlIiwiZ2V0R2xvYmVIdWdlSGFsb0xheWVyIiwiZ2V0R2xvYmVBdG1vc3BoZXJlU2t5TGF5ZXIiLCJnZXRHbG9iZURlcHRoRGlza0xheWVyIiwiZmlsbENvbG9yIiwic3VyZmFjZUNvbG9yIiwiU29saWRQb2x5Z29uTGF5ZXIiLCJkYXRhIiwiZ2V0UG9seWdvbiIsImQiLCJmaWxsZWQiLCJnZXRGaWxsQ29sb3IiLCJwYXJhbWV0ZXJzIiwid2F0ZXIiLCJ3YXRlckNvbG9yIiwiVGlsZUxheWVyIiwiY29uY2F0IiwibWluWm9vbSIsIm1heFpvb20iLCJ6b29tT2Zmc2V0IiwiZXh0ZW50IiwidGlsZVNpemUiLCJyZW5kZXJTdWJMYXllcnMiLCJwcm9wcyIsIl9wcm9wcyR0aWxlJGJib3giLCJ0aWxlIiwiYmJveCIsIndlc3QiLCJzb3V0aCIsImVhc3QiLCJub3J0aCIsIkJpdG1hcExheWVyIiwiX2ltYWdlQ29vcmRpbmF0ZVN5c3RlbSIsIkNPT1JESU5BVEVfU1lTVEVNIiwiQ0FSVEVTSUFOIiwiaW1hZ2UiLCJib3VuZHMiLCJNVlRMYXllciIsImJpbmFyeSIsImxvYWRPcHRpb25zIiwibXZ0IiwiTVZUTGFiZWxMYXllciIsImYiLCJwcm9wZXJ0aWVzIiwiZ2V0TGluZUNvbG9yIiwiYWRtaW5MaW5lcyIsImFkbWluTGluZXNDb2xvciIsImdldExpbmVXaWR0aCIsImFkbWluX2xldmVsIiwidXBkYXRlVHJpZ2dlcnMiLCJsaW5lV2lkdGhVbml0cyIsImxpbmVXaWR0aE1pblBpeGVscyIsImxpbmVXaWR0aE1heFBpeGVscyIsImdldFBvaW50UmFkaXVzIiwicG9pbnRSYWRpdXNNaW5QaXhlbHMiLCJnZXRHbG9iZVRvcExheWVycyIsIl9yZWYzIiwiZ2V0R2xvYmVBdG1vc3BoZXJlTGF5ZXIiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZ2xvYmUvZ2xvYmUtbGF5ZXJzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCB7Q09PUkRJTkFURV9TWVNURU0sIExheWVyfSBmcm9tICdAZGVjay5nbC9jb3JlJztcbmltcG9ydCB7U29saWRQb2x5Z29uTGF5ZXIsIEJpdG1hcExheWVyfSBmcm9tICdAZGVjay5nbC9sYXllcnMnO1xuaW1wb3J0IHtUaWxlTGF5ZXIsIE1WVExheWVyfSBmcm9tICdAZGVjay5nbC9nZW8tbGF5ZXJzJztcblxuaW1wb3J0IHR5cGUge0dsb2JlfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQgdHlwZSB7UkdCQ29sb3J9IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuXG5pbXBvcnQge2dldEdsb2JlQXRtb3NwaGVyZUxheWVyLCBnZXRHbG9iZUF0bW9zcGhlcmVTa3lMYXllciwgZ2V0R2xvYmVIdWdlSGFsb0xheWVyfSBmcm9tICcuL2F0bW9zcGhlcmUtbGF5ZXInO1xuaW1wb3J0IHtnZXRHbG9iZURlcHRoRGlza0xheWVyfSBmcm9tICcuL2dsb2JlLWRlcHRoLWRpc2stbGF5ZXInO1xuaW1wb3J0IHtNVlRMYWJlbExheWVyfSBmcm9tICcuL212dC1sYWJlbC1sYXllcic7XG5cbnR5cGUgTGF5ZXJHcm91cCA9IHtzbHVnOiBzdHJpbmc7IGZpbHRlcjogKGxheWVyOiBhbnkpID0+IGJvb2xlYW59O1xuXG5jb25zdCBkZXZpY2VQaXhlbFJhdGlvID0gTWF0aC5taW4oXG4gIDIsXG4gICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbykgfHwgMVxuKTtcblxuY29uc3QgQkFDS0dST1VORF9QQVJBTUVURVJTID0ge1xuICBkZXB0aFRlc3Q6IHRydWUsXG4gIGN1bGw6IHRydWUsXG4gIGRlcHRoTWFzazogZmFsc2Vcbn07XG5cbmNvbnN0IEJBU0VNQVBfUkFTVEVSX1BBUkFNRVRFUlMgPSB7XG4gIGRlcHRoTWFzazogZmFsc2Vcbn07XG5cbmNvbnN0IEJBQ0tHUk9VTkRfREFUQSA9IFtcbiAgW1xuICAgIFstMTgwLCA5MF0sXG4gICAgWzAsIDkwXSxcbiAgICBbMTgwLCA5MF0sXG4gICAgWzE4MCwgLTkwXSxcbiAgICBbMCwgLTkwXSxcbiAgICBbLTE4MCwgLTkwXVxuICBdXG5dO1xuXG5jb25zdCBCQUNLR1JPVU5EX05PUlRIX1BPTEVfREFUQSA9IFtcbiAgW1xuICAgIFstMTgwLCA5MF0sXG4gICAgWzAsIDkwXSxcbiAgICBbMTgwLCA5MF0sXG4gICAgWzE4MCwgODVdLFxuICAgIFswLCA4NV0sXG4gICAgWy0xODAsIDg1XVxuICBdXG5dO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9CQVNFTUFQX0NPTE9SID0ge1xuICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBbOSwgMTYsIDI5XSBhcyBSR0JDb2xvcixcbiAgYmFzZW1hcERlZmF1bHRGaWxsQ29sb3I6IFsyNTUsIDI1NSwgMjU1XSBhcyBSR0JDb2xvcixcbiAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBbMTcsIDM1LCA0OF0gYXMgUkdCQ29sb3IsXG4gIGJhc2VtYXBEZWZhdWx0TGluZUNvbG9yOiBbNDAsIDYzLCA5M10gYXMgUkdCQ29sb3IsXG4gIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogWzQwLCA2MywgOTNdIGFzIFJHQkNvbG9yLFxuICBiYXNlbWFwTGFiZWxDb2xvcjogWzExNC43NSwgMTE0Ljc1LCAxMTQuNzVdIGFzIFJHQkNvbG9yXG59O1xuXG5mdW5jdGlvbiBnZXRQYWludENvbG9yKGNvbG9yOiBhbnkpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoY29sb3IpICYmIGNvbG9yWzBdID09PSAnaW50ZXJwb2xhdGUnKSB7XG4gICAgcmV0dXJuIGNvbG9yWzRdO1xuICB9XG4gIHJldHVybiBjb2xvcjtcbn1cblxuZnVuY3Rpb24gY29sb3JTdHJpbmdUb1JHQihjb2xvcjogc3RyaW5nIHwgbnVsbCk6IFJHQkNvbG9yIHwgbnVsbCB7XG4gIGlmICghY29sb3IpIHJldHVybiBudWxsO1xuICBpZiAodHlwZW9mIGNvbG9yICE9PSAnc3RyaW5nJykgcmV0dXJuIG51bGw7XG5cbiAgLy8gSGFuZGxlIGhzbCgpIGZvcm1hdFxuICBjb25zdCBoc2xNYXRjaCA9IGNvbG9yLm1hdGNoKC9oc2xcXChcXHMqKFxcZCspXFxzKixcXHMqKFxcZCspJVxccyosXFxzKihcXGQrKSVcXHMqXFwpLyk7XG4gIGlmIChoc2xNYXRjaCkge1xuICAgIGNvbnN0IGggPSBwYXJzZUludChoc2xNYXRjaFsxXSwgMTApIC8gMzYwO1xuICAgIGNvbnN0IHMgPSBwYXJzZUludChoc2xNYXRjaFsyXSwgMTApIC8gMTAwO1xuICAgIGNvbnN0IGwgPSBwYXJzZUludChoc2xNYXRjaFszXSwgMTApIC8gMTAwO1xuICAgIC8vIEhTTCB0byBSR0IgY29udmVyc2lvblxuICAgIGxldCByOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyO1xuICAgIGlmIChzID09PSAwKSB7XG4gICAgICByID0gZyA9IGIgPSBsO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBodWUycmdiID0gKHA6IG51bWJlciwgcTogbnVtYmVyLCB0OiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKHQgPCAwKSB0ICs9IDE7XG4gICAgICAgIGlmICh0ID4gMSkgdCAtPSAxO1xuICAgICAgICBpZiAodCA8IDEgLyA2KSByZXR1cm4gcCArIChxIC0gcCkgKiA2ICogdDtcbiAgICAgICAgaWYgKHQgPCAxIC8gMikgcmV0dXJuIHE7XG4gICAgICAgIGlmICh0IDwgMiAvIDMpIHJldHVybiBwICsgKHEgLSBwKSAqICgyIC8gMyAtIHQpICogNjtcbiAgICAgICAgcmV0dXJuIHA7XG4gICAgICB9O1xuICAgICAgY29uc3QgcSA9IGwgPCAwLjUgPyBsICogKDEgKyBzKSA6IGwgKyBzIC0gbCAqIHM7XG4gICAgICBjb25zdCBwID0gMiAqIGwgLSBxO1xuICAgICAgciA9IGh1ZTJyZ2IocCwgcSwgaCArIDEgLyAzKTtcbiAgICAgIGcgPSBodWUycmdiKHAsIHEsIGgpO1xuICAgICAgYiA9IGh1ZTJyZ2IocCwgcSwgaCAtIDEgLyAzKTtcbiAgICB9XG4gICAgcmV0dXJuIFtNYXRoLnJvdW5kKHIgKiAyNTUpLCBNYXRoLnJvdW5kKGcgKiAyNTUpLCBNYXRoLnJvdW5kKGIgKiAyNTUpXSBhcyBSR0JDb2xvcjtcbiAgfVxuXG4gIC8vIEhhbmRsZSByZ2IoKSBmb3JtYXRcbiAgY29uc3QgcmdiTWF0Y2ggPSBjb2xvci5tYXRjaCgvcmdiXFwoXFxzKihcXGQrKVxccyosXFxzKihcXGQrKVxccyosXFxzKihcXGQrKVxccypcXCkvKTtcbiAgaWYgKHJnYk1hdGNoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHBhcnNlSW50KHJnYk1hdGNoWzFdLCAxMCksXG4gICAgICBwYXJzZUludChyZ2JNYXRjaFsyXSwgMTApLFxuICAgICAgcGFyc2VJbnQocmdiTWF0Y2hbM10sIDEwKVxuICAgIF0gYXMgUkdCQ29sb3I7XG4gIH1cblxuICAvLyBIYW5kbGUgaGV4IGZvcm1hdFxuICBjb25zdCBoZXhNYXRjaCA9IGNvbG9yLm1hdGNoKC9eIyhbMC05YS1mXXs2fSkkL2kpO1xuICBpZiAoaGV4TWF0Y2gpIHtcbiAgICBjb25zdCBoZXggPSBoZXhNYXRjaFsxXTtcbiAgICByZXR1cm4gW1xuICAgICAgcGFyc2VJbnQoaGV4LnNsaWNlKDAsIDIpLCAxNiksXG4gICAgICBwYXJzZUludChoZXguc2xpY2UoMiwgNCksIDE2KSxcbiAgICAgIHBhcnNlSW50KGhleC5zbGljZSg0LCA2KSwgMTYpXG4gICAgXSBhcyBSR0JDb2xvcjtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaW5kRmlyc3RMYXllckJ5R3JvdXAobGF5ZXJzOiBhbnlbXSwgbGF5ZXJHcm91cHM6IExheWVyR3JvdXBbXSwgZ3JvdXBTbHVnOiBzdHJpbmcpIHtcbiAgY29uc3QgbGF5ZXJHcm91cCA9IGxheWVyR3JvdXBzLmZpbmQoZ3JvdXAgPT4gZ3JvdXAuc2x1ZyA9PT0gZ3JvdXBTbHVnKTtcbiAgaWYgKCFsYXllckdyb3VwKSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIGxheWVycy5maW5kKGxheWVyID0+IGxheWVyR3JvdXAuZmlsdGVyKGxheWVyKSk7XG59XG5cbmZ1bmN0aW9uIGZpbmRCYWNrZ3JvdW5kQ29sb3Ioc3R5bGU6IGFueSk6IFJHQkNvbG9yIHwgbnVsbCB7XG4gIGxldCBmb3VuZCA9IHN0eWxlLmxheWVycy5maW5kKChsOiBhbnkpID0+IGwuaWQgPT09ICdiYWNrZ3JvdW5kJyB8fCBsLmlkID09PSAnbGFuZCcpO1xuICBmb3VuZCA9IGZvdW5kIHx8IHN0eWxlLmxheWVycy5maW5kKChsOiBhbnkpID0+IGwudHlwZSA9PT0gJ2JhY2tncm91bmQnKTtcbiAgcmV0dXJuIGNvbG9yU3RyaW5nVG9SR0IoZ2V0UGFpbnRDb2xvcihmb3VuZD8ucGFpbnQ/LlsnYmFja2dyb3VuZC1jb2xvciddKSk7XG59XG5cbmZ1bmN0aW9uIGZpbmRXYXRlckNvbG9yKHN0eWxlOiBhbnksIGxheWVyR3JvdXBzOiBMYXllckdyb3VwW10pOiBSR0JDb2xvciB8IG51bGwge1xuICBjb25zdCBmb3VuZCA9XG4gICAgc3R5bGUubGF5ZXJzLmZpbmQoKGw6IGFueSkgPT4gbC5pZCA9PT0gJ3dhdGVyJykgfHxcbiAgICBmaW5kRmlyc3RMYXllckJ5R3JvdXAoc3R5bGUubGF5ZXJzLCBsYXllckdyb3VwcywgJ3dhdGVyJyk7XG4gIHJldHVybiBjb2xvclN0cmluZ1RvUkdCKGZvdW5kPy5wYWludD8uWydmaWxsLWNvbG9yJ10pO1xufVxuXG5mdW5jdGlvbiBmaW5kQWRtaW5Db2xvcihzdHlsZTogYW55LCBsYXllckdyb3VwczogTGF5ZXJHcm91cFtdKTogUkdCQ29sb3IgfCBudWxsIHtcbiAgY29uc3QgYm9yZGVyTGF5ZXJzID1cbiAgICBzdHlsZS5sYXllcnMuZmluZCgobHlyOiBhbnkpID0+IGx5ci5pZCA9PT0gJ2FkbWluLTMtNC1ib3VuZGFyaWVzJykgfHxcbiAgICBmaW5kRmlyc3RMYXllckJ5R3JvdXAoc3R5bGUubGF5ZXJzLCBsYXllckdyb3VwcywgJ2JvcmRlcicpO1xuICByZXR1cm4gY29sb3JTdHJpbmdUb1JHQihib3JkZXJMYXllcnM/LnBhaW50Py5bJ2xpbmUtY29sb3InXSk7XG59XG5cbmZ1bmN0aW9uIGZpbmRMYWJlbENvbG9yKHN0eWxlOiBhbnksIGxheWVyR3JvdXBzOiBMYXllckdyb3VwW10pOiBSR0JDb2xvciB8IG51bGwge1xuICBsZXQgbGFiZWxMYXllciA9IHN0eWxlLmxheWVycy5maW5kKFxuICAgIChseXI6IGFueSkgPT4gbHlyLmlkID09PSAnY291bnRyeS1sYWJlbC1sZycgJiYgbHlyLnR5cGUgPT09ICdzeW1ib2wnXG4gICk7XG4gIGxhYmVsTGF5ZXIgPVxuICAgIGxhYmVsTGF5ZXIgfHxcbiAgICBzdHlsZS5sYXllcnMuZmluZCgobHlyOiBhbnkpID0+IGx5ci5pZCA9PT0gJ2NvdW50cnktbGFiZWwnICYmIGx5ci50eXBlID09PSAnc3ltYm9sJyk7XG4gIGxhYmVsTGF5ZXIgPSBsYWJlbExheWVyIHx8IGZpbmRGaXJzdExheWVyQnlHcm91cChzdHlsZS5sYXllcnMsIGxheWVyR3JvdXBzLCAnbGFiZWwnKTtcbiAgcmV0dXJuIGNvbG9yU3RyaW5nVG9SR0IobGFiZWxMYXllcj8ucGFpbnQ/LlsndGV4dC1jb2xvciddKTtcbn1cblxuZXhwb3J0IGNvbnN0IGdldEJhc2VtYXBDb2xvcnMgPSAoXG4gIG1hcFN0eWxlOiBQYXJ0aWFsPHtzdHlsZTogYW55OyBsYXllckdyb3VwczogTGF5ZXJHcm91cFtdfT5cbik6IHtcbiAgYmFja2dyb3VuZEZpbGxDb2xvcjogUkdCQ29sb3I7XG4gIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogUkdCQ29sb3I7XG4gIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogUkdCQ29sb3I7XG4gIGJhc2VtYXBMYWJlbENvbG9yOiBSR0JDb2xvcjtcbn0gPT4ge1xuICBjb25zdCB7c3R5bGU6IHN0eWxlSnNvbiA9IHtsYXllcnM6IFtdfSwgbGF5ZXJHcm91cHMgPSBbXX0gPSBtYXBTdHlsZTtcblxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRGaWxsQ29sb3I6XG4gICAgICBmaW5kQmFja2dyb3VuZENvbG9yKHN0eWxlSnNvbikgPz8gREVGQVVMVF9CQVNFTUFQX0NPTE9SLmJhY2tncm91bmRGaWxsQ29sb3IsXG4gICAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOlxuICAgICAgZmluZFdhdGVyQ29sb3Ioc3R5bGVKc29uLCBsYXllckdyb3VwcykgPz8gREVGQVVMVF9CQVNFTUFQX0NPTE9SLmJhc2VtYXBXYXRlckZpbGxDb2xvcixcbiAgICBiYXNlbWFwQWRtaW5MaW5lQ29sb3I6XG4gICAgICBmaW5kQWRtaW5Db2xvcihzdHlsZUpzb24sIGxheWVyR3JvdXBzKSA/PyBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFzZW1hcEFkbWluTGluZUNvbG9yLFxuICAgIGJhc2VtYXBMYWJlbENvbG9yOlxuICAgICAgZmluZExhYmVsQ29sb3Ioc3R5bGVKc29uLCBsYXllckdyb3VwcykgPz8gREVGQVVMVF9CQVNFTUFQX0NPTE9SLmJhc2VtYXBMYWJlbENvbG9yXG4gIH07XG59O1xuXG4vLyBQcmVkZWZpbmVkIGNvbG9yIHNjaGVtZXMgZm9yIHdlbGwta25vd24gYmFzZW1hcCBzdHlsZXNcbmNvbnN0IEtOT1dOX1NUWUxFX0NPTE9SUzogUmVjb3JkPFxuICBzdHJpbmcsXG4gIHtcbiAgICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBSR0JDb2xvcjtcbiAgICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IFJHQkNvbG9yO1xuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogUkdCQ29sb3I7XG4gICAgYmFzZW1hcExhYmVsQ29sb3I6IFJHQkNvbG9yO1xuICB9XG4+ID0ge1xuICBkYXJrOiB7XG4gICAgYmFja2dyb3VuZEZpbGxDb2xvcjogWzE1LCAxNSwgMTVdLFxuICAgIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogWzEwLCAyMCwgMzVdLFxuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogWzYwLCA2MCwgODBdLFxuICAgIGJhc2VtYXBMYWJlbENvbG9yOiBbMTUwLCAxNTAsIDE1MF1cbiAgfSxcbiAgJ2RhcmstbWF0dGVyJzoge1xuICAgIGJhY2tncm91bmRGaWxsQ29sb3I6IFsxOCwgMTgsIDE4XSxcbiAgICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IFsxNCwgMTksIDI5XSxcbiAgICBiYXNlbWFwQWRtaW5MaW5lQ29sb3I6IFs1MCwgNTAsIDYwXSxcbiAgICBiYXNlbWFwTGFiZWxDb2xvcjogWzEzMCwgMTMwLCAxMzBdXG4gIH0sXG4gIGxpZ2h0OiB7XG4gICAgYmFja2dyb3VuZEZpbGxDb2xvcjogWzIzNSwgMjMzLCAyMjhdLFxuICAgIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogWzE3MCwgMjExLCAyMjNdLFxuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogWzE4MCwgMTc1LCAxNzBdLFxuICAgIGJhc2VtYXBMYWJlbENvbG9yOiBbODAsIDgwLCA4MF1cbiAgfSxcbiAgcG9zaXRyb246IHtcbiAgICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBbMjQyLCAyMzksIDIzM10sXG4gICAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBbMTc0LCAyMDksIDIyMF0sXG4gICAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBbMTkwLCAxODUsIDE4MF0sXG4gICAgYmFzZW1hcExhYmVsQ29sb3I6IFs5MCwgOTAsIDkwXVxuICB9LFxuICB2b3lhZ2VyOiB7XG4gICAgYmFja2dyb3VuZEZpbGxDb2xvcjogWzIzNCwgMjI5LCAyMjBdLFxuICAgIGJhc2VtYXBXYXRlckZpbGxDb2xvcjogWzE3MCwgMjExLCAyMjNdLFxuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogWzE4MCwgMTcwLCAxNjBdLFxuICAgIGJhc2VtYXBMYWJlbENvbG9yOiBbNzAsIDcwLCA3MF1cbiAgfSxcbiAgbXV0ZWQ6IHtcbiAgICBiYWNrZ3JvdW5kRmlsbENvbG9yOiBbMjI1LCAyMjUsIDIxOF0sXG4gICAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBbMTgwLCAyMTAsIDIyMF0sXG4gICAgYmFzZW1hcEFkbWluTGluZUNvbG9yOiBbMTcwLCAxNjUsIDE2MF0sXG4gICAgYmFzZW1hcExhYmVsQ29sb3I6IFs5MCwgOTAsIDkwXVxuICB9LFxuICBtdXRlZF9uaWdodDoge1xuICAgIGJhY2tncm91bmRGaWxsQ29sb3I6IFsyMiwgMjYsIDMwXSxcbiAgICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IFsxNSwgMjUsIDQwXSxcbiAgICBiYXNlbWFwQWRtaW5MaW5lQ29sb3I6IFs1NSwgNjAsIDcwXSxcbiAgICBiYXNlbWFwTGFiZWxDb2xvcjogWzE0MCwgMTQwLCAxNDBdXG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGJhc2VtYXAgY29sb3JzIGVpdGhlciBmcm9tIHRoZSBzdHlsZSBKU09OIG9yIGZyb20ga25vd24gc3R5bGUgcHJlc2V0cy5cbiAqIEZhbGxzIGJhY2sgdG8gZGVmYXVsdCBkYXJrIGNvbG9ycyBpZiBzdHlsZSBpcyB1bmtub3duIGFuZCBubyBKU09OIGlzIGF2YWlsYWJsZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEJhc2VtYXBDb2xvcnNGb3JTdHlsZSA9IChcbiAgc3R5bGVUeXBlOiBzdHJpbmcsXG4gIG1hcFN0eWxlPzogUGFydGlhbDx7c3R5bGU6IGFueTsgbGF5ZXJHcm91cHM6IExheWVyR3JvdXBbXX0+XG4pOiB7XG4gIGJhY2tncm91bmRGaWxsQ29sb3I6IFJHQkNvbG9yO1xuICBiYXNlbWFwV2F0ZXJGaWxsQ29sb3I6IFJHQkNvbG9yO1xuICBiYXNlbWFwQWRtaW5MaW5lQ29sb3I6IFJHQkNvbG9yO1xuICBiYXNlbWFwTGFiZWxDb2xvcjogUkdCQ29sb3I7XG59ID0+IHtcbiAgLy8gVHJ5IHRvIGV4dHJhY3QgZnJvbSBzdHlsZSBKU09OIGZpcnN0XG4gIGlmIChtYXBTdHlsZT8uc3R5bGU/LmxheWVycz8ubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGdldEJhc2VtYXBDb2xvcnMobWFwU3R5bGUpO1xuICB9XG4gIC8vIEZhbGwgYmFjayB0byBrbm93biBzdHlsZSBwcmVzZXRzXG4gIGlmIChLTk9XTl9TVFlMRV9DT0xPUlNbc3R5bGVUeXBlXSkge1xuICAgIHJldHVybiBLTk9XTl9TVFlMRV9DT0xPUlNbc3R5bGVUeXBlXTtcbiAgfVxuICAvLyBEZWZhdWx0IGRhcmsgY29sb3JzXG4gIHJldHVybiB7XG4gICAgYmFja2dyb3VuZEZpbGxDb2xvcjogREVGQVVMVF9CQVNFTUFQX0NPTE9SLmJhY2tncm91bmRGaWxsQ29sb3IsXG4gICAgYmFzZW1hcFdhdGVyRmlsbENvbG9yOiBERUZBVUxUX0JBU0VNQVBfQ09MT1IuYmFzZW1hcFdhdGVyRmlsbENvbG9yLFxuICAgIGJhc2VtYXBBZG1pbkxpbmVDb2xvcjogREVGQVVMVF9CQVNFTUFQX0NPTE9SLmJhc2VtYXBBZG1pbkxpbmVDb2xvcixcbiAgICBiYXNlbWFwTGFiZWxDb2xvcjogREVGQVVMVF9CQVNFTUFQX0NPTE9SLmJhc2VtYXBMYWJlbENvbG9yXG4gIH07XG59O1xuXG4vKipcbiAqIENsZWFyIGNvbG9yIChiYWNrZ3JvdW5kIGFyb3VuZCB0aGUgZ2xvYmUpIGZvciBnbG9iZSBtb2RlLCBpbiBSR0JBIDAtMjU1IGFzXG4gKiBleHBlY3RlZCBieSBkZWNrLmdsJ3MgVmlldyBgY2xlYXJDb2xvcmAgcHJvcCAoZGVjay5nbCA+PSA5IG5vIGxvbmdlciBzdXBwb3J0c1xuICogdGhlIGdsb2JhbCBgcGFyYW1ldGVycy5jbGVhckNvbG9yYDsgaXQgbXVzdCBiZSBzZXQgcGVyLXZpZXcgd2l0aCBgY2xlYXI6IHRydWVgKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdsb2JlQ2xlYXJDb2xvcihcbiAgYmFja2dyb3VuZENvbG9yPzogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVtYmVyW11cbik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdIHtcbiAgaWYgKGJhY2tncm91bmRDb2xvcikge1xuICAgIHJldHVybiBbYmFja2dyb3VuZENvbG9yWzBdLCBiYWNrZ3JvdW5kQ29sb3JbMV0sIGJhY2tncm91bmRDb2xvclsyXSwgMjU1XTtcbiAgfVxuICAvLyBEZWZhdWx0IG1hdGNoZXMgdGhlIHByZXZpb3VzIGhhcmRjb2RlZCBjbGVhciBjb2xvciBbMC4wMTUsIDAuMDM1LCAwLjA2NV0gaW4gMC0xIHNwYWNlLlxuICByZXR1cm4gWzQsIDksIDE3LCAyNTVdO1xufVxuXG5jb25zdCBJTlZJU0lCTEVfQ09MT1I6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzAsIDAsIDAsIDBdO1xuXG5jb25zdCBCQVNFTUFQX01WVF9QQVJBTUVURVJTID0ge1xuICAvLyBPY2NsdWRlIHRoZSBmYXIgc2lkZSBvZiB0aGUgZ2xvYmUgdmlhIHRoZSBERVBUSCBESVNLIChnZXRHbG9iZURlcHRoRGlza0xheWVyKVxuICAvLyByYXRoZXIgdGhhbiBiYWNrLWZhY2UgY3VsbGluZy4gR2xvYmUgbW9kZSBzZXRzIGEgZ2xvYmFsIGBjdWxsOiB0cnVlYCBmb3IgdGhlXG4gIC8vIG9wYXF1ZSBzcGhlcmUgc3VyZmFjZSwgYnV0IGJhY2stZmFjZSBjdWxsaW5nIHJlbGllcyBvbiBzdGFibGUgdHJpYW5nbGVcbiAgLy8gd2luZGluZyDigJQgYW5kIGRlY2suZ2wgOSdzIGdsb2JlIHByb2plY3Rpb24gbG9zZXMgcHJlY2lzaW9uIGF0IGhpZ2ggem9vbVxuICAvLyAoZmxvYXQzMiksIGZsaXBwaW5nIHRoZSB3aW5kaW5nIG9mIHRoZSBzbWFsbCBhZG1pbi93YXRlciB0cmlhbmdsZXMgc28gdGhleVxuICAvLyBnZXQgd3JvbmdseSBjdWxsZWQgYW5kIHRoZSBnZW9tZXRyeSB2YW5pc2hlcyBwYXN0IH56b29tIDEyICh5b3UgdGhlbiBzZWVcbiAgLy8gdGhyb3VnaCB0byB0aGUgZmFyIHNpZGUgLyBcImRpZmZlcmVudCBnZW9tZXRyeVwiKS4gRGVwdGggdGVzdGluZyBhZ2FpbnN0IHRoZSBkaXNrXG4gIC8vIGlzIGEgcHJlY2lzaW9uLXJvYnVzdCBvY2NsdWRlciB0aGF0IHdvcmtzIGF0IGFueSB6b29tLCBzbzpcbiAgLy8gICAtIGN1bGw6IGZhbHNlICAgICDihpIgZG9uJ3Qgd2luZGluZy1jdWxsIHRoZSBuZWFyLXNpZGUgZ2VvbWV0cnlcbiAgLy8gICAtIGRlcHRoVGVzdDogdHJ1ZSDihpIgZmFyLXNpZGUgZ2VvbWV0cnkgKGJlaGluZCB0aGUgZGlzaykgZmFpbHMgZGVwdGgsIGhpZGRlblxuICAvLyAgIC0gZGVwdGhNYXNrOiBmYWxzZSDihpIgZG9uJ3Qgd3JpdGUgZGVwdGggKGF2b2lkIHNlbGYgei1maWdodGluZyBvbiB0aGUgc2hlbGwpXG4gIC8vIFJhc3RlciB0aWxlcyBhcmUgdW5hZmZlY3RlZCAodGhlaXIgNC1jb3JuZXIgcXVhZHMga2VlcCBzdGFibGUgd2luZGluZyksIHdoaWNoXG4gIC8vIGlzIHdoeSBzYXRlbGxpdGUgYWxyZWFkeSB6b29tcyB0byBtYXggY2xlYW5seS4gTGFiZWxzIGRpc2FibGUgY3VsbCBmb3IgdGhlXG4gIC8vIHNhbWUgcmVhc29uIChzZWUgbXZ0LWxhYmVsLWxheWVyLnRzKS5cbiAgZGVwdGhUZXN0OiB0cnVlLFxuICBkZXB0aE1hc2s6IGZhbHNlLFxuICBjdWxsOiBmYWxzZVxufTtcblxuLy8gZGVjay5nbCA5J3MgZ2xvYmUgc2VsZWN0cyBmaW5lciB0aWxlcyB0aGFuIG5lZWRlZCBmb3IgYSBnaXZlbiB2aWV3IChpdHNcbi8vIEdsb2JlVmlld3BvcnQgc2NhbGUgaXMgfjN4IHNtYWxsZXIgdGhhbiB0aGUgZXF1aXZhbGVudCBtZXJjYXRvciB6b29tKSwgc28gYmlhc1xuLy8gdmVjdG9yIHRpbGUgc2VsZWN0aW9uIGNvYXJzZXIgdG8ga2VlcCB0aGUgdGlsZSBjb3VudCDigJQgYW5kIHRodXMgcGVyZm9ybWFuY2Ug4oCUXG4vLyBpbiBjaGVjay4gVGhpcyB0cmFkZXMgYSBsaXR0bGUgZGV0YWlsIGZvciBmYXIgZmV3ZXIgdGlsZXM7IG1ha2UgaXQgbGVzcyBuZWdhdGl2ZVxuLy8gKHRvd2FyZCAwKSBmb3Igc2hhcnBlciBkZXRhaWwsIG9yIG1vcmUgbmVnYXRpdmUgZm9yIG1vcmUgcGVyZi5cbi8vIFRoZXNlIGFyZSAqYmFzZSogb2Zmc2V0czogZ2xvYmVMYXRpdHVkZVpvb21Db21wZW5zYXRpb24gaXMgYWRkZWQgb24gdG9wIGF0IGRyYXdcbi8vIHRpbWUsIHNvIHRoZSBlZmZlY3RpdmUgem9vbU9mZnNldCBvbmx5IGVxdWFscyB0aGVzZSBleGFjdCB2YWx1ZXMgYXQgdGhlIGVxdWF0b3IuXG4vLyBTYXRlbGxpdGUgcmFzdGVyIHVzZXMgYmFzZSAwIOKAlCBpdCBkb2Vzbid0IG5lZWQgdGhlIHZlY3RvciBiaWFzIChhIGNvYXJzZXIgcmFzdGVyXG4vLyB0aWxlIGp1c3QgbG9va3Mgc29mdGVyIHJhdGhlciB0aGFuIGRyb3BwaW5nIGZlYXR1cmVzKS5cbmNvbnN0IE1BUEJPWF9HTE9CRV9WRUNUT1JfWk9PTV9PRkZTRVQgPSAtMjtcbmNvbnN0IENBUlRPX0dMT0JFX1ZFQ1RPUl9aT09NX09GRlNFVCA9IC0yO1xuY29uc3QgR0xPQkVfU0FURUxMSVRFX1pPT01fT0ZGU0VUID0gMDtcblxuLy8gV2hvbGUtd29ybGQgdGlsZSBleHRlbnQgKFdlYiBNZXJjYXRvciBsYXRpdHVkZSBsaW1pdCkuIFJlcXVpcmVkIHdoZW5ldmVyIGFcbi8vIG5lZ2F0aXZlIGB6b29tT2Zmc2V0YCBpcyB1c2VkOiBkZWNrJ3MgYGdldFRpbGVJbmRpY2VzYCByZXR1cm5zIE5PIHRpbGVzIHdoZW5cbi8vIHRoZSB0YXJnZXQgem9vbSBkcm9wcyBiZWxvdyBgbWluWm9vbWAgKnVubGVzcyogYW4gYGV4dGVudGAgaXMgc2V0IChpbiB3aGljaFxuLy8gY2FzZSBpdCBjbGFtcHMgdG8gYG1pblpvb21gIGluc3RlYWQpLiBXaXRob3V0IHRoaXMsIHpvb21pbmcgb3V0IG9yIHBhbm5pbmdcbi8vIHRvd2FyZCB0aGUgcG9sZXMgKHdoZXJlIGRlY2sgOSdzIGdsb2JlIGNvbnRyb2xsZXIgbG93ZXJzIHRoZSBlZmZlY3RpdmUgem9vbSlcbi8vIG1ha2VzIHRoZSB3aG9sZSBnbG9iZSBiYXNlbWFwIGRpc2FwcGVhci5cbmNvbnN0IEdMT0JFX1RJTEVfRVhURU5UOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFtcbiAgLTE4MCwgLTg1LjA1MTEyOSwgMTgwLCA4NS4wNTExMjlcbl07XG5cbi8vIE1heCAqbmF0aXZlKiB6b29tIG9mIGVhY2ggdmVjdG9yIHRpbGUgc291cmNlLiBTZXQgdGhpcyAobm90IGFuIGFyYml0cmFyaWx5XG4vLyBoaWdoIG51bWJlcikgc28gZGVjayBvdmVyem9vbXMg4oCUIGkuZS4ga2VlcHMgcmVuZGVyaW5nIHRoZSBkZWVwZXN0IHJlYWwgdGlsZVxuLy8gd2hlbiB0aGUgdmlldyB6b29tcyBwYXN0IGl0IOKAlCBpbnN0ZWFkIG9mIHJlcXVlc3RpbmcgdGlsZXMgdGhhdCBkb24ndCBleGlzdFxuLy8gYW5kIDQwNCAod2hpY2ggc2hvd3MgdXAgYXMgZW1wdHkgcmVjdGFuZ2xlcykuIFRoZSByYXcgYC52ZWN0b3IucGJmYCAvYC5tdnRgXG4vLyBlbmRwb2ludHMgZG8gTk9UIGF1dG8tb3Zlcnpvb20gdGhlIHdheSBNYXBib3ggR0wgZG9lcy5cbi8vICAgLSBtYXBib3gtc3RyZWV0cy12OCBoYXMgZGF0YSB1cCB0byB6MTZcbi8vICAgLSBDQVJUTyBjYXJ0by5zdHJlZXRzIHYxIGhhcyBkYXRhIHVwIHRvIHoxNFxuY29uc3QgTUFQQk9YX1ZFQ1RPUl9NQVhfREFUQV9aT09NID0gMTY7XG5jb25zdCBDQVJUT19WRUNUT1JfTUFYX0RBVEFfWk9PTSA9IDE0O1xuXG4vKipcbiAqIGRlY2suZ2wgOSdzIGdsb2JlIGNvdXBsZXMgem9vbSB0byBsYXRpdHVkZSB2aWEgYHpvb21BZGp1c3RgIChzZWVcbiAqIGdsb2JlLXZpZXdwb3J0LmpzKTogYHNjYWxlID0gMl4oem9vbSAtIHpvb21BZGp1c3QobGF0KSlgLCBhbmQgaXRzIGNvbnRyb2xsZXJcbiAqICpsb3dlcnMqIHRoZSBzdG9yZWQgYHpvb21gIGFzIHlvdSBwYW4gdG93YXJkIHRoZSBwb2xlcyB0byBrZWVwIHRoZSBnbG9iZSdzXG4gKiBvbi1zY3JlZW4gc2l6ZSBjb25zdGFudC4gVGlsZSBMT0QsIGhvd2V2ZXIsIGlzIHNlbGVjdGVkIGZyb20gdGhlIHJhdyBgem9vbWAsXG4gKiBzbyByb3RhdGluZyB0b3dhcmQgYSBwb2xlIHNpbGVudGx5IGRyb3BzIHRoZSBMT0QgYW5kIHRoaW5zIG91dCBsYWJlbHMuXG4gKiBSZXBsaWNhdGVkIGZyb20gYEBkZWNrLmdsL2NvcmVgIGdsb2JlLXZpZXdwb3J0LmpzIGB6b29tQWRqdXN0YC5cbiAqL1xuZnVuY3Rpb24gem9vbUFkanVzdChsYXRpdHVkZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgubG9nMihNYXRoLlBJICogTWF0aC5jb3MoKGxhdGl0dWRlICogTWF0aC5QSSkgLyAxODApKTtcbn1cblxuLyoqXG4gKiBMYXRpdHVkZSBjb21wZW5zYXRpb24gdG8gYWRkIHRvIGEgZ2xvYmUgdGlsZSBsYXllcidzIGB6b29tT2Zmc2V0YCwgc28gdGlsZSBMT0RcbiAqIHRyYWNrcyB0aGUgKnZpc3VhbCogKG9uLXNjcmVlbikgc2NhbGUgaW5zdGVhZCBvZiB0aGUgbGF0aXR1ZGUtYWRqdXN0ZWQgbWVyY2F0b3JcbiAqIHpvb20uIFRoaXMgY2FuY2VscyB0aGUgcGFuLWluZHVjZWQgem9vbSBkcm9wLCBrZWVwaW5nIHRpbGUgZGV0YWlsL2xhYmVsc1xuICogY29uc3RhbnQgd2hpbGUgcm90YXRpbmcgdG93YXJkIHRoZSBwb2xlcy5cbiAqL1xuZnVuY3Rpb24gZ2xvYmVMYXRpdHVkZVpvb21Db21wZW5zYXRpb24obGF0aXR1ZGU/OiBudW1iZXIpOiBudW1iZXIge1xuICBpZiAobGF0aXR1ZGUgPT0gbnVsbCB8fCAhTnVtYmVyLmlzRmluaXRlKGxhdGl0dWRlKSkge1xuICAgIHJldHVybiAwO1xuICB9XG4gIC8vIENsYW1wIGF3YXkgZnJvbSB0aGUgcG9sZXMgdG8gYXZvaWQgbG9nMigwKSA9IC1JbmZpbml0eSBhdCB8bGF0fCA9IDkwLlxuICBjb25zdCBjbGFtcGVkID0gTWF0aC5tYXgoLTg1LCBNYXRoLm1pbig4NSwgbGF0aXR1ZGUpKTtcbiAgcmV0dXJuIHpvb21BZGp1c3QoMCkgLSB6b29tQWRqdXN0KGNsYW1wZWQpO1xufVxuXG4vKipcbiAqIEdsb2JlIGJhc2VtYXAgdGlsZSBwcm92aWRlci5cbiAqXG4gKiAtIGBtYXBib3hgIHVzZXMgTWFwYm94IHZlY3Rvci9yYXN0ZXIgdGlsZXMgYW5kIHJlcXVpcmVzIGFuIGFjY2VzcyB0b2tlbi5cbiAqIC0gYGNhcnRvYCB1c2VzIENBUlRPJ3MgZnJlZSBPcGVuTWFwVGlsZXMgdmVjdG9yIHRpbGVzICsgRXNyaSBXb3JsZCBJbWFnZXJ5XG4gKiAgIHJhc3RlciwgYW5kIG5lZWRzIG5vIHRva2VuLiBVc2VkIGFzIGFuIGF1dG9tYXRpYyBmYWxsYmFjayB3aGVuIG5vIE1hcGJveFxuICogICB0b2tlbiBpcyBhdmFpbGFibGUgKGUuZy4gTWFwTGlicmUgLyBDQVJUTyBiYXNlbWFwIHNldHVwcyksIHNvIHRoZSBnbG9iZVxuICogICBiYXNlbWFwIHN0aWxsIHJlbmRlcnMgaW5zdGVhZCBvZiBzaG93aW5nIGEgc29saWQtY29sb3Igc3BoZXJlLlxuICovXG5leHBvcnQgdHlwZSBHbG9iZUJhc2VtYXBQcm92aWRlciA9ICdtYXBib3gnIHwgJ2NhcnRvJztcblxuLyoqXG4gKiBSZXNvbHZlIHdoaWNoIGdsb2JlIGJhc2VtYXAgdGlsZSBwcm92aWRlciB0byB1c2UuXG4gKlxuICogVGhlIGdsb2JlIHNob3VsZCBmb2xsb3cgdGhlICpzZWxlY3RlZCBiYXNlbWFwIHN0eWxlJ3MqIHJlbmRlcmluZyBsaWJyYXJ5IHNvXG4gKiBpdCBzdGF5cyBjb25zaXN0ZW50IHdpdGggdGhlIGZsYXQgMkQgbWFwOiBhIE1hcExpYnJlL0NBUlRPIHN0eWxlIHVzZXMgdGhlXG4gKiBmcmVlIENBUlRPIHRpbGVzIChldmVuIHdoZW4gYSBNYXBib3ggdG9rZW4gaXMgYXZhaWxhYmxlKSwgYW5kIGEgTWFwYm94IHN0eWxlXG4gKiB1c2VzIE1hcGJveCB0aWxlcy4gQSBNYXBib3ggc3R5bGUgd2l0aCBubyB0b2tlbiBmYWxscyBiYWNrIHRvIENBUlRPIHNvIHRoZVxuICogZ2xvYmUgc3RpbGwgcmVuZGVycyBpbnN0ZWFkIG9mIHNob3dpbmcgYSBiYXJlIGNvbG9yZWQgc3BoZXJlLlxuICpcbiAqIEBwYXJhbSBiYXNlTWFwTGlicmFyeSB0aGUgc2VsZWN0ZWQgc3R5bGUncyBsaWJyYXJ5ICgnbWFwYm94JyB8ICdtYXBsaWJyZScpLFxuICogICBlLmcuIGZyb20gYGdldEJhc2VNYXBMaWJyYXJ5KGN1cnJlbnRTdHlsZSlgLlxuICovXG5leHBvcnQgY29uc3QgcmVzb2x2ZUdsb2JlQmFzZW1hcFByb3ZpZGVyID0gKFxuICBiYXNlTWFwTGlicmFyeTogJ21hcGJveCcgfCAnbWFwbGlicmUnIHwgdW5kZWZpbmVkLFxuICBtYXBib3hBcGlBY2Nlc3NUb2tlbj86IHN0cmluZ1xuKTogR2xvYmVCYXNlbWFwUHJvdmlkZXIgPT4ge1xuICBpZiAoYmFzZU1hcExpYnJhcnkgPT09ICdtYXBsaWJyZScpIHtcbiAgICByZXR1cm4gJ2NhcnRvJztcbiAgfVxuICBpZiAoYmFzZU1hcExpYnJhcnkgPT09ICdtYXBib3gnKSB7XG4gICAgcmV0dXJuIG1hcGJveEFwaUFjY2Vzc1Rva2VuID8gJ21hcGJveCcgOiAnY2FydG8nO1xuICB9XG4gIC8vIFVua25vd24gbGlicmFyeTogcHJlZmVyIE1hcGJveCB3aGVuIGEgdG9rZW4gZXhpc3RzLCBvdGhlcndpc2UgQ0FSVE8uXG4gIHJldHVybiBtYXBib3hBcGlBY2Nlc3NUb2tlbiA/ICdtYXBib3gnIDogJ2NhcnRvJztcbn07XG5cbi8vIENBUlRPIGZyZWUgdmVjdG9yIHRpbGVzIChPcGVuTWFwVGlsZXMgc2NoZW1hLCBubyBBUEkga2V5IHJlcXVpcmVkKS5cbmNvbnN0IENBUlRPX1ZFQ1RPUl9USUxFX1VSTFMgPSBbXG4gICdodHRwczovL3RpbGVzLWEuYmFzZW1hcHMuY2FydG9jZG4uY29tL3ZlY3RvcnRpbGVzL2NhcnRvLnN0cmVldHMvdjEve3p9L3t4fS97eX0ubXZ0JyxcbiAgJ2h0dHBzOi8vdGlsZXMtYi5iYXNlbWFwcy5jYXJ0b2Nkbi5jb20vdmVjdG9ydGlsZXMvY2FydG8uc3RyZWV0cy92MS97en0ve3h9L3t5fS5tdnQnLFxuICAnaHR0cHM6Ly90aWxlcy1jLmJhc2VtYXBzLmNhcnRvY2RuLmNvbS92ZWN0b3J0aWxlcy9jYXJ0by5zdHJlZXRzL3YxL3t6fS97eH0ve3l9Lm12dCcsXG4gICdodHRwczovL3RpbGVzLWQuYmFzZW1hcHMuY2FydG9jZG4uY29tL3ZlY3RvcnRpbGVzL2NhcnRvLnN0cmVldHMvdjEve3p9L3t4fS97eX0ubXZ0J1xuXTtcblxuLy8gRnJlZSBzYXRlbGxpdGUgcmFzdGVyIGZhbGxiYWNrIChFc3JpIFdvcmxkIEltYWdlcnksIG5vIEFQSSBrZXkgcmVxdWlyZWQpLlxuY29uc3QgRVNSSV9XT1JMRF9JTUFHRVJZX1VSTCA9XG4gICdodHRwczovL3NlcnZlci5hcmNnaXNvbmxpbmUuY29tL0FyY0dJUy9yZXN0L3NlcnZpY2VzL1dvcmxkX0ltYWdlcnkvTWFwU2VydmVyL3RpbGUve3p9L3t5fS97eH0nO1xuXG4vKipcbiAqIE1hcHMgYSByYXcgTVZUIHNvdXJjZS1sYXllciBuYW1lIHRvIGEgbm9ybWFsaXplZCBzZW1hbnRpYyBsYXllciBraW5kLCBzbyB0aGVcbiAqIGZpbGwvbGluZS9sYWJlbCBhY2Nlc3NvcnMgd29yayBhY3Jvc3MgYm90aCB0aGUgTWFwYm94IChgbWFwYm94LXN0cmVldHMtdjhgKVxuICogYW5kIENBUlRPL09wZW5NYXBUaWxlcyBzY2hlbWFzLlxuICpcbiAqIHwgc2VtYW50aWMgfCBtYXBib3ggICAgICAgIHwgb3Blbm1hcHRpbGVzIHxcbiAqIHwgLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tIHxcbiAqIHwgd2F0ZXIgICAgfCBgd2F0ZXJgICAgICAgIHwgYHdhdGVyYCAgICAgIHxcbiAqIHwgYWRtaW4gICAgfCBgYWRtaW5gICAgICAgIHwgYGJvdW5kYXJ5YCAgIHxcbiAqIHwgbGFiZWwgICAgfCBgcGxhY2VfbGFiZWxgIHwgYHBsYWNlYCAgICAgIHxcbiAqL1xudHlwZSBCYXNlbWFwTGF5ZXJLaW5kID0gJ3dhdGVyJyB8ICdhZG1pbicgfCAnbGFiZWwnIHwgJ290aGVyJztcblxuZnVuY3Rpb24gZ2V0QmFzZW1hcExheWVyS2luZChsYXllck5hbWU/OiBzdHJpbmcpOiBCYXNlbWFwTGF5ZXJLaW5kIHtcbiAgc3dpdGNoIChsYXllck5hbWUpIHtcbiAgICBjYXNlICd3YXRlcic6XG4gICAgICByZXR1cm4gJ3dhdGVyJztcbiAgICBjYXNlICdhZG1pbic6XG4gICAgY2FzZSAnYm91bmRhcnknOlxuICAgICAgcmV0dXJuICdhZG1pbic7XG4gICAgY2FzZSAncGxhY2VfbGFiZWwnOlxuICAgIGNhc2UgJ3BsYWNlJzpcbiAgICAgIHJldHVybiAnbGFiZWwnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJ290aGVyJztcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBHbG9iZUF0dHJpYnV0aW9uID0ge2xhYmVsOiBzdHJpbmc7IGhyZWY6IHN0cmluZ307XG5cbmNvbnN0IE1BUEJPWF9BVFRSSUJVVElPTjogR2xvYmVBdHRyaWJ1dGlvbiA9IHtcbiAgbGFiZWw6ICfCqSBNYXBib3gnLFxuICBocmVmOiAnaHR0cHM6Ly93d3cubWFwYm94LmNvbS9hYm91dC9tYXBzLydcbn07XG5jb25zdCBPU01fQVRUUklCVVRJT046IEdsb2JlQXR0cmlidXRpb24gPSB7XG4gIGxhYmVsOiAnwqkgT3BlblN0cmVldE1hcCcsXG4gIGhyZWY6ICdodHRwczovL3d3dy5vcGVuc3RyZWV0bWFwLm9yZy9jb3B5cmlnaHQnXG59O1xuY29uc3QgQ0FSVE9fQVRUUklCVVRJT046IEdsb2JlQXR0cmlidXRpb24gPSB7XG4gIGxhYmVsOiAnwqkgQ0FSVE8nLFxuICBocmVmOiAnaHR0cHM6Ly9jYXJ0by5jb20vYXR0cmlidXRpb25zJ1xufTtcbmNvbnN0IEVTUklfQVRUUklCVVRJT046IEdsb2JlQXR0cmlidXRpb24gPSB7XG4gIGxhYmVsOiAnUG93ZXJlZCBieSBFc3JpJyxcbiAgaHJlZjogJ2h0dHBzOi8vd3d3LmVzcmkuY29tLydcbn07XG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgdGlsZS1zb3VyY2UgYXR0cmlidXRpb24gZW50cmllcyBmb3IgdGhlIGdsb2JlIGJhc2VtYXAuIGRlY2suZ2xcbiAqIHJlbmRlcnMgdGhlIGdsb2JlIGJhc2VtYXAgdGlsZXMgaXRzZWxmIChub3QgdGhlIGJhc2UgTWFwbGlicmUvTWFwYm94IG1hcCksIHNvXG4gKiB0aGUgYmFzZSBtYXAncyBhdHRyaWJ1dGlvbiBtYWNoaW5lcnkgbmV2ZXIgc2VlcyB0aGVtLiBUaGlzIGxldHMgdGhlIFVJIGNyZWRpdFxuICogdGhlIGFjdHVhbCB0aWxlIHByb3ZpZGVyKHMpIGluIGdsb2JlIG1vZGUuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRHbG9iZUJhc2VtYXBBdHRyaWJ1dGlvbnMgPSAoe1xuICBnbG9iZSxcbiAgbWFwYm94QXBpQWNjZXNzVG9rZW4sXG4gIG1hcFN0eWxlVHlwZSxcbiAgYmFzZW1hcFByb3ZpZGVyXG59OiB7XG4gIGdsb2JlPzogR2xvYmU7XG4gIG1hcGJveEFwaUFjY2Vzc1Rva2VuPzogc3RyaW5nO1xuICBtYXBTdHlsZVR5cGU/OiBzdHJpbmc7XG4gIGJhc2VtYXBQcm92aWRlcj86IEdsb2JlQmFzZW1hcFByb3ZpZGVyO1xufSk6IEdsb2JlQXR0cmlidXRpb25bXSA9PiB7XG4gIGlmICghZ2xvYmU/LmVuYWJsZWQgfHwgIWdsb2JlLmNvbmZpZz8uYmFzZW1hcCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHByb3ZpZGVyOiBHbG9iZUJhc2VtYXBQcm92aWRlciA9XG4gICAgYmFzZW1hcFByb3ZpZGVyID8/IHJlc29sdmVHbG9iZUJhc2VtYXBQcm92aWRlcih1bmRlZmluZWQsIG1hcGJveEFwaUFjY2Vzc1Rva2VuKTtcblxuICBpZiAocHJvdmlkZXIgPT09ICdtYXBib3gnKSB7XG4gICAgcmV0dXJuIG1hcGJveEFwaUFjY2Vzc1Rva2VuID8gW01BUEJPWF9BVFRSSUJVVElPTiwgT1NNX0FUVFJJQlVUSU9OXSA6IFtdO1xuICB9XG5cbiAgY29uc3QgaXNTYXRlbGxpdGUgPSBtYXBTdHlsZVR5cGUgPT09ICdzYXRlbGxpdGUnIHx8IG1hcFN0eWxlVHlwZSA9PT0gJ3NhdGVsbGl0ZS1zdHJlZXQnO1xuICAvLyBDQVJUTyB2ZWN0b3IgdGlsZXMgYXJlIE9wZW5TdHJlZXRNYXAtZGVyaXZlZDsgRXNyaSBpbWFnZXJ5IGlzIGNyZWRpdGVkIHNlcGFyYXRlbHkuXG4gIHJldHVybiBpc1NhdGVsbGl0ZVxuICAgID8gW0VTUklfQVRUUklCVVRJT04sIENBUlRPX0FUVFJJQlVUSU9OLCBPU01fQVRUUklCVVRJT05dXG4gICAgOiBbQ0FSVE9fQVRUUklCVVRJT04sIE9TTV9BVFRSSUJVVElPTl07XG59O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZXhwb3J0IGNvbnN0IGdldEdsb2JlQmFzZUxheWVycyA9ICh7XG4gIG1hcGJveEFwaUFjY2Vzc1Rva2VuLFxuICBnbG9iZSxcbiAgbWFwU3R5bGVUeXBlLFxuICBiYXNlbWFwUHJvdmlkZXIsXG4gIGxhdGl0dWRlLFxuICB6b29tXG59OiB7XG4gIG1hcGJveEFwaUFjY2Vzc1Rva2VuOiBzdHJpbmc7XG4gIGdsb2JlOiBHbG9iZTtcbiAgbWFwU3R5bGVUeXBlPzogc3RyaW5nO1xuICAvKipcbiAgICogV2hpY2ggdGlsZSBwcm92aWRlciB0byB1c2UgZm9yIHRoZSBnbG9iZSBiYXNlbWFwLiBEZWZhdWx0cyB0byBgbWFwYm94YCB3aGVuXG4gICAqIGEgdG9rZW4gaXMgcHJlc2VudCwgb3RoZXJ3aXNlIGZhbGxzIGJhY2sgdG8gdGhlIHRva2VuLWZyZWUgYGNhcnRvYCB0aWxlcy5cbiAgICovXG4gIGJhc2VtYXBQcm92aWRlcj86IEdsb2JlQmFzZW1hcFByb3ZpZGVyO1xuICAvKipcbiAgICogQ3VycmVudCBjYW1lcmEgY2VudGVyIGxhdGl0dWRlLiBVc2VkIHRvIGtlZXAgdGlsZSBMT0QgY29uc3RhbnQgd2hpbGUgcm90YXRpbmdcbiAgICogdG93YXJkIHRoZSBwb2xlcyAoZGVjay5nbCA5IGxvd2VycyB0aGUgZWZmZWN0aXZlIHpvb20gbmVhciB0aGUgcG9sZXMpLiBXaGVuXG4gICAqIG9taXR0ZWQsIG5vIGxhdGl0dWRlIGNvbXBlbnNhdGlvbiBpcyBhcHBsaWVkIChlcXVhdG9yIGJlaGF2aW9yKS5cbiAgICovXG4gIGxhdGl0dWRlPzogbnVtYmVyO1xuICAvKipcbiAgICogQ3VycmVudCBtYXAgem9vbSBsZXZlbC4gVXNlZCB0byBmYWRlIHRoZSBhdG1vc3BoZXJlIGVmZmVjdHMgb3V0IHdoZW4gdGhlIHVzZXJcbiAgICogem9vbXMgaW4gcGFzdCBhIGNlcnRhaW4gdGhyZXNob2xkIChtaXJyb3JzIEdvb2dsZSBNYXBzIGdsb2JlIGJlaGF2aW91cikuXG4gICAqL1xuICB6b29tPzogbnVtYmVyO1xufSk6IExheWVyW10gPT4ge1xuICBjb25zdCB7Y29uZmlnfSA9IGdsb2JlO1xuXG4gIGNvbnN0IGlzU2F0ZWxsaXRlID0gbWFwU3R5bGVUeXBlID09PSAnc2F0ZWxsaXRlJztcbiAgY29uc3QgaXNTYXRlbGxpdGVTdHJlZXQgPSBtYXBTdHlsZVR5cGUgPT09ICdzYXRlbGxpdGUtc3RyZWV0JztcblxuICBjb25zdCBsYXRab29tQ29tcGVuc2F0aW9uID0gZ2xvYmVMYXRpdHVkZVpvb21Db21wZW5zYXRpb24obGF0aXR1ZGUpO1xuXG4gIC8vIEZhbGwgYmFjayB0byB0aGUgZnJlZSBDQVJUTyB0aWxlcyB3aGVuZXZlciBubyBNYXBib3ggdG9rZW4gaXMgYXZhaWxhYmxlIHNvXG4gIC8vIHRoZSBnbG9iZSBiYXNlbWFwIHN0aWxsIHJlbmRlcnMgKG1hdGNoZXMga2VwbGVyJ3MgZGVmYXVsdCB0b2tlbi1mcmVlXG4gIC8vIE1hcExpYnJlL0NBUlRPIGJhc2VtYXBzKS4gQ2FsbGVycyBzaG91bGQgcGFzcyBhbiBleHBsaWNpdCBgYmFzZW1hcFByb3ZpZGVyYFxuICAvLyAoZGVyaXZlZCBmcm9tIHRoZSBzZWxlY3RlZCBzdHlsZSkgc28gdGhlIGdsb2JlIGZvbGxvd3MgdGhlIDJEIGJhc2VtYXAuXG4gIGNvbnN0IHByb3ZpZGVyOiBHbG9iZUJhc2VtYXBQcm92aWRlciA9XG4gICAgYmFzZW1hcFByb3ZpZGVyID8/IHJlc29sdmVHbG9iZUJhc2VtYXBQcm92aWRlcih1bmRlZmluZWQsIG1hcGJveEFwaUFjY2Vzc1Rva2VuKTtcbiAgY29uc3QgdXNlQ2FydG8gPSBwcm92aWRlciA9PT0gJ2NhcnRvJztcbiAgY29uc3QgaGFzVGlsZUFjY2VzcyA9IHVzZUNhcnRvIHx8IEJvb2xlYW4obWFwYm94QXBpQWNjZXNzVG9rZW4pO1xuXG4gIHJldHVybiBbXG4gICAgLy8gSHVnZSBoYWxvIGJlaGluZCB0aGUgdGhpbiByZWFsaXN0aWMgbGltYiBzbyBib3RoIGNhbiBiZSB2aXNpYmxlIHRvZ2V0aGVyLlxuICAgIGNvbmZpZy5hdG1vc3BoZXJlID8gZ2V0R2xvYmVIdWdlSGFsb0xheWVyKHtjb25maWcsIHpvb219KSA6IG51bGwsXG4gICAgY29uZmlnLmF0bW9zcGhlcmUgPyBnZXRHbG9iZUF0bW9zcGhlcmVTa3lMYXllcih7Y29uZmlnLCB6b29tfSkgOiBudWxsLFxuXG4gICAgLy8gRGVwdGgtb25seSBjcm9zcy1zZWN0aW9uIGRpc2s6IHdyaXRlcyBkZXB0aCBhdCB0aGUgZ2xvYmUncyBzaWxob3VldHRlIHNvXG4gICAgLy8gZmFyLXNpZGUgZ2VvbWV0cnkgKGFyY3MvbGluZXMpIGlzIG9jY2x1ZGVkIGJ5IHRoZSBwbGFuZXQuXG4gICAgZ2V0R2xvYmVEZXB0aERpc2tMYXllcih7ZmlsbENvbG9yOiBjb25maWcuc3VyZmFjZUNvbG9yfSksXG5cbiAgICAvLyBCYWNrZ3JvdW5kIHN1cmZhY2UgcG9seWdvblxuICAgICghY29uZmlnLmJhc2VtYXAgfHwgKCFpc1NhdGVsbGl0ZSAmJiAhaXNTYXRlbGxpdGVTdHJlZXQpKSAmJlxuICAgICAgbmV3IFNvbGlkUG9seWdvbkxheWVyKHtcbiAgICAgICAgaWQ6ICdnbG9iZS1iYWNrZ3JvdW5kJyxcbiAgICAgICAgZGF0YTogQkFDS0dST1VORF9EQVRBLFxuICAgICAgICBnZXRQb2x5Z29uOiAoKGQ6IG51bWJlcltdW10pID0+IGQpIGFzIGFueSxcbiAgICAgICAgZmlsbGVkOiB0cnVlLFxuICAgICAgICBnZXRGaWxsQ29sb3I6IGNvbmZpZy5zdXJmYWNlQ29sb3IgYXMgYW55LFxuICAgICAgICBwYXJhbWV0ZXJzOiBCQUNLR1JPVU5EX1BBUkFNRVRFUlNcbiAgICAgIH0pLFxuXG4gICAgLy8gRmlsbCBob2xlIGF0IG5vcnRoIHBvbGVcbiAgICBjb25maWcuYmFzZW1hcCAmJlxuICAgICAgbmV3IFNvbGlkUG9seWdvbkxheWVyKHtcbiAgICAgICAgaWQ6ICdnbG9iZS1iYWNrZ3JvdW5kLW5vcnRoLXBvbGUnLFxuICAgICAgICBkYXRhOiBCQUNLR1JPVU5EX05PUlRIX1BPTEVfREFUQSxcbiAgICAgICAgZ2V0UG9seWdvbjogKChkOiBudW1iZXJbXVtdKSA9PiBkKSBhcyBhbnksXG4gICAgICAgIGZpbGxlZDogdHJ1ZSxcbiAgICAgICAgZ2V0RmlsbENvbG9yOiAoY29uZmlnLndhdGVyID8gY29uZmlnLndhdGVyQ29sb3IgOiBjb25maWcuc3VyZmFjZUNvbG9yKSBhcyBhbnksXG4gICAgICAgIHBhcmFtZXRlcnM6IEJBQ0tHUk9VTkRfUEFSQU1FVEVSU1xuICAgICAgfSksXG5cbiAgICAvLyBTYXRlbGxpdGUgdGlsZXNcbiAgICBjb25maWcuYmFzZW1hcCAmJlxuICAgICAgKGlzU2F0ZWxsaXRlIHx8IGlzU2F0ZWxsaXRlU3RyZWV0KSAmJlxuICAgICAgaGFzVGlsZUFjY2VzcyAmJlxuICAgICAgbmV3IFRpbGVMYXllcih7XG4gICAgICAgIGlkOiBgZ2xvYmUtc2F0ZWxsaXRlLXRpbGVzLSR7cHJvdmlkZXJ9YCxcbiAgICAgICAgZGF0YTogdXNlQ2FydG9cbiAgICAgICAgICA/IFtFU1JJX1dPUkxEX0lNQUdFUllfVVJMXVxuICAgICAgICAgIDogW1xuICAgICAgICAgICAgICBgaHR0cHM6Ly9hcGkubWFwYm94LmNvbS92NC9tYXBib3guc2F0ZWxsaXRlL3t6fS97eH0ve3l9QDJ4LnBuZz9hY2Nlc3NfdG9rZW49JHttYXBib3hBcGlBY2Nlc3NUb2tlbn1gXG4gICAgICAgICAgICBdLFxuICAgICAgICBtaW5ab29tOiAwLFxuICAgICAgICBtYXhab29tOiB1c2VDYXJ0byA/IDE4IDogMTksXG4gICAgICAgIHpvb21PZmZzZXQ6IEdMT0JFX1NBVEVMTElURV9aT09NX09GRlNFVCArIGxhdFpvb21Db21wZW5zYXRpb24sXG4gICAgICAgIGV4dGVudDogR0xPQkVfVElMRV9FWFRFTlQsXG4gICAgICAgIC8vIEVzcmkgdGlsZXMgYXJlIDI1NnB4OyBNYXBib3ggQDJ4IHRpbGVzIGFyZSA1MTJweC5cbiAgICAgICAgdGlsZVNpemU6IHVzZUNhcnRvID8gMjU2IDogNTEyIC8gZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgcmVuZGVyU3ViTGF5ZXJzOiAocHJvcHM6IGFueSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGJib3g6IHt3ZXN0LCBzb3V0aCwgZWFzdCwgbm9ydGh9XG4gICAgICAgICAgfSA9IHByb3BzLnRpbGU7XG5cbiAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgbmV3IEJpdG1hcExheWVyKHByb3BzLCB7XG4gICAgICAgICAgICAgIF9pbWFnZUNvb3JkaW5hdGVTeXN0ZW06IENPT1JESU5BVEVfU1lTVEVNLkNBUlRFU0lBTixcbiAgICAgICAgICAgICAgZGF0YTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBpbWFnZTogcHJvcHMuZGF0YSxcbiAgICAgICAgICAgICAgYm91bmRzOiBbd2VzdCwgc291dGgsIGVhc3QsIG5vcnRoXVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICBdO1xuICAgICAgICB9LFxuICAgICAgICBwYXJhbWV0ZXJzOiBCQVNFTUFQX1JBU1RFUl9QQVJBTUVURVJTXG4gICAgICB9KSxcblxuICAgIC8vIFZlY3RvciBiYXNlbWFwIChNVlQgbGFiZWxzL2FkbWluL3dhdGVyKVxuICAgIGNvbmZpZy5iYXNlbWFwICYmXG4gICAgICAhaXNTYXRlbGxpdGUgJiZcbiAgICAgIGhhc1RpbGVBY2Nlc3MgJiZcbiAgICAgIG5ldyBNVlRMYXllcih7XG4gICAgICAgIC8vIGZvcmNlIHRoZSBsYXllciB0byB1cGRhdGUgd2hlbiB0aGUgc3R5bGUvbGFiZWwvcHJvdmlkZXIgY29uZmlnIGNoYW5nZXNcbiAgICAgICAgaWQ6IGBnbG9iZS1iYXNlbWFwLW12dC1sYXllci0ke3Byb3ZpZGVyfS0ke21hcFN0eWxlVHlwZX1gLFxuICAgICAgICBkYXRhOiB1c2VDYXJ0b1xuICAgICAgICAgID8gQ0FSVE9fVkVDVE9SX1RJTEVfVVJMU1xuICAgICAgICAgIDogYGh0dHBzOi8vYS50aWxlcy5tYXBib3guY29tL3Y0L21hcGJveC5tYXBib3gtc3RyZWV0cy12OC97en0ve3h9L3t5fS52ZWN0b3IucGJmP2FjY2Vzc190b2tlbj0ke21hcGJveEFwaUFjY2Vzc1Rva2VufWAsXG4gICAgICAgIG1pblpvb206IDAsXG4gICAgICAgIC8vIE92ZXJ6b29tIHBhc3QgdGhlIHNvdXJjZSdzIG5hdGl2ZSBtYXggaW5zdGVhZCBvZiA0MDQtaW5nIG9uIHRpbGVzIHRoYXRcbiAgICAgICAgLy8gZG9uJ3QgZXhpc3QgKHdoaWNoIHJlbmRlcnMgYXMgZW1wdHkgcmVjdGFuZ2xlcyBhdCBoaWdoIHpvb20pLlxuICAgICAgICBtYXhab29tOiB1c2VDYXJ0byA/IENBUlRPX1ZFQ1RPUl9NQVhfREFUQV9aT09NIDogTUFQQk9YX1ZFQ1RPUl9NQVhfREFUQV9aT09NLFxuICAgICAgICB6b29tT2Zmc2V0OlxuICAgICAgICAgICh1c2VDYXJ0byA/IENBUlRPX0dMT0JFX1ZFQ1RPUl9aT09NX09GRlNFVCA6IE1BUEJPWF9HTE9CRV9WRUNUT1JfWk9PTV9PRkZTRVQpICtcbiAgICAgICAgICBsYXRab29tQ29tcGVuc2F0aW9uLFxuICAgICAgICBleHRlbnQ6IEdMT0JFX1RJTEVfRVhURU5ULFxuICAgICAgICBiaW5hcnk6IGZhbHNlLFxuICAgICAgICBwYXJhbWV0ZXJzOiBCQVNFTUFQX01WVF9QQVJBTUVURVJTLFxuICAgICAgICBsb2FkT3B0aW9uczogdXNlQ2FydG9cbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgLy8gT3Blbk1hcFRpbGVzIHNjaGVtYTogYGJvdW5kYXJ5YCA9IGFkbWluIGxpbmVzLCBgcGxhY2VgID0gbGFiZWxzLlxuICAgICAgICAgICAgICBtdnQ6IHtcbiAgICAgICAgICAgICAgICBsYXllcnM6IGlzU2F0ZWxsaXRlU3RyZWV0XG4gICAgICAgICAgICAgICAgICA/IFsncGxhY2UnLCAnYm91bmRhcnknXVxuICAgICAgICAgICAgICAgICAgOiBbJ3BsYWNlJywgJ2JvdW5kYXJ5JywgJ3dhdGVyJywgJ3RyYW5zcG9ydGF0aW9uJ11cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDoge1xuICAgICAgICAgICAgICBtdnQ6IHtcbiAgICAgICAgICAgICAgICBsYXllcnM6IGlzU2F0ZWxsaXRlU3RyZWV0XG4gICAgICAgICAgICAgICAgICA/IFsncGxhY2VfbGFiZWwnLCAnYWRtaW4nXVxuICAgICAgICAgICAgICAgICAgOiBbJ3BsYWNlX2xhYmVsJywgJ2FkbWluJywgJ3dhdGVyJywgJ3JvYWQnXVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAvLyBSZW5kZXIgYWRtaW4vd2F0ZXIgdmlhIEdlb0pzb25MYXllciBhbmQgcGxhY2UgbGFiZWxzIHZpYSBUZXh0TGF5ZXIuXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVuZGVyU3ViTGF5ZXJzOiAocHJvcHM6IGFueSkgPT4gbmV3IE1WVExhYmVsTGF5ZXIocHJvcHMpLFxuICAgICAgICBnZXRGaWxsQ29sb3I6IChmOiBhbnkpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGdldEJhc2VtYXBMYXllcktpbmQoZi5wcm9wZXJ0aWVzLmxheWVyTmFtZSkpIHtcbiAgICAgICAgICAgIGNhc2UgJ3dhdGVyJzpcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy53YXRlciA/IGNvbmZpZy53YXRlckNvbG9yIDogSU5WSVNJQkxFX0NPTE9SO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy5zdXJmYWNlQ29sb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBnZXRMaW5lQ29sb3I6IChmOiBhbnkpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGdldEJhc2VtYXBMYXllcktpbmQoZi5wcm9wZXJ0aWVzLmxheWVyTmFtZSkpIHtcbiAgICAgICAgICAgIGNhc2UgJ2FkbWluJzpcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy5hZG1pbkxpbmVzID8gY29uZmlnLmFkbWluTGluZXNDb2xvciA6IElOVklTSUJMRV9DT0xPUjtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuc3VyZmFjZUNvbG9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZ2V0TGluZVdpZHRoOiAoZjogYW55KSA9PiB7XG4gICAgICAgICAgc3dpdGNoIChnZXRCYXNlbWFwTGF5ZXJLaW5kKGYucHJvcGVydGllcy5sYXllck5hbWUpKSB7XG4gICAgICAgICAgICBjYXNlICdhZG1pbic6XG4gICAgICAgICAgICAgIHN3aXRjaCAoZi5wcm9wZXJ0aWVzLmFkbWluX2xldmVsKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICByZXR1cm4gMC43NTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB1cGRhdGVUcmlnZ2Vyczoge1xuICAgICAgICAgIGdldEZpbGxDb2xvcjogW2NvbmZpZy53YXRlckNvbG9yLCBjb25maWcuc3VyZmFjZUNvbG9yLCBjb25maWcud2F0ZXJdLFxuICAgICAgICAgIGdldExpbmVDb2xvcjogW2NvbmZpZy5hZG1pbkxpbmVzQ29sb3IsIGNvbmZpZy5zdXJmYWNlQ29sb3IsIGNvbmZpZy5hZG1pbkxpbmVzXVxuICAgICAgICB9LFxuICAgICAgICBsaW5lV2lkdGhVbml0czogJ3BpeGVscycsXG4gICAgICAgIGxpbmVXaWR0aE1pblBpeGVsczogMCxcbiAgICAgICAgbGluZVdpZHRoTWF4UGl4ZWxzOiAyMCxcbiAgICAgICAgZ2V0UG9pbnRSYWRpdXM6IDAsXG4gICAgICAgIHBvaW50UmFkaXVzTWluUGl4ZWxzOiAwXG4gICAgICB9IGFzIGFueSlcbiAgXS5maWx0ZXIoQm9vbGVhbikgYXMgTGF5ZXJbXTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRHbG9iZVRvcExheWVycyA9ICh7Z2xvYmUsIHpvb219OiB7Z2xvYmU6IEdsb2JlOyB6b29tPzogbnVtYmVyfSk6IExheWVyW10gPT4ge1xuICBjb25zdCB7Y29uZmlnfSA9IGdsb2JlO1xuICByZXR1cm4gW2NvbmZpZy5hdG1vc3BoZXJlID8gZ2V0R2xvYmVBdG1vc3BoZXJlTGF5ZXIoe2NvbmZpZywgem9vbX0pIDogbnVsbF0uZmlsdGVyKEJvb2xlYW4pIGFzIExheWVyW107XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUdBLElBQUFBLEtBQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLFVBQUEsR0FBQUYsT0FBQTtBQUtBLElBQUFHLGdCQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxvQkFBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssY0FBQSxHQUFBTCxPQUFBO0FBWkE7QUFDQTs7QUFlQSxJQUFNTSxnQkFBZ0IsR0FBR0MsSUFBSSxDQUFDQyxHQUFHLENBQy9CLENBQUMsRUFDQSxPQUFPQyxNQUFNLEtBQUssV0FBVyxJQUFJQSxNQUFNLENBQUNILGdCQUFnQixJQUFLLENBQ2hFLENBQUM7QUFFRCxJQUFNSSxxQkFBcUIsR0FBRztFQUM1QkMsU0FBUyxFQUFFLElBQUk7RUFDZkMsSUFBSSxFQUFFLElBQUk7RUFDVkMsU0FBUyxFQUFFO0FBQ2IsQ0FBQztBQUVELElBQU1DLHlCQUF5QixHQUFHO0VBQ2hDRCxTQUFTLEVBQUU7QUFDYixDQUFDO0FBRUQsSUFBTUUsZUFBZSxHQUFHLENBQ3RCLENBQ0UsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFDVixDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFDUCxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFDVCxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUNWLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQ1IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUNaLENBQ0Y7QUFFRCxJQUFNQywwQkFBMEIsR0FBRyxD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