UNPKG

kepler.gl

Version:

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

276 lines (268 loc) 33.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; 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 _utils = require("@kepler.gl/utils"); var _iterableTileSet = _interopRequireDefault(require("./iterable-tile-set")); var _tileUtils = require("./tile-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; } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project /** * Per-tile stats, for caching */ /** * Stateful class offering dataset-style functions for the set of tiles. */ var TileDataset = exports["default"] = /*#__PURE__*/function () { function TileDataset(accessors, tiles) { (0, _classCallCheck2["default"])(this, TileDataset); (0, _defineProperty2["default"])(this, "accessors", void 0); (0, _defineProperty2["default"])(this, "tiles", void 0); (0, _defineProperty2["default"])(this, "tileSet", void 0); (0, _defineProperty2["default"])(this, "tileIds", new Set()); /** Cache for per-tile field stats: tileId -> fieldId -> stats */ (0, _defineProperty2["default"])(this, "tileStats", new Map()); this.accessors = accessors; this.tiles = []; this.tileSet = new _iterableTileSet["default"]([], accessors.getRowCount); if (tiles) { this.updateTiles(tiles); } } /** * Invalidate the cached data */ return (0, _createClass2["default"])(TileDataset, [{ key: "invalidateCache", value: function invalidateCache() { // TODO: implement later } /** * Update the set of tiles in the viewport */ }, { key: "updateTiles", value: function updateTiles(tiles) { var _this$accessors = this.accessors, getTileId = _this$accessors.getTileId, getIterable = _this$accessors.getIterable, getRowCount = _this$accessors.getRowCount; var tileIds = new Set(tiles.map(getTileId)); if (!areEqualSets(tileIds, this.tileIds)) { this.invalidateCache(); } this.tiles = tiles; this.tileIds = tileIds; this.tileSet = new _iterableTileSet["default"](tiles.map(getIterable), getRowCount); } /** * Return current tiles */ }, { key: "getTiles", value: function getTiles() { return this.tiles; } /** * Get the min/max domain of a field */ }, { key: "getExtent", value: function getExtent(field) { var _this$accessors2 = this.accessors, getRowValue = _this$accessors2.getRowValue, getIterable = _this$accessors2.getIterable; var accessor = getRowValue(field); var min = Infinity; var max = -Infinity; var _iterator = _createForOfIteratorHelper(this.tiles), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var tile = _step.value; // Check the cache var extent = this.getTileStat(tile, field, 'extent'); if (!extent) { // Cache miss, calculate and cache extent = getTileExtent(getIterable(tile), field, accessor); this.setTileStat(tile, field, 'extent', extent); } if (extent) { if (extent[0] < min) min = extent[0]; if (extent[1] > max) max = extent[1]; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return Number.isFinite(min) && Number.isFinite(max) ? [min, max] : [0, 0]; } /** * Get a sample of field values to use in estimating quantiles */ }, { key: "getQuantileSample", value: function getQuantileSample(field) { var minRowCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000; // TODO: There should be reasonable per-tile caching possible here var set = this.tileSet; var accessor = this.accessors.getRowValue(field); var sample = []; var sampleStep = Math.max(Math.floor(set.rowCount / minRowCount), 1); var i = 0; var _iterator2 = _createForOfIteratorHelper(set), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var _row = _step2.value; if (++i === sampleStep) { var val = accessor(field, _row); if (val !== null) sample.push(val); i = 0; } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } (0, _utils.quickInsertionSort)(sample); (0, _tileUtils.pruneQuantiles)(sample); return sample; } /** * Get a set of unique values for a field */ }, { key: "getUniqueValues", value: function getUniqueValues(field) { var _this$accessors3 = this.accessors, getRowValue = _this$accessors3.getRowValue, getIterable = _this$accessors3.getIterable; var accessor = getRowValue(field); var uniques = new Set(); var _iterator3 = _createForOfIteratorHelper(this.tiles), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var _tileUniques; var tile = _step3.value; // Check the cache var tileUniques = this.getTileStat(tile, field, 'uniqueValues'); if (!tileUniques) { // Cache miss, calculate and cache tileUniques = getTileUniqueValues(getIterable(tile), field, accessor); this.setTileStat(tile, field, 'uniqueValues', tileUniques); } var _iterator4 = _createForOfIteratorHelper((_tileUniques = tileUniques) !== null && _tileUniques !== void 0 ? _tileUniques : []), _step4; try { for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { var val = _step4.value; uniques.add(val); } } catch (err) { _iterator4.e(err); } finally { _iterator4.f(); } } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } return (0, _toConsumableArray2["default"])(uniques); } }, { key: "getTileStat", value: function getTileStat(tile, field, stat) { var _this$tileStats$get; return (_this$tileStats$get = this.tileStats.get(this.accessors.getTileId(tile))) === null || _this$tileStats$get === void 0 || (_this$tileStats$get = _this$tileStats$get.get(field.name)) === null || _this$tileStats$get === void 0 ? void 0 : _this$tileStats$get[stat]; } }, { key: "setTileStat", value: function setTileStat(tile, field, stat, value) { var _this$tileStats$get2, _tileStats$get; var tileId = this.accessors.getTileId(tile); var tileStats = (_this$tileStats$get2 = this.tileStats.get(tileId)) !== null && _this$tileStats$get2 !== void 0 ? _this$tileStats$get2 : new Map(); var tileFieldStats = (_tileStats$get = tileStats.get(field.name)) !== null && _tileStats$get !== void 0 ? _tileStats$get : {}; tileFieldStats[stat] = value; tileStats.set(field.name, tileFieldStats); this.tileStats.set(tileId, tileStats); } }]); }(); /** * Get the min/max domain of a field in a given tile */ function getTileExtent(iterable, field, accessor) { var min = Infinity; var max = -Infinity; var _iterator5 = _createForOfIteratorHelper(iterable), _step5; try { for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { var _row2 = _step5.value; var val = accessor(field, _row2); if (val === null) continue; if (val < min) min = val; if (val > max) max = val; } } catch (err) { _iterator5.e(err); } finally { _iterator5.f(); } return Number.isFinite(min) && Number.isFinite(max) ? [min, max] : undefined; } /** * Get unique values for a field in a given tile */ function getTileUniqueValues(iterable, field, accessor) { var maxUniques = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 20; var uniques = new Set(); var _iterator6 = _createForOfIteratorHelper(iterable), _step6; try { for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { var _row3 = _step6.value; if (uniques.size >= maxUniques) return uniques; uniques.add(accessor(field, _row3)); } } catch (err) { _iterator6.e(err); } finally { _iterator6.f(); } return uniques; } function areEqualSets(a, b) { if (a.size !== b.size) return false; var _iterator7 = _createForOfIteratorHelper(a), _step7; try { for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { var val = _step7.value; if (!b.has(val)) { return false; } } } catch (err) { _iterator7.e(err); } finally { _iterator7.f(); } return true; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdXRpbHMiLCJyZXF1aXJlIiwiX2l0ZXJhYmxlVGlsZVNldCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfdGlsZVV0aWxzIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJUaWxlRGF0YXNldCIsImV4cG9ydHMiLCJhY2Nlc3NvcnMiLCJ0aWxlcyIsIl9jbGFzc0NhbGxDaGVjazIiLCJfZGVmaW5lUHJvcGVydHkyIiwiU2V0IiwiTWFwIiwidGlsZVNldCIsIkl0ZXJhYmxlVGlsZVNldCIsImdldFJvd0NvdW50IiwidXBkYXRlVGlsZXMiLCJfY3JlYXRlQ2xhc3MyIiwia2V5IiwiaW52YWxpZGF0ZUNhY2hlIiwiX3RoaXMkYWNjZXNzb3JzIiwiZ2V0VGlsZUlkIiwiZ2V0SXRlcmFibGUiLCJ0aWxlSWRzIiwibWFwIiwiYXJlRXF1YWxTZXRzIiwiZ2V0VGlsZXMiLCJnZXRFeHRlbnQiLCJmaWVsZCIsIl90aGlzJGFjY2Vzc29yczIiLCJnZXRSb3dWYWx1ZSIsImFjY2Vzc29yIiwibWluIiwiSW5maW5pdHkiLCJtYXgiLCJfaXRlcmF0b3IiLCJfc3RlcCIsInRpbGUiLCJleHRlbnQiLCJnZXRUaWxlU3RhdCIsImdldFRpbGVFeHRlbnQiLCJzZXRUaWxlU3RhdCIsImVyciIsIk51bWJlciIsImlzRmluaXRlIiwiZ2V0UXVhbnRpbGVTYW1wbGUiLCJtaW5Sb3dDb3VudCIsImFyZ3VtZW50cyIsInVuZGVmaW5lZCIsInNldCIsInNhbXBsZSIsInNhbXBsZVN0ZXAiLCJNYXRoIiwiZmxvb3IiLCJyb3dDb3VudCIsImkiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwicm93IiwidmFsIiwicHVzaCIsInF1aWNrSW5zZXJ0aW9uU29ydCIsInBydW5lUXVhbnRpbGVzIiwiZ2V0VW5pcXVlVmFsdWVzIiwiX3RoaXMkYWNjZXNzb3JzMyIsInVuaXF1ZXMiLCJfaXRlcmF0b3IzIiwiX3N0ZXAzIiwiX3RpbGVVbmlxdWVzIiwidGlsZVVuaXF1ZXMiLCJnZXRUaWxlVW5pcXVlVmFsdWVzIiwiX2l0ZXJhdG9yNCIsIl9zdGVwNCIsImFkZCIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJzdGF0IiwiX3RoaXMkdGlsZVN0YXRzJGdldCIsInRpbGVTdGF0cyIsImdldCIsIl90aGlzJHRpbGVTdGF0cyRnZXQyIiwiX3RpbGVTdGF0cyRnZXQiLCJ0aWxlSWQiLCJ0aWxlRmllbGRTdGF0cyIsIml0ZXJhYmxlIiwiX2l0ZXJhdG9yNSIsIl9zdGVwNSIsIm1heFVuaXF1ZXMiLCJfaXRlcmF0b3I2IiwiX3N0ZXA2Iiwic2l6ZSIsImIiLCJfaXRlcmF0b3I3IiwiX3N0ZXA3IiwiaGFzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3ZlY3Rvci10aWxlL2NvbW1vbi10aWxlL3RpbGUtZGF0YXNldC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0ZpZWxkIGFzIEtlcGxlckZpZWxkfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB7cXVpY2tJbnNlcnRpb25Tb3J0fSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IEl0ZXJhYmxlVGlsZVNldCwge1Jvd0NvdW50QWNjZXNzb3J9IGZyb20gJy4vaXRlcmFibGUtdGlsZS1zZXQnO1xuaW1wb3J0IHtwcnVuZVF1YW50aWxlc30gZnJvbSAnLi90aWxlLXV0aWxzJztcblxuZXhwb3J0IHR5cGUgRGF0dW0gPSBudW1iZXIgfCBzdHJpbmcgfCBudWxsO1xuXG50eXBlIFJvd1ZhbHVlQWNjZXNzb3I8VD4gPSAoXG4gIGZpZWxkOiBLZXBsZXJGaWVsZCxcbiAgcm93OiBUIGV4dGVuZHMgSXRlcmFibGU8aW5mZXIgVj4gPyBWIDogbmV2ZXJcbikgPT4gRGF0dW07XG50eXBlIFJvd1ZhbHVlQWNjZXNzb3JGYWN0b3J5PFQ+ID0gKFxuICBmaWVsZD86IEtlcGxlckZpZWxkLFxuICBpbmRleEtleT86IG51bWJlciB8IG51bGxcbikgPT4gUm93VmFsdWVBY2Nlc3NvcjxUPjtcblxudHlwZSBUaWxlQWNjZXNzb3JzPFQsIEkgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+ID0gVCBleHRlbmRzIEl0ZXJhYmxlPGFueT4gPyBUIDogbmV2ZXI+ID0ge1xuICBnZXRUaWxlSWQ6ICh0aWxlOiBUKSA9PiBzdHJpbmc7XG4gIGdldEl0ZXJhYmxlOiAodGlsZTogVCkgPT4gSTtcbiAgZ2V0Um93Q291bnQ6IFJvd0NvdW50QWNjZXNzb3I8ST47XG4gIGdldFJvd1ZhbHVlOiBSb3dWYWx1ZUFjY2Vzc29yRmFjdG9yeTxJPjtcbn07XG5cbi8qKlxuICogUGVyLXRpbGUgc3RhdHMsIGZvciBjYWNoaW5nXG4gKi9cbnR5cGUgVGlsZUZpZWxkU3RhdHMgPSB7XG4gIGV4dGVudD86IFtudW1iZXIsIG51bWJlcl07XG4gIHNhbXBsZT86IERhdHVtW107XG4gIHVuaXF1ZVZhbHVlcz86IFNldDxEYXR1bT47XG59O1xuXG4vKipcbiAqIFN0YXRlZnVsIGNsYXNzIG9mZmVyaW5nIGRhdGFzZXQtc3R5bGUgZnVuY3Rpb25zIGZvciB0aGUgc2V0IG9mIHRpbGVzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaWxlRGF0YXNldDxULCBJIGV4dGVuZHMgSXRlcmFibGU8YW55PiA9IFQgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+ID8gVCA6IG5ldmVyPiB7XG4gIHByaXZhdGUgYWNjZXNzb3JzOiBUaWxlQWNjZXNzb3JzPFQsIEk+O1xuICBwcml2YXRlIHRpbGVzOiByZWFkb25seSBUW107XG4gIHByaXZhdGUgdGlsZVNldDogSXRlcmFibGVUaWxlU2V0PEk+O1xuICBwcml2YXRlIHRpbGVJZHM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gIC8qKiBDYWNoZSBmb3IgcGVyLXRpbGUgZmllbGQgc3RhdHM6IHRpbGVJZCAtPiBmaWVsZElkIC0+IHN0YXRzICovXG4gIHByaXZhdGUgdGlsZVN0YXRzOiBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBUaWxlRmllbGRTdGF0cz4+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKGFjY2Vzc29yczogVGlsZUFjY2Vzc29yczxULCBJPiwgdGlsZXM/OiByZWFkb25seSBUW10pIHtcbiAgICB0aGlzLmFjY2Vzc29ycyA9IGFjY2Vzc29ycztcbiAgICB0aGlzLnRpbGVzID0gW107XG4gICAgdGhpcy50aWxlU2V0ID0gbmV3IEl0ZXJhYmxlVGlsZVNldChbXSwgYWNjZXNzb3JzLmdldFJvd0NvdW50KTtcbiAgICBpZiAodGlsZXMpIHtcbiAgICAgIHRoaXMudXBkYXRlVGlsZXModGlsZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZhbGlkYXRlIHRoZSBjYWNoZWQgZGF0YVxuICAgKi9cbiAgaW52YWxpZGF0ZUNhY2hlKCk6IHZvaWQge1xuICAgIC8vIFRPRE86IGltcGxlbWVudCBsYXRlclxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgc2V0IG9mIHRpbGVzIGluIHRoZSB2aWV3cG9ydFxuICAgKi9cbiAgdXBkYXRlVGlsZXModGlsZXM6IHJlYWRvbmx5IFRbXSk6IHZvaWQge1xuICAgIGNvbnN0IHtnZXRUaWxlSWQsIGdldEl0ZXJhYmxlLCBnZXRSb3dDb3VudH0gPSB0aGlzLmFjY2Vzc29ycztcbiAgICBjb25zdCB0aWxlSWRzID0gbmV3IFNldDxzdHJpbmc+KHRpbGVzLm1hcChnZXRUaWxlSWQpKTtcbiAgICBpZiAoIWFyZUVxdWFsU2V0cyh0aWxlSWRzLCB0aGlzLnRpbGVJZHMpKSB7XG4gICAgICB0aGlzLmludmFsaWRhdGVDYWNoZSgpO1xuICAgIH1cbiAgICB0aGlzLnRpbGVzID0gdGlsZXM7XG4gICAgdGhpcy50aWxlSWRzID0gdGlsZUlkcztcbiAgICB0aGlzLnRpbGVTZXQgPSBuZXcgSXRlcmFibGVUaWxlU2V0KHRpbGVzLm1hcChnZXRJdGVyYWJsZSksIGdldFJvd0NvdW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gY3VycmVudCB0aWxlc1xuICAgKi9cbiAgZ2V0VGlsZXMoKTogcmVhZG9ubHkgVFtdIHtcbiAgICByZXR1cm4gdGhpcy50aWxlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbi9tYXggZG9tYWluIG9mIGEgZmllbGRcbiAgICovXG4gIGdldEV4dGVudChmaWVsZDogS2VwbGVyRmllbGQpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCB7Z2V0Um93VmFsdWUsIGdldEl0ZXJhYmxlfSA9IHRoaXMuYWNjZXNzb3JzO1xuICAgIGNvbnN0IGFjY2Vzc29yID0gZ2V0Um93VmFsdWUoZmllbGQpO1xuICAgIGxldCBtaW4gPSBJbmZpbml0eTtcbiAgICBsZXQgbWF4ID0gLUluZmluaXR5O1xuXG4gICAgZm9yIChjb25zdCB0aWxlIG9mIHRoaXMudGlsZXMpIHtcbiAgICAgIC8vIENoZWNrIHRoZSBjYWNoZVxuICAgICAgbGV0IGV4dGVudCA9IHRoaXMuZ2V0VGlsZVN0YXQodGlsZSwgZmllbGQsICdleHRlbnQnKTtcbiAgICAgIGlmICghZXh0ZW50KSB7XG4gICAgICAgIC8vIENhY2hlIG1pc3MsIGNhbGN1bGF0ZSBhbmQgY2FjaGVcbiAgICAgICAgZXh0ZW50ID0gZ2V0VGlsZUV4dGVudChnZXRJdGVyYWJsZSh0aWxlKSwgZmllbGQsIGFjY2Vzc29yKTtcbiAgICAgICAgdGhpcy5zZXRUaWxlU3RhdCh0aWxlLCBmaWVsZCwgJ2V4dGVudCcsIGV4dGVudCk7XG4gICAgICB9XG4gICAgICBpZiAoZXh0ZW50KSB7XG4gICAgICAgIGlmIChleHRlbnRbMF0gPCBtaW4pIG1pbiA9IGV4dGVudFswXTtcbiAgICAgICAgaWYgKGV4dGVudFsxXSA+IG1heCkgbWF4ID0gZXh0ZW50WzFdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG1pbikgJiYgTnVtYmVyLmlzRmluaXRlKG1heCkgPyBbbWluLCBtYXhdIDogWzAsIDBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHNhbXBsZSBvZiBmaWVsZCB2YWx1ZXMgdG8gdXNlIGluIGVzdGltYXRpbmcgcXVhbnRpbGVzXG4gICAqL1xuICBnZXRRdWFudGlsZVNhbXBsZShmaWVsZDogS2VwbGVyRmllbGQsIG1pblJvd0NvdW50ID0gMTAwMCk6IG51bWJlcltdIHtcbiAgICAvLyBUT0RPOiBUaGVyZSBzaG91bGQgYmUgcmVhc29uYWJsZSBwZXItdGlsZSBjYWNoaW5nIHBvc3NpYmxlIGhlcmVcbiAgICBjb25zdCBzZXQgPSB0aGlzLnRpbGVTZXQ7XG4gICAgY29uc3QgYWNjZXNzb3IgPSB0aGlzLmFjY2Vzc29ycy5nZXRSb3dWYWx1ZShmaWVsZCk7XG4gICAgY29uc3Qgc2FtcGxlOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IHNhbXBsZVN0ZXAgPSBNYXRoLm1heChNYXRoLmZsb29yKHNldC5yb3dDb3VudCAvIG1pblJvd0NvdW50KSwgMSk7XG4gICAgbGV0IGkgPSAwO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHNldCkge1xuICAgICAgaWYgKCsraSA9PT0gc2FtcGxlU3RlcCkge1xuICAgICAgICBjb25zdCB2YWwgPSBhY2Nlc3NvcihmaWVsZCwgcm93KSBhcyBudW1iZXIgfCBudWxsO1xuICAgICAgICBpZiAodmFsICE9PSBudWxsKSBzYW1wbGUucHVzaCh2YWwpO1xuICAgICAgICBpID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgcXVpY2tJbnNlcnRpb25Tb3J0KHNhbXBsZSk7XG4gICAgcHJ1bmVRdWFudGlsZXMoc2FtcGxlKTtcbiAgICByZXR1cm4gc2FtcGxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHNldCBvZiB1bmlxdWUgdmFsdWVzIGZvciBhIGZpZWxkXG4gICAqL1xuICBnZXRVbmlxdWVWYWx1ZXMoZmllbGQ6IEtlcGxlckZpZWxkKTogRGF0dW1bXSB7XG4gICAgY29uc3Qge2dldFJvd1ZhbHVlLCBnZXRJdGVyYWJsZX0gPSB0aGlzLmFjY2Vzc29ycztcbiAgICBjb25zdCBhY2Nlc3NvciA9IGdldFJvd1ZhbHVlKGZpZWxkKTtcbiAgICBjb25zdCB1bmlxdWVzID0gbmV3IFNldDxEYXR1bT4oKTtcblxuICAgIGZvciAoY29uc3QgdGlsZSBvZiB0aGlzLnRpbGVzKSB7XG4gICAgICAvLyBDaGVjayB0aGUgY2FjaGVcbiAgICAgIGxldCB0aWxlVW5pcXVlcyA9IHRoaXMuZ2V0VGlsZVN0YXQodGlsZSwgZmllbGQsICd1bmlxdWVWYWx1ZXMnKTtcbiAgICAgIGlmICghdGlsZVVuaXF1ZXMpIHtcbiAgICAgICAgLy8gQ2FjaGUgbWlzcywgY2FsY3VsYXRlIGFuZCBjYWNoZVxuICAgICAgICB0aWxlVW5pcXVlcyA9IGdldFRpbGVVbmlxdWVWYWx1ZXMoZ2V0SXRlcmFibGUodGlsZSksIGZpZWxkLCBhY2Nlc3Nvcik7XG4gICAgICAgIHRoaXMuc2V0VGlsZVN0YXQodGlsZSwgZmllbGQsICd1bmlxdWVWYWx1ZXMnLCB0aWxlVW5pcXVlcyk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aWxlVW5pcXVlcyA/PyBbXSkge1xuICAgICAgICB1bmlxdWVzLmFkZCh2YWwpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gWy4uLnVuaXF1ZXNdO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUaWxlU3RhdDxLIGV4dGVuZHMga2V5b2YgVGlsZUZpZWxkU3RhdHM+KFxuICAgIHRpbGU6IFQsXG4gICAgZmllbGQ6IEtlcGxlckZpZWxkLFxuICAgIHN0YXQ6IEtcbiAgKTogVGlsZUZpZWxkU3RhdHNbS10ge1xuICAgIHJldHVybiB0aGlzLnRpbGVTdGF0cy5nZXQodGhpcy5hY2Nlc3NvcnMuZ2V0VGlsZUlkKHRpbGUpKT8uZ2V0KGZpZWxkLm5hbWUpPy5bc3RhdF07XG4gIH1cblxuICBwcml2YXRlIHNldFRpbGVTdGF0PEsgZXh0ZW5kcyBrZXlvZiBUaWxlRmllbGRTdGF0cz4oXG4gICAgdGlsZTogVCxcbiAgICBmaWVsZDogS2VwbGVyRmllbGQsXG4gICAgc3RhdDogSyxcbiAgICB2YWx1ZTogVGlsZUZpZWxkU3RhdHNbS11cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgdGlsZUlkID0gdGhpcy5hY2Nlc3NvcnMuZ2V0VGlsZUlkKHRpbGUpO1xuICAgIGNvbnN0IHRpbGVTdGF0cyA9IHRoaXMudGlsZVN0YXRzLmdldCh0aWxlSWQpID8/IG5ldyBNYXAoKTtcbiAgICBjb25zdCB0aWxlRmllbGRTdGF0cyA9IHRpbGVTdGF0cy5nZXQoZmllbGQubmFtZSkgPz8ge307XG4gICAgdGlsZUZpZWxkU3RhdHNbc3RhdF0gPSB2YWx1ZTtcbiAgICB0aWxlU3RhdHMuc2V0KGZpZWxkLm5hbWUsIHRpbGVGaWVsZFN0YXRzKTtcbiAgICB0aGlzLnRpbGVTdGF0cy5zZXQodGlsZUlkLCB0aWxlU3RhdHMpO1xuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBtaW4vbWF4IGRvbWFpbiBvZiBhIGZpZWxkIGluIGEgZ2l2ZW4gdGlsZVxuICovXG5mdW5jdGlvbiBnZXRUaWxlRXh0ZW50PEkgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+PihcbiAgaXRlcmFibGU6IEksXG4gIGZpZWxkOiBLZXBsZXJGaWVsZCxcbiAgYWNjZXNzb3I6IFJvd1ZhbHVlQWNjZXNzb3I8ST5cbik6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQge1xuICBsZXQgbWluID0gSW5maW5pdHk7XG4gIGxldCBtYXggPSAtSW5maW5pdHk7XG4gIGZvciAoY29uc3Qgcm93IG9mIGl0ZXJhYmxlKSB7XG4gICAgY29uc3QgdmFsID0gYWNjZXNzb3IoZmllbGQsIHJvdykgYXMgbnVtYmVyIHwgbnVsbDtcbiAgICBpZiAodmFsID09PSBudWxsKSBjb250aW51ZTtcbiAgICBpZiAodmFsIDwgbWluKSBtaW4gPSB2YWw7XG4gICAgaWYgKHZhbCA+IG1heCkgbWF4ID0gdmFsO1xuICB9XG4gIHJldHVybiBOdW1iZXIuaXNGaW5pdGUobWluKSAmJiBOdW1iZXIuaXNGaW5pdGUobWF4KSA/IFttaW4sIG1heF0gOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2V0IHVuaXF1ZSB2YWx1ZXMgZm9yIGEgZmllbGQgaW4gYSBnaXZlbiB0aWxlXG4gKi9cbmZ1bmN0aW9uIGdldFRpbGVVbmlxdWVWYWx1ZXM8SSBleHRlbmRzIEl0ZXJhYmxlPGFueT4+KFxuICBpdGVyYWJsZTogSSxcbiAgZmllbGQ6IEtlcGxlckZpZWxkLFxuICBhY2Nlc3NvcjogUm93VmFsdWVBY2Nlc3NvcjxJPixcbiAgbWF4VW5pcXVlcyA9IDIwXG4pOiBTZXQ8RGF0dW0+IHtcbiAgY29uc3QgdW5pcXVlcyA9IG5ldyBTZXQ8RGF0dW0+KCk7XG4gIGZvciAoY29uc3Qgcm93IG9mIGl0ZXJhYmxlKSB7XG4gICAgaWYgKHVuaXF1ZXMuc2l6ZSA+PSBtYXhVbmlxdWVzKSByZXR1cm4gdW5pcXVlcztcbiAgICB1bmlxdWVzLmFkZChhY2Nlc3NvcihmaWVsZCwgcm93KSk7XG4gIH1cbiAgcmV0dXJuIHVuaXF1ZXM7XG59XG5cbmZ1bmN0aW9uIGFyZUVxdWFsU2V0cyhhOiBTZXQ8c3RyaW5nPiwgYjogU2V0PHN0cmluZz4pOiBib29sZWFuIHtcbiAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSByZXR1cm4gZmFsc2U7XG4gIGZvciAoY29uc3QgdmFsIG9mIGEpIHtcbiAgICBpZiAoIWIuaGFzKHZhbCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBSUEsSUFBQUEsTUFBQSxH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