UNPKG

kepler.gl

Version:

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

445 lines (442 loc) 57.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.tile3DVisConfigs = exports["default"] = exports.TILE3D_LAYER_TYPE = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); 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 _geoLayers = require("@deck.gl/geo-layers"); var _dTiles = require("@loaders.gl/3d-tiles"); var _i3s = require("@loaders.gl/i3s"); var _tiles = require("@loaders.gl/tiles"); var _baseLayer = _interopRequireDefault(require("../base-layer")); var _tile3dLayerIcon = _interopRequireDefault(require("./tile3d-layer-icon")); var _constants = require("@kepler.gl/constants"); 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; } 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; } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project /** * Custom DeckTile3DLayer that catches exceptions in _loadTileset and * _updateTileset (which calls selectTiles – an unhandled-promise path * where errors like "boundingVolume must contain …" escape). * See: https://github.com/visgl/deck.gl/issues/8755 */ // @ts-expect-error Types have separate declarations of a private property '_loadTileset'. var KeplerTile3DLayer = /*#__PURE__*/function (_DeckTile3DLayer) { function KeplerTile3DLayer() { (0, _classCallCheck2["default"])(this, KeplerTile3DLayer); return _callSuper(this, KeplerTile3DLayer, arguments); } (0, _inherits2["default"])(KeplerTile3DLayer, _DeckTile3DLayer); return (0, _createClass2["default"])(KeplerTile3DLayer, [{ key: "_loadTileset", value: // @ts-ignore override of private method called by deck.gl internals function () { var _loadTileset2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(tilesetUrl) { var _error$message; return _regenerator["default"].wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.prev = 0; _context.next = 3; return _superPropGet(KeplerTile3DLayer, "_loadTileset", this, 3)([tilesetUrl]); case 3: _context.next = 8; break; case 5: _context.prev = 5; _context.t0 = _context["catch"](0); if (_context.t0 !== null && _context.t0 !== void 0 && (_error$message = _context.t0.message) !== null && _error$message !== void 0 && _error$message.includes("reading 'refine'")) { this.raiseError(new Error('Bad tileset format or invalid API key'), '_loadTileset'); } else { console.error('Tile3DLayer: tileset load error', _context.t0); } case 8: case "end": return _context.stop(); } }, _callee, this, [[0, 5]]); })); function _loadTileset(_x) { return _loadTileset2.apply(this, arguments); } return _loadTileset; }() /** * Override _updateTileset to catch errors from selectTiles(), * which deck.gl calls with .then() but no .catch(). * Errors from tilesetInitializationPromise (e.g. invalid boundingVolume * in child tiles) surface here as unhandled promise rejections. */ // @ts-ignore override of private method }, { key: "_updateTileset", value: function _updateTileset(viewports) { var _this = this; if (!viewports) return; var _ref = this.state, tileset3d = _ref.tileset3d; var timeline = this.context.timeline; var viewportsNumber = Object.keys(viewports).length; if (!timeline || !viewportsNumber || !tileset3d) return; tileset3d.selectTiles(Object.values(viewports)).then(function (frameNumber) { var tilesetChanged = _this.state.frameNumber !== frameNumber; if (tilesetChanged) { _this.setState({ frameNumber: frameNumber }); } })["catch"](function (error) { console.error('Tile3DLayer: selectTiles error', error); }); } // deck.gl's ScenegraphLayer does not recreate its models when // defaultShaderModules change (extensionsChanged flag). This means // adding/removing the Light & Shadow effect after tiles are loaded // leaves ScenegraphLayer sublayers without the shadow shader module. // SimpleMeshLayer (ArcGIS/I3S) already handles extensionsChanged // correctly, so only invalidate SCENEGRAPH sublayers (Google 3D Tiles). }, { key: "updateState", value: function updateState(params) { _superPropGet(KeplerTile3DLayer, "updateState", this, 3)([params]); if (params.changeFlags.extensionsChanged) { var _ref2 = this.state, layerMap = _ref2.layerMap; if (layerMap) { for (var _i = 0, _Object$keys = Object.keys(layerMap); _i < _Object$keys.length; _i++) { var _entry$tile; var key = _Object$keys[_i]; var entry = layerMap[key]; if (((_entry$tile = entry.tile) === null || _entry$tile === void 0 ? void 0 : _entry$tile.type) === _tiles.TILE_TYPE.SCENEGRAPH) { entry.layer = null; entry.needsUpdate = true; } } } } } }]); }(_geoLayers.Tile3DLayer); KeplerTile3DLayer.layerName = 'KeplerTile3DLayer'; var TILE3D_LAYER_TYPE = exports.TILE3D_LAYER_TYPE = _constants.LAYER_TYPES.tile3d; var tile3DVisConfigs = exports.tile3DVisConfigs = { opacity: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.opacity), {}, { defaultValue: 1, property: 'opacity' }), pointSize: { type: 'number', defaultValue: 2, label: 'layerVisConfigs.pointSize', isRanged: false, range: [0.5, 20], step: 0.5, group: 'display', property: 'pointSize', allowCustomValue: false } }; var EMPTY_EXTENSIONS = []; var DEPTH_TEST_PARAMS = { depthTest: true }; function getTile3DProviderFromUrl() { var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; for (var _i2 = 0, _Object$keys2 = Object.keys(_constants.TILE3D_PROVIDERS); _i2 < _Object$keys2.length; _i2++) { var key = _Object$keys2[_i2]; if (url.includes(_constants.TILE3D_PROVIDERS[key].urlKey)) { return _constants.TILE3D_PROVIDERS[key]; } } return null; } var Tile3DLayer = exports["default"] = /*#__PURE__*/function (_Layer) { function Tile3DLayer(props) { var _this2; (0, _classCallCheck2["default"])(this, Tile3DLayer); _this2 = _callSuper(this, Tile3DLayer, [props]); (0, _defineProperty2["default"])(_this2, "_cachedDataAndLoader", null); (0, _defineProperty2["default"])(_this2, "_layerCallbacks", null); (0, _defineProperty2["default"])(_this2, "_hasFittedBounds", false); (0, _defineProperty2["default"])(_this2, "_onTilesetLoad", function (tileset3d) { var _this2$meta; _this2._extractBoundsFromTileset(tileset3d); var tileUrl = tileset3d.url || ''; var isGoogle = getTile3DProviderFromUrl(tileUrl) === _constants.TILE3D_PROVIDERS.google; if (!_this2._hasFittedBounds && (_this2$meta = _this2.meta) !== null && _this2$meta !== void 0 && _this2$meta.bounds && !isGoogle) { var _this2$_layerCallback, _this2$_layerCallback2; _this2._hasFittedBounds = true; (_this2$_layerCallback = _this2._layerCallbacks) === null || _this2$_layerCallback === void 0 || (_this2$_layerCallback2 = _this2$_layerCallback.onFitBounds) === null || _this2$_layerCallback2 === void 0 || _this2$_layerCallback2.call(_this2$_layerCallback, _this2.meta.bounds); } if (isGoogle) { tileset3d.options.onTraversalComplete = function (selectedTiles) { var credits = new Set(); selectedTiles.forEach(function (tile) { var _content; var _ref3 = ((_content = tile.content) === null || _content === void 0 || (_content = _content.gltf) === null || _content === void 0 ? void 0 : _content.asset) || {}, copyright = _ref3.copyright; if (copyright) copyright.split(';').forEach(function (c) { return credits.add(c); }); }); var title = Array.from(credits).join('; '); _this2.updateMeta({ googleAttribution: title }); return selectedTiles; }; } }); (0, _defineProperty2["default"])(_this2, "_onTileLoad", function (tile) { var _tile$content; // I3S materials often lack metallicFactor/roughnessFactor. // PBR spec defaults metallicFactor to 1 (fully metallic), // causing black surfaces when lighting/shadow effects are active. var pbr = (_tile$content = tile.content) === null || _tile$content === void 0 || (_tile$content = _tile$content.material) === null || _tile$content === void 0 ? void 0 : _tile$content.pbrMetallicRoughness; if (pbr) { if (pbr.metallicFactor === undefined) { pbr.metallicFactor = 0; } if (pbr.roughnessFactor === undefined) { pbr.roughnessFactor = 1; } } }); (0, _defineProperty2["default"])(_this2, "_onTileUnload", function (_tile) { /* noop */ }); _this2.registerVisConfig(tile3DVisConfigs); _this2.meta = {}; return _this2; } (0, _inherits2["default"])(Tile3DLayer, _Layer); return (0, _createClass2["default"])(Tile3DLayer, [{ key: "type", get: function get() { return TILE3D_LAYER_TYPE; } }, { key: "name", get: function get() { return '3D Tile'; } }, { key: "requireData", get: function get() { return false; } }, { key: "requiredLayerColumns", get: function get() { return []; } }, { key: "layerIcon", get: function get() { return _tile3dLayerIcon["default"]; } }, { key: "supportedDatasetTypes", get: function get() { return [_constants.DatasetType.TILE_3D]; } }, { key: "visualChannels", get: function get() { return {}; } }, { key: "shouldRenderLayer", value: function shouldRenderLayer() { return Boolean(this.type && this.config.isVisible); } }, { key: "getHoverData", value: function getHoverData() { return null; } }, { key: "formatLayerData", value: function formatLayerData(datasets) { var dataId = this.config.dataId; if (!dataId || !datasets[dataId]) { return {}; } var dataset = datasets[dataId]; var metadata = dataset.metadata || {}; return { tile3dUrl: metadata.tile3dUrl, tile3dAccessToken: metadata.tile3dAccessToken }; } }, { key: "updateLayerMeta", value: function updateLayerMeta(dataset) { if (dataset.type !== _constants.DatasetType.TILE_3D) { return; } var metadata = dataset.metadata || {}; var provider = getTile3DProviderFromUrl(metadata.tile3dUrl); this.updateMeta({ provider: provider }); } }, { key: "_getDataAndLoaderOptions", value: function _getDataAndLoaderOptions(tileUrl, accessToken) { var cacheKey = "".concat(tileUrl, "::").concat(accessToken || ''); if (this._cachedDataAndLoader && this._cachedDataAndLoader._cacheKey === cacheKey) { return this._cachedDataAndLoader; } var provider = getTile3DProviderFromUrl(tileUrl); var result; if (provider === _constants.TILE3D_PROVIDERS.google) { var separator = tileUrl.includes('?') ? '&' : '?'; result = { data: "".concat(tileUrl).concat(separator, "key=").concat(accessToken || ''), loader: _dTiles.Tiles3DLoader, loadOptions: { fetch: { headers: { 'X-GOOG-API-KEY': accessToken || '' } } } }; } else if (provider === _constants.TILE3D_PROVIDERS.cesium) { result = { data: tileUrl, loader: _dTiles.CesiumIonLoader, loadOptions: { 'cesium-ion': { accessToken: accessToken } } }; } else if (provider === _constants.TILE3D_PROVIDERS.arcgis) { result = { data: tileUrl, loader: _i3s.I3SLoader, loadOptions: { i3s: { useCompressedTextures: false } } }; } else { result = { data: tileUrl, loader: _dTiles.Tiles3DLoader }; } this._cachedDataAndLoader = _objectSpread(_objectSpread({}, result), {}, { _cacheKey: cacheKey }); return this._cachedDataAndLoader; } }, { key: "_extractBoundsFromTileset", value: function _extractBoundsFromTileset(tileset3d) { try { var root = tileset3d.root; if (root) { var bbox = root.boundingBox; if (bbox && bbox.length === 2) { var _bbox = (0, _slicedToArray2["default"])(bbox, 2), min = _bbox[0], max = _bbox[1]; // bbox = [[westDeg, southDeg, minHeight], [eastDeg, northDeg, maxHeight]] this.updateMeta({ bounds: [min[0], min[1], max[0], max[1]] }); return; } } } catch (_unused) { // boundingBox getter may throw for malformed volumes } // Fallback: approximate bounds from cartographicCenter and zoom var center = tileset3d.cartographicCenter; if (center) { var lng = center[0]; var lat = center[1]; var zoom = tileset3d.zoom || 14; // Approximate half-span in degrees based on zoom level var span = 180 / Math.pow(2, zoom); this.updateMeta({ bounds: [lng - span, lat - span, lng + span, lat + span] }); } } }, { key: "renderLayer", value: function renderLayer(opts) { var _visConfig$pointSize, _visConfig$opacity; var data = opts.data, layerCallbacks = opts.layerCallbacks; var _ref4 = data || {}, tile3dUrl = _ref4.tile3dUrl, tile3dAccessToken = _ref4.tile3dAccessToken; if (!tile3dUrl) { return []; } this._layerCallbacks = layerCallbacks || null; var visConfig = this.config.visConfig; var defaultLayerProps = this.getDefaultDeckLayerProps(opts); var _this$_getDataAndLoad = this._getDataAndLoaderOptions(tile3dUrl, tile3dAccessToken), tileData = _this$_getDataAndLoad.data, loadOptions = _this$_getDataAndLoad.loadOptions, loader = _this$_getDataAndLoad.loader; var color = this.config.color; var pointColor = color ? [color[0], color[1], color[2], 255] : [255, 255, 255, 255]; return [new KeplerTile3DLayer({ id: defaultLayerProps.id, coordinateSystem: defaultLayerProps.coordinateSystem, wrapLongitude: defaultLayerProps.wrapLongitude, visible: defaultLayerProps.visible, data: tileData, loader: loader, loadOptions: loadOptions, onTilesetLoad: this._onTilesetLoad, onTileLoad: this._onTileLoad, onTileUnload: this._onTileUnload, getPointColor: pointColor, pointSize: (_visConfig$pointSize = visConfig.pointSize) !== null && _visConfig$pointSize !== void 0 ? _visConfig$pointSize : 2, pickable: false, opacity: (_visConfig$opacity = visConfig.opacity) !== null && _visConfig$opacity !== void 0 ? _visConfig$opacity : 1, extensions: EMPTY_EXTENSIONS, parameters: DEPTH_TEST_PARAMS })]; } }], [{ key: "findDefaultLayerProps", value: function findDefaultLayerProps(dataset) { if (dataset.type !== _constants.DatasetType.TILE_3D) { return { props: [] }; } return { props: [{ label: dataset.label, isVisible: true, color: [255, 255, 255] }] }; } }]); }(_baseLayer["default"]); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZ2VvTGF5ZXJzIiwicmVxdWlyZSIsIl9kVGlsZXMiLCJfaTNzIiwiX3RpbGVzIiwiX2Jhc2VMYXllciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfdGlsZTNkTGF5ZXJJY29uIiwiX2NvbnN0YW50cyIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiX2NhbGxTdXBlciIsIl9nZXRQcm90b3R5cGVPZjIiLCJfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIiLCJfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0IiwiUmVmbGVjdCIsImNvbnN0cnVjdCIsImNvbnN0cnVjdG9yIiwiQm9vbGVhbiIsInByb3RvdHlwZSIsInZhbHVlT2YiLCJjYWxsIiwiX3N1cGVyUHJvcEdldCIsInAiLCJfZ2V0MiIsIktlcGxlclRpbGUzRExheWVyIiwiX0RlY2tUaWxlM0RMYXllciIsIl9jbGFzc0NhbGxDaGVjazIiLCJfaW5oZXJpdHMyIiwiX2NyZWF0ZUNsYXNzMiIsImtleSIsInZhbHVlIiwiX2xvYWRUaWxlc2V0MiIsIl9hc3luY1RvR2VuZXJhdG9yMiIsIl9yZWdlbmVyYXRvciIsIm1hcmsiLCJfY2FsbGVlIiwidGlsZXNldFVybCIsIl9lcnJvciRtZXNzYWdlIiwid3JhcCIsIl9jYWxsZWUkIiwiX2NvbnRleHQiLCJwcmV2IiwibmV4dCIsInQwIiwibWVzc2FnZSIsImluY2x1ZGVzIiwicmFpc2VFcnJvciIsIkVycm9yIiwiY29uc29sZSIsImVycm9yIiwic3RvcCIsIl9sb2FkVGlsZXNldCIsIl94IiwiX3VwZGF0ZVRpbGVzZXQiLCJ2aWV3cG9ydHMiLCJfdGhpcyIsIl9yZWYiLCJzdGF0ZSIsInRpbGVzZXQzZCIsInRpbWVsaW5lIiwiY29udGV4dCIsInZpZXdwb3J0c051bWJlciIsInNlbGVjdFRpbGVzIiwidmFsdWVzIiwidGhlbiIsImZyYW1lTnVtYmVyIiwidGlsZXNldENoYW5nZWQiLCJzZXRTdGF0ZSIsInVwZGF0ZVN0YXRlIiwicGFyYW1zIiwiY2hhbmdlRmxhZ3MiLCJleHRlbnNpb25zQ2hhbmdlZCIsIl9yZWYyIiwibGF5ZXJNYXAiLCJfaSIsIl9PYmplY3Qka2V5cyIsIl9lbnRyeSR0aWxlIiwiZW50cnkiLCJ0aWxlIiwidHlwZSIsIlRJTEVfVFlQRSIsIlNDRU5FR1JBUEgiLCJsYXllciIsIm5lZWRzVXBkYXRlIiwiRGVja1RpbGUzRExheWVyIiwibGF5ZXJOYW1lIiwiVElMRTNEX0xBWUVSX1RZUEUiLCJleHBvcnRzIiwiTEFZRVJfVFlQRVMiLCJ0aWxlM2QiLCJ0aWxlM0RWaXNDb25maWdzIiwib3BhY2l0eSIsIkxBWUVSX1ZJU19DT05GSUdTIiwiZGVmYXVsdFZhbHVlIiwicHJvcGVydHkiLCJwb2ludFNpemUiLCJsYWJlbCIsImlzUmFuZ2VkIiwicmFuZ2UiLCJzdGVwIiwiZ3JvdXAiLCJhbGxvd0N1c3RvbVZhbHVlIiwiRU1QVFlfRVhURU5TSU9OUyIsIkRFUFRIX1RFU1RfUEFSQU1TIiwiZGVwdGhUZXN0IiwiZ2V0VGlsZTNEUHJvdmlkZXJGcm9tVXJsIiwidXJsIiwidW5kZWZpbmVkIiwiX2kyIiwiX09iamVjdCRrZXlzMiIsIlRJTEUzRF9QUk9WSURFUlMiLCJ1cmxLZXkiLCJUaWxlM0RMYXllciIsIl9MYXllciIsInByb3BzIiwiX3RoaXMyIiwiX3RoaXMyJG1ldGEiLCJfZXh0cmFjdEJvdW5kc0Zyb21UaWxlc2V0IiwidGlsZVVybCIsImlzR29vZ2xlIiwiZ29vZ2xlIiwiX2hhc0ZpdHRlZEJvdW5kcyIsIm1ldGEiLCJib3VuZHMiLCJfdGhpczIkX2xheWVyQ2FsbGJhY2siLCJfdGhpczIkX2xheWVyQ2FsbGJhY2syIiwiX2xheWVyQ2FsbGJhY2tzIiwib25GaXRCb3VuZHMiLCJvcHRpb25zIiwib25UcmF2ZXJzYWxDb21wbGV0ZSIsInNlbGVjdGVkVGlsZXMiLCJjcmVkaXRzIiwiU2V0IiwiX2NvbnRlbnQiLCJfcmVmMyIsImNvbnRlbnQiLCJnbHRmIiwiYXNzZXQiLCJjb3B5cmlnaHQiLCJzcGxpdCIsImMiLCJhZGQiLCJ0aXRsZSIsIkFycmF5IiwiZnJvbSIsImpvaW4iLCJ1cGRhdGVNZXRhIiwiZ29vZ2xlQXR0cmlidXRpb24iLCJfdGlsZSRjb250ZW50IiwicGJyIiwibWF0ZXJpYWwiLCJwYnJNZXRhbGxpY1JvdWdobmVzcyIsIm1ldGFsbGljRmFjdG9yIiwicm91Z2huZXNzRmFjdG9yIiwiX3RpbGUiLCJyZWdpc3RlclZpc0NvbmZpZyIsImdldCIsIlRpbGUzRExheWVySWNvbiIsIkRhdGFzZXRUeXBlIiwiVElMRV8zRCIsInNob3VsZFJlbmRlckxheWVyIiwiY29uZmlnIiwiaXNWaXNpYmxlIiwiZ2V0SG92ZXJEYXRhIiwiZm9ybWF0TGF5ZXJEYXRhIiwiZGF0YXNldHMiLCJkYXRhSWQiLCJkYXRhc2V0IiwibWV0YWRhdGEiLCJ0aWxlM2RVcmwiLCJ0aWxlM2RBY2Nlc3NUb2tlbiIsInVwZGF0ZUxheWVyTWV0YSIsInByb3ZpZGVyIiwiX2dldERhdGFBbmRMb2FkZXJPcHRpb25zIiwiYWNjZXNzVG9rZW4iLCJjYWNoZUtleSIsImNvbmNhdCIsIl9jYWNoZWREYXRhQW5kTG9hZGVyIiwiX2NhY2hlS2V5IiwicmVzdWx0Iiwic2VwYXJhdG9yIiwiZGF0YSIsImxvYWRlciIsIlRpbGVzM0RMb2FkZXIiLCJsb2FkT3B0aW9ucyIsImZldGNoIiwiaGVhZGVycyIsImNlc2l1bSIsIkNlc2l1bUlvbkxvYWRlciIsImFyY2dpcyIsIkkzU0xvYWRlciIsImkzcyIsInVzZUNvbXByZXNzZWRUZXh0dXJlcyIsInJvb3QiLCJiYm94IiwiYm91bmRpbmdCb3giLCJfYmJveCIsIl9zbGljZWRUb0FycmF5MiIsIm1pbiIsIm1heCIsIl91bnVzZWQiLCJjZW50ZXIiLCJjYXJ0b2dyYXBoaWNDZW50ZXIiLCJsbmciLCJsYXQiLCJ6b29tIiwic3BhbiIsIk1hdGgiLCJwb3ciLCJyZW5kZXJMYXllciIsIm9wdHMiLCJfdmlzQ29uZmlnJHBvaW50U2l6ZSIsIl92aXNDb25maWckb3BhY2l0eSIsImxheWVyQ2FsbGJhY2tzIiwiX3JlZjQiLCJ2aXNDb25maWciLCJkZWZhdWx0TGF5ZXJQcm9wcyIsImdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyIsIl90aGlzJF9nZXREYXRhQW5kTG9hZCIsInRpbGVEYXRhIiwiY29sb3IiLCJwb2ludENvbG9yIiwiaWQiLCJjb29yZGluYXRlU3lzdGVtIiwid3JhcExvbmdpdHVkZSIsInZpc2libGUiLCJvblRpbGVzZXRMb2FkIiwiX29uVGlsZXNldExvYWQiLCJvblRpbGVMb2FkIiwiX29uVGlsZUxvYWQiLCJvblRpbGVVbmxvYWQiLCJfb25UaWxlVW5sb2FkIiwiZ2V0UG9pbnRDb2xvciIsInBpY2thYmxlIiwiZXh0ZW5zaW9ucyIsInBhcmFtZXRlcnMiLCJmaW5kRGVmYXVsdExheWVyUHJvcHMiLCJMYXllciJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90aWxlM2QtbGF5ZXIvdGlsZTNkLWxheWVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCB7VGlsZTNETGF5ZXIgYXMgRGVja1RpbGUzRExheWVyfSBmcm9tICdAZGVjay5nbC9nZW8tbGF5ZXJzJztcbmltcG9ydCB7VXBkYXRlUGFyYW1ldGVyc30gZnJvbSAnQGRlY2suZ2wvY29yZSc7XG5pbXBvcnQge1RpbGVzM0RMb2FkZXIsIENlc2l1bUlvbkxvYWRlcn0gZnJvbSAnQGxvYWRlcnMuZ2wvM2QtdGlsZXMnO1xuaW1wb3J0IHtJM1NMb2FkZXJ9IGZyb20gJ0Bsb2FkZXJzLmdsL2kzcyc7XG5pbXBvcnQge1RpbGVzZXQzRCwgVGlsZTNELCBUSUxFX1RZUEV9IGZyb20gJ0Bsb2FkZXJzLmdsL3RpbGVzJztcblxuaW1wb3J0IExheWVyIGZyb20gJy4uL2Jhc2UtbGF5ZXInO1xuaW1wb3J0IFRpbGUzRExheWVySWNvbiBmcm9tICcuL3RpbGUzZC1sYXllci1pY29uJztcbmltcG9ydCB7RmluZERlZmF1bHRMYXllclByb3BzUmV0dXJuVmFsdWV9IGZyb20gJy4uL2xheWVyLXV0aWxzJztcbmltcG9ydCB7XG4gIExBWUVSX1ZJU19DT05GSUdTLFxuICBMQVlFUl9UWVBFUyxcbiAgRGF0YXNldFR5cGUsXG4gIFRJTEUzRF9QUk9WSURFUlMsXG4gIFRpbGUzRERhdGFzZXRNZXRhZGF0YVxufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge0tlcGxlclRhYmxlIGFzIEtlcGxlckRhdGFzZXQsIERhdGFzZXRzIGFzIEtlcGxlckRhdGFzZXRzfSBmcm9tICdAa2VwbGVyLmdsL3RhYmxlJztcbmltcG9ydCB7VmlzQ29uZmlnTnVtYmVyLCBCaW5kZWRMYXllckNhbGxiYWNrc30gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5cbi8qKlxuICogQ3VzdG9tIERlY2tUaWxlM0RMYXllciB0aGF0IGNhdGNoZXMgZXhjZXB0aW9ucyBpbiBfbG9hZFRpbGVzZXQgYW5kXG4gKiBfdXBkYXRlVGlsZXNldCAod2hpY2ggY2FsbHMgc2VsZWN0VGlsZXMg4oCTIGFuIHVuaGFuZGxlZC1wcm9taXNlIHBhdGhcbiAqIHdoZXJlIGVycm9ycyBsaWtlIFwiYm91bmRpbmdWb2x1bWUgbXVzdCBjb250YWluIOKAplwiIGVzY2FwZSkuXG4gKiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92aXNnbC9kZWNrLmdsL2lzc3Vlcy84NzU1XG4gKi9cbi8vIEB0cy1leHBlY3QtZXJyb3IgVHlwZXMgaGF2ZSBzZXBhcmF0ZSBkZWNsYXJhdGlvbnMgb2YgYSBwcml2YXRlIHByb3BlcnR5ICdfbG9hZFRpbGVzZXQnLlxuY2xhc3MgS2VwbGVyVGlsZTNETGF5ZXIgZXh0ZW5kcyBEZWNrVGlsZTNETGF5ZXIge1xuICAvLyBAdHMtaWdub3JlIG92ZXJyaWRlIG9mIHByaXZhdGUgbWV0aG9kIGNhbGxlZCBieSBkZWNrLmdsIGludGVybmFsc1xuICBwcml2YXRlIGFzeW5jIF9sb2FkVGlsZXNldCh0aWxlc2V0VXJsOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBfbG9hZFRpbGVzZXQgaXMgcHJpdmF0ZSBpbiBEZWNrVGlsZTNETGF5ZXJcbiAgICAgIGF3YWl0IHN1cGVyLl9sb2FkVGlsZXNldCh0aWxlc2V0VXJsKTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBpZiAoZXJyb3I/Lm1lc3NhZ2U/LmluY2x1ZGVzKFwicmVhZGluZyAncmVmaW5lJ1wiKSkge1xuICAgICAgICB0aGlzLnJhaXNlRXJyb3IobmV3IEVycm9yKCdCYWQgdGlsZXNldCBmb3JtYXQgb3IgaW52YWxpZCBBUEkga2V5JyksICdfbG9hZFRpbGVzZXQnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RpbGUzRExheWVyOiB0aWxlc2V0IGxvYWQgZXJyb3InLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIF91cGRhdGVUaWxlc2V0IHRvIGNhdGNoIGVycm9ycyBmcm9tIHNlbGVjdFRpbGVzKCksXG4gICAqIHdoaWNoIGRlY2suZ2wgY2FsbHMgd2l0aCAudGhlbigpIGJ1dCBubyAuY2F0Y2goKS5cbiAgICogRXJyb3JzIGZyb20gdGlsZXNldEluaXRpYWxpemF0aW9uUHJvbWlzZSAoZS5nLiBpbnZhbGlkIGJvdW5kaW5nVm9sdW1lXG4gICAqIGluIGNoaWxkIHRpbGVzKSBzdXJmYWNlIGhlcmUgYXMgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9ucy5cbiAgICovXG4gIC8vIEB0cy1pZ25vcmUgb3ZlcnJpZGUgb2YgcHJpdmF0ZSBtZXRob2RcbiAgcHJpdmF0ZSBfdXBkYXRlVGlsZXNldCh2aWV3cG9ydHM6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKCF2aWV3cG9ydHMpIHJldHVybjtcbiAgICBjb25zdCB7dGlsZXNldDNkfSA9IHRoaXMuc3RhdGUgYXMgYW55O1xuICAgIGNvbnN0IHt0aW1lbGluZX0gPSB0aGlzLmNvbnRleHQ7XG4gICAgY29uc3Qgdmlld3BvcnRzTnVtYmVyID0gT2JqZWN0LmtleXModmlld3BvcnRzKS5sZW5ndGg7XG4gICAgaWYgKCF0aW1lbGluZSB8fCAhdmlld3BvcnRzTnVtYmVyIHx8ICF0aWxlc2V0M2QpIHJldHVybjtcblxuICAgIHRpbGVzZXQzZFxuICAgICAgLnNlbGVjdFRpbGVzKE9iamVjdC52YWx1ZXModmlld3BvcnRzKSlcbiAgICAgIC50aGVuKChmcmFtZU51bWJlcjogbnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHRpbGVzZXRDaGFuZ2VkID0gKHRoaXMuc3RhdGUgYXMgYW55KS5mcmFtZU51bWJlciAhPT0gZnJhbWVOdW1iZXI7XG4gICAgICAgIGlmICh0aWxlc2V0Q2hhbmdlZCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe2ZyYW1lTnVtYmVyfSk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignVGlsZTNETGF5ZXI6IHNlbGVjdFRpbGVzIGVycm9yJywgZXJyb3IpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBkZWNrLmdsJ3MgU2NlbmVncmFwaExheWVyIGRvZXMgbm90IHJlY3JlYXRlIGl0cyBtb2RlbHMgd2hlblxuICAvLyBkZWZhdWx0U2hhZGVyTW9kdWxlcyBjaGFuZ2UgKGV4dGVuc2lvbnNDaGFuZ2VkIGZsYWcpLiAgVGhpcyBtZWFuc1xuICAvLyBhZGRpbmcvcmVtb3ZpbmcgdGhlIExpZ2h0ICYgU2hhZG93IGVmZmVjdCBhZnRlciB0aWxlcyBhcmUgbG9hZGVkXG4gIC8vIGxlYXZlcyBTY2VuZWdyYXBoTGF5ZXIgc3VibGF5ZXJzIHdpdGhvdXQgdGhlIHNoYWRvdyBzaGFkZXIgbW9kdWxlLlxuICAvLyBTaW1wbGVNZXNoTGF5ZXIgKEFyY0dJUy9JM1MpIGFscmVhZHkgaGFuZGxlcyBleHRlbnNpb25zQ2hhbmdlZFxuICAvLyBjb3JyZWN0bHksIHNvIG9ubHkgaW52YWxpZGF0ZSBTQ0VORUdSQVBIIHN1YmxheWVycyAoR29vZ2xlIDNEIFRpbGVzKS5cbiAgdXBkYXRlU3RhdGUocGFyYW1zOiBVcGRhdGVQYXJhbWV0ZXJzPHRoaXM+KTogdm9pZCB7XG4gICAgc3VwZXIudXBkYXRlU3RhdGUocGFyYW1zKTtcbiAgICBpZiAocGFyYW1zLmNoYW5nZUZsYWdzLmV4dGVuc2lvbnNDaGFuZ2VkKSB7XG4gICAgICBjb25zdCB7bGF5ZXJNYXB9ID0gdGhpcy5zdGF0ZSBhcyBhbnk7XG4gICAgICBpZiAobGF5ZXJNYXApIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMobGF5ZXJNYXApKSB7XG4gICAgICAgICAgY29uc3QgZW50cnkgPSBsYXllck1hcFtrZXldO1xuICAgICAgICAgIGlmIChlbnRyeS50aWxlPy50eXBlID09PSBUSUxFX1RZUEUuU0NFTkVHUkFQSCkge1xuICAgICAgICAgICAgZW50cnkubGF5ZXIgPSBudWxsO1xuICAgICAgICAgICAgZW50cnkubmVlZHNVcGRhdGUgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuKEtlcGxlclRpbGUzRExheWVyIGFzIGFueSkubGF5ZXJOYW1lID0gJ0tlcGxlclRpbGUzRExheWVyJztcblxuZXhwb3J0IGNvbnN0IFRJTEUzRF9MQVlFUl9UWVBFID0gTEFZRVJfVFlQRVMudGlsZTNkO1xuXG5leHBvcnQgdHlwZSBUaWxlM0RMYXllclZpc0NvbmZpZ1NldHRpbmdzID0ge1xuICBvcGFjaXR5OiBWaXNDb25maWdOdW1iZXI7XG4gIHBvaW50U2l6ZTogVmlzQ29uZmlnTnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgVGlsZTNETGF5ZXJWaXNDb25maWcgPSB7XG4gIG9wYWNpdHk6IG51bWJlcjtcbiAgcG9pbnRTaXplOiBudW1iZXI7XG59O1xuXG5leHBvcnQgY29uc3QgdGlsZTNEVmlzQ29uZmlncyA9IHtcbiAgb3BhY2l0eToge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLm9wYWNpdHksXG4gICAgZGVmYXVsdFZhbHVlOiAxLFxuICAgIHByb3BlcnR5OiAnb3BhY2l0eSdcbiAgfSBhcyBWaXNDb25maWdOdW1iZXIsXG4gIHBvaW50U2l6ZToge1xuICAgIHR5cGU6ICdudW1iZXInIGFzIGNvbnN0LFxuICAgIGRlZmF1bHRWYWx1ZTogMixcbiAgICBsYWJlbDogJ2xheWVyVmlzQ29uZmlncy5wb2ludFNpemUnLFxuICAgIGlzUmFuZ2VkOiBmYWxzZSxcbiAgICByYW5nZTogWzAuNSwgMjBdLFxuICAgIHN0ZXA6IDAuNSxcbiAgICBncm91cDogJ2Rpc3BsYXknIGFzIGNvbnN0LFxuICAgIHByb3BlcnR5OiAncG9pbnRTaXplJyxcbiAgICBhbGxvd0N1c3RvbVZhbHVlOiBmYWxzZVxuICB9IGFzIFZpc0NvbmZpZ051bWJlclxufTtcblxuY29uc3QgRU1QVFlfRVhURU5TSU9OUzogYW55W10gPSBbXTtcbmNvbnN0IERFUFRIX1RFU1RfUEFSQU1TID0ge2RlcHRoVGVzdDogdHJ1ZX07XG5cbmZ1bmN0aW9uIGdldFRpbGUzRFByb3ZpZGVyRnJvbVVybCh1cmwgPSAnJyk6ICh0eXBlb2YgVElMRTNEX1BST1ZJREVSUylbc3RyaW5nXSB8IG51bGwge1xuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhUSUxFM0RfUFJPVklERVJTKSkge1xuICAgIGlmICh1cmwuaW5jbHVkZXMoVElMRTNEX1BST1ZJREVSU1trZXldLnVybEtleSkpIHtcbiAgICAgIHJldHVybiBUSUxFM0RfUFJPVklERVJTW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaWxlM0RMYXllciBleHRlbmRzIExheWVyIHtcbiAgZGVjbGFyZSB2aXNDb25maWdTZXR0aW5nczogVGlsZTNETGF5ZXJWaXNDb25maWdTZXR0aW5ncztcblxuICBwcml2YXRlIF9jYWNoZWREYXRhQW5kTG9hZGVyOiB7XG4gICAgZGF0YTogc3RyaW5nO1xuICAgIGxvYWRPcHRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgbG9hZGVyPzogYW55O1xuICAgIF9jYWNoZUtleT86IHN0cmluZztcbiAgfSB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgX2xheWVyQ2FsbGJhY2tzOiBCaW5kZWRMYXllckNhbGxiYWNrcyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9oYXNGaXR0ZWRCb3VuZHMgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczoge2RhdGFJZDogc3RyaW5nfSAmIFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5yZWdpc3RlclZpc0NvbmZpZyh0aWxlM0RWaXNDb25maWdzKTtcbiAgICB0aGlzLm1ldGEgPSB7fTtcbiAgfVxuXG4gIHN0YXRpYyBmaW5kRGVmYXVsdExheWVyUHJvcHMoZGF0YXNldDogS2VwbGVyRGF0YXNldCk6IEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlIHtcbiAgICBpZiAoZGF0YXNldC50eXBlICE9PSBEYXRhc2V0VHlwZS5USUxFXzNEKSB7XG4gICAgICByZXR1cm4ge3Byb3BzOiBbXX07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByb3BzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogZGF0YXNldC5sYWJlbCxcbiAgICAgICAgICBpc1Zpc2libGU6IHRydWUsXG4gICAgICAgICAgY29sb3I6IFsyNTUsIDI1NSwgMjU1XSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH07XG4gIH1cblxuICBnZXQgdHlwZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBUSUxFM0RfTEFZRVJfVFlQRTtcbiAgfVxuXG4gIGdldCBuYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICczRCBUaWxlJztcbiAgfVxuXG4gIGdldCByZXF1aXJlRGF0YSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBnZXQgcmVxdWlyZWRMYXllckNvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGdldCBsYXllckljb24oKTogdHlwZW9mIFRpbGUzRExheWVySWNvbiB7XG4gICAgcmV0dXJuIFRpbGUzRExheWVySWNvbjtcbiAgfVxuXG4gIGdldCBzdXBwb3J0ZWREYXRhc2V0VHlwZXMoKTogRGF0YXNldFR5cGVbXSB7XG4gICAgcmV0dXJuIFtEYXRhc2V0VHlwZS5USUxFXzNEXTtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBzaG91bGRSZW5kZXJMYXllcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLnR5cGUgJiYgdGhpcy5jb25maWcuaXNWaXNpYmxlKTtcbiAgfVxuXG4gIGdldEhvdmVyRGF0YSgpOiBhbnkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZm9ybWF0TGF5ZXJEYXRhKGRhdGFzZXRzOiBLZXBsZXJEYXRhc2V0cyk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICAgIGNvbnN0IHtkYXRhSWR9ID0gdGhpcy5jb25maWc7XG4gICAgaWYgKCFkYXRhSWQgfHwgIWRhdGFzZXRzW2RhdGFJZF0pIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhc2V0ID0gZGF0YXNldHNbZGF0YUlkXTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IChkYXRhc2V0Lm1ldGFkYXRhIHx8IHt9KSBhcyBUaWxlM0REYXRhc2V0TWV0YWRhdGE7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGlsZTNkVXJsOiBtZXRhZGF0YS50aWxlM2RVcmwsXG4gICAgICB0aWxlM2RBY2Nlc3NUb2tlbjogbWV0YWRhdGEudGlsZTNkQWNjZXNzVG9rZW5cbiAgICB9O1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJNZXRhKGRhdGFzZXQ6IEtlcGxlckRhdGFzZXQpOiB2b2lkIHtcbiAgICBpZiAoZGF0YXNldC50eXBlICE9PSBEYXRhc2V0VHlwZS5USUxFXzNEKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1ldGFkYXRhID0gKGRhdGFzZXQubWV0YWRhdGEgfHwge30pIGFzIFRpbGUzRERhdGFzZXRNZXRhZGF0YTtcbiAgICBjb25zdCBwcm92aWRlciA9IGdldFRpbGUzRFByb3ZpZGVyRnJvbVVybChtZXRhZGF0YS50aWxlM2RVcmwpO1xuICAgIHRoaXMudXBkYXRlTWV0YSh7cHJvdmlkZXJ9KTtcbiAgfVxuXG4gIF9nZXREYXRhQW5kTG9hZGVyT3B0aW9ucyhcbiAgICB0aWxlVXJsOiBzdHJpbmcsXG4gICAgYWNjZXNzVG9rZW4/OiBzdHJpbmdcbiAgKToge2RhdGE6IHN0cmluZzsgbG9hZE9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjsgbG9hZGVyPzogYW55fSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBgJHt0aWxlVXJsfTo6JHthY2Nlc3NUb2tlbiB8fCAnJ31gO1xuICAgIGlmICh0aGlzLl9jYWNoZWREYXRhQW5kTG9hZGVyICYmIHRoaXMuX2NhY2hlZERhdGFBbmRMb2FkZXIuX2NhY2hlS2V5ID09PSBjYWNoZUtleSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZERhdGFBbmRMb2FkZXI7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBnZXRUaWxlM0RQcm92aWRlckZyb21VcmwodGlsZVVybCk7XG4gICAgbGV0IHJlc3VsdDoge2RhdGE6IHN0cmluZzsgbG9hZE9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjsgbG9hZGVyPzogYW55fTtcblxuICAgIGlmIChwcm92aWRlciA9PT0gVElMRTNEX1BST1ZJREVSUy5nb29nbGUpIHtcbiAgICAgIGNvbnN0IHNlcGFyYXRvciA9IHRpbGVVcmwuaW5jbHVkZXMoJz8nKSA/ICcmJyA6ICc/JztcbiAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgZGF0YTogYCR7dGlsZVVybH0ke3NlcGFyYXRvcn1rZXk9JHthY2Nlc3NUb2tlbiB8fCAnJ31gLFxuICAgICAgICBsb2FkZXI6IFRpbGVzM0RMb2FkZXIsXG4gICAgICAgIGxvYWRPcHRpb25zOiB7XG4gICAgICAgICAgZmV0Y2g6IHtoZWFkZXJzOiB7J1gtR09PRy1BUEktS0VZJzogYWNjZXNzVG9rZW4gfHwgJyd9fVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAocHJvdmlkZXIgPT09IFRJTEUzRF9QUk9WSURFUlMuY2VzaXVtKSB7XG4gICAgICByZXN1bHQgPSB7XG4gICAgICAgIGRhdGE6IHRpbGVVcmwsXG4gICAgICAgIGxvYWRlcjogQ2VzaXVtSW9uTG9hZGVyLFxuICAgICAgICBsb2FkT3B0aW9uczoge1xuICAgICAgICAgICdjZXNpdW0taW9uJzoge2FjY2Vzc1Rva2VufVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAocHJvdmlkZXIgPT09IFRJTEUzRF9QUk9WSURFUlMuYXJjZ2lzKSB7XG4gICAgICByZXN1bHQgPSB7XG4gICAgICAgIGRhdGE6IHRpbGVVcmwsXG4gICAgICAgIGxvYWRlcjogSTNTTG9hZGVyLFxuICAgICAgICBsb2FkT3B0aW9uczoge1xuICAgICAgICAgIGkzczoge3VzZUNvbXByZXNzZWRUZXh0dXJlczogZmFsc2V9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgZGF0YTogdGlsZVVybCxcbiAgICAgICAgbG9hZGVyOiBUaWxlczNETG9hZGVyXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuX2NhY2hlZERhdGFBbmRMb2FkZXIgPSB7Li4ucmVzdWx0LCBfY2FjaGVLZXk6IGNhY2hlS2V5fTtcbiAgICByZXR1cm4gdGhpcy5fY2FjaGVkRGF0YUFuZExvYWRlcjtcbiAgfVxuXG4gIF9vblRpbGVzZXRMb2FkID0gKHRpbGVzZXQzZDogVGlsZXNldDNEKTogdm9pZCA9PiB7XG4gICAgdGhpcy5fZXh0cmFjdEJvdW5kc0Zyb21UaWxlc2V0KHRpbGVzZXQzZCk7XG5cbiAgICBjb25zdCB0aWxlVXJsID0gdGlsZXNldDNkLnVybCB8fCAnJztcbiAgICBjb25zdCBpc0dvb2dsZSA9IGdldFRpbGUzRFByb3ZpZGVyRnJvbVVybCh0aWxlVXJsKSA9PT0gVElMRTNEX1BST1ZJREVSUy5nb29nbGU7XG5cbiAgICBpZiAoIXRoaXMuX2hhc0ZpdHRlZEJvdW5kcyAmJiB0aGlzLm1ldGE/LmJvdW5kcyAmJiAhaXNHb29nbGUpIHtcbiAgICAgIHRoaXMuX2hhc0ZpdHRlZEJvdW5kcyA9IHRydWU7XG4gICAgICB0aGlzLl9sYXllckNhbGxiYWNrcz8ub25GaXRCb3VuZHM/Lih0aGlzLm1ldGEuYm91bmRzKTtcbiAgICB9XG5cbiAgICBpZiAoaXNHb29nbGUpIHtcbiAgICAgIHRpbGVzZXQzZC5vcHRpb25zLm9uVHJhdmVyc2FsQ29tcGxldGUgPSBzZWxlY3RlZFRpbGVzID0+IHtcbiAgICAgICAgY29uc3QgY3JlZGl0cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICBzZWxlY3RlZFRpbGVzLmZvckVhY2goKHRpbGU6IFRpbGUzRCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHtjb3B5cmlnaHR9ID0gKHRpbGUgYXMgYW55KS5jb250ZW50Py5nbHRmPy5hc3NldCB8fCB7fTtcbiAgICAgICAgICBpZiAoY29weXJpZ2h0KSBjb3B5cmlnaHQuc3BsaXQoJzsnKS5mb3JFYWNoKGMgPT4gY3JlZGl0cy5hZGQoYykpO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgdGl0bGUgPSBBcnJheS5mcm9tKGNyZWRpdHMpLmpvaW4oJzsgJyk7XG4gICAgICAgIHRoaXMudXBkYXRlTWV0YSh7XG4gICAgICAgICAgZ29vZ2xlQXR0cmlidXRpb246IHRpdGxlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2VsZWN0ZWRUaWxlcztcbiAgICAgIH07XG4gICAgfVxuICB9O1xuXG4gIF9leHRyYWN0Qm91bmRzRnJvbVRpbGVzZXQodGlsZXNldDNkOiBUaWxlc2V0M0QpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgcm9vdCA9IHRpbGVzZXQzZC5yb290O1xuICAgICAgaWYgKHJvb3QpIHtcbiAgICAgICAgY29uc3QgYmJveCA9IChyb290IGFzIGFueSkuYm91bmRpbmdCb3g7XG4gICAgICAgIGlmIChiYm94ICYmIGJib3gubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgY29uc3QgW21pbiwgbWF4XSA9IGJib3g7XG4gICAgICAgICAgLy8gYmJveCA9IFtbd2VzdERlZywgc291dGhEZWcsIG1pbkhlaWdodF0sIFtlYXN0RGVnLCBub3J0aERlZywgbWF4SGVpZ2h0XV1cbiAgICAgICAgICB0aGlzLnVwZGF0ZU1ldGEoe1xuICAgICAgICAgICAgYm91bmRzOiBbbWluWzBdLCBtaW5bMV0sIG1heFswXSwgbWF4WzFdXVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gYm91bmRpbmdCb3ggZ2V0dGVyIG1heSB0aHJvdyBmb3IgbWFsZm9ybWVkIHZvbHVtZXNcbiAgICB9XG5cbiAgICAvLyBGYWxsYmFjazogYXBwcm94aW1hdGUgYm91bmRzIGZyb20gY2FydG9ncmFwaGljQ2VudGVyIGFuZCB6b29tXG4gICAgY29uc3QgY2VudGVyID0gdGlsZXNldDNkLmNhcnRvZ3JhcGhpY0NlbnRlcjtcbiAgICBpZiAoY2VudGVyKSB7XG4gICAgICBjb25zdCBsbmcgPSBjZW50ZXJbMF07XG4gICAgICBjb25zdCBsYXQgPSBjZW50ZXJbMV07XG4gICAgICBjb25zdCB6b29tID0gdGlsZXNldDNkLnpvb20gfHwgMTQ7XG4gICAgICAvLyBBcHByb3hpbWF0ZSBoYWxmLXNwYW4gaW4gZGVncmVlcyBiYXNlZCBvbiB6b29tIGxldmVsXG4gICAgICBjb25zdCBzcGFuID0gMTgwIC8gTWF0aC5wb3coMiwgem9vbSk7XG4gICAgICB0aGlzLnVwZGF0ZU1ldGEoe1xuICAgICAgICBib3VuZHM6IFtsbmcgLSBzcGFuLCBsYXQgLSBzcGFuLCBsbmcgKyBzcGFuLCBsYXQgKyBzcGFuXVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX29uVGlsZUxvYWQgPSAodGlsZTogVGlsZTNEKTogdm9pZCA9PiB7XG4gICAgLy8gSTNTIG1hdGVyaWFscyBvZnRlbiBsYWNrIG1ldGFsbGljRmFjdG9yL3JvdWdobmVzc0ZhY3Rvci5cbiAgICAvLyBQQlIgc3BlYyBkZWZhdWx0cyBtZXRhbGxpY0ZhY3RvciB0byAxIChmdWxseSBtZXRhbGxpYyksXG4gICAgLy8gY2F1c2luZyBibGFjayBzdXJmYWNlcyB3aGVuIGxpZ2h0aW5nL3NoYWRvdyBlZmZlY3RzIGFyZSBhY3RpdmUuXG4gICAgY29uc3QgcGJyID0gdGlsZS5jb250ZW50Py5tYXRlcmlhbD8ucGJyTWV0YWxsaWNSb3VnaG5lc3M7XG4gICAgaWYgKHBicikge1xuICAgICAgaWYgKHBici5tZXRhbGxpY0ZhY3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBici5tZXRhbGxpY0ZhY3RvciA9IDA7XG4gICAgICB9XG4gICAgICBpZiAocGJyLnJvdWdobmVzc0ZhY3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBici5yb3VnaG5lc3NGYWN0b3IgPSAxO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBfb25UaWxlVW5sb2FkID0gKF90aWxlOiBUaWxlM0QpOiB2b2lkID0+IHtcbiAgICAvKiBub29wICovXG4gIH07XG5cbiAgcmVuZGVyTGF5ZXIob3B0czogYW55KTogS2VwbGVyVGlsZTNETGF5ZXJbXSB7XG4gICAgY29uc3Qge2RhdGEsIGxheWVyQ2FsbGJhY2tzfSA9IG9wdHM7XG4gICAgY29uc3Qge3RpbGUzZFVybCwgdGlsZTNkQWNjZXNzVG9rZW59ID0gZGF0YSB8fCB7fTtcbiAgICBpZiAoIXRpbGUzZFVybCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHRoaXMuX2xheWVyQ2FsbGJhY2tzID0gbGF5ZXJDYWxsYmFja3MgfHwgbnVsbDtcblxuICAgIGNvbnN0IHt2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG4gICAgY29uc3QgZGVmYXVsdExheWVyUHJvcHMgPSB0aGlzLmdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyhvcHRzKTtcbiAgICBjb25zdCB7XG4gICAgICBkYXRhOiB0aWxlRGF0YSxcbiAgICAgIGxvYWRPcHRpb25zLFxuICAgICAgbG9hZGVyXG4gICAgfSA9IHRoaXMuX2dldERhdGFBbmRMb2FkZXJPcHRpb25zKHRpbGUzZFVybCwgdGlsZTNkQWNjZXNzVG9rZW4pO1xuXG4gICAgY29uc3Qge2NvbG9yfSA9IHRoaXMuY29uZmlnO1xuICAgIGNvbnN0IHBvaW50Q29sb3I6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gY29sb3JcbiAgICAgID8gW2NvbG9yWzBdLCBjb2xvclsxXSwgY29sb3JbMl0sIDI1NV1cbiAgICAgIDogWzI1NSwgMjU1LCAyNTUsIDI1NV07XG5cbiAgICByZXR1cm4gW1xuICAgICAgbmV3IEtlcGxlclRpbGUzRExheWVyKHtcbiAgICAgICAgaWQ6IGRlZmF1bHRMYXllclByb3BzLmlkLFxuICAgICAgICBjb29yZGluYXRlU3lzdGVtOiBkZWZhdWx0TGF5ZXJQcm9wcy5jb29yZGluYXRlU3lzdGVtLFxuICAgICAgICB3cmFwTG9uZ2l0dWRlOiBkZWZhdWx0TGF5ZXJQcm9wcy53cmFwTG9uZ2l0dWRlLFxuICAgICAgICB2aXNpYmxlOiBkZWZhdWx0TGF5ZXJQcm9wcy52aXNpYmxlLFxuICAgICAgICBkYXRhOiB0aWxlRGF0YSxcbiAgICAgICAgbG9hZGVyLFxuICAgICAgICBsb2FkT3B0aW9ucyxcbiAgICAgICAgb25UaWxlc2V0TG9hZDogdGhpcy5fb25UaWxlc2V0TG9hZCxcbiAgICAgICAgb25UaWxlTG9hZDogdGhpcy5fb25UaWxlTG9hZCxcbiAgICAgICAgb25UaWxlVW5sb2FkOiB0aGlzLl9vblRpbGVVbmxvYWQsXG4gICAgICAgIGdldFBvaW50Q29sb3I6IHBvaW50Q29sb3IsXG4gICAgICAgIHBvaW50U2l6ZTogdmlzQ29uZmlnLnBvaW50U2l6ZSA/PyAyLFxuICAgICAgICBwaWNrYWJsZTogZmFsc2UsXG4gICAgICAgIG9wYWNpdHk6IHZpc0NvbmZpZy5vcGFjaXR5ID8/IDEsXG4gICAgICAgIGV4dGVuc2lvbnM6IEVNUFRZX0VYVEVOU0lPTlMsXG4gICAgICAgIHBhcmFtZXRlcnM6IERFUFRIX1RFU1RfUEFSQU1TXG4gICAgICB9KVxuICAgIF07XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxVQUFBLEdBQUFDLE9BQUE7QUFFQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxJQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxNQUFBLEdBQUFILE9BQUE7QUFFQSxJQUFBSSxVQUFBLEdBQUFDLHNCQUFBLENBQUFMLE9BQUE7QUFDQSxJQUFBTSxnQkFBQSxHQUFBRCxzQkFBQSxDQUFBTCxPQUFBO0FBRUEsSUFBQU8sVUFBQSxHQUFBUCxPQUFBO0FBTThCLFNBQUFRLFFBQUFDLENBQUEsRUFBQUMsQ0FBQSxRQUFBQyxDQUFBLEdBQUFDLE1BQUEsQ0FBQUMsSUFBQSxDQUFBSixDQUFBLE9BQUFHLE1BQUEsQ0FBQUUscUJBQUEsUUFBQUMsQ0FBQSxHQUFBSCxNQUFBLENBQUFFLHFCQUFBLENBQUFMLENBQUEsR0FBQUMsQ0FBQSxLQUFBSyxDQUFBLEdBQUFBLENBQUEsQ0FBQUMsTUFBQSxXQUFBTixDQUFBLFdBQUFFLE1BQUEsQ0FBQUssd0JBQUEsQ0FBQVIsQ0FBQSxFQUFBQyxDQUFBLEVBQUFRLFVBQUEsT0FBQVAsQ0FBQSxDQUFBUSxJQUFBLENBQUFDLEtBQUEsQ0FBQVQsQ0FBQSxFQUFBSSxDQUFBLFlBQUFKLENBQUE7QUFBQSxTQUFBVSxjQUFBWixDQUFBLGFBQUFDLENBQUEsTUFBQUEsQ0FBQSxHQUFBWSxTQUFBLENBQUFDLE1BQUEsRUFBQWIsQ0FBQSxVQUFBQyxDQUFBLFdBQUFXLFNBQUEsQ0FBQVosQ0FBQSxJQUFBWSxTQUFBLENBQUFaLENBQUEsUUFBQUEsQ0FBQSxPQUFBRixPQUFBLENBQUFJLE1BQUEsQ0FBQUQsQ0FBQSxPQUFBYSxPQUFBLFdBQUFkLENBQUEsUUFBQWUsZ0JBQUEsYUFBQWhCLENBQUEsRUFBQUMsQ0FBQSxFQUFBQyxDQUFBLENBQUFELENBQUEsU0FBQUUsTUFBQSxDQUFBYyx5QkFBQSxHQUFBZCxNQUFBLENBQUFlLGdCQUFBLENBQUFsQixDQUFBLEVBQUFHLE1BQUEsQ0FBQWMseUJBQUEsQ0FBQWYsQ0FBQSxLQUFBSCxPQUFBLENBQUFJLE1BQUEsQ0FBQUQsQ0FBQSxHQUFBYSxPQUFBLFdBQUFkLENBQUEsSUFBQUUsTUFBQSxDQUFBZ0IsY0FBQSxDQUFBbkIsQ0FBQSxFQUFBQyxDQUFBLEVBQUFFLE1BQUEsQ0FBQUssd0JBQUEsQ0FBQU4sQ0FBQSxFQUFBRCxDQUFBLGlCQUFBRCxDQUFBO0FBQUEsU0FBQW9CLFdBQUFsQixDQUFBLEVBQUFJLENBQUEsRUFBQU4sQ0FBQSxXQUFBTSxDQUFBLE9BQUFlLGdCQUFBLGFBQUFmLENBQUEsT0FBQWdCLDJCQUFBLGFBQUFwQixDQUFBLEVBQUFxQix5QkFBQSxLQUFBQyxPQUFBLENBQUFDLFNBQUEsQ0FBQW5CLENBQUEsRUFBQU4sQ0FBQSxZQUFBcUIsZ0JBQUEsYUFBQW5CLENBQUEsRUFBQXdCLFdBQUEsSUFBQXBCLENBQUEsQ0FBQUssS0FBQSxDQUFBVCxDQUFBLEVBQUFGLENBQUE7QUFBQSxTQUFBdUIsMEJBQUEsY0FBQXJCLENBQUEsSUFBQXlCLE9BQUEsQ0FBQUMsU0FBQSxDQUFBQyxPQUFBLENBQUFDLElBQUEsQ0FBQU4sT0FBQSxDQUFBQyxTQUFBLENBQUFFLE9BQUEsaUNBQUF6QixDQUFBLGFBQUFxQix5QkFBQSxZQUFBQSwwQkFBQSxhQUFBckIsQ0FBQTtBQUFBLFNBQUE2QixjQUFBN0IsQ0FBQSxFQUFBRixDQUFBLEVBQUFDLENBQUEsRUFBQUssQ0FBQSxRQUFBMEIsQ0FBQSxPQUFBQyxLQUFBLGlCQUFBWixnQkFBQSxpQkFBQWYsQ0FBQSxHQUFBSixDQUFBLENBQUEwQixTQUFBLEdBQUExQixDQUFBLEdBQUFGLENBQUEsRUFBQUMsQ0FBQSxjQUFBSyxDQUFBLGFBQUFKLENBQUEsV0FBQThCLENBQUEsQ0FBQXJCLEtBQUEsQ0FBQVYsQ0FBQSxFQUFBQyxDQUFBLE9BQUE4QixDQUFBLElBbEI5QjtBQUNBO0FBcUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUEsSUFDTUUsaUJBQWlCLDBCQUFBQyxnQkFBQTtFQUFBLFNBQUFELGtCQUFBO0lBQUEsSUFBQUUsZ0JBQUEsbUJBQUFGLGlCQUFBO0lBQUEsT0FBQWQsVUFBQSxPQUFBYyxpQkFBQSxFQUFBckIsU0FBQTtFQUFBO0VBQUEsSUFBQXdCLFVBQUEsYUFBQUgsaUJBQUEsRUFBQUMsZ0JBQUE7RUFBQSxXQUFBRyxhQUFBLGFBQUFKLGlCQUFBO0lBQUFLLEdBQUE7SUFBQUMsS0FBQSxFQUNyQjtJQUFBO01BQUEsSUFBQUMsYUFBQSxPQUFBQyxrQkFBQSwyQkFBQUMsWUFBQSxZQUFBQyxJQUFBLENBQ0EsU0FBQUMsUUFBMkJDLFVBQWtCO1FBQUEsSUFBQUMsY0FBQTtRQUFBLE9BQUFKLFlBQUEsWUFBQUssSUFBQSxVQUFBQyxTQUFBQyxRQUFBO1VBQUEsa0JBQUFBLFFBQUEsQ0FBQUMsSUFBQSxHQUFBRCxRQUFBLENBQUFFLElBQUE7WUFBQTtjQUFBRixRQUFBLENBQUFDLElBQUE7Y0FBQUQsUUFBQSxDQUFBRSxJQUFBO2NBQUEsT0FBQXJCLGFBQUEsQ0FBQUcsaUJBQUEsNEJBR2hCWSxVQUFVO1lBQUE7Y0FBQUksUUFBQSxDQUFBRSxJQUFBO2NBQUE7WUFBQTtjQUFBRixRQUFBLENBQUFDLElBQUE7Y0FBQUQsUUFBQSxDQUFBRyxFQUFBLEdBQUFILFFBQUE7Y0FFbkMsSUFBQUEsUUFBQSxDQUFBRyxFQUFBLGFBQUFILFFBQUEsQ0FBQUcsRUFBQSxnQkFBQU4sY0FBQSxHQUFJRyxRQUFBLENBQUFHLEVBQUEsQ0FBT0MsT0FBTyxjQUFBUCxjQUFBLGVBQWRBLGNBQUEsQ0FBZ0JRLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFO2dCQUNoRCxJQUFJLENBQUNDLFVBQVUsQ0FBQyxJQUFJQyxLQUFLLENBQUMsdUNBQXVDLENBQUMsRUFBRSxjQUFjLENBQUM7Y0FDckYsQ0FBQyxNQUFNO2dCQUNMQyxPQUFPLENBQUNDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBQVQsUUFBQSxDQUFBRyxFQUFPLENBQUM7Y0FDekQ7WUFBQztZQUFBO2NBQUEsT0FBQUgsUUFBQSxDQUFBVSxJQUFBO1VBQUE7UUFBQSxHQUFBZixPQUFBO01BQUEsQ0FFSjtNQUFBLFNBWGFnQixZQUFZQSxDQUFBQyxFQUFBO1FBQUEsT0FBQXJCLGFBQUEsQ0FBQTlCLEtBQUEsT0FBQUUsU0FBQTtNQUFBO01BQUEsT0FBWmdELFlBQVk7SUFBQTtJQWExQjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7SUFDRTtFQUFBO0lBQUF0QixHQUFBO0lBQUFDLEtBQUEsRUFDQSxTQUFRdUIsY0FBY0EsQ0FBQ0MsU0FBcUMsRUFBUTtNQUFBLElBQUFDLEtBQUE7TUFDbEUsSUFBSSxDQUFDRCxTQUFTLEVBQUU7TUFDaEIsSUFBQUUsSUFBQSxHQUFvQixJQUFJLENBQUNDLEtBQUs7UUFBdkJDLFNBQVMsR0FBQUYsSUFBQSxDQUFURSxTQUFTO01BQ2hCLElBQU9DLFFBQVEsR0FBSSxJQUFJLENBQUNDLE9BQU8sQ0FBeEJELFFBQVE7TUFDZixJQUFNRSxlQUFlLEdBQUdwRSxNQUFNLENBQUNDLElBQUksQ0FBQzRELFNBQVMsQ0FBQyxDQUFDbEQsTUFBTTtNQUNyRCxJQUFJLENBQUN1RCxRQUFRLElBQUksQ0FBQ0UsZUFBZSxJQUFJLENBQUNILFNBQVMsRUFBRTtNQUVqREEsU0FBUyxDQUNOSSxXQUFXLENBQUNyRSxNQUFNLENBQUNzRSxNQUFNLENBQUNULFNBQVMsQ0FBQyxDQUFDLENBQ3JDVSxJQUFJLENBQUMsVUFBQ0MsV0FBbUIsRUFBSztRQUM3QixJQUFNQyxjQUFjLEdBQUlYLEtBQUksQ0FBQ0UsS0FBSyxDQUFTUSxXQUFXLEtBQUtBLFdBQVc7UUFDdEUsSUFBSUMsY0FBYyxFQUFFO1VBQ2xCWCxLQUFJLENBQUNZLFFBQVEsQ0FBQztZQUFDRixXQUFXLEVBQVhBO1VBQVcsQ0FBQyxDQUFDO1FBQzlCO01BQ0YsQ0FBQyxDQUFDLFNBQ0ksQ0FBQyxVQUFDaEIsS0FBVSxFQUFLO1FBQ3JCRCxPQUFPLENBQUNDLEtBQUssQ0FBQyxnQ0FBZ0MsRUFBRUEsS0FBSyxDQUFDO01BQ3hELENBQUMsQ0FBQztJQUNOOztJQUVBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtFQUFBO0lBQUFwQixHQUFBO0lBQUFDLEtBQUEsRUFDQSxTQUFBc0MsV0FBV0EsQ0FBQ0MsTUFBOEIsRUFBUTtNQUNoRGhELGFBQUEsQ0FBQUcsaUJBQUEsMkJBQWtCNkMsTUFBTTtNQUN4QixJQUFJQSxNQUFNLENBQUNDLFdBQVcsQ0FBQ0MsaUJBQWlCLEVBQUU7UUFDeEMsSUFBQUMsS0FBQSxHQUFtQixJQUFJLENBQUNmLEtBQUs7VUFBdEJnQixRQUFRLEdBQUFELEtBQUEsQ0FBUkMsUUFBUTtRQUNmLElBQUlBLFFBQVEsRUFBRTtVQUNaLFNBQUFDLEVBQUEsTUFBQUMsWUFBQSxHQUFrQmxGLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDK0UsUUFBUSxDQUFDLEVBQUFDLEVBQUEsR0FBQUMsWUFBQSxDQUFBdkUsTUFBQSxFQUFBc0UsRUFBQSxJQUFFO1lBQUEsSUFBQUUsV0FBQTtZQUFwQyxJQUFNL0MsR0FBRyxHQUFBOEMsWUFBQSxDQUFBRCxFQUFBO1lBQ1osSUFBTUcsS0FBSyxHQUFHSixRQUFRLENBQUM1QyxHQUFHLENBQUM7WUFDM0IsSUFBSSxFQUFBK0MsV0FBQSxHQUFBQyxLQUFLLENBQUNDLElBQUksY0FBQUYsV0FBQSx1QkFBVkEsV0FBQSxDQUFZRyxJQUFJLE1BQUtDLGdCQUFTLENBQUNDLFVBQVUsRUFBRTtjQUM3Q0osS0FBSyxDQUFDSyxLQUFLLEdBQUcsSUFBSTtjQUNsQkwsS0FBSyxDQUFDTSxXQUFXLEdBQUcsSUFBSTtZQUMxQjtVQUNGO1FBQ0Y7TUFDRjtJQUNGO0VBQUM7QUFBQSxFQTlENkJDLHNCQUFlO0FBZ0U5QzVELGlCQUFpQixDQUFTNkQsU0FBUyxHQUFHLG1CQUFtQjtBQUVuRCxJQUFNQyxpQkFBaUIsR0FBQUMsT0FBQSxDQUFBRCxpQkFBQSxHQUFHRSxzQkFBVyxDQUFDQyxNQUFNO0FBWTVDLElBQU1DLGdCQUFnQixHQUFBSCxPQUFBLENBQUFHLGdCQUFBLEdBQUc7RUFDOUJDLE9BQU8sRUFBQXpGLGFBQUEsQ0FBQUEsYUFBQSxLQUNGMEYsNEJBQWlCLENBQUNELE9BQU87SUFDNUJFLFlBQVksRUFBRSxDQUFDO0lBQ2ZDLFFBQVEsRUFBRTtFQUFTLEVBQ0Q7RUFDcEJDLFNBQVMsRUFBRTtJQUNUaEIsSUFBSSxFQUFFLFFBQWlCO0lBQ3ZCYyxZQUFZLEVBQUUsQ0FBQztJQUNmRyxLQUFLLEVBQUUsMkJBQTJCO0lBQ2xDQyxRQUFRLEVBQUUsS0FBSztJQUNmQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQ2hCQyxJQUFJLEVBQUUsR0FBRztJQUNUQyxLQUFLLEVBQUUsU0FBa0I7SUFDekJOLFFBQVEsRUFBRSxXQUFXO0lBQ3JCTyxnQkFBZ0IsRUFBRTtFQUNwQjtBQUNGLENBQUM7QUFFRCxJQUFNQyxnQkFBdUIsR0FBRyxFQUFFO0FBQ2xDLElBQU1DLGlCQUFpQixHQUFHO0VBQUNDLFNBQVMsRUFBRTtBQUFJLENBQUM7QUFFM0MsU0FBU0Msd0JBQXdCQSxDQUFBLEVBQXFEO0VBQUEsSUFBcERDLEdBQUcsR0FBQXZHLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUF3RyxTQUFBLEdBQUF4RyxTQUFBLE1BQUcsRUFBRTtFQUN4QyxTQUFBeUcsR0FBQSxNQUFBQyxhQUFBLEdBQWtCcEgsTUFBTSxDQUFDQyxJQUFJLENBQUNvSCwyQkFBZ0IsQ0FBQyxFQUFBRixHQUFBLEdBQUFDLGFBQUEsQ0FBQXpHLE1BQUEsRUFBQXdHLEdBQUEsSUFBRTtJQUE1QyxJQUFNL0UsR0FBRyxHQUFBZ0YsYUFBQSxDQUFBRCxHQUFBO0lBQ1osSUFBSUYsR0FBRyxDQUFDN0QsUUFBUSxDQUFDaUUsMkJBQWdCLENBQUNqRixHQUFHLENBQUMsQ0FBQ2tGLE1BQU0sQ0FBQyxFQUFFO01BQzlDLE9BQU9ELDJCQUFnQixDQUFDakYsR0FBRyxDQUFDO0lBQzlCO0VBQ0Y7RUFDQSxPQUFPLElBQUk7QUFDYjtBQUFDLElBRW9CbUYsV0FBVyxHQUFBekIsT0FBQSxxQ0FBQTBCLE1BQUE7RUFhOUIsU0FBQUQsWUFBWUUsS0FBNkMsRUFBRTtJQUFBLElBQUFDLE1BQUE7SUFBQSxJQUFBekYsZ0JBQUEsbUJBQUFzRixXQUFBO0lBQ3pERyxNQUFBLEdBQUF6RyxVQUFBLE9BQUFzRyxXQUFBLEdBQU1FLEtBQUs7SUFBRSxJQUFBNUcsZ0JBQUEsYUFBQTZHLE1BQUEsMEJBTkosSUFBSTtJQUFBLElBQUE3RyxnQkFBQSxhQUFBNkcsTUFBQSxxQkFFd0MsSUFBSTtJQUFBLElBQUE3RyxnQkFBQSxhQUFBNkcsTUFBQSxzQkFDaEMsS0FBSztJQUFBLElBQUE3RyxnQkFBQSxhQUFBNkcsTUFBQSxvQkFvSWYsVUFBQ3pELFNBQW9CLEVBQVc7TUFBQSxJQUFBMEQsV0FBQTtNQUMvQ0QsTUFBQSxDQUFLRSx5QkFBeUIsQ0FBQzNELFNBQVMsQ0FBQztNQUV6QyxJQUFNNEQsT0FBTyxHQUFHNUQsU0FBUyxDQUFDZ0QsR0FBRyxJQUFJLEVBQUU7TUFDbkMsSUFBTWEsUUFBUSxHQUFHZCx3QkFBd0IsQ0FBQ2EsT0FBTyxDQUFDLEtBQUtSLDJCQUFnQixDQUFDVSxNQUFNO01BRTlFLElBQUksQ0FBQ0wsTUFBQSxDQUFLTSxnQkFBZ0IsS0FBQUwsV0FBQSxHQUFJRCxNQUFBLENBQUtPLElBQUksY0FBQU4sV0FBQSxlQUFUQSxXQUFBLENBQVdPLE1BQU0sSUFBSSxDQUFDSixRQUFRLEVBQUU7UUFBQSxJQUFBSyxxQkFBQSxFQUFBQyxzQkFBQTtRQUM1RFYsTUFBQSxDQUFLTSxnQkFBZ0IsR0FBRyxJQUFJO1FBQzVCLENBQUFHLHFCQUFBLEdBQUFULE1BQUEsQ0FBS1csZUFBZSxjQUFBRixxQkFBQSxnQkFBQUMsc0JBQUEsR0FBcEJELHFCQUFBLENBQXNCRyxXQUFXLGNBQUFGLHNCQUFBLGVBQWpDQSxzQkFBQSxDQUFBekcsSUFBQSxDQUFBd0cscUJBQUEsRUFBb0NULE1BQUEsQ0FBS08sSUFBSSxDQUFDQyxNQUFNLENBQUM7TUFDdkQ7TUFFQSxJQUFJSixRQUFRLEVBQUU7UUFDWjdELFNBQVMsQ0FBQ3NFLE9BQU8sQ0FBQ0MsbUJBQW1CLEdBQUcsVUFBQUMsYUFBYSxFQUFJO1VBQ3ZELElBQU1DLE9BQU8sR0FBRyxJQUFJQyxHQUFHLENBQVMsQ0FBQztVQUNqQ0YsYUFBYSxDQUFDN0gsT0FBTyxDQUFDLFVBQUN5RSxJQUFZLEVBQUs7WUFBQSxJQUFBdUQsUUFBQTtZQUN0QyxJQUFBQyxLQUFBLEdBQW9CLEVBQUFELFFBQUEsR0FBQ3ZELElBQUksQ0FBU3lELE9BQU8sY0FBQUYsUUFBQSxnQkFBQUEsUUFBQSxHQUFyQkEsUUFBQSxDQUF1QkcsSUFBSSxjQUFBSCxRQUFBLHVCQUEzQkEsUUFBQSxDQUE2QkksS0FBSyxLQUFJLENBQUMsQ0FBQztjQUFyREMsU0FBUyxHQUFBSixLQUFBLENBQVRJLFNBQVM7WUFDaEIsSUFBSUEsU0FBUyxFQUFFQSxTQUFTLENBQUNDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQ3RJLE9BQU8sQ0FBQyxVQUFBdUksQ0FBQztjQUFBLE9BQUlULE9BQU8sQ0FBQ1UsR0FBRyxDQUFDRCxDQUFDLENBQUM7WUFBQSxFQUFDO1VBQ2xFLENBQUMsQ0FBQztVQUNGLElBQU1FLEtBQUssR0FBR0MsS0FBSyxDQUFDQyxJQUFJLENBQUNiLE9BQU8sQ0FBQyxDQUFDYyxJQUFJLENBQUMsSUFBSSxDQUFDO1VBQzVDOUIsTUFBQSxDQUFLK0IsVUFBVSxDQUFDO1lBQ2RDLGlCQUFpQixFQUFFTDtVQUNyQixDQUFDLENBQUM7VUFDRixPQUFPWixhQUFhO1FBQ3RCLENBQUM7TUFDSDtJQUNGLENBQUM7SUFBQSxJQUFBNUgsZ0JBQUEsYUFBQTZHLE1BQUEsaUJBa0NhLFVBQUNyQyxJQUFZLEVBQVc7TUFBQSxJQUFBc0UsYUFBQTtNQUNwQztNQUNBO01BQ0E7TUFDQSxJQUFNQyxHQUFHLElBQUFELGFBQUEsR0FBR3RFLElBQUksQ0FBQ3lELE9BQU8sY0FBQWEsYUFBQSxnQkFBQUEsYUFBQSxHQUFaQSxhQUFBLENBQWNFLFFBQVEsY0FBQUYsYUFBQSx1QkFBdEJBLGFBQUEsQ0FBd0JHLG9CQUFvQjtNQUN4RCxJQUFJRixHQUFHLEVBQUU7UUFDUCxJQUFJQSxHQUFHLENBQUNHLGNBQWMsS0FBSzdDLFNBQVMsRUFBRTtVQUNwQzBDLEdBQUcsQ0FBQ0csY0FBYyxHQUFHLENBQUM7UUFDeEI7UUFDQSxJQUFJSCxHQUFHLENBQUNJLGVBQWUsS0FBSzlDLFNBQVMsRUFBRTtVQUNyQzBDLEdBQUcsQ0FBQ0ksZUFBZSxHQUFHLENBQUM7UUFDekI7TUFDRjtJQUNGLENBQUM7SUFBQSxJQUFBbkosZ0JBQUEsYUFBQTZHLE1BQUEsbUJBRWUsVUFBQ3VDLEtBQWEsRUFBVztNQUN2QztJQUFBLENBQ0Q7SUE1TUN2QyxNQUFBLENBQUt3QyxpQkFBaUIsQ0FBQ2pFLGdCQUFnQixDQUFDO0lBQ3hDeUIsTUFBQSxDQUFLTyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQUMsT0FBQVAsTUFBQTtFQUNqQjtFQUFDLElBQUF4RixVQUFBLGFBQUFxRixXQUFBLEVBQUFDLE1BQUE7RUFBQSxXQUFBckYsYUFBQSxhQUFBb0YsV0FBQTtJQUFBbkYsR0FBQTtJQUFBK0gsR0FBQSxFQWtCRCxTQUFBQSxJQUFBLEVBQW1CO01BQ2pCLE9BQU90RSxpQkFBaUI7SUFDMUI7RUFBQztJQUFBekQsR0FBQTtJQUFBK0gsR0FBQSxFQUVELFNBQUFBLElBQUEsRUFBbUI7TUFDakIsT0FBTyxTQUFTO0lBQ2xCO0VBQUM7SUFBQS9ILEdBQUE7SUFBQStILEdBQUEsRUFFRCxTQUFBQSxJQUFBLEVBQTJCO01BQ3pCLE9BQU8sS0FBSztJQUNkO0VBQUM7SUFBQS9ILEdBQUE7SUFBQStILEdBQUEsRUFFRCxTQUFBQSxJQUFBLEVBQXFDO01BQ25DLE9BQU8sRUFBRTtJQUNYO0VBQUM7SUFBQ