UNPKG

kepler.gl.geoiq

Version:

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

262 lines (216 loc) 29.9 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"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _lodash = _interopRequireDefault(require("lodash.uniq")); var _styledComponents = _interopRequireDefault(require("styled-components")); var _itemSelector = _interopRequireDefault(require("../../common/item-selector/item-selector")); var _styledComponents2 = require("../../common/styled-components"); var _rangeSlider = _interopRequireDefault(require("../../common/range-slider")); var _switch = _interopRequireDefault(require("../../common/switch")); var _colorPalette = _interopRequireDefault(require("./color-palette")); var _colorRanges = require("../../../constants/color-ranges"); var _dataUtils = require("../../../utils/data-utils"); var _templateObject, _templateObject2, _templateObject3, _templateObject4; function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } 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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var ALL_TYPES = (0, _lodash["default"])(_colorRanges.COLOR_RANGES.map(function (c) { return c.type; }).concat(['all'])); var ALL_STEPS = (0, _lodash["default"])(_colorRanges.COLOR_RANGES.map(function (d) { return d.colors.length; })).sort(_dataUtils.numberSort); var StyledColorConfig = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n padding: 12px 12px 0 12px;\n"]))); var ColorRangeSelector = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n padding-bottom: 12px;\n"]))); var ColorRangeSelect = exports["default"] = /*#__PURE__*/function (_Component) { (0, _inherits2["default"])(ColorRangeSelect, _Component); var _super = _createSuper(ColorRangeSelect); function ColorRangeSelect() { var _this; (0, _classCallCheck2["default"])(this, ColorRangeSelect); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { config: { type: { type: 'select', value: 'all', options: ALL_TYPES }, steps: { type: 'select', value: 6, options: ALL_STEPS }, reversed: { type: 'switch', value: false, options: [true, false] } } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_updateConfig", function (_ref) { var key = _ref.key, value = _ref.value; var currentValue = _this.state.config[key].value; if (value !== currentValue) { _this.setState({ config: _objectSpread(_objectSpread({}, _this.state.config), {}, (0, _defineProperty2["default"])({}, key, _objectSpread(_objectSpread({}, _this.state.config[key]), {}, { value: value }))) }); } }); return _this; } (0, _createClass2["default"])(ColorRangeSelect, [{ key: "render", value: function render() { var _this2 = this; var config = this.state.config; return (/*#__PURE__*/_react["default"].createElement(ColorRangeSelector, { className: "color-range-selector" }, /*#__PURE__*/_react["default"].createElement(StyledColorConfig, null, Object.keys(config).map(function (key) { return (/*#__PURE__*/_react["default"].createElement(PaletteConfig, { key: key, label: key, config: config[key], onChange: function onChange(value) { return _this2._updateConfig({ key: key, value: value }); } }) ); })), /*#__PURE__*/_react["default"].createElement(ColorPaletteGroup, { config: config, colorRanges: this.props.colorRanges, onSelect: this.props.onSelectColorRange, selected: this.props.selectedColorRange })) ); } }]); return ColorRangeSelect; }(_react.Component); (0, _defineProperty2["default"])(ColorRangeSelect, "propTypes", { colorRanges: _propTypes["default"].arrayOf(_propTypes["default"].any), selectedColorRange: _propTypes["default"].object, onSelectColorRange: _propTypes["default"].func.isRequired }); (0, _defineProperty2["default"])(ColorRangeSelect, "defaultProps", { colorRanges: _colorRanges.COLOR_RANGES, onSelectColorRange: function onSelectColorRange() {} }); var StyledPaletteConfig = _styledComponents["default"].div(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n margin-bottom: 8px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n .color-palette__config__label {\n flex-grow: 1;\n }\n .color-palette__config__select {\n flex-grow: 1;\n }\n .item-selector .item-selector__dropdown {\n ", ";\n }\n"])), function (props) { return props.theme.secondaryInput; }); var PaletteConfig = function PaletteConfig(_ref2) { var category = _ref2.category, label = _ref2.label, _ref2$config = _ref2.config, type = _ref2$config.type, value = _ref2$config.value, options = _ref2$config.options, _onChange = _ref2.onChange; return (/*#__PURE__*/_react["default"].createElement(StyledPaletteConfig, { className: "color-palette__config", onClick: function onClick(e) { return e.stopPropagation(); } }, /*#__PURE__*/_react["default"].createElement("div", { className: "color-palette__config__label" }, /*#__PURE__*/_react["default"].createElement(_styledComponents2.PanelLabel, null, label)), type === 'select' && /*#__PURE__*/_react["default"].createElement("div", { className: "color-palette__config__select" }, /*#__PURE__*/_react["default"].createElement(_itemSelector["default"], { selectedItems: value, options: options, multiSelect: false, searchable: false, onChange: _onChange })), type === 'slider' && /*#__PURE__*/_react["default"].createElement("div", { className: "color-palette__config__slider" }, /*#__PURE__*/_react["default"].createElement("div", { className: "color-palette__config__slider__slider" }, /*#__PURE__*/_react["default"].createElement(_rangeSlider["default"], { range: options, value0: options[0], value1: value, step: 1, isRanged: false, showInput: false, onChange: function onChange(val) { return _onChange(val[1]); } })), /*#__PURE__*/_react["default"].createElement("div", { className: "color-palette__config__slider__number" }, value)), type === 'switch' && /*#__PURE__*/_react["default"].createElement(_switch["default"], { checked: value, id: "".concat(category, "-").concat(label, "-toggle"), onChange: function onChange() { return _onChange(!value); }, secondary: true })) ); }; var StyledColorRange = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 0 8px;\n :hover {\n background-color: ", ";\n cursor: pointer;\n }\n"])), function (props) { return props.theme.panelBackgroundHover; }); var ColorPaletteGroup = function ColorPaletteGroup(_ref3) { var _ref3$config = _ref3.config, config = _ref3$config === void 0 ? {} : _ref3$config, onSelect = _ref3.onSelect, selected = _ref3.selected, colorRanges = _ref3.colorRanges; var steps = config.steps, reversed = config.reversed, type = config.type; var filtered = colorRanges.filter(function (colorRange) { var isType = !type || type.value === 'all' || type.value === colorRange.type; var isStep = !steps || Number(steps.value) === colorRange.colors.length; return isType && isStep; }); var isReversed = Boolean(reversed && reversed.value); return (/*#__PURE__*/_react["default"].createElement("div", { className: "color-palette__group" }, filtered.map(function (colorRange) { return (/*#__PURE__*/_react["default"].createElement(StyledColorRange, { className: "color-ranges", key: colorRange.name, onClick: function onClick(e) { return onSelect(_objectSpread(_objectSpread({}, colorRange), {}, { reversed: isReversed, colors: isReversed ? colorRange.colors.slice().reverse() : colorRange.colors }), e); } }, /*#__PURE__*/_react["default"].createElement(_colorPalette["default"], { colors: colorRange.colors, isReversed: isReversed, isSelected: colorRange.name === selected.name && isReversed === Boolean(selected.reversed) })) ); })) ); }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3NpZGUtcGFuZWwvd2lkZ2V0LXBhbmVsL2NvbG9yLXJhbmdlLXNlbGVjdG9yLmpzIl0sIm5hbWVzIjpbIkFMTF9UWVBFUyIsIkNPTE9SX1JBTkdFUyIsIm1hcCIsImMiLCJ0eXBlIiwiY29uY2F0IiwiQUxMX1NURVBTIiwiZCIsImNvbG9ycyIsImxlbmd0aCIsInNvcnQiLCJudW1iZXJTb3J0IiwiU3R5bGVkQ29sb3JDb25maWciLCJzdHlsZWQiLCJkaXYiLCJDb2xvclJhbmdlU2VsZWN0b3IiLCJDb2xvclJhbmdlU2VsZWN0IiwiY29uZmlnIiwidmFsdWUiLCJvcHRpb25zIiwic3RlcHMiLCJyZXZlcnNlZCIsImtleSIsImN1cnJlbnRWYWx1ZSIsInN0YXRlIiwic2V0U3RhdGUiLCJPYmplY3QiLCJrZXlzIiwiX3VwZGF0ZUNvbmZpZyIsInByb3BzIiwiY29sb3JSYW5nZXMiLCJvblNlbGVjdENvbG9yUmFuZ2UiLCJzZWxlY3RlZENvbG9yUmFuZ2UiLCJDb21wb25lbnQiLCJQcm9wVHlwZXMiLCJhcnJheU9mIiwiYW55Iiwib2JqZWN0IiwiZnVuYyIsImlzUmVxdWlyZWQiLCJTdHlsZWRQYWxldHRlQ29uZmlnIiwidGhlbWUiLCJzZWNvbmRhcnlJbnB1dCIsIlBhbGV0dGVDb25maWciLCJjYXRlZ29yeSIsImxhYmVsIiwib25DaGFuZ2UiLCJlIiwic3RvcFByb3BhZ2F0aW9uIiwidmFsIiwiU3R5bGVkQ29sb3JSYW5nZSIsInBhbmVsQmFja2dyb3VuZEhvdmVyIiwiQ29sb3JQYWxldHRlR3JvdXAiLCJvblNlbGVjdCIsInNlbGVjdGVkIiwiZmlsdGVyZWQiLCJmaWx0ZXIiLCJjb2xvclJhbmdlIiwiaXNUeXBlIiwiaXNTdGVwIiwiTnVtYmVyIiwiaXNSZXZlcnNlZCIsIkJvb2xlYW4iLCJuYW1lIiwic2xpY2UiLCJyZXZlcnNlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFv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QUFDRSxVQUFBLFNBQVMsRUFBQyxjQURaO0FBRUUsVUFBQSxHQUFHLEVBQUVBLFVBQVUsQ0FBQ00sSUFGbEI7QUFHRSxVQUFBLE9BQU8sRUFBRSxpQkFBQWhCLENBQUM7QUFBQSxtQkFDUk0sUUFBUSxpQ0FFREksVUFGQztBQUdKcEMsY0FBQUEsUUFBUSxFQUFFd0MsVUFITjtBQUlKckQsY0FBQUEsTUFBTSxFQUFFcUQsVUFBVSxHQUNkSixVQUFVLENBQUNqRCxNQUFYLENBQWtCd0QsS0FBbEIsR0FBMEJDLE9BQTFCLEVBRGMsR0FFZFIsVUFBVSxDQUFDakQ7QUFOWCxnQkFRTnVDLENBUk0sQ0FEQTtBQUFBO0FBSFosd0JBZ0JFLGdDQUFDLHdCQUFEO0FBQ0UsVUFBQSxNQUFNLEVBQUVVLFVBQVUsQ0FBQ2pELE1BRHJCO0FBRUUsVUFBQSxVQUFVLEVBQUVxRCxVQUZkO0FBR0UsVUFBQSxVQUFVLEVBQ1JKLFVBQVUsQ0FBQ00sSUFBWCxLQUFvQlQsUUFBUSxDQUFDUyxJQUE3QixJQUNBRixVQUFVLEtBQUtDLE9BQU8sQ0FBQ1IsUUFBUSxDQUFDakMsUUFBVjtBQUwxQixVQWhCRjtBQURzQjtBQUFBLEtBQXZCLENBREg7QUFERjtBQStCRCxDQTVDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBSZWFjdCwge0NvbXBvbmVudH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCB1bmlxIGZyb20gJ2xvZGFzaC51bmlxJztcbmltcG9ydCBzdHlsZWQgZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IEl0ZW1TZWxlY3RvciBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9pdGVtLXNlbGVjdG9yL2l0ZW0tc2VsZWN0b3InO1xuaW1wb3J0IHtQYW5lbExhYmVsfSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9zdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQgUmFuZ2VTbGlkZXIgZnJvbSAnY29tcG9uZW50cy9jb21tb24vcmFuZ2Utc2xpZGVyJztcbmltcG9ydCBTd2l0Y2ggZnJvbSAnY29tcG9uZW50cy9jb21tb24vc3dpdGNoJztcbmltcG9ydCBDb2xvclBhbGV0dGUgZnJvbSAnLi9jb2xvci1wYWxldHRlJztcblxuaW1wb3J0IHtDT0xPUl9SQU5HRVN9IGZyb20gJ2NvbnN0YW50cy9jb2xvci1yYW5nZXMnO1xuaW1wb3J0IHtudW1iZXJTb3J0fSBmcm9tICd1dGlscy9kYXRhLXV0aWxzJztcblxuY29uc3QgQUxMX1RZUEVTID0gdW5pcShDT0xPUl9SQU5HRVMubWFwKGMgPT4gYy50eXBlKS5jb25jYXQoWydhbGwnXSkpO1xuY29uc3QgQUxMX1NURVBTID0gdW5pcShDT0xPUl9SQU5HRVMubWFwKGQgPT4gZC5jb2xvcnMubGVuZ3RoKSkuc29ydChudW1iZXJTb3J0KTtcblxuY29uc3QgU3R5bGVkQ29sb3JDb25maWcgPSBzdHlsZWQuZGl2YFxuICBwYWRkaW5nOiAxMnB4IDEycHggMCAxMnB4O1xuYDtcblxuY29uc3QgQ29sb3JSYW5nZVNlbGVjdG9yID0gc3R5bGVkLmRpdmBcbiAgcGFkZGluZy1ib3R0b206IDEycHg7XG5gO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29sb3JSYW5nZVNlbGVjdCBleHRlbmRzIENvbXBvbmVudCB7XG4gIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgY29sb3JSYW5nZXM6IFByb3BUeXBlcy5hcnJheU9mKFByb3BUeXBlcy5hbnkpLFxuICAgIHNlbGVjdGVkQ29sb3JSYW5nZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICBvblNlbGVjdENvbG9yUmFuZ2U6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWRcbiAgfTtcblxuICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgIGNvbG9yUmFuZ2VzOiBDT0xPUl9SQU5HRVMsXG4gICAgb25TZWxlY3RDb2xvclJhbmdlOiAoKSA9PiB7fVxuICB9O1xuXG4gIHN0YXRlID0ge1xuICAgIGNvbmZpZzoge1xuICAgICAgdHlwZToge1xuICAgICAgICB0eXBlOiAnc2VsZWN0JyxcbiAgICAgICAgdmFsdWU6ICdhbGwnLFxuICAgICAgICBvcHRpb25zOiBBTExfVFlQRVNcbiAgICAgIH0sXG4gICAgICBzdGVwczoge1xuICAgICAgICB0eXBlOiAnc2VsZWN0JyxcbiAgICAgICAgdmFsdWU6IDYsXG4gICAgICAgIG9wdGlvbnM6IEFMTF9TVEVQU1xuICAgICAgfSxcbiAgICAgIHJldmVyc2VkOiB7XG4gICAgICAgIHR5cGU6ICdzd2l0Y2gnLFxuICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgIG9wdGlvbnM6IFt0cnVlLCBmYWxzZV1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgX3VwZGF0ZUNvbmZpZyA9ICh7a2V5LCB2YWx1ZX0pID0+IHtcbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLnN0YXRlLmNvbmZpZ1trZXldLnZhbHVlO1xuICAgIGlmICh2YWx1ZSAhPT0gY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgLi4udGhpcy5zdGF0ZS5jb25maWcsXG4gICAgICAgICAgW2tleV06IHtcbiAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuY29uZmlnW2tleV0sXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHJlbmRlcigpIHtcbiAgICBjb25zdCB7Y29uZmlnfSA9IHRoaXMuc3RhdGU7XG4gICAgcmV0dXJuIChcbiAgICAgIDxDb2xvclJhbmdlU2VsZWN0b3IgY2xhc3NOYW1lPVwiY29sb3ItcmFuZ2Utc2VsZWN0b3JcIj5cbiAgICAgICAgPFN0eWxlZENvbG9yQ29uZmlnPlxuICAgICAgICAgIHtPYmplY3Qua2V5cyhjb25maWcpLm1hcChrZXkgPT4gKFxuICAgICAgICAgICAgPFBhbGV0dGVDb25maWdcbiAgICAgICAgICAgICAga2V5PXtrZXl9XG4gICAgICAgICAgICAgIGxhYmVsPXtrZXl9XG4gICAgICAgICAgICAgIGNvbmZpZz17Y29uZmlnW2tleV19XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXt2YWx1ZSA9PiB0aGlzLl91cGRhdGVDb25maWcoe2tleSwgdmFsdWV9KX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSl9XG4gICAgICAgIDwvU3R5bGVkQ29sb3JDb25maWc+XG4gICAgICAgIDxDb2xvclBhbGV0dGVHcm91cFxuICAgICAgICAgIGNvbmZpZz17Y29uZmlnfVxuICAgICAgICAgIGNvbG9yUmFuZ2VzPXt0aGlzLnByb3BzLmNvbG9yUmFuZ2VzfVxuICAgICAgICAgIG9uU2VsZWN0PXt0aGlzLnByb3BzLm9uU2VsZWN0Q29sb3JSYW5nZX1cbiAgICAgICAgICBzZWxlY3RlZD17dGhpcy5wcm9wcy5zZWxlY3RlZENvbG9yUmFuZ2V9XG4gICAgICAgIC8+XG4gICAgICA8L0NvbG9yUmFuZ2VTZWxlY3Rvcj5cbiAgICApO1xuICB9XG59XG5cbmNvbnN0IFN0eWxlZFBhbGV0dGVDb25maWcgPSBzdHlsZWQuZGl2YFxuICBtYXJnaW4tYm90dG9tOiA4cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgLmNvbG9yLXBhbGV0dGVfX2NvbmZpZ19fbGFiZWwge1xuICAgIGZsZXgtZ3JvdzogMTtcbiAgfVxuICAuY29sb3ItcGFsZXR0ZV9fY29uZmlnX19zZWxlY3Qge1xuICAgIGZsZXgtZ3JvdzogMTtcbiAgfVxuICAuaXRlbS1zZWxlY3RvciAuaXRlbS1zZWxlY3Rvcl9fZHJvcGRvd24ge1xuICAgICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuc2Vjb25kYXJ5SW5wdXR9O1xuICB9XG5gO1xuXG5jb25zdCBQYWxldHRlQ29uZmlnID0gKHtcbiAgY2F0ZWdvcnksXG4gIGxhYmVsLFxuICBjb25maWc6IHt0eXBlLCB2YWx1ZSwgb3B0aW9uc30sXG4gIG9uQ2hhbmdlXG59KSA9PiAoXG4gIDxTdHlsZWRQYWxldHRlQ29uZmlnXG4gICAgY2xhc3NOYW1lPVwiY29sb3ItcGFsZXR0ZV9fY29uZmlnXCJcbiAgICBvbkNsaWNrPXtlID0+IGUuc3RvcFByb3BhZ2F0aW9uKCl9XG4gID5cbiAgICA8ZGl2IGNsYXNzTmFtZT1cImNvbG9yLXBhbGV0dGVfX2NvbmZpZ19fbGFiZWxcIj5cbiAgICAgIDxQYW5lbExhYmVsPntsYWJlbH08L1BhbmVsTGFiZWw+XG4gICAgPC9kaXY+XG4gICAge3R5cGUgPT09ICdzZWxlY3QnICYmIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY29sb3ItcGFsZXR0ZV9fY29uZmlnX19zZWxlY3RcIj5cbiAgICAgICAgPEl0ZW1TZWxlY3RvclxuICAgICAgICAgIHNlbGVjdGVkSXRlbXM9e3ZhbHVlfVxuICAgICAgICAgIG9wdGlvbnM9e29wdGlvbnN9XG4gICAgICAgICAgbXVsdGlTZWxlY3Q9e2ZhbHNlfVxuICAgICAgICAgIHNlYXJjaGFibGU9e2ZhbHNlfVxuICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgLz5cbiAgICAgIDwvZGl2PlxuICAgICl9XG4gICAge3R5cGUgPT09ICdzbGlkZXInICYmIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY29sb3ItcGFsZXR0ZV9fY29uZmlnX19zbGlkZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJjb2xvci1wYWxldHRlX19jb25maWdfX3NsaWRlcl9fc2xpZGVyXCI+XG4gICAgICAgICAgPFJhbmdlU2xpZGVyXG4gICAgICAgICAgICByYW5nZT17b3B0aW9uc31cbiAgICAgICAgICAgIHZhbHVlMD17b3B0aW9uc1swXX1cbiAgICAgICAgICAgIHZhbHVlMT17dmFsdWV9XG4gICAgICAgICAgICBzdGVwPXsxfVxuICAgICAgICAgICAgaXNSYW5nZWQ9e2ZhbHNlfVxuICAgICAgICAgICAgc2hvd0lucHV0PXtmYWxzZX1cbiAgICAgICAgICAgIG9uQ2hhbmdlPXt2YWwgPT4gb25DaGFuZ2UodmFsWzFdKX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJjb2xvci1wYWxldHRlX19jb25maWdfX3NsaWRlcl9fbnVtYmVyXCI+e3ZhbHVlfTwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgKX1cbiAgICB7dHlwZSA9PT0gJ3N3aXRjaCcgJiYgKFxuICAgICAgPFN3aXRjaFxuICAgICAgICBjaGVja2VkPXt2YWx1ZX1cbiAgICAgICAgaWQ9e2Ake2NhdGVnb3J5fS0ke2xhYmVsfS10b2dnbGVgfVxuICAgICAgICBvbkNoYW5nZT17KCkgPT4gb25DaGFuZ2UoIXZhbHVlKX1cbiAgICAgICAgc2Vjb25kYXJ5XG4gICAgICAvPlxuICAgICl9XG4gIDwvU3R5bGVkUGFsZXR0ZUNvbmZpZz5cbik7XG5cbmNvbnN0IFN0eWxlZENvbG9yUmFuZ2UgPSBzdHlsZWQuZGl2YFxuICBwYWRkaW5nOiAwIDhweDtcbiAgOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLnBhbmVsQmFja2dyb3VuZEhvdmVyfTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cbmA7XG5cbmNvbnN0IENvbG9yUGFsZXR0ZUdyb3VwID0gKHtjb25maWcgPSB7fSwgb25TZWxlY3QsIHNlbGVjdGVkLCBjb2xvclJhbmdlc30pID0+IHtcbiAgY29uc3Qge3N0ZXBzLCByZXZlcnNlZCwgdHlwZX0gPSBjb25maWc7XG5cbiAgY29uc3QgZmlsdGVyZWQgPSBjb2xvclJhbmdlcy5maWx0ZXIoY29sb3JSYW5nZSA9PiB7XG4gICAgY29uc3QgaXNUeXBlID1cbiAgICAgICF0eXBlIHx8IHR5cGUudmFsdWUgPT09ICdhbGwnIHx8IHR5cGUudmFsdWUgPT09IGNvbG9yUmFuZ2UudHlwZTtcbiAgICBjb25zdCBpc1N0ZXAgPSAhc3RlcHMgfHwgTnVtYmVyKHN0ZXBzLnZhbHVlKSA9PT0gY29sb3JSYW5nZS5jb2xvcnMubGVuZ3RoO1xuXG4gICAgcmV0dXJuIGlzVHlwZSAmJiBpc1N0ZXA7XG4gIH0pO1xuXG4gIGNvbnN0IGlzUmV2ZXJzZWQgPSBCb29sZWFuKHJldmVyc2VkICYmIHJldmVyc2VkLnZhbHVlKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwiY29sb3ItcGFsZXR0ZV9fZ3JvdXBcIj5cbiAgICAgIHtmaWx0ZXJlZC5tYXAoY29sb3JSYW5nZSA9PiAoXG4gICAgICAgIDxTdHlsZWRDb2xvclJhbmdlXG4gICAgICAgICAgY2xhc3NOYW1lPVwiY29sb3ItcmFuZ2VzXCJcbiAgICAgICAgICBrZXk9e2NvbG9yUmFuZ2UubmFtZX1cbiAgICAgICAgICBvbkNsaWNrPXtlID0+XG4gICAgICAgICAgICBvblNlbGVjdChcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLmNvbG9yUmFuZ2UsXG4gICAgICAgICAgICAgICAgcmV2ZXJzZWQ6IGlzUmV2ZXJzZWQsXG4gICAgICAgICAgICAgICAgY29sb3JzOiBpc1JldmVyc2VkXG4gICAgICAgICAgICAgICAgICA/IGNvbG9yUmFuZ2UuY29sb3JzLnNsaWNlKCkucmV2ZXJzZSgpXG4gICAgICAgICAgICAgICAgICA6IGNvbG9yUmFuZ2UuY29sb3JzXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGVcbiAgICAgICAgICAgIClcbiAgICAgICAgICB9XG4gICAgICAgID5cbiAgICAgICAgICA8Q29sb3JQYWxldHRlXG4gICAgICAgICAgICBjb2xvcnM9e2NvbG9yUmFuZ2UuY29sb3JzfVxuICAgICAgICAgICAgaXNSZXZlcnNlZD17aXNSZXZlcnNlZH1cbiAgICAgICAgICAgIGlzU2VsZWN0ZWQ9e1xuICAgICAgICAgICAgICBjb2xvclJhbmdlLm5hbWUgPT09IHNlbGVjdGVkLm5hbWUgJiZcbiAgICAgICAgICAgICAgaXNSZXZlcnNlZCA9PT0gQm9vbGVhbihzZWxlY3RlZC5yZXZlcnNlZClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1N0eWxlZENvbG9yUmFuZ2U+XG4gICAgICApKX1cbiAgICA8L2Rpdj5cbiAgKTtcbn07XG4iXX0=