UNPKG

kepler.gl

Version:

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

386 lines (383 loc) 53.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.commonTileVisConfigs = exports.DEFAULT_RADIUS = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = _interopRequireDefault(require("lodash.throttle")); var _commonUtils = require("@kepler.gl/common-utils"); var _constants = require("@kepler.gl/constants"); var _table = require("@kepler.gl/table"); var _utils = require("@kepler.gl/utils"); var _baseLayer = _interopRequireDefault(require("../base-layer")); var _tileUtils = require("./common-tile/tile-utils"); function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _superPropGet(t, e, r, o) { var p = (0, _get2["default"])((0, _getPrototypeOf2["default"])(1 & o ? t.prototype : t), e, r); return 2 & o ? function (t) { return p.apply(r, t); } : p; } 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 DEFAULT_ELEVATION = 500; var DEFAULT_RADIUS = exports.DEFAULT_RADIUS = 1; var commonTileVisConfigs = exports.commonTileVisConfigs = { strokeColor: 'strokeColor', strokeOpacity: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.opacity), {}, { property: 'strokeOpacity' }), radius: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.radius), {}, { range: [0.1, 100], step: 0.1, defaultValue: DEFAULT_RADIUS, allowCustomValue: false }), radiusUnits: { type: 'boolean', defaultValue: true, label: 'Radius in pixels', group: '', property: 'radiusUnits', description: 'Radius in pixels or in meters' }, enable3d: 'enable3d', stroked: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.stroked), {}, { defaultValue: false }), transition: { type: 'boolean', defaultValue: false, label: 'Transition', group: '', property: 'transition', description: 'Smoother transition during animation (enable transition will decrease performance)' }, heightRange: 'elevationRange', elevationScale: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.elevationScale), {}, { allowCustomValue: false }), opacity: 'opacity', colorRange: 'colorRange', // TODO: figure out type for radiusByZoom vis config radiusByZoom: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.radius), {}, { defaultValue: { enabled: false, stops: null } }), dynamicColor: { type: 'boolean', defaultValue: false, label: 'Dynamic Color', group: '', property: 'dynamicColor', description: 'Use a dynamic color scale based on data visible in the viewport' } }; /** * Abstract tile layer, including common functionality for viewport-based datasets, * dynamic scales, and tile-based animation */ var AbstractTileLayer = exports["default"] = /*#__PURE__*/function (_KeplerLayer) { function AbstractTileLayer(props) { var _this; (0, _classCallCheck2["default"])(this, AbstractTileLayer); _this = _callSuper(this, AbstractTileLayer, [props]); (0, _defineProperty2["default"])(_this, "tileDataset", void 0); (0, _defineProperty2["default"])(_this, "setLayerDomain", undefined); /** * Callback to invoke when the viewport changes */ (0, _defineProperty2["default"])(_this, "onViewportLoad", function (tiles) { _this.tileDataset.updateTiles(tiles); // Update dynamic color domain if required if (_this.config.visConfig.dynamicColor) { _this.setDynamicColorDomain(); } }); (0, _defineProperty2["default"])(_this, "setDynamicColorDomain", (0, _lodash["default"])(function () { var _this2 = _this, config = _this2.config, tileDataset = _this2.tileDataset, setLayerDomain = _this2.setLayerDomain; var field = config.colorField; var colorDomain = config.colorDomain, colorScale = config.colorScale; if (!tileDataset || !setLayerDomain || !field) return; if (colorScale === _constants.SCALE_TYPES.quantize) { var _tileDataset$getExten = tileDataset.getExtent(field), _tileDataset$getExten2 = (0, _slicedToArray2["default"])(_tileDataset$getExten, 2), min = _tileDataset$getExten2[0], max = _tileDataset$getExten2[1]; if (!Array.isArray(colorDomain) || min !== colorDomain[0] || max !== colorDomain[1]) { setLayerDomain({ domain: [min, max] }); } } else if (colorScale === _constants.SCALE_TYPES.quantile) { var domain = tileDataset.getQuantileSample(field); setLayerDomain({ domain: domain }); } else if (colorScale === _constants.SCALE_TYPES.ordinal) { var _domain = tileDataset.getUniqueValues(field); setLayerDomain({ domain: _domain }); } }, 500)); _this.registerVisConfig(commonTileVisConfigs); _this.tileDataset = _this.initTileDataset(); return _this; } (0, _inherits2["default"])(AbstractTileLayer, _KeplerLayer); return (0, _createClass2["default"])(AbstractTileLayer, [{ key: "requireData", get: function get() { return true; } }, { key: "requiredLayerColumns", get: function get() { return []; } }, { key: "visualChannels", get: function get() { return { color: _objectSpread(_objectSpread({}, _superPropGet(AbstractTileLayer, "visualChannels", this, 1).color), {}, { accessor: 'getFillColor', defaultValue: function defaultValue(config) { return config.color; } }), height: { property: 'height', field: 'heightField', scale: 'heightScale', domain: 'heightDomain', range: 'heightRange', key: 'height', channelScaleType: 'size', accessor: 'getElevation', condition: function condition(config) { return config.visConfig.enable3d; }, nullValue: 0, defaultValue: DEFAULT_ELEVATION } }; } }, { key: "accessVSFieldValue", value: function accessVSFieldValue(inputField, indexKey) { return this.accessRowValue(inputField, indexKey); } }, { key: "getScaleOptions", value: function getScaleOptions(channelKey) { if (channelKey === 'color') { var _field$filterProps; var channel = this.visualChannels.color; var _field = this.config[channel.field]; if ((0, _tileUtils.isDomainQuantiles)(_field === null || _field === void 0 || (_field$filterProps = _field.filterProps) === null || _field$filterProps === void 0 ? void 0 : _field$filterProps.domainQuantiles) || this.config.visConfig.dynamicColor || // If we've set the scale to quantile, we need to include it - there's a loading // period in which the visConfig isn't set yet, but if we don't return the right // scale type we lose it this.config.colorScale === _constants.SCALE_TYPES.quantile) { return [_constants.SCALE_TYPES.quantize, _constants.SCALE_TYPES.quantile, _constants.SCALE_TYPES.custom]; } return [_constants.SCALE_TYPES.quantize, _constants.SCALE_TYPES.custom]; } return [_constants.SCALE_TYPES.linear]; } }, { key: "resetColorDomain", value: function resetColorDomain() { var _this$setLayerDomain; var _this$meta = this.meta, datasetId = _this$meta.datasetId, datasets = _this$meta.datasets; this.updateLayerVisualChannel(datasets === null || datasets === void 0 ? void 0 : datasets[datasetId || ''], 'color'); (_this$setLayerDomain = this.setLayerDomain) === null || _this$setLayerDomain === void 0 || _this$setLayerDomain.call(this, { domain: this.config.colorDomain }); } }, { key: "updateLayerConfig", value: function updateLayerConfig(newConfig) { var _this$config$visConfi, _newConfig$visConfig$, _newConfig$visConfig, _this3 = this; // When the dynamic color setting changes, we need to recalculate the layer domain var old = (_this$config$visConfi = this.config.visConfig.dynamicColor) !== null && _this$config$visConfi !== void 0 ? _this$config$visConfi : false; var next = (_newConfig$visConfig$ = (_newConfig$visConfig = newConfig.visConfig) === null || _newConfig$visConfig === void 0 ? void 0 : _newConfig$visConfig.dynamicColor) !== null && _newConfig$visConfig$ !== void 0 ? _newConfig$visConfig$ : old; var scaleTypeChanged = newConfig.colorScale && this.config.colorScale !== newConfig.colorScale; _superPropGet(AbstractTileLayer, "updateLayerConfig", this, 3)([newConfig]); var colorField = this.config.colorField; if (colorField) { // When we switch from dynamic to non-dynamic or vice versa, we need to update // the color domain. This is downstream from a dispatch call, so we use // setTimeout to avoid "reducers may not dispatch actions" errors if (next && (!old || scaleTypeChanged)) { setTimeout(function () { return _this3.setDynamicColorDomain(); }, 0); } else if (old && !next) { setTimeout(function () { return _this3.resetColorDomain(); }, 0); } } return this; } }, { key: "animationDomain", get: function get() { return this.config.animation.domain; } }, { key: "setInitialLayerConfig", value: function setInitialLayerConfig(dataset) { var defaultColorField = (0, _utils.findDefaultColorField)(dataset); if (defaultColorField) { this.updateLayerConfig({ colorField: defaultColorField }); this.updateLayerVisualChannel(dataset, 'color'); } return this; } }, { key: "getDefaultLayerConfig", value: function getDefaultLayerConfig(props) { return _objectSpread(_objectSpread({}, _superPropGet(AbstractTileLayer, "getDefaultLayerConfig", this, 3)([props])), {}, { colorScale: _constants.SCALE_TYPES.quantize, // add height visual channel heightField: null, heightDomain: [0, 1], heightScale: 'linear' }); } // We can render without columns, so we redefine this method }, { key: "shouldRenderLayer", value: function shouldRenderLayer() { return Boolean(this.type && this.config.isVisible); } }, { key: "updateAnimationDomainByField", value: function updateAnimationDomainByField(channel) { var field = this.config[this.visualChannels[channel].field]; if ((0, _tileUtils.isIndexedField)(field) && field.indexBy.type === _constants.ALL_FIELD_TYPES.timestamp) { var timeDomain = field.indexBy.timeDomain; this.updateLayerConfig({ animation: _objectSpread(_objectSpread({}, timeDomain), {}, { enabled: true, startTime: timeDomain.domain[0] }) }); } } }, { key: "updateAnimationDomain", value: function updateAnimationDomain(domain) { this.updateLayerConfig({ animation: _objectSpread(_objectSpread({}, this.config.animation), {}, { domain: domain }) }); } }, { key: "updateLayerDomain", value: function updateLayerDomain(datasets, newFilter) { var _this4 = this; _superPropGet(AbstractTileLayer, "updateLayerDomain", this, 3)([datasets, newFilter]); if (newFilter) { // invalidate cachedVisibleDataset when e.g. changing filters this.tileDataset.invalidateCache(); } Object.keys(this.visualChannels).forEach(function (channel) { _this4.updateAnimationDomainByField(channel); }); return this; } }, { key: "updateLayerVisualChannel", value: function updateLayerVisualChannel(dataset, channel) { _superPropGet(AbstractTileLayer, "updateLayerVisualChannel", this, 3)([dataset, channel]); // create animation if field is indexed by time this.updateAnimationDomainByField(channel); } }, { key: "formatLayerData", value: function formatLayerData(datasets, oldLayerData, animationConfig) { var dataId = this.config.dataId; if (!(0, _commonUtils.notNullorUndefined)(dataId)) { return {}; } var dataset = datasets[dataId]; var dataUpdateTriggers = this.getDataUpdateTriggers(dataset); var triggerChanged = this.getChangedTriggers(dataUpdateTriggers); if (triggerChanged && triggerChanged.getMeta) { this.updateLayerMeta(dataset, datasets); } var indexKey = this.config.animation.enabled ? animationConfig.currentTime : null; var accessors = this.getAttributeAccessors({ dataAccessor: function dataAccessor() { return function (d) { return d; }; }, dataContainer: dataset.dataContainer, indexKey: indexKey }); var metadata = dataset === null || dataset === void 0 ? void 0 : dataset.metadata; var metadataToData = metadata ? { minZoom: metadata.minZoom, maxZoom: metadata.maxZoom, bounds: metadata.bounds } : {}; return _objectSpread(_objectSpread({}, metadataToData), accessors); } }, { key: "getGpuFilterValueAccessor", value: function getGpuFilterValueAccessor(_ref) { var _this5 = this; var gpuFilter = _ref.gpuFilter, animationConfig = _ref.animationConfig; var indexKey = this.config.animation.enabled ? animationConfig.currentTime : null; var valueAccessor = function valueAccessor(dataContainer, d) { return function (field) { return _this5.accessVSFieldValue(field, indexKey)(field, d); }; }; return gpuFilter.filterValueAccessor(null)(undefined, valueAccessor); } }], [{ key: "findDefaultLayerProps", value: function findDefaultLayerProps(dataset) { if (!(0, _table.isTileDataset)(dataset)) { return { props: [] }; } var newLayerProp = { dataId: dataset.id, label: dataset.label, isVisible: true }; return { props: [newLayerProp] }; } }]); }(_baseLayer["default"]); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfY29tbW9uVXRpbHMiLCJfY29uc3RhbnRzIiwiX3RhYmxlIiwiX3V0aWxzIiwiX2Jhc2VMYXllciIsIl90aWxlVXRpbHMiLCJfY2FsbFN1cGVyIiwidCIsIm8iLCJlIiwiX2dldFByb3RvdHlwZU9mMiIsIl9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMiIsIl9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QiLCJSZWZsZWN0IiwiY29uc3RydWN0IiwiY29uc3RydWN0b3IiLCJhcHBseSIsIkJvb2xlYW4iLCJwcm90b3R5cGUiLCJ2YWx1ZU9mIiwiY2FsbCIsIl9zdXBlclByb3BHZXQiLCJyIiwicCIsIl9nZXQyIiwib3duS2V5cyIsIk9iamVjdCIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJERUZBVUxUX0VMRVZBVElPTiIsIkRFRkFVTFRfUkFESVVTIiwiZXhwb3J0cyIsImNvbW1vblRpbGVWaXNDb25maWdzIiwic3Ryb2tlQ29sb3IiLCJzdHJva2VPcGFjaXR5IiwiTEFZRVJfVklTX0NPTkZJR1MiLCJvcGFjaXR5IiwicHJvcGVydHkiLCJyYWRpdXMiLCJyYW5nZSIsInN0ZXAiLCJkZWZhdWx0VmFsdWUiLCJhbGxvd0N1c3RvbVZhbHVlIiwicmFkaXVzVW5pdHMiLCJ0eXBlIiwibGFiZWwiLCJncm91cCIsImRlc2NyaXB0aW9uIiwiZW5hYmxlM2QiLCJzdHJva2VkIiwidHJhbnNpdGlvbiIsImhlaWdodFJhbmdlIiwiZWxldmF0aW9uU2NhbGUiLCJjb2xvclJhbmdlIiwicmFkaXVzQnlab29tIiwiZW5hYmxlZCIsInN0b3BzIiwiZHluYW1pY0NvbG9yIiwiQWJzdHJhY3RUaWxlTGF5ZXIiLCJfS2VwbGVyTGF5ZXIiLCJwcm9wcyIsIl90aGlzIiwiX2NsYXNzQ2FsbENoZWNrMiIsInVuZGVmaW5lZCIsInRpbGVzIiwidGlsZURhdGFzZXQiLCJ1cGRhdGVUaWxlcyIsImNvbmZpZyIsInZpc0NvbmZpZyIsInNldER5bmFtaWNDb2xvckRvbWFpbiIsInRocm90dGxlIiwiX3RoaXMyIiwic2V0TGF5ZXJEb21haW4iLCJmaWVsZCIsImNvbG9yRmllbGQiLCJjb2xvckRvbWFpbiIsImNvbG9yU2NhbGUiLCJTQ0FMRV9UWVBFUyIsInF1YW50aXplIiwiX3RpbGVEYXRhc2V0JGdldEV4dGVuIiwiZ2V0RXh0ZW50IiwiX3RpbGVEYXRhc2V0JGdldEV4dGVuMiIsIl9zbGljZWRUb0FycmF5MiIsIm1pbiIsIm1heCIsIkFycmF5IiwiaXNBcnJheSIsImRvbWFpbiIsInF1YW50aWxlIiwiZ2V0UXVhbnRpbGVTYW1wbGUiLCJvcmRpbmFsIiwiZ2V0VW5pcXVlVmFsdWVzIiwicmVnaXN0ZXJWaXNDb25maWciLCJpbml0VGlsZURhdGFzZXQiLCJfaW5oZXJpdHMyIiwiX2NyZWF0ZUNsYXNzMiIsImtleSIsImdldCIsImNvbG9yIiwiYWNjZXNzb3IiLCJoZWlnaHQiLCJzY2FsZSIsImNoYW5uZWxTY2FsZVR5cGUiLCJjb25kaXRpb24iLCJudWxsVmFsdWUiLCJ2YWx1ZSIsImFjY2Vzc1ZTRmllbGRWYWx1ZSIsImlucHV0RmllbGQiLCJpbmRleEtleSIsImFjY2Vzc1Jvd1ZhbHVlIiwiZ2V0U2NhbGVPcHRpb25zIiwiY2hhbm5lbEtleSIsIl9maWVsZCRmaWx0ZXJQcm9wcyIsImNoYW5uZWwiLCJ2aXN1YWxDaGFubmVscyIsImlzRG9tYWluUXVhbnRpbGVzIiwiZmlsdGVyUHJvcHMiLCJkb21haW5RdWFudGlsZXMiLCJjdXN0b20iLCJsaW5lYXIiLCJyZXNldENvbG9yRG9tYWluIiwiX3RoaXMkc2V0TGF5ZXJEb21haW4iLCJfdGhpcyRtZXRhIiwibWV0YSIsImRhdGFzZXRJZCIsImRhdGFzZXRzIiwidXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsIiwidXBkYXRlTGF5ZXJDb25maWciLCJuZXdDb25maWciLCJfdGhpcyRjb25maWckdmlzQ29uZmkiLCJfbmV3Q29uZmlnJHZpc0NvbmZpZyQiLCJfbmV3Q29uZmlnJHZpc0NvbmZpZyIsIl90aGlzMyIsIm9sZCIsIm5leHQiLCJzY2FsZVR5cGVDaGFuZ2VkIiwic2V0VGltZW91dCIsImFuaW1hdGlvbiIsInNldEluaXRpYWxMYXllckNvbmZpZyIsImRhdGFzZXQiLCJkZWZhdWx0Q29sb3JGaWVsZCIsImZpbmREZWZhdWx0Q29sb3JGaWVsZCIsImdldERlZmF1bHRMYXllckNvbmZpZyIsImhlaWdodEZpZWxkIiwiaGVpZ2h0RG9tYWluIiwiaGVpZ2h0U2NhbGUiLCJzaG91bGRSZW5kZXJMYXllciIsImlzVmlzaWJsZSIsInVwZGF0ZUFuaW1hdGlvbkRvbWFpbkJ5RmllbGQiLCJpc0luZGV4ZWRGaWVsZCIsImluZGV4QnkiLCJBTExfRklFTERfVFlQRVMiLCJ0aW1lc3RhbXAiLCJ0aW1lRG9tYWluIiwic3RhcnRUaW1lIiwidXBkYXRlQW5pbWF0aW9uRG9tYWluIiwidXBkYXRlTGF5ZXJEb21haW4iLCJuZXdGaWx0ZXIiLCJfdGhpczQiLCJpbnZhbGlkYXRlQ2FjaGUiLCJmb3JtYXRMYXllckRhdGEiLCJvbGRMYXllckRhdGEiLCJhbmltYXRpb25Db25maWciLCJkYXRhSWQiLCJub3ROdWxsb3JVbmRlZmluZWQiLCJkYXRhVXBkYXRlVHJpZ2dlcnMiLCJnZXREYXRhVXBkYXRlVHJpZ2dlcnMiLCJ0cmlnZ2VyQ2hhbmdlZCIsImdldENoYW5nZWRUcmlnZ2VycyIsImdldE1ldGEiLCJ1cGRhdGVMYXllck1ldGEiLCJjdXJyZW50VGltZSIsImFjY2Vzc29ycyIsImdldEF0dHJpYnV0ZUFjY2Vzc29ycyIsImRhdGFBY2Nlc3NvciIsImQiLCJkYXRhQ29udGFpbmVyIiwibWV0YWRhdGEiLCJtZXRhZGF0YVRvRGF0YSIsIm1pblpvb20iLCJtYXhab29tIiwiYm91bmRzIiwiZ2V0R3B1RmlsdGVyVmFsdWVBY2Nlc3NvciIsIl9yZWYiLCJfdGhpczUiLCJncHVGaWx0ZXIiLCJ2YWx1ZUFjY2Vzc29yIiwiZmlsdGVyVmFsdWVBY2Nlc3NvciIsImZpbmREZWZhdWx0TGF5ZXJQcm9wcyIsImlzVGlsZURhdGFzZXQiLCJuZXdMYXllclByb3AiLCJpZCIsIktlcGxlckxheWVyIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ZlY3Rvci10aWxlL2Fic3RyYWN0LXRpbGUtbGF5ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHRocm90dGxlIGZyb20gJ2xvZGFzaC50aHJvdHRsZSc7XG5cbmltcG9ydCB7bm90TnVsbG9yVW5kZWZpbmVkfSBmcm9tICdAa2VwbGVyLmdsL2NvbW1vbi11dGlscyc7XG5pbXBvcnQge1NDQUxFX1RZUEVTLCBBTExfRklFTERfVFlQRVMsIExBWUVSX1ZJU19DT05GSUdTfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge1xuICBpc1RpbGVEYXRhc2V0LFxuICBLZXBsZXJUYWJsZSBhcyBLZXBsZXJEYXRhc2V0LFxuICBEYXRhc2V0cyBhcyBLZXBsZXJEYXRhc2V0cyxcbiAgR3B1RmlsdGVyXG59IGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuaW1wb3J0IHtcbiAgQW5pbWF0aW9uQ29uZmlnLFxuICBGaWVsZCxcbiAgQmluZGVkTGF5ZXJDYWxsYmFja3MsXG4gIFZpc0NvbmZpZ0Jvb2xlYW4sXG4gIFZpc0NvbmZpZ1JhbmdlLFxuICBWaXNDb25maWdDb2xvclJhbmdlLFxuICBWaXNDb25maWdOdW1iZXIsXG4gIFZpc0NvbmZpZ0NvbG9yU2VsZWN0LFxuICBMYXllckNvbG9yQ29uZmlnLFxuICBMYXllckhlaWdodENvbmZpZyxcbiAgRmlsdGVyLFxuICBGaWVsZCBhcyBLZXBsZXJGaWVsZCxcbiAgTWFwU3RhdGUsXG4gIE1lcmdlLFxuICBab29tU3RvcHNDb25maWdcbn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge2ZpbmREZWZhdWx0Q29sb3JGaWVsZCwgRGF0YUNvbnRhaW5lckludGVyZmFjZX0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5cbmltcG9ydCB7XG4gIGRlZmF1bHQgYXMgS2VwbGVyTGF5ZXIsXG4gIExheWVyQmFzZUNvbmZpZyxcbiAgTGF5ZXJCYXNlQ29uZmlnUGFydGlhbCxcbiAgVmlzdWFsQ2hhbm5lbCxcbiAgVmlzdWFsQ2hhbm5lbERvbWFpbixcbiAgVmlzdWFsQ2hhbm5lbEZpZWxkXG59IGZyb20gJy4uL2Jhc2UtbGF5ZXInO1xuaW1wb3J0IFRpbGVEYXRhc2V0IGZyb20gJy4vY29tbW9uLXRpbGUvdGlsZS1kYXRhc2V0JztcbmltcG9ydCB7aXNJbmRleGVkRmllbGQsIGlzRG9tYWluUXVhbnRpbGVzfSBmcm9tICcuL2NvbW1vbi10aWxlL3RpbGUtdXRpbHMnO1xuaW1wb3J0IHtGaW5kRGVmYXVsdExheWVyUHJvcHNSZXR1cm5WYWx1ZX0gZnJvbSAnLi4vbGF5ZXItdXRpbHMnO1xuXG5jb25zdCBERUZBVUxUX0VMRVZBVElPTiA9IDUwMDtcbmV4cG9ydCBjb25zdCBERUZBVUxUX1JBRElVUyA9IDE7XG5cbmV4cG9ydCB0eXBlIEFic3RyYWN0VGlsZUxheWVyVmlzQ29uZmlnU2V0dGluZ3MgPSB7XG4gIHN0cm9rZUNvbG9yOiBWaXNDb25maWdDb2xvclNlbGVjdDtcbiAgc3Ryb2tlT3BhY2l0eTogVmlzQ29uZmlnTnVtYmVyO1xuICByYWRpdXM6IFZpc0NvbmZpZ051bWJlcjtcbiAgcmFkaXVzVW5pdHM6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIGVuYWJsZTNkOiBWaXNDb25maWdCb29sZWFuO1xuICBzdHJva2VkOiBWaXNDb25maWdCb29sZWFuO1xuICB0cmFuc2l0aW9uOiBWaXNDb25maWdCb29sZWFuO1xuICBoZWlnaHRSYW5nZTogVmlzQ29uZmlnUmFuZ2U7XG4gIGVsZXZhdGlvblNjYWxlOiBWaXNDb25maWdOdW1iZXI7XG4gIG9wYWNpdHk6IFZpc0NvbmZpZ051bWJlcjtcbiAgY29sb3JSYW5nZTogVmlzQ29uZmlnQ29sb3JSYW5nZTtcbiAgLy8gVE9ETzogZmlndXJlIG91dCB0eXBlIGZvciByYWRpdXNCeVpvb20gdmlzIGNvbmZpZ1xuICByYWRpdXNCeVpvb206IGFueTtcbiAgZHluYW1pY0NvbG9yOiBWaXNDb25maWdCb29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgTGF5ZXJEYXRhID0ge1xuICBtaW5ab29tPzogbnVtYmVyO1xuICBtYXhab29tPzogbnVtYmVyO1xuICBib3VuZHM/OiBudW1iZXJbXTtcbiAgZ2V0UG9pbnRSYWRpdXM/OiAoKSA9PiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBMYXllck9wdHMgPSB7XG4gIGlkeDogbnVtYmVyO1xuICBtYXBTdGF0ZTogTWFwU3RhdGU7XG4gIGRhdGE6IExheWVyRGF0YTtcbiAgZ3B1RmlsdGVyOiBHcHVGaWx0ZXI7XG4gIGFuaW1hdGlvbkNvbmZpZzogQW5pbWF0aW9uQ29uZmlnO1xuICB0aWxlc2V0RGF0YVVybD86IHN0cmluZyB8IG51bGw7XG4gIGxheWVyQ2FsbGJhY2tzOiBCaW5kZWRMYXllckNhbGxiYWNrcztcbn07XG5cbmV4cG9ydCBjb25zdCBjb21tb25UaWxlVmlzQ29uZmlncyA9IHtcbiAgc3Ryb2tlQ29sb3I6ICdzdHJva2VDb2xvcicgYXMgY29uc3QsXG4gIHN0cm9rZU9wYWNpdHk6IHtcbiAgICAuLi5MQVlFUl9WSVNfQ09ORklHUy5vcGFjaXR5LFxuICAgIHByb3BlcnR5OiAnc3Ryb2tlT3BhY2l0eSdcbiAgfSxcbiAgcmFkaXVzOiB7XG4gICAgLi4uTEFZRVJfVklTX0NPTkZJR1MucmFkaXVzLFxuICAgIHJhbmdlOiBbMC4xLCAxMDBdLFxuICAgIHN0ZXA6IDAuMSxcbiAgICBkZWZhdWx0VmFsdWU6IERFRkFVTFRfUkFESVVTLFxuICAgIGFsbG93Q3VzdG9tVmFsdWU6IGZhbHNlXG4gIH0gYXMgVmlzQ29uZmlnTnVtYmVyLFxuICByYWRpdXNVbml0czoge1xuICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICBkZWZhdWx0VmFsdWU6IHRydWUsXG4gICAgbGFiZWw6ICdSYWRpdXMgaW4gcGl4ZWxzJyxcbiAgICBncm91cDogJycsXG4gICAgcHJvcGVydHk6ICdyYWRpdXNVbml0cycsXG4gICAgZGVzY3JpcHRpb246ICdSYWRpdXMgaW4gcGl4ZWxzIG9yIGluIG1ldGVycydcbiAgfSBhcyBWaXNDb25maWdCb29sZWFuLFxuICBlbmFibGUzZDogJ2VuYWJsZTNkJyBhcyBjb25zdCxcbiAgc3Ryb2tlZDoge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLnN0cm9rZWQsXG4gICAgZGVmYXVsdFZhbHVlOiBmYWxzZVxuICB9LFxuICB0cmFuc2l0aW9uOiB7XG4gICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlZmF1bHRWYWx1ZTogZmFsc2UsXG4gICAgbGFiZWw6ICdUcmFuc2l0aW9uJyxcbiAgICBncm91cDogJycsXG4gICAgcHJvcGVydHk6ICd0cmFuc2l0aW9uJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdTbW9vdGhlciB0cmFuc2l0aW9uIGR1cmluZyBhbmltYXRpb24gKGVuYWJsZSB0cmFuc2l0aW9uIHdpbGwgZGVjcmVhc2UgcGVyZm9ybWFuY2UpJ1xuICB9IGFzIFZpc0NvbmZpZ0Jvb2xlYW4sXG4gIGhlaWdodFJhbmdlOiAnZWxldmF0aW9uUmFuZ2UnIGFzIGNvbnN0LFxuICBlbGV2YXRpb25TY2FsZTogey4uLkxBWUVSX1ZJU19DT05GSUdTLmVsZXZhdGlvblNjYWxlLCBhbGxvd0N1c3RvbVZhbHVlOiBmYWxzZX0sXG4gIG9wYWNpdHk6ICdvcGFjaXR5JyBhcyBjb25zdCxcbiAgY29sb3JSYW5nZTogJ2NvbG9yUmFuZ2UnIGFzIGNvbnN0LFxuICAvLyBUT0RPOiBmaWd1cmUgb3V0IHR5cGUgZm9yIHJhZGl1c0J5Wm9vbSB2aXMgY29uZmlnXG4gIHJhZGl1c0J5Wm9vbToge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLnJhZGl1cyxcbiAgICBkZWZhdWx0VmFsdWU6IHtcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgc3RvcHM6IG51bGxcbiAgICB9IGFzIFpvb21TdG9wc0NvbmZpZ1xuICB9IGFzIGFueSxcbiAgZHluYW1pY0NvbG9yOiB7XG4gICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlZmF1bHRWYWx1ZTogZmFsc2UsXG4gICAgbGFiZWw6ICdEeW5hbWljIENvbG9yJyxcbiAgICBncm91cDogJycsXG4gICAgcHJvcGVydHk6ICdkeW5hbWljQ29sb3InLFxuICAgIGRlc2NyaXB0aW9uOiAnVXNlIGEgZHluYW1pYyBjb2xvciBzY2FsZSBiYXNlZCBvbiBkYXRhIHZpc2libGUgaW4gdGhlIHZpZXdwb3J0J1xuICB9IGFzIFZpc0NvbmZpZ0Jvb2xlYW5cbn07XG5cbmV4cG9ydCB0eXBlIEFic3RyYWN0VGlsZUxheWVyQ29uZmlnID0gTWVyZ2U8XG4gIExheWVyQmFzZUNvbmZpZyxcbiAge2NvbG9yRmllbGQ/OiBWaXN1YWxDaGFubmVsRmllbGQ7IGNvbG9yU2NhbGU/OiBzdHJpbmc7IGNvbG9yRG9tYWluPzogVmlzdWFsQ2hhbm5lbERvbWFpbn1cbj47XG5cbi8qKlxuICogQWJzdHJhY3QgdGlsZSBsYXllciwgaW5jbHVkaW5nIGNvbW1vbiBmdW5jdGlvbmFsaXR5IGZvciB2aWV3cG9ydC1iYXNlZCBkYXRhc2V0cyxcbiAqIGR5bmFtaWMgc2NhbGVzLCBhbmQgdGlsZS1iYXNlZCBhbmltYXRpb25cbiAqL1xuZXhwb3J0IGRlZmF1bHQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RUaWxlTGF5ZXI8XG4gIC8vIFR5cGUgb2YgdGhlIHRpbGUgaXRzZWxmXG4gIFQsXG4gIC8vIFR5cGUgb2YgdGhlIGl0ZXJhYmxlIGRhdGEgb2JqZWN0XG4gIEkgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+ID0gVCBleHRlbmRzIEl0ZXJhYmxlPGFueT4gPyBUIDogbmV2ZXJcbj4gZXh0ZW5kcyBLZXBsZXJMYXllciB7XG4gIGRlY2xhcmUgY29uZmlnOiBBYnN0cmFjdFRpbGVMYXllckNvbmZpZztcbiAgZGVjbGFyZSB2aXNDb25maWdTZXR0aW5nczogQWJzdHJhY3RUaWxlTGF5ZXJWaXNDb25maWdTZXR0aW5ncztcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQ29uc3RydWN0b3JQYXJhbWV0ZXJzPHR5cGVvZiBLZXBsZXJMYXllcj5bMF0pIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5yZWdpc3RlclZpc0NvbmZpZyhjb21tb25UaWxlVmlzQ29uZmlncyk7XG4gICAgdGhpcy50aWxlRGF0YXNldCA9IHRoaXMuaW5pdFRpbGVEYXRhc2V0KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdGlsZURhdGFzZXQ6IFRpbGVEYXRhc2V0PFQsIEk+O1xuICBwcm90ZWN0ZWQgc2V0TGF5ZXJEb21haW46IEJpbmRlZExheWVyQ2FsbGJhY2tzWydvblNldExheWVyRG9tYWluJ10gPSB1bmRlZmluZWQ7XG5cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGluaXRUaWxlRGF0YXNldCgpOiBUaWxlRGF0YXNldDxULCBJPjtcblxuICBzdGF0aWMgZmluZERlZmF1bHRMYXllclByb3BzKGRhdGFzZXQ6IEtlcGxlckRhdGFzZXQpOiBGaW5kRGVmYXVsdExheWVyUHJvcHNSZXR1cm5WYWx1ZSB7XG4gICAgaWYgKCFpc1RpbGVEYXRhc2V0KGRhdGFzZXQpKSB7XG4gICAgICByZXR1cm4ge3Byb3BzOiBbXX07XG4gICAgfVxuXG4gICAgY29uc3QgbmV3TGF5ZXJQcm9wID0ge1xuICAgICAgZGF0YUlkOiBkYXRhc2V0LmlkLFxuICAgICAgbGFiZWw6IGRhdGFzZXQubGFiZWwsXG4gICAgICBpc1Zpc2libGU6IHRydWVcbiAgICB9O1xuXG4gICAgcmV0dXJuIHtwcm9wczogW25ld0xheWVyUHJvcF19O1xuICB9XG5cbiAgZ2V0IHJlcXVpcmVEYXRhKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZ2V0IHJlcXVpcmVkTGF5ZXJDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXQgdmlzdWFsQ2hhbm5lbHMoKTogUmVjb3JkPHN0cmluZywgVmlzdWFsQ2hhbm5lbD4ge1xuICAgIHJldHVybiB7XG4gICAgICBjb2xvcjoge1xuICAgICAgICAuLi5zdXBlci52aXN1YWxDaGFubmVscy5jb2xvcixcbiAgICAgICAgYWNjZXNzb3I6ICdnZXRGaWxsQ29sb3InLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IGNvbmZpZyA9PiBjb25maWcuY29sb3JcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgcHJvcGVydHk6ICdoZWlnaHQnLFxuICAgICAgICBmaWVsZDogJ2hlaWdodEZpZWxkJyxcbiAgICAgICAgc2NhbGU6ICdoZWlnaHRTY2FsZScsXG4gICAgICAgIGRvbWFpbjogJ2hlaWdodERvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnaGVpZ2h0UmFuZ2UnLFxuICAgICAgICBrZXk6ICdoZWlnaHQnLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiAnc2l6ZScsXG4gICAgICAgIGFjY2Vzc29yOiAnZ2V0RWxldmF0aW9uJyxcbiAgICAgICAgY29uZGl0aW9uOiBjb25maWcgPT4gY29uZmlnLnZpc0NvbmZpZy5lbmFibGUzZCxcbiAgICAgICAgbnVsbFZhbHVlOiAwLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IERFRkFVTFRfRUxFVkFUSU9OXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdmlld3BvcnQgY2hhbmdlc1xuICAgKi9cbiAgb25WaWV3cG9ydExvYWQgPSAodGlsZXM6IFRbXSk6IHZvaWQgPT4ge1xuICAgIHRoaXMudGlsZURhdGFzZXQudXBkYXRlVGlsZXModGlsZXMpO1xuICAgIC8vIFVwZGF0ZSBkeW5hbWljIGNvbG9yIGRvbWFpbiBpZiByZXF1aXJlZFxuICAgIGlmICh0aGlzLmNvbmZpZy52aXNDb25maWcuZHluYW1pY0NvbG9yKSB7XG4gICAgICB0aGlzLnNldER5bmFtaWNDb2xvckRvbWFpbigpO1xuICAgIH1cbiAgfTtcblxuICBhYnN0cmFjdCBhY2Nlc3NSb3dWYWx1ZShcbiAgICBmaWVsZD86IEtlcGxlckZpZWxkLFxuICAgIGluZGV4S2V5PzogbnVtYmVyIHwgbnVsbFxuICApOiAoZmllbGQ6IEtlcGxlckZpZWxkLCBkYXR1bTogVCBleHRlbmRzIEl0ZXJhYmxlPGluZmVyIFY+ID8gViA6IG5ldmVyKSA9PiBzdHJpbmcgfCBudW1iZXIgfCBudWxsO1xuXG4gIGFjY2Vzc1ZTRmllbGRWYWx1ZShpbnB1dEZpZWxkPzogRmllbGQsIGluZGV4S2V5PzogbnVtYmVyIHwgbnVsbCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuYWNjZXNzUm93VmFsdWUoaW5wdXRGaWVsZCwgaW5kZXhLZXkpO1xuICB9XG5cbiAgZ2V0U2NhbGVPcHRpb25zKGNoYW5uZWxLZXk6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICBpZiAoY2hhbm5lbEtleSA9PT0gJ2NvbG9yJykge1xuICAgICAgY29uc3QgY2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHMuY29sb3I7XG4gICAgICBjb25zdCBmaWVsZCA9IHRoaXMuY29uZmlnW2NoYW5uZWwuZmllbGRdO1xuXG4gICAgICBpZiAoXG4gICAgICAgIGlzRG9tYWluUXVhbnRpbGVzKGZpZWxkPy5maWx0ZXJQcm9wcz8uZG9tYWluUXVhbnRpbGVzKSB8fFxuICAgICAgICB0aGlzLmNvbmZpZy52aXNDb25maWcuZHluYW1pY0NvbG9yIHx8XG4gICAgICAgIC8vIElmIHdlJ3ZlIHNldCB0aGUgc2NhbGUgdG8gcXVhbnRpbGUsIHdlIG5lZWQgdG8gaW5jbHVkZSBpdCAtIHRoZXJlJ3MgYSBsb2FkaW5nXG4gICAgICAgIC8vIHBlcmlvZCBpbiB3aGljaCB0aGUgdmlzQ29uZmlnIGlzbid0IHNldCB5ZXQsIGJ1dCBpZiB3ZSBkb24ndCByZXR1cm4gdGhlIHJpZ2h0XG4gICAgICAgIC8vIHNjYWxlIHR5cGUgd2UgbG9zZSBpdFxuICAgICAgICB0aGlzLmNvbmZpZy5jb2xvclNjYWxlID09PSBTQ0FMRV9UWVBFUy5xdWFudGlsZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBbU0NBTEVfVFlQRVMucXVhbnRpemUsIFNDQUxFX1RZUEVTLnF1YW50aWxlLCBTQ0FMRV9UWVBFUy5jdXN0b21dO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtTQ0FMRV9UWVBFUy5xdWFudGl6ZSwgU0NBTEVfVFlQRVMuY3VzdG9tXTtcbiAgICB9XG5cbiAgICByZXR1cm4gW1NDQUxFX1RZUEVTLmxpbmVhcl07XG4gIH1cblxuICBzZXREeW5hbWljQ29sb3JEb21haW4gPSB0aHJvdHRsZSgoKTogdm9pZCA9PiB7XG4gICAgY29uc3Qge2NvbmZpZywgdGlsZURhdGFzZXQsIHNldExheWVyRG9tYWlufSA9IHRoaXM7XG4gICAgY29uc3QgZmllbGQgPSBjb25maWcuY29sb3JGaWVsZDtcbiAgICBjb25zdCB7Y29sb3JEb21haW4sIGNvbG9yU2NhbGV9ID0gY29uZmlnO1xuICAgIGlmICghdGlsZURhdGFzZXQgfHwgIXNldExheWVyRG9tYWluIHx8ICFmaWVsZCkgcmV0dXJuO1xuXG4gICAgaWYgKGNvbG9yU2NhbGUgPT09IFNDQUxFX1RZUEVTLnF1YW50aXplKSB7XG4gICAgICBjb25zdCBbbWluLCBtYXhdID0gdGlsZURhdGFzZXQuZ2V0RXh0ZW50KGZpZWxkKTtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShjb2xvckRvbWFpbikgfHwgbWluICE9PSBjb2xvckRvbWFpblswXSB8fCBtYXggIT09IGNvbG9yRG9tYWluWzFdKSB7XG4gICAgICAgIHNldExheWVyRG9tYWluKHtkb21haW46IFttaW4sIG1heF19KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNvbG9yU2NhbGUgPT09IFNDQUxFX1RZUEVTLnF1YW50aWxlKSB7XG4gICAgICBjb25zdCBkb21haW4gPSB0aWxlRGF0YXNldC5nZXRRdWFudGlsZVNhbXBsZShmaWVsZCk7XG4gICAgICBzZXRMYXllckRvbWFpbih7ZG9tYWlufSk7XG4gICAgfSBlbHNlIGlmIChjb2xvclNjYWxlID09PSBTQ0FMRV9UWVBFUy5vcmRpbmFsKSB7XG4gICAgICBjb25zdCBkb21haW4gPSB0aWxlRGF0YXNldC5nZXRVbmlxdWVWYWx1ZXMoZmllbGQpO1xuICAgICAgc2V0TGF5ZXJEb21haW4oe2RvbWFpbn0pO1xuICAgIH1cbiAgfSwgNTAwKTtcblxuICByZXNldENvbG9yRG9tYWluKCk6IHZvaWQge1xuICAgIGNvbnN0IHtkYXRhc2V0SWQsIGRhdGFzZXRzfSA9IHRoaXMubWV0YTtcbiAgICB0aGlzLnVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbChkYXRhc2V0cz8uW2RhdGFzZXRJZCB8fCAnJ10sICdjb2xvcicpO1xuICAgIHRoaXMuc2V0TGF5ZXJEb21haW4/Lih7ZG9tYWluOiB0aGlzLmNvbmZpZy5jb2xvckRvbWFpbn0pO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJDb25maWcoXG4gICAgbmV3Q29uZmlnOiBQYXJ0aWFsPExheWVyQmFzZUNvbmZpZz4gJiBQYXJ0aWFsPExheWVyQ29sb3JDb25maWc+XG4gICk6IEFic3RyYWN0VGlsZUxheWVyPFQsIEk+IHtcbiAgICAvLyBXaGVuIHRoZSBkeW5hbWljIGNvbG9yIHNldHRpbmcgY2hhbmdlcywgd2UgbmVlZCB0byByZWNhbGN1bGF0ZSB0aGUgbGF5ZXIgZG9tYWluXG4gICAgY29uc3Qgb2xkID0gdGhpcy5jb25maWcudmlzQ29uZmlnLmR5bmFtaWNDb2xvciA/PyBmYWxzZTtcbiAgICBjb25zdCBuZXh0ID0gbmV3Q29uZmlnLnZpc0NvbmZpZz8uZHluYW1pY0NvbG9yID8/IG9sZDtcbiAgICBjb25zdCBzY2FsZVR5cGVDaGFuZ2VkID1cbiAgICAgIG5ld0NvbmZpZy5jb2xvclNjYWxlICYmIHRoaXMuY29uZmlnLmNvbG9yU2NhbGUgIT09IG5ld0NvbmZpZy5jb2xvclNjYWxlO1xuXG4gICAgc3VwZXIudXBkYXRlTGF5ZXJDb25maWcobmV3Q29uZmlnKTtcbiAgICBjb25zdCB7Y29sb3JGaWVsZH0gPSB0aGlzLmNvbmZpZztcblxuICAgIGlmIChjb2xvckZpZWxkKSB7XG4gICAgICAvLyBXaGVuIHdlIHN3aXRjaCBmcm9tIGR5bmFtaWMgdG8gbm9uLWR5bmFtaWMgb3IgdmljZSB2ZXJzYSwgd2UgbmVlZCB0byB1cGRhdGVcbiAgICAgIC8vIHRoZSBjb2xvciBkb21haW4uIFRoaXMgaXMgZG93bnN0cmVhbSBmcm9tIGEgZGlzcGF0Y2ggY2FsbCwgc28gd2UgdXNlXG4gICAgICAvLyBzZXRUaW1lb3V0IHRvIGF2b2lkIFwicmVkdWNlcnMgbWF5IG5vdCBkaXNwYXRjaCBhY3Rpb25zXCIgZXJyb3JzXG4gICAgICBpZiAobmV4dCAmJiAoIW9sZCB8fCBzY2FsZVR5cGVDaGFuZ2VkKSkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2V0RHluYW1pY0NvbG9yRG9tYWluKCksIDApO1xuICAgICAgfSBlbHNlIGlmIChvbGQgJiYgIW5leHQpIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnJlc2V0Q29sb3JEb21haW4oKSwgMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXQgYW5pbWF0aW9uRG9tYWluKCk6IFtudW1iZXIsIG51bWJlcl0gfCBudWxsIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuYW5pbWF0aW9uLmRvbWFpbjtcbiAgfVxuXG4gIHNldEluaXRpYWxMYXllckNvbmZpZyhkYXRhc2V0OiBLZXBsZXJEYXRhc2V0KTogQWJzdHJhY3RUaWxlTGF5ZXI8VCwgST4ge1xuICAgIGNvbnN0IGRlZmF1bHRDb2xvckZpZWxkID0gZmluZERlZmF1bHRDb2xvckZpZWxkKGRhdGFzZXQpO1xuXG4gICAgaWYgKGRlZmF1bHRDb2xvckZpZWxkKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtcbiAgICAgICAgY29sb3JGaWVsZDogZGVmYXVsdENvbG9yRmllbGRcbiAgICAgIH0pO1xuICAgICAgdGhpcy51cGRhdGVMYXllclZpc3VhbENoYW5uZWwoZGF0YXNldCwgJ2NvbG9yJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXREZWZhdWx0TGF5ZXJDb25maWcoXG4gICAgcHJvcHM6IExheWVyQmFzZUNvbmZpZ1BhcnRpYWxcbiAgKTogTGF5ZXJCYXNlQ29uZmlnICYgUGFydGlhbDxMYXllckNvbG9yQ29uZmlnICYgTGF5ZXJIZWlnaHRDb25maWc+IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3VwZXIuZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzKSxcbiAgICAgIGNvbG9yU2NhbGU6IFNDQUxFX1RZUEVTLnF1YW50aXplLFxuXG4gICAgICAvLyBhZGQgaGVpZ2h0IHZpc3VhbCBjaGFubmVsXG4gICAgICBoZWlnaHRGaWVsZDogbnVsbCxcbiAgICAgIGhlaWdodERvbWFpbjogWzAsIDFdLFxuICAgICAgaGVpZ2h0U2NhbGU6ICdsaW5lYXInXG4gICAgfTtcbiAgfVxuXG4gIC8vIFdlIGNhbiByZW5kZXIgd2l0aG91dCBjb2x1bW5zLCBzbyB3ZSByZWRlZmluZSB0aGlzIG1ldGhvZFxuICBzaG91bGRSZW5kZXJMYXllcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLnR5cGUgJiYgdGhpcy5jb25maWcuaXNWaXNpYmxlKTtcbiAgfVxuXG4gIHVwZGF0ZUFuaW1hdGlvbkRvbWFpbkJ5RmllbGQoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZmllbGQgPSB0aGlzLmNvbmZpZ1t0aGlzLnZpc3VhbENoYW5uZWxzW2NoYW5uZWxdLmZpZWxkXTtcblxuICAgIGlmIChpc0luZGV4ZWRGaWVsZChmaWVsZCkgJiYgZmllbGQuaW5kZXhCeS50eXBlID09PSBBTExfRklFTERfVFlQRVMudGltZXN0YW1wKSB7XG4gICAgICBjb25zdCB7dGltZURvbWFpbn0gPSBmaWVsZC5pbmRleEJ5O1xuXG4gICAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtcbiAgICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgICAgLi4udGltZURvbWFpbixcbiAgICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICAgIHN0YXJ0VGltZTogdGltZURvbWFpbi5kb21haW5bMF1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQW5pbWF0aW9uRG9tYWluKGRvbWFpbjogW251bWJlciwgbnVtYmVyXSB8IG51bGwgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtcbiAgICAgIGFuaW1hdGlvbjoge1xuICAgICAgICAuLi50aGlzLmNvbmZpZy5hbmltYXRpb24sXG4gICAgICAgIGRvbWFpblxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJEb21haW4oZGF0YXNldHM6IEtlcGxlckRhdGFzZXRzLCBuZXdGaWx0ZXI/OiBGaWx0ZXIpOiBBYnN0cmFjdFRpbGVMYXllcjxULCBJPiB7XG4gICAgc3VwZXIudXBkYXRlTGF5ZXJEb21haW4oZGF0YXNldHMsIG5ld0ZpbHRlcik7XG4gICAgaWYgKG5ld0ZpbHRlcikge1xuICAgICAgLy8gaW52YWxpZGF0ZSBjYWNoZWRWaXNpYmxlRGF0YXNldCB3aGVuIGUuZy4gY2hhbmdpbmcgZmlsdGVyc1xuICAgICAgdGhpcy50aWxlRGF0YXNldC5pbnZhbGlkYXRlQ2FjaGUoKTtcbiAgICB9XG4gICAgT2JqZWN0LmtleXModGhpcy52aXN1YWxDaGFubmVscykuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIHRoaXMudXBkYXRlQW5pbWF0aW9uRG9tYWluQnlGaWVsZChjaGFubmVsKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbChkYXRhc2V0OiBLZXBsZXJEYXRhc2V0LCBjaGFubmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBzdXBlci51cGRhdGVMYXllclZpc3VhbENoYW5uZWwoZGF0YXNldCwgY2hhbm5lbCk7XG5cbiAgICAvLyBjcmVhdGUgYW5pbWF0aW9uIGlmIGZpZWxkIGlzIGluZGV4ZWQgYnkgdGltZVxuICAgIHRoaXMudXBkYXRlQW5pbWF0aW9uRG9tYWluQnlGaWVsZChjaGFubmVsKTtcbiAgfVxuXG4gIGZvcm1hdExheWVyRGF0YShcbiAgICBkYXRhc2V0czogS2VwbGVyRGF0YXNldHMsXG4gICAgb2xkTGF5ZXJEYXRhOiB1bmtub3duLFxuICAgIGFuaW1hdGlvbkNvbmZpZzogQW5pbWF0aW9uQ29uZmlnXG4gICk6IExheWVyRGF0YSB7XG4gICAgY29uc3Qge2RhdGFJZH0gPSB0aGlzLmNvbmZpZztcbiAgICBpZiAoIW5vdE51bGxvclVuZGVmaW5lZChkYXRhSWQpKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0c1tkYXRhSWRdO1xuXG4gICAgY29uc3QgZGF0YVVwZGF0ZVRyaWdnZXJzID0gdGhpcy5nZXREYXRhVXBkYXRlVHJpZ2dlcnMoZGF0YXNldCk7XG4gICAgY29uc3QgdHJpZ2dlckNoYW5nZWQgPSB0aGlzLmdldENoYW5nZWRUcmlnZ2VycyhkYXRhVXBkYXRlVHJpZ2dlcnMpO1xuXG4gICAgaWYgKHRyaWdnZXJDaGFuZ2VkICYmIHRyaWdnZXJDaGFuZ2VkLmdldE1ldGEpIHtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJNZXRhKGRhdGFzZXQsIGRhdGFzZXRzKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmRleEtleSA9IHRoaXMuY29uZmlnLmFuaW1hdGlvbi5lbmFibGVkID8gYW5pbWF0aW9uQ29uZmlnLmN1cnJlbnRUaW1lIDogbnVsbDtcbiAgICBjb25zdCBhY2Nlc3NvcnMgPSB0aGlzLmdldEF0dHJpYnV0ZUFjY2Vzc29ycyh7XG4gICAgICBkYXRhQWNjZXNzb3I6ICgpID0+IGQgPT4gZCxcbiAgICAgIGRhdGFDb250YWluZXI6IGRhdGFzZXQuZGF0YUNvbnRhaW5lcixcbiAgICAgIGluZGV4S2V5XG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IGRhdGFzZXQ/Lm1ldGFkYXRhIGFzIExheWVyRGF0YSB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBtZXRhZGF0YVRvRGF0YSA9IG1ldGFkYXRhXG4gICAgICA/IHtcbiAgICAgICAgICBtaW5ab29tOiBtZXRhZGF0YS5taW5ab29tLFxuICAgICAgICAgIG1heFpvb206IG1ldGFkYXRhLm1heFpvb20sXG4gICAgICAgICAgYm91bmRzOiBtZXRhZGF0YS5ib3VuZHNcbiAgICAgICAgfVxuICAgICAgOiB7fTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5tZXRhZGF0YVRvRGF0YSxcbiAgICAgIC4uLmFjY2Vzc29yc1xuICAgIH07XG4gIH1cblxuICBnZXRHcHVGaWx0ZXJWYWx1ZUFjY2Vzc29yKHtncHVGaWx0ZXIsIGFuaW1hdGlvbkNvbmZpZ306IExheWVyT3B0cyk6IGFueSB7XG4gICAgY29uc3QgaW5kZXhLZXkgPSB0aGlzLmNvbmZpZy5hbmltYXRpb24uZW5hYmxlZCA/IGFuaW1hdGlvbkNvbmZpZy5jdXJyZW50VGltZSA6IG51bGw7XG4gICAgY29uc3QgdmFsdWVBY2Nlc3NvciA9IChkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlLCBkKSA9PiBmaWVsZCA9PlxuICAgICAgdGhpcy5hY2Nlc3NWU0ZpZWxkVmFsdWUoZmllbGQsIGluZGV4S2V5KShmaWVsZCwgZCk7XG4gICAgcmV0dXJuIGdwdUZpbHRlci5maWx0ZXJWYWx1ZUFjY2Vzc29yKG51bGwgYXMgYW55KSh1bmRlZmluZWQsIHZhbHVlQWNjZXNzb3IpO1xuICB9XG59XG4iXSwi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