UNPKG

kepler.gl

Version:

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

398 lines (387 loc) 51.7 kB
"use strict"; var _typeof3 = require("@babel/runtime/helpers/typeof"); var _regeneratorRuntime2 = require("@babel/runtime/regenerator"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ArrowDataContainer = void 0; exports.arrowDataTypeToAnalyzerDataType = arrowDataTypeToAnalyzerDataType; exports.arrowDataTypeToFieldType = arrowDataTypeToFieldType; exports.isArrowFixedSizeList = isArrowFixedSizeList; exports.isArrowStruct = isArrowStruct; exports.isArrowTable = isArrowTable; exports.isArrowVector = isArrowVector; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _constants = require("@kepler.gl/constants"); var arrow = _interopRequireWildcard(require("apache-arrow")); var _window = require("global/window"); var _typeAnalyzer = require("type-analyzer"); var _dataRow = require("./data-row"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } var _marked = /*#__PURE__*/_regeneratorRuntime2.mark(rowsIterator), _marked2 = /*#__PURE__*/_regeneratorRuntime2.mark(columnIterator); // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project /** * Check if table is an ArrowTable object. * * We use duck-typing instead of `instanceof arrow.Table` because DuckDB loads its own * bundled version of Apache Arrow. When DuckDB creates Arrow tables, they are instances * of DuckDB's Arrow.Table class, not the Arrow.Table class from our application's * apache-arrow package. This causes `instanceof` checks to fail even though the objects * are functionally equivalent Arrow tables. * * @param data - object to check * @returns true if data is an ArrowTable object (type guarded) */ function isArrowTable(data) { return (0, _typeof2["default"])(data) === 'object' && data !== null && 'schema' in data && 'getChildAt' in data && typeof data.getChildAt === 'function' && 'batches' in data && Array.isArray(data.batches); } /** * Check if data is an ArrowVector object. * Uses duck-typing instead of `instanceof` to handle DuckDB's bundled Arrow version. * * @param data - object to check * @returns true if data is an ArrowVector object (type guarded) */ function isArrowVector(data) { return (0, _typeof2["default"])(data) === 'object' && data !== null && 'type' in data && 'length' in data && typeof data.length === 'number' && 'get' in data && typeof data.get === 'function' && 'data' in data && Array.isArray(data.data); } /** * Check if data is an Arrow FixedSizeList DataType. * Uses duck-typing instead of `instanceof` to handle DuckDB's bundled Arrow version. * * @param data - object to check * @returns true if data is an Arrow FixedSizeList DataType (type guarded) */ function isArrowFixedSizeList(data) { return (0, _typeof2["default"])(data) === 'object' && data !== null && 'typeId' in data && 'listSize' in data && typeof data.listSize === 'number' && 'children' in data && Array.isArray(data.children); } /** * Check if data is an Arrow Struct DataType. * Uses duck-typing instead of `instanceof` to handle DuckDB's bundled Arrow version. * * @param data - object to check * @returns true if data is an Arrow Struct DataType (type guarded) */ function isArrowStruct(data) { return (0, _typeof2["default"])(data) === 'object' && data !== null && 'typeId' in data && 'children' in data && Array.isArray(data.children) && !('listSize' in data); } /** * @param dataContainer * @param sharedRow */ function rowsIterator(dataContainer, sharedRow) { var numRows, rowIndex; return _regenerator["default"].wrap(function rowsIterator$(_context) { while (1) switch (_context.prev = _context.next) { case 0: numRows = dataContainer.numRows(); rowIndex = 0; case 2: if (!(rowIndex < numRows)) { _context.next = 8; break; } _context.next = 5; return dataContainer.row(rowIndex, sharedRow); case 5: ++rowIndex; _context.next = 2; break; case 8: case "end": return _context.stop(); } }, _marked); } /** * @param dataContainer * @param columnIndex */ function columnIterator(dataContainer, columnIndex) { var numRows, rowIndex; return _regenerator["default"].wrap(function columnIterator$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: numRows = dataContainer.numRows(); rowIndex = 0; case 2: if (!(rowIndex < numRows)) { _context2.next = 8; break; } _context2.next = 5; return dataContainer.valueAt(rowIndex, columnIndex); case 5: ++rowIndex; _context2.next = 2; break; case 8: case "end": return _context2.stop(); } }, _marked2); } /** * A data container where all data is stored in raw Arrow table */ var ArrowDataContainer = exports.ArrowDataContainer = /*#__PURE__*/function () { function ArrowDataContainer(data) { (0, _classCallCheck2["default"])(this, ArrowDataContainer); (0, _defineProperty2["default"])(this, "_cols", void 0); (0, _defineProperty2["default"])(this, "_numColumns", void 0); (0, _defineProperty2["default"])(this, "_numRows", void 0); (0, _defineProperty2["default"])(this, "_fields", void 0); (0, _defineProperty2["default"])(this, "_numChunks", void 0); // cache column data to make valueAt() faster // _colData: any[][]; /** An arrow table recreated from vectors */ (0, _defineProperty2["default"])(this, "_arrowTable", void 0); if (!data.cols) { throw Error('ArrowDataContainer: no columns provided'); } if (!Array.isArray(data.cols)) { throw Error("ArrowDataContainer: columns object isn't an array"); } this._cols = data.cols; this._numColumns = data.cols.length; this._numRows = data.cols[0].length; this._fields = data.fields || []; this._numChunks = data.cols[0].data.length; // this._colData = data.cols.map(c => c.toArray()); this._arrowTable = data.arrowTable || this._createTable(); } /** * Restores internal Arrow table from vectors. * TODO: consider using original arrow table, as it could contain extra metadata, not passed to the fields. */ return (0, _createClass2["default"])(ArrowDataContainer, [{ key: "_createTable", value: function _createTable() { var _this = this; var creaOpts = {}; this._fields.map(function (field, index) { creaOpts[field.name] = _this._cols[index]; }); return new arrow.Table(creaOpts); } }, { key: "getTable", value: function getTable() { return this._arrowTable; } }, { key: "update", value: function update(updateData) { var _this$_cols$length, _this$_cols, _this$_cols$0$length, _this$_cols2, _this$_cols$0$data$le, _this$_cols3; var isArrow = isArrowTable(updateData); if (isArrow) { this._cols = Array.from({ length: updateData.numCols }, function (_, i) { return updateData.getChildAt(i); }).filter(function (col) { return col; }); } else { this._cols = updateData; } this._numColumns = (_this$_cols$length = (_this$_cols = this._cols) === null || _this$_cols === void 0 ? void 0 : _this$_cols.length) !== null && _this$_cols$length !== void 0 ? _this$_cols$length : 0; this._numRows = (_this$_cols$0$length = (_this$_cols2 = this._cols) === null || _this$_cols2 === void 0 || (_this$_cols2 = _this$_cols2[0]) === null || _this$_cols2 === void 0 ? void 0 : _this$_cols2.length) !== null && _this$_cols$0$length !== void 0 ? _this$_cols$0$length : 0; this._numChunks = (_this$_cols$0$data$le = (_this$_cols3 = this._cols) === null || _this$_cols3 === void 0 || (_this$_cols3 = _this$_cols3[0]) === null || _this$_cols3 === void 0 || (_this$_cols3 = _this$_cols3.data) === null || _this$_cols3 === void 0 ? void 0 : _this$_cols3.length) !== null && _this$_cols$0$data$le !== void 0 ? _this$_cols$0$data$le : 0; this._arrowTable = isArrow ? updateData : this._createTable(); // cache column data to make valueAt() faster // this._colData = this._cols.map(c => c.toArray()); } }, { key: "numChunks", value: function numChunks() { return this._numChunks; } }, { key: "numRows", value: function numRows() { return this._numRows; } }, { key: "numColumns", value: function numColumns() { return this._numColumns; } }, { key: "valueAt", value: function valueAt(rowIndex, columnIndex) { // return this._colData[columnIndex][rowIndex]; return this._cols[columnIndex].get(rowIndex); } }, { key: "row", value: function row(rowIndex, sharedRow) { var tSharedRow = _dataRow.DataRow.createSharedRow(sharedRow); if (tSharedRow) { tSharedRow.setSource(this, rowIndex); return tSharedRow; } return new _dataRow.DataRow(this, rowIndex); } }, { key: "rowAsArray", value: function rowAsArray(rowIndex) { // return this._colData.map(col => col[rowIndex]); return this._cols.map(function (col) { return col.get(rowIndex); }); } }, { key: "rows", value: function rows(sharedRow) { var tSharedRow = _dataRow.DataRow.createSharedRow(sharedRow); return rowsIterator(this, tSharedRow); } }, { key: "column", value: function column(columnIndex) { return columnIterator(this, columnIndex); } }, { key: "getColumn", value: function getColumn(columnIndex) { return this._cols[columnIndex]; } }, { key: "getField", value: function getField(columnIndex) { return this._fields[columnIndex]; } }, { key: "flattenData", value: function flattenData() { var data = []; for (var i = 0; i < this._numRows; ++i) { data.push(this.rowAsArray(i)); } return data; } }, { key: "getPlainIndex", value: function getPlainIndex() { return (0, _toConsumableArray2["default"])(Array(this._numRows).keys()); } }, { key: "map", value: function map(func, sharedRow) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var tSharedRow = _dataRow.DataRow.createSharedRow(sharedRow); var _options$start = options.start, start = _options$start === void 0 ? 0 : _options$start, _options$end = options.end, end = _options$end === void 0 ? this.numRows() : _options$end; var endRow = Math.min(this.numRows(), end); var out = []; for (var rowIndex = start; rowIndex < endRow; ++rowIndex) { var row = this.row(rowIndex, tSharedRow); out.push(func(row, rowIndex)); } return out; } }, { key: "mapIndex", value: function mapIndex(func) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _options$start2 = options.start, start = _options$start2 === void 0 ? 0 : _options$start2, _options$end2 = options.end, end = _options$end2 === void 0 ? this.numRows() : _options$end2; var endRow = Math.min(this.numRows(), end); var out = []; for (var rowIndex = start; rowIndex < endRow; ++rowIndex) { out.push(func({ index: rowIndex }, this)); } return out; } }, { key: "find", value: function find(func, sharedRow) { var tSharedRow = _dataRow.DataRow.createSharedRow(sharedRow); for (var rowIndex = 0; rowIndex < this._numRows; ++rowIndex) { var row = this.row(rowIndex, tSharedRow); if (func(row, rowIndex)) { return row; } } return undefined; } }, { key: "reduce", value: function reduce(func, initialValue, sharedRow) { var tSharedRow = _dataRow.DataRow.createSharedRow(sharedRow); for (var rowIndex = 0; rowIndex < this._numRows; ++rowIndex) { var row = this.row(rowIndex, tSharedRow); initialValue = func(initialValue, row, rowIndex); } return initialValue; } }]); }(); /** * Convert arrow data type to kepler.gl field types * * @param arrowType the arrow data type * @returns corresponding type in `ALL_FIELD_TYPES` */ function arrowDataTypeToFieldType(arrowType) { // Note: this function doesn't return ALL_FIELD_TYPES.geojson or ALL_FIELD_TYPES.array, which // should be further detected by caller if (arrow.DataType.isDate(arrowType)) { return _constants.ALL_FIELD_TYPES.date; } else if (arrow.DataType.isTimestamp(arrowType) || arrow.DataType.isTime(arrowType)) { return _constants.ALL_FIELD_TYPES.timestamp; } else if (arrow.DataType.isFloat(arrowType)) { return _constants.ALL_FIELD_TYPES.real; } else if (arrow.DataType.isInt(arrowType)) { return _constants.ALL_FIELD_TYPES.integer; } else if (arrow.DataType.isBool(arrowType)) { return _constants.ALL_FIELD_TYPES["boolean"]; } else if (arrow.DataType.isUtf8(arrowType) || arrow.DataType.isNull(arrowType)) { return _constants.ALL_FIELD_TYPES.string; } else if (arrow.DataType.isBinary(arrowType) || arrow.DataType.isDictionary(arrowType) || arrow.DataType.isFixedSizeBinary(arrowType) || arrow.DataType.isFixedSizeList(arrowType) || arrow.DataType.isList(arrowType) || arrow.DataType.isMap(arrowType) || arrow.DataType.isStruct(arrowType)) { return _constants.ALL_FIELD_TYPES.object; } _window.console.warn("Unsupported arrow type: ".concat(arrowType)); return _constants.ALL_FIELD_TYPES.string; } /** * Convert arrow data type to analyzer type * * @param arrowType the arrow data type * @returns corresponding type in `AnalyzerDATA_TYPES` */ function arrowDataTypeToAnalyzerDataType(arrowType) { if (arrow.DataType.isDate(arrowType)) { return _typeAnalyzer.DATA_TYPES.DATE; } else if (arrow.DataType.isTimestamp(arrowType) || arrow.DataType.isTime(arrowType)) { return _typeAnalyzer.DATA_TYPES.DATETIME; } else if (arrow.DataType.isFloat(arrowType)) { return _typeAnalyzer.DATA_TYPES.FLOAT; } else if (arrow.DataType.isInt(arrowType)) { return _typeAnalyzer.DATA_TYPES.INT; } else if (arrow.DataType.isBool(arrowType)) { return _typeAnalyzer.DATA_TYPES.BOOLEAN; } else if (arrow.DataType.isUtf8(arrowType) || arrow.DataType.isNull(arrowType)) { return _typeAnalyzer.DATA_TYPES.STRING; } else if (arrow.DataType.isBinary(arrowType) || arrow.DataType.isDictionary(arrowType) || arrow.DataType.isFixedSizeBinary(arrowType) || arrow.DataType.isFixedSizeList(arrowType) || arrow.DataType.isList(arrowType) || arrow.DataType.isMap(arrowType) || arrow.DataType.isStruct(arrowType)) { return _typeAnalyzer.DATA_TYPES.OBJECT; } _window.console.warn("Unsupported arrow type: ".concat(arrowType)); return _typeAnalyzer.DATA_TYPES.STRING; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29uc3RhbnRzIiwicmVxdWlyZSIsImFycm93IiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJfd2luZG93IiwiX3R5cGVBbmFseXplciIsIl9kYXRhUm93IiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJfdHlwZW9mMyIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIl9tYXJrZWQiLCJfcmVnZW5lcmF0b3JSdW50aW1lMiIsIm1hcmsiLCJyb3dzSXRlcmF0b3IiLCJfbWFya2VkMiIsImNvbHVtbkl0ZXJhdG9yIiwiaXNBcnJvd1RhYmxlIiwiZGF0YSIsIl90eXBlb2YyIiwiZ2V0Q2hpbGRBdCIsIkFycmF5IiwiaXNBcnJheSIsImJhdGNoZXMiLCJpc0Fycm93VmVjdG9yIiwibGVuZ3RoIiwiaXNBcnJvd0ZpeGVkU2l6ZUxpc3QiLCJsaXN0U2l6ZSIsImNoaWxkcmVuIiwiaXNBcnJvd1N0cnVjdCIsImRhdGFDb250YWluZXIiLCJzaGFyZWRSb3ciLCJudW1Sb3dzIiwicm93SW5kZXgiLCJfcmVnZW5lcmF0b3IiLCJ3cmFwIiwicm93c0l0ZXJhdG9yJCIsIl9jb250ZXh0IiwicHJldiIsIm5leHQiLCJyb3ciLCJzdG9wIiwiY29sdW1uSW5kZXgiLCJjb2x1bW5JdGVyYXRvciQiLCJfY29udGV4dDIiLCJ2YWx1ZUF0IiwiQXJyb3dEYXRhQ29udGFpbmVyIiwiZXhwb3J0cyIsIl9jbGFzc0NhbGxDaGVjazIiLCJfZGVmaW5lUHJvcGVydHkyIiwiY29scyIsIkVycm9yIiwiX2NvbHMiLCJfbnVtQ29sdW1ucyIsIl9udW1Sb3dzIiwiX2ZpZWxkcyIsImZpZWxkcyIsIl9udW1DaHVua3MiLCJfYXJyb3dUYWJsZSIsImFycm93VGFibGUiLCJfY3JlYXRlVGFibGUiLCJfY3JlYXRlQ2xhc3MyIiwia2V5IiwidmFsdWUiLCJfdGhpcyIsImNyZWFPcHRzIiwibWFwIiwiZmllbGQiLCJpbmRleCIsIm5hbWUiLCJUYWJsZSIsImdldFRhYmxlIiwidXBkYXRlIiwidXBkYXRlRGF0YSIsIl90aGlzJF9jb2xzJGxlbmd0aCIsIl90aGlzJF9jb2xzIiwiX3RoaXMkX2NvbHMkMCRsZW5ndGgiLCJfdGhpcyRfY29sczIiLCJfdGhpcyRfY29scyQwJGRhdGEkbGUiLCJfdGhpcyRfY29sczMiLCJpc0Fycm93IiwiZnJvbSIsIm51bUNvbHMiLCJfIiwiZmlsdGVyIiwiY29sIiwibnVtQ2h1bmtzIiwibnVtQ29sdW1ucyIsInRTaGFyZWRSb3ciLCJEYXRhUm93IiwiY3JlYXRlU2hhcmVkUm93Iiwic2V0U291cmNlIiwicm93QXNBcnJheSIsInJvd3MiLCJjb2x1bW4iLCJnZXRDb2x1bW4iLCJnZXRGaWVsZCIsImZsYXR0ZW5EYXRhIiwicHVzaCIsImdldFBsYWluSW5kZXgiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwia2V5cyIsImZ1bmMiLCJvcHRpb25zIiwiYXJndW1lbnRzIiwidW5kZWZpbmVkIiwiX29wdGlvbnMkc3RhcnQiLCJzdGFydCIsIl9vcHRpb25zJGVuZCIsImVuZCIsImVuZFJvdyIsIk1hdGgiLCJtaW4iLCJvdXQiLCJtYXBJbmRleCIsIl9vcHRpb25zJHN0YXJ0MiIsIl9vcHRpb25zJGVuZDIiLCJmaW5kIiwicmVkdWNlIiwiaW5pdGlhbFZhbHVlIiwiYXJyb3dEYXRhVHlwZVRvRmllbGRUeXBlIiwiYXJyb3dUeXBlIiwiRGF0YVR5cGUiLCJpc0RhdGUiLCJBTExfRklFTERfVFlQRVMiLCJkYXRlIiwiaXNUaW1lc3RhbXAiLCJpc1RpbWUiLCJ0aW1lc3RhbXAiLCJpc0Zsb2F0IiwicmVhbCIsImlzSW50IiwiaW50ZWdlciIsImlzQm9vbCIsImlzVXRmOCIsImlzTnVsbCIsInN0cmluZyIsImlzQmluYXJ5IiwiaXNEaWN0aW9uYXJ5IiwiaXNGaXhlZFNpemVCaW5hcnkiLCJpc0ZpeGVkU2l6ZUxpc3QiLCJpc0xpc3QiLCJpc01hcCIsImlzU3RydWN0Iiwib2JqZWN0IiwiZ2xvYmFsQ29uc29sZSIsIndhcm4iLCJjb25jYXQiLCJhcnJvd0RhdGFUeXBlVG9BbmFseXplckRhdGFUeXBlIiwiQW5hbHl6ZXJEQVRBX1RZUEVTIiwiREFURSIsIkRBVEVUSU1FIiwiRkxPQVQiLCJJTlQiLCJCT09MRUFOIiwiU1RSSU5HIiwiT0JKRUNUIl0sInNvdXJjZXMiOlsiLi4vc3JjL2Fycm93LWRhdGEtY29udGFpbmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCB7QUxMX0ZJRUxEX1RZUEVTfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge1Byb3RvRGF0YXNldEZpZWxkfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCAqIGFzIGFycm93IGZyb20gJ2FwYWNoZS1hcnJvdyc7XG5pbXBvcnQge2NvbnNvbGUgYXMgZ2xvYmFsQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQge0RBVEFfVFlQRVMgYXMgQW5hbHl6ZXJEQVRBX1RZUEVTfSBmcm9tICd0eXBlLWFuYWx5emVyJztcblxuaW1wb3J0IHtEYXRhQ29udGFpbmVySW50ZXJmYWNlLCBSYW5nZU9wdGlvbnN9IGZyb20gJy4vZGF0YS1jb250YWluZXItaW50ZXJmYWNlJztcbmltcG9ydCB7RGF0YVJvdywgU2hhcmVkUm93T3B0aW9uc30gZnJvbSAnLi9kYXRhLXJvdyc7XG5cbnR5cGUgQXJyb3dEYXRhQ29udGFpbmVySW5wdXQgPSB7XG4gIGNvbHM6IGFycm93LlZlY3RvcltdO1xuICBmaWVsZHM/OiBQcm90b0RhdGFzZXRGaWVsZFtdO1xuICBhcnJvd1RhYmxlPzogYXJyb3cuVGFibGU7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRhYmxlIGlzIGFuIEFycm93VGFibGUgb2JqZWN0LlxuICpcbiAqIFdlIHVzZSBkdWNrLXR5cGluZyBpbnN0ZWFkIG9mIGBpbnN0YW5jZW9mIGFycm93LlRhYmxlYCBiZWNhdXNlIER1Y2tEQiBsb2FkcyBpdHMgb3duXG4gKiBidW5kbGVkIHZlcnNpb24gb2YgQXBhY2hlIEFycm93LiBXaGVuIER1Y2tEQiBjcmVhdGVzIEFycm93IHRhYmxlcywgdGhleSBhcmUgaW5zdGFuY2VzXG4gKiBvZiBEdWNrREIncyBBcnJvdy5UYWJsZSBjbGFzcywgbm90IHRoZSBBcnJvdy5UYWJsZSBjbGFzcyBmcm9tIG91ciBhcHBsaWNhdGlvbidzXG4gKiBhcGFjaGUtYXJyb3cgcGFja2FnZS4gVGhpcyBjYXVzZXMgYGluc3RhbmNlb2ZgIGNoZWNrcyB0byBmYWlsIGV2ZW4gdGhvdWdoIHRoZSBvYmplY3RzXG4gKiBhcmUgZnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgQXJyb3cgdGFibGVzLlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gb2JqZWN0IHRvIGNoZWNrXG4gKiBAcmV0dXJucyB0cnVlIGlmIGRhdGEgaXMgYW4gQXJyb3dUYWJsZSBvYmplY3QgKHR5cGUgZ3VhcmRlZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyb3dUYWJsZShkYXRhOiBhbnkpOiBkYXRhIGlzIGFycm93LlRhYmxlIHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgJiZcbiAgICBkYXRhICE9PSBudWxsICYmXG4gICAgJ3NjaGVtYScgaW4gZGF0YSAmJlxuICAgICdnZXRDaGlsZEF0JyBpbiBkYXRhICYmXG4gICAgdHlwZW9mIGRhdGEuZ2V0Q2hpbGRBdCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICdiYXRjaGVzJyBpbiBkYXRhICYmXG4gICAgQXJyYXkuaXNBcnJheShkYXRhLmJhdGNoZXMpXG4gICk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgZGF0YSBpcyBhbiBBcnJvd1ZlY3RvciBvYmplY3QuXG4gKiBVc2VzIGR1Y2stdHlwaW5nIGluc3RlYWQgb2YgYGluc3RhbmNlb2ZgIHRvIGhhbmRsZSBEdWNrREIncyBidW5kbGVkIEFycm93IHZlcnNpb24uXG4gKlxuICogQHBhcmFtIGRhdGEgLSBvYmplY3QgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHRydWUgaWYgZGF0YSBpcyBhbiBBcnJvd1ZlY3RvciBvYmplY3QgKHR5cGUgZ3VhcmRlZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyb3dWZWN0b3IoZGF0YTogYW55KTogZGF0YSBpcyBhcnJvdy5WZWN0b3Ige1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JyAmJlxuICAgIGRhdGEgIT09IG51bGwgJiZcbiAgICAndHlwZScgaW4gZGF0YSAmJlxuICAgICdsZW5ndGgnIGluIGRhdGEgJiZcbiAgICB0eXBlb2YgZGF0YS5sZW5ndGggPT09ICdudW1iZXInICYmXG4gICAgJ2dldCcgaW4gZGF0YSAmJlxuICAgIHR5cGVvZiBkYXRhLmdldCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICdkYXRhJyBpbiBkYXRhICYmXG4gICAgQXJyYXkuaXNBcnJheShkYXRhLmRhdGEpXG4gICk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgZGF0YSBpcyBhbiBBcnJvdyBGaXhlZFNpemVMaXN0IERhdGFUeXBlLlxuICogVXNlcyBkdWNrLXR5cGluZyBpbnN0ZWFkIG9mIGBpbnN0YW5jZW9mYCB0byBoYW5kbGUgRHVja0RCJ3MgYnVuZGxlZCBBcnJvdyB2ZXJzaW9uLlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gb2JqZWN0IHRvIGNoZWNrXG4gKiBAcmV0dXJucyB0cnVlIGlmIGRhdGEgaXMgYW4gQXJyb3cgRml4ZWRTaXplTGlzdCBEYXRhVHlwZSAodHlwZSBndWFyZGVkKVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJvd0ZpeGVkU2l6ZUxpc3QoZGF0YTogYW55KTogZGF0YSBpcyBhcnJvdy5GaXhlZFNpemVMaXN0IHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgJiZcbiAgICBkYXRhICE9PSBudWxsICYmXG4gICAgJ3R5cGVJZCcgaW4gZGF0YSAmJlxuICAgICdsaXN0U2l6ZScgaW4gZGF0YSAmJlxuICAgIHR5cGVvZiBkYXRhLmxpc3RTaXplID09PSAnbnVtYmVyJyAmJlxuICAgICdjaGlsZHJlbicgaW4gZGF0YSAmJlxuICAgIEFycmF5LmlzQXJyYXkoZGF0YS5jaGlsZHJlbilcbiAgKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBkYXRhIGlzIGFuIEFycm93IFN0cnVjdCBEYXRhVHlwZS5cbiAqIFVzZXMgZHVjay10eXBpbmcgaW5zdGVhZCBvZiBgaW5zdGFuY2VvZmAgdG8gaGFuZGxlIER1Y2tEQidzIGJ1bmRsZWQgQXJyb3cgdmVyc2lvbi5cbiAqXG4gKiBAcGFyYW0gZGF0YSAtIG9iamVjdCB0byBjaGVja1xuICogQHJldHVybnMgdHJ1ZSBpZiBkYXRhIGlzIGFuIEFycm93IFN0cnVjdCBEYXRhVHlwZSAodHlwZSBndWFyZGVkKVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJvd1N0cnVjdChkYXRhOiBhbnkpOiBkYXRhIGlzIGFycm93LlN0cnVjdCB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnICYmXG4gICAgZGF0YSAhPT0gbnVsbCAmJlxuICAgICd0eXBlSWQnIGluIGRhdGEgJiZcbiAgICAnY2hpbGRyZW4nIGluIGRhdGEgJiZcbiAgICBBcnJheS5pc0FycmF5KGRhdGEuY2hpbGRyZW4pICYmXG4gICAgISgnbGlzdFNpemUnIGluIGRhdGEpXG4gICk7XG59XG5cbi8qKlxuICogQHBhcmFtIGRhdGFDb250YWluZXJcbiAqIEBwYXJhbSBzaGFyZWRSb3dcbiAqL1xuZnVuY3Rpb24qIHJvd3NJdGVyYXRvcihkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlLCBzaGFyZWRSb3c6IFNoYXJlZFJvd09wdGlvbnMpIHtcbiAgY29uc3QgbnVtUm93cyA9IGRhdGFDb250YWluZXIubnVtUm93cygpO1xuICBmb3IgKGxldCByb3dJbmRleCA9IDA7IHJvd0luZGV4IDwgbnVtUm93czsgKytyb3dJbmRleCkge1xuICAgIHlpZWxkIGRhdGFDb250YWluZXIucm93KHJvd0luZGV4LCBzaGFyZWRSb3cpO1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIGRhdGFDb250YWluZXJcbiAqIEBwYXJhbSBjb2x1bW5JbmRleFxuICovXG5mdW5jdGlvbiogY29sdW1uSXRlcmF0b3IoZGF0YUNvbnRhaW5lcjogRGF0YUNvbnRhaW5lckludGVyZmFjZSwgY29sdW1uSW5kZXg6IG51bWJlcikge1xuICBjb25zdCBudW1Sb3dzID0gZGF0YUNvbnRhaW5lci5udW1Sb3dzKCk7XG4gIGZvciAobGV0IHJvd0luZGV4ID0gMDsgcm93SW5kZXggPCBudW1Sb3dzOyArK3Jvd0luZGV4KSB7XG4gICAgeWllbGQgZGF0YUNvbnRhaW5lci52YWx1ZUF0KHJvd0luZGV4LCBjb2x1bW5JbmRleCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGRhdGEgY29udGFpbmVyIHdoZXJlIGFsbCBkYXRhIGlzIHN0b3JlZCBpbiByYXcgQXJyb3cgdGFibGVcbiAqL1xuZXhwb3J0IGNsYXNzIEFycm93RGF0YUNvbnRhaW5lciBpbXBsZW1lbnRzIERhdGFDb250YWluZXJJbnRlcmZhY2Uge1xuICBfY29sczogYXJyb3cuVmVjdG9yW107XG4gIF9udW1Db2x1bW5zOiBudW1iZXI7XG4gIF9udW1Sb3dzOiBudW1iZXI7XG4gIF9maWVsZHM6IFByb3RvRGF0YXNldEZpZWxkW107XG4gIF9udW1DaHVua3M6IG51bWJlcjtcbiAgLy8gY2FjaGUgY29sdW1uIGRhdGEgdG8gbWFrZSB2YWx1ZUF0KCkgZmFzdGVyXG4gIC8vIF9jb2xEYXRhOiBhbnlbXVtdO1xuXG4gIC8qKiBBbiBhcnJvdyB0YWJsZSByZWNyZWF0ZWQgZnJvbSB2ZWN0b3JzICovXG4gIF9hcnJvd1RhYmxlOiBhcnJvdy5UYWJsZTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBBcnJvd0RhdGFDb250YWluZXJJbnB1dCkge1xuICAgIGlmICghZGF0YS5jb2xzKSB7XG4gICAgICB0aHJvdyBFcnJvcignQXJyb3dEYXRhQ29udGFpbmVyOiBubyBjb2x1bW5zIHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEuY29scykpIHtcbiAgICAgIHRocm93IEVycm9yKFwiQXJyb3dEYXRhQ29udGFpbmVyOiBjb2x1bW5zIG9iamVjdCBpc24ndCBhbiBhcnJheVwiKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jb2xzID0gZGF0YS5jb2xzO1xuICAgIHRoaXMuX251bUNvbHVtbnMgPSBkYXRhLmNvbHMubGVuZ3RoO1xuICAgIHRoaXMuX251bVJvd3MgPSBkYXRhLmNvbHNbMF0ubGVuZ3RoO1xuICAgIHRoaXMuX2ZpZWxkcyA9IGRhdGEuZmllbGRzIHx8IFtdO1xuICAgIHRoaXMuX251bUNodW5rcyA9IGRhdGEuY29sc1swXS5kYXRhLmxlbmd0aDtcbiAgICAvLyB0aGlzLl9jb2xEYXRhID0gZGF0YS5jb2xzLm1hcChjID0+IGMudG9BcnJheSgpKTtcblxuICAgIHRoaXMuX2Fycm93VGFibGUgPSBkYXRhLmFycm93VGFibGUgfHwgdGhpcy5fY3JlYXRlVGFibGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXN0b3JlcyBpbnRlcm5hbCBBcnJvdyB0YWJsZSBmcm9tIHZlY3RvcnMuXG4gICAqIFRPRE86IGNvbnNpZGVyIHVzaW5nIG9yaWdpbmFsIGFycm93IHRhYmxlLCBhcyBpdCBjb3VsZCBjb250YWluIGV4dHJhIG1ldGFkYXRhLCBub3QgcGFzc2VkIHRvIHRoZSBmaWVsZHMuXG4gICAqL1xuICBwcml2YXRlIF9jcmVhdGVUYWJsZSgpIHtcbiAgICBjb25zdCBjcmVhT3B0cyA9IHt9O1xuICAgIHRoaXMuX2ZpZWxkcy5tYXAoKGZpZWxkLCBpbmRleCkgPT4ge1xuICAgICAgY3JlYU9wdHNbZmllbGQubmFtZV0gPSB0aGlzLl9jb2xzW2luZGV4XTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3IGFycm93LlRhYmxlKGNyZWFPcHRzKTtcbiAgfVxuXG4gIGdldFRhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLl9hcnJvd1RhYmxlO1xuICB9XG5cbiAgdXBkYXRlKHVwZGF0ZURhdGE6IGFycm93LlZlY3Rvcjxhbnk+W10gfCBhcnJvdy5UYWJsZSkge1xuICAgIGNvbnN0IGlzQXJyb3cgPSBpc0Fycm93VGFibGUodXBkYXRlRGF0YSk7XG4gICAgaWYgKGlzQXJyb3cpIHtcbiAgICAgIHRoaXMuX2NvbHMgPSBBcnJheS5mcm9tKFxuICAgICAgICB7bGVuZ3RoOiB1cGRhdGVEYXRhLm51bUNvbHN9LFxuICAgICAgICAoXywgaSkgPT4gdXBkYXRlRGF0YS5nZXRDaGlsZEF0KGkpIGFzIGFycm93LlZlY3RvclxuICAgICAgKS5maWx0ZXIoY29sID0+IGNvbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2NvbHMgPSB1cGRhdGVEYXRhO1xuICAgIH1cbiAgICB0aGlzLl9udW1Db2x1bW5zID0gdGhpcy5fY29scz8ubGVuZ3RoID8/IDA7XG4gICAgdGhpcy5fbnVtUm93cyA9IHRoaXMuX2NvbHM/LlswXT8ubGVuZ3RoID8/IDA7XG4gICAgdGhpcy5fbnVtQ2h1bmtzID0gdGhpcy5fY29scz8uWzBdPy5kYXRhPy5sZW5ndGggPz8gMDtcbiAgICB0aGlzLl9hcnJvd1RhYmxlID0gaXNBcnJvdyA/IHVwZGF0ZURhdGEgOiB0aGlzLl9jcmVhdGVUYWJsZSgpO1xuXG4gICAgLy8gY2FjaGUgY29sdW1uIGRhdGEgdG8gbWFrZSB2YWx1ZUF0KCkgZmFzdGVyXG4gICAgLy8gdGhpcy5fY29sRGF0YSA9IHRoaXMuX2NvbHMubWFwKGMgPT4gYy50b0FycmF5KCkpO1xuICB9XG5cbiAgbnVtQ2h1bmtzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX251bUNodW5rcztcbiAgfVxuXG4gIG51bVJvd3MoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbnVtUm93cztcbiAgfVxuXG4gIG51bUNvbHVtbnMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbnVtQ29sdW1ucztcbiAgfVxuXG4gIHZhbHVlQXQocm93SW5kZXg6IG51bWJlciwgY29sdW1uSW5kZXg6IG51bWJlcik6IGFueSB7XG4gICAgLy8gcmV0dXJuIHRoaXMuX2NvbERhdGFbY29sdW1uSW5kZXhdW3Jvd0luZGV4XTtcbiAgICByZXR1cm4gdGhpcy5fY29sc1tjb2x1bW5JbmRleF0uZ2V0KHJvd0luZGV4KTtcbiAgfVxuXG4gIHJvdyhyb3dJbmRleDogbnVtYmVyLCBzaGFyZWRSb3c/OiBTaGFyZWRSb3dPcHRpb25zKTogRGF0YVJvdyB7XG4gICAgY29uc3QgdFNoYXJlZFJvdyA9IERhdGFSb3cuY3JlYXRlU2hhcmVkUm93KHNoYXJlZFJvdyk7XG4gICAgaWYgKHRTaGFyZWRSb3cpIHtcbiAgICAgIHRTaGFyZWRSb3cuc2V0U291cmNlKHRoaXMsIHJvd0luZGV4KTtcbiAgICAgIHJldHVybiB0U2hhcmVkUm93O1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRGF0YVJvdyh0aGlzLCByb3dJbmRleCk7XG4gIH1cblxuICByb3dBc0FycmF5KHJvd0luZGV4OiBudW1iZXIpOiBhbnlbXSB7XG4gICAgLy8gcmV0dXJuIHRoaXMuX2NvbERhdGEubWFwKGNvbCA9PiBjb2xbcm93SW5kZXhdKTtcbiAgICByZXR1cm4gdGhpcy5fY29scy5tYXAoY29sID0+IGNvbC5nZXQocm93SW5kZXgpKTtcbiAgfVxuXG4gIHJvd3Moc2hhcmVkUm93OiBTaGFyZWRSb3dPcHRpb25zKSB7XG4gICAgY29uc3QgdFNoYXJlZFJvdyA9IERhdGFSb3cuY3JlYXRlU2hhcmVkUm93KHNoYXJlZFJvdyk7XG4gICAgcmV0dXJuIHJvd3NJdGVyYXRvcih0aGlzLCB0U2hhcmVkUm93KTtcbiAgfVxuXG4gIGNvbHVtbihjb2x1bW5JbmRleDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIGNvbHVtbkl0ZXJhdG9yKHRoaXMsIGNvbHVtbkluZGV4KTtcbiAgfVxuXG4gIGdldENvbHVtbihjb2x1bW5JbmRleDogbnVtYmVyKTogYXJyb3cuVmVjdG9yIHtcbiAgICByZXR1cm4gdGhpcy5fY29sc1tjb2x1bW5JbmRleF07XG4gIH1cblxuICBnZXRGaWVsZChjb2x1bW5JbmRleDogbnVtYmVyKTogUHJvdG9EYXRhc2V0RmllbGQge1xuICAgIHJldHVybiB0aGlzLl9maWVsZHNbY29sdW1uSW5kZXhdO1xuICB9XG5cbiAgZmxhdHRlbkRhdGEoKTogYW55W11bXSB7XG4gICAgY29uc3QgZGF0YTogYW55W11bXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbnVtUm93czsgKytpKSB7XG4gICAgICBkYXRhLnB1c2godGhpcy5yb3dBc0FycmF5KGkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBnZXRQbGFpbkluZGV4KCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gWy4uLkFycmF5KHRoaXMuX251bVJvd3MpLmtleXMoKV07XG4gIH1cblxuICBtYXA8VD4oXG4gICAgZnVuYzogKHJvdzogRGF0YVJvdywgaW5kZXg6IG51bWJlcikgPT4gVCxcbiAgICBzaGFyZWRSb3c/OiBTaGFyZWRSb3dPcHRpb25zLFxuICAgIG9wdGlvbnM6IFJhbmdlT3B0aW9ucyA9IHt9XG4gICk6IFRbXSB7XG4gICAgY29uc3QgdFNoYXJlZFJvdyA9IERhdGFSb3cuY3JlYXRlU2hhcmVkUm93KHNoYXJlZFJvdyk7XG5cbiAgICBjb25zdCB7c3RhcnQgPSAwLCBlbmQgPSB0aGlzLm51bVJvd3MoKX0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGVuZFJvdyA9IE1hdGgubWluKHRoaXMubnVtUm93cygpLCBlbmQpO1xuXG4gICAgY29uc3Qgb3V0OiBUW10gPSBbXTtcbiAgICBmb3IgKGxldCByb3dJbmRleCA9IHN0YXJ0OyByb3dJbmRleCA8IGVuZFJvdzsgKytyb3dJbmRleCkge1xuICAgICAgY29uc3Qgcm93ID0gdGhpcy5yb3cocm93SW5kZXgsIHRTaGFyZWRSb3cpO1xuICAgICAgb3V0LnB1c2goZnVuYyhyb3csIHJvd0luZGV4KSk7XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBtYXBJbmRleDxUPihmdW5jOiAoe2luZGV4fSwgZGM6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+IFQsIG9wdGlvbnM6IFJhbmdlT3B0aW9ucyA9IHt9KTogVFtdIHtcbiAgICBjb25zdCB7c3RhcnQgPSAwLCBlbmQgPSB0aGlzLm51bVJvd3MoKX0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGVuZFJvdyA9IE1hdGgubWluKHRoaXMubnVtUm93cygpLCBlbmQpO1xuXG4gICAgY29uc3Qgb3V0OiBUW10gPSBbXTtcbiAgICBmb3IgKGxldCByb3dJbmRleCA9IHN0YXJ0OyByb3dJbmRleCA8IGVuZFJvdzsgKytyb3dJbmRleCkge1xuICAgICAgb3V0LnB1c2goZnVuYyh7aW5kZXg6IHJvd0luZGV4fSwgdGhpcykpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgZmluZChcbiAgICBmdW5jOiAocm93OiBEYXRhUm93LCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuLFxuICAgIHNoYXJlZFJvdz86IFNoYXJlZFJvd09wdGlvbnNcbiAgKTogRGF0YVJvdyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdFNoYXJlZFJvdyA9IERhdGFSb3cuY3JlYXRlU2hhcmVkUm93KHNoYXJlZFJvdyk7XG5cbiAgICBmb3IgKGxldCByb3dJbmRleCA9IDA7IHJvd0luZGV4IDwgdGhpcy5fbnVtUm93czsgKytyb3dJbmRleCkge1xuICAgICAgY29uc3Qgcm93ID0gdGhpcy5yb3cocm93SW5kZXgsIHRTaGFyZWRSb3cpO1xuICAgICAgaWYgKGZ1bmMocm93LCByb3dJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIHJvdztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJlZHVjZTxUPihcbiAgICBmdW5jOiAoYWNjOiBULCByb3c6IERhdGFSb3csIGluZGV4OiBudW1iZXIpID0+IFQsXG4gICAgaW5pdGlhbFZhbHVlOiBULFxuICAgIHNoYXJlZFJvdz86IFNoYXJlZFJvd09wdGlvbnNcbiAgKTogVCB7XG4gICAgY29uc3QgdFNoYXJlZFJvdyA9IERhdGFSb3cuY3JlYXRlU2hhcmVkUm93KHNoYXJlZFJvdyk7XG5cbiAgICBmb3IgKGxldCByb3dJbmRleCA9IDA7IHJvd0luZGV4IDwgdGhpcy5fbnVtUm93czsgKytyb3dJbmRleCkge1xuICAgICAgY29uc3Qgcm93ID0gdGhpcy5yb3cocm93SW5kZXgsIHRTaGFyZWRSb3cpO1xuICAgICAgaW5pdGlhbFZhbHVlID0gZnVuYyhpbml0aWFsVmFsdWUsIHJvdywgcm93SW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gaW5pdGlhbFZhbHVlO1xuICB9XG59XG5cbi8qKlxuICogQ29udmVydCBhcnJvdyBkYXRhIHR5cGUgdG8ga2VwbGVyLmdsIGZpZWxkIHR5cGVzXG4gKlxuICogQHBhcmFtIGFycm93VHlwZSB0aGUgYXJyb3cgZGF0YSB0eXBlXG4gKiBAcmV0dXJucyBjb3JyZXNwb25kaW5nIHR5cGUgaW4gYEFMTF9GSUVMRF9UWVBFU2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFycm93RGF0YVR5cGVUb0ZpZWxkVHlwZShhcnJvd1R5cGU6IGFycm93LkRhdGFUeXBlKTogc3RyaW5nIHtcbiAgLy8gTm90ZTogdGhpcyBmdW5jdGlvbiBkb2Vzbid0IHJldHVybiBBTExfRklFTERfVFlQRVMuZ2VvanNvbiBvciBBTExfRklFTERfVFlQRVMuYXJyYXksIHdoaWNoXG4gIC8vIHNob3VsZCBiZSBmdXJ0aGVyIGRldGVjdGVkIGJ5IGNhbGxlclxuICBpZiAoYXJyb3cuRGF0YVR5cGUuaXNEYXRlKGFycm93VHlwZSkpIHtcbiAgICByZXR1cm4gQUxMX0ZJRUxEX1RZUEVTLmRhdGU7XG4gIH0gZWxzZSBpZiAoYXJyb3cuRGF0YVR5cGUuaXNUaW1lc3RhbXAoYXJyb3dUeXBlKSB8fCBhcnJvdy5EYXRhVHlwZS5pc1RpbWUoYXJyb3dUeXBlKSkge1xuICAgIHJldHVybiBBTExfRklFTERfVFlQRVMudGltZXN0YW1wO1xuICB9IGVsc2UgaWYgKGFycm93LkRhdGFUeXBlLmlzRmxvYXQoYXJyb3dUeXBlKSkge1xuICAgIHJldHVybiBBTExfRklFTERfVFlQRVMucmVhbDtcbiAgfSBlbHNlIGlmIChhcnJvdy5EYXRhVHlwZS5pc0ludChhcnJvd1R5cGUpKSB7XG4gICAgcmV0dXJuIEFMTF9GSUVMRF9UWVBFUy5pbnRlZ2VyO1xuICB9IGVsc2UgaWYgKGFycm93LkRhdGFUeXBlLmlzQm9vbChhcnJvd1R5cGUpKSB7XG4gICAgcmV0dXJuIEFMTF9GSUVMRF9UWVBFUy5ib29sZWFuO1xuICB9IGVsc2UgaWYgKGFycm93LkRhdGFUeXBlLmlzVXRmOChhcnJvd1R5cGUpIHx8IGFycm93LkRhdGFUeXBlLmlzTnVsbChhcnJvd1R5cGUpKSB7XG4gICAgcmV0dXJuIEFMTF9GSUVMRF9UWVBFUy5zdHJpbmc7XG4gIH0gZWxzZSBpZiAoXG4gICAgYXJyb3cuRGF0YVR5cGUuaXNCaW5hcnkoYXJyb3dUeXBlKSB8fFxuICAgIGFycm93LkRhdGFUeXBlLmlzRGljdGlvbmFyeShhcnJvd1R5cGUpIHx8XG4gICAgYXJyb3cuRGF0YVR5cGUuaXNGaXhlZFNpemVCaW5hcnkoYXJyb3dUeXBlKSB8fFxuICAgIGFycm93LkRhdGFUeXBlLmlzRml4ZWRTaXplTGlzdChhcnJvd1R5cGUpIHx8XG4gICAgYXJyb3cuRGF0YVR5cGUuaXNMaXN0KGFycm93VHlwZSkgfHxcbiAgICBhcnJvdy5EYXRhVHlwZS5pc01hcChhcnJvd1R5cGUpIHx8XG4gICAgYXJyb3cuRGF0YVR5cGUuaXNTdHJ1Y3QoYXJyb3dUeXBlKVxuICApIHtcbiAgICByZXR1cm4gQUxMX0ZJRUxEX1RZUEVTLm9iamVjdDtcbiAgfVxuICBnbG9iYWxDb25zb2xlLndhcm4oYFVuc3VwcG9ydGVkIGFycm93IHR5cGU6ICR7YXJyb3dUeXBlfWApO1xuICByZXR1cm4gQUxMX0ZJRUxEX1RZUEVTLnN0cmluZztcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFycm93IGRhdGEgdHlwZSB0byBhbmFseXplciB0eXBlXG4gKlxuICogQHBhcmFtIGFycm93VHlwZSB0aGUgYXJyb3cgZGF0YSB0eXBlXG4gKiBAcmV0dXJucyBjb3JyZXNwb25kaW5nIHR5cGUgaW4gYEFuYWx5emVyREFUQV9UWVBFU2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFycm93RGF0YVR5cGVUb0FuYWx5emVyRGF0YVR5cGUoXG4gIGFycm93VHlwZTogYXJyb3cuRGF0YVR5cGVcbik6IHR5cGVvZiBBbmFseXplckRBVEFfVFlQRVMge1xuICBpZiAoYXJyb3cuRGF0YVR5cGUuaXNEYXRlKGFycm93VHlwZSkpIHtcbiAgICByZXR1cm4gQW5hbHl6ZXJEQVRBX1RZUEVTLkRBVEU7XG4gIH0gZWxzZSBpZiAoYXJyb3cuRGF0YVR5cGUuaXNUaW1lc3RhbXAoYXJyb3dUeXBlKSB8fCBhcnJvdy5EYXRhVHlwZS5pc1RpbWUoYXJyb3dUeXBlKSkge1xuICAgIHJldHVybiBBbmFseXplckRBVEFfVFlQRVMuREFURVRJTUU7XG4gIH0gZWxzZSBpZiAoYXJyb3cuRGF0YVR5cGUuaXNGbG9hdChhcnJvd1R5cGUpKSB7XG4gICAgcmV0dXJuIEFuYWx5emVyREFUQV9UWVBFUy5GTE9BVDtcbiAgfSBlbHNlIGlmIChhcnJvdy5EYXRhVHlwZS5pc0ludChhcnJvd1R5cGUpKSB7XG4gICAgcmV0dXJuIEFuYWx5emVyREFUQV9UWVBFUy5JTlQ7XG4gIH0gZWxzZSBpZiAoYXJyb3cuRGF0YVR5cGUuaXNCb29sKGFycm93VHlwZSkpIHtcbiAgICByZXR1cm4gQW5hbHl6ZXJEQVRBX1RZUEVTLkJPT0xFQU47XG4gIH0gZWxzZSBpZiAoYXJyb3cuRGF0YVR5cGUuaXNVdGY4KGFycm93VHlwZSkgfHwgYXJyb3cuRGF0YVR5cGUuaXNOdWxsKGFycm93VHlwZSkpIHtcbiAgICByZXR1cm4gQW5hbHl6ZXJEQVRBX1RZUEVTLlNUUklORztcbiAgfSBlbHNlIGlmIChcbiAgICBhcnJvdy5EYXRhVHlwZS5pc0JpbmFyeShhcnJvd1R5cGUpIHx8XG4gICAgYXJyb3cuRGF0YVR5cGUuaXNEaWN0aW9uYXJ5KGFycm93VHlwZSkgfHxcbiAgICBhcnJvdy5EYXRhVHlwZS5pc0ZpeGVkU2l6ZUJpbmFyeShhcnJvd1R5cGUpIHx8XG4gICAgYXJyb3cuRGF0YVR5cGUuaXNGaXhlZFNpemVMaXN0KGFycm93VHlwZSkgfHxcbiAgICBhcnJvdy5EYXRhVHlwZS5pc0xpc3QoYXJyb3dUeXBlKSB8fFxuICAgIGFycm93LkRhdGFUeXBlLmlzTWFwKGFycm93VHlwZSkgfHxcbiAgICBhcnJvdy5EYXRhVHlwZS5pc1N0cnVjdChhcnJvd1R5cGUpXG4gICkge1xuICAgIHJldHVybiBBbmFseXplckRBVEFfVFlQRVMuT0JKRUNUO1xuICB9XG4gIGdsb2JhbENvbnNvbGUud2FybihgVW5zdXBwb3J0ZWQgYXJyb3cgdHlwZTogJHthcnJvd1R5cGV9YCk7XG4gIHJldHVybiBBbmFseXplckRBVEFfVFlQRVMuU1RSSU5HO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxVQUFBLEdBQUFDLE9BQUE7QUFFQSxJQUFBQyxLQUFBLEdBQUFDLHVCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBRyxPQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxhQUFBLEdBQUFKLE9BQUE7QUFHQSxJQUFBSyxRQUFBLEdBQUFMLE9BQUE7QUFBcUQsU0FBQU0seUJBQUFDLENBQUEsNkJBQUFDLE9BQUEsbUJBQUFDLENBQUEsT0FBQUQsT0FBQSxJQUFBRSxDQUFBLE9BQUFGLE9BQUEsWUFBQUYsd0JBQUEsWUFBQUEseUJBQUFDLENBQUEsV0FBQUEsQ0FBQSxHQUFBRyxDQUFBLEdBQUFELENBQUEsS0FBQUYsQ0FBQTtBQUFBLFNBQUFMLHdCQUFBSyxDQUFBLEVBQUFFLENBQUEsU0FBQUEsQ0FBQSxJQUFB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