UNPKG

kepler.gl

Version:

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

307 lines (300 loc) 39 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.clusterAggregation = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); 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 _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _layers = require("@deck.gl/layers"); var _aggregationLayers = require("@deck.gl/aggregation-layers"); var _geoViewport = _interopRequireDefault(require("@mapbox/geo-viewport")); var _cpuAggregator = _interopRequireWildcard(require("../layer-utils/cpu-aggregator")); var _viewportMercatorProject = require("viewport-mercator-project"); var _d3Array = require("d3-array"); var _constants = require("@kepler.gl/constants"); var _clusterUtils = _interopRequireWildcard(require("../layer-utils/cluster-utils")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 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; })(); } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project var defaultRadius = _constants.LAYER_VIS_CONFIGS.clusterRadius.defaultValue; var defaultRadiusRange = _constants.LAYER_VIS_CONFIGS.clusterRadiusRange.defaultValue; var defaultGetColorValue = function defaultGetColorValue(points) { return points.length; }; var defaultGetRadiusValue = function defaultGetRadiusValue(cell) { return cell.filteredPoints ? cell.filteredPoints.length : cell.points.length; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars function processGeoJSON(step, props, aggregation, _ref) { var viewport = _ref.viewport; var data = props.data, getPosition = props.getPosition, filterData = props.filterData; var geoJSON = (0, _clusterUtils.getGeoJSON)(data, getPosition, filterData); var clusterBuilder = new _clusterUtils["default"](); this.setState({ geoJSON: geoJSON, clusterBuilder: clusterBuilder }); } // eslint-disable-next-line @typescript-eslint/no-unused-vars function getClusters(step, props, aggregation, _ref2) { var viewport = _ref2.viewport; var _this$state = this.state, geoJSON = _this$state.geoJSON, clusterBuilder = _this$state.clusterBuilder; var clusterRadius = props.clusterRadius, zoom = props.zoom, width = props.width, height = props.height; var longitude = viewport.longitude, latitude = viewport.latitude; // zoom needs to be an integer for the different map utils. Also helps with cache key. var bbox = _geoViewport["default"].bounds([longitude, latitude], zoom, [width, height]); var clusters = clusterBuilder.clustersAtZoom({ bbox: bbox, clusterRadius: clusterRadius, geoJSON: geoJSON, zoom: zoom }); this.setState({ layerData: { data: clusters } }); } function getSubLayerRadius(dimensionState, dimension, layerProps) { return function (cell) { var getRadiusValue = layerProps.getRadiusValue; var scaleFunc = dimensionState.scaleFunc; return scaleFunc(getRadiusValue(cell)); }; } var clusterAggregation = exports.clusterAggregation = { key: 'position', updateSteps: [{ key: 'geojson', triggers: { position: { prop: 'getPosition', updateTrigger: 'getPosition' }, filterData: { prop: 'filterData', updateTrigger: 'filterData' } }, updater: processGeoJSON }, { key: 'clustering', triggers: { clusterRadius: { prop: 'clusterRadius' }, zoom: { prop: 'zoom' }, width: { prop: 'width' }, height: { prop: 'height' } }, updater: getClusters }] }; function getRadiusValueDomain(step, props, dimensionUpdater) { var key = dimensionUpdater.key; var getRadiusValue = props.getRadiusValue; var layerData = this.state.layerData; var valueDomain = [0, (0, _d3Array.max)(layerData.data, getRadiusValue)]; this._setDimensionState(key, { valueDomain: valueDomain }); } var clusterLayerDimensions = [_cpuAggregator.defaultColorDimension, { key: 'radius', accessor: 'getRadius', nullValue: 0, updateSteps: [{ key: 'getDomain', triggers: { value: { prop: 'getRadiusValue', updateTrigger: 'getRadiusValue' } }, updater: getRadiusValueDomain }, { key: 'getScaleFunc', triggers: { domain: { prop: 'radiusDomain' }, range: { prop: 'radiusRange' }, scaleType: { prop: 'radiusScaleType' } }, updater: _cpuAggregator.getDimensionScale }], getSubLayerAccessor: getSubLayerRadius, getPickingInfo: function getPickingInfo(dimensionState, cell, layerProps) { var radiusValue = layerProps.getRadiusValue(cell); var scaleFunc = dimensionState.scaleFunc; var scaledRadiusValue = scaleFunc ? scaleFunc(radiusValue) : radiusValue; return { radiusValue: radiusValue, scaledRadiusValue: scaledRadiusValue }; } }]; var defaultProps = { clusterRadius: defaultRadius, colorDomain: null, colorRange: _constants.DEFAULT_COLOR_RANGE, colorScaleType: _constants.SCALE_TYPES.quantize, radiusScaleType: _constants.SCALE_TYPES.sqrt, radiusRange: defaultRadiusRange, getPosition: { type: 'accessor', value: function value(x) { return x.position; } }, getColorValue: { type: 'accessor', value: defaultGetColorValue }, getRadiusValue: { type: 'accessor', value: defaultGetRadiusValue } }; var ClusterLayer = exports["default"] = /*#__PURE__*/function (_AggregationLayer) { function ClusterLayer() { (0, _classCallCheck2["default"])(this, ClusterLayer); return _callSuper(this, ClusterLayer, arguments); } (0, _inherits2["default"])(ClusterLayer, _AggregationLayer); return (0, _createClass2["default"])(ClusterLayer, [{ key: "initializeState", value: function initializeState() { var cpuAggregator = new _cpuAggregator["default"]({ aggregation: clusterAggregation, dimensions: clusterLayerDimensions }); this.state = { cpuAggregator: cpuAggregator, aggregatorState: cpuAggregator.state }; var attributeManager = this.getAttributeManager(); attributeManager.add({ positions: { size: 3, accessor: 'getPosition' } }); } }, { key: "updateState", value: function updateState(_ref3) { var oldProps = _ref3.oldProps, props = _ref3.props, changeFlags = _ref3.changeFlags; this.setState({ // make a copy of the internal state of cpuAggregator for testing aggregatorState: this.state.cpuAggregator.updateState({ oldProps: oldProps, props: props, changeFlags: changeFlags }, { viewport: this.context.viewport, attributes: this.getAttributes(), numInstances: this.getNumInstances(props) }) }); } }, { key: "getPickingInfo", value: function getPickingInfo(_ref4) { var info = _ref4.info; var obj = this.state.cpuAggregator.getPickingInfo({ info: info }, this.props); if (obj !== null && obj !== void 0 && obj.object) { // @ts-expect-error var distanceScale = (0, _viewportMercatorProject.getDistanceScales)(this.context.viewport); var metersPerPixel = distanceScale.metersPerPixel[0]; obj.object.scaledRadiusValue = obj.object.scaledRadiusValue * metersPerPixel; } return obj; } }, { key: "_getSublayerUpdateTriggers", value: function _getSublayerUpdateTriggers() { return this.state.cpuAggregator.getUpdateTriggers(this.props); } }, { key: "_getSubLayerAccessors", value: function _getSubLayerAccessors() { return { getRadius: this.state.cpuAggregator.getAccessor('radius', this.props), getFillColor: this.state.cpuAggregator.getAccessor('fillColor', this.props) }; } }, { key: "renderLayers", value: function renderLayers() { // for subclassing, override this method to return // customized sub layer props var _this$props = this.props, id = _this$props.id, radiusScale = _this$props.radiusScale; var cpuAggregator = this.state.cpuAggregator; // base layer props var _this$props2 = this.props, visible = _this$props2.visible, opacity = _this$props2.opacity, pickable = _this$props2.pickable, autoHighlight = _this$props2.autoHighlight, highlightColor = _this$props2.highlightColor; var updateTriggers = this._getSublayerUpdateTriggers(); var accessors = this._getSubLayerAccessors(); // @ts-expect-error var distanceScale = (0, _viewportMercatorProject.getDistanceScales)(this.context.viewport); var metersPerPixel = distanceScale.metersPerPixel[0]; // return props to the sublayer constructor return new _layers.ScatterplotLayer(_objectSpread({ id: "".concat(id, "-cluster"), data: cpuAggregator.state.layerData.data, radiusScale: metersPerPixel * radiusScale, visible: visible, opacity: opacity, pickable: pickable, autoHighlight: autoHighlight, highlightColor: highlightColor, updateTriggers: updateTriggers, parameters: { depthMask: false } }, accessors)); } }]); }(_aggregationLayers._AggregationLayer); ClusterLayer.layerName = 'ClusterLayer'; ClusterLayer.defaultProps = defaultProps; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbGF5ZXJzIiwicmVxdWlyZSIsIl9hZ2dyZWdhdGlvbkxheWVycyIsIl9nZW9WaWV3cG9ydCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfY3B1QWdncmVnYXRvciIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX3ZpZXdwb3J0TWVyY2F0b3JQcm9qZWN0IiwiX2QzQXJyYXkiLCJfY29uc3RhbnRzIiwiX2NsdXN0ZXJVdGlscyIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiX3R5cGVvZiIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIm93bktleXMiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsIl9jYWxsU3VwZXIiLCJfZ2V0UHJvdG90eXBlT2YyIiwiX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yIiwiX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCIsIlJlZmxlY3QiLCJjb25zdHJ1Y3QiLCJjb25zdHJ1Y3RvciIsIkJvb2xlYW4iLCJwcm90b3R5cGUiLCJ2YWx1ZU9mIiwiZGVmYXVsdFJhZGl1cyIsIkxBWUVSX1ZJU19DT05GSUdTIiwiY2x1c3RlclJhZGl1cyIsImRlZmF1bHRWYWx1ZSIsImRlZmF1bHRSYWRpdXNSYW5nZSIsImNsdXN0ZXJSYWRpdXNSYW5nZSIsImRlZmF1bHRHZXRDb2xvclZhbHVlIiwicG9pbnRzIiwiZGVmYXVsdEdldFJhZGl1c1ZhbHVlIiwiY2VsbCIsImZpbHRlcmVkUG9pbnRzIiwicHJvY2Vzc0dlb0pTT04iLCJzdGVwIiwicHJvcHMiLCJhZ2dyZWdhdGlvbiIsIl9yZWYiLCJ2aWV3cG9ydCIsImRhdGEiLCJnZXRQb3NpdGlvbiIsImZpbHRlckRhdGEiLCJnZW9KU09OIiwiZ2V0R2VvSlNPTiIsImNsdXN0ZXJCdWlsZGVyIiwiQ2x1c3RlckJ1aWxkZXIiLCJzZXRTdGF0ZSIsImdldENsdXN0ZXJzIiwiX3JlZjIiLCJfdGhpcyRzdGF0ZSIsInN0YXRlIiwiem9vbSIsIndpZHRoIiwiaGVpZ2h0IiwibG9uZ2l0dWRlIiwibGF0aXR1ZGUiLCJiYm94IiwiZ2VvVmlld3BvcnQiLCJib3VuZHMiLCJjbHVzdGVycyIsImNsdXN0ZXJzQXRab29tIiwibGF5ZXJEYXRhIiwiZ2V0U3ViTGF5ZXJSYWRpdXMiLCJkaW1lbnNpb25TdGF0ZSIsImRpbWVuc2lvbiIsImxheWVyUHJvcHMiLCJnZXRSYWRpdXNWYWx1ZSIsInNjYWxlRnVuYyIsImNsdXN0ZXJBZ2dyZWdhdGlvbiIsImV4cG9ydHMiLCJrZXkiLCJ1cGRhdGVTdGVwcyIsInRyaWdnZXJzIiwicG9zaXRpb24iLCJwcm9wIiwidXBkYXRlVHJpZ2dlciIsInVwZGF0ZXIiLCJnZXRSYWRpdXNWYWx1ZURvbWFpbiIsImRpbWVuc2lvblVwZGF0ZXIiLCJ2YWx1ZURvbWFpbiIsIm1heCIsIl9zZXREaW1lbnNpb25TdGF0ZSIsImNsdXN0ZXJMYXllckRpbWVuc2lvbnMiLCJkZWZhdWx0Q29sb3JEaW1lbnNpb24iLCJhY2Nlc3NvciIsIm51bGxWYWx1ZSIsInZhbHVlIiwiZG9tYWluIiwicmFuZ2UiLCJzY2FsZVR5cGUiLCJnZXREaW1lbnNpb25TY2FsZSIsImdldFN1YkxheWVyQWNjZXNzb3IiLCJnZXRQaWNraW5nSW5mbyIsInJhZGl1c1ZhbHVlIiwic2NhbGVkUmFkaXVzVmFsdWUiLCJkZWZhdWx0UHJvcHMiLCJjb2xvckRvbWFpbiIsImNvbG9yUmFuZ2UiLCJERUZBVUxUX0NPTE9SX1JBTkdFIiwiY29sb3JTY2FsZVR5cGUiLCJTQ0FMRV9UWVBFUyIsInF1YW50aXplIiwicmFkaXVzU2NhbGVUeXBlIiwic3FydCIsInJhZGl1c1JhbmdlIiwidHlwZSIsIngiLCJnZXRDb2xvclZhbHVlIiwiQ2x1c3RlckxheWVyIiwiX0FnZ3JlZ2F0aW9uTGF5ZXIiLCJfY2xhc3NDYWxsQ2hlY2syIiwiX2luaGVyaXRzMiIsIl9jcmVhdGVDbGFzczIiLCJpbml0aWFsaXplU3RhdGUiLCJjcHVBZ2dyZWdhdG9yIiwiQ1BVQWdncmVnYXRvciIsImRpbWVuc2lvbnMiLCJhZ2dyZWdhdG9yU3RhdGUiLCJhdHRyaWJ1dGVNYW5hZ2VyIiwiZ2V0QXR0cmlidXRlTWFuYWdlciIsImFkZCIsInBvc2l0aW9ucyIsInNpemUiLCJ1cGRhdGVTdGF0ZSIsIl9yZWYzIiwib2xkUHJvcHMiLCJjaGFuZ2VGbGFncyIsImNvbnRleHQiLCJhdHRyaWJ1dGVzIiwiZ2V0QXR0cmlidXRlcyIsIm51bUluc3RhbmNlcyIsImdldE51bUluc3RhbmNlcyIsIl9yZWY0IiwiaW5mbyIsIm9iaiIsIm9iamVjdCIsImRpc3RhbmNlU2NhbGUiLCJnZXREaXN0YW5jZVNjYWxlcyIsIm1ldGVyc1BlclBpeGVsIiwiX2dldFN1YmxheWVyVXBkYXRlVHJpZ2dlcnMiLCJnZXRVcGRhdGVUcmlnZ2VycyIsIl9nZXRTdWJMYXllckFjY2Vzc29ycyIsImdldFJhZGl1cyIsImdldEFjY2Vzc29yIiwiZ2V0RmlsbENvbG9yIiwicmVuZGVyTGF5ZXJzIiwiX3RoaXMkcHJvcHMiLCJpZCIsInJhZGl1c1NjYWxlIiwiX3RoaXMkcHJvcHMyIiwidmlzaWJsZSIsIm9wYWNpdHkiLCJwaWNrYWJsZSIsImF1dG9IaWdobGlnaHQiLCJoaWdobGlnaHRDb2xvciIsInVwZGF0ZVRyaWdnZXJzIiwiYWNjZXNzb3JzIiwiU2NhdHRlcnBsb3RMYXllciIsImNvbmNhdCIsInBhcmFtZXRlcnMiLCJkZXB0aE1hc2siLCJBZ2dyZWdhdGlvbkxheWVyIiwibGF5ZXJOYW1lIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsdXN0ZXItbGF5ZXIvY2x1c3Rlci1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge1NjYXR0ZXJwbG90TGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2xheWVycyc7XG5pbXBvcnQge19BZ2dyZWdhdGlvbkxheWVyIGFzIEFnZ3JlZ2F0aW9uTGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2FnZ3JlZ2F0aW9uLWxheWVycyc7XG5cbmltcG9ydCBnZW9WaWV3cG9ydCBmcm9tICdAbWFwYm94L2dlby12aWV3cG9ydCc7XG5pbXBvcnQgQ1BVQWdncmVnYXRvciwge1xuICBBZ2dyZWdhdGlvblR5cGUsXG4gIGRlZmF1bHRDb2xvckRpbWVuc2lvbixcbiAgRGltZW5zaW9uVHlwZSxcbiAgZ2V0RGltZW5zaW9uU2NhbGVcbn0gZnJvbSAnLi4vbGF5ZXItdXRpbHMvY3B1LWFnZ3JlZ2F0b3InO1xuaW1wb3J0IHtnZXREaXN0YW5jZVNjYWxlc30gZnJvbSAndmlld3BvcnQtbWVyY2F0b3ItcHJvamVjdCc7XG5pbXBvcnQge21heH0gZnJvbSAnZDMtYXJyYXknO1xuXG5pbXBvcnQge1NDQUxFX1RZUEVTLCBERUZBVUxUX0NPTE9SX1JBTkdFLCBMQVlFUl9WSVNfQ09ORklHU30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IENsdXN0ZXJCdWlsZGVyLCB7Z2V0R2VvSlNPTn0gZnJvbSAnLi4vbGF5ZXItdXRpbHMvY2x1c3Rlci11dGlscyc7XG5pbXBvcnQge1JHQkFDb2xvcn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge0FnZ3JlZ2F0aW9uTGF5ZXJQcm9wc30gZnJvbSAnQGRlY2suZ2wvYWdncmVnYXRpb24tbGF5ZXJzL2FnZ3JlZ2F0aW9uLWxheWVyJztcblxuY29uc3QgZGVmYXVsdFJhZGl1cyA9IExBWUVSX1ZJU19DT05GSUdTLmNsdXN0ZXJSYWRpdXMuZGVmYXVsdFZhbHVlO1xuY29uc3QgZGVmYXVsdFJhZGl1c1JhbmdlID0gTEFZRVJfVklTX0NPTkZJR1MuY2x1c3RlclJhZGl1c1JhbmdlLmRlZmF1bHRWYWx1ZTtcblxuY29uc3QgZGVmYXVsdEdldENvbG9yVmFsdWUgPSBwb2ludHMgPT4gcG9pbnRzLmxlbmd0aDtcbmNvbnN0IGRlZmF1bHRHZXRSYWRpdXNWYWx1ZSA9IGNlbGwgPT5cbiAgY2VsbC5maWx0ZXJlZFBvaW50cyA/IGNlbGwuZmlsdGVyZWRQb2ludHMubGVuZ3RoIDogY2VsbC5wb2ludHMubGVuZ3RoO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG5mdW5jdGlvbiBwcm9jZXNzR2VvSlNPTih0aGlzOiBDUFVBZ2dyZWdhdG9yLCBzdGVwLCBwcm9wcywgYWdncmVnYXRpb24sIHt2aWV3cG9ydH0pIHtcbiAgY29uc3Qge2RhdGEsIGdldFBvc2l0aW9uLCBmaWx0ZXJEYXRhfSA9IHByb3BzO1xuICBjb25zdCBnZW9KU09OID0gZ2V0R2VvSlNPTihkYXRhLCBnZXRQb3NpdGlvbiwgZmlsdGVyRGF0YSk7XG4gIGNvbnN0IGNsdXN0ZXJCdWlsZGVyID0gbmV3IENsdXN0ZXJCdWlsZGVyKCk7XG5cbiAgdGhpcy5zZXRTdGF0ZSh7Z2VvSlNPTiwgY2x1c3RlckJ1aWxkZXJ9KTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuZnVuY3Rpb24gZ2V0Q2x1c3RlcnModGhpczogQ1BVQWdncmVnYXRvciwgc3RlcCwgcHJvcHMsIGFnZ3JlZ2F0aW9uLCB7dmlld3BvcnR9KSB7XG4gIGNvbnN0IHtnZW9KU09OLCBjbHVzdGVyQnVpbGRlcn0gPSB0aGlzLnN0YXRlO1xuICBjb25zdCB7Y2x1c3RlclJhZGl1cywgem9vbSwgd2lkdGgsIGhlaWdodH0gPSBwcm9wcztcbiAgY29uc3Qge2xvbmdpdHVkZSwgbGF0aXR1ZGV9ID0gdmlld3BvcnQ7XG5cbiAgLy8gem9vbSBuZWVkcyB0byBiZSBhbiBpbnRlZ2VyIGZvciB0aGUgZGlmZmVyZW50IG1hcCB1dGlscy4gQWxzbyBoZWxwcyB3aXRoIGNhY2hlIGtleS5cbiAgY29uc3QgYmJveCA9IGdlb1ZpZXdwb3J0LmJvdW5kcyhbbG9uZ2l0dWRlLCBsYXRpdHVkZV0sIHpvb20sIFt3aWR0aCwgaGVpZ2h0XSk7XG4gIGNvbnN0IGNsdXN0ZXJzID0gY2x1c3RlckJ1aWxkZXIuY2x1c3RlcnNBdFpvb20oe2Jib3gsIGNsdXN0ZXJSYWRpdXMsIGdlb0pTT04sIHpvb219KTtcblxuICB0aGlzLnNldFN0YXRlKHtcbiAgICBsYXllckRhdGE6IHtkYXRhOiBjbHVzdGVyc31cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFN1YkxheWVyUmFkaXVzKGRpbWVuc2lvblN0YXRlLCBkaW1lbnNpb24sIGxheWVyUHJvcHMpIHtcbiAgcmV0dXJuIGNlbGwgPT4ge1xuICAgIGNvbnN0IHtnZXRSYWRpdXNWYWx1ZX0gPSBsYXllclByb3BzO1xuICAgIGNvbnN0IHtzY2FsZUZ1bmN9ID0gZGltZW5zaW9uU3RhdGU7XG4gICAgcmV0dXJuIHNjYWxlRnVuYyhnZXRSYWRpdXNWYWx1ZShjZWxsKSk7XG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBjbHVzdGVyQWdncmVnYXRpb246IEFnZ3JlZ2F0aW9uVHlwZSA9IHtcbiAga2V5OiAncG9zaXRpb24nLFxuICB1cGRhdGVTdGVwczogW1xuICAgIHtcbiAgICAgIGtleTogJ2dlb2pzb24nLFxuICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBwcm9wOiAnZ2V0UG9zaXRpb24nLFxuICAgICAgICAgIHVwZGF0ZVRyaWdnZXI6ICdnZXRQb3NpdGlvbidcbiAgICAgICAgfSxcbiAgICAgICAgZmlsdGVyRGF0YToge1xuICAgICAgICAgIHByb3A6ICdmaWx0ZXJEYXRhJyxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZmlsdGVyRGF0YSdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHVwZGF0ZXI6IHByb2Nlc3NHZW9KU09OXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdjbHVzdGVyaW5nJyxcbiAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgIGNsdXN0ZXJSYWRpdXM6IHtcbiAgICAgICAgICBwcm9wOiAnY2x1c3RlclJhZGl1cydcbiAgICAgICAgfSxcbiAgICAgICAgem9vbToge1xuICAgICAgICAgIHByb3A6ICd6b29tJ1xuICAgICAgICB9LFxuICAgICAgICB3aWR0aDoge1xuICAgICAgICAgIHByb3A6ICd3aWR0aCdcbiAgICAgICAgfSxcbiAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgcHJvcDogJ2hlaWdodCdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHVwZGF0ZXI6IGdldENsdXN0ZXJzXG4gICAgfVxuICBdXG59O1xuXG5mdW5jdGlvbiBnZXRSYWRpdXNWYWx1ZURvbWFpbih0aGlzOiBDUFVBZ2dyZWdhdG9yLCBzdGVwLCBwcm9wcywgZGltZW5zaW9uVXBkYXRlcikge1xuICBjb25zdCB7a2V5fSA9IGRpbWVuc2lvblVwZGF0ZXI7XG4gIGNvbnN0IHtnZXRSYWRpdXNWYWx1ZX0gPSBwcm9wcztcbiAgY29uc3Qge2xheWVyRGF0YX0gPSB0aGlzLnN0YXRlO1xuXG4gIGNvbnN0IHZhbHVlRG9tYWluID0gWzAsIG1heChsYXllckRhdGEuZGF0YSwgZ2V0UmFkaXVzVmFsdWUpXTtcbiAgdGhpcy5fc2V0RGltZW5zaW9uU3RhdGUoa2V5LCB7dmFsdWVEb21haW59KTtcbn1cblxuY29uc3QgY2x1c3RlckxheWVyRGltZW5zaW9uczogW0RpbWVuc2lvblR5cGU8UkdCQUNvbG9yPiwgRGltZW5zaW9uVHlwZTxudW1iZXI+XSA9IFtcbiAgZGVmYXVsdENvbG9yRGltZW5zaW9uLFxuICB7XG4gICAga2V5OiAncmFkaXVzJyxcbiAgICBhY2Nlc3NvcjogJ2dldFJhZGl1cycsXG4gICAgbnVsbFZhbHVlOiAwLFxuICAgIHVwZGF0ZVN0ZXBzOiBbXG4gICAgICB7XG4gICAgICAgIGtleTogJ2dldERvbWFpbicsXG4gICAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgIHByb3A6ICdnZXRSYWRpdXNWYWx1ZScsXG4gICAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZ2V0UmFkaXVzVmFsdWUnXG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB1cGRhdGVyOiBnZXRSYWRpdXNWYWx1ZURvbWFpblxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAga2V5OiAnZ2V0U2NhbGVGdW5jJyxcbiAgICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgICBkb21haW46IHtwcm9wOiAncmFkaXVzRG9tYWluJ30sXG4gICAgICAgICAgcmFuZ2U6IHtwcm9wOiAncmFkaXVzUmFuZ2UnfSxcbiAgICAgICAgICBzY2FsZVR5cGU6IHtwcm9wOiAncmFkaXVzU2NhbGVUeXBlJ31cbiAgICAgICAgfSxcbiAgICAgICAgdXBkYXRlcjogZ2V0RGltZW5zaW9uU2NhbGVcbiAgICAgIH1cbiAgICBdLFxuICAgIGdldFN1YkxheWVyQWNjZXNzb3I6IGdldFN1YkxheWVyUmFkaXVzLFxuICAgIGdldFBpY2tpbmdJbmZvOiAoZGltZW5zaW9uU3RhdGUsIGNlbGwsIGxheWVyUHJvcHMpID0+IHtcbiAgICAgIGNvbnN0IHJhZGl1c1ZhbHVlID0gbGF5ZXJQcm9wcy5nZXRSYWRpdXNWYWx1ZShjZWxsKTtcbiAgICAgIGNvbnN0IHtzY2FsZUZ1bmN9ID0gZGltZW5zaW9uU3RhdGU7XG4gICAgICBjb25zdCBzY2FsZWRSYWRpdXNWYWx1ZSA9IHNjYWxlRnVuYyA/IHNjYWxlRnVuYyhyYWRpdXNWYWx1ZSkgOiByYWRpdXNWYWx1ZTtcblxuICAgICAgcmV0dXJuIHtyYWRpdXNWYWx1ZSwgc2NhbGVkUmFkaXVzVmFsdWV9O1xuICAgIH1cbiAgfVxuXTtcblxuY29uc3QgZGVmYXVsdFByb3BzID0ge1xuICBjbHVzdGVyUmFkaXVzOiBkZWZhdWx0UmFkaXVzLFxuICBjb2xvckRvbWFpbjogbnVsbCxcbiAgY29sb3JSYW5nZTogREVGQVVMVF9DT0xPUl9SQU5HRSxcbiAgY29sb3JTY2FsZVR5cGU6IFNDQUxFX1RZUEVTLnF1YW50aXplLFxuICByYWRpdXNTY2FsZVR5cGU6IFNDQUxFX1RZUEVTLnNxcnQsXG4gIHJhZGl1c1JhbmdlOiBkZWZhdWx0UmFkaXVzUmFuZ2UsXG4gIGdldFBvc2l0aW9uOiB7dHlwZTogJ2FjY2Vzc29yJywgdmFsdWU6IHggPT4geC5wb3NpdGlvbn0sXG4gIGdldENvbG9yVmFsdWU6IHt0eXBlOiAnYWNjZXNzb3InLCB2YWx1ZTogZGVmYXVsdEdldENvbG9yVmFsdWV9LFxuICBnZXRSYWRpdXNWYWx1ZToge3R5cGU6ICdhY2Nlc3NvcicsIHZhbHVlOiBkZWZhdWx0R2V0UmFkaXVzVmFsdWV9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDbHVzdGVyTGF5ZXIgZXh0ZW5kcyBBZ2dyZWdhdGlvbkxheWVyPFxuICBhbnksXG4gIEFnZ3JlZ2F0aW9uTGF5ZXJQcm9wczxhbnk+ICYge3JhZGl1c1NjYWxlOiBudW1iZXJ9XG4+IHtcbiAgaW5pdGlhbGl6ZVN0YXRlKCkge1xuICAgIGNvbnN0IGNwdUFnZ3JlZ2F0b3IgPSBuZXcgQ1BVQWdncmVnYXRvcih7XG4gICAgICBhZ2dyZWdhdGlvbjogY2x1c3RlckFnZ3JlZ2F0aW9uLFxuICAgICAgZGltZW5zaW9uczogY2x1c3RlckxheWVyRGltZW5zaW9uc1xuICAgIH0pO1xuXG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGNwdUFnZ3JlZ2F0b3IsXG4gICAgICBhZ2dyZWdhdG9yU3RhdGU6IGNwdUFnZ3JlZ2F0b3Iuc3RhdGVcbiAgICB9O1xuICAgIGNvbnN0IGF0dHJpYnV0ZU1hbmFnZXIgPSB0aGlzLmdldEF0dHJpYnV0ZU1hbmFnZXIoKTtcbiAgICBhdHRyaWJ1dGVNYW5hZ2VyLmFkZCh7XG4gICAgICBwb3NpdGlvbnM6IHtzaXplOiAzLCBhY2Nlc3NvcjogJ2dldFBvc2l0aW9uJ31cbiAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZVN0YXRlKHtvbGRQcm9wcywgcHJvcHMsIGNoYW5nZUZsYWdzfSkge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgLy8gbWFrZSBhIGNvcHkgb2YgdGhlIGludGVybmFsIHN0YXRlIG9mIGNwdUFnZ3JlZ2F0b3IgZm9yIHRlc3RpbmdcbiAgICAgIGFnZ3JlZ2F0b3JTdGF0ZTogdGhpcy5zdGF0ZS5jcHVBZ2dyZWdhdG9yLnVwZGF0ZVN0YXRlKFxuICAgICAgICB7b2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFnc30sXG4gICAgICAgIHtcbiAgICAgICAgICB2aWV3cG9ydDogdGhpcy5jb250ZXh0LnZpZXdwb3J0LFxuICAgICAgICAgIGF0dHJpYnV0ZXM6IHRoaXMuZ2V0QXR0cmlidXRlcygpLFxuICAgICAgICAgIG51bUluc3RhbmNlczogdGhpcy5nZXROdW1JbnN0YW5jZXMocHJvcHMpXG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9KTtcbiAgfVxuXG4gIGdldFBpY2tpbmdJbmZvKHtpbmZvfSkge1xuICAgIGNvbnN0IG9iaiA9IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci5nZXRQaWNraW5nSW5mbyh7aW5mb30sIHRoaXMucHJvcHMpO1xuICAgIGlmIChvYmo/Lm9iamVjdCkge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgY29uc3QgZGlzdGFuY2VTY2FsZSA9IGdldERpc3RhbmNlU2NhbGVzKHRoaXMuY29udGV4dC52aWV3cG9ydCk7XG4gICAgICBjb25zdCBtZXRlcnNQZXJQaXhlbCA9IGRpc3RhbmNlU2NhbGUubWV0ZXJzUGVyUGl4ZWxbMF07XG4gICAgICBvYmoub2JqZWN0LnNjYWxlZFJhZGl1c1ZhbHVlID0gb2JqLm9iamVjdC5zY2FsZWRSYWRpdXNWYWx1ZSAqIG1ldGVyc1BlclBpeGVsO1xuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICBfZ2V0U3VibGF5ZXJVcGRhdGVUcmlnZ2VycygpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5jcHVBZ2dyZWdhdG9yLmdldFVwZGF0ZVRyaWdnZXJzKHRoaXMucHJvcHMpO1xuICB9XG5cbiAgX2dldFN1YkxheWVyQWNjZXNzb3JzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBnZXRSYWRpdXM6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci5nZXRBY2Nlc3NvcigncmFkaXVzJywgdGhpcy5wcm9wcyksXG4gICAgICBnZXRGaWxsQ29sb3I6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci5nZXRBY2Nlc3NvcignZmlsbENvbG9yJywgdGhpcy5wcm9wcylcbiAgICB9O1xuICB9XG5cbiAgcmVuZGVyTGF5ZXJzKCkge1xuICAgIC8vIGZvciBzdWJjbGFzc2luZywgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuXG4gICAgLy8gY3VzdG9taXplZCBzdWIgbGF5ZXIgcHJvcHNcbiAgICBjb25zdCB7aWQsIHJhZGl1c1NjYWxlfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3Qge2NwdUFnZ3JlZ2F0b3J9ID0gdGhpcy5zdGF0ZTtcblxuICAgIC8vIGJhc2UgbGF5ZXIgcHJvcHNcbiAgICBjb25zdCB7dmlzaWJsZSwgb3BhY2l0eSwgcGlja2FibGUsIGF1dG9IaWdobGlnaHQsIGhpZ2hsaWdodENvbG9yfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgdXBkYXRlVHJpZ2dlcnMgPSB0aGlzLl9nZXRTdWJsYXllclVwZGF0ZVRyaWdnZXJzKCk7XG4gICAgY29uc3QgYWNjZXNzb3JzID0gdGhpcy5fZ2V0U3ViTGF5ZXJBY2Nlc3NvcnMoKTtcblxuICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICBjb25zdCBkaXN0YW5jZVNjYWxlID0gZ2V0RGlzdGFuY2VTY2FsZXModGhpcy5jb250ZXh0LnZpZXdwb3J0KTtcbiAgICBjb25zdCBtZXRlcnNQZXJQaXhlbCA9IGRpc3RhbmNlU2NhbGUubWV0ZXJzUGVyUGl4ZWxbMF07XG5cbiAgICAvLyByZXR1cm4gcHJvcHMgdG8gdGhlIHN1YmxheWVyIGNvbnN0cnVjdG9yXG4gICAgcmV0dXJuIG5ldyBTY2F0dGVycGxvdExheWVyKHtcbiAgICAgIGlkOiBgJHtpZH0tY2x1c3RlcmAsXG4gICAgICBkYXRhOiBjcHVBZ2dyZWdhdG9yLnN0YXRlLmxheWVyRGF0YS5kYXRhLFxuICAgICAgcmFkaXVzU2NhbGU6IG1ldGVyc1BlclBpeGVsICogcmFkaXVzU2NhbGUsXG4gICAgICB2aXNpYmxlLFxuICAgICAgb3BhY2l0eSxcbiAgICAgIHBpY2thYmxlLFxuICAgICAgYXV0b0hpZ2hsaWdodCxcbiAgICAgIGhpZ2hsaWdodENvbG9yLFxuICAgICAgdXBkYXRlVHJpZ2dlcnMsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIGRlcHRoTWFzazogZmFsc2VcbiAgICAgIH0sXG4gICAgICAuLi5hY2Nlc3NvcnNcbiAgICB9KTtcbiAgfVxufVxuXG5DbHVzdGVyTGF5ZXIubGF5ZXJOYW1lID0gJ0NsdXN0ZXJMYXllcic7XG5DbHVzdGVyTGF5ZXIuZGVmYXVsdFByb3BzID0gZGVmYXVsdFByb3BzO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUdBLElBQUFBLE9BQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLGtCQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxZQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxjQUFBLEdBQUFDLHVCQUFBLENBQUFMLE9BQUE7QUFNQSxJQUFBTSx3QkFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sUUFBQSxHQUFBUCxPQUFBO0FBRUEsSUFBQVEsVUFBQSxHQUFBUixPQUFBO0FBQ0EsSUFBQVMsYUFBQSxHQUFBSix1QkFBQSxDQUFBTCxPQUFBO0FBQXdFLFNBQUFVLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLHlCQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBTix3QkFBQU0sQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLGdCQUFBSyxPQUFBLENBQUFMLENBQUEsMEJBQUFBLENBQUEsc0JBQUFBLENBQUEsUUFBQUcsQ0FBQSxHQUFBSix3QkFBQSxDQUFBRyxDQUFBLE9BQUFDLENBQUEsSUFBQUEsQ0FBQSxDQUFBRyxHQUFBLENBQUFOLENBQUEsVUFBQUcsQ0FBQSxDQUFBSSxHQUFBLENBQUFQLENBQUEsT0FBQVEsQ0FBQSxLQUFBQyxTQUFBLFVBQUFDLENBQUEsR0FBQUMsTUFBQSxDQUFBQyxjQUFBLElBQUFELE1BQUEsQ0FBQUUsd0JBQUEsV0FBQUMsQ0FBQSxJQUFBZCxDQUFBLG9CQUFBYyxDQUFBLE9BQUFDLGNBQUEsQ0FBQUMsSUFBQSxDQUFBaEIsQ0FBQSxFQUFBYyxDQUFBLFNBQUFHLENBQUEsR0FBQVAsQ0FBQSxHQUFBQyxNQUFBLENBQUFFLHdCQUFBLENBQUFiLENBQUEsRUFBQWMsQ0FBQSxVQUFBRyxDQUFBLEtBQUFBLENBQUEsQ0FBQVYsR0FBQSxJQUFBVSxDQUFBLENBQUFDLEdBQUEsSUFBQVAsTUFBQSxDQUFBQyxjQUFBLENBQUFKLENBQUEsRUFBQU0sQ0FBQSxFQUFBRyxDQUFBLElBQUFULENBQUEsQ0FBQU0sQ0FBQSxJQUFBZCxDQUFBLENBQUFjLENBQUEsWUFBQU4sQ0FBQSxjQUFBUixDQUFBLEVBQUFHLENBQUEsSUFBQUEsQ0FBQSxDQUFBZSxHQUFBLENBQUFsQixDQUFBLEVBQUFRLENBQUEsR0FBQUEsQ0FBQTtBQUFBLFNBQUFXLFFBQUFuQixDQUFBLEVBQUFFLENBQUEsUUFBQUMsQ0FBQSxHQUFBUSxNQUFBLENBQUFTLElBQUEsQ0FBQXBCLENBQUEsT0FBQVcsTUFBQSxDQUFBVSxxQkFBQSxRQUFBQyxDQUFBLEdBQUFYLE1BQUEsQ0FBQVUscUJBQUEsQ0FBQXJCLENBQUEsR0FBQUUsQ0FBQSxLQUFBb0IsQ0FBQSxHQUFBQSxDQUFBLENBQUFDLE1BQUEsV0FBQXJCLENBQUEsV0FBQVMsTUFBQSxDQUFBRSx3QkFBQSxDQUFBYixDQUFBLEVBQUFFLENBQUEsRUFBQXNCLFVBQUEsT0FBQXJCLENBQUEsQ0FBQXNCLElBQUEsQ0FBQUMsS0FBQSxDQUFBdkIsQ0FBQSxFQUFBbUIsQ0FBQSxZQUFBbkIsQ0FBQTtBQUFBLFNBQUF3QixjQUFBM0IsQ0FBQSxhQUFBRSxDQUFBLE1BQUFBLENBQUEsR0FBQTBCLFNBQUEsQ0FBQUMsTUFBQSxFQUFBM0IsQ0FBQSxVQUFBQyxDQUFBLFdBQUF5QixTQUFBLENBQUExQixDQUFBLElBQUEwQixTQUFBLENBQUExQixDQUFBLFFBQUFBLENBQUEsT0FBQWlCLE9BQUEsQ0FBQVIsTUFBQSxDQUFBUixDQUFBLE9BQUEyQixPQUFBLFdBQUE1QixDQUFBLFFBQUE2QixnQkFBQSxhQUFBL0IsQ0FBQSxFQUFBRSxDQUFBLEVBQUFDLENBQUEsQ0FBQUQsQ0FBQSxTQUFBUyxNQUFBLENBQUFxQix5QkFBQSxHQUFBckIsTUFBQSxDQUFBc0IsZ0JBQUEsQ0FBQWpDLENBQUEsRUFBQVcsTUFBQSxDQUFBcUIseUJBQUEsQ0FBQTdCLENBQUEsS0FBQWdCLE9BQUEsQ0FBQVIsTUFBQSxDQUFBUixDQUFBLEdBQUEyQixPQUFBLFdBQUE1QixDQUFBLElBQUFTLE1BQUEsQ0FBQUMsY0FBQSxDQUFBWixDQUFBLEVBQUFFLENBQUEsRUFBQVMsTUFBQSxDQUFBRSx3QkFBQSxDQUFBVixDQUFBLEVBQUFELENBQUEsaUJBQUFGLENBQUE7QUFBQSxTQUFBa0MsV0FBQS9CLENBQUEsRUFBQW1CLENBQUEsRUFBQXRCLENBQUEsV0FBQXNCLENBQUEsT0FBQWEsZ0JBQUEsYUFBQWIsQ0FBQSxPQUFBYywyQkFBQSxhQUFBakMsQ0FBQSxFQUFBa0MseUJBQUEsS0FBQUMsT0FBQSxDQUFBQyxTQUFBLENBQUFqQixDQUFBLEVBQUF0QixDQUFBLFlBQUFtQyxnQkFBQSxhQUFBaEMsQ0FBQSxFQUFBcUMsV0FBQSxJQUFBbEIsQ0FBQSxDQUFBSSxLQUFBLENBQUF2QixDQUFBLEVBQUFILENBQUE7QUFBQSxTQUFBcUMsMEJBQUEsY0FBQWxDLENBQUEsSUFBQXNDLE9BQUEsQ0FBQUMsU0FBQSxDQUFBQyxPQUFBLENBQUEzQixJQUFBLENBQUFzQixPQUFBLENBQUFDLFNBQUEsQ0FBQUUsT0FBQSxpQ0FBQXRDLENBQUEsYUFBQWtDLHlCQUFBLFlBQUFBLDBCQUFBLGFBQUFsQyxDQUFBLFVBakJ4RTtBQUNBO0FBb0JBLElBQU15QyxhQUFhLEdBQUdDLDRCQUFpQixDQUFDQyxhQUFhLENBQUNDLFlBQVk7QUFDbEUsSUFBTUMsa0JBQWtCLEdBQUdILDRCQUFpQixDQUFDSSxrQkFBa0IsQ0FBQ0YsWUFBWTtBQUU1RSxJQUFNRyxvQkFBb0IsR0FBRyxTQUF2QkEsb0JBQW9CQSxDQUFHQyxNQUFNO0VBQUEsT0FBSUEsTUFBTSxDQUFDdEIsTUFBTTtBQUFBO0FBQ3BELElBQU11QixxQkFBcUIsR0FBRyxTQUF4QkEscUJBQXFCQSxDQUFHQyxJQUFJO0VBQUEsT0FDaENBLElBQUksQ0FBQ0MsY0FBYyxHQUFHRCxJQUFJLENBQUNDLGNBQWMsQ0FBQ3pCLE1BQU0sR0FBR3dCLElBQUksQ0FBQ0YsTUFBTSxDQUFDdEIsTUFBTTtBQUFBOztBQUV2RTtBQUNBLFNBQVMwQixjQUFjQSxDQUFzQkMsSUFBSSxFQUFFQyxLQUFLLEVBQUVDLFdBQVcsRUFBQUMsSUFBQSxFQUFjO0VBQUEsSUFBWEMsUUFBUSxHQUFBRCxJQUFBLENBQVJDLFFBQVE7RUFDOUUsSUFBT0MsSUFBSSxHQUE2QkosS0FBSyxDQUF0Q0ksSUFBSTtJQUFFQyxXQUFXLEdBQWdCTCxLQUFLLENBQWhDSyxXQUFXO0lBQUVDLFVBQVUsR0FBSU4sS0FBSyxDQUFuQk0sVUFBVTtFQUNwQyxJQUFNQyxPQUFPLEdBQUcsSUFBQUMsd0JBQVUsRUFBQ0osSUFBSSxFQUFFQyxXQUFXLEVBQUVDLFVBQVUsQ0FBQztFQUN6RCxJQUFNRyxjQUFjLEdBQUcsSUFBSUMsd0JBQWMsQ0FBQyxDQUFDO0VBRTNDLElBQUksQ0FBQ0MsUUFBUSxDQUFDO0lBQUNKLE9BQU8sRUFBUEEsT0FBTztJQUFFRSxjQUFjLEVBQWRBO0VBQWMsQ0FBQyxDQUFDO0FBQzFDOztBQUVBO0FBQ0EsU0FBU0csV0FBV0EsQ0FBc0JiLElBQUksRUFBRUMsS0FBSyxFQUFFQyxXQUFXLEVBQUFZLEtBQUEsRUFBYztFQUFBLElBQVhWLFFBQVEsR0FBQVUsS0FBQSxDQUFSVixRQUFRO0VBQzNFLElBQUFXLFdBQUEsR0FBa0MsSUFBSSxDQUFDQyxLQUFLO0lBQXJDUixPQUFPLEdBQUFPLFdBQUEsQ0FBUFAsT0FBTztJQUFFRSxjQUFjLEdBQUFLLFdBQUEsQ0FBZEwsY0FBYztFQUM5QixJQUFPcEIsYUFBYSxHQUF5QlcsS0FBSyxDQUEzQ1gsYUFBYTtJQUFFMkIsSUFBSSxHQUFtQmhCLEtBQUssQ0FBNUJnQixJQUFJO0lBQUVDLEtBQUssR0FBWWpCLEtBQUssQ0FBdEJpQixLQUFLO0lBQUVDLE1BQU0sR0FBSWxCLEtBQUssQ0FBZmtCLE1BQU07RUFDekMsSUFBT0MsU0FBUyxHQUFjaEIsUUFBUSxDQUEvQmdCLFNBQVM7SUFBRUMsUUFBUSxHQUFJakIsUUFBUSxDQUFwQmlCLFFBQVE7O0VBRTFCO0VBQ0EsSUFBTUMsSUFBSSxHQUFHQyx1QkFBVyxDQUFDQyxNQUFNLENBQUMsQ0FBQ0osU0FBUyxFQUFFQyxRQUFRLENBQUMsRUFBRUosSUFBSSxFQUFFLENBQUNDLEtBQUssRUFBRUMsTUFBTSxDQUFDLENBQUM7RUFDN0UsSUFBTU0sUUFBUSxHQUFHZixjQUFjLENBQUNnQixjQUFjLENBQUM7SUFBQ0osSUFBSSxFQUFKQSxJQUFJO0lBQUVoQyxhQUFhLEVBQWJBLGFBQWE7SUFBRWtCLE9BQU8sRUFBUEEsT0FBTztJQUFFUyxJQUFJLEVBQUpBO0VBQUksQ0FBQyxDQUFDO0VBRXBGLElBQUksQ0FBQ0wsUUFBUSxDQUFDO0lBQ1plLFNBQVMsRUFBRTtNQUFDdEIsSUFBSSxFQUFFb0I7SUFBUTtFQUM1QixDQUFDLENBQUM7QUFDSjtBQUVBLFNBQVNHLGlCQUFpQkEsQ0FBQ0MsY0FBYyxFQUFFQyxTQUFTLEVBQUVDLFVBQVUsRUFBRTtFQUNoRSxPQUFPLFVBQUFsQyxJQUFJLEVBQUk7SUFDYixJQUFPbUMsY0FBYyxHQUFJRCxVQUFVLENBQTVCQyxjQUFjO0lBQ3JCLElBQU9DLFNBQVMsR0FBSUosY0FBYyxDQUEzQkksU0FBUztJQUNoQixPQUFPQSxTQUFTLENBQUNELGNBQWMsQ0FBQ25DLElBQUksQ0FBQyxDQUFDO0VBQ3hDLENBQUM7QUFDSDtBQUVPLElBQU1xQyxrQkFBbUMsR0FBQUMsT0FBQSxDQUFBRCxrQkFBQSxHQUFHO0VBQ2pERSxHQUFHLEVBQUUsVUFBVTtFQUNmQyxXQUFXLEVBQUUsQ0FDWDtJQUNFRCxHQUFHLEVBQUUsU0FBUztJQUNkRSxRQUFRLEVBQUU7TUFDUkMsUUFBUSxFQUFFO1FBQ1JDLElBQUksRUFBRSxhQUFhO1FBQ25CQyxhQUFhLEVBQUU7TUFDakIsQ0FBQztNQUNEbEMsVUFBVSxFQUFFO1FBQ1ZpQyxJQUFJLEVBQUUsWUFBWTtRQUNsQkMsYUFBYSxFQUFFO01BQ2pCO0lBQ0YsQ0FBQztJQUNEQyxPQUFPLEVBQUUzQztFQUNYLENBQUMsRUFDRDtJQUNFcUMsR0FBRyxFQUFFLFlBQVk7SUFDakJFLFFBQVEsRUFBRTtNQUNSaEQsYUFBYSxFQUFFO1FBQ2JrRCxJQUFJLEVBQUU7TUFDUixDQUFDO01BQ0R2QixJQUFJLEVBQUU7UUFDSnVCLElBQUksRUFBRTtNQUNSLENBQUM7TUFDRHRCLEtBQUssRUFBRTtRQUNMc0IsSUFBSSxFQUFFO01BQ1IsQ0FBQztNQUNEckIsTUFBTSxFQUFFO1FBQ05xQixJQUFJLEVBQUU7TUFDUjtJQUNGLENBQUM7SUFDREUsT0FBTyxFQUFFN0I7RUFDWCxDQUFDO0FBRUwsQ0FBQztBQUVELFNBQVM4QixvQkFBb0JBLENBQXNCM0MsSUFBSSxFQUFFQyxLQUFLLEVBQUUyQyxnQkFBZ0IsRUFBRTtFQUNoRixJQUFPUixHQUFHLEdBQUlRLGdCQUFnQixDQUF2QlIsR0FBRztFQUNWLElBQU9KLGNBQWMsR0FBSS9CLEtBQUssQ0FBdkIrQixjQUFjO0VBQ3JCLElBQU9MLFNBQVMsR0FBSSxJQUFJLENBQUNYLEtBQUssQ0FBdkJXLFNBQVM7RUFFaEIsSUFBTWtCLFdBQVcsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFBQyxZQUFHLEVBQUNuQixTQUFTLENBQUN0QixJQUFJLEVBQUUyQixjQUFjLENBQUMsQ0FBQztFQUM1RCxJQUFJLENBQUNlLGtCQUFrQixDQUFDWCxHQUFHLEVBQUU7SUFBQ1MsV0FBVyxFQUFYQTtFQUFXLENBQUMsQ0FBQztBQUM3QztBQUVBLElBQU1HLHNCQUF5RSxHQUFHLENBQ2hGQyxvQ0FBcUIsRUFDckI7RUFDRWIsR0FBRyxFQUFFLFFBQVE7RUFDYmMsUUFBUSxFQUFFLFdBQVc7RUFDckJDLFNBQVMsRUFBRSxDQUFDO0VBQ1pkLFdBQVcsRUFBRSxDQUNYO0lBQ0VELEdBQUcsRUFBRSxXQUFXO0lBQ2hCRSxRQUFRLEVBQUU7TUFDUmMsS0FBSyxFQUFFO1FBQ0xaLElBQUksRUFBRSxnQkFBZ0I7UUFDdEJDLGFBQWEsRUFBRTtNQUNqQjtJQUNGLENBQUM7SUFDREMsT0FBTyxFQUFFQztFQUNYLENBQUMsRUFDRDtJQUNFUCxHQUFHLEVBQUUsY0FBYztJQUNuQkUsUUFBUSxFQUFFO01BQ1JlLE1BQU0sRUFBRTtRQUFDYixJQUFJLEVBQUU7TUFBYyxDQUFDO01BQzlCYyxLQUFLLEVBQUU7UUFBQ2QsSUFBSSxFQUFFO01BQWEsQ0FBQztNQUM1QmUsU0FBUyxFQUFFO1FBQUNmLElBQUksRUFBRTtNQUFpQjtJQUNyQyxDQUFDO0lBQ0RFLE9BQU8sRUFBRWM7RUFDWCxDQUFDLENBQ0Y7RUFDREMsbUJBQW1CLEVBQUU3QixpQkFBaUI7RUFDdEM4QixjQUFjLEVBQUUsU0FBaEJBLGNBQWNBLENBQUc3QixjQUFjLEVBQUVoQyxJQUFJLEVBQUVrQyxVQUFVLEVBQUs7SUFDcEQsSUFBTTRCLFdBQVcsR0FBRzVCLFVBQVUsQ0FBQ0MsY0FBYyxDQUFDbkMsSUFBSSxDQUFDO0lBQ25ELElBQU9vQyxTQUFTLEdBQUlKLGNBQWMsQ0FBM0JJLFNBQVM7SUFDaEIsSUFBTTJCLGlCQUFpQixHQUFHM0IsU0FBUyxHQUFHQSxTQUFTLENBQUMwQixXQUFXLENBQUMsR0FBR0EsV0FBVztJQUUxRSxPQUFPO01BQUNBLFdBQVcsRUFBWEEsV0FBVztNQUFFQyxpQkFBaUIsRUFBakJBO0lBQWlCLENBQUM7RUFDekM7QUFDRixDQUFDLENBQ0Y7QUFFRCxJQUFNQyxZQUFZLEdBQUc7RUFDbkJ2RSxhQUFhLEVBQUVGLGFBQWE7RUFDNUIwRSxXQUFXLEVBQUUsSUFBSTtFQUNqQkMsVUFBVSxFQUFFQyw4QkFBbUI7RUFDL0JDLGNBQWMsRUFBRUMsc0JBQVcsQ0FBQ0MsUUFBUTtFQUNwQ0MsZUFBZSxFQUFFRixzQkFBVyxDQUFDRyxJQUFJO0VBQ2pDQyxXQUFXLEVBQUU5RSxrQkFBa0I7RUFDL0JjLFdBQVcsRUFBRTtJQUFDaUUsSUFBSSxFQUFFLFVBQVU7SUFBRW5CLEtBQUssRUFBRSxTQUFQQSxLQUFLQSxDQUFFb0IsQ0FBQztNQUFBLE9BQUlBLENBQUMsQ0FBQ2pDLFFBQVE7SUFBQTtFQUFBLENBQUM7RUFDdkRrQyxhQUFhLEVBQUU7SUFBQ0YsSUFBSSxFQUFFLFVBQVU7SUFBRW5CLEtBQUssRUFBRTFEO0VBQW9CLENBQUM7RUFDOURzQyxjQUFjLEVBQUU7SUFBQ3VDLElBQUksRUFBRSxVQUFVO0lBQUVuQixLQUFLLEVBQUV4RDtFQUFxQjtBQUNqRSxDQUFDO0FBQUMsSUFFbUI4RSxZQUFZLEdBQUF2QyxPQUFBLHFDQUFBd0MsaUJBQUE7RUFBQSxTQUFBRCxhQUFBO0lBQUEsSUFBQUUsZ0JBQUEsbUJBQUFGLFlBQUE7SUFBQSxPQUFBaEcsVUFBQSxPQUFBZ0csWUFBQSxFQUFBdEcsU0FBQTtFQUFBO0VBQUEsSUFBQXlHLFVBQUEsYUFBQUgsWUFBQSxFQUFBQyxpQkFBQTtFQUFBLFdBQUFHLGFBQUEsYUFBQUosWUFBQTtJQUFBdEMsR0FBQTtJQUFBZ0IsS0FBQSxFQUkvQixTQUFBMkIsZUFBZUEsQ0FBQSxFQUFHO01BQ2hCLElBQU1DLGFBQWEsR0FBRyxJQUFJQyx5QkFBYSxDQUFDO1FBQ3RDL0UsV0FBVyxFQUFFZ0Msa0JBQWtCO1FBQy9CZ0QsVUFBVSxFQUFFbEM7TUFDZCxDQUFDLENBQUM7TUFFRixJQUFJLENBQUNoQyxLQUFLLEdBQUc7UUFDWGdFLGFBQWEsRUFBYkEsYUFBYTtRQUNiRyxlQUFlLEVBQUVILGFBQWEsQ0FBQ2hFO01BQ2pDLENBQUM7TUFDRCxJQUFNb0UsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDQyxtQkFBbUIsQ0FBQyxDQUFDO01BQ25ERCxnQkFBZ0IsQ0FBQ0UsR0FBRyxDQUFDO1FBQ25CQyxTQUFTLEVBQUU7VUFBQ0MsSUFBSSxFQUFFLENBQUM7VUFBRXRDLFFBQVEsRUFBRTtRQUFhO01BQzlDLENBQUMsQ0FBQztJQUNKO0VBQUM7SUFBQWQsR0FBQTtJQUFBZ0IsS0FBQSxFQUVELFNBQUFxQyxXQUFXQSxDQUFBQyxLQUFBLEVBQWlDO01BQUEsSUFBL0JDLFFBQVEsR0FBQUQsS0FBQSxDQUFSQyxRQUFRO1FBQUUxRixLQUFLLEdBQUF5RixLQUFBLENBQUx6RixLQUFLO1FBQUUyRixXQUFXLEdBQUFGLEtBQUEsQ0FBWEUsV0FBVztNQUN2QyxJQUFJLENBQUNoRixRQUFRLENBQUM7UUFDWjtRQUNBdUUsZUFBZSxFQUFFLElBQUksQ0FBQ25FLEtBQUssQ0FBQ2dFLGFBQWEsQ0FBQ1MsV0FBVyxDQUNuRDtVQUFDRSxRQUFRLEVBQVJBLFFBQVE7VUFBRTFGLEtBQUssRUFBTEEsS0FBSztVQUFFMkYsV0FBVyxFQUFYQTtRQUFXLENBQUMsRUFDOUI7VUFDRXhGLFFBQVEsRUFBRSxJQUFJLENBQUN5RixPQUFPLENBQUN6RixRQUFRO1VBQy9CMEYsVUFBVSxFQUFFLElBQUksQ0FBQ0MsYUFBYSxDQUFDLENBQUM7VUFDaENDLFlBQVksRUFBRSxJQUFJLENBQUNDLGVBQWUsQ0FBQ2hHLEtBQUs7UUFDMUMsQ0FDRjtNQUNGLENBQUMsQ0FBQztJQUNKO0VBQUM7SUFBQW1DLEdBQUE7SUFBQWdCLEtBQUEsRUFFRCxTQUFBTSxjQUFjQSxDQUFBd0MsS0FBQSxFQUFTO01BQUEsSUFBUEMsSUFBSSxHQUFBRCxLQUFBLENBQUpDLElBQUk7TUFDbEIsSUFBTUMsR0FBRyxHQUFHLElBQUksQ0FBQ3BGLEtBQUssQ0FBQ2dFLGFBQWEsQ0FBQ3RCLGNBQWMsQ0FBQztRQUFDeUMsSUFBSSxFQUFKQTtNQUFJLENBQUMsRUFBRSxJQUFJLENBQUNsRyxLQUFLLENBQUM7TUFDdkUsSUFBSW1HLEdBQUcsYUFBSEEsR0FBRyxlQUFIQSxHQUFHLENBQUVDLE1BQU0sRUFBRTtRQUNmO1FBQ0EsSUFBTUMsYUFBYSxHQUFHLElBQUFDLDBDQUFpQixFQUFDLElBQUksQ0FBQ1YsT0FBTyxDQUFDekYsUUFBUSxDQUFDO1FBQzlELElBQU1vRyxjQUFjLEdBQUdGLGFBQWEsQ0FBQ0UsY0FBYyxDQUFDLENBQUMsQ0FBQztRQUN0REosR0FBRyxDQUFDQyxNQUFNLENBQUN6QyxpQkFBaUIsR0FBR3dDLEdBQUcsQ0FBQ0MsTUFBTSxDQUFDekMsaUJBQWlCLEdBQUc0QyxjQUFjO01BQzlFO01BRUEsT0FBT0osR0FBRztJQUNaO0VBQUM7SUFBQWhFLEdBQUE7SUFBQWdCLEtBQUEsRUFFRCxTQUFBcUQsMEJBQTBCQSxDQUFBLEVBQUc7TUFDM0IsT0FBTyxJQUFJLENBQUN6RixLQUFLLENBQUNnRSxhQUFhLENBQUMwQixpQkFBaUIsQ0FBQyxJQUFJLENBQUN6RyxLQUFLLENBQUM7SUFDL0Q7RUFBQztJQUFBbUMsR0FBQTtJQUFBZ0IsS0FBQSxFQUVELFNBQUF1RCxxQkFBcUJBLENBQUEsRUFBRztNQUN0QixPQUFPO1FBQ0xDLFNBQVMsRUFBRSxJQUFJLENBQUM1RixLQUFLLENBQUNnRSxhQUFhLENBQUM2QixXQUFXLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQzVHLEtBQUssQ0FBQztRQUNyRTZHLFlBQVksRUFBRSxJQUFJLENBQUM5RixLQUFLLENBQUNnRSxhQUFhLENBQUM2QixXQUFXLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQzVHLEtBQUs7TUFDNUUsQ0FBQztJQUNIO0VBQUM7SUFBQW1DLEdBQUE7SUFBQWdCLEtBQUEsRUFFRCxTQUFBMkQsWUFBWUEsQ0FBQSxFQUFHO01BQ2I7TUFDQTtNQUNBLElBQUFDLFdBQUEsR0FBMEIsSUFBSSxDQUFDL0csS0FBSztRQUE3QmdILEVBQUUsR0FBQUQsV0FBQSxDQUFGQyxFQUFFO1FBQUVDLFdBQVcsR0FBQUYsV0FBQSxDQUFYRSxXQUFXO01BQ3RCLElBQU9sQyxhQUFhLEdBQUksSUFBSSxDQUFDaEUsS0FBSyxDQUEzQmdFLGFBQWE7O01BRXBCO01BQ0EsSUFBQW1DLFlBQUEsR0FBb0UsSUFBSSxDQUFDbEgsS0FBSztRQUF2RW1ILE9BQU8sR0FBQUQsWUFBQSxDQUFQQyxPQUFPO1FBQUVDLE9BQU8sR0FBQUYsWUFBQSxDQUFQRSxPQUFPO1FBQUVDLFFBQVEsR0FBQUgsWUFBQSxDQUFSRyxRQUFRO1FBQUVDLGFBQWEsR0FBQUosWUFBQSxDQUFiSSxhQUFhO1FBQUVDLGNBQWMsR0FBQUwsWUFBQSxDQUFkSyxjQUFjO01BQ2hFLElBQU1DLGNBQWMsR0FBRyxJQUFJLENBQUNoQiwwQkFBMEIsQ0FBQyxDQUFDO01BQ3hELElBQU1pQixTQUFTLEdBQUcsSUFBSSxDQUFDZixxQkFBcUIsQ0FBQyxDQUFDOztNQUU5QztNQUNBLElBQU1MLGFBQWEsR0FBRyxJQUFBQywwQ0FBaUIsRUFBQyxJQUFJLENBQUNWLE9BQU8sQ0FBQ3pGLFFBQVEsQ0FBQztNQUM5RCxJQUFNb0csY0FBYyxHQUFHRixhQUFhLENBQUNFLGNBQWMsQ0FBQyxDQUFDLENBQUM7O01BRXREO01BQ0EsT0FBTyxJQUFJbUIsd0JBQWdCLENBQUF4SixhQUFBO1FBQ3pCOEksRUFBRSxLQUFBVyxNQUFBLENBQUtYLEVBQUUsYUFBVTtRQUNuQjVHLElBQUksRUFBRTJFLGFBQWEsQ0FBQ2hFLEtBQUssQ0FBQ1csU0FBUyxDQUFDdEIsSUFBSTtRQUN4QzZHLFdBQVcsRUFBRVYsY0FBYyxHQUFHVSxXQUFXO1FBQ3pDRSxPQUFPLEVBQVBBLE9BQU87UUFDUEMsT0FBTyxFQUFQQSxPQUFPO1FBQ1BDLFFBQVEsRUFBUkEsUUFBUTtRQUNSQyxhQUFhLEVBQWJBLGFBQWE7UUFDYkMsY0FBYyxFQUFkQSxjQUFjO1FBQ2RDLGNBQWMsRUFBZEEsY0FBYztRQUNkSSxVQUFVLEVBQUU7VUFDVkMsU0FBUyxFQUFFO1FBQ2I7TUFBQyxHQUNFSixTQUFTLENBQ2IsQ0FBQztJQUNKO0VBQUM7QUFBQSxFQXhGdUNLLG9DQUFnQjtBQTJGMURyRCxZQUFZLENBQUNzRCxTQUFTLEdBQUcsY0FBYztBQUN2Q3RELFlBQVksQ0FBQ2IsWUFBWSxHQUFHQSxZQUFZIiwiaWdub3JlTGlzdCI6W119