kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
331 lines (324 loc) • 43.3 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CSV_NULLS = exports.COLUMN_TYPES_PRIORITIES = void 0;
exports.columnTypeToFieldType = columnTypeToFieldType;
exports.fieldTypeToColumnType = fieldTypeToColumnType;
exports.processCsvRowObject = processCsvRowObject;
exports.processGeojson = processGeojson;
exports.processKeplerglJSONforDuckDb = processKeplerglJSONforDuckDb;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _geojsonNormalize = _interopRequireDefault(require("@mapbox/geojson-normalize"));
var _commonUtils = require("@kepler.gl/common-utils");
var _constants = require("@kepler.gl/constants");
var _processors = require("@kepler.gl/processors");
var _utils = require("@kepler.gl/utils");
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; } } }; }
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; } }
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; }
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 CSV_NULLS = exports.CSV_NULLS = /^(null|NULL|Null|NaN|\/N||)$/;
var COLUMN_TYPES = /*#__PURE__*/function (COLUMN_TYPES) {
COLUMN_TYPES["GEOMETRY"] = "GEOMETRY";
COLUMN_TYPES["BOOLEAN"] = "BOOLEAN";
COLUMN_TYPES["INTEGER"] = "INTEGER";
COLUMN_TYPES["FLOAT"] = "FLOAT";
COLUMN_TYPES["TIME"] = "TIME";
COLUMN_TYPES["DATE"] = "DATE";
COLUMN_TYPES["TIMESTAMP"] = "TIMESTAMP";
COLUMN_TYPES["VARCHAR"] = "VARCHAR";
return COLUMN_TYPES;
}(COLUMN_TYPES || {}); // https://duckdb.org/docs/data/csv/auto_detection.html#type-detection
var COLUMN_TYPES_PRIORITIES = exports.COLUMN_TYPES_PRIORITIES = ['GEOMETRY', 'BOOLEAN', 'INTEGER', 'FLOAT', 'TIME', 'DATE', 'TIMESTAMP', 'VARCHAR'];
function columnTypeToFieldType(columnType) {
switch (columnType) {
case COLUMN_TYPES.BOOLEAN:
return _constants.ALL_FIELD_TYPES["boolean"];
case COLUMN_TYPES.DATE:
return _constants.ALL_FIELD_TYPES.date;
case COLUMN_TYPES.INTEGER:
return _constants.ALL_FIELD_TYPES.integer;
case COLUMN_TYPES.FLOAT:
return _constants.ALL_FIELD_TYPES.real;
case COLUMN_TYPES.VARCHAR:
return _constants.ALL_FIELD_TYPES.string;
case COLUMN_TYPES.TIMESTAMP:
return _constants.ALL_FIELD_TYPES.timestamp;
case COLUMN_TYPES.GEOMETRY:
return _constants.ALL_FIELD_TYPES.geojson;
default:
// is there any other type we didn't cover?
console.warn("Unsupported DuckDB Column type: ".concat(columnType));
return null;
}
}
function fieldTypeToColumnType(fieldType) {
switch (fieldType) {
case _constants.ALL_FIELD_TYPES["boolean"]:
return COLUMN_TYPES.BOOLEAN;
case _constants.ALL_FIELD_TYPES.date:
return COLUMN_TYPES.DATE;
case _constants.ALL_FIELD_TYPES.integer:
return COLUMN_TYPES.INTEGER;
case _constants.ALL_FIELD_TYPES.real:
return COLUMN_TYPES.FLOAT;
case _constants.ALL_FIELD_TYPES.string:
return COLUMN_TYPES.VARCHAR;
case _constants.ALL_FIELD_TYPES.timestamp:
return COLUMN_TYPES.TIMESTAMP;
case _constants.ALL_FIELD_TYPES.geojson:
return COLUMN_TYPES.GEOMETRY;
default:
// is there any other type we didn't cover?
console.warn("Unsupported Field type for DuckDb: ".concat(fieldType));
return null;
}
}
/*
* Process uploaded exported Keplergl json map.
* We need to populate field with proper DuckDb compatible type.
*/
// TODO: merge with logic from processCsvRowObject. Different formats: [[]] vs [{}]
function processKeplerglJSONforDuckDb(_x) {
return _processKeplerglJSONforDuckDb.apply(this, arguments);
}
/*
* Process uploaded csv returned by loaders.gl as row object and string value
*/
function _processKeplerglJSONforDuckDb() {
_processKeplerglJSONforDuckDb = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(keplerJson) {
var res, datasets, _iterator, _step, _loop2;
return _regenerator["default"].wrap(function _callee$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
res = (0, _processors.processKeplerglJSON)(keplerJson);
datasets = (res === null || res === void 0 ? void 0 : res.datasets) || [];
_iterator = _createForOfIteratorHelper(datasets);
_context2.prev = 3;
_loop2 = /*#__PURE__*/_regenerator["default"].mark(function _loop2() {
var dataset, rowsAll, fieldsAll, header, sample, schema, fieldsUpd;
return _regenerator["default"].wrap(function _loop2$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
dataset = _step.value;
rowsAll = dataset.data.rows;
fieldsAll = dataset.data.fields;
header = fieldsAll.map(function (f) {
return f.name;
});
sample = (0, _commonUtils.getSampleForTypeAnalyze)({
fields: header,
rows: rowsAll
});
if (!(sample.length > 0)) {
_context.next = 11;
break;
}
_context.next = 8;
return sniffCsvSchema(sample);
case 8:
_context.t0 = _context.sent;
_context.next = 12;
break;
case 11:
_context.t0 = fieldsAll.reduce(function (acc, field) {
acc[field.name] = fieldTypeToColumnType(field.type);
return acc;
}, {});
case 12:
schema = _context.t0;
fieldsUpd = consolidateFieldTypes(dataset.data.fields, schema);
dataset.data.fields = fieldsAll.map(function (f, i) {
return _objectSpread(_objectSpread({}, fieldsUpd[i]), f);
});
case 15:
case "end":
return _context.stop();
}
}, _loop2);
});
_iterator.s();
case 6:
if ((_step = _iterator.n()).done) {
_context2.next = 10;
break;
}
return _context2.delegateYield(_loop2(), "t0", 8);
case 8:
_context2.next = 6;
break;
case 10:
_context2.next = 15;
break;
case 12:
_context2.prev = 12;
_context2.t1 = _context2["catch"](3);
_iterator.e(_context2.t1);
case 15:
_context2.prev = 15;
_iterator.f();
return _context2.finish(15);
case 18:
return _context2.abrupt("return", res);
case 19:
case "end":
return _context2.stop();
}
}, _callee, null, [[3, 12, 15, 18]]);
}));
return _processKeplerglJSONforDuckDb.apply(this, arguments);
}
function processCsvRowObject(_x2) {
return _processCsvRowObject.apply(this, arguments);
}
function _processCsvRowObject() {
_processCsvRowObject = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(rawData) {
var header, sample, schema, fieldsWAnalyzerType, fields;
return _regenerator["default"].wrap(function _callee2$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
if (!(!Array.isArray(rawData) || !rawData.length)) {
_context3.next = 2;
break;
}
return _context3.abrupt("return", {
fields: [],
rows: []
});
case 2:
header = Object.keys(rawData[0]); // [lat, lng, value]
// row object can still contain values like `Null` or `N/A`
cleanUpFalsyCsvValue(rawData);
sample = (0, _commonUtils.getSampleForTypeAnalyze)({
fields: header,
rows: rawData
}); // add sample data to duckdb and get schema
_context3.next = 7;
return sniffCsvSchema(sample);
case 7:
schema = _context3.sent;
fieldsWAnalyzerType = (0, _commonUtils.getFieldsFromData)(sample, header);
fields = consolidateFieldTypes(fieldsWAnalyzerType, schema);
return _context3.abrupt("return", {
rows: rawData,
fields: fields
});
case 11:
case "end":
return _context3.stop();
}
}, _callee2);
}));
return _processCsvRowObject.apply(this, arguments);
}
function cleanUpFalsyCsvValue(rows) {
var re = new RegExp(CSV_NULLS, 'g');
var _loop = function _loop(i) {
Object.keys(rows[i]).forEach(function (key) {
// here we parse empty data as null
if (typeof rows[i][key] === 'string' && rows[i][key].match(re)) {
rows[i][key] = null;
}
});
};
for (var i = 0; i < rows.length; i++) {
_loop(i);
}
}
// align type analyzer types with DuckDB csv auto detected column types
function consolidateFieldTypes(fields, schema) {
return fields.map(function (field) {
var columnName = field.name;
var detectedColumnType = schema[columnName];
// TODO columnTypeToFieldType tranforms detected timestamps to string,
// completely breaking time filter logic.
// const fieldType = columnTypeToFieldType(detectedColumnType) || field.type;
return _objectSpread(_objectSpread({}, field), {}, {
// type: fieldType,
duckDBColumnType: detectedColumnType
});
});
}
function toCSVRow(row) {
return "".concat(row.map(function (r) {
var rToStr = (0, _commonUtils.notNullorUndefined)(r) ? String(r).replace(/"/g, '\\"') : '';
return rToStr.includes(',') ? "\"".concat(rToStr, "\"") : rToStr;
}).join(','), "\n");
}
// Use DucckDB to detect csv column schema
function sniffCsvSchema(_x3) {
return _sniffCsvSchema.apply(this, arguments);
}
function _sniffCsvSchema() {
_sniffCsvSchema = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(sample) {
var headerRow, csvContent, db, c, fileName, result, schemaResult, columns, schema, i;
return _regenerator["default"].wrap(function _callee3$(_context4) {
while (1) switch (_context4.prev = _context4.next) {
case 0:
if (!(!Array.isArray(sample) || sample.length < 0)) {
_context4.next = 2;
break;
}
return _context4.abrupt("return");
case 2:
headerRow = toCSVRow(Object.keys(sample[0]));
csvContent = sample.reduce(function (accu, row) {
return "".concat(accu).concat(toCSVRow(Object.values(row)));
}, headerRow);
db = (0, _utils.getApplicationConfig)().database;
if (db) {
_context4.next = 8;
break;
}
console.error('The database is not configured properly.');
return _context4.abrupt("return");
case 8:
_context4.next = 10;
return db.connect();
case 10:
c = _context4.sent;
fileName = (0, _commonUtils.generateHashId)();
_context4.next = 14;
return db.registerFileText("".concat(fileName, "-").concat(_commonUtils.generateHashId, ".csv"), csvContent);
case 14:
_context4.next = 16;
return c.query("\n FROM sniff_csv('".concat(fileName, "-").concat(_commonUtils.generateHashId, ".csv', \n sample_size = 500,\n auto_type_candidates = ['FLOAT', 'INTEGER', 'TIMESTAMP', 'DATE', 'TIME', 'VARCHAR', 'BOOLEAN']);\n "));
case 16:
result = _context4.sent;
schemaResult = result.toArray().map(function (row) {
return row.toJSON();
});
columns = schemaResult[0].Columns;
schema = {};
for (i = 0; i < columns.length; i++) {
schema[columns.get(i).name] = columns.get(i).type;
}
return _context4.abrupt("return", schema);
case 22:
case "end":
return _context4.stop();
}
}, _callee3);
}));
return _sniffCsvSchema.apply(this, arguments);
}
function processGeojson(rawData) {
var normalizedGeojson = (0, _geojsonNormalize["default"])(rawData);
if (!normalizedGeojson || !Array.isArray(normalizedGeojson.features)) {
var error = new Error("Read File Failed: File is not a valid GeoJSON. Read more about [supported file format](".concat(_constants.GUIDES_FILE_FORMAT_DOC, ")"));
throw error;
}
// @ts-expect-error Don't pass empty fields, as duck db outputs an empty dataset
return {
rows: normalizedGeojson
// TODO get fields to preserve field names?
// fields: []
};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZ2VvanNvbk5vcm1hbGl6ZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2NvbW1vblV0aWxzIiwiX2NvbnN0YW50cyIsIl9wcm9jZXNzb3JzIiwiX3V0aWxzIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJvd25LZXlzIiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiQ1NWX05VTExTIiwiZXhwb3J0cyIsIkNPTFVNTl9UWVBFUyIsIkNPTFVNTl9UWVBFU19QUklPUklUSUVTIiwiY29sdW1uVHlwZVRvRmllbGRUeXBlIiwiY29sdW1uVHlwZSIsIkJPT0xFQU4iLCJBTExfRklFTERfVFlQRVMiLCJEQVRFIiwiZGF0ZSIsIklOVEVHRVIiLCJpbnRlZ2VyIiwiRkxPQVQiLCJyZWFsIiwiVkFSQ0hBUiIsInN0cmluZyIsIlRJTUVTVEFNUCIsInRpbWVzdGFtcCIsIkdFT01FVFJZIiwiZ2VvanNvbiIsImNvbnNvbGUiLCJ3YXJuIiwiY29uY2F0IiwiZmllbGRUeXBlVG9Db2x1bW5UeXBlIiwiZmllbGRUeXBlIiwicHJvY2Vzc0tlcGxlcmdsSlNPTmZvckR1Y2tEYiIsIl94IiwiX3Byb2Nlc3NLZXBsZXJnbEpTT05mb3JEdWNrRGIiLCJfYXN5bmNUb0dlbmVyYXRvcjIiLCJfcmVnZW5lcmF0b3IiLCJtYXJrIiwiX2NhbGxlZSIsImtlcGxlckpzb24iLCJyZXMiLCJkYXRhc2V0cyIsIl9pdGVyYXRvciIsIl9zdGVwIiwiX2xvb3AyIiwid3JhcCIsIl9jYWxsZWUkIiwiX2NvbnRleHQyIiwicHJldiIsInByb2Nlc3NLZXBsZXJnbEpTT04iLCJkYXRhc2V0Iiwicm93c0FsbCIsImZpZWxkc0FsbCIsImhlYWRlciIsInNhbXBsZSIsInNjaGVtYSIsImZpZWxkc1VwZCIsIl9sb29wMiQiLCJfY29udGV4dCIsImRhdGEiLCJyb3dzIiwiZmllbGRzIiwibWFwIiwiZ2V0U2FtcGxlRm9yVHlwZUFuYWx5emUiLCJzbmlmZkNzdlNjaGVtYSIsInQwIiwic2VudCIsInJlZHVjZSIsImFjYyIsImZpZWxkIiwidHlwZSIsImNvbnNvbGlkYXRlRmllbGRUeXBlcyIsImkiLCJzdG9wIiwiZGVsZWdhdGVZaWVsZCIsInQxIiwiZmluaXNoIiwiYWJydXB0IiwicHJvY2Vzc0NzdlJvd09iamVjdCIsIl94MiIsIl9wcm9jZXNzQ3N2Um93T2JqZWN0IiwiX2NhbGxlZTIiLCJyYXdEYXRhIiwiZmllbGRzV0FuYWx5emVyVHlwZSIsIl9jYWxsZWUyJCIsIl9jb250ZXh0MyIsImNsZWFuVXBGYWxzeUNzdlZhbHVlIiwiZ2V0RmllbGRzRnJvbURhdGEiLCJyZSIsIlJlZ0V4cCIsIl9sb29wIiwia2V5IiwibWF0Y2giLCJjb2x1bW5OYW1lIiwiZGV0ZWN0ZWRDb2x1bW5UeXBlIiwiZHVja0RCQ29sdW1uVHlwZSIsInRvQ1NWUm93Iiwicm93IiwiclRvU3RyIiwibm90TnVsbG9yVW5kZWZpbmVkIiwiU3RyaW5nIiwicmVwbGFjZSIsImluY2x1ZGVzIiwiam9pbiIsIl94MyIsIl9zbmlmZkNzdlNjaGVtYSIsIl9jYWxsZWUzIiwiaGVhZGVyUm93IiwiY3N2Q29udGVudCIsImRiIiwiYyIsImZpbGVOYW1lIiwicmVzdWx0Iiwic2NoZW1hUmVzdWx0IiwiY29sdW1ucyIsIl9jYWxsZWUzJCIsIl9jb250ZXh0NCIsImFjY3UiLCJ2YWx1ZXMiLCJnZXRBcHBsaWNhdGlvbkNvbmZpZyIsImRhdGFiYXNlIiwiZXJyb3IiLCJjb25uZWN0IiwiZ2VuZXJhdGVIYXNoSWQiLCJyZWdpc3RlckZpbGVUZXh0IiwicXVlcnkiLCJ0b0FycmF5IiwidG9KU09OIiwiQ29sdW1ucyIsImdldCIsInByb2Nlc3NHZW9qc29uIiwibm9ybWFsaXplZEdlb2pzb24iLCJub3JtYWxpemUiLCJmZWF0dXJlcyIsIkVycm9yIiwiR1VJREVTX0ZJTEVfRk9STUFUX0RPQyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm9jZXNzb3JzL2RhdGEtcHJvY2Vzc29yLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCAqIGFzIGFycm93IGZyb20gJ2FwYWNoZS1hcnJvdyc7XG5pbXBvcnQgbm9ybWFsaXplIGZyb20gJ0BtYXBib3gvZ2VvanNvbi1ub3JtYWxpemUnO1xuXG5pbXBvcnQge1xuICBnZXRTYW1wbGVGb3JUeXBlQW5hbHl6ZSxcbiAgZ2V0RmllbGRzRnJvbURhdGEsXG4gIGdlbmVyYXRlSGFzaElkLFxuICBub3ROdWxsb3JVbmRlZmluZWRcbn0gZnJvbSAnQGtlcGxlci5nbC9jb21tb24tdXRpbHMnO1xuaW1wb3J0IHtQcm90b0RhdGFzZXRGaWVsZH0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge0FMTF9GSUVMRF9UWVBFUywgR1VJREVTX0ZJTEVfRk9STUFUX0RPQ30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtwcm9jZXNzS2VwbGVyZ2xKU09OfSBmcm9tICdAa2VwbGVyLmdsL3Byb2Nlc3NvcnMnO1xuaW1wb3J0IHtnZXRBcHBsaWNhdGlvbkNvbmZpZ30gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5cbmV4cG9ydCBjb25zdCBDU1ZfTlVMTFMgPSAvXihudWxsfE5VTEx8TnVsbHxOYU58XFwvTnx8KSQvO1xuXG50eXBlIFJvd3NBc0FycmF5ID0gYW55W11bXTtcbnR5cGUgUm93c0FzT2JqZWN0ID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXTtcbnR5cGUgUm93RGF0YSA9IFJvd3NBc0FycmF5IHwgUm93c0FzT2JqZWN0O1xuXG5leHBvcnQgdHlwZSBQcm9jZXNzb3JSZXN1bHQgPSB7XG4gIGNvbHM/OiBhcnJvdy5WZWN0b3JbXTtcbiAgcm93czogUm93RGF0YTtcbiAgZmllbGRzOiBQcm90b0RhdGFzZXRGaWVsZFtdO1xufTtcblxuZW51bSBDT0xVTU5fVFlQRVMge1xuICBHRU9NRVRSWSA9ICdHRU9NRVRSWScsXG4gIEJPT0xFQU4gPSAnQk9PTEVBTicsXG4gIElOVEVHRVIgPSAnSU5URUdFUicsXG4gIEZMT0FUID0gJ0ZMT0FUJyxcbiAgVElNRSA9ICdUSU1FJyxcbiAgREFURSA9ICdEQVRFJyxcbiAgVElNRVNUQU1QID0gJ1RJTUVTVEFNUCcsXG4gIFZBUkNIQVIgPSAnVkFSQ0hBUidcbn1cbi8vIGh0dHBzOi8vZHVja2RiLm9yZy9kb2NzL2RhdGEvY3N2L2F1dG9fZGV0ZWN0aW9uLmh0bWwjdHlwZS1kZXRlY3Rpb25cbmV4cG9ydCBjb25zdCBDT0xVTU5fVFlQRVNfUFJJT1JJVElFUyA9IFtcbiAgJ0dFT01FVFJZJyxcbiAgJ0JPT0xFQU4nLFxuICAnSU5URUdFUicsXG4gICdGTE9BVCcsXG4gICdUSU1FJyxcbiAgJ0RBVEUnLFxuICAnVElNRVNUQU1QJyxcbiAgJ1ZBUkNIQVInXG5dO1xuXG5leHBvcnQgZnVuY3Rpb24gY29sdW1uVHlwZVRvRmllbGRUeXBlKGNvbHVtblR5cGU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBzd2l0Y2ggKGNvbHVtblR5cGUpIHtcbiAgICBjYXNlIENPTFVNTl9UWVBFUy5CT09MRUFOOlxuICAgICAgcmV0dXJuIEFMTF9GSUVMRF9UWVBFUy5ib29sZWFuO1xuICAgIGNhc2UgQ09MVU1OX1RZUEVTLkRBVEU6XG4gICAgICByZXR1cm4gQUxMX0ZJRUxEX1RZUEVTLmRhdGU7XG4gICAgY2FzZSBDT0xVTU5fVFlQRVMuSU5URUdFUjpcbiAgICAgIHJldHVybiBBTExfRklFTERfVFlQRVMuaW50ZWdlcjtcbiAgICBjYXNlIENPTFVNTl9UWVBFUy5GTE9BVDpcbiAgICAgIHJldHVybiBBTExfRklFTERfVFlQRVMucmVhbDtcbiAgICBjYXNlIENPTFVNTl9UWVBFUy5WQVJDSEFSOlxuICAgICAgcmV0dXJuIEFMTF9GSUVMRF9UWVBFUy5zdHJpbmc7XG4gICAgY2FzZSBDT0xVTU5fVFlQRVMuVElNRVNUQU1QOlxuICAgICAgcmV0dXJuIEFMTF9GSUVMRF9UWVBFUy50aW1lc3RhbXA7XG4gICAgY2FzZSBDT0xVTU5fVFlQRVMuR0VPTUVUUlk6XG4gICAgICByZXR1cm4gQUxMX0ZJRUxEX1RZUEVTLmdlb2pzb247XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIGlzIHRoZXJlIGFueSBvdGhlciB0eXBlIHdlIGRpZG4ndCBjb3Zlcj9cbiAgICAgIGNvbnNvbGUud2FybihgVW5zdXBwb3J0ZWQgRHVja0RCIENvbHVtbiB0eXBlOiAke2NvbHVtblR5cGV9YCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZmllbGRUeXBlVG9Db2x1bW5UeXBlKGZpZWxkVHlwZTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIHN3aXRjaCAoZmllbGRUeXBlKSB7XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuYm9vbGVhbjpcbiAgICAgIHJldHVybiBDT0xVTU5fVFlQRVMuQk9PTEVBTjtcbiAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5kYXRlOlxuICAgICAgcmV0dXJuIENPTFVNTl9UWVBFUy5EQVRFO1xuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLmludGVnZXI6XG4gICAgICByZXR1cm4gQ09MVU1OX1RZUEVTLklOVEVHRVI7XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMucmVhbDpcbiAgICAgIHJldHVybiBDT0xVTU5fVFlQRVMuRkxPQVQ7XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuc3RyaW5nOlxuICAgICAgcmV0dXJuIENPTFVNTl9UWVBFUy5WQVJDSEFSO1xuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLnRpbWVzdGFtcDpcbiAgICAgIHJldHVybiBDT0xVTU5fVFlQRVMuVElNRVNUQU1QO1xuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLmdlb2pzb246XG4gICAgICByZXR1cm4gQ09MVU1OX1RZUEVTLkdFT01FVFJZO1xuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBpcyB0aGVyZSBhbnkgb3RoZXIgdHlwZSB3ZSBkaWRuJ3QgY292ZXI/XG4gICAgICBjb25zb2xlLndhcm4oYFVuc3VwcG9ydGVkIEZpZWxkIHR5cGUgZm9yIER1Y2tEYjogJHtmaWVsZFR5cGV9YCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKlxuICogUHJvY2VzcyB1cGxvYWRlZCBleHBvcnRlZCBLZXBsZXJnbCBqc29uIG1hcC5cbiAqIFdlIG5lZWQgdG8gcG9wdWxhdGUgZmllbGQgd2l0aCBwcm9wZXIgRHVja0RiIGNvbXBhdGlibGUgdHlwZS5cbiAqL1xuLy8gVE9ETzogbWVyZ2Ugd2l0aCBsb2dpYyBmcm9tIHByb2Nlc3NDc3ZSb3dPYmplY3QuIERpZmZlcmVudCBmb3JtYXRzOiBbW11dIHZzIFt7fV1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm9jZXNzS2VwbGVyZ2xKU09OZm9yRHVja0RiKFxuICBrZXBsZXJKc29uXG4pOiBQcm9taXNlPFJldHVyblR5cGU8dHlwZW9mIHByb2Nlc3NLZXBsZXJnbEpTT04+PiB7XG4gIGNvbnN0IHJlcyA9IHByb2Nlc3NLZXBsZXJnbEpTT04oa2VwbGVySnNvbik7XG5cbiAgY29uc3QgZGF0YXNldHMgPSByZXM/LmRhdGFzZXRzIHx8IFtdO1xuICBmb3IgKGNvbnN0IGRhdGFzZXQgb2YgZGF0YXNldHMpIHtcbiAgICBjb25zdCByb3dzQWxsID0gZGF0YXNldC5kYXRhLnJvd3M7XG4gICAgY29uc3QgZmllbGRzQWxsID0gZGF0YXNldC5kYXRhLmZpZWxkcztcblxuICAgIGNvbnN0IGhlYWRlciA9IGZpZWxkc0FsbC5tYXAoZiA9PiBmLm5hbWUpO1xuICAgIGNvbnN0IHNhbXBsZSA9IGdldFNhbXBsZUZvclR5cGVBbmFseXplKHtmaWVsZHM6IGhlYWRlciwgcm93czogcm93c0FsbH0pO1xuXG4gICAgY29uc3Qgc2NoZW1hID1cbiAgICAgIHNhbXBsZS5sZW5ndGggPiAwXG4gICAgICAgID8gYXdhaXQgc25pZmZDc3ZTY2hlbWEoc2FtcGxlKVxuICAgICAgICA6IGZpZWxkc0FsbC5yZWR1Y2UoKGFjYywgZmllbGQpID0+IHtcbiAgICAgICAgICAgIGFjY1tmaWVsZC5uYW1lXSA9IGZpZWxkVHlwZVRvQ29sdW1uVHlwZShmaWVsZC50eXBlKTtcbiAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgfSwge30pO1xuICAgIGNvbnN0IGZpZWxkc1VwZCA9IGNvbnNvbGlkYXRlRmllbGRUeXBlcyhkYXRhc2V0LmRhdGEuZmllbGRzLCBzY2hlbWEpO1xuXG4gICAgZGF0YXNldC5kYXRhLmZpZWxkcyA9IGZpZWxkc0FsbC5tYXAoKGYsIGkpID0+IHtcbiAgICAgIHJldHVybiB7Li4uZmllbGRzVXBkW2ldLCAuLi5mfTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59XG5cbi8qXG4gKiBQcm9jZXNzIHVwbG9hZGVkIGNzdiByZXR1cm5lZCBieSBsb2FkZXJzLmdsIGFzIHJvdyBvYmplY3QgYW5kIHN0cmluZyB2YWx1ZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvY2Vzc0NzdlJvd09iamVjdChcbiAgcmF3RGF0YTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD5bXVxuKTogUHJvbWlzZTxQcm9jZXNzb3JSZXN1bHQ+IHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHJhd0RhdGEpIHx8ICFyYXdEYXRhLmxlbmd0aCkge1xuICAgIHJldHVybiB7XG4gICAgICBmaWVsZHM6IFtdLFxuICAgICAgcm93czogW11cbiAgICB9O1xuICB9XG5cbiAgY29uc3QgaGVhZGVyID0gT2JqZWN0LmtleXMocmF3RGF0YVswXSk7IC8vIFtsYXQsIGxuZywgdmFsdWVdXG5cbiAgLy8gcm93IG9iamVjdCBjYW4gc3RpbGwgY29udGFpbiB2YWx1ZXMgbGlrZSBgTnVsbGAgb3IgYE4vQWBcbiAgY2xlYW5VcEZhbHN5Q3N2VmFsdWUocmF3RGF0YSk7XG4gIGNvbnN0IHNhbXBsZSA9IGdldFNhbXBsZUZvclR5cGVBbmFseXplKHtmaWVsZHM6IGhlYWRlciwgcm93czogcmF3RGF0YX0pO1xuICAvLyBhZGQgc2FtcGxlIGRhdGEgdG8gZHVja2RiIGFuZCBnZXQgc2NoZW1hXG4gIGNvbnN0IHNjaGVtYSA9IGF3YWl0IHNuaWZmQ3N2U2NoZW1hKHNhbXBsZSk7XG5cbiAgY29uc3QgZmllbGRzV0FuYWx5emVyVHlwZSA9IGdldEZpZWxkc0Zyb21EYXRhKHNhbXBsZSwgaGVhZGVyKTtcblxuICBjb25zdCBmaWVsZHMgPSBjb25zb2xpZGF0ZUZpZWxkVHlwZXMoZmllbGRzV0FuYWx5emVyVHlwZSwgc2NoZW1hKTtcblxuICByZXR1cm4ge3Jvd3M6IHJhd0RhdGEsIGZpZWxkc307XG59XG5cbmZ1bmN0aW9uIGNsZWFuVXBGYWxzeUNzdlZhbHVlKHJvd3M6IFJvd0RhdGEpOiB2b2lkIHtcbiAgY29uc3QgcmUgPSBuZXcgUmVnRXhwKENTVl9OVUxMUywgJ2cnKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7XG4gICAgT2JqZWN0LmtleXMocm93c1tpXSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgLy8gaGVyZSB3ZSBwYXJzZSBlbXB0eSBkYXRhIGFzIG51bGxcbiAgICAgIGlmICh0eXBlb2Ygcm93c1tpXVtrZXldID09PSAnc3RyaW5nJyAmJiAocm93c1tpXVtrZXldIGFzIHN0cmluZykubWF0Y2gocmUpKSB7XG4gICAgICAgIHJvd3NbaV1ba2V5XSA9IG51bGw7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuLy8gYWxpZ24gdHlwZSBhbmFseXplciB0eXBlcyB3aXRoIER1Y2tEQiBjc3YgYXV0byBkZXRlY3RlZCBjb2x1bW4gdHlwZXNcbmZ1bmN0aW9uIGNvbnNvbGlkYXRlRmllbGRUeXBlcyhmaWVsZHMsIHNjaGVtYSkge1xuICByZXR1cm4gZmllbGRzLm1hcChmaWVsZCA9PiB7XG4gICAgY29uc3QgY29sdW1uTmFtZSA9IGZpZWxkLm5hbWU7XG5cbiAgICBjb25zdCBkZXRlY3RlZENvbHVtblR5cGUgPSBzY2hlbWFbY29sdW1uTmFtZV07XG5cbiAgICAvLyBUT0RPIGNvbHVtblR5cGVUb0ZpZWxkVHlwZSB0cmFuZm9ybXMgZGV0ZWN0ZWQgdGltZXN0YW1wcyB0byBzdHJpbmcsXG4gICAgLy8gY29tcGxldGVseSBicmVha2luZyB0aW1lIGZpbHRlciBsb2dpYy5cbiAgICAvLyBjb25zdCBmaWVsZFR5cGUgPSBjb2x1bW5UeXBlVG9GaWVsZFR5cGUoZGV0ZWN0ZWRDb2x1bW5UeXBlKSB8fCBmaWVsZC50eXBlO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmZpZWxkLFxuICAgICAgLy8gdHlwZTogZmllbGRUeXBlLFxuICAgICAgZHVja0RCQ29sdW1uVHlwZTogZGV0ZWN0ZWRDb2x1bW5UeXBlXG4gICAgfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHRvQ1NWUm93KHJvdzogdW5rbm93bltdKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke3Jvd1xuICAgIC5tYXAociA9PiB7XG4gICAgICBjb25zdCByVG9TdHIgPSBub3ROdWxsb3JVbmRlZmluZWQocikgPyBTdHJpbmcocikucmVwbGFjZSgvXCIvZywgJ1xcXFxcIicpIDogJyc7XG4gICAgICByZXR1cm4gclRvU3RyLmluY2x1ZGVzKCcsJykgPyBgXCIke3JUb1N0cn1cImAgOiByVG9TdHI7XG4gICAgfSlcbiAgICAuam9pbignLCcpfVxcbmA7XG59XG5cbi8vIFVzZSBEdWNja0RCIHRvIGRldGVjdCBjc3YgY29sdW1uIHNjaGVtYVxuYXN5bmMgZnVuY3Rpb24gc25pZmZDc3ZTY2hlbWEoc2FtcGxlOiBSb3dEYXRhKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShzYW1wbGUpIHx8IHNhbXBsZS5sZW5ndGggPCAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IGhlYWRlclJvdyA9IHRvQ1NWUm93KE9iamVjdC5rZXlzKHNhbXBsZVswXSkpO1xuXG4gIGNvbnN0IGNzdkNvbnRlbnQgPSAoc2FtcGxlIGFzIChhbnlbXSB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtdKS5yZWR1Y2UoXG4gICAgKGFjY3U6IHN0cmluZywgcm93KSA9PiBgJHthY2N1fSR7dG9DU1ZSb3coT2JqZWN0LnZhbHVlcyhyb3cpKX1gLFxuICAgIGhlYWRlclJvd1xuICApO1xuXG4gIGNvbnN0IGRiID0gZ2V0QXBwbGljYXRpb25Db25maWcoKS5kYXRhYmFzZTtcbiAgaWYgKCFkYikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBkYXRhYmFzZSBpcyBub3QgY29uZmlndXJlZCBwcm9wZXJseS4nKTtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgYyA9IGF3YWl0IGRiLmNvbm5lY3QoKTtcblxuICBjb25zdCBmaWxlTmFtZSA9IGdlbmVyYXRlSGFzaElkKCk7XG4gIGF3YWl0IGRiLnJlZ2lzdGVyRmlsZVRleHQoYCR7ZmlsZU5hbWV9LSR7Z2VuZXJhdGVIYXNoSWR9LmNzdmAsIGNzdkNvbnRlbnQpO1xuXG4gIC8vIGh0dHBzOi8vZHVja2RiLm9yZy9kb2NzL2RhdGEvY3N2L2F1dG9fZGV0ZWN0aW9uLmh0bWxcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYy5xdWVyeShgXG4gICAgICAgIEZST00gc25pZmZfY3N2KCcke2ZpbGVOYW1lfS0ke2dlbmVyYXRlSGFzaElkfS5jc3YnLCBcbiAgICAgICAgc2FtcGxlX3NpemUgPSA1MDAsXG4gICAgICAgIGF1dG9fdHlwZV9jYW5kaWRhdGVzID0gWydGTE9BVCcsICdJTlRFR0VSJywgJ1RJTUVTVEFNUCcsICdEQVRFJywgJ1RJTUUnLCAnVkFSQ0hBUicsICdCT09MRUFOJ10pO1xuICAgIGApO1xuXG4gIGNvbnN0IHNjaGVtYVJlc3VsdCA9IHJlc3VsdC50b0FycmF5KCkubWFwKHJvdyA9PiByb3cudG9KU09OKCkpO1xuXG4gIGNvbnN0IGNvbHVtbnMgPSBzY2hlbWFSZXN1bHRbMF0uQ29sdW1ucztcbiAgY29uc3Qgc2NoZW1hID0ge307XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY29sdW1ucy5sZW5ndGg7IGkrKykge1xuICAgIHNjaGVtYVtjb2x1bW5zLmdldChpKS5uYW1lXSA9IGNvbHVtbnMuZ2V0KGkpLnR5cGU7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc0dlb2pzb24ocmF3RGF0YTogdW5rbm93bik6IFByb2Nlc3NvclJlc3VsdCB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRHZW9qc29uID0gbm9ybWFsaXplKHJhd0RhdGEpO1xuXG4gIGlmICghbm9ybWFsaXplZEdlb2pzb24gfHwgIUFycmF5LmlzQXJyYXkobm9ybWFsaXplZEdlb2pzb24uZmVhdHVyZXMpKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoXG4gICAgICBgUmVhZCBGaWxlIEZhaWxlZDogRmlsZSBpcyBub3QgYSB2YWxpZCBHZW9KU09OLiBSZWFkIG1vcmUgYWJvdXQgW3N1cHBvcnRlZCBmaWxlIGZvcm1hdF0oJHtHVUlERVNfRklMRV9GT1JNQVRfRE9DfSlgXG4gICAgKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIC8vIEB0cy1leHBlY3QtZXJyb3IgRG9uJ3QgcGFzcyBlbXB0eSBmaWVsZHMsIGFzIGR1Y2sgZGIgb3V0cHV0cyBhbiBlbXB0eSBkYXRhc2V0XG4gIHJldHVybiB7XG4gICAgcm93czogbm9ybWFsaXplZEdlb2pzb25cbiAgICAvLyBUT0RPIGdldCBmaWVsZHMgdG8gcHJlc2VydmUgZmllbGQgbmFtZXM/XG4gICAgLy8gZmllbGRzOiBbXVxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFJQSxJQUFBQSxpQkFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUMsWUFBQSxHQUFBRCxPQUFBO0FBT0EsSUFBQUUsVUFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsV0FBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksTUFBQSxHQUFBSixPQUFBO0FBQXNELFNBQUFLLDJCQUFBQyxDQUFBLEVBQUFDLENBQUEsUUFBQUMsQ0FBQSx5QkFBQUMsTUFBQSxJQUFBSCxDQUFBLENBQUFHLE1BQUEsQ0FBQUMsUUFBQSxLQUFBSixDQUFBLHFCQUFBRSxDQUFBLFFBQUFHLEtBQUEsQ0FBQUMsT0FBQSxDQUFBTixDQUFBLE1BQUFFLENBQUEsR0FBQUssMkJBQUEsQ0FBQVAsQ0FBQSxNQUFBQyxDQUFBLElBQUFELENBQUEsdUJBQUFBLENBQUEsQ0FBQVEsTUFBQSxJQUFBTixDQUFBLEtBQUFGLENBQUEsR0FBQUUsQ0FBQSxPQUFBTyxFQUFBLE1BQUFDLENBQUEsWUFBQUEsRUFBQSxlQUFBQyxDQUFBLEVBQUFELENBQUEsRUFBQUUsQ0FBQSxXQUFBQSxFQUFBLFdBQUFILEVBQUEsSUFBQVQsQ0FBQSxDQUFBUSxNQUFBLEtBQUFLLElBQUEsV0FBQUEsSUFBQSxNQUFBQyxLQUFBLEVBQUFkLENBQUEsQ0FBQVMsRUFBQSxVQUFBUixDQUFBLFdBQUFBLEVBQUFELENBQUEsVUFBQUEsQ0FBQSxLQUFBZSxDQUFBLEVBQUFMLENBQUEsZ0JBQUFNLFNBQUEsaUpBQUFDLENBQUEsRUFBQUMsQ0FBQSxPQUFBQyxDQUFBLGdCQUFBUixDQUFBLFdBQUFBLEVBQUEsSUFBQVQsQ0FBQSxHQUFB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
;