kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
178 lines (172 loc) • 38.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = BottomWidgetFactory;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireWildcard(require("styled-components"));
var _constants = require("@kepler.gl/constants");
var _utils = require("@kepler.gl/utils");
var _styles = require("@kepler.gl/styles");
var _timeWidget = _interopRequireDefault(require("./filters/time-widget"));
var _filterAnimationController = _interopRequireDefault(require("./filter-animation-controller"));
var _layerAnimationController = _interopRequireDefault(require("./layer-animation-controller"));
var _animationControl = _interopRequireDefault(require("./common/animation-control/animation-control"));
var _templateObject, _templateObject2, _templateObject3; // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
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; }
var maxWidth = 1080;
var BottomWidgetContainer = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n flex-direction: column;\n padding-top: ", "px;\n padding-right: ", "px;\n padding-bottom: ", "px;\n padding-left: ", "px;\n pointer-events: none !important; /* prevent padding from blocking input */\n & > * {\n /* all children should allow input */\n pointer-events: all;\n }\n width: ", "px;\n z-index: 1;\n ", "\n"])), function (props) {
return props.hasPadding ? props.theme.bottomWidgetPaddingTop : 0;
}, function (props) {
return props.hasPadding ? props.theme.bottomWidgetPaddingRight : 0;
}, function (props) {
return props.hasPadding ? props.theme.bottomWidgetPaddingBottom : 0;
}, function (props) {
return props.hasPadding ? props.theme.bottomWidgetPaddingLeft : 0;
}, function (props) {
return props.width;
}, _styles.media.portable(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["padding: 0;"]))));
BottomWidgetFactory.deps = [_timeWidget["default"], _animationControl["default"], _filterAnimationController["default"], _layerAnimationController["default"]];
/* eslint-disable complexity */
function BottomWidgetFactory(TimeWidget, AnimationControl, FilterAnimationController, LayerAnimationController) {
var LayerAnimationControl = (0, _styledComponents["default"])(AnimationControl)(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n background-color: ", ";\n "])), function (props) {
return props.theme.sidePanelBg;
});
var BottomWidget = function BottomWidget(props) {
var _uiState$mapControls, _uiState$mapControls2, _theme$mapControl, _theme$mapControl2;
var datasets = props.datasets,
filters = props.filters,
animationConfig = props.animationConfig,
visStateActions = props.visStateActions,
containerW = props.containerW,
uiState = props.uiState,
sidePanelWidth = props.sidePanelWidth,
layers = props.layers,
rootRef = props.rootRef,
theme = props.theme;
var activeSidePanel = uiState.activeSidePanel,
readOnly = uiState.readOnly;
var isOpen = Boolean(activeSidePanel);
var enlargedFilterIdx = (0, _react.useMemo)(function () {
return filters.findIndex(function (f) {
return !(0, _utils.isSideFilter)(f);
});
}, [filters]);
var animatedFilterIdx = (0, _react.useMemo)(function () {
return filters.findIndex(function (f) {
return f.isAnimating;
});
}, [filters]);
var animatedFilter = animatedFilterIdx > -1 ? filters[animatedFilterIdx] : null;
// we need to hide layer timeline when filter is synced and not enlarged
var isTimelineLinkedWithFilter = (0, _react.useMemo)(function () {
return filters.some(function (f) {
return f.syncedWithLayerTimeline;
});
}, [filters]);
var isMobile = (0, _react.useMemo)(function () {
return (0, _utils.hasPortableWidth)(_styles.breakPointValues);
}, []);
var isLegendPinned = ((_uiState$mapControls = uiState.mapControls) === null || _uiState$mapControls === void 0 || (_uiState$mapControls = _uiState$mapControls.mapLegend) === null || _uiState$mapControls === void 0 ? void 0 : _uiState$mapControls.show) && ((_uiState$mapControls2 = uiState.mapControls) === null || _uiState$mapControls2 === void 0 || (_uiState$mapControls2 = _uiState$mapControls2.mapLegend) === null || _uiState$mapControls2 === void 0 ? void 0 : _uiState$mapControls2.active);
var spaceForLegendWidth = isLegendPinned ? ((_theme$mapControl = theme.mapControl) === null || _theme$mapControl === void 0 ? void 0 : _theme$mapControl.width) + ((_theme$mapControl2 = theme.mapControl) === null || _theme$mapControl2 === void 0 || (_theme$mapControl2 = _theme$mapControl2.mapLegend) === null || _theme$mapControl2 === void 0 || (_theme$mapControl2 = _theme$mapControl2.pinned) === null || _theme$mapControl2 === void 0 ? void 0 : _theme$mapControl2.right) * 2 - theme.bottomWidgetPaddingRight : 0;
var enlargedFilterWidth = (0, _react.useMemo)(function () {
return (!isMobile && isOpen ? containerW - sidePanelWidth : containerW) - spaceForLegendWidth;
}, [isMobile, isOpen, containerW, sidePanelWidth, spaceForLegendWidth]);
// show playback control if layers contain trip layer & at least one trip layer is visible
var animatableLayer = (0, _react.useMemo)(function () {
return layers.filter(function (l) {
return l.config.animation && l.config.animation.enabled && l.config.isVisible;
});
}, [layers]);
var readyToAnimation = (0, _react.useMemo)(function () {
return Array.isArray(animationConfig.domain) && Number.isFinite(animationConfig.currentTime);
}, [animationConfig.domain, animationConfig.currentTime]);
// if animation control is showing, hide time display in time slider
var showFloatingTimeDisplay = !animatableLayer.length;
var showAnimationControl = animatableLayer.length && readyToAnimation && !animationConfig.hideControl;
var showTimeWidget = enlargedFilterIdx > -1 && Object.keys(datasets).length > 0;
// if filter is not animating, pass in enlarged filter here because
// animation controller needs to call reset on it
var filter = (0, _react.useMemo)(function () {
return animatedFilter || filters[enlargedFilterIdx];
}, [animatedFilter, filters, enlargedFilterIdx]);
// we merge filter and timeline if filter is synced
var _useMemo = (0, _react.useMemo)(function () {
return filter !== null && filter !== void 0 && filter.syncedWithLayerTimeline ? (0, _utils.mergeFilterWithTimeline)(filter, animationConfig) : {
filter: filter,
animationConfig: animationConfig
};
}, [filter, animationConfig]),
enhancedFilter = _useMemo.filter,
enhancedAnimationConfig = _useMemo.animationConfig;
var onClose = (0, _react.useCallback)(function () {
return visStateActions.setFilterView(enlargedFilterIdx, _constants.FILTER_VIEW_TYPES.side);
}, [visStateActions, enlargedFilterIdx]);
var onToggleMinify = (0, _react.useCallback)(function () {
return visStateActions.setFilterView(enlargedFilterIdx, filter.view === _constants.FILTER_VIEW_TYPES.enlarged ? _constants.FILTER_VIEW_TYPES.minified : _constants.FILTER_VIEW_TYPES.enlarged);
}, [enlargedFilterIdx, visStateActions, filter]);
return /*#__PURE__*/_react["default"].createElement(BottomWidgetContainer, {
width: Math.min(maxWidth, enlargedFilterWidth),
style: {
marginRight: spaceForLegendWidth
},
className: "bottom-widget--container",
hasPadding: showAnimationControl || showTimeWidget,
ref: rootRef
}, !isTimelineLinkedWithFilter ? /*#__PURE__*/_react["default"].createElement(LayerAnimationController, {
animationConfig: enhancedAnimationConfig,
setLayerAnimationTime: visStateActions.setLayerAnimationTime
}, function (isAnimating, start, pause, resetAnimation, timeline, setTimelineValue) {
return showAnimationControl ? /*#__PURE__*/_react["default"].createElement(LayerAnimationControl, {
updateAnimationSpeed: visStateActions.updateLayerAnimationSpeed,
toggleAnimation: visStateActions.toggleLayerAnimation,
isAnimatable: !animatedFilter,
isAnimating: isAnimating,
resetAnimation: resetAnimation,
setTimelineValue: setTimelineValue,
timeline: timeline
}) : null;
}) : null, enhancedFilter ? /*#__PURE__*/_react["default"].createElement(FilterAnimationController, {
filter: enhancedFilter,
filterIdx: animatedFilterIdx > -1 ? animatedFilterIdx : enlargedFilterIdx,
setFilterAnimationTime: visStateActions.setFilterAnimationTime
}, function (isAnimating, start, pause, resetAnimation, timeline, setTimelineValue) {
return showTimeWidget && timeline ? /*#__PURE__*/_react["default"].createElement(TimeWidget
// TimeWidget uses React.memo, here we pass width
// even though it doesnt use it, to force rerender
, {
filter: enhancedFilter,
index: enlargedFilterIdx,
datasets: datasets,
layers: layers,
readOnly: readOnly,
showTimeDisplay: showFloatingTimeDisplay,
setFilterPlot: visStateActions.setFilterPlot,
setFilterAnimationTime: setTimelineValue,
setFilterAnimationWindow: visStateActions.setFilterAnimationWindow,
setFilterSyncTimelineMode: visStateActions.setTimeFilterSyncTimelineMode,
toggleAnimation: visStateActions.toggleFilterAnimation,
updateAnimationSpeed: visStateActions.updateFilterAnimationSpeed,
resetAnimation: resetAnimation,
isAnimatable: !animationConfig || !animationConfig.isAnimating,
animationConfig: animationConfig,
onClose: onClose,
timeline: timeline,
onToggleMinify: onToggleMinify
}) : null;
}) : null);
};
return (0, _styledComponents.withTheme)( /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
return /*#__PURE__*/_react["default"].createElement(BottomWidget, (0, _extends2["default"])({}, props, {
rootRef: ref
}));
}));
}
/* eslint-enable complexity */
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfc3R5bGVkQ29tcG9uZW50cyIsIl9jb25zdGFudHMiLCJfdXRpbHMiLCJfc3R5bGVzIiwiX3RpbWVXaWRnZXQiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2ZpbHRlckFuaW1hdGlvbkNvbnRyb2xsZXIiLCJfbGF5ZXJBbmltYXRpb25Db250cm9sbGVyIiwiX2FuaW1hdGlvbkNvbnRyb2wiLCJfdGVtcGxhdGVPYmplY3QiLCJfdGVtcGxhdGVPYmplY3QyIiwiX3RlbXBsYXRlT2JqZWN0MyIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiX3R5cGVvZiIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIm1heFdpZHRoIiwiQm90dG9tV2lkZ2V0Q29udGFpbmVyIiwic3R5bGVkIiwiZGl2IiwiX3RhZ2dlZFRlbXBsYXRlTGl0ZXJhbDIiLCJwcm9wcyIsImhhc1BhZGRpbmciLCJ0aGVtZSIsImJvdHRvbVdpZGdldFBhZGRpbmdUb3AiLCJib3R0b21XaWRnZXRQYWRkaW5nUmlnaHQiLCJib3R0b21XaWRnZXRQYWRkaW5nQm90dG9tIiwiYm90dG9tV2lkZ2V0UGFkZGluZ0xlZnQiLCJ3aWR0aCIsIm1lZGlhIiwicG9ydGFibGUiLCJCb3R0b21XaWRnZXRGYWN0b3J5IiwiZGVwcyIsIlRpbWVXaWRnZXRGYWN0b3J5IiwiQW5pbWF0aW9uQ29udHJvbEZhY3RvcnkiLCJGaWx0ZXJBbmltYXRpb25Db250cm9sbGVyRmFjdG9yeSIsIkxheWVyQW5pbWF0aW9uQ29udHJvbGxlckZhY3RvcnkiLCJUaW1lV2lkZ2V0IiwiQW5pbWF0aW9uQ29udHJvbCIsIkZpbHRlckFuaW1hdGlvbkNvbnRyb2xsZXIiLCJMYXllckFuaW1hdGlvbkNvbnRyb2xsZXIiLCJMYXllckFuaW1hdGlvbkNvbnRyb2wiLCJzaWRlUGFuZWxCZyIsIkJvdHRvbVdpZGdldCIsIl91aVN0YXRlJG1hcENvbnRyb2xzIiwiX3VpU3RhdGUkbWFwQ29udHJvbHMyIiwiX3RoZW1lJG1hcENvbnRyb2wiLCJfdGhlbWUkbWFwQ29udHJvbDIiLCJkYXRhc2V0cyIsImZpbHRlcnMiLCJhbmltYXRpb25Db25maWciLCJ2aXNTdGF0ZUFjdGlvbnMiLCJjb250YWluZXJXIiwidWlTdGF0ZSIsInNpZGVQYW5lbFdpZHRoIiwibGF5ZXJzIiwicm9vdFJlZiIsImFjdGl2ZVNpZGVQYW5lbCIsInJlYWRPbmx5IiwiaXNPcGVuIiwiQm9vbGVhbiIsImVubGFyZ2VkRmlsdGVySWR4IiwidXNlTWVtbyIsImZpbmRJbmRleCIsImYiLCJpc1NpZGVGaWx0ZXIiLCJhbmltYXRlZEZpbHRlcklkeCIsImlzQW5pbWF0aW5nIiwiYW5pbWF0ZWRGaWx0ZXIiLCJpc1RpbWVsaW5lTGlua2VkV2l0aEZpbHRlciIsInNvbWUiLCJzeW5jZWRXaXRoTGF5ZXJUaW1lbGluZSIsImlzTW9iaWxlIiwiaGFzUG9ydGFibGVXaWR0aCIsImJyZWFrUG9pbnRWYWx1ZXMiLCJpc0xlZ2VuZFBpbm5lZCIsIm1hcENvbnRyb2xzIiwibWFwTGVnZW5kIiwic2hvdyIsImFjdGl2ZSIsInNwYWNlRm9yTGVnZW5kV2lkdGgiLCJtYXBDb250cm9sIiwicGlubmVkIiwicmlnaHQiLCJlbmxhcmdlZEZpbHRlcldpZHRoIiwiYW5pbWF0YWJsZUxheWVyIiwiZmlsdGVyIiwibCIsImNvbmZpZyIsImFuaW1hdGlvbiIsImVuYWJsZWQiLCJpc1Zpc2libGUiLCJyZWFkeVRvQW5pbWF0aW9uIiwiQXJyYXkiLCJpc0FycmF5IiwiZG9tYWluIiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJjdXJyZW50VGltZSIsInNob3dGbG9hdGluZ1RpbWVEaXNwbGF5IiwibGVuZ3RoIiwic2hvd0FuaW1hdGlvbkNvbnRyb2wiLCJoaWRlQ29udHJvbCIsInNob3dUaW1lV2lkZ2V0Iiwia2V5cyIsIl91c2VNZW1vIiwibWVyZ2VGaWx0ZXJXaXRoVGltZWxpbmUiLCJlbmhhbmNlZEZpbHRlciIsImVuaGFuY2VkQW5pbWF0aW9uQ29uZmlnIiwib25DbG9zZSIsInVzZUNhbGxiYWNrIiwic2V0RmlsdGVyVmlldyIsIkZJTFRFUl9WSUVXX1RZUEVTIiwic2lkZSIsIm9uVG9nZ2xlTWluaWZ5IiwidmlldyIsImVubGFyZ2VkIiwibWluaWZpZWQiLCJjcmVhdGVFbGVtZW50IiwiTWF0aCIsIm1pbiIsInN0eWxlIiwibWFyZ2luUmlnaHQiLCJjbGFzc05hbWUiLCJyZWYiLCJzZXRMYXllckFuaW1hdGlvblRpbWUiLCJzdGFydCIsInBhdXNlIiwicmVzZXRBbmltYXRpb24iLCJ0aW1lbGluZSIsInNldFRpbWVsaW5lVmFsdWUiLCJ1cGRhdGVBbmltYXRpb25TcGVlZCIsInVwZGF0ZUxheWVyQW5pbWF0aW9uU3BlZWQiLCJ0b2dnbGVBbmltYXRpb24iLCJ0b2dnbGVMYXllckFuaW1hdGlvbiIsImlzQW5pbWF0YWJsZSIsImZpbHRlcklkeCIsInNldEZpbHRlckFuaW1hdGlvblRpbWUiLCJpbmRleCIsInNob3dUaW1lRGlzcGxheSIsInNldEZpbHRlclBsb3QiLCJzZXRGaWx0ZXJBbmltYXRpb25XaW5kb3ciLCJzZXRGaWx0ZXJTeW5jVGltZWxpbmVNb2RlIiwic2V0VGltZUZpbHRlclN5bmNUaW1lbGluZU1vZGUiLCJ0b2dnbGVGaWx0ZXJBbmltYXRpb24iLCJ1cGRhdGVGaWx0ZXJBbmltYXRpb25TcGVlZCIsIndpdGhUaGVtZSIsImZvcndhcmRSZWYiLCJfZXh0ZW5kczIiXSwic291cmNlcyI6WyIuLi9zcmMvYm90dG9tLXdpZGdldC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IFJlYWN0LCB7Zm9yd2FyZFJlZiwgdXNlTWVtbywgdXNlQ2FsbGJhY2t9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBzdHlsZWQsIHt3aXRoVGhlbWUsIElTdHlsZWRDb21wb25lbnR9IGZyb20gJ3N0eWxlZC1jb21wb25lbnRzJztcblxuaW1wb3J0IHtGSUxURVJfVklFV19UWVBFU30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtoYXNQb3J0YWJsZVdpZHRoLCBpc1NpZGVGaWx0ZXIsIG1lcmdlRmlsdGVyV2l0aFRpbWVsaW5lfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcbmltcG9ydCB7bWVkaWEsIGJyZWFrUG9pbnRWYWx1ZXN9IGZyb20gJ0BrZXBsZXIuZ2wvc3R5bGVzJztcbmltcG9ydCB7VGltZVJhbmdlRmlsdGVyfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuaW1wb3J0IFRpbWVXaWRnZXRGYWN0b3J5IGZyb20gJy4vZmlsdGVycy90aW1lLXdpZGdldCc7XG5pbXBvcnQge2JvdHRvbVdpZGdldFNlbGVjdG9yfSBmcm9tICcuL2tlcGxlci1nbCc7XG5pbXBvcnQgRmlsdGVyQW5pbWF0aW9uQ29udHJvbGxlckZhY3RvcnkgZnJvbSAnLi9maWx0ZXItYW5pbWF0aW9uLWNvbnRyb2xsZXInO1xuaW1wb3J0IExheWVyQW5pbWF0aW9uQ29udHJvbGxlckZhY3RvcnkgZnJvbSAnLi9sYXllci1hbmltYXRpb24tY29udHJvbGxlcic7XG5pbXBvcnQgQW5pbWF0aW9uQ29udHJvbEZhY3RvcnkgZnJvbSAnLi9jb21tb24vYW5pbWF0aW9uLWNvbnRyb2wvYW5pbWF0aW9uLWNvbnRyb2wnO1xuaW1wb3J0IHtCYXNlQ29tcG9uZW50UHJvcHN9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBtYXhXaWR0aCA9IDEwODA7XG5cbmV4cG9ydCB0eXBlIEJvdHRvbVdpZGdldENvbnRhaW5lclByb3BzID0gQmFzZUNvbXBvbmVudFByb3BzICYge1xuICBoYXNQYWRkaW5nPzogYm9vbGVhbjtcbiAgd2lkdGg6IG51bWJlcjtcbiAgcmVmOiBSZWFjdC5Gb3J3YXJkZWRSZWY8SFRNTERpdkVsZW1lbnQ+O1xufTtcblxuY29uc3QgQm90dG9tV2lkZ2V0Q29udGFpbmVyOiBJU3R5bGVkQ29tcG9uZW50PFxuICAnd2ViJyxcbiAgQm90dG9tV2lkZ2V0Q29udGFpbmVyUHJvcHNcbj4gPSBzdHlsZWQuZGl2PEJvdHRvbVdpZGdldENvbnRhaW5lclByb3BzPmBcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgcGFkZGluZy10b3A6ICR7cHJvcHMgPT4gKHByb3BzLmhhc1BhZGRpbmcgPyBwcm9wcy50aGVtZS5ib3R0b21XaWRnZXRQYWRkaW5nVG9wIDogMCl9cHg7XG4gIHBhZGRpbmctcmlnaHQ6ICR7cHJvcHMgPT4gKHByb3BzLmhhc1BhZGRpbmcgPyBwcm9wcy50aGVtZS5ib3R0b21XaWRnZXRQYWRkaW5nUmlnaHQgOiAwKX1weDtcbiAgcGFkZGluZy1ib3R0b206ICR7cHJvcHMgPT4gKHByb3BzLmhhc1BhZGRpbmcgPyBwcm9wcy50aGVtZS5ib3R0b21XaWRnZXRQYWRkaW5nQm90dG9tIDogMCl9cHg7XG4gIHBhZGRpbmctbGVmdDogJHtwcm9wcyA9PiAocHJvcHMuaGFzUGFkZGluZyA/IHByb3BzLnRoZW1lLmJvdHRvbVdpZGdldFBhZGRpbmdMZWZ0IDogMCl9cHg7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lICFpbXBvcnRhbnQ7IC8qIHByZXZlbnQgcGFkZGluZyBmcm9tIGJsb2NraW5nIGlucHV0ICovXG4gICYgPiAqIHtcbiAgICAvKiBhbGwgY2hpbGRyZW4gc2hvdWxkIGFsbG93IGlucHV0ICovXG4gICAgcG9pbnRlci1ldmVudHM6IGFsbDtcbiAgfVxuICB3aWR0aDogJHtwcm9wcyA9PiBwcm9wcy53aWR0aH1weDtcbiAgei1pbmRleDogMTtcbiAgJHttZWRpYS5wb3J0YWJsZWBwYWRkaW5nOiAwO2B9XG5gO1xuXG5leHBvcnQgdHlwZSBCb3R0b21XaWRnZXRQcm9wcyA9IHtcbiAgcm9vdFJlZjogUmVhY3QuRm9yd2FyZGVkUmVmPEhUTUxEaXZFbGVtZW50PjtcbiAgY29udGFpbmVyVzogbnVtYmVyO1xufSAmIFJldHVyblR5cGU8dHlwZW9mIGJvdHRvbVdpZGdldFNlbGVjdG9yPjtcbnR5cGUgVGhlbWVQcm9wID0ge1xuICB0aGVtZTogYW55O1xufTtcbnR5cGUgQm90dG9tV2lkZ2V0VGhlbWVkUHJvcHMgPSBCb3R0b21XaWRnZXRQcm9wcyAmIFRoZW1lUHJvcDtcblxuQm90dG9tV2lkZ2V0RmFjdG9yeS5kZXBzID0gW1xuICBUaW1lV2lkZ2V0RmFjdG9yeSxcbiAgQW5pbWF0aW9uQ29udHJvbEZhY3RvcnksXG4gIEZpbHRlckFuaW1hdGlvbkNvbnRyb2xsZXJGYWN0b3J5LFxuICBMYXllckFuaW1hdGlvbkNvbnRyb2xsZXJGYWN0b3J5XG5dO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCb3R0b21XaWRnZXRGYWN0b3J5KFxuICBUaW1lV2lkZ2V0OiBSZXR1cm5UeXBlPHR5cGVvZiBUaW1lV2lkZ2V0RmFjdG9yeT4sXG4gIEFuaW1hdGlvbkNvbnRyb2w6IFJldHVyblR5cGU8dHlwZW9mIEFuaW1hdGlvbkNvbnRyb2xGYWN0b3J5PixcbiAgRmlsdGVyQW5pbWF0aW9uQ29udHJvbGxlcjogUmV0dXJuVHlwZTx0eXBlb2YgRmlsdGVyQW5pbWF0aW9uQ29udHJvbGxlckZhY3Rvcnk+LFxuICBMYXllckFuaW1hdGlvbkNvbnRyb2xsZXI6IFJldHVyblR5cGU8dHlwZW9mIExheWVyQW5pbWF0aW9uQ29udHJvbGxlckZhY3Rvcnk+XG4pOiBSZWFjdC5GQzxCb3R0b21XaWRnZXRUaGVtZWRQcm9wcz4ge1xuICBjb25zdCBMYXllckFuaW1hdGlvbkNvbnRyb2wgPSBzdHlsZWQoQW5pbWF0aW9uQ29udHJvbClgXG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5zaWRlUGFuZWxCZ307XG4gIGA7XG5cbiAgY29uc3QgQm90dG9tV2lkZ2V0OiBSZWFjdC5GQzxCb3R0b21XaWRnZXRUaGVtZWRQcm9wcz4gPSAocHJvcHM6IEJvdHRvbVdpZGdldFRoZW1lZFByb3BzKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgZGF0YXNldHMsXG4gICAgICBmaWx0ZXJzLFxuICAgICAgYW5pbWF0aW9uQ29uZmlnLFxuICAgICAgdmlzU3RhdGVBY3Rpb25zLFxuICAgICAgY29udGFpbmVyVyxcbiAgICAgIHVpU3RhdGUsXG4gICAgICBzaWRlUGFuZWxXaWR0aCxcbiAgICAgIGxheWVycyxcbiAgICAgIHJvb3RSZWYsXG4gICAgICB0aGVtZVxuICAgIH0gPSBwcm9wcztcblxuICAgIGNvbnN0IHthY3RpdmVTaWRlUGFuZWwsIHJlYWRPbmx5fSA9IHVpU3RhdGU7XG4gICAgY29uc3QgaXNPcGVuID0gQm9vbGVhbihhY3RpdmVTaWRlUGFuZWwpO1xuXG4gICAgY29uc3QgZW5sYXJnZWRGaWx0ZXJJZHggPSB1c2VNZW1vKCgpID0+IGZpbHRlcnMuZmluZEluZGV4KGYgPT4gIWlzU2lkZUZpbHRlcihmKSksIFtmaWx0ZXJzXSk7XG4gICAgY29uc3QgYW5pbWF0ZWRGaWx0ZXJJZHggPSB1c2VNZW1vKCgpID0+IGZpbHRlcnMuZmluZEluZGV4KGYgPT4gZi5pc0FuaW1hdGluZyksIFtmaWx0ZXJzXSk7XG4gICAgY29uc3QgYW5pbWF0ZWRGaWx0ZXIgPSBhbmltYXRlZEZpbHRlcklkeCA+IC0xID8gZmlsdGVyc1thbmltYXRlZEZpbHRlcklkeF0gOiBudWxsO1xuICAgIC8vIHdlIG5lZWQgdG8gaGlkZSBsYXllciB0aW1lbGluZSB3aGVuIGZpbHRlciBpcyBzeW5jZWQgYW5kIG5vdCBlbmxhcmdlZFxuICAgIGNvbnN0IGlzVGltZWxpbmVMaW5rZWRXaXRoRmlsdGVyID0gdXNlTWVtbyhcbiAgICAgICgpID0+IChmaWx0ZXJzIGFzIFRpbWVSYW5nZUZpbHRlcltdKS5zb21lKGYgPT4gZi5zeW5jZWRXaXRoTGF5ZXJUaW1lbGluZSksXG4gICAgICBbZmlsdGVyc11cbiAgICApO1xuXG4gICAgY29uc3QgaXNNb2JpbGUgPSB1c2VNZW1vKCgpID0+IGhhc1BvcnRhYmxlV2lkdGgoYnJlYWtQb2ludFZhbHVlcyksIFtdKTtcbiAgICBjb25zdCBpc0xlZ2VuZFBpbm5lZCA9XG4gICAgICB1aVN0YXRlLm1hcENvbnRyb2xzPy5tYXBMZWdlbmQ/LnNob3cgJiYgdWlTdGF0ZS5tYXBDb250cm9scz8ubWFwTGVnZW5kPy5hY3RpdmU7XG4gICAgY29uc3Qgc3BhY2VGb3JMZWdlbmRXaWR0aCA9IGlzTGVnZW5kUGlubmVkXG4gICAgICA/IHRoZW1lLm1hcENvbnRyb2w/LndpZHRoICtcbiAgICAgICAgdGhlbWUubWFwQ29udHJvbD8ubWFwTGVnZW5kPy5waW5uZWQ/LnJpZ2h0ICogMiAtXG4gICAgICAgIHRoZW1lLmJvdHRvbVdpZGdldFBhZGRpbmdSaWdodFxuICAgICAgOiAwO1xuXG4gICAgY29uc3QgZW5sYXJnZWRGaWx0ZXJXaWR0aCA9IHVzZU1lbW8oXG4gICAgICAoKSA9PiAoIWlzTW9iaWxlICYmIGlzT3BlbiA/IGNvbnRhaW5lclcgLSBzaWRlUGFuZWxXaWR0aCA6IGNvbnRhaW5lclcpIC0gc3BhY2VGb3JMZWdlbmRXaWR0aCxcbiAgICAgIFtpc01vYmlsZSwgaXNPcGVuLCBjb250YWluZXJXLCBzaWRlUGFuZWxXaWR0aCwgc3BhY2VGb3JMZWdlbmRXaWR0aF1cbiAgICApO1xuXG4gICAgLy8gc2hvdyBwbGF5YmFjayBjb250cm9sIGlmIGxheWVycyBjb250YWluIHRyaXAgbGF5ZXIgJiBhdCBsZWFzdCBvbmUgdHJpcCBsYXllciBpcyB2aXNpYmxlXG4gICAgY29uc3QgYW5pbWF0YWJsZUxheWVyID0gdXNlTWVtbyhcbiAgICAgICgpID0+XG4gICAgICAgIGxheWVycy5maWx0ZXIobCA9PiBsLmNvbmZpZy5hbmltYXRpb24gJiYgbC5jb25maWcuYW5pbWF0aW9uLmVuYWJsZWQgJiYgbC5jb25maWcuaXNWaXNpYmxlKSxcbiAgICAgIFtsYXllcnNdXG4gICAgKTtcblxuICAgIGNvbnN0IHJlYWR5VG9BbmltYXRpb24gPSB1c2VNZW1vKFxuICAgICAgKCkgPT4gQXJyYXkuaXNBcnJheShhbmltYXRpb25Db25maWcuZG9tYWluKSAmJiBOdW1iZXIuaXNGaW5pdGUoYW5pbWF0aW9uQ29uZmlnLmN1cnJlbnRUaW1lKSxcbiAgICAgIFthbmltYXRpb25Db25maWcuZG9tYWluLCBhbmltYXRpb25Db25maWcuY3VycmVudFRpbWVdXG4gICAgKTtcblxuICAgIC8vIGlmIGFuaW1hdGlvbiBjb250cm9sIGlzIHNob3dpbmcsIGhpZGUgdGltZSBkaXNwbGF5IGluIHRpbWUgc2xpZGVyXG4gICAgY29uc3Qgc2hvd0Zsb2F0aW5nVGltZURpc3BsYXkgPSAhYW5pbWF0YWJsZUxheWVyLmxlbmd0aDtcbiAgICBjb25zdCBzaG93QW5pbWF0aW9uQ29udHJvbCA9XG4gICAgICBhbmltYXRhYmxlTGF5ZXIubGVuZ3RoICYmIHJlYWR5VG9BbmltYXRpb24gJiYgIWFuaW1hdGlvbkNvbmZpZy5oaWRlQ29udHJvbDtcbiAgICBjb25zdCBzaG93VGltZVdpZGdldCA9IGVubGFyZ2VkRmlsdGVySWR4ID4gLTEgJiYgT2JqZWN0LmtleXMoZGF0YXNldHMpLmxlbmd0aCA+IDA7XG5cbiAgICAvLyBpZiBmaWx0ZXIgaXMgbm90IGFuaW1hdGluZywgcGFzcyBpbiBlbmxhcmdlZCBmaWx0ZXIgaGVyZSBiZWNhdXNlXG4gICAgLy8gYW5pbWF0aW9uIGNvbnRyb2xsZXIgbmVlZHMgdG8gY2FsbCByZXNldCBvbiBpdFxuICAgIGNvbnN0IGZpbHRlciA9IHVzZU1lbW8oXG4gICAgICAoKSA9PiAoYW5pbWF0ZWRGaWx0ZXIgYXMgVGltZVJhbmdlRmlsdGVyKSB8fCBmaWx0ZXJzW2VubGFyZ2VkRmlsdGVySWR4XSxcbiAgICAgIFthbmltYXRlZEZpbHRlciwgZmlsdGVycywgZW5sYXJnZWRGaWx0ZXJJZHhdXG4gICAgKTtcblxuICAgIC8vIHdlIG1lcmdlIGZpbHRlciBhbmQgdGltZWxpbmUgaWYgZmlsdGVyIGlzIHN5bmNlZFxuICAgIGNvbnN0IHtmaWx0ZXI6IGVuaGFuY2VkRmlsdGVyLCBhbmltYXRpb25Db25maWc6IGVuaGFuY2VkQW5pbWF0aW9uQ29uZmlnfSA9IHVzZU1lbW8oXG4gICAgICAoKSA9PlxuICAgICAgICBmaWx0ZXI/LnN5bmNlZFdpdGhMYXllclRpbWVsaW5lXG4gICAgICAgICAgPyBtZXJnZUZpbHRlcldpdGhUaW1lbGluZShmaWx0ZXIsIGFuaW1hdGlvbkNvbmZpZylcbiAgICAgICAgICA6IHtmaWx0ZXIsIGFuaW1hdGlvbkNvbmZpZ30sXG4gICAgICBbZmlsdGVyLCBhbmltYXRpb25Db25maWddXG4gICAgKTtcblxuICAgIGNvbnN0IG9uQ2xvc2UgPSB1c2VDYWxsYmFjayhcbiAgICAgICgpID0+IHZpc1N0YXRlQWN0aW9ucy5zZXRGaWx0ZXJWaWV3KGVubGFyZ2VkRmlsdGVySWR4LCBGSUxURVJfVklFV19UWVBFUy5zaWRlKSxcbiAgICAgIFt2aXNTdGF0ZUFjdGlvbnMsIGVubGFyZ2VkRmlsdGVySWR4XVxuICAgICk7XG5cbiAgICBjb25zdCBvblRvZ2dsZU1pbmlmeSA9IHVzZUNhbGxiYWNrKFxuICAgICAgKCkgPT5cbiAgICAgICAgdmlzU3RhdGVBY3Rpb25zLnNldEZpbHRlclZpZXcoXG4gICAgICAgICAgZW5sYXJnZWRGaWx0ZXJJZHgsXG4gICAgICAgICAgZmlsdGVyLnZpZXcgPT09IEZJTFRFUl9WSUVXX1RZUEVTLmVubGFyZ2VkXG4gICAgICAgICAgICA/IEZJTFRFUl9WSUVXX1RZUEVTLm1pbmlmaWVkXG4gICAgICAgICAgICA6IEZJTFRFUl9WSUVXX1RZUEVTLmVubGFyZ2VkXG4gICAgICAgICksXG4gICAgICBbZW5sYXJnZWRGaWx0ZXJJZHgsIHZpc1N0YXRlQWN0aW9ucywgZmlsdGVyXVxuICAgICk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPEJvdHRvbVdpZGdldENvbnRhaW5lclxuICAgICAgICB3aWR0aD17TWF0aC5taW4obWF4V2lkdGgsIGVubGFyZ2VkRmlsdGVyV2lkdGgpfVxuICAgICAgICBzdHlsZT17e21hcmdpblJpZ2h0OiBzcGFjZUZvckxlZ2VuZFdpZHRofX1cbiAgICAgICAgY2xhc3NOYW1lPVwiYm90dG9tLXdpZGdldC0tY29udGFpbmVyXCJcbiAgICAgICAgaGFzUGFkZGluZz17c2hvd0FuaW1hdGlvbkNvbnRyb2wgfHwgc2hvd1RpbWVXaWRnZXR9XG4gICAgICAgIHJlZj17cm9vdFJlZn1cbiAgICAgID5cbiAgICAgICAgeyFpc1RpbWVsaW5lTGlua2VkV2l0aEZpbHRlciA/IChcbiAgICAgICAgICA8TGF5ZXJBbmltYXRpb25Db250cm9sbGVyXG4gICAgICAgICAgICBhbmltYXRpb25Db25maWc9e2VuaGFuY2VkQW5pbWF0aW9uQ29uZmlnfVxuICAgICAgICAgICAgc2V0TGF5ZXJBbmltYXRpb25UaW1lPXt2aXNTdGF0ZUFjdGlvbnMuc2V0TGF5ZXJBbmltYXRpb25UaW1lfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIHsoaXNBbmltYXRpbmcsIHN0YXJ0LCBwYXVzZSwgcmVzZXRBbmltYXRpb24sIHRpbWVsaW5lLCBzZXRUaW1lbGluZVZhbHVlKSA9PlxuICAgICAgICAgICAgICBzaG93QW5pbWF0aW9uQ29udHJvbCA/IChcbiAgICAgICAgICAgICAgICA8TGF5ZXJBbmltYXRpb25Db250cm9sXG4gICAgICAgICAgICAgICAgICB1cGRhdGVBbmltYXRpb25TcGVlZD17dmlzU3RhdGVBY3Rpb25zLnVwZGF0ZUxheWVyQW5pbWF0aW9uU3BlZWR9XG4gICAgICAgICAgICAgICAgICB0b2dnbGVBbmltYXRpb249e3Zpc1N0YXRlQWN0aW9ucy50b2dnbGVMYXllckFuaW1hdGlvbn1cbiAgICAgICAgICAgICAgICAgIGlzQW5pbWF0YWJsZT17IWFuaW1hdGVkRmlsdGVyfVxuICAgICAgICAgICAgICAgICAgaXNBbmltYXRpbmc9e2lzQW5pbWF0aW5nfVxuICAgICAgICAgICAgICAgICAgcmVzZXRBbmltYXRpb249e3Jlc2V0QW5pbWF0aW9ufVxuICAgICAgICAgICAgICAgICAgc2V0VGltZWxpbmVWYWx1ZT17c2V0VGltZWxpbmVWYWx1ZX1cbiAgICAgICAgICAgICAgICAgIHRpbWVsaW5lPXt0aW1lbGluZX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICApIDogbnVsbFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvTGF5ZXJBbmltYXRpb25Db250cm9sbGVyPlxuICAgICAgICApIDogbnVsbH1cbiAgICAgICAge2VuaGFuY2VkRmlsdGVyID8gKFxuICAgICAgICAgIDxGaWx0ZXJBbmltYXRpb25Db250cm9sbGVyXG4gICAgICAgICAgICBmaWx0ZXI9e2VuaGFuY2VkRmlsdGVyfVxuICAgICAgICAgICAgZmlsdGVySWR4PXthbmltYXRlZEZpbHRlcklkeCA+IC0xID8gYW5pbWF0ZWRGaWx0ZXJJZHggOiBlbmxhcmdlZEZpbHRlcklkeH1cbiAgICAgICAgICAgIHNldEZpbHRlckFuaW1hdGlvblRpbWU9e3Zpc1N0YXRlQWN0aW9ucy5zZXRGaWx0ZXJBbmltYXRpb25UaW1lfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIHsoaXNBbmltYXRpbmcsIHN0YXJ0LCBwYXVzZSwgcmVzZXRBbmltYXRpb24sIHRpbWVsaW5lLCBzZXRUaW1lbGluZVZhbHVlKSA9PlxuICAgICAgICAgICAgICBzaG93VGltZVdpZGdldCAmJiB0aW1lbGluZSA/IChcbiAgICAgICAgICAgICAgICA8VGltZVdpZGdldFxuICAgICAgICAgICAgICAgICAgLy8gVGltZVdpZGdldCB1c2VzIFJlYWN0Lm1lbW8sIGhlcmUgd2UgcGFzcyB3aWR0aFxuICAgICAgICAgICAgICAgICAgLy8gZXZlbiB0aG91Z2ggaXQgZG9lc250IHVzZSBpdCwgdG8gZm9yY2UgcmVyZW5kZXJcbiAgICAgICAgICAgICAgICAgIGZpbHRlcj17ZW5oYW5jZWRGaWx0ZXIgYXMgVGltZVJhbmdlRmlsdGVyfVxuICAgICAgICAgICAgICAgICAgaW5kZXg9e2VubGFyZ2VkRmlsdGVySWR4fVxuICAgICAgICAgICAgICAgICAgZGF0YXNldHM9e2RhdGFzZXRzfVxuICAgICAgICAgICAgICAgICAgbGF5ZXJzPXtsYXllcnN9XG4gICAgICAgICAgICAgICAgICByZWFkT25seT17cmVhZE9ubHl9XG4gICAgICAgICAgICAgICAgICBzaG93VGltZURpc3BsYXk9e3Nob3dGbG9hdGluZ1RpbWVEaXNwbGF5fVxuICAgICAgICAgICAgICAgICAgc2V0RmlsdGVyUGxvdD17dmlzU3RhdGVBY3Rpb25zLnNldEZpbHRlclBsb3R9XG4gICAgICAgICAgICAgICAgICBzZXRGaWx0ZXJBbmltYXRpb25UaW1lPXtzZXRUaW1lbGluZVZhbHVlfVxuICAgICAgICAgICAgICAgICAgc2V0RmlsdGVyQW5pbWF0aW9uV2luZG93PXt2aXNTdGF0ZUFjdGlvbnMuc2V0RmlsdGVyQW5pbWF0aW9uV2luZG93fVxuICAgICAgICAgICAgICAgICAgc2V0RmlsdGVyU3luY1RpbWVsaW5lTW9kZT17dmlzU3RhdGVBY3Rpb25zLnNldFRpbWVGaWx0ZXJTeW5jVGltZWxpbmVNb2RlfVxuICAgICAgICAgICAgICAgICAgdG9nZ2xlQW5pbWF0aW9uPXt2aXNTdGF0ZUFjdGlvbnMudG9nZ2xlRmlsdGVyQW5pbWF0aW9ufVxuICAgICAgICAgICAgICAgICAgdXBkYXRlQW5pbWF0aW9uU3BlZWQ9e3Zpc1N0YXRlQWN0aW9ucy51cGRhdGVGaWx0ZXJBbmltYXRpb25TcGVlZH1cbiAgICAgICAgICAgICAgICAgIHJlc2V0QW5pbWF0aW9uPXtyZXNldEFuaW1hdGlvbn1cbiAgICAgICAgICAgICAgICAgIGlzQW5pbWF0YWJsZT17IWFuaW1hdGlvbkNvbmZpZyB8fCAhYW5pbWF0aW9uQ29uZmlnLmlzQW5pbWF0aW5nfVxuICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uQ29uZmlnPXthbmltYXRpb25Db25maWd9XG4gICAgICAgICAgICAgICAgICBvbkNsb3NlPXtvbkNsb3NlfVxuICAgICAgICAgICAgICAgICAgdGltZWxpbmU9e3RpbWVsaW5lfVxuICAgICAgICAgICAgICAgICAgb25Ub2dnbGVNaW5pZnk9e29uVG9nZ2xlTWluaWZ5fVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICkgOiBudWxsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9GaWx0ZXJBbmltYXRpb25Db250cm9sbGVyPlxuICAgICAgICApIDogbnVsbH1cbiAgICAgIDwvQm90dG9tV2lkZ2V0Q29udGFpbmVyPlxuICAgICk7XG4gIH07XG5cbiAgcmV0dXJuIHdpdGhUaGVtZShcbiAgICBmb3J3YXJkUmVmKChwcm9wczogQm90dG9tV2lkZ2V0VGhlbWVkUHJvcHMsIHJlZjogUmVhY3QuRm9yd2FyZGVkUmVmPEhUTUxEaXZFbGVtZW50PikgPT4gKFxuICAgICAgPEJvdHRvbVdpZGdldCB7Li4ucHJvcHN9IHJvb3RSZWY9e3JlZn0gLz5cbiAgICApKVxuICApO1xufVxuLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxpQkFBQSxHQUFBRix1QkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUUsVUFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsTUFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBR0EsSUFBQUssV0FBQSxHQUFBQyxzQkFBQSxDQUFBTixPQUFBO0FBRUEsSUFBQU8sMEJBQUEsR0FBQUQsc0JBQUEsQ0FBQU4sT0FBQTtBQUNBLElBQUFRLHlCQUFBLEdBQUFGLHNCQUFBLENBQUFOLE9BQUE7QUFDQSxJQUFBUyxpQkFBQSxHQUFBSCxzQkFBQSxDQUFBTixPQUFBO0FBQW1GLElBQUFVLGVBQUEsRUFBQUMsZ0JBQUEsRUFBQUMsZ0JBQUEsRUFmbkY7QUFDQTtB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