UNPKG

kepler.gl

Version:

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

389 lines (384 loc) 54.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.pointVisConfigs = exports.iconRequiredColumns = exports.iconPosAccessor = exports.iconOptionalColumns = exports.iconAccessor = exports["default"] = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _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 _window = _interopRequireDefault(require("global/window")); var _extensions = require("@deck.gl/extensions"); var _constants = _interopRequireDefault(require("@luma.gl/constants")); var _deckglLayers = require("@kepler.gl/deckgl-layers"); var _iconLayerIcon = _interopRequireDefault(require("./icon-layer-icon")); var _constants2 = require("@kepler.gl/constants"); var _iconInfoModal = _interopRequireDefault(require("./icon-info-modal")); var _baseLayer = _interopRequireDefault(require("../base-layer")); var _layerUtils = require("../layer-utils"); var _utils = require("@kepler.gl/utils"); var _layerTextLabel = require("../layer-text-label"); 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 var brushingExtension = new _extensions.BrushingExtension(); var iconPosAccessor = exports.iconPosAccessor = function iconPosAccessor(_ref) { var lat = _ref.lat, lng = _ref.lng, altitude = _ref.altitude; return function (dc) { return function (d) { return [dc.valueAt(d.index, lng.fieldIdx), dc.valueAt(d.index, lat.fieldIdx), (altitude === null || altitude === void 0 ? void 0 : altitude.fieldIdx) > -1 ? dc.valueAt(d.index, altitude.fieldIdx) : 0]; }; }; }; var iconAccessor = exports.iconAccessor = function iconAccessor(_ref2) { var icon = _ref2.icon; return function (dc) { return function (d) { return dc.valueAt(d.index, icon.fieldIdx); }; }; }; var iconRequiredColumns = exports.iconRequiredColumns = ['lat', 'lng', 'icon']; var iconOptionalColumns = exports.iconOptionalColumns = ['altitude']; var pointVisConfigs = exports.pointVisConfigs = { radius: 'radius', fixedRadius: 'fixedRadius', opacity: 'opacity', colorRange: 'colorRange', radiusRange: 'radiusRange', billboard: 'billboard' }; function flatterIconPositions(icon) { // had to flip y, since @luma modal has changed return icon.mesh.cells.reduce(function (prev, cell) { cell.forEach(function (p) { prev.push.apply(prev, [icon.mesh.positions[p][0], -icon.mesh.positions[p][1], icon.mesh.positions[p][2]]); }); return prev; }, []); } var IconLayer = exports["default"] = /*#__PURE__*/function (_Layer) { function IconLayer(props) { var _this; (0, _classCallCheck2["default"])(this, IconLayer); _this = _callSuper(this, IconLayer, [props]); (0, _defineProperty2["default"])(_this, "getIconAccessor", void 0); (0, _defineProperty2["default"])(_this, "_layerInfoModal", void 0); (0, _defineProperty2["default"])(_this, "iconGeometry", void 0); _this.registerVisConfig(pointVisConfigs); _this.getPositionAccessor = function (dataContainer) { return iconPosAccessor(_this.config.columns)(dataContainer); }; _this.getIconAccessor = function (dataContainer) { return iconAccessor(_this.config.columns)(dataContainer); }; _this._layerInfoModal = (0, _iconInfoModal["default"])(props.svgIcons); _this.iconGeometry = props.iconGeometry || null; if ((0, _utils.isTest)()) { return (0, _possibleConstructorReturn2["default"])(_this); } if (props.svgIcons) { // if svg icons are passed in then bypass fetching of remote svg icons _this.setSvgIcons(props.svgIcons); } else { // prepare layer info modal and fetch remote svg icons _this.getSvgIcons(); } return _this; } (0, _inherits2["default"])(IconLayer, _Layer); return (0, _createClass2["default"])(IconLayer, [{ key: "svgIconUrl", get: function get() { return "".concat((0, _utils.getApplicationConfig)().cdnUrl, "/icons/svg-icons.json"); } }, { key: "type", get: function get() { return 'icon'; } }, { key: "requiredLayerColumns", get: function get() { return iconRequiredColumns; } }, { key: "optionalColumns", get: function get() { return iconOptionalColumns; } }, { key: "columnPairs", get: function get() { return this.defaultPointColumnPairs; } }, { key: "layerIcon", get: function get() { return _iconLayerIcon["default"]; } }, { key: "visualChannels", get: function get() { return { color: _objectSpread(_objectSpread({}, _superPropGet(IconLayer, "visualChannels", this, 1).color), {}, { accessor: 'getFillColor', defaultValue: function defaultValue(config) { return config.color; } }), size: _objectSpread(_objectSpread({}, _superPropGet(IconLayer, "visualChannels", this, 1).size), {}, { property: 'radius', range: 'radiusRange', channelScaleType: 'radius', accessor: 'getRadius', defaultValue: 1 }) }; } }, { key: "layerInfoModal", get: function get() { return { id: 'iconInfo', template: this._layerInfoModal, modalProps: { title: 'modal.iconInfo.title' } }; } }, { key: "getZoomFactor", value: function getZoomFactor(_ref3) { var zoom = _ref3.zoom, _ref3$zoomOffset = _ref3.zoomOffset, zoomOffset = _ref3$zoomOffset === void 0 ? 0 : _ref3$zoomOffset; return Math.pow(2, 14 - zoom + zoomOffset); } }, { key: "getSvgIcons", value: function getSvgIcons() { var _this2 = this; var fetchConfig = { method: 'GET', mode: 'cors', cache: 'no-cache' }; if (_window["default"].fetch && this.svgIconUrl) { _window["default"].fetch(this.svgIconUrl, fetchConfig).then(function (response) { return response.json(); }).then(function () { var parsed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _this2.setSvgIcons(parsed.svgIcons); }); } } }, { key: "setSvgIcons", value: function setSvgIcons() { var svgIcons = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; this.iconGeometry = svgIcons.reduce(function (accu, curr) { return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, curr.id, flatterIconPositions(curr))); }, {}); this._layerInfoModal = (0, _iconInfoModal["default"])(svgIcons); } }, { key: "getFilteredItemCount", value: function getFilteredItemCount() { // use total if (Object.keys(this.filteredItemCount).length) { return Object.values(this.filteredItemCount).reduce(function (total, curr) { return Number.isFinite(curr) ? total + curr : total; }, 0); } return null; } }, { key: "calculateDataAttribute", value: function calculateDataAttribute(_ref4, getPosition) { var dataContainer = _ref4.dataContainer, filteredIndex = _ref4.filteredIndex; var getIcon = this.getIconAccessor(dataContainer); var data = []; for (var i = 0; i < filteredIndex.length; i++) { var index = filteredIndex[i]; var rowIndex = { index: index }; var pos = getPosition(rowIndex); var icon = getIcon(rowIndex); // if doesn't have point lat or lng, do not add the point // deck.gl can't handle position = null if (pos.every(Number.isFinite) && typeof icon === 'string') { data.push({ index: index, icon: icon }); } } return data; } }, { key: "formatLayerData", value: function formatLayerData(datasets, oldLayerData) { if (this.config.dataId === null) { return {}; } var textLabel = this.config.textLabel; var _datasets$this$config = datasets[this.config.dataId], gpuFilter = _datasets$this$config.gpuFilter, dataContainer = _datasets$this$config.dataContainer; var getPosition = this.getPositionAccessor(dataContainer); var _this$updateData = this.updateData(datasets, oldLayerData), data = _this$updateData.data, triggerChanged = _this$updateData.triggerChanged; // get all distinct characters in the text labels var textLabels = (0, _layerTextLabel.formatTextLabelData)({ textLabel: textLabel, triggerChanged: triggerChanged, oldLayerData: oldLayerData, data: data, dataContainer: dataContainer }); var accessors = this.getAttributeAccessors({ dataContainer: dataContainer }); return _objectSpread({ data: data, getPosition: getPosition, getFilterValue: gpuFilter.filterValueAccessor(dataContainer)(), textLabels: textLabels }, accessors); } }, { key: "updateLayerMeta", value: function updateLayerMeta(dataset, getPosition) { var dataContainer = dataset.dataContainer; var bounds = this.getPointsBounds(dataContainer, getPosition); this.updateMeta({ bounds: bounds }); } }, { key: "renderLayer", value: function renderLayer(opts) { var _this$config$columns$, _this3 = this; var data = opts.data, gpuFilter = opts.gpuFilter, objectHovered = opts.objectHovered, mapState = opts.mapState, interactionConfig = opts.interactionConfig; var radiusScale = this.getRadiusScaleByZoom(mapState); var layerProps = _objectSpread({ radiusScale: radiusScale, billboard: this.config.visConfig.billboard }, this.config.visConfig.fixedRadius ? {} : { radiusMaxPixels: 500 }); var updateTriggers = _objectSpread({ getPosition: this.config.columns, getFilterValue: gpuFilter.filterValueUpdateTriggers }, this.getVisualChannelUpdateTriggers()); var defaultLayerProps = this.getDefaultDeckLayerProps(opts); var brushingProps = this.getBrushingExtensionProps(interactionConfig); var getPixelOffset = (0, _layerTextLabel.getTextOffsetByRadius)(radiusScale, data.getRadius, mapState); var extensions = [].concat((0, _toConsumableArray2["default"])(defaultLayerProps.extensions), [brushingExtension]); // shared Props between layer and label layer var sharedProps = _objectSpread({ getFilterValue: data.getFilterValue, extensions: extensions, filterRange: defaultLayerProps.filterRange }, brushingProps); var labelLayers = (0, _toConsumableArray2["default"])(this.renderTextLabelLayer({ getPosition: data.getPosition, sharedProps: sharedProps, getPixelOffset: getPixelOffset, updateTriggers: updateTriggers }, opts)); var hoveredObject = this.hasHoveredObject(objectHovered); var parameters = { // icons will be flat on the map when the altitude column is not used depthTest: ((_this$config$columns$ = this.config.columns.altitude) === null || _this$config$columns$ === void 0 ? void 0 : _this$config$columns$.fieldIdx) > -1, cullFace: _constants["default"].FRONT }; return !this.iconGeometry ? [] : [new _deckglLayers.SvgIconLayer(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultLayerProps), brushingProps), layerProps), data), {}, { parameters: parameters, getIconGeometry: function getIconGeometry(id) { var _this3$iconGeometry; return (_this3$iconGeometry = _this3.iconGeometry) === null || _this3$iconGeometry === void 0 ? void 0 : _this3$iconGeometry[id]; }, // update triggers updateTriggers: updateTriggers, extensions: extensions }))].concat((0, _toConsumableArray2["default"])(hoveredObject ? [ // @ts-expect-error SvgIconLayerProps needs getIcon Field new _deckglLayers.SvgIconLayer(_objectSpread(_objectSpread(_objectSpread({}, this.getDefaultHoverLayerProps()), layerProps), {}, { visible: defaultLayerProps.visible, data: [hoveredObject], parameters: parameters, getPosition: data.getPosition, getRadius: data.getRadius, getFillColor: this.config.highlightColor, getIconGeometry: function getIconGeometry(id) { var _this3$iconGeometry2; return (_this3$iconGeometry2 = _this3.iconGeometry) === null || _this3$iconGeometry2 === void 0 ? void 0 : _this3$iconGeometry2[id]; } }))] : []), (0, _toConsumableArray2["default"])(labelLayers)); } }], [{ key: "findDefaultLayerProps", value: function findDefaultLayerProps(_ref5) { var _ref5$fieldPairs = _ref5.fieldPairs, fieldPairs = _ref5$fieldPairs === void 0 ? [] : _ref5$fieldPairs, _ref5$fields = _ref5.fields, fields = _ref5$fields === void 0 ? [] : _ref5$fields; var notFound = { props: [] }; if (!fieldPairs.length || !fields.length) { return notFound; } var iconFields = fields.filter(function (_ref6) { var name = _ref6.name; return name.replace(/[_,.]+/g, ' ').trim().split(' ').some(function (seg) { return _constants2.ICON_FIELDS.icon.some(function (t) { return t.includes(seg); }); }); }); if (!iconFields.length) { return notFound; } // create icon layers for first point pair var ptPair = fieldPairs[0]; var columns = (0, _layerUtils.assignPointPairToLayerColumn)(ptPair, true); var props = iconFields.map(function (iconField) { return { label: iconField.name.replace(/[_,.]+/g, ' ').trim(), columns: _objectSpread(_objectSpread({}, columns), {}, { icon: { value: iconField.name, fieldIdx: iconField.fieldIdx } }), isVisible: true }; }); return { props: props }; } }]); }(_baseLayer["default"]); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfd2luZG93IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZXh0ZW5zaW9ucyIsIl9jb25zdGFudHMiLCJfZGVja2dsTGF5ZXJzIiwiX2ljb25MYXllckljb24iLCJfY29uc3RhbnRzMiIsIl9pY29uSW5mb01vZGFsIiwiX2Jhc2VMYXllciIsIl9sYXllclV0aWxzIiwiX3V0aWxzIiwiX2xheWVyVGV4dExhYmVsIiwib3duS2V5cyIsImUiLCJyIiwidCIsIk9iamVjdCIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJfY2FsbFN1cGVyIiwiX2dldFByb3RvdHlwZU9mMiIsIl9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMiIsIl9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QiLCJSZWZsZWN0IiwiY29uc3RydWN0IiwiY29uc3RydWN0b3IiLCJCb29sZWFuIiwicHJvdG90eXBlIiwidmFsdWVPZiIsImNhbGwiLCJfc3VwZXJQcm9wR2V0IiwicCIsIl9nZXQyIiwiYnJ1c2hpbmdFeHRlbnNpb24iLCJCcnVzaGluZ0V4dGVuc2lvbiIsImljb25Qb3NBY2Nlc3NvciIsImV4cG9ydHMiLCJfcmVmIiwibGF0IiwibG5nIiwiYWx0aXR1ZGUiLCJkYyIsImQiLCJ2YWx1ZUF0IiwiaW5kZXgiLCJmaWVsZElkeCIsImljb25BY2Nlc3NvciIsIl9yZWYyIiwiaWNvbiIsImljb25SZXF1aXJlZENvbHVtbnMiLCJpY29uT3B0aW9uYWxDb2x1bW5zIiwicG9pbnRWaXNDb25maWdzIiwicmFkaXVzIiwiZml4ZWRSYWRpdXMiLCJvcGFjaXR5IiwiY29sb3JSYW5nZSIsInJhZGl1c1JhbmdlIiwiYmlsbGJvYXJkIiwiZmxhdHRlckljb25Qb3NpdGlvbnMiLCJtZXNoIiwiY2VsbHMiLCJyZWR1Y2UiLCJwcmV2IiwiY2VsbCIsInBvc2l0aW9ucyIsIkljb25MYXllciIsIl9MYXllciIsInByb3BzIiwiX3RoaXMiLCJfY2xhc3NDYWxsQ2hlY2syIiwicmVnaXN0ZXJWaXNDb25maWciLCJnZXRQb3NpdGlvbkFjY2Vzc29yIiwiZGF0YUNvbnRhaW5lciIsImNvbmZpZyIsImNvbHVtbnMiLCJnZXRJY29uQWNjZXNzb3IiLCJfbGF5ZXJJbmZvTW9kYWwiLCJJY29uSW5mb01vZGFsRmFjdG9yeSIsInN2Z0ljb25zIiwiaWNvbkdlb21ldHJ5IiwiaXNUZXN0Iiwic2V0U3ZnSWNvbnMiLCJnZXRTdmdJY29ucyIsIl9pbmhlcml0czIiLCJfY3JlYXRlQ2xhc3MyIiwia2V5IiwiZ2V0IiwiY29uY2F0IiwiZ2V0QXBwbGljYXRpb25Db25maWciLCJjZG5VcmwiLCJkZWZhdWx0UG9pbnRDb2x1bW5QYWlycyIsIkljb25MYXllckljb24iLCJjb2xvciIsImFjY2Vzc29yIiwiZGVmYXVsdFZhbHVlIiwic2l6ZSIsInByb3BlcnR5IiwicmFuZ2UiLCJjaGFubmVsU2NhbGVUeXBlIiwiaWQiLCJ0ZW1wbGF0ZSIsIm1vZGFsUHJvcHMiLCJ0aXRsZSIsInZhbHVlIiwiZ2V0Wm9vbUZhY3RvciIsIl9yZWYzIiwiem9vbSIsIl9yZWYzJHpvb21PZmZzZXQiLCJ6b29tT2Zmc2V0IiwiTWF0aCIsInBvdyIsIl90aGlzMiIsImZldGNoQ29uZmlnIiwibWV0aG9kIiwibW9kZSIsImNhY2hlIiwiV2luZG93IiwiZmV0Y2giLCJzdmdJY29uVXJsIiwidGhlbiIsInJlc3BvbnNlIiwianNvbiIsInBhcnNlZCIsInVuZGVmaW5lZCIsImFjY3UiLCJjdXJyIiwiZ2V0RmlsdGVyZWRJdGVtQ291bnQiLCJmaWx0ZXJlZEl0ZW1Db3VudCIsInZhbHVlcyIsInRvdGFsIiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJjYWxjdWxhdGVEYXRhQXR0cmlidXRlIiwiX3JlZjQiLCJnZXRQb3NpdGlvbiIsImZpbHRlcmVkSW5kZXgiLCJnZXRJY29uIiwiZGF0YSIsImkiLCJyb3dJbmRleCIsInBvcyIsImV2ZXJ5IiwiZm9ybWF0TGF5ZXJEYXRhIiwiZGF0YXNldHMiLCJvbGRMYXllckRhdGEiLCJkYXRhSWQiLCJ0ZXh0TGFiZWwiLCJfZGF0YXNldHMkdGhpcyRjb25maWciLCJncHVGaWx0ZXIiLCJfdGhpcyR1cGRhdGVEYXRhIiwidXBkYXRlRGF0YSIsInRyaWdnZXJDaGFuZ2VkIiwidGV4dExhYmVscyIsImZvcm1hdFRleHRMYWJlbERhdGEiLCJhY2Nlc3NvcnMiLCJnZXRBdHRyaWJ1dGVBY2Nlc3NvcnMiLCJnZXRGaWx0ZXJWYWx1ZSIsImZpbHRlclZhbHVlQWNjZXNzb3IiLCJ1cGRhdGVMYXllck1ldGEiLCJkYXRhc2V0IiwiYm91bmRzIiwiZ2V0UG9pbnRzQm91bmRzIiwidXBkYXRlTWV0YSIsInJlbmRlckxheWVyIiwib3B0cyIsIl90aGlzJGNvbmZpZyRjb2x1bW5zJCIsIl90aGlzMyIsIm9iamVjdEhvdmVyZWQiLCJtYXBTdGF0ZSIsImludGVyYWN0aW9uQ29uZmlnIiwicmFkaXVzU2NhbGUiLCJnZXRSYWRpdXNTY2FsZUJ5Wm9vbSIsImxheWVyUHJvcHMiLCJ2aXNDb25maWciLCJyYWRpdXNNYXhQaXhlbHMiLCJ1cGRhdGVUcmlnZ2VycyIsImZpbHRlclZhbHVlVXBkYXRlVHJpZ2dlcnMiLCJnZXRWaXN1YWxDaGFubmVsVXBkYXRlVHJpZ2dlcnMiLCJkZWZhdWx0TGF5ZXJQcm9wcyIsImdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyIsImJydXNoaW5nUHJvcHMiLCJnZXRCcnVzaGluZ0V4dGVuc2lvblByb3BzIiwiZ2V0UGl4ZWxPZmZzZXQiLCJnZXRUZXh0T2Zmc2V0QnlSYWRpdXMiLCJnZXRSYWRpdXMiLCJleHRlbnNpb25zIiwiX3RvQ29uc3VtYWJsZUFycmF5MiIsInNoYXJlZFByb3BzIiwiZmlsdGVyUmFuZ2UiLCJsYWJlbExheWVycyIsInJlbmRlclRleHRMYWJlbExheWVyIiwiaG92ZXJlZE9iamVjdCIsImhhc0hvdmVyZWRPYmplY3QiLCJwYXJhbWV0ZXJzIiwiZGVwdGhUZXN0IiwiY3VsbEZhY2UiLCJHTCIsIkZST05UIiwiU3ZnSWNvbkxheWVyIiwiZ2V0SWNvbkdlb21ldHJ5IiwiX3RoaXMzJGljb25HZW9tZXRyeSIsImdldERlZmF1bHRIb3ZlckxheWVyUHJvcHMiLCJ2aXNpYmxlIiwiZ2V0RmlsbENvbG9yIiwiaGlnaGxpZ2h0Q29sb3IiLCJfdGhpczMkaWNvbkdlb21ldHJ5MiIsImZpbmREZWZhdWx0TGF5ZXJQcm9wcyIsIl9yZWY1IiwiX3JlZjUkZmllbGRQYWlycyIsImZpZWxkUGFpcnMiLCJfcmVmNSRmaWVsZHMiLCJmaWVsZHMiLCJub3RGb3VuZCIsImljb25GaWVsZHMiLCJfcmVmNiIsIm5hbWUiLCJyZXBsYWNlIiwidHJpbSIsInNwbGl0Iiwic29tZSIsInNlZyIsIklDT05fRklFTERTIiwiaW5jbHVkZXMiLCJwdFBhaXIiLCJhc3NpZ25Qb2ludFBhaXJUb0xheWVyQ29sdW1uIiwibWFwIiwiaWNvbkZpZWxkIiwibGFiZWwiLCJpc1Zpc2libGUiLCJMYXllciJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pY29uLWxheWVyL2ljb24tbGF5ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IFdpbmRvdyBmcm9tICdnbG9iYWwvd2luZG93JztcbmltcG9ydCB7QnJ1c2hpbmdFeHRlbnNpb259IGZyb20gJ0BkZWNrLmdsL2V4dGVuc2lvbnMnO1xuaW1wb3J0IEdMIGZyb20gJ0BsdW1hLmdsL2NvbnN0YW50cyc7XG5cbmltcG9ydCB7U3ZnSWNvbkxheWVyfSBmcm9tICdAa2VwbGVyLmdsL2RlY2tnbC1sYXllcnMnO1xuaW1wb3J0IEljb25MYXllckljb24gZnJvbSAnLi9pY29uLWxheWVyLWljb24nO1xuaW1wb3J0IHtJQ09OX0ZJRUxEU30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IEljb25JbmZvTW9kYWxGYWN0b3J5IGZyb20gJy4vaWNvbi1pbmZvLW1vZGFsJztcbmltcG9ydCBMYXllciwge0xheWVyQmFzZUNvbmZpZywgTGF5ZXJCYXNlQ29uZmlnUGFydGlhbH0gZnJvbSAnLi4vYmFzZS1sYXllcic7XG5pbXBvcnQge2Fzc2lnblBvaW50UGFpclRvTGF5ZXJDb2x1bW4sIEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlfSBmcm9tICcuLi9sYXllci11dGlscyc7XG5pbXBvcnQge2lzVGVzdH0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5pbXBvcnQge2dldFRleHRPZmZzZXRCeVJhZGl1cywgZm9ybWF0VGV4dExhYmVsRGF0YX0gZnJvbSAnLi4vbGF5ZXItdGV4dC1sYWJlbCc7XG5pbXBvcnQge2RlZmF1bHQgYXMgS2VwbGVyVGFibGV9IGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuaW1wb3J0IHtnZXRBcHBsaWNhdGlvbkNvbmZpZywgRGF0YUNvbnRhaW5lckludGVyZmFjZX0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5pbXBvcnQge1xuICBDb2xvclJhbmdlLFxuICBWaXNDb25maWdCb29sZWFuLFxuICBWaXNDb25maWdDb2xvclJhbmdlLFxuICBWaXNDb25maWdOdW1iZXIsXG4gIFZpc0NvbmZpZ1JhbmdlLFxuICBNZXJnZSxcbiAgTGF5ZXJDb2x1bW5cbn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5cbmV4cG9ydCB0eXBlIEljb25MYXllckNvbHVtbnNDb25maWcgPSB7XG4gIGxhdDogTGF5ZXJDb2x1bW47XG4gIGxuZzogTGF5ZXJDb2x1bW47XG4gIGFsdGl0dWRlOiBMYXllckNvbHVtbjtcbiAgaWNvbjogTGF5ZXJDb2x1bW47XG59O1xuXG50eXBlIEljb25HZW9tZXRyeSA9IG9iamVjdCB8IG51bGw7XG5cbmV4cG9ydCB0eXBlIEljb25MYXllclZpc0NvbmZpZ1NldHRpbmdzID0ge1xuICByYWRpdXM6IFZpc0NvbmZpZ051bWJlcjtcbiAgZml4ZWRSYWRpdXM6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIG9wYWNpdHk6IFZpc0NvbmZpZ051bWJlcjtcbiAgY29sb3JSYW5nZTogVmlzQ29uZmlnQ29sb3JSYW5nZTtcbiAgcmFkaXVzUmFuZ2U6IFZpc0NvbmZpZ1JhbmdlO1xufTtcblxuZXhwb3J0IHR5cGUgSWNvbkxheWVyVmlzQ29uZmlnID0ge1xuICByYWRpdXM6IG51bWJlcjtcbiAgZml4ZWRSYWRpdXM6IGJvb2xlYW47XG4gIG9wYWNpdHk6IG51bWJlcjtcbiAgY29sb3JSYW5nZTogQ29sb3JSYW5nZTtcbiAgcmFkaXVzUmFuZ2U6IFtudW1iZXIsIG51bWJlcl07XG4gIGJpbGxib2FyZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCB0eXBlIEljb25MYXllckNvbmZpZyA9IE1lcmdlPFxuICBMYXllckJhc2VDb25maWcsXG4gIHtjb2x1bW5zOiBJY29uTGF5ZXJDb2x1bW5zQ29uZmlnOyB2aXNDb25maWc6IEljb25MYXllclZpc0NvbmZpZ31cbj47XG5cbmV4cG9ydCB0eXBlIEljb25MYXllckRhdGEgPSB7aW5kZXg6IG51bWJlcjsgaWNvbjogc3RyaW5nfTtcblxuY29uc3QgYnJ1c2hpbmdFeHRlbnNpb24gPSBuZXcgQnJ1c2hpbmdFeHRlbnNpb24oKTtcblxuZXhwb3J0IGNvbnN0IGljb25Qb3NBY2Nlc3NvciA9XG4gICh7bGF0LCBsbmcsIGFsdGl0dWRlfTogSWNvbkxheWVyQ29sdW1uc0NvbmZpZykgPT5cbiAgKGRjOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKSA9PlxuICBkID0+XG4gICAgW1xuICAgICAgZGMudmFsdWVBdChkLmluZGV4LCBsbmcuZmllbGRJZHgpLFxuICAgICAgZGMudmFsdWVBdChkLmluZGV4LCBsYXQuZmllbGRJZHgpLFxuICAgICAgYWx0aXR1ZGU/LmZpZWxkSWR4ID4gLTEgPyBkYy52YWx1ZUF0KGQuaW5kZXgsIGFsdGl0dWRlLmZpZWxkSWR4KSA6IDBcbiAgICBdO1xuXG5leHBvcnQgY29uc3QgaWNvbkFjY2Vzc29yID1cbiAgKHtpY29ufTogSWNvbkxheWVyQ29sdW1uc0NvbmZpZykgPT5cbiAgKGRjOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKSA9PlxuICBkID0+XG4gICAgZGMudmFsdWVBdChkLmluZGV4LCBpY29uLmZpZWxkSWR4KTtcblxuZXhwb3J0IGNvbnN0IGljb25SZXF1aXJlZENvbHVtbnM6IFsnbGF0JywgJ2xuZycsICdpY29uJ10gPSBbJ2xhdCcsICdsbmcnLCAnaWNvbiddO1xuZXhwb3J0IGNvbnN0IGljb25PcHRpb25hbENvbHVtbnM6IFsnYWx0aXR1ZGUnXSA9IFsnYWx0aXR1ZGUnXTtcblxuZXhwb3J0IGNvbnN0IHBvaW50VmlzQ29uZmlnczoge1xuICByYWRpdXM6ICdyYWRpdXMnO1xuICBmaXhlZFJhZGl1czogJ2ZpeGVkUmFkaXVzJztcbiAgb3BhY2l0eTogJ29wYWNpdHknO1xuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZSc7XG4gIHJhZGl1c1JhbmdlOiAncmFkaXVzUmFuZ2UnO1xuICBiaWxsYm9hcmQ6ICdiaWxsYm9hcmQnO1xufSA9IHtcbiAgcmFkaXVzOiAncmFkaXVzJyxcbiAgZml4ZWRSYWRpdXM6ICdmaXhlZFJhZGl1cycsXG4gIG9wYWNpdHk6ICdvcGFjaXR5JyxcbiAgY29sb3JSYW5nZTogJ2NvbG9yUmFuZ2UnLFxuICByYWRpdXNSYW5nZTogJ3JhZGl1c1JhbmdlJyxcbiAgYmlsbGJvYXJkOiAnYmlsbGJvYXJkJ1xufTtcblxuZnVuY3Rpb24gZmxhdHRlckljb25Qb3NpdGlvbnMoaWNvbikge1xuICAvLyBoYWQgdG8gZmxpcCB5LCBzaW5jZSBAbHVtYSBtb2RhbCBoYXMgY2hhbmdlZFxuICByZXR1cm4gaWNvbi5tZXNoLmNlbGxzLnJlZHVjZSgocHJldiwgY2VsbCkgPT4ge1xuICAgIGNlbGwuZm9yRWFjaChwID0+IHtcbiAgICAgIHByZXYucHVzaChcbiAgICAgICAgLi4uW2ljb24ubWVzaC5wb3NpdGlvbnNbcF1bMF0sIC1pY29uLm1lc2gucG9zaXRpb25zW3BdWzFdLCBpY29uLm1lc2gucG9zaXRpb25zW3BdWzJdXVxuICAgICAgKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcHJldjtcbiAgfSwgW10pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJY29uTGF5ZXIgZXh0ZW5kcyBMYXllciB7XG4gIGdldEljb25BY2Nlc3NvcjogKGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+IChkOiBhbnkpID0+IGFueTtcbiAgX2xheWVySW5mb01vZGFsOiAoKSA9PiBKU1guRWxlbWVudDtcbiAgaWNvbkdlb21ldHJ5OiBJY29uR2VvbWV0cnk7XG5cbiAgZGVjbGFyZSB2aXNDb25maWdTZXR0aW5nczogSWNvbkxheWVyVmlzQ29uZmlnU2V0dGluZ3M7XG4gIGRlY2xhcmUgY29uZmlnOiBJY29uTGF5ZXJDb25maWc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvcHM6IHtcbiAgICAgIGlkPzogc3RyaW5nO1xuICAgICAgaWNvbkdlb21ldHJ5PzogSWNvbkdlb21ldHJ5O1xuICAgICAgc3ZnSWNvbnM/OiBhbnlbXTtcbiAgICB9ICYgTGF5ZXJCYXNlQ29uZmlnUGFydGlhbFxuICApIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyVmlzQ29uZmlnKHBvaW50VmlzQ29uZmlncyk7XG4gICAgdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yID0gKGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+XG4gICAgICBpY29uUG9zQWNjZXNzb3IodGhpcy5jb25maWcuY29sdW1ucykoZGF0YUNvbnRhaW5lcik7XG4gICAgdGhpcy5nZXRJY29uQWNjZXNzb3IgPSBkYXRhQ29udGFpbmVyID0+IGljb25BY2Nlc3Nvcih0aGlzLmNvbmZpZy5jb2x1bW5zKShkYXRhQ29udGFpbmVyKTtcblxuICAgIHRoaXMuX2xheWVySW5mb01vZGFsID0gSWNvbkluZm9Nb2RhbEZhY3RvcnkocHJvcHMuc3ZnSWNvbnMpO1xuICAgIHRoaXMuaWNvbkdlb21ldHJ5ID0gcHJvcHMuaWNvbkdlb21ldHJ5IHx8IG51bGw7XG5cbiAgICBpZiAoaXNUZXN0KCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHByb3BzLnN2Z0ljb25zKSB7XG4gICAgICAvLyBpZiBzdmcgaWNvbnMgYXJlIHBhc3NlZCBpbiB0aGVuIGJ5cGFzcyBmZXRjaGluZyBvZiByZW1vdGUgc3ZnIGljb25zXG4gICAgICB0aGlzLnNldFN2Z0ljb25zKHByb3BzLnN2Z0ljb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcHJlcGFyZSBsYXllciBpbmZvIG1vZGFsIGFuZCBmZXRjaCByZW1vdGUgc3ZnIGljb25zXG4gICAgICB0aGlzLmdldFN2Z0ljb25zKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHN2Z0ljb25VcmwoKSB7XG4gICAgcmV0dXJuIGAke2dldEFwcGxpY2F0aW9uQ29uZmlnKCkuY2RuVXJsfS9pY29ucy9zdmctaWNvbnMuanNvbmA7XG4gIH1cblxuICBnZXQgdHlwZSgpOiAnaWNvbicge1xuICAgIHJldHVybiAnaWNvbic7XG4gIH1cblxuICBnZXQgcmVxdWlyZWRMYXllckNvbHVtbnMoKSB7XG4gICAgcmV0dXJuIGljb25SZXF1aXJlZENvbHVtbnM7XG4gIH1cblxuICBnZXQgb3B0aW9uYWxDb2x1bW5zKCkge1xuICAgIHJldHVybiBpY29uT3B0aW9uYWxDb2x1bW5zO1xuICB9XG5cbiAgZ2V0IGNvbHVtblBhaXJzKCkge1xuICAgIHJldHVybiB0aGlzLmRlZmF1bHRQb2ludENvbHVtblBhaXJzO1xuICB9XG5cbiAgZ2V0IGxheWVySWNvbigpIHtcbiAgICByZXR1cm4gSWNvbkxheWVySWNvbjtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6IHtcbiAgICAgICAgLi4uc3VwZXIudmlzdWFsQ2hhbm5lbHMuY29sb3IsXG4gICAgICAgIGFjY2Vzc29yOiAnZ2V0RmlsbENvbG9yJyxcbiAgICAgICAgZGVmYXVsdFZhbHVlOiBjb25maWcgPT4gY29uZmlnLmNvbG9yXG4gICAgICB9LFxuICAgICAgc2l6ZToge1xuICAgICAgICAuLi5zdXBlci52aXN1YWxDaGFubmVscy5zaXplLFxuICAgICAgICBwcm9wZXJ0eTogJ3JhZGl1cycsXG4gICAgICAgIHJhbmdlOiAncmFkaXVzUmFuZ2UnLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiAncmFkaXVzJyxcbiAgICAgICAgYWNjZXNzb3I6ICdnZXRSYWRpdXMnLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IDFcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZ2V0IGxheWVySW5mb01vZGFsKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogJ2ljb25JbmZvJyxcbiAgICAgIHRlbXBsYXRlOiB0aGlzLl9sYXllckluZm9Nb2RhbCxcbiAgICAgIG1vZGFsUHJvcHM6IHtcbiAgICAgICAgdGl0bGU6ICdtb2RhbC5pY29uSW5mby50aXRsZSdcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZ2V0Wm9vbUZhY3Rvcih7em9vbSwgem9vbU9mZnNldCA9IDB9OiB7em9vbTogbnVtYmVyOyB6b29tT2Zmc2V0PzogbnVtYmVyfSkge1xuICAgIHJldHVybiBNYXRoLnBvdygyLCAxNCAtIHpvb20gKyB6b29tT2Zmc2V0KTtcbiAgfVxuXG4gIGdldFN2Z0ljb25zKCkge1xuICAgIGNvbnN0IGZldGNoQ29uZmlnID0ge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIG1vZGU6ICdjb3JzJyxcbiAgICAgIGNhY2hlOiAnbm8tY2FjaGUnXG4gICAgfTtcblxuICAgIGlmIChXaW5kb3cuZmV0Y2ggJiYgdGhpcy5zdmdJY29uVXJsKSB7XG4gICAgICBXaW5kb3cuZmV0Y2godGhpcy5zdmdJY29uVXJsLCBmZXRjaENvbmZpZylcbiAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UuanNvbigpKVxuICAgICAgICAudGhlbigocGFyc2VkOiB7c3ZnSWNvbnM/OiBhbnlbXX0gPSB7fSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0U3ZnSWNvbnMocGFyc2VkLnN2Z0ljb25zKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0U3ZnSWNvbnMoc3ZnSWNvbnM6IGFueVtdID0gW10pIHtcbiAgICB0aGlzLmljb25HZW9tZXRyeSA9IHN2Z0ljb25zLnJlZHVjZShcbiAgICAgIChhY2N1LCBjdXJyKSA9PiAoe1xuICAgICAgICAuLi5hY2N1LFxuICAgICAgICBbY3Vyci5pZF06IGZsYXR0ZXJJY29uUG9zaXRpb25zKGN1cnIpXG4gICAgICB9KSxcbiAgICAgIHt9XG4gICAgKTtcblxuICAgIHRoaXMuX2xheWVySW5mb01vZGFsID0gSWNvbkluZm9Nb2RhbEZhY3Rvcnkoc3ZnSWNvbnMpO1xuICB9XG5cbiAgc3RhdGljIGZpbmREZWZhdWx0TGF5ZXJQcm9wcyh7XG4gICAgZmllbGRQYWlycyA9IFtdLFxuICAgIGZpZWxkcyA9IFtdXG4gIH06IEtlcGxlclRhYmxlKTogRmluZERlZmF1bHRMYXllclByb3BzUmV0dXJuVmFsdWUge1xuICAgIGNvbnN0IG5vdEZvdW5kOiBGaW5kRGVmYXVsdExheWVyUHJvcHNSZXR1cm5WYWx1ZSA9IHtwcm9wczogW119O1xuICAgIGlmICghZmllbGRQYWlycy5sZW5ndGggfHwgIWZpZWxkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBub3RGb3VuZDtcbiAgICB9XG5cbiAgICBjb25zdCBpY29uRmllbGRzID0gZmllbGRzLmZpbHRlcigoe25hbWV9KSA9PlxuICAgICAgbmFtZVxuICAgICAgICAucmVwbGFjZSgvW18sLl0rL2csICcgJylcbiAgICAgICAgLnRyaW0oKVxuICAgICAgICAuc3BsaXQoJyAnKVxuICAgICAgICAuc29tZShzZWcgPT4gSUNPTl9GSUVMRFMuaWNvbi5zb21lKHQgPT4gdC5pbmNsdWRlcyhzZWcpKSlcbiAgICApO1xuXG4gICAgaWYgKCFpY29uRmllbGRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG5vdEZvdW5kO1xuICAgIH1cblxuICAgIC8vIGNyZWF0ZSBpY29uIGxheWVycyBmb3IgZmlyc3QgcG9pbnQgcGFpclxuICAgIGNvbnN0IHB0UGFpciA9IGZpZWxkUGFpcnNbMF07XG4gICAgY29uc3QgY29sdW1ucyA9IGFzc2lnblBvaW50UGFpclRvTGF5ZXJDb2x1bW4ocHRQYWlyLCB0cnVlKTtcblxuICAgIGNvbnN0IHByb3BzID0gaWNvbkZpZWxkcy5tYXAoaWNvbkZpZWxkID0+ICh7XG4gICAgICBsYWJlbDogaWNvbkZpZWxkLm5hbWUucmVwbGFjZSgvW18sLl0rL2csICcgJykudHJpbSgpLFxuICAgICAgY29sdW1uczoge1xuICAgICAgICAuLi5jb2x1bW5zLFxuICAgICAgICBpY29uOiB7XG4gICAgICAgICAgdmFsdWU6IGljb25GaWVsZC5uYW1lLFxuICAgICAgICAgIGZpZWxkSWR4OiBpY29uRmllbGQuZmllbGRJZHhcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGlzVmlzaWJsZTogdHJ1ZVxuICAgIH0pKTtcblxuICAgIHJldHVybiB7cHJvcHN9O1xuICB9XG5cbiAgZ2V0RmlsdGVyZWRJdGVtQ291bnQoKSB7XG4gICAgLy8gdXNlIHRvdGFsXG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuZmlsdGVyZWRJdGVtQ291bnQpLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5maWx0ZXJlZEl0ZW1Db3VudCkucmVkdWNlKFxuICAgICAgICAodG90YWwsIGN1cnIpID0+IChOdW1iZXIuaXNGaW5pdGUoY3VycikgPyB0b3RhbCArIGN1cnIgOiB0b3RhbCksXG4gICAgICAgIDBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjYWxjdWxhdGVEYXRhQXR0cmlidXRlKHtkYXRhQ29udGFpbmVyLCBmaWx0ZXJlZEluZGV4fTogS2VwbGVyVGFibGUsIGdldFBvc2l0aW9uKSB7XG4gICAgY29uc3QgZ2V0SWNvbiA9IHRoaXMuZ2V0SWNvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuICAgIGNvbnN0IGRhdGE6IEljb25MYXllckRhdGFbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWx0ZXJlZEluZGV4Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGZpbHRlcmVkSW5kZXhbaV07XG4gICAgICBjb25zdCByb3dJbmRleCA9IHtpbmRleH07XG4gICAgICBjb25zdCBwb3MgPSBnZXRQb3NpdGlvbihyb3dJbmRleCk7XG4gICAgICBjb25zdCBpY29uID0gZ2V0SWNvbihyb3dJbmRleCk7XG5cbiAgICAgIC8vIGlmIGRvZXNuJ3QgaGF2ZSBwb2ludCBsYXQgb3IgbG5nLCBkbyBub3QgYWRkIHRoZSBwb2ludFxuICAgICAgLy8gZGVjay5nbCBjYW4ndCBoYW5kbGUgcG9zaXRpb24gPSBudWxsXG4gICAgICBpZiAocG9zLmV2ZXJ5KE51bWJlci5pc0Zpbml0ZSkgJiYgdHlwZW9mIGljb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGRhdGEucHVzaCh7XG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgaWNvblxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIGZvcm1hdExheWVyRGF0YShkYXRhc2V0cywgb2xkTGF5ZXJEYXRhKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLmRhdGFJZCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCB7dGV4dExhYmVsfSA9IHRoaXMuY29uZmlnO1xuICAgIGNvbnN0IHtncHVGaWx0ZXIsIGRhdGFDb250YWluZXJ9ID0gZGF0YXNldHNbdGhpcy5jb25maWcuZGF0YUlkXTtcblxuICAgIGNvbnN0IGdldFBvc2l0aW9uID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuXG4gICAgY29uc3Qge2RhdGEsIHRyaWdnZXJDaGFuZ2VkfSA9IHRoaXMudXBkYXRlRGF0YShkYXRhc2V0cywgb2xkTGF5ZXJEYXRhKTtcblxuICAgIC8vIGdldCBhbGwgZGlzdGluY3QgY2hhcmFjdGVycyBpbiB0aGUgdGV4dCBsYWJlbHNcbiAgICBjb25zdCB0ZXh0TGFiZWxzID0gZm9ybWF0VGV4dExhYmVsRGF0YSh7XG4gICAgICB0ZXh0TGFiZWwsXG4gICAgICB0cmlnZ2VyQ2hhbmdlZCxcbiAgICAgIG9sZExheWVyRGF0YSxcbiAgICAgIGRhdGEsXG4gICAgICBkYXRhQ29udGFpbmVyXG4gICAgfSk7XG5cbiAgICBjb25zdCBhY2Nlc3NvcnMgPSB0aGlzLmdldEF0dHJpYnV0ZUFjY2Vzc29ycyh7ZGF0YUNvbnRhaW5lcn0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGEsXG4gICAgICBnZXRQb3NpdGlvbixcbiAgICAgIGdldEZpbHRlclZhbHVlOiBncHVGaWx0ZXIuZmlsdGVyVmFsdWVBY2Nlc3NvcihkYXRhQ29udGFpbmVyKSgpLFxuICAgICAgdGV4dExhYmVscyxcbiAgICAgIC4uLmFjY2Vzc29yc1xuICAgIH07XG4gIH1cblxuICB1cGRhdGVMYXllck1ldGEoZGF0YXNldDogS2VwbGVyVGFibGUsIGdldFBvc2l0aW9uKSB7XG4gICAgY29uc3Qge2RhdGFDb250YWluZXJ9ID0gZGF0YXNldDtcbiAgICBjb25zdCBib3VuZHMgPSB0aGlzLmdldFBvaW50c0JvdW5kcyhkYXRhQ29udGFpbmVyLCBnZXRQb3NpdGlvbik7XG4gICAgdGhpcy51cGRhdGVNZXRhKHtib3VuZHN9KTtcbiAgfVxuXG4gIHJlbmRlckxheWVyKG9wdHMpIHtcbiAgICBjb25zdCB7ZGF0YSwgZ3B1RmlsdGVyLCBvYmplY3RIb3ZlcmVkLCBtYXBTdGF0ZSwgaW50ZXJhY3Rpb25Db25maWd9ID0gb3B0cztcblxuICAgIGNvbnN0IHJhZGl1c1NjYWxlID0gdGhpcy5nZXRSYWRpdXNTY2FsZUJ5Wm9vbShtYXBTdGF0ZSk7XG5cbiAgICBjb25zdCBsYXllclByb3BzID0ge1xuICAgICAgcmFkaXVzU2NhbGUsXG4gICAgICBiaWxsYm9hcmQ6IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5iaWxsYm9hcmQsXG4gICAgICAuLi4odGhpcy5jb25maWcudmlzQ29uZmlnLmZpeGVkUmFkaXVzID8ge30gOiB7cmFkaXVzTWF4UGl4ZWxzOiA1MDB9KVxuICAgIH07XG5cbiAgICBjb25zdCB1cGRhdGVUcmlnZ2VycyA9IHtcbiAgICAgIGdldFBvc2l0aW9uOiB0aGlzLmNvbmZpZy5jb2x1bW5zLFxuICAgICAgZ2V0RmlsdGVyVmFsdWU6IGdwdUZpbHRlci5maWx0ZXJWYWx1ZVVwZGF0ZVRyaWdnZXJzLFxuICAgICAgLi4udGhpcy5nZXRWaXN1YWxDaGFubmVsVXBkYXRlVHJpZ2dlcnMoKVxuICAgIH07XG5cbiAgICBjb25zdCBkZWZhdWx0TGF5ZXJQcm9wcyA9IHRoaXMuZ2V0RGVmYXVsdERlY2tMYXllclByb3BzKG9wdHMpO1xuICAgIGNvbnN0IGJydXNoaW5nUHJvcHMgPSB0aGlzLmdldEJydXNoaW5nRXh0ZW5zaW9uUHJvcHMoaW50ZXJhY3Rpb25Db25maWcpO1xuICAgIGNvbnN0IGdldFBpeGVsT2Zmc2V0ID0gZ2V0VGV4dE9mZnNldEJ5UmFkaXVzKHJhZGl1c1NjYWxlLCBkYXRhLmdldFJhZGl1cywgbWFwU3RhdGUpO1xuICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBbLi4uZGVmYXVsdExheWVyUHJvcHMuZXh0ZW5zaW9ucywgYnJ1c2hpbmdFeHRlbnNpb25dO1xuXG4gICAgLy8gc2hhcmVkIFByb3BzIGJldHdlZW4gbGF5ZXIgYW5kIGxhYmVsIGxheWVyXG4gICAgY29uc3Qgc2hhcmVkUHJvcHMgPSB7XG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZGF0YS5nZXRGaWx0ZXJWYWx1ZSxcbiAgICAgIGV4dGVuc2lvbnMsXG4gICAgICBmaWx0ZXJSYW5nZTogZGVmYXVsdExheWVyUHJvcHMuZmlsdGVyUmFuZ2UsXG4gICAgICAuLi5icnVzaGluZ1Byb3BzXG4gICAgfTtcblxuICAgIGNvbnN0IGxhYmVsTGF5ZXJzID0gW1xuICAgICAgLi4udGhpcy5yZW5kZXJUZXh0TGFiZWxMYXllcihcbiAgICAgICAge1xuICAgICAgICAgIGdldFBvc2l0aW9uOiBkYXRhLmdldFBvc2l0aW9uLFxuICAgICAgICAgIHNoYXJlZFByb3BzLFxuICAgICAgICAgIGdldFBpeGVsT2Zmc2V0LFxuICAgICAgICAgIHVwZGF0ZVRyaWdnZXJzXG4gICAgICAgIH0sXG4gICAgICAgIG9wdHNcbiAgICAgIClcbiAgICBdO1xuICAgIGNvbnN0IGhvdmVyZWRPYmplY3QgPSB0aGlzLmhhc0hvdmVyZWRPYmplY3Qob2JqZWN0SG92ZXJlZCk7XG5cbiAgICBjb25zdCBwYXJhbWV0ZXJzID0ge1xuICAgICAgLy8gaWNvbnMgd2lsbCBiZSBmbGF0IG9uIHRoZSBtYXAgd2hlbiB0aGUgYWx0aXR1ZGUgY29sdW1uIGlzIG5vdCB1c2VkXG4gICAgICBkZXB0aFRlc3Q6IHRoaXMuY29uZmlnLmNvbHVtbnMuYWx0aXR1ZGU/LmZpZWxkSWR4ID4gLTEsXG4gICAgICBjdWxsRmFjZTogR0wuRlJPTlRcbiAgICB9O1xuXG4gICAgcmV0dXJuICF0aGlzLmljb25HZW9tZXRyeVxuICAgICAgPyBbXVxuICAgICAgOiBbXG4gICAgICAgICAgbmV3IFN2Z0ljb25MYXllcih7XG4gICAgICAgICAgICAuLi5kZWZhdWx0TGF5ZXJQcm9wcyxcbiAgICAgICAgICAgIC4uLmJydXNoaW5nUHJvcHMsXG4gICAgICAgICAgICAuLi5sYXllclByb3BzLFxuICAgICAgICAgICAgLi4uZGF0YSxcbiAgICAgICAgICAgIHBhcmFtZXRlcnMsXG4gICAgICAgICAgICBnZXRJY29uR2VvbWV0cnk6IGlkID0+IHRoaXMuaWNvbkdlb21ldHJ5Py5baWRdLFxuXG4gICAgICAgICAgICAvLyB1cGRhdGUgdHJpZ2dlcnNcbiAgICAgICAgICAgIHVwZGF0ZVRyaWdnZXJzLFxuICAgICAgICAgICAgZXh0ZW5zaW9uc1xuICAgICAgICAgIH0pLFxuXG4gICAgICAgICAgLy8gaG92ZXIgbGF5ZXJcbiAgICAgICAgICAuLi4oaG92ZXJlZE9iamVjdFxuICAgICAgICAgICAgPyBbXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBTdmdJY29uTGF5ZXJQcm9wcyBuZWVkcyBnZXRJY29uIEZpZWxkXG4gICAgICAgICAgICAgICAgbmV3IFN2Z0ljb25MYXllcih7XG4gICAgICAgICAgICAgICAgICAuLi50aGlzLmdldERlZmF1bHRIb3ZlckxheWVyUHJvcHMoKSxcbiAgICAgICAgICAgICAgICAgIC4uLmxheWVyUHJvcHMsXG4gICAgICAgICAgICAgICAgICB2aXNpYmxlOiBkZWZhdWx0TGF5ZXJQcm9wcy52aXNpYmxlLFxuICAgICAgICAgICAgICAgICAgZGF0YTogW2hvdmVyZWRPYmplY3RdLFxuICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycyxcbiAgICAgICAgICAgICAgICAgIGdldFBvc2l0aW9uOiBkYXRhLmdldFBvc2l0aW9uLFxuICAgICAgICAgICAgICAgICAgZ2V0UmFkaXVzOiBkYXRhLmdldFJhZGl1cyxcbiAgICAgICAgICAgICAgICAgIGdldEZpbGxDb2xvcjogdGhpcy5jb25maWcuaGlnaGxpZ2h0Q29sb3IsXG4gICAgICAgICAgICAgICAgICBnZXRJY29uR2VvbWV0cnk6IGlkID0+IHRoaXMuaWNvbkdlb21ldHJ5Py5baWRdXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgOiBbXSksXG5cbiAgICAgICAgICAvLyB0ZXh0IGxhYmVsIGxheWVyXG4gICAgICAgICAgLi4ubGFiZWxMYXllcnNcbiAgICAgICAgXTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJ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