@kepler.gl/mcp 0.0.0-stage → 3.3.0-alpha.20

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 (73) hide show
  1. package/dist/cjs/commands/add-column-command.js +192 -0
  2. package/dist/cjs/commands/basemap-command.js +80 -0
  3. package/dist/cjs/commands/boundary-command.js +81 -0
  4. package/dist/cjs/commands/command-wrappers.js +122 -0
  5. package/dist/cjs/commands/dataset-context-command.js +87 -0
  6. package/dist/cjs/commands/index.js +230 -0
  7. package/dist/cjs/commands/layer-creation-command.js +534 -0
  8. package/dist/cjs/commands/layer-style-command.js +136 -0
  9. package/dist/cjs/commands/load-data-command.js +270 -0
  10. package/dist/cjs/commands/save-data-command.js +118 -0
  11. package/dist/cjs/commands/split-view-command.js +261 -0
  12. package/dist/cjs/commands/table-command.js +199 -0
  13. package/dist/cjs/commands/time-filter-command.js +289 -0
  14. package/dist/cjs/commands/toggle-time-filter-command.js +155 -0
  15. package/dist/cjs/commands/types.js +6 -0
  16. package/dist/cjs/commands/utils.js +536 -0
  17. package/dist/cjs/commands/view-mode-command.js +94 -0
  18. package/dist/cjs/index.js +39 -0
  19. package/dist/cjs/map-contract.js +6 -0
  20. package/dist/cjs/server/bridge-server.js +435 -0
  21. package/dist/cjs/server/index.js +31 -0
  22. package/dist/cjs/server/stdio.js +201 -0
  23. package/dist/cjs/types.js +30 -0
  24. package/dist/commands/add-column-command.d.ts +4 -0
  25. package/dist/commands/basemap-command.d.ts +4 -0
  26. package/dist/commands/boundary-command.d.ts +4 -0
  27. package/dist/commands/command-wrappers.d.ts +52 -0
  28. package/dist/commands/dataset-context-command.d.ts +4 -0
  29. package/dist/commands/index.d.ts +31 -0
  30. package/dist/commands/layer-creation-command.d.ts +8 -0
  31. package/dist/commands/layer-style-command.d.ts +4 -0
  32. package/dist/commands/load-data-command.d.ts +4 -0
  33. package/dist/commands/save-data-command.d.ts +4 -0
  34. package/dist/commands/split-view-command.d.ts +4 -0
  35. package/dist/commands/table-command.d.ts +4 -0
  36. package/dist/commands/time-filter-command.d.ts +13 -0
  37. package/dist/commands/toggle-time-filter-command.d.ts +4 -0
  38. package/dist/commands/types.d.ts +132 -0
  39. package/dist/commands/utils.d.ts +138 -0
  40. package/dist/commands/view-mode-command.d.ts +4 -0
  41. package/dist/esm/commands/add-column-command.js +185 -0
  42. package/dist/esm/commands/basemap-command.js +72 -0
  43. package/dist/esm/commands/boundary-command.js +73 -0
  44. package/dist/esm/commands/command-wrappers.js +114 -0
  45. package/dist/esm/commands/dataset-context-command.js +79 -0
  46. package/dist/esm/commands/index.js +51 -0
  47. package/dist/esm/commands/layer-creation-command.js +527 -0
  48. package/dist/esm/commands/layer-style-command.js +130 -0
  49. package/dist/esm/commands/load-data-command.js +264 -0
  50. package/dist/esm/commands/save-data-command.js +112 -0
  51. package/dist/esm/commands/split-view-command.js +255 -0
  52. package/dist/esm/commands/table-command.js +194 -0
  53. package/dist/esm/commands/time-filter-command.js +280 -0
  54. package/dist/esm/commands/toggle-time-filter-command.js +147 -0
  55. package/dist/esm/commands/types.js +3 -0
  56. package/dist/esm/commands/utils.js +521 -0
  57. package/dist/esm/commands/view-mode-command.js +86 -0
  58. package/dist/esm/index.js +20 -0
  59. package/dist/esm/map-contract.js +3 -0
  60. package/dist/esm/server/bridge-server.js +428 -0
  61. package/dist/esm/server/index.js +13 -0
  62. package/dist/esm/server/stdio.js +198 -0
  63. package/dist/esm/types.js +24 -0
  64. package/dist/index.d.ts +15 -0
  65. package/dist/map-contract.d.ts +31 -0
  66. package/dist/server/bridge-server.d.ts +53 -0
  67. package/dist/server/index.d.ts +9 -0
  68. package/dist/server/stdio.d.ts +2 -0
  69. package/dist/types.d.ts +24 -0
  70. package/package.json +84 -4
  71. package/skill/kepler/SKILL.md +438 -0
  72. package/skill/kepler/skill.yaml +4 -0
  73. package/README.md +0 -3
@@ -0,0 +1,521 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ import _typeof from "@babel/runtime/helpers/esm/typeof";
4
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
5
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ // SPDX-License-Identifier: MIT
8
+ // Copyright contributors to the kepler.gl project
9
+
10
+ /**
11
+ * Pure helpers shared by the map.* commands and the analysis shims. These are
12
+ * dependency-light (apache-arrow only) and free of kepler-app state, so they
13
+ * live in the map surface package and are re-exported for the analysis layer
14
+ * (kepler-assistant) to import.
15
+ */
16
+
17
+ import { Type } from 'apache-arrow';
18
+ import { LAYER_TYPES } from '@kepler.gl/constants';
19
+ import { arrowSchemaToFields } from '@kepler.gl/processors';
20
+
21
+ /** Type for a Redux dispatch function, used by tools that need to dispatch kepler actions */
22
+
23
+ /**
24
+ * Deterministically convert a dataset name into a valid DuckDB table name.
25
+ * Replaces non-alphanumeric characters (except underscores) with underscores,
26
+ * collapses consecutive underscores, trims leading/trailing underscores,
27
+ * lowercases the result, and prepends 'tbl_' to avoid reserved-word collisions.
28
+ */
29
+ export function datasetNameToTableName(datasetName) {
30
+ var sanitized = datasetName.replace(/[^a-zA-Z0-9_]/g, '_').replace(/_+/g, '_').replace(/^_+|_+$/g, '').toLowerCase();
31
+ return "tbl_".concat(sanitized || 'unnamed');
32
+ }
33
+
34
+ /**
35
+ * Recursively convert an Arrow row (which uses proxy objects) into a plain JS
36
+ * object. Handles nested toJSON(), arrays, and bigint values. Extracted from
37
+ * query-tool.ts so the stock @sqlrooms/ai query tool wrapper can share it.
38
+ */
39
+ export function convertArrowRowToObject(row) {
40
+ if (row === null || _typeof(row) !== 'object') return row;
41
+ if (typeof row.toJSON === 'function') {
42
+ var json = row.toJSON();
43
+ for (var key in json) {
44
+ var val = json[key];
45
+ if (val && _typeof(val) === 'object' && typeof val.toJSON === 'function') {
46
+ json[key] = convertArrowRowToObject(val);
47
+ } else if (Array.isArray(val)) {
48
+ json[key] = val.map(function (v) {
49
+ return convertArrowRowToObject(v);
50
+ });
51
+ } else if (typeof val === 'bigint') {
52
+ json[key] = val.toString();
53
+ }
54
+ }
55
+ return json;
56
+ }
57
+ if (Array.isArray(row)) {
58
+ return row.map(convertArrowRowToObject);
59
+ }
60
+ return row;
61
+ }
62
+
63
+ /**
64
+ * Normalize a Decimal BigNum into an indexable word array. Arrow's
65
+ * DecimalBigNum is a Uint32Array (has `.length`); `row.toJSON()` can emit it as
66
+ * a plain numeric-key object ({0: low, 1: high, ...}) with no `.length`, which
67
+ * decimalBigNumToNumber would miscompute (the loop never runs, returning 0).
68
+ */
69
+ function toWordArray(v) {
70
+ if (Array.isArray(v)) {
71
+ return v;
72
+ }
73
+ if (ArrayBuffer.isView(v)) {
74
+ return Array.from(v);
75
+ }
76
+ var words = [];
77
+ for (var i = 0; i < 4; i++) {
78
+ if (v[i] === undefined) break;
79
+ words.push(v[i]);
80
+ }
81
+ return words;
82
+ }
83
+
84
+ /**
85
+ * Convert an Arrow DecimalBigNum (128-bit signed, stored as a Uint32Array of
86
+ * words) to a JS number, applying the column's declared scale.
87
+ *
88
+ * Arrow's own `valueOf(scale)` divides the raw bigint by 10^scale and converts
89
+ * the intermediate denominator with bigIntToNumber, which throws for scale >= 16
90
+ * (10^16 > Number.MAX_SAFE_INTEGER). We instead reconstruct the bigint and
91
+ * insert the decimal point via string manipulation, which avoids that throw and
92
+ * is exact up to the final JS Number coercion — very large Decimal128 values can
93
+ * still lose precision or overflow when converted to a Number.
94
+ */
95
+ function decimalBigNumToNumber(v, scale) {
96
+ var words = toWordArray(v);
97
+ // Only convert when at least one word exists — an empty word array is a
98
+ // zero value (or a non-BigNum object that shouldn't be here).
99
+ if (words.length === 0) return 0;
100
+ var big = 0n;
101
+ for (var i = words.length - 1; i >= 0; i--) {
102
+ big = big << 32n | BigInt(words[i] >>> 0);
103
+ }
104
+ // Two's complement sign (128-bit).
105
+ if (words[words.length - 1] & 0x80000000) {
106
+ big -= 1n << BigInt(32 * words.length);
107
+ }
108
+ var negative = big < 0n;
109
+ if (negative) big = -big;
110
+ var s = big.toString();
111
+ if (scale > 0) {
112
+ if (s.length <= scale) s = s.padStart(scale + 1, '0');
113
+ s = "".concat(s.slice(0, s.length - scale), ".").concat(s.slice(s.length - scale));
114
+ }
115
+ return Number("".concat(negative ? '-' : '').concat(s));
116
+ }
117
+
118
+ /**
119
+ * Convert an Arrow Table to an array of plain JS objects.
120
+ *
121
+ * Decimal columns are resolved to numbers using each column's declared scale.
122
+ * `row.toJSON()` passes Decimal values through as opaque BigNum objects
123
+ * ({0: low, 1: high, ...}), which kepler.gl then stores as `object`-typed
124
+ * fields and downstream commands (e.g. `data.merge-tables`) choke on when they
125
+ * try to re-materialize the dataset into DuckDB. The schema carries the scale,
126
+ * so we resolve the value here.
127
+ */
128
+ export function arrowTableToObjects(table) {
129
+ var _table$schema$fields, _table$schema;
130
+ var scaleByColumn = new Map();
131
+ var _iterator = _createForOfIteratorHelper((_table$schema$fields = (_table$schema = table.schema) === null || _table$schema === void 0 ? void 0 : _table$schema.fields) !== null && _table$schema$fields !== void 0 ? _table$schema$fields : []),
132
+ _step;
133
+ try {
134
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
135
+ var _field$type;
136
+ var field = _step.value;
137
+ if (((_field$type = field.type) === null || _field$type === void 0 ? void 0 : _field$type.typeId) === Type.Decimal && typeof field.type.scale === 'number') {
138
+ scaleByColumn.set(field.name, field.type.scale);
139
+ }
140
+ }
141
+ } catch (err) {
142
+ _iterator.e(err);
143
+ } finally {
144
+ _iterator.f();
145
+ }
146
+ return table.toArray().map(function (row) {
147
+ var json = row.toJSON();
148
+ var _iterator2 = _createForOfIteratorHelper(scaleByColumn),
149
+ _step2;
150
+ try {
151
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
152
+ var _step2$value = _slicedToArray(_step2.value, 2),
153
+ name = _step2$value[0],
154
+ scale = _step2$value[1];
155
+ var v = json[name];
156
+ // The column is Decimal-typed, so object values are BigNums. (The old
157
+ // `typeof v.valueOf === 'function'` guard was always true for objects —
158
+ // every object inherits valueOf — and did not distinguish BigNums.)
159
+ if (v && _typeof(v) === 'object') {
160
+ json[name] = decimalBigNumToNumber(v, scale);
161
+ }
162
+ }
163
+ } catch (err) {
164
+ _iterator2.e(err);
165
+ } finally {
166
+ _iterator2.f();
167
+ }
168
+ for (var key in json) {
169
+ var val = json[key];
170
+ if (val && _typeof(val) === 'object' && typeof val.toJSON === 'function') {
171
+ json[key] = convertArrowRowToObject(val);
172
+ } else if (typeof val === 'bigint') {
173
+ json[key] = val.toString();
174
+ }
175
+ }
176
+ return json;
177
+ });
178
+ }
179
+
180
+ /**
181
+ * Read a column's values from a kepler dataset (by dataset label + field name).
182
+ * Vectors through the vector-tile layer when the dataset is a vector-tile
183
+ * dataset (whose values live in the layer's tile set, not the kepler table).
184
+ *
185
+ * Moved in from kepler-assistant's `src/glue/utils.ts` so this package is
186
+ * self-contained — the map.* commands that call this seam (via `KeplerContext`)
187
+ * cannot import from kepler-assistant (that would be circular).
188
+ */
189
+ export function getValuesFromDataset(datasets, layers, datasetName, variableName) {
190
+ // Commands advertise accepting a dataset "name (label) or id", so match by
191
+ // either — a caller using the dataset id must not fail here.
192
+ var datasetId = Object.keys(datasets).find(function (dataId) {
193
+ return dataId === datasetName || datasets[dataId].label === datasetName;
194
+ });
195
+ if (!datasetId) {
196
+ throw new Error("Dataset ".concat(datasetName, " not found"));
197
+ }
198
+ var dataset = datasets[datasetId];
199
+ if (dataset) {
200
+ var field = dataset.fields.find(function (f) {
201
+ return f.name === variableName;
202
+ });
203
+ if (!field) {
204
+ throw new Error("Field ".concat(variableName, " not found in dataset ").concat(datasetName));
205
+ }
206
+ if (dataset.type === 'vector-tile') {
207
+ // Reuse the field resolved above — no need to re-find it by name.
208
+ return getValuesFromVectorTileLayer(datasetId, layers, field);
209
+ }
210
+ return Array.from({
211
+ length: dataset.length
212
+ }, function (_, i) {
213
+ return dataset.getValue(variableName, i);
214
+ });
215
+ }
216
+ return [];
217
+ }
218
+ export function isVectorTileLayer(layer) {
219
+ return layer.type === LAYER_TYPES.vectorTile;
220
+ }
221
+ export function getValuesFromVectorTileLayer(datasetId, layers, field) {
222
+ var _tileDataset$getTiles, _tileDataset, _tileDataset$getTiles2;
223
+ var layerIndex = layers.findIndex(function (layer) {
224
+ return layer.config.dataId === datasetId;
225
+ });
226
+ if (layerIndex === -1) return [];
227
+ var layer = layers[layerIndex];
228
+ if (!isVectorTileLayer(layer)) return [];
229
+ var accessor = layer.accessRowValue(field);
230
+ var values = [];
231
+ // Iterate the layer's tiles through the public `TileDataset.getTiles()` seam
232
+ // (the same tile->features unwrap the layer itself uses in renderLayer) —
233
+ // not the private `tileSet` field, which is an implementation detail that
234
+ // can change with internal refactors. `tileDataset` is protected, so it
235
+ // needs a cast, but `getTiles()` is a stable public method.
236
+ var tiles = (_tileDataset$getTiles = (_tileDataset = layer.tileDataset) === null || _tileDataset === void 0 || (_tileDataset$getTiles2 = _tileDataset.getTiles) === null || _tileDataset$getTiles2 === void 0 ? void 0 : _tileDataset$getTiles2.call(_tileDataset)) !== null && _tileDataset$getTiles !== void 0 ? _tileDataset$getTiles : [];
237
+ var _iterator3 = _createForOfIteratorHelper(tiles),
238
+ _step3;
239
+ try {
240
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
241
+ var tile = _step3.value;
242
+ var content = tile === null || tile === void 0 ? void 0 : tile.content;
243
+ var features = (content === null || content === void 0 ? void 0 : content.shape) === 'geojson-table' ? content.features : content;
244
+ if (!Array.isArray(features)) continue;
245
+ var _iterator4 = _createForOfIteratorHelper(features),
246
+ _step4;
247
+ try {
248
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
249
+ var row = _step4.value;
250
+ var value = accessor(field, row);
251
+ // Nulls mean "skip this row" (as in kepler's own TileDataset iteration),
252
+ // not "end of data" — breaking here would truncate the values array.
253
+ if (value === null) continue;
254
+ values.push(value);
255
+ }
256
+ } catch (err) {
257
+ _iterator4.e(err);
258
+ } finally {
259
+ _iterator4.f();
260
+ }
261
+ }
262
+ } catch (err) {
263
+ _iterator3.e(err);
264
+ } finally {
265
+ _iterator3.f();
266
+ }
267
+ return values;
268
+ }
269
+
270
+ /**
271
+ * Whether a column holds any non-null object value — e.g. the `_geojson` column,
272
+ * which stores whole GeoJSON Feature objects. Such columns must NOT be handed to
273
+ * `tableFromArrays` raw: Arrow infers ONE type per column from the first value,
274
+ * and a dataset mixing Polygon (depth-3 `coordinates`) and MultiPolygon (depth-4)
275
+ * features gets the shallower type, so the MultiPolygon coordinates come back as
276
+ * `null` and the geometry disappears. Serialize them to JSON strings for the
277
+ * DuckDB round-trip and restore with `restoreObjectColumns`.
278
+ */
279
+ export function isObjectColumn(values) {
280
+ return values.some(function (v) {
281
+ return v !== null && v !== undefined && _typeof(v) === 'object';
282
+ });
283
+ }
284
+
285
+ /**
286
+ * Serialize object values to JSON strings (nulls/primitives pass through
287
+ * unchanged) so `tableFromArrays` never has to infer a nested-struct type.
288
+ */
289
+ export function stringifyObjectColumn(values) {
290
+ if (!isObjectColumn(values)) return values;
291
+ return values.map(function (v) {
292
+ if (v === null || v === undefined) return null;
293
+ return _typeof(v) === 'object' ? JSON.stringify(v) : v;
294
+ });
295
+ }
296
+
297
+ /**
298
+ * Restore object-valued columns that `stringifyObjectColumn` serialized back to
299
+ * their object form, in place. Used after a DuckDB query returns those columns
300
+ * as JSON strings (e.g. `_geojson` after `SELECT *`).
301
+ */
302
+ export function restoreObjectColumns(rows, columnNames) {
303
+ if (columnNames.length === 0) return;
304
+ var _iterator5 = _createForOfIteratorHelper(rows),
305
+ _step5;
306
+ try {
307
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
308
+ var row = _step5.value;
309
+ var _iterator6 = _createForOfIteratorHelper(columnNames),
310
+ _step6;
311
+ try {
312
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
313
+ var name = _step6.value;
314
+ var value = row[name];
315
+ if (typeof value === 'string') {
316
+ try {
317
+ var parsed = JSON.parse(value);
318
+ // Only restore object/array values. A column may mix objects with
319
+ // primitives (e.g. a string "1" alongside real objects), and
320
+ // JSON-parsing those would coerce "1" → 1 / "true" → true, silently
321
+ // changing their types. Leave primitives as the original string.
322
+ if (parsed !== null && _typeof(parsed) === 'object') {
323
+ row[name] = parsed;
324
+ }
325
+ } catch (_unused) {
326
+ // Not JSON — leave the string as-is.
327
+ }
328
+ }
329
+ }
330
+ } catch (err) {
331
+ _iterator6.e(err);
332
+ } finally {
333
+ _iterator6.f();
334
+ }
335
+ }
336
+ } catch (err) {
337
+ _iterator5.e(err);
338
+ } finally {
339
+ _iterator5.f();
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Build an `updateDataset` payload that appends ONE new column to an existing
345
+ * kepler dataset, keeping every existing column byte-for-byte identical.
346
+ *
347
+ * Existing columns are read straight from the kepler dataset (via
348
+ * `getValuesFromDataset`) and NEVER round-tripped through Arrow/DuckDB. That
349
+ * matters for `_geojson`: `tableFromArrays` infers a single Arrow type for the
350
+ * whole column, and a dataset mixing Polygon and MultiPolygon features gets the
351
+ * shallower type — the MultiPolygon's deeper coordinate nesting comes back as
352
+ * nulls and the geometry disappears. Only the NEW column's values come from the
353
+ * computation (DuckDB expression / copy, or geoda write-back).
354
+ *
355
+ * @param datasets kepler datasets (visState.datasets)
356
+ * @param layers kepler layers (visState.layers) — needed for vector-tile datasets
357
+ * @param datasetName the dataset label
358
+ * @param newColumnName name of the column being appended
359
+ * @param newColumnArrow single-column arrow table holding the new column's values
360
+ * @returns an `updateDataset` `data` payload: `{rows, fields}`
361
+ */
362
+ export function buildAddColumnPayload(datasets, layers, datasetName, newColumnName, newColumnArrow) {
363
+ // Match by id or label, consistent with getValuesFromDataset and the
364
+ // commands' "name (label) or id" contract.
365
+ var datasetId = Object.keys(datasets).find(function (id) {
366
+ return id === datasetName || datasets[id].label === datasetName;
367
+ });
368
+ if (!datasetId) {
369
+ throw new Error("Dataset \"".concat(datasetName, "\" not found."));
370
+ }
371
+ var dataset = datasets[datasetId];
372
+ var originalFields = dataset.fields;
373
+
374
+ // The new column's values + field descriptor come from the computation's
375
+ // arrow result (DuckDB expression / copy, or geoda write-back).
376
+ var newColumnValues = arrowTableToObjects(newColumnArrow).map(function (o) {
377
+ return o[newColumnName];
378
+ });
379
+ if (newColumnValues.length !== dataset.length) {
380
+ throw new Error("Computed column \"".concat(newColumnName, "\" produced ").concat(newColumnValues.length, " rows, but dataset ") + "\"".concat(datasetName, "\" has ").concat(dataset.length, " rows. The expression must produce exactly one ") + "value per row \u2014 check for filters, joins, or a non-1:1 query.");
381
+ }
382
+ var newField = arrowSchemaToFields(newColumnArrow)[0];
383
+
384
+ // Existing columns come from the original kepler dataset, never Arrow/DuckDB.
385
+ var columns = originalFields.map(function (f) {
386
+ return {
387
+ name: f.name,
388
+ values: getValuesFromDataset(datasets, layers, datasetName, f.name)
389
+ };
390
+ });
391
+
392
+ // RowDataContainer format: one array per row, indexed by field position.
393
+ var rows = Array.from({
394
+ length: dataset.length
395
+ }, function (_, i) {
396
+ return [].concat(_toConsumableArray(columns.map(function (c) {
397
+ return c.values[i];
398
+ })), [newColumnValues[i]]);
399
+ });
400
+ var fields = [].concat(_toConsumableArray(originalFields), [newField]);
401
+ return {
402
+ rows: rows,
403
+ fields: fields
404
+ };
405
+ }
406
+
407
+ /**
408
+ * Default number of first rows to format and return to the LLM as a preview.
409
+ * Mirrors spatial-agent's NUMBER_OF_ROWS_RETURN_TO_LLM.
410
+ */
411
+ export var NUMBER_OF_ROWS_RETURN_TO_LLM = 5;
412
+
413
+ /**
414
+ * Default total character budget for the LLM-facing preview. Capped at ~1000
415
+ * chars so the preview stays small in context, matching spatial-agent's
416
+ * formatResultsForLLM default.
417
+ */
418
+ export var LLM_PREVIEW_MAX_TOTAL_LENGTH = 1000;
419
+ export var LLM_PREVIEW_MAX_VALUE_LENGTH = 80;
420
+
421
+ /**
422
+ * Format a query result table as a pipe-delimited string suitable for LLM
423
+ * consumption. Truncates individual cell values and total output to stay within
424
+ * a token budget. Shared by the stock @sqlrooms/ai query tool wrapper and the
425
+ * skill executeApi data.query path.
426
+ */
427
+ export function tableToLLMResult(table) {
428
+ var maxTotalLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : LLM_PREVIEW_MAX_TOTAL_LENGTH;
429
+ var maxValueLength = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : LLM_PREVIEW_MAX_VALUE_LENGTH;
430
+ if (table.length === 0) return 'No rows returned';
431
+ var _truncateValue = function truncateValue(value) {
432
+ if (value === null || value === undefined) return '';
433
+ var str;
434
+ if (typeof value === 'bigint') {
435
+ str = value.toString();
436
+ } else if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
437
+ var byteLen = value instanceof ArrayBuffer ? value.byteLength : value.byteLength;
438
+ str = "<".concat(byteLen, " bytes>");
439
+ } else if (Array.isArray(value)) {
440
+ // Format each element through truncateValue so object elements render
441
+ // as JSON (not "[object Object]") and bigints/typed values stay
442
+ // consistent with the scalar branches — String(v) would lose that
443
+ // structure and bypass the bigint-safe stringify.
444
+ str = value.map(function (v) {
445
+ return _truncateValue(v);
446
+ }).join(', ');
447
+ } else if (_typeof(value) === 'object') {
448
+ try {
449
+ str = JSON.stringify(value, function (_k, v) {
450
+ return typeof v === 'bigint' ? v.toString() : v;
451
+ });
452
+ } catch (_unused2) {
453
+ str = String(value);
454
+ }
455
+ } else {
456
+ str = String(value);
457
+ }
458
+ return str.length > maxValueLength ? "".concat(str.slice(0, maxValueLength), "...") : str;
459
+ };
460
+ var columns = Object.keys(table[0] || {});
461
+ var headerRow = "| ".concat(columns.join(' | '), " |");
462
+ var separatorRow = "| ".concat(columns.map(function () {
463
+ return '---';
464
+ }).join(' | '), " |");
465
+ var lines = [headerRow, separatorRow];
466
+ // Track the joined length incrementally instead of re-joining the whole
467
+ // array on every row (O(n²) in the number of preview rows).
468
+ var currentLength = headerRow.length + separatorRow.length + 1; // +1 for the '\n' between them
469
+ var _iterator7 = _createForOfIteratorHelper(table),
470
+ _step7;
471
+ try {
472
+ var _loop = function _loop() {
473
+ var row = _step7.value;
474
+ var values = columns.map(function (col) {
475
+ return _truncateValue(row[col]);
476
+ });
477
+ var line = "| ".concat(values.join(' | '), " |");
478
+ lines.push(line);
479
+ currentLength += line.length + 1; // +1 for the '\n' separator
480
+
481
+ if (currentLength > maxTotalLength - 100) {
482
+ lines.push('...');
483
+ return 1; // break
484
+ }
485
+ };
486
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
487
+ if (_loop()) break;
488
+ }
489
+ } catch (err) {
490
+ _iterator7.e(err);
491
+ } finally {
492
+ _iterator7.f();
493
+ }
494
+ var result = lines.join('\n');
495
+ if (result.length > maxTotalLength) {
496
+ result = "".concat(result.slice(0, maxTotalLength), "\n...");
497
+ }
498
+ return result;
499
+ }
500
+
501
+ /**
502
+ * Format the first N rows of an Arrow result as a pipe-delimited string for the
503
+ * LLM, capped at maxTotalLength chars. Convenience wrapper combining
504
+ * arrowTableToObjects + tableToLLMResult: slices the first `numberOfRows`
505
+ * rows, normalizes Decimal columns via arrowTableToObjects (applying each
506
+ * column's declared scale so previews don't leak opaque BigNum word objects),
507
+ * then renders the pipe table.
508
+ */
509
+ export function formatResultsForLLM(result) {
510
+ var _options$maxTotalLeng, _options$maxValueLeng;
511
+ var numberOfRows = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NUMBER_OF_ROWS_RETURN_TO_LLM;
512
+ var options = arguments.length > 2 ? arguments[2] : undefined;
513
+ var rows = arrowTableToObjects({
514
+ toArray: function toArray() {
515
+ return result.toArray().slice(0, numberOfRows);
516
+ },
517
+ schema: result.schema
518
+ });
519
+ return tableToLLMResult(rows, (_options$maxTotalLeng = options === null || options === void 0 ? void 0 : options.maxTotalLength) !== null && _options$maxTotalLeng !== void 0 ? _options$maxTotalLeng : LLM_PREVIEW_MAX_TOTAL_LENGTH, (_options$maxValueLeng = options === null || options === void 0 ? void 0 : options.maxValueLength) !== null && _options$maxValueLeng !== void 0 ? _options$maxValueLeng : LLM_PREVIEW_MAX_VALUE_LENGTH);
520
+ }
521
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJUeXBlIiwiTEFZRVJfVFlQRVMiLCJhcnJvd1NjaGVtYVRvRmllbGRzIiwiZGF0YXNldE5hbWVUb1RhYmxlTmFtZSIsImRhdGFzZXROYW1lIiwic2FuaXRpemVkIiwicmVwbGFjZSIsInRvTG93ZXJDYXNlIiwiY29uY2F0IiwiY29udmVydEFycm93Um93VG9PYmplY3QiLCJyb3ciLCJfdHlwZW9mIiwidG9KU09OIiwianNvbiIsImtleSIsInZhbCIsIkFycmF5IiwiaXNBcnJheSIsIm1hcCIsInYiLCJ0b1N0cmluZyIsInRvV29yZEFycmF5IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJmcm9tIiwid29yZHMiLCJpIiwidW5kZWZpbmVkIiwicHVzaCIsImRlY2ltYWxCaWdOdW1Ub051bWJlciIsInNjYWxlIiwibGVuZ3RoIiwiYmlnIiwiQmlnSW50IiwibmVnYXRpdmUiLCJzIiwicGFkU3RhcnQiLCJzbGljZSIsIk51bWJlciIsImFycm93VGFibGVUb09iamVjdHMiLCJ0YWJsZSIsIl90YWJsZSRzY2hlbWEkZmllbGRzIiwiX3RhYmxlJHNjaGVtYSIsInNjYWxlQnlDb2x1bW4iLCJNYXAiLCJfaXRlcmF0b3IiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsInNjaGVtYSIsImZpZWxkcyIsIl9zdGVwIiwibiIsImRvbmUiLCJfZmllbGQkdHlwZSIsImZpZWxkIiwidmFsdWUiLCJ0eXBlIiwidHlwZUlkIiwiRGVjaW1hbCIsInNldCIsIm5hbWUiLCJlcnIiLCJlIiwiZiIsInRvQXJyYXkiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwiX3N0ZXAyJHZhbHVlIiwiX3NsaWNlZFRvQXJyYXkiLCJnZXRWYWx1ZXNGcm9tRGF0YXNldCIsImRhdGFzZXRzIiwibGF5ZXJzIiwidmFyaWFibGVOYW1lIiwiZGF0YXNldElkIiwiT2JqZWN0Iiwia2V5cyIsImZpbmQiLCJkYXRhSWQiLCJsYWJlbCIsIkVycm9yIiwiZGF0YXNldCIsImdldFZhbHVlc0Zyb21WZWN0b3JUaWxlTGF5ZXIiLCJfIiwiZ2V0VmFsdWUiLCJpc1ZlY3RvclRpbGVMYXllciIsImxheWVyIiwidmVjdG9yVGlsZSIsIl90aWxlRGF0YXNldCRnZXRUaWxlcyIsIl90aWxlRGF0YXNldCIsIl90aWxlRGF0YXNldCRnZXRUaWxlczIiLCJsYXllckluZGV4IiwiZmluZEluZGV4IiwiY29uZmlnIiwiYWNjZXNzb3IiLCJhY2Nlc3NSb3dWYWx1ZSIsInZhbHVlcyIsInRpbGVzIiwidGlsZURhdGFzZXQiLCJnZXRUaWxlcyIsImNhbGwiLCJfaXRlcmF0b3IzIiwiX3N0ZXAzIiwidGlsZSIsImNvbnRlbnQiLCJmZWF0dXJlcyIsInNoYXBlIiwiX2l0ZXJhdG9yNCIsIl9zdGVwNCIsImlzT2JqZWN0Q29sdW1uIiwic29tZSIsInN0cmluZ2lmeU9iamVjdENvbHVtbiIsIkpTT04iLCJzdHJpbmdpZnkiLCJyZXN0b3JlT2JqZWN0Q29sdW1ucyIsInJvd3MiLCJjb2x1bW5OYW1lcyIsIl9pdGVyYXRvcjUiLCJfc3RlcDUiLCJfaXRlcmF0b3I2IiwiX3N0ZXA2IiwicGFyc2VkIiwicGFyc2UiLCJfdW51c2VkIiwiYnVpbGRBZGRDb2x1bW5QYXlsb2FkIiwibmV3Q29sdW1uTmFtZSIsIm5ld0NvbHVtbkFycm93IiwiaWQiLCJvcmlnaW5hbEZpZWxkcyIsIm5ld0NvbHVtblZhbHVlcyIsIm8iLCJuZXdGaWVsZCIsImNvbHVtbnMiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJjIiwiTlVNQkVSX09GX1JPV1NfUkVUVVJOX1RPX0xMTSIsIkxMTV9QUkVWSUVXX01BWF9UT1RBTF9MRU5HVEgiLCJMTE1fUFJFVklFV19NQVhfVkFMVUVfTEVOR1RIIiwidGFibGVUb0xMTVJlc3VsdCIsIm1heFRvdGFsTGVuZ3RoIiwiYXJndW1lbnRzIiwibWF4VmFsdWVMZW5ndGgiLCJ0cnVuY2F0ZVZhbHVlIiwic3RyIiwiYnl0ZUxlbiIsImJ5dGVMZW5ndGgiLCJqb2luIiwiX2siLCJfdW51c2VkMiIsIlN0cmluZyIsImhlYWRlclJvdyIsInNlcGFyYXRvclJvdyIsImxpbmVzIiwiY3VycmVudExlbmd0aCIsIl9pdGVyYXRvcjciLCJfc3RlcDciLCJfbG9vcCIsImNvbCIsImxpbmUiLCJyZXN1bHQiLCJmb3JtYXRSZXN1bHRzRm9yTExNIiwiX29wdGlvbnMkbWF4VG90YWxMZW5nIiwiX29wdGlvbnMkbWF4VmFsdWVMZW5nIiwibnVtYmVyT2ZSb3dzIiwib3B0aW9ucyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy91dGlscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG4vKipcbiAqIFB1cmUgaGVscGVycyBzaGFyZWQgYnkgdGhlIG1hcC4qIGNvbW1hbmRzIGFuZCB0aGUgYW5hbHlzaXMgc2hpbXMuIFRoZXNlIGFyZVxuICogZGVwZW5kZW5jeS1saWdodCAoYXBhY2hlLWFycm93IG9ubHkpIGFuZCBmcmVlIG9mIGtlcGxlci1hcHAgc3RhdGUsIHNvIHRoZXlcbiAqIGxpdmUgaW4gdGhlIG1hcCBzdXJmYWNlIHBhY2thZ2UgYW5kIGFyZSByZS1leHBvcnRlZCBmb3IgdGhlIGFuYWx5c2lzIGxheWVyXG4gKiAoa2VwbGVyLWFzc2lzdGFudCkgdG8gaW1wb3J0LlxuICovXG5cbmltcG9ydCB7VHlwZX0gZnJvbSAnYXBhY2hlLWFycm93JztcbmltcG9ydCB7TEFZRVJfVFlQRVN9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7YXJyb3dTY2hlbWFUb0ZpZWxkc30gZnJvbSAnQGtlcGxlci5nbC9wcm9jZXNzb3JzJztcbmltcG9ydCB0eXBlIHtMYXllciwgVmVjdG9yVGlsZUxheWVyfSBmcm9tICdAa2VwbGVyLmdsL2xheWVycyc7XG5pbXBvcnQgdHlwZSB7RGF0YXNldHN9IGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuaW1wb3J0IHR5cGUge0ZpZWxkfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuLyoqIFR5cGUgZm9yIGEgUmVkdXggZGlzcGF0Y2ggZnVuY3Rpb24sIHVzZWQgYnkgdG9vbHMgdGhhdCBuZWVkIHRvIGRpc3BhdGNoIGtlcGxlciBhY3Rpb25zICovXG5leHBvcnQgdHlwZSBLZXBsZXJEaXNwYXRjaCA9IChhY3Rpb246IGFueSkgPT4gdm9pZDtcblxuLyoqXG4gKiBEZXRlcm1pbmlzdGljYWxseSBjb252ZXJ0IGEgZGF0YXNldCBuYW1lIGludG8gYSB2YWxpZCBEdWNrREIgdGFibGUgbmFtZS5cbiAqIFJlcGxhY2VzIG5vbi1hbHBoYW51bWVyaWMgY2hhcmFjdGVycyAoZXhjZXB0IHVuZGVyc2NvcmVzKSB3aXRoIHVuZGVyc2NvcmVzLFxuICogY29sbGFwc2VzIGNvbnNlY3V0aXZlIHVuZGVyc2NvcmVzLCB0cmltcyBsZWFkaW5nL3RyYWlsaW5nIHVuZGVyc2NvcmVzLFxuICogbG93ZXJjYXNlcyB0aGUgcmVzdWx0LCBhbmQgcHJlcGVuZHMgJ3RibF8nIHRvIGF2b2lkIHJlc2VydmVkLXdvcmQgY29sbGlzaW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRhdGFzZXROYW1lVG9UYWJsZU5hbWUoZGF0YXNldE5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHNhbml0aXplZCA9IGRhdGFzZXROYW1lXG4gICAgLnJlcGxhY2UoL1teYS16QS1aMC05X10vZywgJ18nKVxuICAgIC5yZXBsYWNlKC9fKy9nLCAnXycpXG4gICAgLnJlcGxhY2UoL15fK3xfKyQvZywgJycpXG4gICAgLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBgdGJsXyR7c2FuaXRpemVkIHx8ICd1bm5hbWVkJ31gO1xufVxuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGNvbnZlcnQgYW4gQXJyb3cgcm93ICh3aGljaCB1c2VzIHByb3h5IG9iamVjdHMpIGludG8gYSBwbGFpbiBKU1xuICogb2JqZWN0LiBIYW5kbGVzIG5lc3RlZCB0b0pTT04oKSwgYXJyYXlzLCBhbmQgYmlnaW50IHZhbHVlcy4gRXh0cmFjdGVkIGZyb21cbiAqIHF1ZXJ5LXRvb2wudHMgc28gdGhlIHN0b2NrIEBzcWxyb29tcy9haSBxdWVyeSB0b29sIHdyYXBwZXIgY2FuIHNoYXJlIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydEFycm93Um93VG9PYmplY3Qocm93OiBhbnkpOiB1bmtub3duIHtcbiAgaWYgKHJvdyA9PT0gbnVsbCB8fCB0eXBlb2Ygcm93ICE9PSAnb2JqZWN0JykgcmV0dXJuIHJvdztcblxuICBpZiAodHlwZW9mIHJvdy50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCBqc29uID0gcm93LnRvSlNPTigpO1xuICAgIGZvciAoY29uc3Qga2V5IGluIGpzb24pIHtcbiAgICAgIGNvbnN0IHZhbCA9IGpzb25ba2V5XTtcbiAgICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAganNvbltrZXldID0gY29udmVydEFycm93Um93VG9PYmplY3QodmFsKTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIGpzb25ba2V5XSA9IHZhbC5tYXAodiA9PiBjb252ZXJ0QXJyb3dSb3dUb09iamVjdCh2KSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdiaWdpbnQnKSB7XG4gICAgICAgIGpzb25ba2V5XSA9IHZhbC50b1N0cmluZygpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ganNvbjtcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHJvdykpIHtcbiAgICByZXR1cm4gcm93Lm1hcChjb252ZXJ0QXJyb3dSb3dUb09iamVjdCkgYXMgYW55O1xuICB9XG5cbiAgcmV0dXJuIHJvdztcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgYSBEZWNpbWFsIEJpZ051bSBpbnRvIGFuIGluZGV4YWJsZSB3b3JkIGFycmF5LiBBcnJvdydzXG4gKiBEZWNpbWFsQmlnTnVtIGlzIGEgVWludDMyQXJyYXkgKGhhcyBgLmxlbmd0aGApOyBgcm93LnRvSlNPTigpYCBjYW4gZW1pdCBpdCBhc1xuICogYSBwbGFpbiBudW1lcmljLWtleSBvYmplY3QgKHswOiBsb3csIDE6IGhpZ2gsIC4uLn0pIHdpdGggbm8gYC5sZW5ndGhgLCB3aGljaFxuICogZGVjaW1hbEJpZ051bVRvTnVtYmVyIHdvdWxkIG1pc2NvbXB1dGUgKHRoZSBsb29wIG5ldmVyIHJ1bnMsIHJldHVybmluZyAwKS5cbiAqL1xuZnVuY3Rpb24gdG9Xb3JkQXJyYXkodjogYW55KTogbnVtYmVyW10ge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2KSkge1xuICAgIHJldHVybiB2O1xuICB9XG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcodikpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh2IGFzIHVua25vd24gYXMgQXJyYXlMaWtlPG51bWJlcj4pO1xuICB9XG4gIGNvbnN0IHdvcmRzOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGlmICh2W2ldID09PSB1bmRlZmluZWQpIGJyZWFrO1xuICAgIHdvcmRzLnB1c2godltpXSk7XG4gIH1cbiAgcmV0dXJuIHdvcmRzO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYW4gQXJyb3cgRGVjaW1hbEJpZ051bSAoMTI4LWJpdCBzaWduZWQsIHN0b3JlZCBhcyBhIFVpbnQzMkFycmF5IG9mXG4gKiB3b3JkcykgdG8gYSBKUyBudW1iZXIsIGFwcGx5aW5nIHRoZSBjb2x1bW4ncyBkZWNsYXJlZCBzY2FsZS5cbiAqXG4gKiBBcnJvdydzIG93biBgdmFsdWVPZihzY2FsZSlgIGRpdmlkZXMgdGhlIHJhdyBiaWdpbnQgYnkgMTBec2NhbGUgYW5kIGNvbnZlcnRzXG4gKiB0aGUgaW50ZXJtZWRpYXRlIGRlbm9taW5hdG9yIHdpdGggYmlnSW50VG9OdW1iZXIsIHdoaWNoIHRocm93cyBmb3Igc2NhbGUgPj0gMTZcbiAqICgxMF4xNiA+IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKS4gV2UgaW5zdGVhZCByZWNvbnN0cnVjdCB0aGUgYmlnaW50IGFuZFxuICogaW5zZXJ0IHRoZSBkZWNpbWFsIHBvaW50IHZpYSBzdHJpbmcgbWFuaXB1bGF0aW9uLCB3aGljaCBhdm9pZHMgdGhhdCB0aHJvdyBhbmRcbiAqIGlzIGV4YWN0IHVwIHRvIHRoZSBmaW5hbCBKUyBOdW1iZXIgY29lcmNpb24g4oCUIHZlcnkgbGFyZ2UgRGVjaW1hbDEyOCB2YWx1ZXMgY2FuXG4gKiBzdGlsbCBsb3NlIHByZWNpc2lvbiBvciBvdmVyZmxvdyB3aGVuIGNvbnZlcnRlZCB0byBhIE51bWJlci5cbiAqL1xuZnVuY3Rpb24gZGVjaW1hbEJpZ051bVRvTnVtYmVyKHY6IGFueSwgc2NhbGU6IG51bWJlcik6IG51bWJlciB7XG4gIGNvbnN0IHdvcmRzID0gdG9Xb3JkQXJyYXkodik7XG4gIC8vIE9ubHkgY29udmVydCB3aGVuIGF0IGxlYXN0IG9uZSB3b3JkIGV4aXN0cyDigJQgYW4gZW1wdHkgd29yZCBhcnJheSBpcyBhXG4gIC8vIHplcm8gdmFsdWUgKG9yIGEgbm9uLUJpZ051bSBvYmplY3QgdGhhdCBzaG91bGRuJ3QgYmUgaGVyZSkuXG4gIGlmICh3b3Jkcy5sZW5ndGggPT09IDApIHJldHVybiAwO1xuICBsZXQgYmlnID0gMG47XG4gIGZvciAobGV0IGkgPSB3b3Jkcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGJpZyA9IChiaWcgPDwgMzJuKSB8IEJpZ0ludCh3b3Jkc1tpXSA+Pj4gMCk7XG4gIH1cbiAgLy8gVHdvJ3MgY29tcGxlbWVudCBzaWduICgxMjgtYml0KS5cbiAgaWYgKHdvcmRzW3dvcmRzLmxlbmd0aCAtIDFdICYgMHg4MDAwMDAwMCkge1xuICAgIGJpZyAtPSAxbiA8PCBCaWdJbnQoMzIgKiB3b3Jkcy5sZW5ndGgpO1xuICB9XG4gIGNvbnN0IG5lZ2F0aXZlID0gYmlnIDwgMG47XG4gIGlmIChuZWdhdGl2ZSkgYmlnID0gLWJpZztcbiAgbGV0IHMgPSBiaWcudG9TdHJpbmcoKTtcbiAgaWYgKHNjYWxlID4gMCkge1xuICAgIGlmIChzLmxlbmd0aCA8PSBzY2FsZSkgcyA9IHMucGFkU3RhcnQoc2NhbGUgKyAxLCAnMCcpO1xuICAgIHMgPSBgJHtzLnNsaWNlKDAsIHMubGVuZ3RoIC0gc2NhbGUpfS4ke3Muc2xpY2Uocy5sZW5ndGggLSBzY2FsZSl9YDtcbiAgfVxuICByZXR1cm4gTnVtYmVyKGAke25lZ2F0aXZlID8gJy0nIDogJyd9JHtzfWApO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYW4gQXJyb3cgVGFibGUgdG8gYW4gYXJyYXkgb2YgcGxhaW4gSlMgb2JqZWN0cy5cbiAqXG4gKiBEZWNpbWFsIGNvbHVtbnMgYXJlIHJlc29sdmVkIHRvIG51bWJlcnMgdXNpbmcgZWFjaCBjb2x1bW4ncyBkZWNsYXJlZCBzY2FsZS5cbiAqIGByb3cudG9KU09OKClgIHBhc3NlcyBEZWNpbWFsIHZhbHVlcyB0aHJvdWdoIGFzIG9wYXF1ZSBCaWdOdW0gb2JqZWN0c1xuICogKHswOiBsb3csIDE6IGhpZ2gsIC4uLn0pLCB3aGljaCBrZXBsZXIuZ2wgdGhlbiBzdG9yZXMgYXMgYG9iamVjdGAtdHlwZWRcbiAqIGZpZWxkcyBhbmQgZG93bnN0cmVhbSBjb21tYW5kcyAoZS5nLiBgZGF0YS5tZXJnZS10YWJsZXNgKSBjaG9rZSBvbiB3aGVuIHRoZXlcbiAqIHRyeSB0byByZS1tYXRlcmlhbGl6ZSB0aGUgZGF0YXNldCBpbnRvIER1Y2tEQi4gVGhlIHNjaGVtYSBjYXJyaWVzIHRoZSBzY2FsZSxcbiAqIHNvIHdlIHJlc29sdmUgdGhlIHZhbHVlIGhlcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcnJvd1RhYmxlVG9PYmplY3RzKHRhYmxlOiB7XG4gIHRvQXJyYXk6ICgpID0+IGFueVtdO1xuICBzY2hlbWE/OiB7ZmllbGRzOiB7bmFtZTogc3RyaW5nOyB0eXBlPzoge3R5cGVJZD86IG51bWJlcjsgc2NhbGU/OiBudW1iZXJ9fVtdfTtcbn0pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdIHtcbiAgY29uc3Qgc2NhbGVCeUNvbHVtbiA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIGZvciAoY29uc3QgZmllbGQgb2YgdGFibGUuc2NoZW1hPy5maWVsZHMgPz8gW10pIHtcbiAgICBpZiAoZmllbGQudHlwZT8udHlwZUlkID09PSBUeXBlLkRlY2ltYWwgJiYgdHlwZW9mIGZpZWxkLnR5cGUuc2NhbGUgPT09ICdudW1iZXInKSB7XG4gICAgICBzY2FsZUJ5Q29sdW1uLnNldChmaWVsZC5uYW1lLCBmaWVsZC50eXBlLnNjYWxlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhYmxlLnRvQXJyYXkoKS5tYXAoKHJvdzogYW55KSA9PiB7XG4gICAgY29uc3QganNvbiA9IHJvdy50b0pTT04oKTtcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBzY2FsZV0gb2Ygc2NhbGVCeUNvbHVtbikge1xuICAgICAgY29uc3QgdiA9IGpzb25bbmFtZV07XG4gICAgICAvLyBUaGUgY29sdW1uIGlzIERlY2ltYWwtdHlwZWQsIHNvIG9iamVjdCB2YWx1ZXMgYXJlIEJpZ051bXMuIChUaGUgb2xkXG4gICAgICAvLyBgdHlwZW9mIHYudmFsdWVPZiA9PT0gJ2Z1bmN0aW9uJ2AgZ3VhcmQgd2FzIGFsd2F5cyB0cnVlIGZvciBvYmplY3RzIOKAlFxuICAgICAgLy8gZXZlcnkgb2JqZWN0IGluaGVyaXRzIHZhbHVlT2Yg4oCUIGFuZCBkaWQgbm90IGRpc3Rpbmd1aXNoIEJpZ051bXMuKVxuICAgICAgaWYgKHYgJiYgdHlwZW9mIHYgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGpzb25bbmFtZV0gPSBkZWNpbWFsQmlnTnVtVG9OdW1iZXIodiwgc2NhbGUpO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBqc29uKSB7XG4gICAgICBjb25zdCB2YWwgPSBqc29uW2tleV07XG4gICAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWwudG9KU09OID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGpzb25ba2V5XSA9IGNvbnZlcnRBcnJvd1Jvd1RvT2JqZWN0KHZhbCk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdiaWdpbnQnKSB7XG4gICAgICAgIGpzb25ba2V5XSA9IHZhbC50b1N0cmluZygpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ganNvbjtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVhZCBhIGNvbHVtbidzIHZhbHVlcyBmcm9tIGEga2VwbGVyIGRhdGFzZXQgKGJ5IGRhdGFzZXQgbGFiZWwgKyBmaWVsZCBuYW1lKS5cbiAqIFZlY3RvcnMgdGhyb3VnaCB0aGUgdmVjdG9yLXRpbGUgbGF5ZXIgd2hlbiB0aGUgZGF0YXNldCBpcyBhIHZlY3Rvci10aWxlXG4gKiBkYXRhc2V0ICh3aG9zZSB2YWx1ZXMgbGl2ZSBpbiB0aGUgbGF5ZXIncyB0aWxlIHNldCwgbm90IHRoZSBrZXBsZXIgdGFibGUpLlxuICpcbiAqIE1vdmVkIGluIGZyb20ga2VwbGVyLWFzc2lzdGFudCdzIGBzcmMvZ2x1ZS91dGlscy50c2Agc28gdGhpcyBwYWNrYWdlIGlzXG4gKiBzZWxmLWNvbnRhaW5lZCDigJQgdGhlIG1hcC4qIGNvbW1hbmRzIHRoYXQgY2FsbCB0aGlzIHNlYW0gKHZpYSBgS2VwbGVyQ29udGV4dGApXG4gKiBjYW5ub3QgaW1wb3J0IGZyb20ga2VwbGVyLWFzc2lzdGFudCAodGhhdCB3b3VsZCBiZSBjaXJjdWxhcikuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYWx1ZXNGcm9tRGF0YXNldChcbiAgZGF0YXNldHM6IERhdGFzZXRzLFxuICBsYXllcnM6IExheWVyW10sXG4gIGRhdGFzZXROYW1lOiBzdHJpbmcsXG4gIHZhcmlhYmxlTmFtZTogc3RyaW5nXG4pOiB1bmtub3duW10ge1xuICAvLyBDb21tYW5kcyBhZHZlcnRpc2UgYWNjZXB0aW5nIGEgZGF0YXNldCBcIm5hbWUgKGxhYmVsKSBvciBpZFwiLCBzbyBtYXRjaCBieVxuICAvLyBlaXRoZXIg4oCUIGEgY2FsbGVyIHVzaW5nIHRoZSBkYXRhc2V0IGlkIG11c3Qgbm90IGZhaWwgaGVyZS5cbiAgY29uc3QgZGF0YXNldElkID0gT2JqZWN0LmtleXMoZGF0YXNldHMpLmZpbmQoXG4gICAgZGF0YUlkID0+IGRhdGFJZCA9PT0gZGF0YXNldE5hbWUgfHwgZGF0YXNldHNbZGF0YUlkXS5sYWJlbCA9PT0gZGF0YXNldE5hbWVcbiAgKTtcbiAgaWYgKCFkYXRhc2V0SWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYERhdGFzZXQgJHtkYXRhc2V0TmFtZX0gbm90IGZvdW5kYCk7XG4gIH1cbiAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW2RhdGFzZXRJZF07XG4gIGlmIChkYXRhc2V0KSB7XG4gICAgY29uc3QgZmllbGQgPSBkYXRhc2V0LmZpZWxkcy5maW5kKGYgPT4gZi5uYW1lID09PSB2YXJpYWJsZU5hbWUpO1xuICAgIGlmICghZmllbGQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmllbGQgJHt2YXJpYWJsZU5hbWV9IG5vdCBmb3VuZCBpbiBkYXRhc2V0ICR7ZGF0YXNldE5hbWV9YCk7XG4gICAgfVxuICAgIGlmIChkYXRhc2V0LnR5cGUgPT09ICd2ZWN0b3ItdGlsZScpIHtcbiAgICAgIC8vIFJldXNlIHRoZSBmaWVsZCByZXNvbHZlZCBhYm92ZSDigJQgbm8gbmVlZCB0byByZS1maW5kIGl0IGJ5IG5hbWUuXG4gICAgICByZXR1cm4gZ2V0VmFsdWVzRnJvbVZlY3RvclRpbGVMYXllcihkYXRhc2V0SWQsIGxheWVycywgZmllbGQpO1xuICAgIH1cbiAgICByZXR1cm4gQXJyYXkuZnJvbSh7bGVuZ3RoOiBkYXRhc2V0Lmxlbmd0aH0sIChfLCBpKSA9PiBkYXRhc2V0LmdldFZhbHVlKHZhcmlhYmxlTmFtZSwgaSkpO1xuICB9XG4gIHJldHVybiBbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmVjdG9yVGlsZUxheWVyKGxheWVyOiBMYXllcik6IGxheWVyIGlzIFZlY3RvclRpbGVMYXllciB7XG4gIHJldHVybiBsYXllci50eXBlID09PSBMQVlFUl9UWVBFUy52ZWN0b3JUaWxlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsdWVzRnJvbVZlY3RvclRpbGVMYXllcihkYXRhc2V0SWQ6IHN0cmluZywgbGF5ZXJzOiBMYXllcltdLCBmaWVsZDogRmllbGQpIHtcbiAgY29uc3QgbGF5ZXJJbmRleCA9IGxheWVycy5maW5kSW5kZXgobGF5ZXIgPT4gbGF5ZXIuY29uZmlnLmRhdGFJZCA9PT0gZGF0YXNldElkKTtcbiAgaWYgKGxheWVySW5kZXggPT09IC0xKSByZXR1cm4gW107XG4gIGNvbnN0IGxheWVyID0gbGF5ZXJzW2xheWVySW5kZXhdO1xuICBpZiAoIWlzVmVjdG9yVGlsZUxheWVyKGxheWVyKSkgcmV0dXJuIFtdO1xuICBjb25zdCBhY2Nlc3NvciA9IGxheWVyLmFjY2Vzc1Jvd1ZhbHVlKGZpZWxkKTtcbiAgY29uc3QgdmFsdWVzOiB1bmtub3duW10gPSBbXTtcbiAgLy8gSXRlcmF0ZSB0aGUgbGF5ZXIncyB0aWxlcyB0aHJvdWdoIHRoZSBwdWJsaWMgYFRpbGVEYXRhc2V0LmdldFRpbGVzKClgIHNlYW1cbiAgLy8gKHRoZSBzYW1lIHRpbGUtPmZlYXR1cmVzIHVud3JhcCB0aGUgbGF5ZXIgaXRzZWxmIHVzZXMgaW4gcmVuZGVyTGF5ZXIpIOKAlFxuICAvLyBub3QgdGhlIHByaXZhdGUgYHRpbGVTZXRgIGZpZWxkLCB3aGljaCBpcyBhbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgdGhhdFxuICAvLyBjYW4gY2hhbmdlIHdpdGggaW50ZXJuYWwgcmVmYWN0b3JzLiBgdGlsZURhdGFzZXRgIGlzIHByb3RlY3RlZCwgc28gaXRcbiAgLy8gbmVlZHMgYSBjYXN0LCBidXQgYGdldFRpbGVzKClgIGlzIGEgc3RhYmxlIHB1YmxpYyBtZXRob2QuXG4gIGNvbnN0IHRpbGVzID0gKGxheWVyIGFzIGFueSkudGlsZURhdGFzZXQ/LmdldFRpbGVzPy4oKSA/PyBbXTtcbiAgZm9yIChjb25zdCB0aWxlIG9mIHRpbGVzKSB7XG4gICAgY29uc3QgY29udGVudCA9ICh0aWxlIGFzIGFueSk/LmNvbnRlbnQ7XG4gICAgY29uc3QgZmVhdHVyZXMgPSBjb250ZW50Py5zaGFwZSA9PT0gJ2dlb2pzb24tdGFibGUnID8gY29udGVudC5mZWF0dXJlcyA6IGNvbnRlbnQ7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGZlYXR1cmVzKSkgY29udGludWU7XG4gICAgZm9yIChjb25zdCByb3cgb2YgZmVhdHVyZXMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gYWNjZXNzb3IoZmllbGQsIHJvdyk7XG4gICAgICAvLyBOdWxscyBtZWFuIFwic2tpcCB0aGlzIHJvd1wiIChhcyBpbiBrZXBsZXIncyBvd24gVGlsZURhdGFzZXQgaXRlcmF0aW9uKSxcbiAgICAgIC8vIG5vdCBcImVuZCBvZiBkYXRhXCIg4oCUIGJyZWFraW5nIGhlcmUgd291bGQgdHJ1bmNhdGUgdGhlIHZhbHVlcyBhcnJheS5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgY29udGludWU7XG4gICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZXM7XG59XG5cbi8qKlxuICogV2hldGhlciBhIGNvbHVtbiBob2xkcyBhbnkgbm9uLW51bGwgb2JqZWN0IHZhbHVlIOKAlCBlLmcuIHRoZSBgX2dlb2pzb25gIGNvbHVtbixcbiAqIHdoaWNoIHN0b3JlcyB3aG9sZSBHZW9KU09OIEZlYXR1cmUgb2JqZWN0cy4gU3VjaCBjb2x1bW5zIG11c3QgTk9UIGJlIGhhbmRlZCB0b1xuICogYHRhYmxlRnJvbUFycmF5c2AgcmF3OiBBcnJvdyBpbmZlcnMgT05FIHR5cGUgcGVyIGNvbHVtbiBmcm9tIHRoZSBmaXJzdCB2YWx1ZSxcbiAqIGFuZCBhIGRhdGFzZXQgbWl4aW5nIFBvbHlnb24gKGRlcHRoLTMgYGNvb3JkaW5hdGVzYCkgYW5kIE11bHRpUG9seWdvbiAoZGVwdGgtNClcbiAqIGZlYXR1cmVzIGdldHMgdGhlIHNoYWxsb3dlciB0eXBlLCBzbyB0aGUgTXVsdGlQb2x5Z29uIGNvb3JkaW5hdGVzIGNvbWUgYmFjayBhc1xuICogYG51bGxgIGFuZCB0aGUgZ2VvbWV0cnkgZGlzYXBwZWFycy4gU2VyaWFsaXplIHRoZW0gdG8gSlNPTiBzdHJpbmdzIGZvciB0aGVcbiAqIER1Y2tEQiByb3VuZC10cmlwIGFuZCByZXN0b3JlIHdpdGggYHJlc3RvcmVPYmplY3RDb2x1bW5zYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0Q29sdW1uKHZhbHVlczogdW5rbm93bltdKTogYm9vbGVhbiB7XG4gIHJldHVybiB2YWx1ZXMuc29tZSh2ID0+IHYgIT09IG51bGwgJiYgdiAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2ID09PSAnb2JqZWN0Jyk7XG59XG5cbi8qKlxuICogU2VyaWFsaXplIG9iamVjdCB2YWx1ZXMgdG8gSlNPTiBzdHJpbmdzIChudWxscy9wcmltaXRpdmVzIHBhc3MgdGhyb3VnaFxuICogdW5jaGFuZ2VkKSBzbyBgdGFibGVGcm9tQXJyYXlzYCBuZXZlciBoYXMgdG8gaW5mZXIgYSBuZXN0ZWQtc3RydWN0IHR5cGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmdpZnlPYmplY3RDb2x1bW4odmFsdWVzOiB1bmtub3duW10pOiB1bmtub3duW10ge1xuICBpZiAoIWlzT2JqZWN0Q29sdW1uKHZhbHVlcykpIHJldHVybiB2YWx1ZXM7XG4gIHJldHVybiB2YWx1ZXMubWFwKHYgPT4ge1xuICAgIGlmICh2ID09PSBudWxsIHx8IHYgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHR5cGVvZiB2ID09PSAnb2JqZWN0JyA/IEpTT04uc3RyaW5naWZ5KHYpIDogdjtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzdG9yZSBvYmplY3QtdmFsdWVkIGNvbHVtbnMgdGhhdCBgc3RyaW5naWZ5T2JqZWN0Q29sdW1uYCBzZXJpYWxpemVkIGJhY2sgdG9cbiAqIHRoZWlyIG9iamVjdCBmb3JtLCBpbiBwbGFjZS4gVXNlZCBhZnRlciBhIER1Y2tEQiBxdWVyeSByZXR1cm5zIHRob3NlIGNvbHVtbnNcbiAqIGFzIEpTT04gc3RyaW5ncyAoZS5nLiBgX2dlb2pzb25gIGFmdGVyIGBTRUxFQ1QgKmApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzdG9yZU9iamVjdENvbHVtbnMocm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSwgY29sdW1uTmFtZXM6IHN0cmluZ1tdKTogdm9pZCB7XG4gIGlmIChjb2x1bW5OYW1lcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2x1bW5OYW1lcykge1xuICAgICAgY29uc3QgdmFsdWUgPSByb3dbbmFtZV07XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgICAgIC8vIE9ubHkgcmVzdG9yZSBvYmplY3QvYXJyYXkgdmFsdWVzLiBBIGNvbHVtbiBtYXkgbWl4IG9iamVjdHMgd2l0aFxuICAgICAgICAgIC8vIHByaW1pdGl2ZXMgKGUuZy4gYSBzdHJpbmcgXCIxXCIgYWxvbmdzaWRlIHJlYWwgb2JqZWN0cyksIGFuZFxuICAgICAgICAgIC8vIEpTT04tcGFyc2luZyB0aG9zZSB3b3VsZCBjb2VyY2UgXCIxXCIg4oaSIDEgLyBcInRydWVcIiDihpIgdHJ1ZSwgc2lsZW50bHlcbiAgICAgICAgICAvLyBjaGFuZ2luZyB0aGVpciB0eXBlcy4gTGVhdmUgcHJpbWl0aXZlcyBhcyB0aGUgb3JpZ2luYWwgc3RyaW5nLlxuICAgICAgICAgIGlmIChwYXJzZWQgIT09IG51bGwgJiYgdHlwZW9mIHBhcnNlZCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJvd1tuYW1lXSA9IHBhcnNlZDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIE5vdCBKU09OIOKAlCBsZWF2ZSB0aGUgc3RyaW5nIGFzLWlzLlxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQnVpbGQgYW4gYHVwZGF0ZURhdGFzZXRgIHBheWxvYWQgdGhhdCBhcHBlbmRzIE9ORSBuZXcgY29sdW1uIHRvIGFuIGV4aXN0aW5nXG4gKiBrZXBsZXIgZGF0YXNldCwga2VlcGluZyBldmVyeSBleGlzdGluZyBjb2x1bW4gYnl0ZS1mb3ItYnl0ZSBpZGVudGljYWwuXG4gKlxuICogRXhpc3RpbmcgY29sdW1ucyBhcmUgcmVhZCBzdHJhaWdodCBmcm9tIHRoZSBrZXBsZXIgZGF0YXNldCAodmlhXG4gKiBgZ2V0VmFsdWVzRnJvbURhdGFzZXRgKSBhbmQgTkVWRVIgcm91bmQtdHJpcHBlZCB0aHJvdWdoIEFycm93L0R1Y2tEQi4gVGhhdFxuICogbWF0dGVycyBmb3IgYF9nZW9qc29uYDogYHRhYmxlRnJvbUFycmF5c2AgaW5mZXJzIGEgc2luZ2xlIEFycm93IHR5cGUgZm9yIHRoZVxuICogd2hvbGUgY29sdW1uLCBhbmQgYSBkYXRhc2V0IG1peGluZyBQb2x5Z29uIGFuZCBNdWx0aVBvbHlnb24gZmVhdHVyZXMgZ2V0cyB0aGVcbiAqIHNoYWxsb3dlciB0eXBlIOKAlCB0aGUgTXVsdGlQb2x5Z29uJ3MgZGVlcGVyIGNvb3JkaW5hdGUgbmVzdGluZyBjb21lcyBiYWNrIGFzXG4gKiBudWxscyBhbmQgdGhlIGdlb21ldHJ5IGRpc2FwcGVhcnMuIE9ubHkgdGhlIE5FVyBjb2x1bW4ncyB2YWx1ZXMgY29tZSBmcm9tIHRoZVxuICogY29tcHV0YXRpb24gKER1Y2tEQiBleHByZXNzaW9uIC8gY29weSwgb3IgZ2VvZGEgd3JpdGUtYmFjaykuXG4gKlxuICogQHBhcmFtIGRhdGFzZXRzIGtlcGxlciBkYXRhc2V0cyAodmlzU3RhdGUuZGF0YXNldHMpXG4gKiBAcGFyYW0gbGF5ZXJzIGtlcGxlciBsYXllcnMgKHZpc1N0YXRlLmxheWVycykg4oCUIG5lZWRlZCBmb3IgdmVjdG9yLXRpbGUgZGF0YXNldHNcbiAqIEBwYXJhbSBkYXRhc2V0TmFtZSB0aGUgZGF0YXNldCBsYWJlbFxuICogQHBhcmFtIG5ld0NvbHVtbk5hbWUgbmFtZSBvZiB0aGUgY29sdW1uIGJlaW5nIGFwcGVuZGVkXG4gKiBAcGFyYW0gbmV3Q29sdW1uQXJyb3cgc2luZ2xlLWNvbHVtbiBhcnJvdyB0YWJsZSBob2xkaW5nIHRoZSBuZXcgY29sdW1uJ3MgdmFsdWVzXG4gKiBAcmV0dXJucyBhbiBgdXBkYXRlRGF0YXNldGAgYGRhdGFgIHBheWxvYWQ6IGB7cm93cywgZmllbGRzfWBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQWRkQ29sdW1uUGF5bG9hZChcbiAgZGF0YXNldHM6IERhdGFzZXRzLFxuICBsYXllcnM6IExheWVyW10sXG4gIGRhdGFzZXROYW1lOiBzdHJpbmcsXG4gIG5ld0NvbHVtbk5hbWU6IHN0cmluZyxcbiAgbmV3Q29sdW1uQXJyb3c6IGFueVxuKToge3Jvd3M6IHVua25vd25bXVtdOyBmaWVsZHM6IGFueVtdfSB7XG4gIC8vIE1hdGNoIGJ5IGlkIG9yIGxhYmVsLCBjb25zaXN0ZW50IHdpdGggZ2V0VmFsdWVzRnJvbURhdGFzZXQgYW5kIHRoZVxuICAvLyBjb21tYW5kcycgXCJuYW1lIChsYWJlbCkgb3IgaWRcIiBjb250cmFjdC5cbiAgY29uc3QgZGF0YXNldElkID0gT2JqZWN0LmtleXMoZGF0YXNldHMpLmZpbmQoXG4gICAgaWQgPT4gaWQgPT09IGRhdGFzZXROYW1lIHx8IGRhdGFzZXRzW2lkXS5sYWJlbCA9PT0gZGF0YXNldE5hbWVcbiAgKTtcbiAgaWYgKCFkYXRhc2V0SWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYERhdGFzZXQgXCIke2RhdGFzZXROYW1lfVwiIG5vdCBmb3VuZC5gKTtcbiAgfVxuICBjb25zdCBkYXRhc2V0ID0gZGF0YXNldHNbZGF0YXNldElkXTtcbiAgY29uc3Qgb3JpZ2luYWxGaWVsZHMgPSBkYXRhc2V0LmZpZWxkcztcblxuICAvLyBUaGUgbmV3IGNvbHVtbidzIHZhbHVlcyArIGZpZWxkIGRlc2NyaXB0b3IgY29tZSBmcm9tIHRoZSBjb21wdXRhdGlvbidzXG4gIC8vIGFycm93IHJlc3VsdCAoRHVja0RCIGV4cHJlc3Npb24gLyBjb3B5LCBvciBnZW9kYSB3cml0ZS1iYWNrKS5cbiAgY29uc3QgbmV3Q29sdW1uVmFsdWVzID0gYXJyb3dUYWJsZVRvT2JqZWN0cyhuZXdDb2x1bW5BcnJvdykubWFwKG8gPT4gb1tuZXdDb2x1bW5OYW1lXSk7XG4gIGlmIChuZXdDb2x1bW5WYWx1ZXMubGVuZ3RoICE9PSBkYXRhc2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBDb21wdXRlZCBjb2x1bW4gXCIke25ld0NvbHVtbk5hbWV9XCIgcHJvZHVjZWQgJHtuZXdDb2x1bW5WYWx1ZXMubGVuZ3RofSByb3dzLCBidXQgZGF0YXNldCBgICtcbiAgICAgICAgYFwiJHtkYXRhc2V0TmFtZX1cIiBoYXMgJHtkYXRhc2V0Lmxlbmd0aH0gcm93cy4gVGhlIGV4cHJlc3Npb24gbXVzdCBwcm9kdWNlIGV4YWN0bHkgb25lIGAgK1xuICAgICAgICBgdmFsdWUgcGVyIHJvdyDigJQgY2hlY2sgZm9yIGZpbHRlcnMsIGpvaW5zLCBvciBhIG5vbi0xOjEgcXVlcnkuYFxuICAgICk7XG4gIH1cbiAgY29uc3QgbmV3RmllbGQgPSBhcnJvd1NjaGVtYVRvRmllbGRzKG5ld0NvbHVtbkFycm93KVswXTtcblxuICAvLyBFeGlzdGluZyBjb2x1bW5zIGNvbWUgZnJvbSB0aGUgb3JpZ2luYWwga2VwbGVyIGRhdGFzZXQsIG5ldmVyIEFycm93L0R1Y2tEQi5cbiAgY29uc3QgY29sdW1ucyA9IG9yaWdpbmFsRmllbGRzLm1hcChmID0+ICh7XG4gICAgbmFtZTogZi5uYW1lLFxuICAgIHZhbHVlczogZ2V0VmFsdWVzRnJvbURhdGFzZXQoZGF0YXNldHMsIGxheWVycywgZGF0YXNldE5hbWUsIGYubmFtZSlcbiAgfSkpO1xuXG4gIC8vIFJvd0RhdGFDb250YWluZXIgZm9ybWF0OiBvbmUgYXJyYXkgcGVyIHJvdywgaW5kZXhlZCBieSBmaWVsZCBwb3NpdGlvbi5cbiAgY29uc3Qgcm93cyA9IEFycmF5LmZyb20oe2xlbmd0aDogZGF0YXNldC5sZW5ndGh9LCAoXywgaSkgPT4gW1xuICAgIC4uLmNvbHVtbnMubWFwKGMgPT4gYy52YWx1ZXNbaV0pLFxuICAgIG5ld0NvbHVtblZhbHVlc1tpXVxuICBdKTtcblxuICBjb25zdCBmaWVsZHMgPSBbLi4ub3JpZ2luYWxGaWVsZHMsIG5ld0ZpZWxkXTtcbiAgcmV0dXJuIHtyb3dzLCBmaWVsZHN9O1xufVxuXG4vKipcbiAqIERlZmF1bHQgbnVtYmVyIG9mIGZpcnN0IHJvd3MgdG8gZm9ybWF0IGFuZCByZXR1cm4gdG8gdGhlIExMTSBhcyBhIHByZXZpZXcuXG4gKiBNaXJyb3JzIHNwYXRpYWwtYWdlbnQncyBOVU1CRVJfT0ZfUk9XU19SRVRVUk5fVE9fTExNLlxuICovXG5leHBvcnQgY29uc3QgTlVNQkVSX09GX1JPV1NfUkVUVVJOX1RPX0xMTSA9IDU7XG5cbi8qKlxuICogRGVmYXVsdCB0b3RhbCBjaGFyYWN0ZXIgYnVkZ2V0IGZvciB0aGUgTExNLWZhY2luZyBwcmV2aWV3LiBDYXBwZWQgYXQgfjEwMDBcbiAqIGNoYXJzIHNvIHRoZSBwcmV2aWV3IHN0YXlzIHNtYWxsIGluIGNvbnRleHQsIG1hdGNoaW5nIHNwYXRpYWwtYWdlbnQnc1xuICogZm9ybWF0UmVzdWx0c0ZvckxMTSBkZWZhdWx0LlxuICovXG5leHBvcnQgY29uc3QgTExNX1BSRVZJRVdfTUFYX1RPVEFMX0xFTkdUSCA9IDEwMDA7XG5leHBvcnQgY29uc3QgTExNX1BSRVZJRVdfTUFYX1ZBTFVFX0xFTkdUSCA9IDgwO1xuXG4vKipcbiAqIEZvcm1hdCBhIHF1ZXJ5IHJlc3VsdCB0YWJsZSBhcyBhIHBpcGUtZGVsaW1pdGVkIHN0cmluZyBzdWl0YWJsZSBmb3IgTExNXG4gKiBjb25zdW1wdGlvbi4gVHJ1bmNhdGVzIGluZGl2aWR1YWwgY2VsbCB2YWx1ZXMgYW5kIHRvdGFsIG91dHB1dCB0byBzdGF5IHdpdGhpblxuICogYSB0b2tlbiBidWRnZXQuIFNoYXJlZCBieSB0aGUgc3RvY2sgQHNxbHJvb21zL2FpIHF1ZXJ5IHRvb2wgd3JhcHBlciBhbmQgdGhlXG4gKiBza2lsbCBleGVjdXRlQXBpIGRhdGEucXVlcnkgcGF0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRhYmxlVG9MTE1SZXN1bHQoXG4gIHRhYmxlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICBtYXhUb3RhbExlbmd0aDogbnVtYmVyID0gTExNX1BSRVZJRVdfTUFYX1RPVEFMX0xFTkdUSCxcbiAgbWF4VmFsdWVMZW5ndGg6IG51bWJlciA9IExMTV9QUkVWSUVXX01BWF9WQUxVRV9MRU5HVEhcbik6IHN0cmluZyB7XG4gIGlmICh0YWJsZS5sZW5ndGggPT09IDApIHJldHVybiAnTm8gcm93cyByZXR1cm5lZCc7XG5cbiAgY29uc3QgdHJ1bmNhdGVWYWx1ZSA9ICh2YWx1ZTogdW5rbm93bik6IHN0cmluZyA9PiB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICBsZXQgc3RyOiBzdHJpbmc7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcbiAgICAgIHN0ciA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgfSBlbHNlIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcodmFsdWUpIHx8IHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIGNvbnN0IGJ5dGVMZW4gPVxuICAgICAgICB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyID8gdmFsdWUuYnl0ZUxlbmd0aCA6ICh2YWx1ZSBhcyBBcnJheUJ1ZmZlclZpZXcpLmJ5dGVMZW5ndGg7XG4gICAgICBzdHIgPSBgPCR7Ynl0ZUxlbn0gYnl0ZXM+YDtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAvLyBGb3JtYXQgZWFjaCBlbGVtZW50IHRocm91Z2ggdHJ1bmNhdGVWYWx1ZSBzbyBvYmplY3QgZWxlbWVudHMgcmVuZGVyXG4gICAgICAvLyBhcyBKU09OIChub3QgXCJbb2JqZWN0IE9iamVjdF1cIikgYW5kIGJpZ2ludHMvdHlwZWQgdmFsdWVzIHN0YXlcbiAgICAgIC8vIGNvbnNpc3RlbnQgd2l0aCB0aGUgc2NhbGFyIGJyYW5jaGVzIOKAlCBTdHJpbmcodikgd291bGQgbG9zZSB0aGF0XG4gICAgICAvLyBzdHJ1Y3R1cmUgYW5kIGJ5cGFzcyB0aGUgYmlnaW50LXNhZmUgc3RyaW5naWZ5LlxuICAgICAgc3RyID0gdmFsdWUubWFwKHYgPT4gdHJ1bmNhdGVWYWx1ZSh2KSkuam9pbignLCAnKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN0ciA9IEpTT04uc3RyaW5naWZ5KHZhbHVlLCAoX2ssIHYpID0+ICh0eXBlb2YgdiA9PT0gJ2JpZ2ludCcgPyB2LnRvU3RyaW5nKCkgOiB2KSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgc3RyID0gU3RyaW5nKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0ci5sZW5ndGggPiBtYXhWYWx1ZUxlbmd0aCA/IGAke3N0ci5zbGljZSgwLCBtYXhWYWx1ZUxlbmd0aCl9Li4uYCA6IHN0cjtcbiAgfTtcblxuICBjb25zdCBjb2x1bW5zID0gT2JqZWN0LmtleXModGFibGVbMF0gfHwge30pO1xuICBjb25zdCBoZWFkZXJSb3cgPSBgfCAke2NvbHVtbnMuam9pbignIHwgJyl9IHxgO1xuICBjb25zdCBzZXBhcmF0b3JSb3cgPSBgfCAke2NvbHVtbnMubWFwKCgpID0+ICctLS0nKS5qb2luKCcgfCAnKX0gfGA7XG4gIGNvbnN0IGxpbmVzID0gW2hlYWRlclJvdywgc2VwYXJhdG9yUm93XTtcbiAgLy8gVHJhY2sgdGhlIGpvaW5lZCBsZW5ndGggaW5jcmVtZW50YWxseSBpbnN0ZWFkIG9mIHJlLWpvaW5pbmcgdGhlIHdob2xlXG4gIC8vIGFycmF5IG9uIGV2ZXJ5IHJvdyAoTyhuwrIpIGluIHRoZSBudW1iZXIgb2YgcHJldmlldyByb3dzKS5cbiAgbGV0IGN1cnJlbnRMZW5ndGggPSBoZWFkZXJSb3cubGVuZ3RoICsgc2VwYXJhdG9yUm93Lmxlbmd0aCArIDE7IC8vICsxIGZvciB0aGUgJ1xcbicgYmV0d2VlbiB0aGVtXG5cbiAgZm9yIChjb25zdCByb3cgb2YgdGFibGUpIHtcbiAgICBjb25zdCB2YWx1ZXMgPSBjb2x1bW5zLm1hcChjb2wgPT4gdHJ1bmNhdGVWYWx1ZShyb3dbY29sXSkpO1xuICAgIGNvbnN0IGxpbmUgPSBgfCAke3ZhbHVlcy5qb2luKCcgfCAnKX0gfGA7XG4gICAgbGluZXMucHVzaChsaW5lKTtcbiAgICBjdXJyZW50TGVuZ3RoICs9IGxpbmUubGVuZ3RoICsgMTsgLy8gKzEgZm9yIHRoZSAnXFxuJyBzZXBhcmF0b3JcblxuICAgIGlmIChjdXJyZW50TGVuZ3RoID4gbWF4VG90YWxMZW5ndGggLSAxMDApIHtcbiAgICAgIGxpbmVzLnB1c2goJy4uLicpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgbGV0IHJlc3VsdCA9IGxpbmVzLmpvaW4oJ1xcbicpO1xuICBpZiAocmVzdWx0Lmxlbmd0aCA+IG1heFRvdGFsTGVuZ3RoKSB7XG4gICAgcmVzdWx0ID0gYCR7cmVzdWx0LnNsaWNlKDAsIG1heFRvdGFsTGVuZ3RoKX1cXG4uLi5gO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRm9ybWF0IHRoZSBmaXJzdCBOIHJvd3Mgb2YgYW4gQXJyb3cgcmVzdWx0IGFzIGEgcGlwZS1kZWxpbWl0ZWQgc3RyaW5nIGZvciB0aGVcbiAqIExMTSwgY2FwcGVkIGF0IG1heFRvdGFsTGVuZ3RoIGNoYXJzLiBDb252ZW5pZW5jZSB3cmFwcGVyIGNvbWJpbmluZ1xuICogYXJyb3dUYWJsZVRvT2JqZWN0cyArIHRhYmxlVG9MTE1SZXN1bHQ6IHNsaWNlcyB0aGUgZmlyc3QgYG51bWJlck9mUm93c2BcbiAqIHJvd3MsIG5vcm1hbGl6ZXMgRGVjaW1hbCBjb2x1bW5zIHZpYSBhcnJvd1RhYmxlVG9PYmplY3RzIChhcHBseWluZyBlYWNoXG4gKiBjb2x1bW4ncyBkZWNsYXJlZCBzY2FsZSBzbyBwcmV2aWV3cyBkb24ndCBsZWFrIG9wYXF1ZSBCaWdOdW0gd29yZCBvYmplY3RzKSxcbiAqIHRoZW4gcmVuZGVycyB0aGUgcGlwZSB0YWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFJlc3VsdHNGb3JMTE0oXG4gIHJlc3VsdDoge1xuICAgIHRvQXJyYXk6ICgpID0+IGFueVtdO1xuICAgIHNjaGVtYT86IHtmaWVsZHM6IHtuYW1lOiBzdHJpbmc7IHR5cGU/OiB7dHlwZUlkPzogbnVtYmVyOyBzY2FsZT86IG51bWJlcn19W119O1xuICB9LFxuICBudW1iZXJPZlJvd3M6IG51bWJlciA9IE5VTUJFUl9PRl9ST1dTX1JFVFVSTl9UT19MTE0sXG4gIG9wdGlvbnM/OiB7bWF4VG90YWxMZW5ndGg/OiBudW1iZXI7IG1heFZhbHVlTGVuZ3RoPzogbnVtYmVyfVxuKTogc3RyaW5nIHtcbiAgY29uc3Qgcm93cyA9IGFycm93VGFibGVUb09iamVjdHMoe1xuICAgIHRvQXJyYXk6ICgpID0+IHJlc3VsdC50b0FycmF5KCkuc2xpY2UoMCwgbnVtYmVyT2ZSb3dzKSxcbiAgICBzY2hlbWE6IHJlc3VsdC5zY2hlbWFcbiAgfSk7XG4gIHJldHVybiB0YWJsZVRvTExNUmVzdWx0KFxuICAgIHJvd3MsXG4gICAgb3B0aW9ucz8ubWF4VG90YWxMZW5ndGggPz8gTExNX1BSRVZJRVdfTUFYX1RPVEFMX0xFTkdUSCxcbiAgICBvcHRpb25zPy5tYXhWYWx1ZUxl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