UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

240 lines (239 loc) 39.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.AddLayerToolComponent = AddLayerToolComponent; exports.addLayer = void 0; exports.guessDefaultLayer = guessDefaultLayer; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _lib = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/node_modules/react-redux/lib"); var _src = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/src/layers/src"); var _src2 = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/src/reducers/src"); var _src3 = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/src/actions/src"); var _utils = require("@openassistant/utils"); var _zod = require("zod"); var _react = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/node_modules/react"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project var addLayer = exports.addLayer = (0, _utils.extendedTool)({ description: "Add a kepler.gl map layer from a dataset.\nYou can create basic map layer without color styling, or enhanced map layer with color visualization.\n\nFor basic maps:\n- Simply use datasetName, geometryColumn (if needed), latitudeColumn/longitudeColumn (for point maps), and mapType\n- Omit color-related parameters for simple visualization\n\nFor colored maps:\n- If user requests color visualization, use available columns in the dataset\n- Use dataClassify tool to classify data into bins or unique values when needed\n- If dataClassify tool returns a list of k breaks\n a. For a list of k break values, you must create k+1 entries in the colorMap, with the last value being null.\n b. For example: for breaks = [0, 3, 10], the colorMap could be [{value: 0, color: '##fff7bc', label: '< 0'}, {value: 3, color: '#fec44f', label: '[0-3)'}, {value: null, color: '#d95f0e', label: '>= 3'}]\n- If dataClassify tool returns a list of k unique values\n a. There should be k colors in the colorMap. For example: for uniqueValues = ['a', 'b', 'c'], the colorMap could be [{value: 'a', color: '#1b9e77'}, {value: 'b', color: '#d95f02'}, {value: 'c', color: '#7570b3'}]\n- Generate colorBrewer colors automatically if user doesn't specify colors\n\nFor geojson datasets:\n- Use geometryColumn: '_geojson' and mapType: 'geojson' even for point collections\n", parameters: _zod.z.object({ datasetName: _zod.z.string().describe('The name of the dataset. Note: please do NOT use the datasetId.'), latitudeColumn: _zod.z.string().optional(), longitudeColumn: _zod.z.string().optional(), layerName: _zod.z.string().optional().describe('If possible, generate a name for the layer based on the context.'), layerType: _zod.z["enum"](['point', 'arc', 'line', 'grid', 'hexagon', 'geojson', 'cluster', 'heatmap', 'h3', 'trip', 's2']), colorBy: _zod.z.string().optional(), colorType: _zod.z["enum"](['breaks', 'unique']).optional(), colorMap: _zod.z.array(_zod.z.object({ value: _zod.z.union([_zod.z.string(), _zod.z.number(), _zod.z["null"]()]), color: _zod.z.string() })).optional() }), execute: executeAddLayer, component: AddLayerToolComponent }); function isAddLayerArgs(args) { return (0, _typeof2["default"])(args) === 'object' && args !== null && 'datasetName' in args && 'layerType' in args; } function isAddLayerFunctionContext(context) { return context && typeof context.getDatasets === 'function'; } function executeAddLayer(_x, _x2) { return _executeAddLayer.apply(this, arguments); } function _executeAddLayer() { _executeAddLayer = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(args, options) { var _layer2, _layer3, datasetName, layerName, latitudeColumn, longitudeColumn, layerType, colorBy, colorType, colorMap, datasets, datasetId, dataset, layer, layerId, columns, newLayer, colorField, colorScale, colors, keplerColorMap, colorRange; return _regenerator["default"].wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.prev = 0; if (isAddLayerArgs(args)) { _context.next = 3; break; } throw new Error('Invalid addLayer arguments'); case 3: if (isAddLayerFunctionContext(options.context)) { _context.next = 5; break; } throw new Error('Invalid addLayer context'); case 5: datasetName = args.datasetName, layerName = args.layerName, latitudeColumn = args.latitudeColumn, longitudeColumn = args.longitudeColumn, layerType = args.layerType, colorBy = args.colorBy, colorType = args.colorType, colorMap = args.colorMap; datasets = options.context.getDatasets(); // check if dataset exists in kepler.gl datasetId = Object.keys(datasets).find(function (dataId) { return datasets[dataId].label === datasetName; }); if (datasetId) { _context.next = 10; break; } throw new Error("Dataset ".concat(datasetName, " not found.")); case 10: // check if field exists in the dataset dataset = datasets[datasetId]; // check if layerType is valid layer = guessDefaultLayer(dataset, layerType); layerId = ((_layer2 = layer) === null || _layer2 === void 0 ? void 0 : _layer2.id) || "layer_".concat((0, _utils.generateId)()); if (!layer) { // for point layer, try to creat a point layer manually if LLM sugggests Lat/Lng fields if (layerType === 'point' && latitudeColumn && longitudeColumn) { layer = { id: layerId, type: 'point', config: { dataId: datasetId, label: layerName || "".concat(datasetName, "-").concat(layerType), columns: { lat: { value: latitudeColumn, fieldIdx: dataset.getColumnFieldIdx(latitudeColumn) }, lng: { value: longitudeColumn, fieldIdx: dataset.getColumnFieldIdx(longitudeColumn) } } }, visConfig: { colorRange: { name: 'Ice And Fire', type: 'diverging', category: 'Uber', colors: ['#D50255', '#FEAD54', '#FEEDB1', '#E8FEB5', '#49E3CE', '#0198BD'] } } }; } } if (layer) { _context.next = 16; break; } throw new Error("Invalid layer type: ".concat(layerType, ".")); case 16: columns = ((_layer3 = layer) === null || _layer3 === void 0 || (_layer3 = _layer3.config) === null || _layer3 === void 0 ? void 0 : _layer3.columns) || {}; // construct new layer config for addLayer() action newLayer = { id: layerId, type: layer.type, config: _objectSpread(_objectSpread({}, layer.config), {}, { dataId: datasetId, label: layerName || "".concat(datasetName, "-").concat(layerType), columns: Object.keys(columns).reduce(function (acc, key) { var column = columns[key]; if (column) { acc[key] = column.value; } return acc; }, {}) }) }; if (!colorBy) { _context.next = 33; break; } colorField = dataset.fields.find(function (f) { return f.name === colorBy; }); if (colorField) { _context.next = 22; break; } throw new Error("Field ".concat(colorBy, " not found.")); case 22: // create kepler.gl's colorMap from uniqueValues and breaks colorScale = colorType === 'breaks' ? 'custom' : 'customOrdinal'; colors = colorMap === null || colorMap === void 0 ? void 0 : colorMap.map(function (color) { return color.color; }); keplerColorMap = colorMap === null || colorMap === void 0 ? void 0 : colorMap.map(function (color) { return [color.value, color.color]; }); colorRange = { name: 'color.customPalette', type: 'custom', category: 'Custom', colors: colors, colorMap: keplerColorMap }; newLayer.config['colorScale'] = colorScale; newLayer.config['colorField'] = colorField; newLayer.config['strokeColorScale'] = colorScale; newLayer.config['strokeColorField'] = colorField; newLayer.config.visConfig['colorRange'] = colorRange; newLayer.config.visConfig['strokeColorRange'] = colorRange; newLayer.config['visualChannels'] = { colorField: { name: colorBy, type: colorField === null || colorField === void 0 ? void 0 : colorField.type }, colorScale: colorScale }; case 33: return _context.abrupt("return", { llmResult: { success: true, layer: JSON.stringify(newLayer), details: "map layer ".concat(layerId, " will be added to the map.") }, additionalData: { layer: newLayer, datasetId: datasetId } }); case 36: _context.prev = 36; _context.t0 = _context["catch"](0); return _context.abrupt("return", { llmResult: { success: false, error: _context.t0 instanceof Error ? _context.t0.message : 'Unknown error', instruction: 'Try to fix the error. If the error persists, pause the execution and ask the user to try with different prompt and context.' } }); case 39: case "end": return _context.stop(); } }, _callee, null, [[0, 36]]); })); return _executeAddLayer.apply(this, arguments); } function guessDefaultLayer(dataset, layerType) { // special case for hexagon layer, which could be implemented as findDefaultLayerProps() in hexagon-layer.tsx if (layerType === 'hexagon') { if (dataset.fieldPairs && dataset.fieldPairs.length > 0) { var props = dataset.fieldPairs.map(function (fieldPair) { return { isVisible: true, label: 'Hexbin', columns: fieldPair.pair }; }); var _layer = new _src.LayerClasses.hexagon(props[0]); return _layer; } } var defaultLayers = (0, _src2.findDefaultLayer)(dataset, _src.LayerClasses); var layer = defaultLayers.find(function (l) { return l.type === layerType; }); return layer || defaultLayers.length > 0 ? defaultLayers[0] : null; } function AddLayerToolComponent(_ref) { var layer = _ref.layer, datasetId = _ref.datasetId; var dispatch = (0, _lib.useDispatch)(); (0, _react.useEffect)(function () { dispatch((0, _src3.addLayer)(layer, datasetId)); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return null; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbGliIiwicmVxdWlyZSIsIl9zcmMiLCJfc3JjMiIsIl9zcmMzIiwiX3V0aWxzIiwiX3pvZCIsIl9yZWFjdCIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiYWRkTGF5ZXIiLCJleHBvcnRzIiwiZXh0ZW5kZWRUb29sIiwiZGVzY3JpcHRpb24iLCJwYXJhbWV0ZXJzIiwieiIsIm9iamVjdCIsImRhdGFzZXROYW1lIiwic3RyaW5nIiwiZGVzY3JpYmUiLCJsYXRpdHVkZUNvbHVtbiIsIm9wdGlvbmFsIiwibG9uZ2l0dWRlQ29sdW1uIiwibGF5ZXJOYW1lIiwibGF5ZXJUeXBlIiwiY29sb3JCeSIsImNvbG9yVHlwZSIsImNvbG9yTWFwIiwiYXJyYXkiLCJ2YWx1ZSIsInVuaW9uIiwibnVtYmVyIiwiY29sb3IiLCJleGVjdXRlIiwiZXhlY3V0ZUFkZExheWVyIiwiY29tcG9uZW50IiwiQWRkTGF5ZXJUb29sQ29tcG9uZW50IiwiaXNBZGRMYXllckFyZ3MiLCJhcmdzIiwiX3R5cGVvZjIiLCJpc0FkZExheWVyRnVuY3Rpb25Db250ZXh0IiwiY29udGV4dCIsImdldERhdGFzZXRzIiwiX3giLCJfeDIiLCJfZXhlY3V0ZUFkZExheWVyIiwiX2FzeW5jVG9HZW5lcmF0b3IyIiwiX3JlZ2VuZXJhdG9yIiwibWFyayIsIl9jYWxsZWUiLCJvcHRpb25zIiwiX2xheWVyMiIsIl9sYXllcjMiLCJkYXRhc2V0cyIsImRhdGFzZXRJZCIsImRhdGFzZXQiLCJsYXllciIsImxheWVySWQiLCJjb2x1bW5zIiwibmV3TGF5ZXIiLCJjb2xvckZpZWxkIiwiY29sb3JTY2FsZSIsImNvbG9ycyIsImtlcGxlckNvbG9yTWFwIiwiY29sb3JSYW5nZSIsIndyYXAiLCJfY2FsbGVlJCIsIl9jb250ZXh0IiwicHJldiIsIm5leHQiLCJFcnJvciIsImZpbmQiLCJkYXRhSWQiLCJsYWJlbCIsImNvbmNhdCIsImd1ZXNzRGVmYXVsdExheWVyIiwiaWQiLCJnZW5lcmF0ZUlkIiwidHlwZSIsImNvbmZpZyIsImxhdCIsImZpZWxkSWR4IiwiZ2V0Q29sdW1uRmllbGRJZHgiLCJsbmciLCJ2aXNDb25maWciLCJuYW1lIiwiY2F0ZWdvcnkiLCJyZWR1Y2UiLCJhY2MiLCJrZXkiLCJjb2x1bW4iLCJmaWVsZHMiLCJmIiwibWFwIiwiYWJydXB0IiwibGxtUmVzdWx0Iiwic3VjY2VzcyIsIkpTT04iLCJzdHJpbmdpZnkiLCJkZXRhaWxzIiwiYWRkaXRpb25hbERhdGEiLCJ0MCIsImVycm9yIiwibWVzc2FnZSIsImluc3RydWN0aW9uIiwic3RvcCIsImZpZWxkUGFpcnMiLCJwcm9wcyIsImZpZWxkUGFpciIsImlzVmlzaWJsZSIsInBhaXIiLCJMYXllckNsYXNzZXMiLCJoZXhhZ29uIiwiZGVmYXVsdExheWVycyIsImZpbmREZWZhdWx0TGF5ZXIiLCJsIiwiX3JlZiIsImRpc3BhdGNoIiwidXNlRGlzcGF0Y2giLCJ1c2VFZmZlY3QiLCJhZGRMYXllckFjdGlvbiJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9haS1hc3Npc3RhbnQvc3JjL3Rvb2xzL2tlcGxlci10b29scy9sYXllci1jcmVhdGlvbi10b29sLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge3VzZURpc3BhdGNofSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge0xheWVyQ2xhc3Nlc30gZnJvbSAnQGtlcGxlci5nbC9sYXllcnMnO1xuaW1wb3J0IEtlcGxlclRhYmxlLCB7RGF0YXNldHN9IGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuaW1wb3J0IHtmaW5kRGVmYXVsdExheWVyfSBmcm9tICdAa2VwbGVyLmdsL3JlZHVjZXJzJztcbmltcG9ydCB7YWRkTGF5ZXIgYXMgYWRkTGF5ZXJBY3Rpb259IGZyb20gJ0BrZXBsZXIuZ2wvYWN0aW9ucyc7XG5pbXBvcnQge2V4dGVuZGVkVG9vbCwgZ2VuZXJhdGVJZH0gZnJvbSAnQG9wZW5hc3Npc3RhbnQvdXRpbHMnO1xuaW1wb3J0IHt6fSBmcm9tICd6b2QnO1xuaW1wb3J0IHt1c2VFZmZlY3R9IGZyb20gJ3JlYWN0JztcblxuZXhwb3J0IGNvbnN0IGFkZExheWVyID0gZXh0ZW5kZWRUb29sPFxuICAvLyBwYXJhbWV0ZXJzXG4gIHouWm9kT2JqZWN0PHtcbiAgICBkYXRhc2V0TmFtZTogei5ab2RTdHJpbmc7XG4gICAgbGF0aXR1ZGVDb2x1bW46IHouWm9kT3B0aW9uYWw8ei5ab2RTdHJpbmc+O1xuICAgIGxvbmdpdHVkZUNvbHVtbjogei5ab2RPcHRpb25hbDx6LlpvZFN0cmluZz47XG4gICAgbGF5ZXJUeXBlOiB6LlpvZEVudW08XG4gICAgICBbXG4gICAgICAgICdwb2ludCcsXG4gICAgICAgICdhcmMnLFxuICAgICAgICAnbGluZScsXG4gICAgICAgICdncmlkJyxcbiAgICAgICAgJ2hleGFnb24nLFxuICAgICAgICAnZ2VvanNvbicsXG4gICAgICAgICdjbHVzdGVyJyxcbiAgICAgICAgJ2hlYXRtYXAnLFxuICAgICAgICAnaDMnLFxuICAgICAgICAndHJpcCcsXG4gICAgICAgICdzMidcbiAgICAgIF1cbiAgICA+O1xuICAgIGNvbG9yQnk6IHouWm9kT3B0aW9uYWw8ei5ab2RTdHJpbmc+O1xuICAgIGNvbG9yVHlwZTogei5ab2RPcHRpb25hbDx6LlpvZEVudW08WydicmVha3MnLCAndW5pcXVlJ10+PjtcbiAgICBjb2xvck1hcDogei5ab2RPcHRpb25hbDxcbiAgICAgIHouWm9kQXJyYXk8XG4gICAgICAgIHouWm9kT2JqZWN0PHtcbiAgICAgICAgICB2YWx1ZTogei5ab2RVbmlvbjxbei5ab2RTdHJpbmcsIHouWm9kTnVtYmVyLCB6LlpvZE51bGxdPjtcbiAgICAgICAgICBjb2xvcjogei5ab2RTdHJpbmc7XG4gICAgICAgIH0+XG4gICAgICA+XG4gICAgPjtcbiAgfT4sXG4gIC8vIHJldHVybiB0eXBlXG4gIEV4ZWN1dGVBZGRMYXllclJlc3VsdFsnbGxtUmVzdWx0J10sXG4gIC8vIGFkZGl0aW9uYWwgZGF0YVxuICBFeGVjdXRlQWRkTGF5ZXJSZXN1bHRbJ2FkZGl0aW9uYWxEYXRhJ10sXG4gIC8vIGNvbnRleHRcbiAgQWRkTGF5ZXJGdW5jdGlvbkNvbnRleHRcbj4oe1xuICBkZXNjcmlwdGlvbjogYEFkZCBhIGtlcGxlci5nbCBtYXAgbGF5ZXIgZnJvbSBhIGRhdGFzZXQuXG5Zb3UgY2FuIGNyZWF0ZSBiYXNpYyBtYXAgbGF5ZXIgd2l0aG91dCBjb2xvciBzdHlsaW5nLCBvciBlbmhhbmNlZCBtYXAgbGF5ZXIgd2l0aCBjb2xvciB2aXN1YWxpemF0aW9uLlxuXG5Gb3IgYmFzaWMgbWFwczpcbi0gU2ltcGx5IHVzZSBkYXRhc2V0TmFtZSwgZ2VvbWV0cnlDb2x1bW4gKGlmIG5lZWRlZCksIGxhdGl0dWRlQ29sdW1uL2xvbmdpdHVkZUNvbHVtbiAoZm9yIHBvaW50IG1hcHMpLCBhbmQgbWFwVHlwZVxuLSBPbWl0IGNvbG9yLXJlbGF0ZWQgcGFyYW1ldGVycyBmb3Igc2ltcGxlIHZpc3VhbGl6YXRpb25cblxuRm9yIGNvbG9yZWQgbWFwczpcbi0gSWYgdXNlciByZXF1ZXN0cyBjb2xvciB2aXN1YWxpemF0aW9uLCB1c2UgYXZhaWxhYmxlIGNvbHVtbnMgaW4gdGhlIGRhdGFzZXRcbi0gVXNlIGRhdGFDbGFzc2lmeSB0b29sIHRvIGNsYXNzaWZ5IGRhdGEgaW50byBiaW5zIG9yIHVuaXF1ZSB2YWx1ZXMgd2hlbiBuZWVkZWRcbi0gSWYgZGF0YUNsYXNzaWZ5IHRvb2wgcmV0dXJucyBhIGxpc3Qgb2YgayBicmVha3NcbiAgYS4gRm9yIGEgbGlzdCBvZiBrIGJyZWFrIHZhbHVlcywgeW91IG11c3QgY3JlYXRlIGsrMSBlbnRyaWVzIGluIHRoZSBjb2xvck1hcCwgd2l0aCB0aGUgbGFzdCB2YWx1ZSBiZWluZyBudWxsLlxuICBiLiBGb3IgZXhhbXBsZTogZm9yIGJyZWFrcyA9IFswLCAzLCAxMF0sIHRoZSBjb2xvck1hcCBjb3VsZCBiZSBbe3ZhbHVlOiAwLCBjb2xvcjogJyMjZmZmN2JjJywgbGFiZWw6ICc8IDAnfSwge3ZhbHVlOiAzLCBjb2xvcjogJyNmZWM0NGYnLCBsYWJlbDogJ1swLTMpJ30sIHt2YWx1ZTogbnVsbCwgY29sb3I6ICcjZDk1ZjBlJywgbGFiZWw6ICc+PSAzJ31dXG4tIElmIGRhdGFDbGFzc2lmeSB0b29sIHJldHVybnMgYSBsaXN0IG9mIGsgdW5pcXVlIHZhbHVlc1xuICBhLiBUaGVyZSBzaG91bGQgYmUgayBjb2xvcnMgaW4gdGhlIGNvbG9yTWFwLiBGb3IgZXhhbXBsZTogZm9yIHVuaXF1ZVZhbHVlcyA9IFsnYScsICdiJywgJ2MnXSwgdGhlIGNvbG9yTWFwIGNvdWxkIGJlIFt7dmFsdWU6ICdhJywgY29sb3I6ICcjMWI5ZTc3J30sIHt2YWx1ZTogJ2InLCBjb2xvcjogJyNkOTVmMDInfSwge3ZhbHVlOiAnYycsIGNvbG9yOiAnIzc1NzBiMyd9XVxuLSBHZW5lcmF0ZSBjb2xvckJyZXdlciBjb2xvcnMgYXV0b21hdGljYWxseSBpZiB1c2VyIGRvZXNuJ3Qgc3BlY2lmeSBjb2xvcnNcblxuRm9yIGdlb2pzb24gZGF0YXNldHM6XG4tIFVzZSBnZW9tZXRyeUNvbHVtbjogJ19nZW9qc29uJyBhbmQgbWFwVHlwZTogJ2dlb2pzb24nIGV2ZW4gZm9yIHBvaW50IGNvbGxlY3Rpb25zXG5gLFxuICBwYXJhbWV0ZXJzOiB6Lm9iamVjdCh7XG4gICAgZGF0YXNldE5hbWU6IHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLmRlc2NyaWJlKCdUaGUgbmFtZSBvZiB0aGUgZGF0YXNldC4gTm90ZTogcGxlYXNlIGRvIE5PVCB1c2UgdGhlIGRhdGFzZXRJZC4nKSxcbiAgICBsYXRpdHVkZUNvbHVtbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGxvbmdpdHVkZUNvbHVtbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGxheWVyTmFtZTogelxuICAgICAgLnN0cmluZygpXG4gICAgICAub3B0aW9uYWwoKVxuICAgICAgLmRlc2NyaWJlKCdJZiBwb3NzaWJsZSwgZ2VuZXJhdGUgYSBuYW1lIGZvciB0aGUgbGF5ZXIgYmFzZWQgb24gdGhlIGNvbnRleHQuJyksXG4gICAgbGF5ZXJUeXBlOiB6LmVudW0oW1xuICAgICAgJ3BvaW50JyxcbiAgICAgICdhcmMnLFxuICAgICAgJ2xpbmUnLFxuICAgICAgJ2dyaWQnLFxuICAgICAgJ2hleGFnb24nLFxuICAgICAgJ2dlb2pzb24nLFxuICAgICAgJ2NsdXN0ZXInLFxuICAgICAgJ2hlYXRtYXAnLFxuICAgICAgJ2gzJyxcbiAgICAgICd0cmlwJyxcbiAgICAgICdzMidcbiAgICBdKSxcbiAgICBjb2xvckJ5OiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgY29sb3JUeXBlOiB6LmVudW0oWydicmVha3MnLCAndW5pcXVlJ10pLm9wdGlvbmFsKCksXG4gICAgY29sb3JNYXA6IHpcbiAgICAgIC5hcnJheShcbiAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgIHZhbHVlOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpLCB6Lm51bGwoKV0pLFxuICAgICAgICAgIGNvbG9yOiB6LnN0cmluZygpXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAub3B0aW9uYWwoKVxuICB9KSxcbiAgZXhlY3V0ZTogZXhlY3V0ZUFkZExheWVyLFxuICBjb21wb25lbnQ6IEFkZExheWVyVG9vbENvbXBvbmVudFxufSk7XG5cbmV4cG9ydCB0eXBlIEFkZExheWVyVG9vbCA9IHR5cGVvZiBhZGRMYXllcjtcblxudHlwZSBBZGRMYXllckFyZ3MgPSB7XG4gIGRhdGFzZXROYW1lOiBzdHJpbmc7XG4gIGxheWVyTmFtZT86IHN0cmluZztcbiAgbGF5ZXJUeXBlOiBzdHJpbmc7XG4gIGxhdGl0dWRlQ29sdW1uPzogc3RyaW5nO1xuICBsb25naXR1ZGVDb2x1bW4/OiBzdHJpbmc7XG4gIGNvbG9yQnk/OiBzdHJpbmc7XG4gIGNvbG9yVHlwZT86IHN0cmluZztcbiAgY29sb3JNYXA/OiBBcnJheTx7dmFsdWU6IHN0cmluZyB8IG51bWJlciB8IG51bGw7IGNvbG9yOiBzdHJpbmc7IGxhYmVsPzogc3RyaW5nfT47XG59O1xuXG5mdW5jdGlvbiBpc0FkZExheWVyQXJncyhhcmdzOiBhbnkpOiBhcmdzIGlzIEFkZExheWVyQXJncyB7XG4gIHJldHVybiB0eXBlb2YgYXJncyA9PT0gJ29iamVjdCcgJiYgYXJncyAhPT0gbnVsbCAmJiAnZGF0YXNldE5hbWUnIGluIGFyZ3MgJiYgJ2xheWVyVHlwZScgaW4gYXJncztcbn1cblxudHlwZSBBZGRMYXllckZ1bmN0aW9uQ29udGV4dCA9IHtcbiAgZ2V0RGF0YXNldHM6ICgpID0+IERhdGFzZXRzO1xufTtcblxuZnVuY3Rpb24gaXNBZGRMYXllckZ1bmN0aW9uQ29udGV4dChjb250ZXh0OiBhbnkpOiBjb250ZXh0IGlzIEFkZExheWVyRnVuY3Rpb25Db250ZXh0IHtcbiAgcmV0dXJuIGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQuZ2V0RGF0YXNldHMgPT09ICdmdW5jdGlvbic7XG59XG5cbnR5cGUgRXhlY3V0ZUFkZExheWVyUmVzdWx0ID0ge1xuICBsbG1SZXN1bHQ6IHtcbiAgICBzdWNjZXNzOiBib29sZWFuO1xuICAgIGxheWVyPzogc3RyaW5nO1xuICAgIGRldGFpbHM/OiBzdHJpbmc7XG4gICAgZXJyb3I/OiBzdHJpbmc7XG4gICAgaW5zdHJ1Y3Rpb24/OiBzdHJpbmc7XG4gIH07XG4gIGFkZGl0aW9uYWxEYXRhPzoge1xuICAgIGxheWVyOiBvYmplY3Q7XG4gICAgZGF0YXNldElkOiBzdHJpbmc7XG4gIH07XG59O1xuXG5hc3luYyBmdW5jdGlvbiBleGVjdXRlQWRkTGF5ZXIoYXJncywgb3B0aW9ucyk6IFByb21pc2U8RXhlY3V0ZUFkZExheWVyUmVzdWx0PiB7XG4gIHRyeSB7XG4gICAgaWYgKCFpc0FkZExheWVyQXJncyhhcmdzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGFkZExheWVyIGFyZ3VtZW50cycpO1xuICAgIH1cblxuICAgIGlmICghaXNBZGRMYXllckZ1bmN0aW9uQ29udGV4dChvcHRpb25zLmNvbnRleHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYWRkTGF5ZXIgY29udGV4dCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIGRhdGFzZXROYW1lLFxuICAgICAgbGF5ZXJOYW1lLFxuICAgICAgbGF0aXR1ZGVDb2x1bW4sXG4gICAgICBsb25naXR1ZGVDb2x1bW4sXG4gICAgICBsYXllclR5cGUsXG4gICAgICBjb2xvckJ5LFxuICAgICAgY29sb3JUeXBlLFxuICAgICAgY29sb3JNYXBcbiAgICB9ID0gYXJncztcblxuICAgIGNvbnN0IGRhdGFzZXRzID0gb3B0aW9ucy5jb250ZXh0LmdldERhdGFzZXRzKCk7XG5cbiAgICAvLyBjaGVjayBpZiBkYXRhc2V0IGV4aXN0cyBpbiBrZXBsZXIuZ2xcbiAgICBjb25zdCBkYXRhc2V0SWQgPSBPYmplY3Qua2V5cyhkYXRhc2V0cykuZmluZChkYXRhSWQgPT4gZGF0YXNldHNbZGF0YUlkXS5sYWJlbCA9PT0gZGF0YXNldE5hbWUpO1xuICAgIGlmICghZGF0YXNldElkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYERhdGFzZXQgJHtkYXRhc2V0TmFtZX0gbm90IGZvdW5kLmApO1xuICAgIH1cblxuICAgIC8vIGNoZWNrIGlmIGZpZWxkIGV4aXN0cyBpbiB0aGUgZGF0YXNldFxuICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0c1tkYXRhc2V0SWRdO1xuXG4gICAgLy8gY2hlY2sgaWYgbGF5ZXJUeXBlIGlzIHZhbGlkXG4gICAgbGV0IGxheWVyID0gZ3Vlc3NEZWZhdWx0TGF5ZXIoZGF0YXNldCwgbGF5ZXJUeXBlKTtcblxuICAgIGNvbnN0IGxheWVySWQgPSBsYXllcj8uaWQgfHwgYGxheWVyXyR7Z2VuZXJhdGVJZCgpfWA7XG5cbiAgICBpZiAoIWxheWVyKSB7XG4gICAgICAvLyBmb3IgcG9pbnQgbGF5ZXIsIHRyeSB0byBjcmVhdCBhIHBvaW50IGxheWVyIG1hbnVhbGx5IGlmIExMTSBzdWdnZ2VzdHMgTGF0L0xuZyBmaWVsZHNcbiAgICAgIGlmIChsYXllclR5cGUgPT09ICdwb2ludCcgJiYgbGF0aXR1ZGVDb2x1bW4gJiYgbG9uZ2l0dWRlQ29sdW1uKSB7XG4gICAgICAgIGxheWVyID0ge1xuICAgICAgICAgIGlkOiBsYXllcklkLFxuICAgICAgICAgIHR5cGU6ICdwb2ludCcsXG4gICAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgICBkYXRhSWQ6IGRhdGFzZXRJZCxcbiAgICAgICAgICAgIGxhYmVsOiBsYXllck5hbWUgfHwgYCR7ZGF0YXNldE5hbWV9LSR7bGF5ZXJUeXBlfWAsXG4gICAgICAgICAgICBjb2x1bW5zOiB7XG4gICAgICAgICAgICAgIGxhdDoge3ZhbHVlOiBsYXRpdHVkZUNvbHVtbiwgZmllbGRJZHg6IGRhdGFzZXQuZ2V0Q29sdW1uRmllbGRJZHgobGF0aXR1ZGVDb2x1bW4pfSxcbiAgICAgICAgICAgICAgbG5nOiB7dmFsdWU6IGxvbmdpdHVkZUNvbHVtbiwgZmllbGRJZHg6IGRhdGFzZXQuZ2V0Q29sdW1uRmllbGRJZHgobG9uZ2l0dWRlQ29sdW1uKX1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHZpc0NvbmZpZzoge1xuICAgICAgICAgICAgY29sb3JSYW5nZToge1xuICAgICAgICAgICAgICBuYW1lOiAnSWNlIEFuZCBGaXJlJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2RpdmVyZ2luZycsXG4gICAgICAgICAgICAgIGNhdGVnb3J5OiAnVWJlcicsXG4gICAgICAgICAgICAgIGNvbG9yczogWycjRDUwMjU1JywgJyNGRUFENTQnLCAnI0ZFRURCMScsICcjRThGRUI1JywgJyM0OUUzQ0UnLCAnIzAxOThCRCddXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGFzIGFueTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFsYXllcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGxheWVyIHR5cGU6ICR7bGF5ZXJUeXBlfS5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb2x1bW5zID0gbGF5ZXI/LmNvbmZpZz8uY29sdW1ucyB8fCB7fTtcblxuICAgIC8vIGNvbnN0cnVjdCBuZXcgbGF5ZXIgY29uZmlnIGZvciBhZGRMYXllcigpIGFjdGlvblxuICAgIGNvbnN0IG5ld0xheWVyID0ge1xuICAgICAgaWQ6IGxheWVySWQsXG4gICAgICB0eXBlOiBsYXllci50eXBlLFxuICAgICAgY29uZmlnOiB7XG4gICAgICAgIC4uLmxheWVyLmNvbmZpZyxcbiAgICAgICAgZGF0YUlkOiBkYXRhc2V0SWQsXG4gICAgICAgIGxhYmVsOiBsYXllck5hbWUgfHwgYCR7ZGF0YXNldE5hbWV9LSR7bGF5ZXJUeXBlfWAsXG4gICAgICAgIGNvbHVtbnM6IE9iamVjdC5rZXlzKGNvbHVtbnMpLnJlZHVjZSgoYWNjLCBrZXkpID0+IHtcbiAgICAgICAgICBjb25zdCBjb2x1bW4gPSBjb2x1bW5zW2tleV07XG4gICAgICAgICAgaWYgKGNvbHVtbikge1xuICAgICAgICAgICAgYWNjW2tleV0gPSBjb2x1bW4udmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIHt9KVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoY29sb3JCeSkge1xuICAgICAgY29uc3QgY29sb3JGaWVsZCA9IGRhdGFzZXQuZmllbGRzLmZpbmQoZiA9PiBmLm5hbWUgPT09IGNvbG9yQnkpO1xuICAgICAgaWYgKCFjb2xvckZpZWxkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmllbGQgJHtjb2xvckJ5fSBub3QgZm91bmQuYCk7XG4gICAgICB9XG4gICAgICAvLyBjcmVhdGUga2VwbGVyLmdsJ3MgY29sb3JNYXAgZnJvbSB1bmlxdWVWYWx1ZXMgYW5kIGJyZWFrc1xuICAgICAgY29uc3QgY29sb3JTY2FsZSA9IGNvbG9yVHlwZSA9PT0gJ2JyZWFrcycgPyAnY3VzdG9tJyA6ICdjdXN0b21PcmRpbmFsJztcbiAgICAgIGNvbnN0IGNvbG9ycyA9IGNvbG9yTWFwPy5tYXAoY29sb3IgPT4gY29sb3IuY29sb3IpO1xuICAgICAgY29uc3Qga2VwbGVyQ29sb3JNYXAgPSBjb2xvck1hcD8ubWFwKGNvbG9yID0+IFtjb2xvci52YWx1ZSwgY29sb3IuY29sb3JdKTtcbiAgICAgIGNvbnN0IGNvbG9yUmFuZ2UgPSB7XG4gICAgICAgIG5hbWU6ICdjb2xvci5jdXN0b21QYWxldHRlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvbScsXG4gICAgICAgIGNhdGVnb3J5OiAnQ3VzdG9tJyxcbiAgICAgICAgY29sb3JzLFxuICAgICAgICBjb2xvck1hcDoga2VwbGVyQ29sb3JNYXBcbiAgICAgIH07XG5cbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snY29sb3JTY2FsZSddID0gY29sb3JTY2FsZTtcbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snY29sb3JGaWVsZCddID0gY29sb3JGaWVsZDtcbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snc3Ryb2tlQ29sb3JTY2FsZSddID0gY29sb3JTY2FsZTtcbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snc3Ryb2tlQ29sb3JGaWVsZCddID0gY29sb3JGaWVsZDtcbiAgICAgIG5ld0xheWVyLmNvbmZpZy52aXNDb25maWdbJ2NvbG9yUmFuZ2UnXSA9IGNvbG9yUmFuZ2U7XG4gICAgICBuZXdMYXllci5jb25maWcudmlzQ29uZmlnWydzdHJva2VDb2xvclJhbmdlJ10gPSBjb2xvclJhbmdlO1xuICAgICAgbmV3TGF5ZXIuY29uZmlnWyd2aXN1YWxDaGFubmVscyddID0ge1xuICAgICAgICBjb2xvckZpZWxkOiB7XG4gICAgICAgICAgbmFtZTogY29sb3JCeSxcbiAgICAgICAgICB0eXBlOiBjb2xvckZpZWxkPy50eXBlXG4gICAgICAgIH0sXG4gICAgICAgIGNvbG9yU2NhbGVcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGxsbVJlc3VsdDoge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBsYXllcjogSlNPTi5zdHJpbmdpZnkobmV3TGF5ZXIpLFxuICAgICAgICBkZXRhaWxzOiBgbWFwIGxheWVyICR7bGF5ZXJJZH0gd2lsbCBiZSBhZGRlZCB0byB0aGUgbWFwLmBcbiAgICAgIH0sXG4gICAgICBhZGRpdGlvbmFsRGF0YToge1xuICAgICAgICBsYXllcjogbmV3TGF5ZXIsXG4gICAgICAgIGRhdGFzZXRJZFxuICAgICAgfVxuICAgIH07XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxsbVJlc3VsdDoge1xuICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InLFxuICAgICAgICBpbnN0cnVjdGlvbjpcbiAgICAgICAgICAnVHJ5IHRvIGZpeCB0aGUgZXJyb3IuIElmIHRoZSBlcnJvciBwZXJzaXN0cywgcGF1c2UgdGhlIGV4ZWN1dGlvbiBhbmQgYXNrIHRoZSB1c2VyIHRvIHRyeSB3aXRoIGRpZmZlcmVudCBwcm9tcHQgYW5kIGNvbnRleHQuJ1xuICAgICAgfVxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGd1ZXNzRGVmYXVsdExheWVyKGRhdGFzZXQ6IEtlcGxlclRhYmxlLCBsYXllclR5cGU6IHN0cmluZykge1xuICAvLyBzcGVjaWFsIGNhc2UgZm9yIGhleGFnb24gbGF5ZXIsIHdoaWNoIGNvdWxkIGJlIGltcGxlbWVudGVkIGFzIGZpbmREZWZhdWx0TGF5ZXJQcm9wcygpIGluIGhleGFnb24tbGF5ZXIudHN4XG4gIGlmIChsYXllclR5cGUgPT09ICdoZXhhZ29uJykge1xuICAgIGlmIChkYXRhc2V0LmZpZWxkUGFpcnMgJiYgZGF0YXNldC5maWVsZFBhaXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHByb3BzID0gZGF0YXNldC5maWVsZFBhaXJzLm1hcChmaWVsZFBhaXIgPT4gKHtcbiAgICAgICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgICAgICBsYWJlbDogJ0hleGJpbicsXG4gICAgICAgIGNvbHVtbnM6IGZpZWxkUGFpci5wYWlyXG4gICAgICB9KSk7XG4gICAgICBjb25zdCBsYXllciA9IG5ldyBMYXllckNsYXNzZXMuaGV4YWdvbihwcm9wc1swXSk7XG4gICAgICByZXR1cm4gbGF5ZXI7XG4gICAgfVxuICB9XG4gIGNvbnN0IGRlZmF1bHRMYXllcnMgPSBmaW5kRGVmYXVsdExheWVyKGRhdGFzZXQsIExheWVyQ2xhc3Nlcyk7XG4gIGNvbnN0IGxheWVyID0gZGVmYXVsdExheWVycy5maW5kKGwgPT4gbC50eXBlID09PSBsYXllclR5cGUpO1xuICByZXR1cm4gbGF5ZXIgfHwgZGVmYXVsdExheWVycy5sZW5ndGggPiAwID8gZGVmYXVsdExheWVyc1swXSA6IG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBBZGRMYXllclRvb2xDb21wb25lbnQoe2xheWVyLCBkYXRhc2V0SWR9KSB7XG4gIGNvbnN0IGRpc3BhdGNoID0gdXNlRGlzcGF0Y2goKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGRpc3BhdGNoKGFkZExheWVyQWN0aW9uKGxheWVyLCBkYXRhc2V0SWQpKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1k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