kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
2,339 lines • 240 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof3 = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.INITIAL_VIS_STATE = exports.DEFAULT_EDITOR = void 0;
exports.addDefaultLayers = addDefaultLayers;
exports.addDefaultTooltips = addDefaultTooltips;
exports.addWidgetUpdater = exports.addLayerUpdater = exports.addFilterUpdater = void 0;
exports.apiCallData = apiCallData;
exports.defaultAnimationConfig = void 0;
exports.deleteFeatureUpdater = deleteFeatureUpdater;
exports.enlargeFilterUpdater = void 0;
exports.interactionConfigChangeUpdater = interactionConfigChangeUpdater;
exports.layerColorUIChangeUpdater = exports.layerClickUpdater = void 0;
exports.layerConfigChangeUpdater = layerConfigChangeUpdater;
exports.layerHoverUpdater = void 0;
exports.layerTextLabelChangeUpdater = layerTextLabelChangeUpdater;
exports.layerTypeChangeUpdater = layerTypeChangeUpdater;
exports.layerVisConfigChangeUpdater = layerVisConfigChangeUpdater;
exports.layerVisualChannelChangeUpdater = layerVisualChannelChangeUpdater;
exports.loadFilesUpdater = exports.loadFilesErrUpdater = exports.loadEDLinkData = void 0;
exports.loadURLUpdater = loadURLUpdater;
exports.setEditorModeUpdater = exports.resetMapConfigUpdater = exports.reorderWidgetUpdater = exports.reorderLayerUpdater = exports.removeWidgetUpdater = exports.removeLayerUpdater = exports.removeFilterUpdater = exports.removeDatasetUpdater = exports.receiveMapConfigUpdater = exports.mouseMoveUpdater = exports.mapClickUpdater = void 0;
exports.setFeaturesUpdater = setFeaturesUpdater;
exports.setFilterAPIUpdater = setFilterAPIUpdater;
exports.setFilterPlotUpdater = void 0;
exports.setFilterUpdater = setFilterUpdater;
exports.setPolygonFilterLayerUpdater = setPolygonFilterLayerUpdater;
exports.showDatasetTableUpdater = exports.setSelectedFeatureUpdater = void 0;
exports.toggleEditorVisibility = toggleEditorVisibility;
exports.toggleSplitMapUpdater = exports.toggleLayerForMapUpdater = exports.toggleFilterAnimationUpdater = void 0;
exports.updateAllLayerDomainData = updateAllLayerDomainData;
exports.updateAnimationDomain = updateAnimationDomain;
exports.updateAnimationTimeUpdater = void 0;
exports.updateDatasetInfo = updateDatasetInfo;
exports.updateLayerBlendingUpdater = exports.updateLayerAnimationSpeedUpdater = exports.updateFilterAnimationSpeedUpdater = void 0;
exports.updateStateOnLayerVisibilityChange = updateStateOnLayerVisibilityChange;
exports.updateStateWithLayerDataUpdater = updateStateWithLayerDataUpdater;
exports.updateVisDataUpdater = void 0;
exports.updateWidgetAggregationData = updateWidgetAggregationData;
exports.widgetConfigChangeUpdater = widgetConfigChangeUpdater;
exports.widgetTypeChangeUpdater = widgetTypeChangeUpdater;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _readOnlyError2 = _interopRequireDefault(require("@babel/runtime/helpers/readOnlyError"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _window = require("global/window");
var _tasks = _interopRequireWildcard(require("react-palm/tasks"));
var _lodash = _interopRequireDefault(require("lodash.clonedeep"));
var _lodash2 = _interopRequireDefault(require("lodash.uniq"));
var _lodash3 = _interopRequireDefault(require("lodash.get"));
var _lodash4 = _interopRequireDefault(require("lodash.xor"));
var _utils = require("../utils/utils");
var _tasks2 = require("../tasks/tasks");
var _visStateActions = require("../actions/vis-state-actions");
var _actions = require("../actions");
var _interactionUtils = require("../utils/interaction-utils");
var _filterUtils = require("../utils/filter-utils");
var _datasetUtils = require("../utils/dataset-utils");
var _layerUtils = require("../utils/layer-utils/layer-utils");
var _visStateMerger = require("./vis-state-merger");
var _simplifyGeojson = _interopRequireDefault(require("simplify-geojson"));
var _splitMapUtils = require("../utils/split-map-utils");
var _dataProcessor = require("../processors/data-processor");
var _layers = require("../layers");
var _widgets = require("../widgets");
var _fileUtils = require("../utils/file-utils");
var _layerFactory = require("../layers/layer-factory");
var _defaultSettings = require("../constants/default-settings");
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 || _typeof3(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 _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return (0, _typeof2["default"])(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if ((0, _typeof2["default"])(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if ((0, _typeof2["default"])(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
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; }
// react-palm
// disable capture exception for react-palm call to withTask
(0, _tasks.disableStackCapturing)();
/**
* Updaters for `visState` reducer. Can be used in your root reducer to directly modify kepler.gl's state.
* Read more about [Using updaters](../advanced-usage/using-updaters.md)
*
* @public
* @example
*
* import keplerGlReducer, {visStateUpdaters} from 'kepler.gl/reducers';
* // Root Reducer
* const reducers = combineReducers({
* keplerGl: keplerGlReducer,
* app: appReducer
* });
*
* const composedReducer = (state, action) => {
* switch (action.type) {
* case 'CLICK_BUTTON':
* return {
* ...state,
* keplerGl: {
* ...state.keplerGl,
* foo: {
* ...state.keplerGl.foo,
* visState: visStateUpdaters.enlargeFilterUpdater(
* state.keplerGl.foo.visState,
* {idx: 0}
* )
* }
* }
* };
* }
* return reducers(state, action);
* };
*
* export default composedReducer;
*/
/* eslint-disable no-unused-vars */
// const visStateUpdaters = null;
/* eslint-enable no-unused-vars */
var defaultAnimationConfig = exports.defaultAnimationConfig = {
domain: null,
currentTime: null,
speed: 1
};
var DEFAULT_EDITOR = exports.DEFAULT_EDITOR = {
mode: _defaultSettings.EDITOR_MODES.DRAW_POLYGON,
features: [],
selectedFeature: null,
visible: true
};
/**
* Default initial `visState`
* @memberof visStateUpdaters
* @constant
* @type {Object}
* @property {Array} layers
* @property {Array} layerData
* @property {Array} layerToBeMerged
* @property {Array} layerOrder
* @property {Array} filters
* @property {Array} filterToBeMerged
* @property {Array} datasets
* @property {string} editingDataset
* @property {Object} interactionConfig
* @property {Object} interactionToBeMerged
* @property {string} layerBlending
* @property {Object} hoverInfo
* @property {Object} clicked
* @property {Object} mousePos
* @property {Array} splitMaps - a list of objects of layer availabilities and visibilities for each map
* @property {Object} layerClasses
* @property {Object} animationConfig
* @property {Object} editor
* @public
*/
var INITIAL_VIS_STATE = exports.INITIAL_VIS_STATE = {
// layers
layers: [],
layerData: [],
layerToBeMerged: [],
layerOrder: [],
// filters
filters: [],
filterToBeMerged: [],
// widgets
widgets: [],
widgetToBeMerged: [],
widgetOrder: [],
// a collection of multiple dataset
datasets: {},
editingDataset: undefined,
interactionConfig: (0, _interactionUtils.getDefaultInteraction)(),
interactionToBeMerged: undefined,
layerBlending: 'normal',
hoverInfo: undefined,
clicked: undefined,
mousePos: {},
// this is used when user split maps
splitMaps: [// this will contain a list of objects to
// describe the state of layer availability and visibility for each map
// [
// {
// layers: {layer_id: true | false}
// }
// ]
],
//
// defaults layer classes
layerClasses: _layers.LayerClasses,
// default widget classes
widgetClasses: _widgets.WidgetClasses,
// default animation
// time in unix timestamp (milliseconds) (the number of seconds since the Unix Epoch)
animationConfig: defaultAnimationConfig,
editor: DEFAULT_EDITOR
};
function updateStateWithWidgetAndData(state, _ref) {
var widget = _ref.widget,
idx = _ref.idx;
return _objectSpread(_objectSpread({}, state), {}, {
widgets: state.widgets.map(function (wdgt, i) {
return i === idx ? widget : wdgt;
})
});
}
/**
* Called to update layer base config: dataId, label, column, isVisible
*
*/
function widgetConfigChangeUpdater(state, action) {
var oldWidget = action.oldWidget,
auth = action.auth,
project = action.project;
var mapState = action.newConfig.mapState;
var x = state.widgets.findIndex(function (w) {
return w.id === oldWidget.id;
});
var props = Object.keys(action.newConfig);
action.newConfig.mapState ? delete action.newConfig.mapState : null;
var newWidget = oldWidget.updateWidgetConfig(action.newConfig); // if (newWidget.shouldCalculateAggregatedData(props)) {
// const aggregatedData = newWidget.calculateAggregationData(
// newWidget,
// state.filters,
// state.datasets,
// mapState,
// auth,
// project
// );
// newWidget.updateWidgetConfg({apiCallRequest: true});
// return updateStateWithWidgetAndData(updatedState ? updatedState : state, {
// widget: newWidget,
// x
// });
// }
var newState = _objectSpread(_objectSpread({}, state), {}, {
splitMaps: 'isVisible' in action.newConfig ? toggleWidgetFromSplitMaps(state, widget) : state.splitMaps
});
return updateStateWithWidgetAndData(newState, {
widget: newWidget,
x: x
});
}
function widgetTypeChangeUpdater(state, action) {
var oldWidget = action.oldWidget,
newType = action.newType;
var oldId = oldWidget.id;
var idx = state.widgets.findIndex(function (w) {
return w.id === oldId;
});
if (!state.widgetClasses[newType]) {
_window.console.error("".concat(newType, " is not a valid widget type"));
return state;
} // get a mint widget, with new id and type
// because deck.gl uses id to match between new and old layer.
// If type has changed but id is the same, it will break
var newWidget = new state.widgetClasses[newType]();
newWidget.config.aggregatedData = null;
newWidget.assignConfigToWidget(oldWidget.config, oldWidget.visConfigSettings);
var newState = state;
var widget = newWidget;
return updateStateWithWidgetAndData(newState, {
widget: widget,
idx: idx
});
}
function updateStateWithLayerAndData(state, _ref2) {
var layerData = _ref2.layerData,
layer = _ref2.layer,
idx = _ref2.idx;
return _objectSpread(_objectSpread({}, state), {}, {
layers: state.layers.map(function (lyr, i) {
return i === idx ? layer : lyr;
}),
layerData: layerData ? state.layerData.map(function (d, i) {
return i === idx ? layerData : d;
}) : state.layerData
});
}
function updateStateOnLayerVisibilityChange(state, layer) {
var newState = state;
if (state.splitMaps.length) {
newState = _objectSpread(_objectSpread({}, state), {}, {
splitMaps: layer.config.isVisible ? (0, _splitMapUtils.addNewLayersToSplitMap)(state.splitMaps, layer) : (0, _splitMapUtils.removeLayerFromSplitMaps)(state.splitMaps, layer)
});
}
if (layer.config.animation.enabled) {
newState = updateAnimationDomain(state);
}
return newState;
}
/**
* Update layer base config: dataId, label, column, isVisible
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.oldLayer layer to be updated
* @param {Object} action.newConfig new config
* @returns {Object} nextState
*/
function layerConfigChangeUpdater(state, action) {
var oldLayer = action.oldLayer;
var idx = state.layers.findIndex(function (l) {
return l.id === oldLayer.id;
});
var props = Object.keys(action.newConfig);
var newLayer = oldLayer.updateLayerConfig(action.newConfig);
var layerData; // let newLayer;
if (newLayer.shouldCalculateLayerData(props)) {
var oldLayerData = state.layerData[idx];
var updateLayerDataResult = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, {
sameData: true
});
layerData = updateLayerDataResult.layerData;
newLayer = updateLayerDataResult.layer;
}
var newState = state;
if ('isVisible' in action.newConfig) {
newState = updateStateOnLayerVisibilityChange(state, newLayer);
}
return updateStateWithLayerAndData(newState, {
layer: newLayer,
layerData: layerData,
idx: idx
});
}
function addOrRemoveTextLabels(newFields, textLabel) {
var newTextLabel = textLabel.slice();
var currentFields = textLabel.map(function (tl) {
return tl.field && tl.field.name;
}).filter(function (d) {
return d;
});
var addFields = newFields.filter(function (f) {
return !currentFields.includes(f.name);
});
var deleteFields = currentFields.filter(function (f) {
return !newFields.find(function (fd) {
return fd.name === f;
});
}); // delete
newTextLabel = newTextLabel.filter(function (tl) {
return tl.field && !deleteFields.includes(tl.field.name);
});
newTextLabel = !newTextLabel.length ? [_layerFactory.DEFAULT_TEXT_LABEL] : newTextLabel; // add
newTextLabel = [].concat((0, _toConsumableArray2["default"])(newTextLabel.filter(function (tl) {
return tl.field;
})), (0, _toConsumableArray2["default"])(addFields.map(function (af) {
return _objectSpread(_objectSpread({}, _layerFactory.DEFAULT_TEXT_LABEL), {}, {
field: af
});
})));
return newTextLabel;
}
function updateTextLabelPropAndValue(idx, prop, value, textLabel) {
if (!textLabel[idx].hasOwnProperty(prop)) {
return textLabel;
}
var newTextLabel = textLabel.slice();
if (prop && (value || textLabel.length === 1)) {
newTextLabel = textLabel.map(function (tl, i) {
return i === idx ? _objectSpread(_objectSpread({}, tl), {}, (0, _defineProperty2["default"])({}, prop, value)) : tl;
});
} else if (prop === 'field' && value === null && textLabel.length > 1) {
// remove label when field value is set to null
newTextLabel.splice(idx, 1);
}
return newTextLabel;
}
function layerTextLabelChangeUpdater(state, action) {
var oldLayer = action.oldLayer,
idx = action.idx,
prop = action.prop,
value = action.value;
var textLabel = oldLayer.config.textLabel;
var newTextLabel = textLabel.slice();
if (!textLabel[idx] && idx === textLabel.length) {
// if idx is set to length, add empty text label
newTextLabel = [].concat((0, _toConsumableArray2["default"])(textLabel), [_layerFactory.DEFAULT_TEXT_LABEL]);
}
if (idx === 'all' && prop === 'fields') {
newTextLabel = addOrRemoveTextLabels(value, textLabel);
} else {
newTextLabel = updateTextLabelPropAndValue(idx, prop, value, newTextLabel);
} // update text label prop and value
return layerConfigChangeUpdater(state, {
oldLayer: oldLayer,
newConfig: {
textLabel: newTextLabel
}
});
}
/**
* Update layer type. Previews layer config will be copied if applicable.
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.oldLayer layer to be updated
* @param {string} action.newType new type
* @returns {Object} nextState
* @public
*/
function layerTypeChangeUpdater(state, action) {
var oldLayer = action.oldLayer,
newType = action.newType;
if (!oldLayer) {
return state;
}
var oldId = oldLayer.id;
var idx = state.layers.findIndex(function (l) {
return l.id === oldId;
});
if (!state.layerClasses[newType]) {
_window.console.error("".concat(newType, " is not a valid layer type"));
return state;
} // get a mint layer, with new id and type
// because deck.gl uses id to match between new and old layer.
// If type has changed but id is the same, it will break
var newLayer = new state.layerClasses[newType]();
if (newLayer.name !== 'boundary' && newLayer.name !== 'pincode') {
oldLayer.config.apiCallRequest = true;
}
newLayer.assignConfigToLayer(oldLayer.config, oldLayer.visConfigSettings);
if (newLayer.config.dataId) {
var dataset = state.datasets[newLayer.config.dataId];
newLayer.updateLayerDomain(dataset);
}
var _calculateLayerData = (0, _layerUtils.calculateLayerData)(newLayer, state),
layerData = _calculateLayerData.layerData,
layer = _calculateLayerData.layer;
var newState = updateStateWithLayerAndData(state, {
layerData: layerData,
layer: layer,
idx: idx
});
if (layer.config.animation.enabled || oldLayer.config.animation.enabled) {
newState = updateAnimationDomain(newState);
} // update widgets layer id
// if (state.widgets) {
// state.widgets.map(widget => {
// const {config} = widget;
// const {selectedLayer} = config;
// if (widget.type && selectedLayer.id === oldId) {
// widget.updateWidgetConfig({
// selectedLayer: {...selectedLayer, id: newLayer.id}
// });
// }
// });
// }
// update splitMap layer id
if (state.splitMaps.length) {
newState = _objectSpread(_objectSpread({}, newState), {}, {
splitMaps: newState.splitMaps.map(function (settings) {
var _settings$layers = settings.layers,
oldLayerMap = _settings$layers[oldId],
otherLayers = (0, _objectWithoutProperties2["default"])(_settings$layers, [oldId].map(_toPropertyKey));
return oldId in settings.layers ? _objectSpread(_objectSpread({}, settings), {}, {
layers: _objectSpread(_objectSpread({}, otherLayers), {}, (0, _defineProperty2["default"])({}, layer.id, oldLayerMap))
}) : settings;
})
});
}
return newState;
}
/**
* Update layer visual channel
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.oldLayer layer to be updated
* @param {Object} action.newConfig new visual channel config
* @param {string} action.channel channel to be updated
* @returns {Object} nextState
* @public
*/
function layerVisualChannelChangeUpdater(state, action) {
var oldLayer = action.oldLayer,
newConfig = action.newConfig,
channel = action.channel;
var dataset = state.datasets[oldLayer.config.dataId];
var idx = state.layers.findIndex(function (l) {
return l.id === oldLayer.id;
});
var newLayer = oldLayer.updateLayerConfig(newConfig);
newLayer.updateLayerVisualChannel(dataset, channel);
var oldLayerData = state.layerData[idx];
var _calculateLayerData2 = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, {
sameData: true
}),
layerData = _calculateLayerData2.layerData,
layer = _calculateLayerData2.layer; // let data = layer.axiosApiCall();
// if (layer.type === 'boundary') {
// data.then(function(result) {
// // const testData = layer.formatLayer();
// var {layerData, layer} = calculateLayerDataAfterAPICall(
// newLayer,
// state,
// layerData,
// result
// );
// layerData = {
// ...layerData,
// result
// };
// newLayers[i] = layer;
// newLayerDatas[i] = layerData;
// return {
// ...state,
// layers: newLayers,
// layerData: newLayerDatas
// };
// });
// }
return updateStateWithLayerAndData(state, {
layerData: layerData,
layer: layer,
idx: idx
});
}
/**
* Update layer `visConfig`
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.oldLayer layer to be updated
* @param {Object} action.newVisConfig new visConfig as a key value map: e.g. `{opacity: 0.8}`
* @returns {Object} nextState
* @public
*/
function layerVisConfigChangeUpdater(state, action) {
var oldLayer = action.oldLayer;
var idx = state.layers.findIndex(function (l) {
return l.id === oldLayer.id;
});
var props = Object.keys(action.newVisConfig);
var newVisConfig = _objectSpread(_objectSpread({}, oldLayer.config.visConfig), action.newVisConfig);
var newLayer = oldLayer.updateLayerConfig({
visConfig: newVisConfig
});
if (newLayer.shouldCalculateLayerData(props)) {
var oldLayerData = state.layerData[idx];
var _calculateLayerData4 = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, {
sameData: true
}),
layerData = _calculateLayerData4.layerData,
layer = _calculateLayerData4.layer;
return updateStateWithLayerAndData(state, {
layerData: layerData,
layer: layer,
idx: idx
});
}
return updateStateWithLayerAndData(state, {
layer: newLayer,
idx: idx
});
}
/* eslint-enable max-statements */
/**
* Update `interactionConfig`
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.config new config as key value map: `{tooltip: {enabled: true}}`
* @returns {Object} nextState
* @public
*/
function interactionConfigChangeUpdater(state, action) {
var config = action.config;
var interactionConfig = _objectSpread(_objectSpread({}, state.interactionConfig), (0, _defineProperty2["default"])({}, config.id, config)); // Don't enable tooltip and brush at the same time
// but coordinates can be shown at all time
var contradict = ['brush', 'tooltip'];
if (contradict.includes(config.id) && config.enabled && !state.interactionConfig[config.id].enabled) {
// only enable one interaction at a time
contradict.forEach(function (k) {
if (k !== config.id) {
interactionConfig[k] = _objectSpread(_objectSpread({}, interactionConfig[k]), {}, {
enabled: false
});
}
});
}
return _objectSpread(_objectSpread({}, state), {}, {
interactionConfig: interactionConfig
});
}
/**
* Update filter property
* @param {object} state
* @param {object} action
* @param {Number} action.idx `idx` of filter to be updated
* @param {string} action.prop `prop` of filter, e,g, `dataId`, `name`, `value`
* @param {*} action.value new value
* @param {string} action.dataId
* @param {string} action.range
* @param {object} action.histogram
* @returns {object} newState
*/
function setFilterAPIUpdater(state, action) {
var dataId = action.dataId,
prop = action.prop,
value = action.value,
_action$valueIndex = action.valueIndex,
valueIndex = _action$valueIndex === void 0 ? 0 : _action$valueIndex,
domain = action.domain,
_action$histogram = action.histogram,
histogram = _action$histogram === void 0 ? {} : _action$histogram,
idx = action.idx;
var newState = state;
var newFilter = _objectSpread(_objectSpread({}, state.filters[idx]), {}, (0, _defineProperty2["default"])({}, prop, value));
if (!histogram) {
({}), (0, _readOnlyError2["default"])("histogram");
}
var datasetId = newFilter.dataId[valueIndex];
var _applyFilterApiFieldN = (0, _filterUtils.applyFilterApiFieldName)(newFilter, state.datasets[datasetId], value, valueIndex, {
mergeDomain: false
}, histogram, domain),
updatedFilter = _applyFilterApiFieldN.filter;
if (!updatedFilter) {
return state;
}
newFilter = updatedFilter; // newState = newState.layers.map(l => {
// if (l.config.dataId === dataId) {
// layerConfigChangeUpdater(l, {
// apiCallRequest: true
// });
// }
// });
newState = _objectSpread(_objectSpread({}, newState), {}, {
filters: Object.assign((0, _toConsumableArray2["default"])(state.filters), (0, _defineProperty2["default"])({}, idx, newFilter))
});
return newState;
}
/**
* Update filter property
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.idx `idx` of filter to be updated
* @param {string} action.prop `prop` of filter, e,g, `dataId`, `name`, `value`
* @param {*} action.value new value
* @param {string} datasetId used when updating a prop (dataId, name) that can be linked to multiple datasets
* @returns {Object} nextState
* @public
*/
function setFilterUpdater(state, action) {
var idx = action.idx,
prop = action.prop,
value = action.value,
_action$valueIndex2 = action.valueIndex,
valueIndex = _action$valueIndex2 === void 0 ? 0 : _action$valueIndex2,
mapState = action.mapState,
auth = action.auth,
project = action.project;
var oldFilter = state.filters[idx];
var newFilter = (0, _utils.set)([prop], value, oldFilter);
var newState = state;
var _newFilter = newFilter,
dataId = _newFilter.dataId; // Ensuring backward compatibility
var datasetIds = Array.isArray(dataId) ? dataId : [dataId];
switch (prop) {
// TODO: Next PR for UI if we update dataId, we need to consider two cases:
// 1. dataId is empty: create a default filter
// 2. Add a new dataset id
case _filterUtils.FILTER_UPDATER_PROPS.dataId:
// if trying to update filter dataId. create an empty new filter
newFilter = (0, _filterUtils.getDefaultFilter)(dataId);
break;
case _filterUtils.FILTER_UPDATER_PROPS.name:
// we are supporting the current functionality
// TODO: Next PR for UI filter name will only update filter name but it won't have side effects
// we are gonna use pair of datasets and fieldIdx to update the filter
var datasetId = newFilter.dataId[valueIndex];
var _applyFilterFieldName2 = (0, _filterUtils.applyFilterFieldName)(newFilter, state.datasets[datasetId], value, valueIndex, {
mergeDomain: false
}),
updatedFilter = _applyFilterFieldName2.filter,
newDataset = _applyFilterFieldName2.dataset;
if (!updatedFilter) {
return state;
}
newFilter = updatedFilter;
newState = _objectSpread(_objectSpread({}, state), {}, {
datasets: _objectSpread(_objectSpread({}, state.datasets), {}, (0, _defineProperty2["default"])({}, datasetId, newDataset))
});
break;
case _filterUtils.FILTER_UPDATER_PROPS.layerId:
// We need to update only datasetId/s if we have added/removed layers
// - check for layerId changes (XOR works because of string values)
// if no differences between layerIds, don't do any filtering
var layerIdDifference = (0, _lodash4["default"])(newFilter.layerId, oldFilter.layerId);
var layerDataIds = (0, _lodash2["default"])(layerIdDifference.map(function (lid) {
return (0, _lodash3["default"])(state.layers.find(function (l) {
return l.id === lid;
}), ['config', 'dataId']);
}).filter(function (d) {
return d;
})); // only filter datasetsIds
datasetIds = layerDataIds; // Update newFilter dataIds
var newDataIds = (0, _lodash2["default"])(newFilter.layerId.map(function (lid) {
return (0, _lodash3["default"])(state.layers.find(function (l) {
return l.id === lid;
}), ['config', 'dataId']);
}).filter(function (d) {
return d;
}));
newFilter = _objectSpread(_objectSpread({}, newFilter), {}, {
dataId: newDataIds
}); // only filter the current dataset
break;
default:
break;
}
var enlargedFilter = state.filters.find(function (f) {
return f.enlarged;
});
if (enlargedFilter && enlargedFilter.id !== newFilter.id) {
// there should be only one enlarged filter
newFilter.enlarged = false;
} // save new filters to newState
newState = _objectSpread(_objectSpread({}, newState), {}, {
filters: Object.assign((0, _toConsumableArray2["default"])(state.filters), (0, _defineProperty2["default"])({}, idx, newFilter))
}); // if we are currently setting a prop that only requires to filter the current
// dataset we will pass only the current dataset to applyFiltersToDatasets and
// updateAllLayerDomainData otherwise we pass the all list of datasets as defined in dataId
var datasetIdsToFilter = _filterUtils.LIMITED_FILTER_EFFECT_PROPS[prop] ? (0, _utils.toArray)(datasetIds[valueIndex]) : datasetIds; // filter data
newState = _objectSpread(_objectSpread({}, newState), {}, {
datasets: (0, _filterUtils.applyFiltersToDatasets)(datasetIdsToFilter, newState.datasets, newState.filters, newState.layers)
}); // newState = updateWidgetAggregationData(newState, mapState, auth, project);
// dataId is an array
// pass only the dataset we need to update
newState = updateAllLayerDomainData(newState, datasetIdsToFilter, newFilter);
return newState;
}
/**
* Set the property of a filter plot
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.idx
* @param {Object} action.newProp key value mapping of new prop `{yAxis: 'histogram'}`
* @returns {Object} nextState
* @public
*/
var setFilterPlotUpdater = exports.setFilterPlotUpdater = function setFilterPlotUpdater(state, _ref3) {
var idx = _ref3.idx,
newProp = _ref3.newProp;
var newFilter = _objectSpread(_objectSpread({}, state.filters[idx]), newProp);
var prop = Object.keys(newProp)[0];
if (prop === 'yAxis') {
var plotType = (0, _filterUtils.getDefaultFilterPlotType)(newFilter);
if (plotType) {
newFilter = _objectSpread(_objectSpread(_objectSpread({}, newFilter), (0, _filterUtils.getFilterPlot)(_objectSpread(_objectSpread({}, newFilter), {}, {
plotType: plotType
}), state.datasets[newFilter.dataId].allData)), {}, {
plotType: plotType
});
}
}
return _objectSpread(_objectSpread({}, state), {}, {
filters: state.filters.map(function (f, i) {
return i === idx ? newFilter : f;
})
});
};
/**
* Add a new filter
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {string} action.dataId dataset `id` this new filter is associated with
* @returns {Object} nextState
* @public
*/
var addFilterUpdater = exports.addFilterUpdater = function addFilterUpdater(state, action) {
return !action.dataId ? state : _objectSpread(_objectSpread({}, state), {}, {
filters: [].concat((0, _toConsumableArray2["default"])(state.filters), [(0, _filterUtils.getDefaultFilter)(action.dataId)])
});
};
/**
* Set layer color palette ui state
* @memberof visStateUpdaters
* @param {Object} state
* @param {Object} action
* @param {Object} action.prop
* @param {Object} action.newConfig
*/
var layerColorUIChangeUpdater = exports.layerColorUIChangeUpdater = function layerColorUIChangeUpdater(state, _ref4) {
var oldLayer = _ref4.oldLayer,
prop = _ref4.prop,
newConfig = _ref4.newConfig;
var newLayer = oldLayer.updateLayerColorUI(prop, newConfig);
return _objectSpread(_objectSpread({}, state), {}, {
layers: state.layers.map(function (l) {
return l.id === oldLayer.id ? newLayer : l;
})
});
};
/**
* Start and end filter animation
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.idx idx of filter
* @returns {Object} nextState
* @public
*/
var toggleFilterAnimationUpdater = exports.toggleFilterAnimationUpdater = function toggleFilterAnimationUpdater(state, action) {
return _objectSpread(_objectSpread({}, state), {}, {
filters: state.filters.map(function (f, i) {
return i === action.idx ? _objectSpread(_objectSpread({}, f), {}, {
isAnimating: !f.isAnimating
}) : f;
})
});
};
/**
* Change filter animation speed
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.idx `idx` of filter
* @param {Number} action.speed `speed` to change it to. `speed` is a multiplier
* @returns {Object} nextState
* @public
*/
var updateFilterAnimationSpeedUpdater = exports.updateFilterAnimationSpeedUpdater = function updateFilterAnimationSpeedUpdater(state, action) {
return _objectSpread(_objectSpread({}, state), {}, {
filters: state.filters.map(function (f, i) {
return i === action.idx ? _objectSpread(_objectSpread({}, f), {}, {
speed: action.speed
}) : f;
})
});
};
/**
* Reset animation config current time to a specified value
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.value the value current time will be set to
* @returns {Object} nextState
* @public
*
*/
var updateAnimationTimeUpdater = exports.updateAnimationTimeUpdater = function updateAnimationTimeUpdater(state, _ref5) {
var value = _ref5.value;
return _objectSpread(_objectSpread({}, state), {}, {
animationConfig: _objectSpread(_objectSpread({}, state.animationConfig), {}, {
currentTime: value
})
});
};
/**
* Update animation speed with the vertical speed slider
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.speed the updated speed of the animation
* @returns {Object} nextState
* @public
*
*/
var updateLayerAnimationSpeedUpdater = exports.updateLayerAnimationSpeedUpdater = function updateLayerAnimationSpeedUpdater(state, _ref6) {
var speed = _ref6.speed;
return _objectSpread(_objectSpread({}, state), {}, {
animationConfig: _objectSpread(_objectSpread({}, state.animationConfig), {}, {
speed: speed
})
});
};
/**
* Show larger time filter at bottom for time playback (apply to time filter only)
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.idx index of filter to enlarge
* @returns {Object} nextState
* @public
*/
var enlargeFilterUpdater = exports.enlargeFilterUpdater = function enlargeFilterUpdater(state, action) {
var isEnlarged = state.filters[action.idx].enlarged;
return _objectSpread(_objectSpread({}, state), {}, {
filters: state.filters.map(function (f, i) {
f.enlarged = !isEnlarged && i === action.idx;
return f;
})
});
};
/**
* Remove a filter
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.idx index of filter to b e removed
* @returns {Object} nextState
* @public
*/
var removeFilterUpdater = exports.removeFilterUpdater = function removeFilterUpdater(state, action) {
var idx = action.idx,
mapState = action.mapState,
auth = action.auth,
project = action.project;
var dataId = state.filters[idx].dataId;
var newFilters = [].concat((0, _toConsumableArray2["default"])(state.filters.slice(0, idx)), (0, _toConsumableArray2["default"])(state.filters.slice(idx + 1, state.filters.length)));
var filter = state.filters[idx];
var filteredDatasets = (0, _filterUtils.applyFiltersToDatasets)(dataId, state.datasets, newFilters, state.layers);
var newState = _objectSpread(_objectSpread({}, state), {}, {
filters: newFilters,
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
features: filter.type !== _filterUtils.FILTER_TYPES.polygon ? state.editor.features : state.editor.features.filter(function (f) {
return f.id !== filter.value.id;
}),
selectedFeature: null
})
}); // call layers api to update data when a filter is removed
var layers = newState.layers.map(function (layer) {
if (layer.dataId === dataId) {
layer.config.apiCallRequest === true;
}
return layer;
});
newState = _objectSpread(_objectSpread({}, newState), {}, {
layers: layers
});
newState = (0, _utils.set)(['datasets'], filteredDatasets, newState);
return updateAllLayerDomainData(newState, dataId);
};
var addWidgetUpdater = exports.addWidgetUpdater = function addWidgetUpdater(state, action) {
var defaultDataset = Object.keys(state.datasets)[0];
var newWidget = new _widgets.Widget(_objectSpread({
isVisible: true,
isConfigActive: true,
dataId: defaultDataset
}, action.props));
return !defaultDataset ? state : _objectSpread(_objectSpread({}, state), {}, {
widgets: [].concat((0, _toConsumableArray2["default"])(state.widgets), [newWidget]),
widgetOrder: [].concat((0, _toConsumableArray2["default"])(state.widgetOrder), [state.widgetOrder.length])
});
};
var removeWidgetUpdater = exports.removeWidgetUpdater = function removeWidgetUpdater(state, _ref7) {
var idx = _ref7.idx;
var widgets = state.widgets;
return _objectSpread(_objectSpread({}, state), {}, {
widgets: [].concat((0, _toConsumableArray2["default"])(widgets.slice(0, idx)), (0, _toConsumableArray2["default"])(widgets.slice(idx + 1, widgets.length))),
widgetOrder: state.widgetOrder.filter(function (i) {
return i !== idx;
}).map(function (pid) {
return pid > idx ? pid - 1 : pid;
})
});
};
var reorderWidgetUpdater = exports.reorderWidgetUpdater = function reorderWidgetUpdater(state, _ref8) {
var order = _ref8.order;
return _objectSpread(_objectSpread({}, state), {}, {
widgetOrder: order
});
};
/**
* Add a new layer
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.props - new layer props
* @returns {Object} nextState
* @public
*/
var addLayerUpdater = exports.addLayerUpdater = function addLayerUpdater(state, action) {
var defaultDataset = Object.keys(state.datasets)[0];
var newLayer = new _layers.Layer(_objectSpread({
isVisible: true,
isConfigActive: true,
dataId: defaultDataset
}, action.props));
return _objectSpread(_objectSpread({}, state), {}, {
layers: [].concat((0, _toConsumableArray2["default"])(state.layers), [newLayer]),
layerData: [].concat((0, _toConsumableArray2["default"])(state.layerData), [{}]),
layerOrder: [].concat((0, _toConsumableArray2["default"])(state.layerOrder), [state.layerOrder.length]),
splitMaps: (0, _splitMapUtils.addNewLayersToSplitMap)(state.splitMaps, newLayer)
});
};
/**
* remove layer
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number} action.idx index of layer to b e removed
* @returns {Object} nextState
* @public
*/
var removeLayerUpdater = exports.removeLayerUpdater = function removeLayerUpdater(state, _ref9) {
var idx = _ref9.idx;
var layers = state.layers,
layerData = state.layerData,
clicked = state.clicked,
hoverInfo = state.hoverInfo;
var layerToRemove = state.layers[idx];
var newMaps = (0, _splitMapUtils.removeLayerFromSplitMaps)(state.splitMaps, layerToRemove);
var newState = _objectSpread(_objectSpread({}, state), {}, {
layers: [].concat((0, _toConsumableArray2["default"])(layers.slice(0, idx)), (0, _toConsumableArray2["default"])(layers.slice(idx + 1, layers.length))),
layerData: [].concat((0, _toConsumableArray2["default"])(layerData.slice(0, idx)), (0, _toConsumableArray2["default"])(layerData.slice(idx + 1, layerData.length))),
layerOrder: state.layerOrder.filter(function (i) {
return i !== idx;
}).map(function (pid) {
return pid > idx ? pid - 1 : pid;
}),
clicked: layerToRemove.isLayerHovered(clicked) ? undefined : clicked,
hoverInfo: layerToRemove.isLayerHovered(hoverInfo) ? undefined : hoverInfo,
splitMaps: newMaps // TODO: update filters, create helper to remove layer form filter (remove layerid and dataid) if mapped
});
return updateAnimationDomain(newState);
};
/**
* Reorder layer
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Array<Number>} action.order an array of layer indexes
* @returns {Object} nextState
* @public
*/
var reorderLayerUpdater = exports.reorderLayerUpdater = function reorderLayerUpdater(state, _ref10) {
var order = _ref10.order;
return _objectSpread(_objectSpread({}, state), {}, {
layerOrder: order
});
};
/**
* Remove a dataset and all layers, filters, tooltip configs that based on it
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {string} action.key dataset id
* @returns {Object} nextState
* @public
*/
var removeDatasetUpdater = exports.removeDatasetUpdater = function removeDatasetUpdater(state, action) {
// extract dataset key
var datasetKey = action.key;
var datasets = state.datasets; // check if dataset is present
if (!datasets[datasetKey]) {
return state;
}
/* eslint-disable no-unused-vars */
var layers = state.layers,
widgets = state.widgets,
_state$datasets = state.datasets,
dataset = _state$datasets[datasetKey],
newDatasets = (0, _objectWithoutProperties2["default"])(_state$datasets, [datasetKey].map(_toPropertyKey));
/* eslint-enable no-unused-vars */
var indexes = layers.reduce(function (listOfIndexes, layer, index) {
if (layer.config.dataId === datasetKey) {
listOfIndexes.push(index);
}
return listOfIndexes;
}, []);
var widgetIndexes = widgets.reduce(function (listOfIndexes, widget, index) {
if (widget.config.dataId === datasetKey) {
listOfIndexes.push(index);
}
return listOfIndexes;
}, []); // remove layers and datasets
var _indexes$reduce = indexes.reduce(function (_ref11, idx) {
var currentState = _ref11.newState,
indexCounter = _ref11.indexCounter;
var currentIndex = idx - indexCounter;
currentState = removeLayerUpdater(currentState, {
idx: currentIndex
});
indexCounter++;
return {
newState: currentState,
indexCounter: indexCounter
};
}, {
newState: _objectSpread(_objectSpread({}, state), {}, {
datasets: newDatasets
}),
indexCounter: 0
}),
newState = _indexes$reduce.newState; // remove widgets
// newState = {
// ...newState,
// widgets: widgetIndexes.map(idx => [
// ...widgets.slice(0, idx),
// ...widgets.slice(idx + 1, widgets.length)
// ])
// };
// const widgets = state.widgets.filter(
// widget => widget.config.dataId !== datasetKey
// );
var _widgetIndexes$reduce = widgetIndexes.reduce(function (_ref12, idx) {
var state = _ref12.finalState,
indexCounter = _ref12.indexCounter;
var currentIndex = idx - indexCounter;
state = removeWidgetUpdater(state, {
idx: currentIndex
});
indexCounter++;
return {
finalState: state,
indexCounter: indexCounter
};
}, {
finalState: _objectSpread({}, newState),
indexCounter: 0
}),
finalState = _widgetIndexes$reduce.finalState; // remove filters
var filters = state.filters.filter(function (filter) {
return !datasetKey.includes(filter.dataId);
}); // update interactionConfig
var interactionConfig = state.interactionConfig;
var _interactionConfig = interactionConfig,
tooltip = _interactionConfig.tooltip;
if (tooltip) {
var config = tooltip.config;
/* eslint-disable no-unused-vars */
var _config$fieldsToShow2 = config.fieldsToShow,
fields = _config$fieldsToShow2[datasetKey],
fieldsToShow = (0, _objectWithoutProperties2["default"])(_config$fieldsToShow2, [datasetKey].map(_toPropertyKey));
/* eslint-enable no-unused-vars */
interactionConfig = _objectSpread(_objectSpread({}, interactionConfig), {}, {
tooltip: _objectSpread(_objectSpread({}, tooltip), {}, {
config: _objectSpread(_objectSpread({}, config), {}, {
fieldsToShow: fieldsToShow
})
})
});
}
return _objectSpread(_objectSpread({}, finalState), {}, {
filters: filters,
interactionConfig: interactionConfig
});
};
/**
* update layer blending mode
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {string} action.mode one of `additive`, `normal` and `subtractive`
* @returns {Object} nextState
* @public
*/
var updateLayerBlendingUpdater = exports.updateLayerBlendingUpdater = function updateLayerBlendingUpdater(state, action) {
return _objectSpread(_objectSpread({}, state), {}, {
layerBlending: action.mode
});
};
/**
* Display dataset table in a modal
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {string} action.dataId dataset id to show in table
* @returns {Object} nextState
* @public
*/
var showDatasetTableUpdater = exports.showDatasetTableUpdater = function showDatasetTableUpdater(state, action) {
return _objectSpread(_objectSpread({}, state), {}, {
editingDataset: action.dataId
});
};
/**
* reset visState to initial State
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @returns {Object} nextState
* @public
*/
var resetMapConfigUpdater = exports.resetMapConfigUpdater = function resetMapConfigUpdater(state) {
return _objectSpread(_objectSpread(_objectSpread({}, INITIAL_VIS_STATE), state.initialState), {}, {
initialState: state.initialState
});
};
/**
* Propagate `visState` reducer with a new configuration. Current config will be override.
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.payload map config to be propagated
* @param {Object} action.payload.config map config to be propagated
* @param {Object} action.payload.option {keepExistingConfig: true | false}
* @returns {Object} nextState
* @public
*/
var receiveMapConfigUpdater = exports.receiveMapConfigUpdater = function receiveMapConfigUpdater(state, _ref13) {
var _ref13$payload = _ref13.payload,
_ref13$payload$config = _ref13$payload.config,
config = _ref13$payload$config === void 0 ? {} : _ref13$payload$config,
_ref13$payload$option = _ref13$payload.options,
options = _ref13$payload$option === void 0 ? {} : _ref13$payload$option;
if (!config.visState) {
return state;
}
var _config$visState = config.visState,
filters = _config$visState.filters,
layers = _config$visState.layers,
widgets = _config$visState.widgets,
interactionConfig = _config$visState.interactionConfig,
layerBlending = _config$visState.layerBlending,
splitMaps = _config$visState.splitMaps,
animationConfig = _config$visState.animationConfig;
var keepExistingConfig = options.keepExistingConfig; // reset config if keepExistingConfig is falsy
var mergedState = !keepExistingConfig ? resetMapConfigUpdater(state) : state;
mergedState = (0, _visStateMerger.mergeFilters)(mergedState, filters); // console.log('After MergeFilters', mergedState);
mergedState = (0, _visStateMerger.mergeLayers)(mergedState, layers); // console.log('After MergeLayers', mergedState);
mergedState = (0, _visStateMerger.mergeInteractions)(mergedState, interactionConfig);
mergedState = (0, _visStateMerger.mergeLayerBlending)(mergedState, layerBlending);
mergedState = (0, _visStateMerger.mergeSplitMaps)(mergedState, splitMaps);
mergedState = (0, _visStateMerger.mergeAnimationConfig)(mergedState, animationConfig);
mergedState = (0, _visStateMerger.mergeWidgets)(mergedState, widgets);
return mergedState;
};
/**
* Trigger layer hover event with hovered object
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.info Object hovered, returned by deck.gl
* @returns {Object} nextState
* @public
*/
var layerHoverUpdater = exports.layerHoverUpdater = function layerHoverUpdater(state, action) {
return _objectSpread(_objectSpread({}, state), {}, {
hoverInfo: action.info
});
};
/**
* Trigger layer click event with clicked object
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Object} action.info Object clicked, returned by deck.gl
* @returns {Object} nextState
* @public
*/
var layerClickUpdater = exports.layerClickUpdater = function layerClickUpdater(state, action) {
return _objectSpread(_objectSpread({}, state), {}, {
mousePos: state.interactionConfig.coordinate.enabled ? _objectSpread(_objectSpread({}, state.mousePos), {}, {
pinned: state.mousePos.pinned ? null : (0, _lodash["default"])(state.mousePos)
}) : state.mousePos,
clicked: action.info && action.info.picked ? action.info : null
});
};
/**
* Trigger map click event, unselect clicked object
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @returns {Object} nextState
* @public
*/
var mapClickUpdater = exports.mapClickUpdater = function mapClickUpdater(state) {
return _objectSpread(_objectSpread({}, state), {}, {
clicked: null
});
};
var mouseMoveUpdater = exports.mouseMoveUpdater = function mouseMoveUpdater(state, _ref14) {
var evt = _ref14.evt;
if (Object.values(state.interactionConfig).some(function (config) {
return config.enabled;
})) {
return _objectSpread(_objectSpread({}, state), {}, {
mousePos: _objectSpread(_objectSpread({}, state.mousePos), {}, {
mousePosition: (0, _toConsumableArray2["default"])(evt.point),
coordinate: (0, _toConsumableArray2["default"])(evt.lngLat)
})
});
}
return state;
};
/**
* Toggle visibility of a layer for a split map
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Number|undefined} action.payload index of the split map
* @returns {Object} nextState
* @public
*/
var toggleSplitMapUpdater = exports.toggleSplitMapUpdater = function toggleSplitMapUpdater(state, action) {
return state.splitMaps && state.splitMaps.length === 0 ? _objectSpread(_objectSpread({}, state), {}, {
// maybe we should use an array to store state for a single map as well
// if current maps length is equal to 0 it means that we are about to split the view
splitMaps: (0, _splitMapUtils.computeSplitMapLayers)(state.layers)
}) : closeSpecificMapAtIndex(state, action);
};
/**
* Toggle visibility of a layer in a split map
* @memberof visStateUpdaters
* @param {Object} state
* @param {Object} action
* @param {Number} action.mapIndex index of the split map
* @param {string} action.layerId id of the layer
* @returns {Object} nextState
* @public
*/
var toggleLayerForMapUpdater = exports.toggleLayerForMapUpdater = function toggleLayerForMapUpdater(state, _ref15) {
var mapIndex = _ref15.mapIndex,
layerId = _ref15.layerId;
var splitMaps = state.splitMaps;
return _objectSpread(_objectSpread({}, state), {}, {
splitMaps: splitMaps.map(function (sm, i) {
return i === mapIndex ? _objectSpread(_objectSpread({}, splitMaps[i]), {}, {
layers: _objectSpread(_objectSpread({}, splitMaps[i].layers), {}, (0, _defineProperty2["default"])({}, layerId, !splitMaps[i].layers[layerId]))
}) : sm;
})
});
};
/**
* Add new dataset to `visState`, with option to load a map config along with the datasets
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Array<Object>|Object} action.datasets - ***required** datasets can be a dataset or an array of datasets
* Each dataset object needs to have `info` and `data` property.
* @param {Object} action.datasets.info -info of a dataset
* @param {string} action.datasets.info.id - id of this dataset. If config is defined, `id` should matches the `dataId` in config.
* @param {string} action.datasets.info.label - A display name of this dataset
* @param {Object} action.datasets.data - ***required** The data object, in a tabular format with 2 properties `fields` and `rows`
* @param {Array<Object>} action.datasets.data.fields - ***required** Array of fields,
* @param {string} action.datasets.data.fields.name - ***required** Name of the field,
* @param {Array<Array>} action.datasets.data.rows - ***required** Array of rows, in a tabular format with `fields` and `rows`
* @param {Object} action.options option object `{centerMap: true, keepExistingConfig: false}`
* @param {Object} action.config map config
* @returns {Object} nextState
* @public
*/
/* eslint-disable max-statements */
var updateVisDataUpdater = exports.updateVisDataUpdater = function updateVisDataUpdater(state, action) {
// datasets can be a single data entries or an array of multiple data entries
var config = action.config,
options = action.options;
var datasets = Array.isArray(action.datasets) ? action.datasets : [action.datasets];
var newDateEntries = datasets.reduce(function (accu, _ref16) {
var _ref16$info = _ref16.info,
info = _ref16$info === void 0 ? {} : _ref16$info,
data = _ref16.data;
return _objectSpread(_objectSpread({}, accu), (0, _datasetUtils.createNewDataEntry)({
info: info,
data: data
}, state.datasets) || {});
}, {});
if (!Object.keys(newDateEntries).length) {
return state;
} // apply config if passed from action
var previousState = config ? receiveMapConfigUpdater(state, {
payload: {
config: config,
options: options
}
}) : state;
var stateWithNewData = _objectSpread(_objectSpread({}, previousState), {}, {
datasets: _objectSpread(_objectSpread({}, previousState.datasets), newDateEntries)
}); // previously saved config before data loaded
var _stateWithNewData$fil = stateWithNewData.filterToBeMerged,
filterToBeMerged = _stateWithNewData$fil === void 0 ? [] : _stateWithNewData$fil,
_stateWithNewData$lay = stateWithNewData.layerToBeMerged,
layerToBeMerged = _stateWithNewData$lay === void 0 ? [] : _stateWithNewData$lay,
_stateWithNewData$wid = stateWithNewData.widgetToBeMerged,
widgetToBeMerged = _stateWithNewData$wid === void 0 ? [] : _stateWithNewData$wid,
_stateWithNewData$int = stateWithNewData.interactionToBeMerged,
interactionToBeMerged = _stateWithNewData$int === void 0 ? {} : _stateWithNewData$int,
_stateWithNewData$spl = stateWithNewData.splitMapsToBeMerged,
splitMapsToBeMerged = _stateWithNewData$spl === void 0 ? [] : _stateWithNewData$spl; // merge state with saved layers
// make sure layers are merged first
var mergedState = (0, _visStateMerger.mergeLayers)(stateWithNewData, layerToBeMerged); // merge state with saved filters
mergedState = (0, _visStateMerger.mergeFilters)(mergedState, filterToBeMerged); // merge state with saved splitMaps
mergedState = (0, _visStateMerger.mergeSplitMaps)(mergedState, splitMapsToBeMerged);
var newLayers = mergedState.layers.filter(function (l) {
return l.config.dataId in newDateEntries;
});
if (!newLayers.length) {
// no layer merged, find defaults
var result = addDefaultLayers(mergedState, newDateEntries); // const result = mergedState;
mergedState = result.state;
newLayers = result.newLayers;
} // if (mergedState.widgets.length === state.widgets.length) {
// mergedState = addDefaultWidget(mergedState, newDateEntries);
// }
if (mergedState.splitMaps.length) {
// if map is split, add new layers to splitMaps
newLayers = mergedState.layers.filter(function (l) {
return l.config.dataId in newDateEntries;
});
mergedState = _objectSpread(_objectSpread({}, mergedState), {}, {
splitMaps: (0, _splitMapUtils.addNewLayersToSplitMap)(mergedState.splitMaps, newLayers)
});
} // console.log(mergedState);
// merge state with saved interactions
mergedState = (0, _visStateMerger.mergeInteractions)(mergedState, interactionToBeMerged); // merge state with saved widgets
mergedState = (0, _visStateMerger.mergeWidgets)(mergedState, widgetToBeMerged); // if no tooltips merged add default tooltips
Object.keys(newDateEntries).forEach(function (dataId) {
var tooltipFields = mergedState.interactionConfig.tooltip.config.fieldsToShow[dataId];
if (!Array.isArray(tooltipFields) || !tooltipFields.length) {
mergedState = addDefaultTooltips(mergedState, newDateEntries[dataId]);
}
});
var updatedState = updateAllLayerDomainData(mergedState, Object.keys(newDateEntries)); // register layer animation domain,
// need to be called after layer data is calculated
updatedState = updateAnimationDomain(updatedState);
return updatedState;
};
/* eslint-enable max-statements */
/**
* Hide an existing layers from custom map layer objects
* @param state
* @param widget
* @returns {[*,*]} Maps of custom layer objects
*/
function toggleWidgetFromSplitMaps(state, layer) {
// console.log('0');
return state.splitMaps.map(function (settings) {
var widgets = settings.widgets;
var newWidgets = _objectSpread(_objectSpread({}, widgets), {}, (0, _defineProperty2["default"])({}, widget.id, generateLayerMetaForSplitViews(widget)));
return _objectSpread(_objectSpread({}, settings), {}, {
widgets: newWidgets
});
});
}
/**
* When a user clicks on the specific map closing icon
* the application will close the selected map
* and will merge the remaining one with the global state
* TODO: i think in the future this action should be called merge map layers with global settings
* @param {Object} state `visState`
* @param {Object} action action
* @returns {Object} nextState
*/
function closeSpecificMapAtIndex(state, action) {
// retrieve layers meta data from the remaining map that we need to keep
var indexToRetrieve = 1 - action.payload;
var mapLayers = state.splitMaps[indexToRetrieve].layers;
var layers = state.layers; // update layer visibility
var newLayers = layers.map(function (layer) {
return !mapLayers[layer.id] && layer.config.isVisible ? layer.updateLayerConfig({
// if layer.id is not in mapLayers, it should be inVisible
isVisible: false
}) : layer;
}); // delete map
return _objectSpread(_objectSpread({}, state), {}, {
layers: newLayers,
splitMaps: []
});
}
/**
* Trigger file loading dispatch `addDataToMap` if succeed, or `loadFilesErr` if failed
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {Array<Object>} action.files array of fileblob
* @returns {Object} nextState
* @public
*/
var loadFilesUpdater = exports.loadFilesUpdater = function loadFilesUpdater(state, action) {
var files = action.files;
var filesToLoad = files.map(function (fileBlob) {
return (0, _fileUtils.processFileToLoad)(fileBlob);
}); // reader -> parser -> augment -> receiveVisData
// console.log('LOAD_FILE_TASK inside loadFilesUpdater', LOAD_FILE_TASK);
var loadFileTasks = [_tasks["default"].all(filesToLoad.map(_tasks2.LOAD_FILE_TASK)).bimap(function (results) {
var data = results.reduce(function (f, c) {
return {
// using concat here because the current datasets could be an array or a single item
datasets: f.datasets.concat(c.datasets),
// we need to deep merge this thing unless we find a better solution
// this case will only happen if we allow to load multiple keplergl json files
config: _objectSpread(_objectSpread({}, f.config), c.config || {})
};
}, {
datasets: [],
config: {},
options: {
centerMap: true
}
});
return (0, _actions.addDataToMap)(data);
}, _visStateActions.loadFilesErr)]; // console.log('loadFileTasks inside loadFilesUpdater', loadFileTasks);
return (0, _tasks.withTask)(state, loadFileTasks);
};
/**
* Trigger loading file error
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {Object} action action
* @param {*} action.error
* @returns {Object} nextState
* @public
*/
var loadFilesErrUpdater = exports.loadFilesErrUpdater = function loadFilesErrUpdater(state, _ref17) {
var error = _ref17.error;
return _objectSpread(_objectSpread({}, state), {}, {
fileLoading: false,
fileLoadingErr: error
});
};
/**
*
* @param {object} state `visState`
* @param {object} action action
* @param {Text<Object>} action.URL url of mapBox vector tiles
* @returns {Object} nextState
* @public
*/
function loadURLUpdater(state, action) {
var URL = action.URL,
range = action.range;
var newLayer;
if (URL) {
var dataId = (0, _utils.generateHashId)(4);
var datasets = (0, _defineProperty2["default"])({}, dataId, {
URL: URL,
populationRange: range,
fields: [// {
// format: '',
// id: '_geojson',
// name: '_geojson',
// tableFieldIndex: 1,
// type: 'geojson'
// },
// {
// format: '',
// id: 'population',
// name: 'Population',
// tableFieldIndex: 2,
// type: 'integer'
// }
],
id: dataId,
externalData: true,
color: (0, _datasetUtils.getNewDatasetColor)(state.datasets),
label: 'population data'
});
state = _objectSpread(_objectSpread(_objectSpread({}, state), state.datasets), {}, {
datasets: datasets
});
newLayer = new state.layerClasses.MVT({
isVisible: true,
isConfigActive: true,
dataId: dataId,
url: URL
}); // newLayer = new state.layerClasses['mvt']();
}
return _objectSpread(_objectSpread({}, state), {}, {
layers: [].concat((0, _toConsumableArray2["default"])(state.layers), [newLayer]),
layerData: [].concat((0, _toConsumableArray2["default"])(state.layerData), [{}]),
layerOrder: [].concat((0, _toConsumableArray2["default"])(state.layerOrder), [state.layerOrder.length]),
splitMaps: (0, _splitMapUtils.addNewLayersToSplitMap)(state.splitMaps, newLayer)
});
}
var loadEDLinkData = exports.loadEDLinkData = function loadEDLinkData(state, action) {
var data = action.data,
dataId = action.dataId,
idx = action.idx;
var dataset = (0, _dataProcessor.processGeojson)(data);
var validatedData = (0, _dataProcessor.validateInputData)(dataset);
if (!validatedData) {
return state;
}
var allData = validatedData.rows;
var fields = validatedData.fields.map(function (f, i) {
return _objectSpread(_objectSpread({}, f), {}, {
id: f.name,
tableFieldIndex: i + 1
});
}); // const idx = state.layers.findIndex(l => l.config.dataId === dataId);
if (state.filters.length) {
var filters = state.filters.map(function (filter) {
if (filter.dataId === dataId) {
var field = dataset.fields[filter.fieldIdx];
filter = _objectSpread(_objectSpread(_objectSpread({}, filter), getFilterProps(allData, field)), {}, {
value: filter.value
});
}
return filter;
});
state = _objectSpread(_objectSpread({}, state), {}, {
filters: filters
});
} // filters.map(f =>{
// var filter = f
// const field = dataset.fields[f.fieldIdx]
// filter ={
// ...filter,
// ...getFilterProps(dataset[allData],field)
// }
// })
// dataset = {
// ...dataset[dataId], allData: allData,
// fields: fields,
// data: allData.slice(), filteredIndex: allData.map((_, i) => i),
// filteredIndexForDomain: allData.map((_, i) => i),
// fieldPairs: findPointFieldPairs(fields)
// }
// let layerData =Object.assign(state.layerData);
// layerData[idx] = data.features;
var stateWithNewData = _objectSpread(_objectSpread({}, state), {}, {
datasets: _objectSpread(_objectSpread({}, state.datasets), {}, (0, _defineProperty2["default"])({}, dataId, _objectSpread(_objectSpread(_objectSpread({}, state.datasets[dataId]), {}, {
allData: allData,
fields: fields
}, (0, _filterUtils.filterTileLayerData)(allData, state.filters, state.layers.filter(function (l) {
return l.config.dataId === dataId;
}))), {}, {
fieldPairs: (0, _datasetUtils.findPointFieldPairs)(fields)
}))),
layerData: state.layerData.map(function (lyrData, i) {
return i === idx ? [data.features] : lyrData;
})
});
return stateWithNewData;
};
/**
* helper function to update All layer domain and layer data of state
*
* @param {object} state
* @param {string} datasets
* @returns {object} state
*/
function addDefaultLayers(state, datasets) {
var defaultLayers = Object.values(datasets).reduce(function (accu, dataset) {
return [].concat((0, _toConsumableArray2["default"])(accu), (0, _toConsumableArray2["default"])((0, _layerUtils.findDefaultLayer)(dataset, state.layerClasses) || []));
}, []);
return {
state: _objectSpread(_objectSpread({}, state), {}, {
layers: [].concat((0, _toConsumableArray2["default"])(state.layers), (0, _toConsumableArray2["default"])(defaultLayers)),
layerOrder: [].concat((0, _toConsumableArray2["default"])(defaultLayers.map(function (_, i) {
return state.layers.length + i;
})), (0, _toConsumableArray2["default"])(state.layerOrder))
}),
newLayers: defaultLayers
};
}
/**
* helper function to update All layer domain and layer data of state
*
* @param {object} state
* @param {string} datasets
* @returns {object} state
*/
// export function addDefaultWidget(state, datasets) {
// const defaultWidget = Object.values(datasets).reduce(
// (accu, dataset) => [
// ...accu,
// ...(findDefaultLayer(dataset, state.widgetClasses) || [])
// ],
// []
// );
// return {
// ...state,
// widgets: [...state.widgets, ...defaultWidget],
// layerOrder: [
// // put new layers on top of old ones
// ...defaultWidget.map((_, i) => state.widgets.length + i),
// ...state.widgetOrder
// ]
// };
// }
/**
* helper function to find default tooltips
* @param {Object} state
* @param {Object} dataset
* @returns {Object} nextState
*/
function addDefaultTooltips(state, dataset) {
var tooltipFields = (0, _interactionUtils.findFieldsToShow)(dataset);
return _objectSpread(_objectSpread({}, state), {}, {
interactionConfig: _objectSpread(_objectSpread({}, state.interactionConfig), {}, {
tooltip: _objectSpread(_objectSpread({}, state.interactionConfig.tooltip), {}, {
config: {
// find default fields to show in tooltip
fieldsToShow: _objectSpread(_objectSpread({}, state.interactionConfig.tooltip.config.fieldsToShow), tooltipFields)
}
})
})
});
}
/**
* Helper function to update layer domains for an array of datasets
* @param {Object} state
* @param {Array|Array<string>} dataId dataset id or array of dataset ids
* @param {Object} newFilter if is called by setFilter, the filter that has changed
* @returns {Object} nextState
*/
function updateAllLayerDomainData(state, dataId, newFilter) {
var dataIds = typeof dataId === 'string' ? [dataId] : dataId;
var newLayers = [];
var newLayerData = [];
state.layers.forEach(function (oldLayer, i) {
if (oldLayer.config.dataId && dataIds.includes(oldLayer.config.dataId)) {
// No need to recalculate layer domain if filter has fixed domain
var newLayer;
if (oldLayer.type === 'boundary') {
newLayer = newFilter && newFilter.fixedDomain ? oldLayer : oldLayer.updateLayerDomain(state.datasets[oldLayer.config.dataId], state.layerData[i], newFilter);
} else {
newLayer = newFilter && newFilter.fixedDomain ? oldLayer : oldLayer.updateLayerDomain(state.datasets[oldLayer.config.dataId], newFilter);
}
var _calculateLayerData5 = (0, _layerUtils.calculateLayerData)(newLayer, state, state.layerData[i]),
layerData = _calculateLayerData5.layerData,
layer = _calculateLayerData5.layer; // console.log('LayerData', layerData);
newLayers.push(layer);
newLayerData.push(layerData);
} else {
newLayers.push(oldLayer);
newLayerData.push(state.layerData[i]);
}
});
var newState = _objectSpread(_objectSpread({}, state), {}, {
layers: newLayers,
layerData: newLayerData
});
return newState;
}
function updateAnimationDomain(state) {
// merge all animatable layer domain and update global config
var animatableLayers = state.layers.filter(function (l) {
return l.config.isVisible && l.config.animation && l.config.animation.enabled && Array.isArray(l.animationDomain);
});
if (!animatableLayers.length) {
return _objectSpread(_objectSpread({}, state), {}, {
animationConfig: defaultAnimationConfig
});
}
var mergedDomain = animatableLayers.reduce(function (accu, layer) {
return [Math.min(accu[0], layer.animationDomain[0]), Math.max(accu[1], layer.animationDomain[1])];
}, [Number(Infinity), -Infinity]);
return _objectSpread(_objectSpread({}, state), {}, {
animationConfig: _objectSpread(_objectSpread({}, state.animationConfig), {}, {
currentTime: (0, _filterUtils.isInRange)(state.animationConfig.currentTime, mergedDomain) ? state.animationConfig.currentTime : mergedDomain[0],
domain: mergedDomain
})
});
}
/**
* helper function to recalculte widget aggregationData everytime layerData is updated
*
* @param {object} state
* @returns {object} state
*/
function updateWidgetAggregationData(state, mapState, auth, project) {
var widgets = state.widgets;
var newWidgets = [];
widgets.map(function (w) {
var _w$calculateAggregati = w.calculateAggregationData(w, state, mapState, auth, project),
newWidget = _w$calculateAggregati.newWidget;
newWidgets.push(newWidget);
});
return _objectSpread(_objectSpread({}, state), {}, {
widgets: newWidgets
});
}
/**
* helper function to update states
*
* @param {object} state
* @returns {object} state
*/
function updateStateWithLayerDataUpdater(state, action) {
var collected = action.collected;
var newLayer = action.layer;
var idx = state.layers.findIndex(function (l) {
return l.id === newLayer.id;
});
var _calculateLayerDataAf = (0, _layerUtils.calculateLayerDataAfterAPICall)(newLayer, state, state.layerData[idx], collected, {
sameData: true
}),
layerData = _calculateLayerDataAf.layerData,
layer = _calculateLayerDataAf.layer;
return _objectSpread(_objectSpread({}, state), {}, {
layerData: state.layerData.map(function (lyrData, i) {
return i === idx ? layerData : lyrData;
})
});
}
/**
* helper function for async API call
*
* @param {object} state
* @returns {object} data
*/
function apiCallData(state, action) {
// console.log(state, action);
var layer = action.layer;
var allData = state.datasets[layer.config.dataId].allData; // console.log(allData);
return state;
}
/**
* update dataset last run time
* @memberof visStateUpdaters
* @param state
* @param {Object} payload
* @return {Object} nextState
*/
function updateDatasetInfo(state, action) {
var dataId = action.dataId,
updatedAt = action.updatedAt;
var newState = _objectSpread(_objectSpread({}, state), {}, {
datasets: _objectSpread(_objectSpread({}, state.datasets), {}, (0, _defineProperty2["default"])({}, dataId, _objectSpread(_objectSpread({}, state.datasets[dataId]), {}, {
lastUpdatedAt: updatedAt
})))
});
return newState;
}
/**
* Update the status of the editor
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {string} mode to set to editor to
* @return {Object} nextState
*/
var setEditorModeUpdater = exports.setEditorModeUpdater = function setEditorModeUpdater(state, _ref18) {
var mode = _ref18.mode;
return _objectSpread(_objectSpread({}, state), {}, {
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
mode: mode,
selectedFeature: null
})
});
}; // const featureToFilterValue = (feature) => ({...feature, id: feature.id});
/**
* Update editor features
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {[Object]} features to store
* @return {Object} nextState
*/
function setFeaturesUpdater(state, _ref19) {
var _ref19$features = _ref19.features,
features = _ref19$features === void 0 ? [] : _ref19$features,
auth = _ref19.auth,
project = _ref19.project,
mapState = _ref19.mapState;
var lastFeature = features.length && features[features.length - 1];
var newState = _objectSpread(_objectSpread({}, state), {}, {
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
// only save none filter features to editor
features: features.filter(function (f) {
return !(0, _filterUtils.getFilterIdInFeature)(f);
}),
mode: lastFeature && lastFeature.properties.isClosed ? _defaultSettings.EDITOR_MODES.EDIT : state.editor.mode
})
}); // Retrieve existing feature
var selectedFeature = state.editor.selectedFeature; // If no feature is selected we can simply return since no operations
if (!selectedFeature) {
return newState;
} // TODO: check if the feature has changed
var feature = features.find(function (f) {
return f.id === selectedFeature.id;
}); // if feature is part of a filter
var filterId = feature && (0, _filterUtils.getFilterIdInFeature)(feature);
if (filterId) {
var featureValue = (0, _filterUtils.featureToFilterValue)(feature, filterId);
var filterIdx = state.filters.findIndex(function (fil) {
return fil.id === filterId;
});
return setFilterUpdater(newState, {
idx: filterIdx,
prop: 'value',
value: featureValue,
auth: auth,
project: project,
mapState: mapState
});
}
return newState;
}
/**
* Set the current selected feature
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {[Object]} features to store
* @return {Object} nextState
*/
var setSelectedFeatureUpdater = exports.setSelectedFeatureUpdater = function setSelectedFeatureUpdater(state, _ref20) {
var feature = _ref20.feature;
return _objectSpread(_objectSpread({}, state), {}, {
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
selectedFeature: feature
})
});
};
/**
* Delete existing feature from filters
* @memberof visStateUpdaters
* @param {Object} state `visState`
* @param {string} selectedFeatureId feature to delete
* @return {Object} nextState
*/
function deleteFeatureUpdater(state, _ref21) {
var feature = _ref21.feature;
if (!feature) {
return state;
}
var newState = _objectSpread(_objectSpread({}, state), {}, {
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
selectedFeature: null
})
});
if ((0, _filterUtils.getFilterIdInFeature)(feature)) {
var filterIdx = newState.filters.findIndex(function (f) {
return f.id === (0, _filterUtils.getFilterIdInFeature)(feature);
});
return filterIdx > -1 ? removeFilterUpdater(newState, {
idx: filterIdx
}) : newState;
} // modify editor object
var newEditor = _objectSpread(_objectSpread({}, state.editor), {}, {
features: state.editor.features.filter(function (f) {
return f.id !== feature.id;
}),
selectedFeature: null
});
return _objectSpread(_objectSpread({}, state), {}, {
editor: newEditor
});
}
/**
* Toggle feature as layer filter
* @memberof visStateUpdaters
* @param state
* @param {Object} payload
* @param {string} payload.featureId
* @param {Object} payload.layer
* @return {Object} nextState
*/
function setPolygonFilterLayerUpdater(state, payload) {
var layer = payload.layer,
feature = payload.feature,
auth = payload.auth,
project = payload.project,
mapState = payload.mapState;
var filterId = (0, _filterUtils.getFilterIdInFeature)(feature); // let newFilter = null;
var filterIdx;
var newLayerId = [layer.id];
var newState = state; // If polygon filter already exists, we need to find out if the current layer is already included
if (filterId) {
filterIdx = state.filters.findIndex(function (f) {
return f.id === filterId;
});
if (!state.filters[filterIdx]) {
// what if filter doesn't exist?... not possible.
// because features in the editor is passed in from filters and editors.
// but we will move this feature back to editor just in case
var noneFilterFeature = _objectSpread(_objectSpread({}, feature), {}, {
properties: _objectSpread(_objectSpread({}, feature.properties), {}, {
filterId: null
})
});
return _objectSpread(_objectSpread({}, state), {}, {
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
features: [].concat((0, _toConsumableArray2["default"])(state.editor.features), [noneFilterFeature]),
selectedFeature: noneFilterFeature
})
});
}
var _ref23 = state.filters[filterIdx] || [],
layerId = _ref23.layerId;
var isLayerIncluded = layerId.includes(layer.id);
var filter = state.filters[filterIdx];
newLayerId = isLayerIncluded ? // if layer is included, remove it
filter.layerId.filter(function (l) {
return l !== layer.id;
}) : [].concat((0, _toConsumableArray2["default"])(filter.layerId), [layer.id]);
} else {
// if we haven't create the polygon filter, create it
var newFilter = (0, _filterUtils.generatePolygonFilter)([], feature);
filterIdx = state.filters.length; // add feature, remove feature from eidtor
newState = _objectSpread(_objectSpread({}, state), {}, {
filters: [].concat((0, _toConsumableArray2["default"])(state.filters), [newFilter]),
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
features: state.editor.features.filter(function (f) {
return f.id !== feature.id;
}),
selectedFeature: newFilter.value
})
});
}
return setFilterUpdater(newState, {
idx: filterIdx,
prop: 'layerId',
value: newLayerId,
auth: auth,
project: project,
mapState: mapState
});
}
/**
* Update editor
* @param {Object} state `visState`
* @param visible
* @return {Object} nextState
*/
function toggleEditorVisibility(state, _ref24) {
var visible = _ref24.visible;
return _objectSpread(_objectSpread({}, state), {}, {
editor: _objectSpread(_objectSpread({}, state.editor), {}, {
visible: !state.editor.visible
})
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy92aXMtc3RhdGUtdXBkYXRlcnMuanMiXSwibmFtZXMiOlsiZGVmYXVsdEFuaW1hdGlvbkNvbmZpZyIsImRvbWFpbiIsImN1cnJlbnRUaW1lIiwic3BlZWQiLCJERUZBVUxUX0VESVRPUiIsIm1vZGUiLCJFRElUT1JfTU9ERVMiLCJEUkFXX1BPTFlHT04iLCJmZWF0dXJlcyIsInNlbGVjdGVkRmVhdHVyZSIsInZpc2libGUiLCJJTklUSUFMX1ZJU19TVEFURSIsImxheWVycyIsImxheWVyRGF0YSIsImxheWVyVG9CZU1lcmdlZCIsImxheWVyT3JkZXIiLCJmaWx0ZXJzIiwiZmlsdGVyVG9CZU1lcmdlZCIsIndpZGdldHMiLCJ3aWRnZXRUb0JlTWVyZ2VkIiwid2lkZ2V0T3JkZXIiLCJkYXRhc2V0cyIsImVkaXRpbmdEYXRhc2V0IiwidW5kZWZpbmVkIiwiaW50ZXJhY3Rpb25Db25maWciLCJpbnRlcmFjdGlvblRvQmVNZXJnZWQiLCJsYXllckJsZW5kaW5nIiwiaG92ZXJJbmZvIiwiY2xpY2tlZCIsIm1vdXNlUG9zIiwic3BsaXRNYXBzIiwibGF5ZXJDbGFzc2VzIiwiTGF5ZXJDbGFzc2VzIiwid2lkZ2V0Q2xhc3NlcyIsIldpZGdldENsYXNzZXMiLCJhbmltYXRpb25Db25maWciLCJlZGl0b3IiLCJ1cGRhdGVTdGF0ZVdpdGhXaWRnZXRBbmREYXRhIiwic3RhdGUiLCJ3aWRnZXQiLCJpZHgiLCJtYXAiLCJ3ZGd0IiwiaSIsIndpZGdldENvbmZpZ0NoYW5nZVVwZGF0ZXIiLCJhY3Rpb24iLCJvbGRXaWRnZXQiLCJhdXRoIiwicHJvamVjdCIsIm1hcFN0YXRlIiwibmV3Q29uZmlnIiwieCIsImZpbmRJbmRleCIsInciLCJpZCIsInByb3BzIiwiT2JqZWN0Iiwia2V5cyIsIm5ld1dpZGdldCIsInVwZGF0ZVdpZGdldENvbmZpZyIsIm5ld1N0YXRlIiwidG9nZ2xlV2lkZ2V0RnJvbVNwbGl0TWFwcyIsIndpZGdldFR5cGVDaGFuZ2VVcGRhdGVyIiwibmV3VHlwZSIsIm9sZElkIiwiQ29uc29sZSIsImVycm9yIiwiY29uZmlnIiwiYWdncmVnYXRlZERhdGEiLCJhc3NpZ25Db25maWdUb1dpZGdldCIsInZpc0NvbmZpZ1NldHRpbmdzIiwidXBkYXRlU3RhdGVXaXRoTGF5ZXJBbmREYXRhIiwibGF5ZXIiLCJseXIiLCJkIiwidXBkYXRlU3RhdGVPbkxheWVyVmlzaWJpbGl0eUNoYW5nZSIsImxlbmd0aCIsImlzVmlzaWJsZSIsImFuaW1hdGlvbiIsImVuYWJsZWQiLCJ1cGRhdGVBbmltYXRpb25Eb21haW4iLCJsYXllckNvbmZpZ0NoYW5nZVVwZGF0ZXIiLCJvbGRMYXllciIsImwiLCJuZXdMYXllciIsInVwZGF0ZUxheWVyQ29uZmlnIiwic2hvdWxkQ2FsY3VsYXRlTGF5ZXJEYXRhIiwib2xkTGF5ZXJEYXRhIiwidXBkYXRlTGF5ZXJEYXRhUmVzdWx0Iiwic2FtZURhdGEiLCJhZGRPclJlbW92ZVRleHRMYWJlbHMiLCJuZXdGaWVsZHMiLCJ0ZXh0TGFiZWwiLCJuZXdUZXh0TGFiZWwiLCJzbGljZSIsImN1cnJlbnRGaWVsZHMiLCJ0bCIsImZpZWxkIiwibmFtZSIsImZpbHRlciIsImFkZEZpZWxkcyIsImYiLCJpbmNsdWRlcyIsImRlbGV0ZUZpZWxkcyIsImZpbmQiLCJmZCIsIkRFRkFVTFRfVEVYVF9MQUJFTCIsImFmIiwidXBkYXRlVGV4dExhYmVsUHJvcEFuZFZhbHVlIiwicHJvcCIsInZhbHVlIiwiaGFzT3duUHJvcGVydHkiLCJzcGxpY2UiLCJsYXllclRleHRMYWJlbENoYW5nZVVwZGF0ZXIiLCJsYXllclR5cGVDaGFuZ2VVcGRhdGVyIiwiYXBpQ2FsbFJlcXVlc3QiLCJhc3NpZ25Db25maWdUb0xheWVyIiwiZGF0YUlkIiwiZGF0YXNldCIsInVwZGF0ZUxheWVyRG9tYWluIiwic2V0dGluZ3MiLCJvbGRMYXllck1hcCIsIm90aGVyTGF5ZXJzIiwibGF5ZXJWaXN1YWxDaGFubmVsQ2hhbmdlVXBkYXRlciIsImNoYW5uZWwiLCJ1cGRhdGVMYXllclZpc3VhbENoYW5uZWwiLCJsYXllclZpc0NvbmZpZ0NoYW5nZVVwZGF0ZXIiLCJuZXdWaXNDb25maWciLCJ2aXNDb25maWciLCJpbnRlcmFjdGlvbkNvbmZpZ0NoYW5nZVVwZGF0ZXIiLCJjb250cmFkaWN0IiwiZm9yRWFjaCIsImsiLCJzZXRGaWx0ZXJBUElVcGRhdGVyIiwidmFsdWVJbmRleCIsImhpc3RvZ3JhbSIsIm5ld0ZpbHRlciIsImRhdGFzZXRJZCIsIm1lcmdlRG9tYWluIiwidXBkYXRlZEZpbHRlciIsImFzc2lnbiIsInNldEZpbHRlclVwZGF0ZXIiLCJvbGRGaWx0ZXIiLCJkYXRhc2V0SWRzIiwiQXJyYXkiLCJpc0FycmF5IiwiRklMVEVSX1VQREFURVJfUFJPUFMiLCJuZXdEYXRhc2V0IiwibGF5ZXJJZCIsImxheWVySWREaWZmZXJlbmNlIiwibGF5ZXJEYXRhSWRzIiwibGlkIiwibmV3RGF0YUlkcyIsImVubGFyZ2VkRmlsdGVyIiwiZW5sYXJnZWQiLCJkYXRhc2V0SWRzVG9GaWx0ZXIiLCJMSU1JVEVEX0ZJTFRFUl9FRkZFQ1RfUFJPUFMiLCJ1cGRhdGVBbGxMYXllckRvbWFpbkRhdGEiLCJzZXRGaWx0ZXJQbG90VXBkYXRlciIsIm5ld1Byb3AiLCJwbG90VHlwZSIsImFsbERhdGEiLCJhZGRGaWx0ZXJVcGRhdGVyIiwibGF5ZXJDb2xvclVJQ2hhbmdlVXBkYXRlciIsInVwZGF0ZUxheWVyQ29sb3JVSSIsInRvZ2dsZUZpbHRlckFuaW1hdGlvblVwZGF0ZXIiLCJpc0FuaW1hdGluZyIsInVwZGF0ZUZpbHRlckFuaW1hdGlvblNwZWVkVXBkYXRlciIsInVwZGF0ZUFuaW1hdGlvblRpbWVVcGRhdGVyIiwidXBkYXRlTGF5ZXJBbmltYXRpb25TcGVlZFVwZGF0ZXIiLCJlbmxhcmdlRmlsdGVyVXBkYXRlciIsImlzRW5sYXJnZWQiLCJyZW1vdmVGaWx0ZXJVcGRhdGVyIiwibmV3RmlsdGVycyIsImZpbHRlcmVkRGF0YXNldHMiLCJ0eXBlIiwiRklMVEVSX1RZUEVTIiwicG9seWdvbiIsImFkZFdpZGdldFVwZGF0ZXIiLCJkZWZhdWx0RGF0YXNldCIsIldpZGdldCIsImlzQ29uZmlnQWN0aXZlIiwicmVtb3ZlV2lkZ2V0VXBkYXRlciIsInBpZCIsInJlb3JkZXJXaWRnZXRVcGRhdGVyIiwib3JkZXIiLCJhZGRMYXllclVwZGF0ZXIiLCJMYXllciIsInJlbW92ZUxheWVyVXBkYXRlciIsImxheWVyVG9SZW1vdmUiLCJuZXdNYXBzIiwiaXNMYXllckhvdmVyZWQiLCJyZW9yZGVyTGF5ZXJVcGRhdGVyIiwicmVtb3ZlRGF0YXNldFVwZGF0ZXIiLCJkYXRhc2V0S2V5Iiwia2V5IiwibmV3RGF0YXNldHMiLCJpbmRleGVzIiwicmVkdWNlIiwibGlzdE9mSW5kZXhlcyIsImluZGV4IiwicHVzaCIsIndpZGdldEluZGV4ZXMiLCJjdXJyZW50U3RhdGUiLCJpbmRleENvdW50ZXIiLCJjdXJyZW50SW5kZXgiLCJmaW5hbFN0YXRlIiwidG9vbHRpcCIsImZpZWxkc1RvU2hvdyIsImZpZWxkcyIsInVwZGF0ZUxheWVyQmxlbmRpbmdVcGRhdGVyIiwic2hvd0RhdGFzZXRUYWJsZVVwZGF0ZXIiLCJyZXNldE1hcENvbmZpZ1VwZGF0ZXIiLCJpbml0aWFsU3RhdGUiLCJyZWNlaXZlTWFwQ29uZmlnVXBkYXRlciIsInBheWxvYWQiLCJvcHRpb25zIiwidmlzU3RhdGUiLCJrZWVwRXhpc3RpbmdDb25maWciLCJtZXJnZWRTdGF0ZSIsImxheWVySG92ZXJVcGRhdGVyIiwiaW5mbyIsImxheWVyQ2xpY2tVcGRhdGVyIiwiY29vcmRpbmF0ZSIsInBpbm5lZCIsInBpY2tlZCIsIm1hcENsaWNrVXBkYXRlciIsIm1vdXNlTW92ZVVwZGF0ZXIiLCJldnQiLCJ2YWx1ZXMiLCJzb21lIiwibW91c2VQb3NpdGlvbiIsInBvaW50IiwibG5nTGF0IiwidG9nZ2xlU3BsaXRNYXBVcGRhdGVyIiwiY2xvc2VTcGVjaWZpY01hcEF0SW5kZXgiLCJ0b2dnbGVMYXllckZvck1hcFVwZGF0ZXIiLCJtYXBJbmRleCIsInNtIiwidXBkYXRlVmlzRGF0YVVwZGF0ZXIiLCJuZXdEYXRlRW50cmllcyIsImFjY3UiLCJkYXRhIiwicHJldmlvdXNTdGF0ZSIsInN0YXRlV2l0aE5ld0RhdGEiLCJzcGxpdE1hcHNUb0JlTWVyZ2VkIiwibmV3TGF5ZXJzIiwicmVzdWx0IiwiYWRkRGVmYXVsdExheWVycyIsInRvb2x0aXBGaWVsZHMiLCJhZGREZWZhdWx0VG9vbHRpcHMiLCJ1cGRhdGVkU3RhdGUiLCJuZXdXaWRnZXRzIiwiZ2VuZXJhdGVMYXllck1ldGFGb3JTcGxpdFZpZXdzIiwiaW5kZXhUb1JldHJpZXZlIiwibWFwTGF5ZXJzIiwibG9hZEZpbGVzVXBkYXRlciIsImZpbGVzIiwiZmlsZXNUb0xvYWQiLCJmaWxlQmxvYiIsImxvYWRGaWxlVGFza3MiLCJUYXNrIiwiYWxsIiwiTE9BRF9GSUxFX1RBU0siLCJiaW1hcCIsInJlc3VsdHMiLCJjIiwiY29uY2F0IiwiY2VudGVyTWFwIiwibG9hZEZpbGVzRXJyIiwibG9hZEZpbGVzRXJyVXBkYXRlciIsImZpbGVMb2FkaW5nIiwiZmlsZUxvYWRpbmdFcnIiLCJsb2FkVVJMVXBkYXRlciIsIlVSTCIsInJhbmdlIiwicG9wdWxhdGlvblJhbmdlIiwiZXh0ZXJuYWxEYXRhIiwiY29sb3IiLCJsYWJlbCIsIk1WVCIsInVybCIsImxvYWRFRExpbmtEYXRhIiwidmFsaWRhdGVkRGF0YSIsInJvd3MiLCJ0YWJsZUZpZWxkSW5kZXgiLCJmaWVsZElkeCIsImdldEZpbHRlclByb3BzIiwiZmllbGRQYWlycyIsImx5ckRhdGEiLCJkZWZhdWx0TGF5ZXJzIiwiXyIsImRhdGFJZHMiLCJuZXdMYXllckRhdGEiLCJmaXhlZERvbWFpbiIsImFuaW1hdGFibGVMYXllcnMiLCJhbmltYXRpb25Eb21haW4iLCJtZXJnZWREb21haW4iLCJNYXRoIiwibWluIiwibWF4IiwiTnVtYmVyIiwiSW5maW5pdHkiLCJ1cGRhdGVXaWRnZXRBZ2dyZWdhdGlvbkRhdGEiLCJjYWxjdWxhdGVBZ2dyZWdhdGlvbkRhdGEiLCJ1cGRhdGVTdGF0ZVdpdGhMYXllckRhdGFVcGRhdGVyIiwiY29sbGVjdGVkIiwiYXBpQ2FsbERhdGEiLCJ1cGRhdGVEYXRhc2V0SW5mbyIsInVwZGF0ZWRBdCIsImxhc3RVcGRhdGVkQXQiLCJzZXRFZGl0b3JNb2RlVXBkYXRlciIsInNldEZlYXR1cmVzVXBkYXRlciIsImxhc3RGZWF0dXJlIiwicHJvcGVydGllcyIsImlzQ2xvc2VkIiwiRURJVCIsImZlYXR1cmUiLCJmaWx0ZXJJZCIsImZlYXR1cmVWYWx1ZSIsImZpbHRlcklkeCIsImZpbCIsInNldFNlbGVjdGVkRmVhdHVyZVVwZGF0ZXIiLCJkZWxldGVGZWF0dXJlVXBkYXRlciIsIm5ld0VkaXRvciIsInNldFBvbHlnb25GaWx0ZXJMYXllclVwZGF0ZXIiLCJuZXdMYXllcklkIiwibm9uZUZpbHRlckZlYXR1cmUiLCJpc0xheWVySW5jbHVkZWQiLCJ0b2dnbGVFZGl0b3JWaXNpYmlsaXR5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUdBOztBQUdBOztBQUNBOztBQUdBOztBQUNBOztBQWlCQTs7QUFNQTs7QUFRQTs7QUFVQTs7QUFFQTs7QUFPQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9DQTtBQUNBOztBQUNBOztBQUVPLElBQU1BLHNCQUFzQixvQ0FBRztBQUNwQ0MsRUFBQUEsTUFBTSxFQUFFLElBRDRCO0FBRXBDQyxFQUFBQSxXQUFXLEVBQUUsSUFGdUI7QUFHcENDLEVBQUFBLEtBQUssRUFBRTtBQUg2QixDQUEvQjtBQU1BLElBQU1DLGNBQWMsNEJBQUc7QUFDNUJDLEVBQUFBLElBQUksRUFBRUMsOEJBQWFDLFlBRFM7QUFF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Q3ZSLElBQUFBLElBQUksRUFBSkEsSUFKZ0M7QUFLaENDLElBQUFBLE9BQU8sRUFBUEEsT0FMZ0M7QUFNaENDLElBQUFBLFFBQVEsRUFBUkE7QUFOZ0MsR0FBWCxDQUF2QjtBQVFEO0FBRUQ7Ozs7Ozs7O0FBTU8sU0FBU3dSLHNCQUFULENBQWdDblMsS0FBaEMsVUFBa0Q7QUFBQSxNQUFWNUIsT0FBVSxVQUFWQSxPQUFVO0FBQ3ZELHlDQUNLNEIsS0FETDtBQUVFRixJQUFBQSxNQUFNLGtDQUNERSxLQUFLLENBQUNGLE1BREw7QUFFSjFCLE1BQUFBLE9BQU8sRUFBRSxDQUFDNEIsS0FBSyxDQUFDRixNQUFOLENBQWExQjtBQUZuQjtBQUZSO0FBT0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjMgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQge2NvbnNvbGUgYXMgQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQgVGFzaywge2Rpc2FibGVTdGFja0NhcHR1cmluZywgd2l0aFRhc2t9IGZyb20gJ3JlYWN0LXBhbG0vdGFza3MnO1xuaW1wb3J0IGNsb25lRGVlcCBmcm9tICdsb2Rhc2guY2xvbmVkZWVwJztcbmltcG9ydCB1bmlxIGZyb20gJ2xvZGFzaC51bmlxJztcbmltcG9ydCBnZXQgZnJvbSAnbG9kYXNoLmdldCc7XG5pbXBvcnQgeG9yIGZyb20gJ2xvZGFzaC54b3InO1xuaW1wb3J0IHtzZXQsIHRvQXJyYXl9IGZyb20gJ3V0aWxzL3V0aWxzJztcblxuLy8gVGFza3NcbmltcG9ydCB7TE9BRF9GSUxFX1RBU0t9IGZyb20gJ3Rhc2tzL3Rhc2tzJztcblxuLy8gQWN0aW9uc1xuaW1wb3J0IHtsb2FkRmlsZXNFcnJ9IGZyb20gJ2FjdGlvbnMvdmlzLXN0YXRlLWFjdGlvbnMnO1xuaW1wb3J0IHthZGREYXRhVG9NYXB9IGZyb20gJ2FjdGlvbnMnO1xuXG4vLyBVdGlsc1xuaW1wb3J0IHtnZXREZWZhdWx0SW50ZXJhY3Rpb24sIGZpbmRGaWVsZHNUb1Nob3d9IGZyb20gJ3V0aWxzL2ludGVyYWN0aW9uLXV0aWxzJztcbmltcG9ydCB7XG4gIEZJTFRFUl9UWVBFUyxcbiAgRklMVEVSX1VQREFURVJfUFJPUFMsXG4gIExJTUlURURfRklMVEVSX0VGRkVDVF9QUk9QUyxcbiAgYXBwbHlGaWx0ZXJBcGlGaWVsZE5hbWUsXG4gIGFwcGx5RmlsdGVyRmllbGROYW1lLFxuICBhcHBseUZpbHRlcnNUb0RhdGFzZXRzLFxuICBnZW5lcmF0ZVBvbHlnb25GaWx0ZXIsXG4gIGdldERlZmF1bHRGaWx0ZXIsXG4gIGdldEZpbHRlclBsb3QsXG4gIGdldERlZmF1bHRGaWx0ZXJQbG90VHlwZSxcbiAgaXNJblJhbmdlLFxuICBnZXRGaWx0ZXJJZEluRmVhdHVyZSxcbiAgZmVhdHVyZVRvRmlsdGVyVmFsdWUsXG4gIHVwZGF0ZUZpbHRlckRhdGFJZFxufSBmcm9tICd1dGlscy9maWx0ZXItdXRpbHMnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVOZXdEYXRhRW50cnksXG4gIGZpbmRQb2ludEZpZWxkUGFpcnMsXG4gIGdldE5ld0RhdGFzZXRDb2xvclxufSBmcm9tICd1dGlscy9kYXRhc2V0LXV0aWxzJztcblxuaW1wb3J0IHtcbiAgZmluZERlZmF1bHRMYXllcixcbiAgY2FsY3VsYXRlTGF5ZXJEYXRhLFxuICBjYWxjdWxhdGVMYXllckRhdGFBZnRlckFQSUNhbGxcbn0gZnJvbSAndXRpbHMvbGF5ZXItdXRpbHMvbGF5ZXItdXRpbHMnO1xuXG5pbXBvcnQge2ZpbHRlclRpbGVMYXllckRhdGF9IGZyb20gJ3V0aWxzL2ZpbHRlci11dGlscyc7XG5cbmltcG9ydCB7XG4gIG1lcmdlRmlsdGVycyxcbiAgbWVyZ2VMYXllcnMsXG4gIG1lcmdlSW50ZXJhY3Rpb25zLFxuICBtZXJnZUxheWVyQmxlbmRpbmcsXG4gIG1lcmdlU3BsaXRNYXBzLFxuICBtZXJnZUFuaW1hdGlvbkNvbmZpZyxcbiAgbWVyZ2VXaWRnZXRzXG59IGZyb20gJy4vdmlzLXN0YXRlLW1lcmdlcic7XG5cbmltcG9ydCBzaW1wbGlmeSBmcm9tICdzaW1wbGlmeS1nZW9qc29uJztcblxuaW1wb3J0IHtcbiAgYWRkTmV3TGF5ZXJzVG9TcGxpdE1hcCxcbiAgcmVtb3ZlTGF5ZXJGcm9tU3BsaXRNYXBzLFxuICBjb21wdXRlU3BsaXRNYXBMYXllcnNcbn0gZnJvbSAndXRpbHMvc3BsaXQtbWFwLXV0aWxzJztcbmltcG9ydCB7Z2VuZXJhdGVIYXNoSWR9IGZyb20gJ3V0aWxzL3V0aWxzJztcblxuaW1wb3J0IHtwcm9jZXNzR2VvanNvbiwgdmFsaWRhdGVJbnB1dERhdGF9IGZyb20gJ3Byb2Nlc3NvcnMvZGF0YS1wcm9jZXNzb3InO1xuXG5pbXBvcnQge0xheWVyLCBMYXllckNsYXNzZXN9IGZyb20gJ2xheWVycyc7XG5cbmltcG9ydCB7V2lkZ2V0LCBXaWRnZXRDbGFzc2VzfSBmcm9tICd3aWRnZXRzJztcblxuaW1wb3J0IHtwcm9jZXNzRmlsZVRvTG9hZH0gZnJvbSAnL3V0aWxzL2ZpbGUtdXRpbHMnO1xuaW1wb3J0IHtERUZBVUxUX1RFWFRfTEFCRUx9IGZyb20gJ2xheWVycy9sYXllci1mYWN0b3J5JztcbmltcG9ydCB7RURJVE9SX01PREVTfSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5cbi8vIHJlYWN0LXBhbG1cbi8vIGRpc2FibGUgY2FwdHVyZSBleGNlcHRpb24gZm9yIHJlYWN0LXBhbG0gY2FsbCB0byB3aXRoVGFza1xuZGlzYWJsZVN0YWNrQ2FwdHVyaW5nKCk7XG5cbi8qKlxuICogVXBkYXRlcnMgZm9yIGB2aXNTdGF0ZWAgcmVkdWNlci4gQ2FuIGJlIHVzZWQgaW4geW91ciByb290IHJlZHVjZXIgdG8gZGlyZWN0bHkgbW9kaWZ5IGtlcGxlci5nbCdzIHN0YXRlLlxuICogUmVhZCBtb3JlIGFib3V0IFtVc2luZyB1cGRhdGVyc10oLi4vYWR2YW5jZWQtdXNhZ2UvdXNpbmctdXBkYXRlcnMubWQpXG4gKlxuICogQHB1YmxpY1xuICogQGV4YW1wbGVcbiAqXG4gKiBpbXBvcnQga2VwbGVyR2xSZWR1Y2VyLCB7dmlzU3RhdGVVcGRhdGVyc30gZnJvbSAna2VwbGVyLmdsL3JlZHVjZXJzJztcbiAqIC8vIFJvb3QgUmVkdWNlclxuICogY29uc3QgcmVkdWNlcnMgPSBjb21iaW5lUmVkdWNlcnMoe1xuICogIGtlcGxlckdsOiBrZXBsZXJHbFJlZHVjZXIsXG4gKiAgYXBwOiBhcHBSZWR1Y2VyXG4gKiB9KTtcbiAqXG4gKiBjb25zdCBjb21wb3NlZFJlZHVjZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICogIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAqICAgIGNhc2UgJ0NMSUNLX0JVVFRPTic6XG4gKiAgICAgIHJldHVybiB7XG4gKiAgICAgICAgLi4uc3RhdGUsXG4gKiAgICAgICAga2VwbGVyR2w6IHtcbiAqICAgICAgICAgIC4uLnN0YXRlLmtlcGxlckdsLFxuICogICAgICAgICAgZm9vOiB7XG4gKiAgICAgICAgICAgICAuLi5zdGF0ZS5rZXBsZXJHbC5mb28sXG4gKiAgICAgICAgICAgICB2aXNTdGF0ZTogdmlzU3RhdGVVcGRhdGVycy5lbmxhcmdlRmlsdGVyVXBkYXRlcihcbiAqICAgICAgICAgICAgICAgc3RhdGUua2VwbGVyR2wuZm9vLnZpc1N0YXRlLFxuICogICAgICAgICAgICAgICB7aWR4OiAwfVxuICogICAgICAgICAgICAgKVxuICogICAgICAgICAgfVxuICogICAgICAgIH1cbiAqICAgICAgfTtcbiAqICB9XG4gKiAgcmV0dXJuIHJlZHVjZXJzKHN0YXRlLCBhY3Rpb24pO1xuICogfTtcbiAqXG4gKiBleHBvcnQgZGVmYXVsdCBjb21wb3NlZFJlZHVjZXI7XG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4vLyBjb25zdCB2aXNTdGF0ZVVwZGF0ZXJzID0gbnVsbDtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRBbmltYXRpb25Db25maWcgPSB7XG4gIGRvbWFpbjogbnVsbCxcbiAgY3VycmVudFRpbWU6IG51bGwsXG4gIHNwZWVkOiAxXG59O1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9FRElUT1IgPSB7XG4gIG1vZGU6IEVESVRPUl9NT0RFUy5EUkFXX1BPTFlHT04sXG4gIGZlYXR1cmVzOiBbXSxcbiAgc2VsZWN0ZWRGZWF0dXJlOiBudWxsLFxuICB2aXNpYmxlOiB0cnVlXG59O1xuXG4vKipcbiAqIERlZmF1bHQgaW5pdGlhbCBgdmlzU3RhdGVgXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQGNvbnN0YW50XG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtBcnJheX0gbGF5ZXJzXG4gKiBAcHJvcGVydHkge0FycmF5fSBsYXllckRhdGFcbiAqIEBwcm9wZXJ0eSB7QXJyYXl9IGxheWVyVG9CZU1lcmdlZFxuICogQHByb3BlcnR5IHtBcnJheX0gbGF5ZXJPcmRlclxuICogQHByb3BlcnR5IHtBcnJheX0gZmlsdGVyc1xuICogQHByb3BlcnR5IHtBcnJheX0gZmlsdGVyVG9CZU1lcmdlZFxuICogQHByb3BlcnR5IHtBcnJheX0gZGF0YXNldHNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBlZGl0aW5nRGF0YXNldFxuICogQHByb3BlcnR5IHtPYmplY3R9IGludGVyYWN0aW9uQ29uZmlnXG4gKiBAcHJvcGVydHkge09iamVjdH0gaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbGF5ZXJCbGVuZGluZ1xuICogQHByb3BlcnR5IHtPYmplY3R9IGhvdmVySW5mb1xuICogQHByb3BlcnR5IHtPYmplY3R9IGNsaWNrZWRcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtb3VzZVBvc1xuICogQHByb3BlcnR5IHtBcnJheX0gc3BsaXRNYXBzIC0gYSBsaXN0IG9mIG9iamVjdHMgb2YgbGF5ZXIgYXZhaWxhYmlsaXRpZXMgYW5kIHZpc2liaWxpdGllcyBmb3IgZWFjaCBtYXBcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsYXllckNsYXNzZXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBhbmltYXRpb25Db25maWdcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBlZGl0b3JcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IElOSVRJQUxfVklTX1NUQVRFID0ge1xuICAvLyBsYXllcnNcbiAgbGF5ZXJzOiBbXSxcbiAgbGF5ZXJEYXRhOiBbXSxcbiAgbGF5ZXJUb0JlTWVyZ2VkOiBbXSxcbiAgbGF5ZXJPcmRlcjogW10sXG5cbiAgLy8gZmlsdGVyc1xuICBmaWx0ZXJzOiBbXSxcbiAgZmlsdGVyVG9CZU1lcmdlZDogW10sXG5cbiAgLy8gd2lkZ2V0c1xuICB3aWRnZXRzOiBbXSxcbiAgd2lkZ2V0VG9CZU1lcmdlZDogW10sXG4gIHdpZGdldE9yZGVyOiBbXSxcblxuICAvLyBhIGNvbGxlY3Rpb24gb2YgbXVsdGlwbGUgZGF0YXNldFxuICBkYXRhc2V0czoge30sXG4gIGVkaXRpbmdEYXRhc2V0OiB1bmRlZmluZWQsXG5cbiAgaW50ZXJhY3Rpb25Db25maWc6IGdldERlZmF1bHRJbnRlcmFjdGlvbigpLFxuICBpbnRlcmFjdGlvblRvQmVNZXJnZWQ6IHVuZGVmaW5lZCxcblxuICBsYXllckJsZW5kaW5nOiAnbm9ybWFsJyxcbiAgaG92ZXJJbmZvOiB1bmRlZmluZWQsXG4gIGNsaWNrZWQ6IHVuZGVmaW5lZCxcbiAgbW91c2VQb3M6IHt9LFxuXG4gIC8vIHRoaXMgaXMgdXNlZCB3aGVuIHVzZXIgc3BsaXQgbWFwc1xuICBzcGxpdE1hcHM6IFtcbiAgICAvLyB0aGlzIHdpbGwgY29udGFpbiBhIGxpc3Qgb2Ygb2JqZWN0cyB0b1xuICAgIC8vIGRlc2NyaWJlIHRoZSBzdGF0ZSBvZiBsYXllciBhdmFpbGFiaWxpdHkgYW5kIHZpc2liaWxpdHkgZm9yIGVhY2ggbWFwXG4gICAgLy8gW1xuICAgIC8vICAge1xuICAgIC8vICAgICAgbGF5ZXJzOiB7bGF5ZXJfaWQ6IHRydWUgfCBmYWxzZX1cbiAgICAvLyAgIH1cbiAgICAvLyBdXG4gIF0sXG4gIC8vXG4gIC8vIGRlZmF1bHRzIGxheWVyIGNsYXNzZXNcbiAgbGF5ZXJDbGFzc2VzOiBMYXllckNsYXNzZXMsXG5cbiAgLy8gZGVmYXVsdCB3aWRnZXQgY2xhc3Nlc1xuICB3aWRnZXRDbGFzc2VzOiBXaWRnZXRDbGFzc2VzLFxuXG4gIC8vIGRlZmF1bHQgYW5pbWF0aW9uXG4gIC8vIHRpbWUgaW4gdW5peCB0aW1lc3RhbXAgKG1pbGxpc2Vjb25kcykgKHRoZSBudW1iZXIgb2Ygc2Vjb25kcyBzaW5jZSB0aGUgVW5peCBFcG9jaClcbiAgYW5pbWF0aW9uQ29uZmlnOiBkZWZhdWx0QW5pbWF0aW9uQ29uZmlnLFxuXG4gIGVkaXRvcjogREVGQVVMVF9FRElUT1Jcbn07XG5cbmZ1bmN0aW9uIHVwZGF0ZVN0YXRlV2l0aFdpZGdldEFuZERhdGEoc3RhdGUsIHt3aWRnZXQsIGlkeH0pIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICB3aWRnZXRzOiBzdGF0ZS53aWRnZXRzLm1hcCgod2RndCwgaSkgPT4gKGkgPT09IGlkeCA/IHdpZGdldCA6IHdkZ3QpKVxuICB9O1xufVxuXG4vKipcbiAqIENhbGxlZCB0byB1cGRhdGUgbGF5ZXIgYmFzZSBjb25maWc6IGRhdGFJZCwgbGFiZWwsIGNvbHVtbiwgaXNWaXNpYmxlXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2lkZ2V0Q29uZmlnQ2hhbmdlVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtvbGRXaWRnZXQsIGF1dGgsIHByb2plY3R9ID0gYWN0aW9uO1xuICBjb25zdCB7bWFwU3RhdGV9ID0gYWN0aW9uLm5ld0NvbmZpZztcbiAgY29uc3QgeCA9IHN0YXRlLndpZGdldHMuZmluZEluZGV4KHcgPT4gdy5pZCA9PT0gb2xkV2lkZ2V0LmlkKTtcbiAgY29uc3QgcHJvcHMgPSBPYmplY3Qua2V5cyhhY3Rpb24ubmV3Q29uZmlnKTtcbiAgYWN0aW9uLm5ld0NvbmZpZy5tYXBTdGF0ZSA/IGRlbGV0ZSBhY3Rpb24ubmV3Q29uZmlnLm1hcFN0YXRlIDogbnVsbDtcbiAgY29uc3QgbmV3V2lkZ2V0ID0gb2xkV2lkZ2V0LnVwZGF0ZVdpZGdldENvbmZpZyhhY3Rpb24ubmV3Q29uZmlnKTtcbiAgLy8gaWYgKG5ld1dpZGdldC5zaG91bGRDYWxjdWxhdGVBZ2dyZWdhdGVkRGF0YShwcm9wcykpIHtcbiAgLy8gY29uc3QgYWdncmVnYXRlZERhdGEgPSBuZXdXaWRnZXQuY2FsY3VsYXRlQWdncmVnYXRpb25EYXRhKFxuICAvLyAgIG5ld1dpZGdldCxcbiAgLy8gICBzdGF0ZS5maWx0ZXJzLFxuICAvLyAgIHN0YXRlLmRhdGFzZXRzLFxuICAvLyAgIG1hcFN0YXRlLFxuICAvLyAgIGF1dGgsXG4gIC8vICAgcHJvamVjdFxuICAvLyApO1xuXG4gIC8vIG5ld1dpZGdldC51cGRhdGVXaWRnZXRDb25mZyh7YXBpQ2FsbFJlcXVlc3Q6IHRydWV9KTtcbiAgLy8gcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aFdpZGdldEFuZERhdGEodXBkYXRlZFN0YXRlID8gdXBkYXRlZFN0YXRlIDogc3RhdGUsIHtcbiAgLy8gICB3aWRnZXQ6IG5ld1dpZGdldCxcbiAgLy8gICB4XG4gIC8vIH0pO1xuICAvLyB9XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgc3BsaXRNYXBzOlxuICAgICAgJ2lzVmlzaWJsZScgaW4gYWN0aW9uLm5ld0NvbmZpZ1xuICAgICAgICA/IHRvZ2dsZVdpZGdldEZyb21TcGxpdE1hcHMoc3RhdGUsIHdpZGdldClcbiAgICAgICAgOiBzdGF0ZS5zcGxpdE1hcHNcbiAgfTtcbiAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aFdpZGdldEFuZERhdGEobmV3U3RhdGUsIHt3aWRnZXQ6IG5ld1dpZGdldCwgeH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2lkZ2V0VHlwZUNoYW5nZVVwZGF0ZXIoc3RhdGUsIGFjdGlvbikge1xuICBjb25zdCB7b2xkV2lkZ2V0LCBuZXdUeXBlfSA9IGFjdGlvbjtcbiAgY29uc3Qgb2xkSWQgPSBvbGRXaWRnZXQuaWQ7XG4gIGNvbnN0IGlkeCA9IHN0YXRlLndpZGdldHMuZmluZEluZGV4KHcgPT4gdy5pZCA9PT0gb2xkSWQpO1xuICBpZiAoIXN0YXRlLndpZGdldENsYXNzZXNbbmV3VHlwZV0pIHtcbiAgICBDb25zb2xlLmVycm9yKGAke25ld1R5cGV9IGlzIG5vdCBhIHZhbGlkIHdpZGdldCB0eXBlYCk7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIC8vIGdldCBhIG1pbnQgd2lkZ2V0LCB3aXRoIG5ldyBpZCBhbmQgdHlwZVxuICAvLyBiZWNhdXNlIGRlY2suZ2wgdXNlcyBpZCB0byBtYXRjaCBiZXR3ZWVuIG5ldyBhbmQgb2xkIGxheWVyLlxuICAvLyBJZiB0eXBlIGhhcyBjaGFuZ2VkIGJ1dCBpZCBpcyB0aGUgc2FtZSwgaXQgd2lsbCBicmVha1xuICB2YXIgbmV3V2lkZ2V0ID0gbmV3IHN0YXRlLndpZGdldENsYXNzZXNbbmV3VHlwZV0oKTtcbiAgbmV3V2lkZ2V0LmNvbmZpZy5hZ2dyZWdhdGVkRGF0YSA9IG51bGw7XG4gIG5ld1dpZGdldC5hc3NpZ25Db25maWdUb1dpZGdldChvbGRXaWRnZXQuY29uZmlnLCBvbGRXaWRnZXQudmlzQ29uZmlnU2V0dGluZ3MpO1xuXG4gIGNvbnN0IG5ld1N0YXRlID0gc3RhdGU7XG4gIGNvbnN0IHdpZGdldCA9IG5ld1dpZGdldDtcbiAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aFdpZGdldEFuZERhdGEobmV3U3RhdGUsIHt3aWRnZXQsIGlkeH0pO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdGF0ZVdpdGhMYXllckFuZERhdGEoc3RhdGUsIHtsYXllckRhdGEsIGxheWVyLCBpZHh9KSB7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJzOiBzdGF0ZS5sYXllcnMubWFwKChseXIsIGkpID0+IChpID09PSBpZHggPyBsYXllciA6IGx5cikpLFxuICAgIGxheWVyRGF0YTogbGF5ZXJEYXRhXG4gICAgICA/IHN0YXRlLmxheWVyRGF0YS5tYXAoKGQsIGkpID0+IChpID09PSBpZHggPyBsYXllckRhdGEgOiBkKSlcbiAgICAgIDogc3RhdGUubGF5ZXJEYXRhXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTdGF0ZU9uTGF5ZXJWaXNpYmlsaXR5Q2hhbmdlKHN0YXRlLCBsYXllcikge1xuICBsZXQgbmV3U3RhdGUgPSBzdGF0ZTtcbiAgaWYgKHN0YXRlLnNwbGl0TWFwcy5sZW5ndGgpIHtcbiAgICBuZXdTdGF0ZSA9IHtcbiAgICAgIC4uLnN0YXRlLFxuICAgICAgc3BsaXRNYXBzOiBsYXllci5jb25maWcuaXNWaXNpYmxlXG4gICAgICAgID8gYWRkTmV3TGF5ZXJzVG9TcGxpdE1hcChzdGF0ZS5zcGxpdE1hcHMsIGxheWVyKVxuICAgICAgICA6IHJlbW92ZUxheWVyRnJvbVNwbGl0TWFwcyhzdGF0ZS5zcGxpdE1hcHMsIGxheWVyKVxuICAgIH07XG4gIH1cblxuICBpZiAobGF5ZXIuY29uZmlnLmFuaW1hdGlvbi5lbmFibGVkKSB7XG4gICAgbmV3U3RhdGUgPSB1cGRhdGVBbmltYXRpb25Eb21haW4oc3RhdGUpO1xuICB9XG5cbiAgcmV0dXJuIG5ld1N0YXRlO1xufVxuXG4vKipcbiAqIFVwZGF0ZSBsYXllciBiYXNlIGNvbmZpZzogZGF0YUlkLCBsYWJlbCwgY29sdW1uLCBpc1Zpc2libGVcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24ub2xkTGF5ZXIgbGF5ZXIgdG8gYmUgdXBkYXRlZFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5uZXdDb25maWcgbmV3IGNvbmZpZ1xuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllckNvbmZpZ0NoYW5nZVVwZGF0ZXIoc3RhdGUsIGFjdGlvbikge1xuICBjb25zdCB7b2xkTGF5ZXJ9ID0gYWN0aW9uO1xuICBjb25zdCBpZHggPSBzdGF0ZS5sYXllcnMuZmluZEluZGV4KGwgPT4gbC5pZCA9PT0gb2xkTGF5ZXIuaWQpO1xuICBjb25zdCBwcm9wcyA9IE9iamVjdC5rZXlzKGFjdGlvbi5uZXdDb25maWcpO1xuICBsZXQgbmV3TGF5ZXIgPSBvbGRMYXllci51cGRhdGVMYXllckNvbmZpZyhhY3Rpb24ubmV3Q29uZmlnKTtcblxuICBsZXQgbGF5ZXJEYXRhO1xuXG4gIC8vIGxldCBuZXdMYXllcjtcbiAgaWYgKG5ld0xheWVyLnNob3VsZENhbGN1bGF0ZUxheWVyRGF0YShwcm9wcykpIHtcbiAgICBjb25zdCBvbGRMYXllckRhdGEgPSBzdGF0ZS5sYXllckRhdGFbaWR4XTtcbiAgICBjb25zdCB1cGRhdGVMYXllckRhdGFSZXN1bHQgPSBjYWxjdWxhdGVMYXllckRhdGEoXG4gICAgICBuZXdMYXllcixcbiAgICAgIHN0YXRlLFxuICAgICAgb2xkTGF5ZXJEYXRhLFxuICAgICAge1xuICAgICAgICBzYW1lRGF0YTogdHJ1ZVxuICAgICAgfVxuICAgICk7XG5cbiAgICBsYXllckRhdGEgPSB1cGRhdGVMYXllckRhdGFSZXN1bHQubGF5ZXJEYXRhO1xuICAgIG5ld0xheWVyID0gdXBkYXRlTGF5ZXJEYXRhUmVzdWx0LmxheWVyO1xuICB9XG5cbiAgbGV0IG5ld1N0YXRlID0gc3RhdGU7XG4gIGlmICgnaXNWaXNpYmxlJyBpbiBhY3Rpb24ubmV3Q29uZmlnKSB7XG4gICAgbmV3U3RhdGUgPSB1cGRhdGVTdGF0ZU9uTGF5ZXJWaXNpYmlsaXR5Q2hhbmdlKHN0YXRlLCBuZXdMYXllcik7XG4gIH1cblxuICByZXR1cm4gdXBkYXRlU3RhdGVXaXRoTGF5ZXJBbmREYXRhKG5ld1N0YXRlLCB7XG4gICAgbGF5ZXI6IG5ld0xheWVyLFxuICAgIGxheWVyRGF0YSxcbiAgICBpZHhcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZE9yUmVtb3ZlVGV4dExhYmVscyhuZXdGaWVsZHMsIHRleHRMYWJlbCkge1xuICBsZXQgbmV3VGV4dExhYmVsID0gdGV4dExhYmVsLnNsaWNlKCk7XG5cbiAgY29uc3QgY3VycmVudEZpZWxkcyA9IHRleHRMYWJlbFxuICAgIC5tYXAodGwgPT4gdGwuZmllbGQgJiYgdGwuZmllbGQubmFtZSlcbiAgICAuZmlsdGVyKGQgPT4gZCk7XG5cbiAgY29uc3QgYWRkRmllbGRzID0gbmV3RmllbGRzLmZpbHRlcihmID0+ICFjdXJyZW50RmllbGRzLmluY2x1ZGVzKGYubmFtZSkpO1xuICBjb25zdCBkZWxldGVGaWVsZHMgPSBjdXJyZW50RmllbGRzLmZpbHRlcihcbiAgICBmID0+ICFuZXdGaWVsZHMuZmluZChmZCA9PiBmZC5uYW1lID09PSBmKVxuICApO1xuXG4gIC8vIGRlbGV0ZVxuICBuZXdUZXh0TGFiZWwgPSBuZXdUZXh0TGFiZWwuZmlsdGVyKFxuICAgIHRsID0+IHRsLmZpZWxkICYmICFkZWxldGVGaWVsZHMuaW5jbHVkZXModGwuZmllbGQubmFtZSlcbiAgKTtcbiAgbmV3VGV4dExhYmVsID0gIW5ld1RleHRMYWJlbC5sZW5ndGggPyBbREVGQVVMVF9URVhUX0xBQkVMXSA6IG5ld1RleHRMYWJlbDtcblxuICAvLyBhZGRcbiAgbmV3VGV4dExhYmVsID0gW1xuICAgIC4uLm5ld1RleHRMYWJlbC5maWx0ZXIodGwgPT4gdGwuZmllbGQpLFxuICAgIC4uLmFkZEZpZWxkcy5tYXAoYWYgPT4gKHtcbiAgICAgIC4uLkRFRkFVTFRfVEVYVF9MQUJFTCxcbiAgICAgIGZpZWxkOiBhZlxuICAgIH0pKVxuICBdO1xuXG4gIHJldHVybiBuZXdUZXh0TGFiZWw7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVRleHRMYWJlbFByb3BBbmRWYWx1ZShpZHgsIHByb3AsIHZhbHVlLCB0ZXh0TGFiZWwpIHtcbiAgaWYgKCF0ZXh0TGFiZWxbaWR4XS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkge1xuICAgIHJldHVybiB0ZXh0TGFiZWw7XG4gIH1cblxuICBsZXQgbmV3VGV4dExhYmVsID0gdGV4dExhYmVsLnNsaWNlKCk7XG5cbiAgaWYgKHByb3AgJiYgKHZhbHVlIHx8IHRleHRMYWJlbC5sZW5ndGggPT09IDEpKSB7XG4gICAgbmV3VGV4dExhYmVsID0gdGV4dExhYmVsLm1hcCgodGwsIGkpID0+XG4gICAgICBpID09PSBpZHggPyB7Li4udGwsIFtwcm9wXTogdmFsdWV9IDogdGxcbiAgICApO1xuICB9IGVsc2UgaWYgKHByb3AgPT09ICdmaWVsZCcgJiYgdmFsdWUgPT09IG51bGwgJiYgdGV4dExhYmVsLmxlbmd0aCA+IDEpIHtcbiAgICAvLyByZW1vdmUgbGFiZWwgd2hlbiBmaWVsZCB2YWx1ZSBpcyBzZXQgdG8gbnVsbFxuICAgIG5ld1RleHRMYWJlbC5zcGxpY2UoaWR4LCAxKTtcbiAgfVxuXG4gIHJldHVybiBuZXdUZXh0TGFiZWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsYXllclRleHRMYWJlbENoYW5nZVVwZGF0ZXIoc3RhdGUsIGFjdGlvbikge1xuICBjb25zdCB7b2xkTGF5ZXIsIGlkeCwgcHJvcCwgdmFsdWV9ID0gYWN0aW9uO1xuICBjb25zdCB7dGV4dExhYmVsfSA9IG9sZExheWVyLmNvbmZpZztcblxuICBsZXQgbmV3VGV4dExhYmVsID0gdGV4dExhYmVsLnNsaWNlKCk7XG4gIGlmICghdGV4dExhYmVsW2lkeF0gJiYgaWR4ID09PSB0ZXh0TGFiZWwubGVuZ3RoKSB7XG4gICAgLy8gaWYgaWR4IGlzIHNldCB0byBsZW5ndGgsIGFkZCBlbXB0eSB0ZXh0IGxhYmVsXG4gICAgbmV3VGV4dExhYmVsID0gWy4uLnRleHRMYWJlbCwgREVGQVVMVF9URVhUX0xBQkVMXTtcbiAgfVxuXG4gIGlmIChpZHggPT09ICdhbGwnICYmIHByb3AgPT09ICdmaWVsZHMnKSB7XG4gICAgbmV3VGV4dExhYmVsID0gYWRkT3JSZW1vdmVUZXh0TGFiZWxzKHZhbHVlLCB0ZXh0TGFiZWwpO1xuICB9IGVsc2Uge1xuICAgIG5ld1RleHRMYWJlbCA9IHVwZGF0ZVRleHRMYWJlbFByb3BBbmRWYWx1ZShpZHgsIHByb3AsIHZhbHVlLCBuZXdUZXh0TGFiZWwpO1xuICB9XG5cbiAgLy8gdXBkYXRlIHRleHQgbGFiZWwgcHJvcCBhbmQgdmFsdWVcbiAgcmV0dXJuIGxheWVyQ29uZmlnQ2hhbmdlVXBkYXRlcihzdGF0ZSwge1xuICAgIG9sZExheWVyLFxuICAgIG5ld0NvbmZpZzoge3RleHRMYWJlbDogbmV3VGV4dExhYmVsfVxuICB9KTtcbn1cblxuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgdHlwZS4gUHJldmlld3MgbGF5ZXIgY29uZmlnIHdpbGwgYmUgY29waWVkIGlmIGFwcGxpY2FibGUuXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uLm9sZExheWVyIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24ubmV3VHlwZSBuZXcgdHlwZVxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllclR5cGVDaGFuZ2VVcGRhdGVyKHN0YXRlLCBhY3Rpb24pIHtcbiAgY29uc3Qge29sZExheWVyLCBuZXdUeXBlfSA9IGFjdGlvbjtcbiAgaWYgKCFvbGRMYXllcikge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuICBjb25zdCBvbGRJZCA9IG9sZExheWVyLmlkO1xuICBjb25zdCBpZHggPSBzdGF0ZS5sYXllcnMuZmluZEluZGV4KGwgPT4gbC5pZCA9PT0gb2xkSWQpO1xuICBpZiAoIXN0YXRlLmxheWVyQ2xhc3Nlc1tuZXdUeXBlXSkge1xuICAgIENvbnNvbGUuZXJyb3IoYCR7bmV3VHlwZX0gaXMgbm90IGEgdmFsaWQgbGF5ZXIgdHlwZWApO1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8vIGdldCBhIG1pbnQgbGF5ZXIsIHdpdGggbmV3IGlkIGFuZCB0eXBlXG4gIC8vIGJlY2F1c2UgZGVjay5nbCB1c2VzIGlkIHRvIG1hdGNoIGJldHdlZW4gbmV3IGFuZCBvbGQgbGF5ZXIuXG4gIC8vIElmIHR5cGUgaGFzIGNoYW5nZWQgYnV0IGlkIGlzIHRoZSBzYW1lLCBpdCB3aWxsIGJyZWFrXG4gIGNvbnN0IG5ld0xheWVyID0gbmV3IHN0YXRlLmxheWVyQ2xhc3Nlc1tuZXdUeXBlXSgpO1xuICBpZiAobmV3TGF5ZXIubmFtZSAhPT0gJ2JvdW5kYXJ5JyAmJiBuZXdMYXllci5uYW1lICE9PSAncGluY29kZScpIHtcbiAgICBvbGRMYXllci5jb25maWcuYXBpQ2FsbFJlcXVlc3QgPSB0cnVlO1xuICB9XG4gIG5ld0xheWVyLmFzc2lnbkNvbmZpZ1RvTGF5ZXIob2xkTGF5ZXIuY29uZmlnLCBvbGRMYXllci52aXNDb25maWdTZXR0aW5ncyk7XG5cbiAgaWYgKG5ld0xheWVyLmNvbmZpZy5kYXRhSWQpIHtcbiAgICBjb25zdCBkYXRhc2V0ID0gc3RhdGUuZGF0YXNldHNbbmV3TGF5ZXIuY29uZmlnLmRhdGFJZF07XG4gICAgbmV3TGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oZGF0YXNldCk7XG4gIH1cblxuICBjb25zdCB7bGF5ZXJEYXRhLCBsYXllcn0gPSBjYWxjdWxhdGVMYXllckRhdGEobmV3TGF5ZXIsIHN0YXRlKTtcbiAgbGV0IG5ld1N0YXRlID0gdXBkYXRlU3RhdGVXaXRoTGF5ZXJBbmREYXRhKHN0YXRlLCB7bGF5ZXJEYXRhLCBsYXllciwgaWR4fSk7XG5cbiAgaWYgKGxheWVyLmNvbmZpZy5hbmltYXRpb24uZW5hYmxlZCB8fCBvbGRMYXllci5jb25maWcuYW5pbWF0aW9uLmVuYWJsZWQpIHtcbiAgICBuZXdTdGF0ZSA9IHVwZGF0ZUFuaW1hdGlvbkRvbWFpbihuZXdTdGF0ZSk7XG4gIH1cblxuICAvLyB1cGRhdGUgd2lkZ2V0cyBsYXllciBpZFxuICAvLyBpZiAoc3RhdGUud2lkZ2V0cykge1xuICAvLyAgIHN0YXRlLndpZGdldHMubWFwKHdpZGdldCA9PiB7XG4gIC8vICAgICBjb25zdCB7Y29uZmlnfSA9IHdpZGdldDtcbiAgLy8gICAgIGNvbnN0IHtzZWxlY3RlZExheWVyfSA9IGNvbmZpZztcbiAgLy8gICAgIGlmICh3aWRnZXQudHlwZSAmJiBzZWxlY3RlZExheWVyLmlkID09PSBvbGRJZCkge1xuICAvLyAgICAgICB3aWRnZXQudXBkYXRlV2lkZ2V0Q29uZmlnKHtcbiAgLy8gICAgICAgICBzZWxlY3RlZExheWVyOiB7Li4uc2VsZWN0ZWRMYXllciwgaWQ6IG5ld0xheWVyLmlkfVxuICAvLyAgICAgICB9KTtcbiAgLy8gICAgIH1cbiAgLy8gICB9KTtcbiAgLy8gfVxuXG4gIC8vIHVwZGF0ZSBzcGxpdE1hcCBsYXllciBpZFxuICBpZiAoc3RhdGUuc3BsaXRNYXBzLmxlbmd0aCkge1xuICAgIG5ld1N0YXRlID0ge1xuICAgICAgLi4ubmV3U3RhdGUsXG4gICAgICBzcGxpdE1hcHM6IG5ld1N0YXRlLnNwbGl0TWFwcy5tYXAoc2V0dGluZ3MgPT4ge1xuICAgICAgICBjb25zdCB7W29sZElkXTogb2xkTGF5ZXJNYXAsIC4uLm90aGVyTGF5ZXJzfSA9IHNldHRpbmdzLmxheWVycztcbiAgICAgICAgcmV0dXJuIG9sZElkIGluIHNldHRpbmdzLmxheWVyc1xuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAuLi5zZXR0aW5ncyxcbiAgICAgICAgICAgICAgbGF5ZXJzOiB7XG4gICAgICAgICAgICAgICAgLi4ub3RoZXJMYXllcnMsXG4gICAgICAgICAgICAgICAgW2xheWVyLmlkXTogb2xkTGF5ZXJNYXBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDogc2V0dGluZ3M7XG4gICAgICB9KVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gbmV3U3RhdGU7XG59XG5cbi8qKlxuICogVXBkYXRlIGxheWVyIHZpc3VhbCBjaGFubmVsXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uLm9sZExheWVyIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24ubmV3Q29uZmlnIG5ldyB2aXN1YWwgY2hhbm5lbCBjb25maWdcbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24uY2hhbm5lbCBjaGFubmVsIHRvIGJlIHVwZGF0ZWRcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJWaXN1YWxDaGFubmVsQ2hhbmdlVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtvbGRMYXllciwgbmV3Q29uZmlnLCBjaGFubmVsfSA9IGFjdGlvbjtcbiAgY29uc3QgZGF0YXNldCA9IHN0YXRlLmRhdGFzZXRzW29sZExheWVyLmNvbmZpZy5kYXRhSWRdO1xuXG4gIGNvbnN0IGlkeCA9IHN0YXRlLmxheWVycy5maW5kSW5kZXgobCA9PiBsLmlkID09PSBvbGRMYXllci5pZCk7XG4gIGNvbnN0IG5ld0xheWVyID0gb2xkTGF5ZXIudXBkYXRlTGF5ZXJDb25maWcobmV3Q29uZmlnKTtcblxuICBuZXdMYXllci51cGRhdGVMYXllclZpc3VhbENoYW5uZWwoZGF0YXNldCwgY2hhbm5lbCk7XG5cbiAgY29uc3Qgb2xkTGF5ZXJEYXRhID0gc3RhdGUubGF5ZXJEYXRhW2lkeF07XG4gIGNvbnN0IHtsYXllckRhdGEsIGxheWVyfSA9IGNhbGN1bGF0ZUxheWVyRGF0YShuZXdMYXllciwgc3RhdGUsIG9sZExheWVyRGF0YSwge1xuICAgIHNhbWVEYXRhOiB0cnVlXG4gIH0pO1xuICAvLyBsZXQgZGF0YSA9IGxheWVyLmF4aW9zQXBpQ2FsbCgpO1xuICAvLyBpZiAobGF5ZXIudHlwZSA9PT0gJ2JvdW5kYXJ5Jykge1xuICAvLyAgIGRhdGEudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgLy8gICAgIC8vIGNvbnN0IHRlc3REYXRhID0gbGF5ZXIuZm9ybWF0TGF5ZXIoKTtcbiAgLy8gICAgIHZhciB7bGF5ZXJEYXRhLCBsYXllcn0gPSBjYWxjdWxhdGVMYXllckRhdGFBZnRlckFQSUNhbGwoXG4gIC8vICAgICAgIG5ld0xheWVyLFxuICAvLyAgICAgICBzdGF0ZSxcbiAgLy8gICAgICAgbGF5ZXJEYXRhLFxuICAvLyAgICAgICByZXN1bHRcbiAgLy8gICAgICk7XG4gIC8vICAgICBsYXllckRhdGEgPSB7XG4gIC8vICAgICAgIC4uLmxheWVyRGF0YSxcbiAgLy8gICAgICAgcmVzdWx0XG4gIC8vICAgICB9O1xuICAvLyAgICAgbmV3TGF5ZXJzW2ldID0gbGF5ZXI7XG4gIC8vICAgICBuZXdMYXllckRhdGFzW2ldID0gbGF5ZXJEYXRhO1xuICAvLyAgICAgcmV0dXJuIHtcbiAgLy8gICAgICAgLi4uc3RhdGUsXG4gIC8vICAgICAgIGxheWVyczogbmV3TGF5ZXJzLFxuICAvLyAgICAgICBsYXllckRhdGE6IG5ld0xheWVyRGF0YXNcbiAgLy8gICAgIH07XG4gIC8vICAgfSk7XG4gIC8vIH1cblxuICByZXR1cm4gdXBkYXRlU3RhdGVXaXRoTGF5ZXJBbmREYXRhKHN0YXRlLCB7bGF5ZXJEYXRhLCBsYXllciwgaWR4fSk7XG59XG5cbi8qKlxuICogVXBkYXRlIGxheWVyIGB2aXNDb25maWdgXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uLm9sZExheWVyIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24ubmV3VmlzQ29uZmlnIG5ldyB2aXNDb25maWcgYXMgYSBrZXkgdmFsdWUgbWFwOiBlLmcuIGB7b3BhY2l0eTogMC44fWBcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJWaXNDb25maWdDaGFuZ2VVcGRhdGVyKHN0YXRlLCBhY3Rpb24pIHtcbiAgY29uc3Qge29sZExheWVyfSA9IGFjdGlvbjtcbiAgY29uc3QgaWR4ID0gc3RhdGUubGF5ZXJzLmZpbmRJbmRleChsID0+IGwuaWQgPT09IG9sZExheWVyLmlkKTtcbiAgY29uc3QgcHJvcHMgPSBPYmplY3Qua2V5cyhhY3Rpb24ubmV3VmlzQ29uZmlnKTtcblxuICBjb25zdCBuZXdWaXNDb25maWcgPSB7XG4gICAgLi4ub2xkTGF5ZXIuY29uZmlnLnZpc0NvbmZpZyxcbiAgICAuLi5hY3Rpb24ubmV3VmlzQ29uZmlnXG4gIH07XG4gIGNvbnN0IG5ld0xheWVyID0gb2xkTGF5ZXIudXBkYXRlTGF5ZXJDb25maWcoe3Zpc0NvbmZpZzogbmV3VmlzQ29uZmlnfSk7XG4gIGlmIChuZXdMYXllci5zaG91bGRDYWxjdWxhdGVMYXllckRhdGEocHJvcHMpKSB7XG4gICAgY29uc3Qgb2xkTGF5ZXJEYXRhID0gc3RhdGUubGF5ZXJEYXRhW2lkeF07XG4gICAgY29uc3Qge2xheWVyRGF0YSwgbGF5ZXJ9ID0gY2FsY3VsYXRlTGF5ZXJEYXRhKFxuICAgICAgbmV3TGF5ZXIsXG4gICAgICBzdGF0ZSxcbiAgICAgIG9sZExheWVyRGF0YSxcbiAgICAgIHtcbiAgICAgICAgc2FtZURhdGE6IHRydWVcbiAgICAgIH1cbiAgICApO1xuICAgIHJldHVybiB1cGRhdGVTdGF0ZVdpdGhMYXllckFuZERhdGEoc3RhdGUsIHtsYXllckRhdGEsIGxheWVyLCBpZHh9KTtcbiAgfVxuXG4gIHJldHVybiB1cGRhdGVTdGF0ZVdpdGhMYXllckFuZERhdGEoc3RhdGUsIHtsYXllcjogbmV3TGF5ZXIsIGlkeH0pO1xufVxuXG4vKiBlc2xpbnQtZW5hYmxlIG1heC1zdGF0ZW1lbnRzICovXG5cbi8qKlxuICogVXBkYXRlIGBpbnRlcmFjdGlvbkNvbmZpZ2BcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24uY29uZmlnIG5ldyBjb25maWcgYXMga2V5IHZhbHVlIG1hcDogYHt0b29sdGlwOiB7ZW5hYmxlZDogdHJ1ZX19YFxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcmFjdGlvbkNvbmZpZ0NoYW5nZVVwZGF0ZXIoc3RhdGUsIGFjdGlvbikge1xuICBjb25zdCB7Y29uZmlnfSA9IGFjdGlvbjtcblxuICBjb25zdCBpbnRlcmFjdGlvbkNvbmZpZyA9IHtcbiAgICAuLi5zdGF0ZS5pbnRlcmFjdGlvbkNvbmZpZyxcbiAgICAuLi57W2NvbmZpZy5pZF06IGNvbmZpZ31cbiAgfTtcblxuICAvLyBEb24ndCBlbmFibGUgdG9vbHRpcCBhbmQgYnJ1c2ggYXQgdGhlIHNhbWUgdGltZVxuICAvLyBidXQgY29vcmRpbmF0ZXMgY2FuIGJlIHNob3duIGF0IGFsbCB0aW1lXG4gIGNvbnN0IGNvbnRyYWRpY3QgPSBbJ2JydXNoJywgJ3Rvb2x0aXAnXTtcblxuICBpZiAoXG4gICAgY29udHJhZGljdC5pbmNsdWRlcyhjb25maWcuaWQpICYmXG4gICAgY29uZmlnLmVuYWJsZWQgJiZcbiAgICAhc3RhdGUuaW50ZXJhY3Rpb25Db25maWdbY29uZmlnLmlkXS5lbmFibGVkXG4gICkge1xuICAgIC8vIG9ubHkgZW5hYmxlIG9uZSBpbnRlcmFjdGlvbiBhdCBhIHRpbWVcbiAgICBjb250cmFkaWN0LmZvckVhY2goayA9PiB7XG4gICAgICBpZiAoayAhPT0gY29uZmlnLmlkKSB7XG4gICAgICAgIGludGVyYWN0aW9uQ29uZmlnW2tdID0gey4uLmludGVyYWN0aW9uQ29uZmlnW2tdLCBlbmFibGVkOiBmYWxzZX07XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGludGVyYWN0aW9uQ29uZmlnXG4gIH07XG59XG5cbi8qKlxuICogVXBkYXRlIGZpbHRlciBwcm9wZXJ0eVxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlXG4gKiBAcGFyYW0ge29iamVjdH0gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLmlkeCBgaWR4YCBvZiBmaWx0ZXIgdG8gYmUgdXBkYXRlZFxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbi5wcm9wIGBwcm9wYCBvZiBmaWx0ZXIsIGUsZywgYGRhdGFJZGAsIGBuYW1lYCwgYHZhbHVlYFxuICogQHBhcmFtIHsqfSBhY3Rpb24udmFsdWUgbmV3IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uLmRhdGFJZFxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbi5yYW5nZVxuICogQHBhcmFtIHtvYmplY3R9IGFjdGlvbi5oaXN0b2dyYW1cbiAqIEByZXR1cm5zIHtvYmplY3R9IG5ld1N0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRGaWx0ZXJBUElVcGRhdGVyKHN0YXRlLCBhY3Rpb24pIHtcbiAgY29uc3Qge1xuICAgIGRhdGFJZCxcbiAgICBwcm9wLFxuICAgIHZhbHVlLFxuICAgIHZhbHVlSW5kZXggPSAwLFxuICAgIGRvbWFpbixcbiAgICBoaXN0b2dyYW0gPSB7fSxcbiAgICBpZHhcbiAgfSA9IGFjdGlvbjtcbiAgbGV0IG5ld1N0YXRlID0gc3RhdGU7XG4gIGxldCBuZXdGaWx0ZXIgPSB7XG4gICAgLi4uc3RhdGUuZmlsdGVyc1tpZHhdLFxuICAgIFtwcm9wXTogdmFsdWVcbiAgfTtcbiAgaWYgKCFoaXN0b2dyYW0pIHtcbiAgICBoaXN0b2dyYW0gPSB7fTtcbiAgfVxuXG4gIGNvbnN0IGRhdGFzZXRJZCA9IG5ld0ZpbHRlci5kYXRhSWRbdmFsdWVJbmRleF07XG4gIGNvbnN0IHtmaWx0ZXI6IHVwZGF0ZWRGaWx0ZXJ9ID0gYXBwbHlGaWx0ZXJBcGlGaWVsZE5hbWUoXG4gICAgbmV3RmlsdGVyLFxuICAgIHN0YXRlLmRhdGFzZXRzW2RhdGFzZXRJZF0sXG4gICAgdmFsdWUsXG4gICAgdmFsdWVJbmRleCxcbiAgICB7bWVyZ2VEb21haW46IGZhbHNlfSxcbiAgICBoaXN0b2dyYW0sXG4gICAgZG9tYWluXG4gICk7XG4gIGlmICghdXBkYXRlZEZpbHRlcikge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIG5ld0ZpbHRlciA9IHVwZGF0ZWRGaWx0ZXI7XG5cbiAgLy8gbmV3U3RhdGUgPSBuZXdTdGF0ZS5sYXllcnMubWFwKGwgPT4ge1xuICAvLyAgIGlmIChsLmNvbmZpZy5kYXRhSWQgPT09IGRhdGFJZCkge1xuICAvLyAgICAgbGF5ZXJDb25maWdDaGFuZ2VVcGRhdGVyKGwsIHtcbiAgLy8gICAgICAgYXBpQ2FsbFJlcXVlc3Q6IHRydWVcbiAgLy8gICAgIH0pO1xuICAvLyAgIH1cbiAgLy8gfSk7XG5cbiAgbmV3U3RhdGUgPSB7XG4gICAgLi4ubmV3U3RhdGUsXG4gICAgZmlsdGVyczogT2JqZWN0LmFzc2lnbihbLi4uc3RhdGUuZmlsdGVyc10sIHtbaWR4XTogbmV3RmlsdGVyfSlcbiAgfTtcblxuICByZXR1cm4gbmV3U3RhdGU7XG59XG5cbi8qKlxuICogVXBkYXRlIGZpbHRlciBwcm9wZXJ0eVxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IGFjdGlvbi5pZHggYGlkeGAgb2YgZmlsdGVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24ucHJvcCBgcHJvcGAgb2YgZmlsdGVyLCBlLGcsIGBkYXRhSWRgLCBgbmFtZWAsIGB2YWx1ZWBcbiAqIEBwYXJhbSB7Kn0gYWN0aW9uLnZhbHVlIG5ldyB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IGRhdGFzZXRJZCB1c2VkIHdoZW4gdXBkYXRpbmcgYSBwcm9wIChkYXRhSWQsIG5hbWUpIHRoYXQgY2FuIGJlIGxpbmtlZCB0byBtdWx0aXBsZSBkYXRhc2V0c1xuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRGaWx0ZXJVcGRhdGVyKHN0YXRlLCBhY3Rpb24pIHtcbiAgY29uc3Qge2lkeCwgcHJvcCwgdmFsdWUsIHZhbHVlSW5kZXggPSAwLCBtYXBTdGF0ZSwgYXV0aCwgcHJvamVjdH0gPSBhY3Rpb247XG5cbiAgY29uc3Qgb2xkRmlsdGVyID0gc3RhdGUuZmlsdGVyc1tpZHhdO1xuICBsZXQgbmV3RmlsdGVyID0gc2V0KFtwcm9wXSwgdmFsdWUsIG9sZEZpbHRlcik7XG4gIGxldCBuZXdTdGF0ZSA9IHN0YXRlO1xuICBjb25zdCB7ZGF0YUlkfSA9IG5ld0ZpbHRlcjtcblxuICAvLyBFbnN1cmluZyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gIGxldCBkYXRhc2V0SWRzID0gQXJyYXkuaXNBcnJheShkYXRhSWQpID8gZGF0YUlkIDogW2RhdGFJZF07XG5cbiAgc3dpdGNoIChwcm9wKSB7XG4gICAgLy8gVE9ETzogTmV4dCBQUiBmb3IgVUkgaWYgd2UgdXBkYXRlIGRhdGFJZCwgd2UgbmVlZCB0byBjb25zaWRlciB0d28gY2FzZXM6XG4gICAgLy8gMS4gZGF0YUlkIGlzIGVtcHR5OiBjcmVhdGUgYSBkZWZhdWx0IGZpbHRlclxuICAgIC8vIDIuIEFkZCBhIG5ldyBkYXRhc2V0IGlkXG4gICAgY2FzZSBGSUxURVJfVVBEQVRFUl9QUk9QUy5kYXRhSWQ6XG4gICAgICAvLyBpZiB0cnlpbmcgdG8gdXBkYXRlIGZpbHRlciBkYXRhSWQuIGNyZWF0ZSBhbiBlbXB0eSBuZXcgZmlsdGVyXG4gICAgICBuZXdGaWx0ZXIgPSBnZXREZWZhdWx0RmlsdGVyKGRhdGFJZCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgRklMVEVSX1VQREFURVJfUFJPUFMubmFtZTpcbiAgICAgIC8vIHdlIGFyZSBzdXBwb3J0aW5nIHRoZSBjdXJyZW50IGZ1bmN0aW9uYWxpdHlcbiAgICAgIC8vIFRPRE86IE5leHQgUFIgZm9yIFVJIGZpbHRlciBuYW1lIHdpbGwgb25seSB1cGRhdGUgZmlsdGVyIG5hbWUgYnV0IGl0IHdvbid0IGhhdmUgc2lkZSBlZmZlY3RzXG4gICAgICAvLyB3ZSBhcmUgZ29ubmEgdXNlIHBhaXIgb2YgZGF0YXNldHMgYW5kIGZpZWxkSWR4IHRvIHVwZGF0ZSB0aGUgZmlsdGVyXG4gICAgICBjb25zdCBkYXRhc2V0SWQgPSBuZXdGaWx0ZXIuZGF0YUlkW3ZhbHVlSW5kZXhdO1xuICAgICAgY29uc3Qge1xuICAgICAgICBmaWx0ZXI6IHVwZGF0ZWRGaWx0ZXIsXG4gICAgICAgIGRhdGFzZXQ6IG5ld0RhdGFzZXRcbiAgICAgIH0gPSBhcHBseUZpbHRlckZpZWxkTmFtZShcbiAgICAgICAgbmV3RmlsdGVyLFxuICAgICAgICBzdGF0ZS5kYXRhc2V0c1tkYXRhc2V0SWRdLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgdmFsdWVJbmRleCxcbiAgICAgICAge21lcmdlRG9tYWluOiBmYWxzZX1cbiAgICAgICk7XG4gICAgICBpZiAoIXVwZGF0ZWRGaWx0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHN0YXRlO1xuICAgICAgfVxuXG4gICAgICBuZXdGaWx0ZXIgPSB1cGRhdGVkRmlsdGVyO1xuXG4gICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIGRhdGFzZXRzOiB7XG4gICAgICAgICAgLi4uc3RhdGUuZGF0YXNldHMsXG4gICAgICAgICAgW2RhdGFzZXRJZF06IG5ld0RhdGFzZXRcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBGSUxURVJfVVBEQVRFUl9QUk9QUy5sYXllcklkOlxuICAgICAgLy8gV2UgbmVlZCB0byB1cGRhdGUgb25seSBkYXRhc2V0SWQvcyBpZiB3ZSBoYXZlIGFkZGVkL3JlbW92ZWQgbGF5ZXJzXG4gICAgICAvLyAtIGNoZWNrIGZvciBsYXllcklkIGNoYW5nZXMgKFhPUiB3b3JrcyBiZWNhdXNlIG9mIHN0cmluZyB2YWx1ZXMpXG4gICAgICAvLyBpZiBubyBkaWZmZXJlbmNlcyBiZXR3ZWVuIGxheWVySWRzLCBkb24ndCBkbyBhbnkgZmlsdGVyaW5nXG4gICAgICBjb25zdCBsYXllcklkRGlmZmVyZW5jZSA9IHhvcihuZXdGaWx0ZXIubGF5ZXJJZCwgb2xkRmlsdGVyLmxheWVySWQpO1xuXG4gICAgICBjb25zdCBsYXllckRhdGFJZHMgPSB1bmlxKFxuICAgICAgICBsYXllcklkRGlmZmVyZW5jZVxuICAgICAgICAgIC5tYXAobGlkID0+XG4gICAgICAgICAgICBnZXQoXG4gICAgICAgICAgICAgIHN0YXRlLmxheWVycy5maW5kKGwgPT4gbC5pZCA9PT0gbGlkKSxcbiAgICAgICAgICAgICAgWydjb25maWcnLCAnZGF0YUlkJ11cbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLmZpbHRlcihkID0+IGQpXG4gICAgICApO1xuXG4gICAgICAvLyBvbmx5IGZpbHRlciBkYXRhc2V0c0lkc1xuICAgICAgZGF0YXNldElkcyA9IGxheWVyRGF0YUlkcztcblxuICAgICAgLy8gVXBkYXRlIG5ld0ZpbHRlciBkYXRhSWRzXG4gICAgICBjb25zdCBuZXdEYXRhSWRzID0gdW5pcShcbiAgICAgICAgbmV3RmlsdGVyLmxheWVySWRcbiAgICAgICAgICAubWFwKGxpZCA9PlxuICAgICAgICAgICAgZ2V0KFxuICAgICAgICAgICAgICBzdGF0ZS5sYXllcnMuZmluZChsID0+IGwuaWQgPT09IGxpZCksXG4gICAgICAgICAgICAgIFsnY29uZmlnJywgJ2RhdGFJZCddXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5maWx0ZXIoZCA9PiBkKVxuICAgICAgKTtcblxuICAgICAgbmV3RmlsdGVyID0ge1xuICAgICAgICAuLi5uZXdGaWx0ZXIsXG4gICAgICAgIGRhdGFJZDogbmV3RGF0YUlkc1xuICAgICAgfTtcbiAgICAgIC8vIG9ubHkgZmlsdGVyIHRoZSBjdXJyZW50IGRhdGFzZXRcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBicmVhaztcbiAgfVxuXG4gIGNvbnN0IGVubGFyZ2VkRmlsdGVyID0gc3RhdGUuZmlsdGVycy5maW5kKGYgPT4gZi5lbmxhcmdlZCk7XG5cbiAgaWYgKGVubGFyZ2VkRmlsdGVyICYmIGVubGFyZ2VkRmlsdGVyLmlkICE9PSBuZXdGaWx0ZXIuaWQpIHtcbiAgICAvLyB0aGVyZSBzaG91bGQgYmUgb25seSBvbmUgZW5sYXJnZWQgZmlsdGVyXG4gICAgbmV3RmlsdGVyLmVubGFyZ2VkID0gZmFsc2U7XG4gIH1cblxuICAvLyBzYXZlIG5ldyBmaWx0ZXJzIHRvIG5ld1N0YXRlXG4gIG5ld1N0YXRlID0ge1xuICAgIC4uLm5ld1N0YXRlLFxuICAgIGZpbHRlcnM6IE9iamVjdC5hc3NpZ24oWy4uLnN0YXRlLmZpbHRlcnNdLCB7W2lkeF06IG5ld0ZpbHRlcn0pXG4gIH07XG5cbiAgLy8gaWYgd2UgYXJlIGN1cnJlbnRseSBzZXR0aW5nIGEgcHJvcCB0aGF0IG9ubHkgcmVxdWlyZXMgdG8gZmlsdGVyIHRoZSBjdXJyZW50XG4gIC8vIGRhdGFzZXQgd2Ugd2lsbCBwYXNzIG9ubHkgdGhlIGN1cnJlbnQgZGF0YXNldCB0byBhcHBseUZpbHRlcnNUb0RhdGFzZXRzIGFuZFxuICAvLyB1cGRhdGVBbGxMYXllckRvbWFpbkRhdGEgb3RoZXJ3aXNlIHdlIHBhc3MgdGhlIGFsbCBsaXN0IG9mIGRhdGFzZXRzIGFzIGRlZmluZWQgaW4gZGF0YUlkXG4gIGNvbnN0IGRhdGFzZXRJZHNUb0ZpbHRlciA9IExJTUlURURfRklMVEVSX0VGRkVDVF9QUk9QU1twcm9wXVxuICAgID8gdG9BcnJheShkYXRhc2V0SWRzW3ZhbHVlSW5kZXhdKVxuICAgIDogZGF0YXNldElkcztcblxuICAvLyBmaWx0ZXIgZGF0YVxuICBuZXdTdGF0ZSA9IHtcbiAgICAuLi5uZXdTdGF0ZSxcbiAgICBkYXRhc2V0czogYXBwbHlGaWx0ZXJzVG9EYXRhc2V0cyhcbiAgICAgIGRhdGFzZXRJZHNUb0ZpbHRlcixcbiAgICAgIG5ld1N0YXRlLmRhdGFzZXRzLFxuICAgICAgbmV3U3RhdGUuZmlsdGVycyxcbiAgICAgIG5ld1N0YXRlLmxheWVyc1xuICAgIClcbiAgfTtcblxuICAvLyBuZXdTdGF0ZSA9IHVwZGF0ZVdpZGdldEFnZ3JlZ2F0aW9uRGF0YShuZXdTdGF0ZSwgbWFwU3RhdGUsIGF1dGgsIHByb2plY3QpO1xuICAvLyBkYXRhSWQgaXMgYW4gYXJyYXlcbiAgLy8gcGFzcyBvbmx5IHRoZSBkYXRhc2V0IHdlIG5lZWQgdG8gdXBkYXRlXG4gIG5ld1N0YXRlID0gdXBkYXRlQWxsTGF5ZXJEb21haW5EYXRhKG5ld1N0YXRlLCBkYXRhc2V0SWRzVG9GaWx0ZXIsIG5ld0ZpbHRlcik7XG5cbiAgcmV0dXJuIG5ld1N0YXRlO1xufVxuXG4vKipcbiAqIFNldCB0aGUgcHJvcGVydHkgb2YgYSBmaWx0ZXIgcGxvdFxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IGFjdGlvbi5pZHhcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24ubmV3UHJvcCBrZXkgdmFsdWUgbWFwcGluZyBvZiBuZXcgcHJvcCBge3lBeGlzOiAnaGlzdG9ncmFtJ31gXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHNldEZpbHRlclBsb3RVcGRhdGVyID0gKHN0YXRlLCB7aWR4LCBuZXdQcm9wfSkgPT4ge1xuICBsZXQgbmV3RmlsdGVyID0gey4uLnN0YXRlLmZpbHRlcnNbaWR4XSwgLi4ubmV3UHJvcH07XG4gIGNvbnN0IHByb3AgPSBPYmplY3Qua2V5cyhuZXdQcm9wKVswXTtcbiAgaWYgKHByb3AgPT09ICd5QXhpcycpIHtcbiAgICBjb25zdCBwbG90VHlwZSA9IGdldERlZmF1bHRGaWx0ZXJQbG90VHlwZShuZXdGaWx0ZXIpO1xuXG4gICAgaWYgKHBsb3RUeXBlKSB7XG4gICAgICBuZXdGaWx0ZXIgPSB7XG4gICAgICAgIC4uLm5ld0ZpbHRlcixcbiAgICAgICAgLi4uZ2V0RmlsdGVyUGxvdChcbiAgICAgICAgICB7Li4ubmV3RmlsdGVyLCBwbG90VHlwZX0sXG4gICAgICAgICAgc3RhdGUuZGF0YXNldHNbbmV3RmlsdGVyLmRhdGFJZF0uYWxsRGF0YVxuICAgICAgICApLFxuICAgICAgICBwbG90VHlwZVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGZpbHRlcnM6IHN0YXRlLmZpbHRlcnMubWFwKChmLCBpKSA9PiAoaSA9PT0gaWR4ID8gbmV3RmlsdGVyIDogZikpXG4gIH07XG59O1xuXG4vKipcbiAqIEFkZCBhIG5ldyBmaWx0ZXJcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24uZGF0YUlkIGRhdGFzZXQgYGlkYCB0aGlzIG5ldyBmaWx0ZXIgaXMgYXNzb2NpYXRlZCB3aXRoXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGFkZEZpbHRlclVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT5cbiAgIWFjdGlvbi5kYXRhSWRcbiAgICA/IHN0YXRlXG4gICAgOiB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICBmaWx0ZXJzOiBbLi4uc3RhdGUuZmlsdGVycywgZ2V0RGVmYXVsdEZpbHRlcihhY3Rpb24uZGF0YUlkKV1cbiAgICAgIH07XG5cbi8qKlxuICogU2V0IGxheWVyIGNvbG9yIHBhbGV0dGUgdWkgc3RhdGVcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24ucHJvcFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5uZXdDb25maWdcbiAqL1xuZXhwb3J0IGNvbnN0IGxheWVyQ29sb3JVSUNoYW5nZVVwZGF0ZXIgPSAoXG4gIHN0YXRlLFxuICB7b2xkTGF5ZXIsIHByb3AsIG5ld0NvbmZpZ31cbikgPT4ge1xuICBjb25zdCBuZXdMYXllciA9IG9sZExheWVyLnVwZGF0ZUxheWVyQ29sb3JVSShwcm9wLCBuZXdDb25maWcpO1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyczogc3RhdGUubGF5ZXJzLm1hcChsID0+IChsLmlkID09PSBvbGRMYXllci5pZCA/IG5ld0xheWVyIDogbCkpXG4gIH07XG59O1xuXG4vKipcbiAqIFN0YXJ0IGFuZCBlbmQgZmlsdGVyIGFuaW1hdGlvblxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IGFjdGlvbi5pZHggaWR4IG9mIGZpbHRlclxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCB0b2dnbGVGaWx0ZXJBbmltYXRpb25VcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBmaWx0ZXJzOiBzdGF0ZS5maWx0ZXJzLm1hcCgoZiwgaSkgPT5cbiAgICBpID09PSBhY3Rpb24uaWR4ID8gey4uLmYsIGlzQW5pbWF0aW5nOiAhZi5pc0FuaW1hdGluZ30gOiBmXG4gIClcbn0pO1xuXG4vKipcbiAqIENoYW5nZSBmaWx0ZXIgYW5pbWF0aW9uIHNwZWVkXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLmlkeCAgYGlkeGAgb2YgZmlsdGVyXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLnNwZWVkIGBzcGVlZGAgdG8gY2hhbmdlIGl0IHRvLiBgc3BlZWRgIGlzIGEgbXVsdGlwbGllclxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCB1cGRhdGVGaWx0ZXJBbmltYXRpb25TcGVlZFVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4gKHtcbiAgLi4uc3RhdGUsXG4gIGZpbHRlcnM6IHN0YXRlLmZpbHRlcnMubWFwKChmLCBpKSA9PlxuICAgIGkgPT09IGFjdGlvbi5pZHggPyB7Li4uZiwgc3BlZWQ6IGFjdGlvbi5zcGVlZH0gOiBmXG4gIClcbn0pO1xuXG4vKipcbiAqIFJlc2V0IGFuaW1hdGlvbiBjb25maWcgY3VycmVudCB0aW1lIHRvIGEgc3BlY2lmaWVkIHZhbHVlXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLnZhbHVlIHRoZSB2YWx1ZSBjdXJyZW50IHRpbWUgd2lsbCBiZSBzZXQgdG9cbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICpcbiAqL1xuXG5leHBvcnQgY29uc3QgdXBkYXRlQW5pbWF0aW9uVGltZVVwZGF0ZXIgPSAoc3RhdGUsIHt2YWx1ZX0pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBhbmltYXRpb25Db25maWc6IHtcbiAgICAuLi5zdGF0ZS5hbmltYXRpb25Db25maWcsXG4gICAgY3VycmVudFRpbWU6IHZhbHVlXG4gIH1cbn0pO1xuXG4vKipcbiAqIFVwZGF0ZSBhbmltYXRpb24gc3BlZWQgd2l0aCB0aGUgdmVydGljYWwgc3BlZWQgc2xpZGVyXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLnNwZWVkIHRoZSB1cGRhdGVkIHNwZWVkIG9mIHRoZSBhbmltYXRpb25cbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICpcbiAqL1xuXG5leHBvcnQgY29uc3QgdXBkYXRlTGF5ZXJBbmltYXRpb25TcGVlZFVwZGF0ZXIgPSAoc3RhdGUsIHtzcGVlZH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBhbmltYXRpb25Db25maWc6IHtcbiAgICAgIC4uLnN0YXRlLmFuaW1hdGlvbkNvbmZpZyxcbiAgICAgIHNwZWVkXG4gICAgfVxuICB9O1xufTtcblxuLyoqXG4gKiBTaG93IGxhcmdlciB0aW1lIGZpbHRlciBhdCBib3R0b20gZm9yIHRpbWUgcGxheWJhY2sgKGFwcGx5IHRvIHRpbWUgZmlsdGVyIG9ubHkpXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLmlkeCBpbmRleCBvZiBmaWx0ZXIgdG8gZW5sYXJnZVxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBlbmxhcmdlRmlsdGVyVXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiB7XG4gIGNvbnN0IGlzRW5sYXJnZWQgPSBzdGF0ZS5maWx0ZXJzW2FjdGlvbi5pZHhdLmVubGFyZ2VkO1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgZmlsdGVyczogc3RhdGUuZmlsdGVycy5tYXAoKGYsIGkpID0+IHtcbiAgICAgIGYuZW5sYXJnZWQgPSAhaXNFbmxhcmdlZCAmJiBpID09PSBhY3Rpb24uaWR4O1xuICAgICAgcmV0dXJuIGY7XG4gICAgfSlcbiAgfTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGEgZmlsdGVyXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLmlkeCBpbmRleCBvZiBmaWx0ZXIgdG8gYiBlIHJlbW92ZWRcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgcmVtb3ZlRmlsdGVyVXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiB7XG4gIGNvbnN0IHtpZHgsIG1hcFN0YXRlLCBhdXRoLCBwcm9qZWN0fSA9IGFjdGlvbjtcbiAgY29uc3Qge2RhdGFJZH0gPSBzdGF0ZS5maWx0ZXJzW2lkeF07XG5cbiAgY29uc3QgbmV3RmlsdGVycyA9IFtcbiAgICAuLi5zdGF0ZS5maWx0ZXJzLnNsaWNlKDAsIGlkeCksXG4gICAgLi4uc3RhdGUuZmlsdGVycy5zbGljZShpZHggKyAxLCBzdGF0ZS5maWx0ZXJzLmxlbmd0aClcbiAgXTtcblxuICBjb25zdCBmaWx0ZXIgPSBzdGF0ZS5maWx0ZXJzW2lkeF07XG4gIGNvbnN0IGZpbHRlcmVkRGF0YXNldHMgPSBhcHBseUZpbHRlcnNUb0RhdGFzZXRzKFxuICAgIGRhdGFJZCxcbiAgICBzdGF0ZS5kYXRhc2V0cyxcbiAgICBuZXdGaWx0ZXJzLFxuICAgIHN0YXRlLmxheWVyc1xuICApO1xuXG4gIGxldCBuZXdTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBmaWx0ZXJzOiBuZXdGaWx0ZXJzLFxuICAgIGVkaXRvcjoge1xuICAgICAgLi4uc3RhdGUuZWRpdG9yLFxuICAgICAgZmVhdHVyZXM6XG4gICAgICAgIGZpbHRlci50eXBlICE9PSBGSUxURVJfVFlQRVMucG9seWdvblxuICAgICAgICAgID8gc3RhdGUuZWRpdG9yLmZlYXR1cmVzXG4gICAgICAgICAgOiBzdGF0ZS5lZGl0b3IuZmVhdHVyZXMuZmlsdGVyKGYgPT4gZi5pZCAhPT0gZmlsdGVyLnZhbHVlLmlkKSxcbiAgICAgIHNlbGVjdGVkRmVhdHVyZTogbnVsbFxuICAgIH1cbiAgfTtcblxuICAvLyBjYWxsIGxheWVycyBhcGkgdG8gdXBkYXRlIGRhdGEgd2hlbiBhIGZpbHRlciBpcyByZW1vdmVkXG5cbiAgY29uc3QgbGF5ZXJzID0gbmV3U3RhdGUubGF5ZXJzLm1hcChsYXllciA9PiB7XG4gICAgaWYgKGxheWVyLmRhdGFJZCA9PT0gZGF0YUlkKSB7XG4gICAgICBsYXllci5jb25maWcuYXBpQ2FsbFJlcXVlc3QgPT09IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBsYXllcjtcbiAgfSk7XG4gIG5ld1N0YXRlID0ge1xuICAgIC4uLm5ld1N0YXRlLFxuICAgIGxheWVyc1xuICB9O1xuICBuZXdTdGF0ZSA9IHNldChbJ2RhdGFzZXRzJ10sIGZpbHRlcmVkRGF0YXNldHMsIG5ld1N0YXRlKTtcblxuICByZXR1cm4gdXBkYXRlQWxsTGF5ZXJEb21haW5EYXRhKG5ld1N0YXRlLCBkYXRhSWQpO1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZFdpZGdldFVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICBjb25zdCBkZWZhdWx0RGF0YXNldCA9IE9iamVjdC5rZXlzKHN0YXRlLmRhdGFzZXRzKVswXTtcbiAgY29uc3QgbmV3V2lkZ2V0ID0gbmV3IFdpZGdldCh7XG4gICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgIGlzQ29uZmlnQWN0aXZlOiB0cnVlLFxuICAgIGRhdGFJZDogZGVmYXVsdERhdGFzZXQsXG4gICAgLi4uYWN0aW9uLnByb3BzXG4gIH0pO1xuXG4gIHJldHVybiAhZGVmYXVsdERhdGFzZXRcbiAgICA/IHN0YXRlXG4gICAgOiB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICB3aWRnZXRzOiBbLi4uc3RhdGUud2lkZ2V0cywgbmV3V2lkZ2V0XSxcbiAgICAgICAgd2lkZ2V0T3JkZXI6IFsuLi5zdGF0ZS53aWRnZXRPcmRlciwgc3RhdGUud2lkZ2V0T3JkZXIubGVuZ3RoXVxuICAgICAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByZW1vdmVXaWRnZXRVcGRhdGVyID0gKHN0YXRlLCB7aWR4fSkgPT4ge1xuICBjb25zdCB7d2lkZ2V0c30gPSBzdGF0ZTtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICB3aWRnZXRzOiBbXG4gICAgICAuLi53aWRnZXRzLnNsaWNlKDAsIGlkeCksXG4gICAgICAuLi53aWRnZXRzLnNsaWNlKGlkeCArIDEsIHdpZGdldHMubGVuZ3RoKVxuICAgIF0sXG4gICAgd2lkZ2V0T3JkZXI6IHN0YXRlLndpZGdldE9yZGVyXG4gICAgICAuZmlsdGVyKGkgPT4gaSAhPT0gaWR4KVxuICAgICAgLm1hcChwaWQgPT4gKHBpZCA+IGlkeCA/IHBpZCAtIDEgOiBwaWQpKVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHJlb3JkZXJXaWRnZXRVcGRhdGVyID0gKHN0YXRlLCB7b3JkZXJ9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgd2lkZ2V0T3JkZXI6IG9yZGVyXG4gIH07XG59O1xuXG4vKipcbiAqIEFkZCBhIG5ldyBsYXllclxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5wcm9wcyAtIG5ldyBsYXllciBwcm9wc1xuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBhZGRMYXllclVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICBjb25zdCBkZWZhdWx0RGF0YXNldCA9IE9iamVjdC5rZXlzKHN0YXRlLmRhdGFzZXRzKVswXTtcblxuICBjb25zdCBuZXdMYXllciA9IG5ldyBMYXllcih7XG4gICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgIGlzQ29uZmlnQWN0aXZlOiB0cnVlLFxuICAgIGRhdGFJZDogZGVmYXVsdERhdGFzZXQsXG4gICAgLi4uYWN0aW9uLnByb3BzXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJzOiBbLi4uc3RhdGUubGF5ZXJzLCBuZXdMYXllcl0sXG4gICAgbGF5ZXJEYXRhOiBbLi4uc3RhdGUubGF5ZXJEYXRhLCB7fV0sXG4gICAgbGF5ZXJPcmRlcjogWy4uLnN0YXRlLmxheWVyT3JkZXIsIHN0YXRlLmxheWVyT3JkZXIubGVuZ3RoXSxcbiAgICBzcGxpdE1hcHM6IGFkZE5ld0xheWVyc1RvU3BsaXRNYXAoc3RhdGUuc3BsaXRNYXBzLCBuZXdMYXllcilcbiAgfTtcbn07XG5cbi8qKlxuICogcmVtb3ZlIGxheWVyXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLmlkeCBpbmRleCBvZiBsYXllciB0byBiIGUgcmVtb3ZlZFxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCByZW1vdmVMYXllclVwZGF0ZXIgPSAoc3RhdGUsIHtpZHh9KSA9PiB7XG4gIGNvbnN0IHtsYXllcnMsIGxheWVyRGF0YSwgY2xpY2tlZCwgaG92ZXJJbmZvfSA9IHN0YXRlO1xuICBjb25zdCBsYXllclRvUmVtb3ZlID0gc3RhdGUubGF5ZXJzW2lkeF07XG4gIGNvbnN0IG5ld01hcHMgPSByZW1vdmVMYXllckZyb21TcGxpdE1hcHMoc3RhdGUuc3BsaXRNYXBzLCBsYXllclRvUmVtb3ZlKTtcblxuICBjb25zdCBuZXdTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBsYXllcnM6IFsuLi5sYXllcnMuc2xpY2UoMCwgaWR4KSwgLi4ubGF5ZXJzLnNsaWNlKGlkeCArIDEsIGxheWVycy5sZW5ndGgpXSxcbiAgICBsYXllckRhdGE6IFtcbiAgICAgIC4uLmxheWVyRGF0YS5zbGljZSgwLCBpZHgpLFxuICAgICAgLi4ubGF5ZXJEYXRhLnNsaWNlKGlkeCArIDEsIGxheWVyRGF0YS5sZW5ndGgpXG4gICAgXSxcbiAgICBsYXllck9yZGVyOiBzdGF0ZS5sYXllck9yZGVyXG4gICAgICAuZmlsdGVyKGkgPT4gaSAhPT0gaWR4KVxuICAgICAgLm1hcChwaWQgPT4gKHBpZCA+IGlkeCA/IHBpZCAtIDEgOiBwaWQpKSxcbiAgICBjbGlja2VkOiBsYXllclRvUmVtb3ZlLmlzTGF5ZXJIb3ZlcmVkKGNsaWNrZWQpID8gdW5kZWZpbmVkIDogY2xpY2tlZCxcbiAgICBob3ZlckluZm86IGxheWVyVG9SZW1vdmUuaXNMYXllckhvdmVyZWQoaG92ZXJJbmZvKSA/IHVuZGVmaW5lZCA6IGhvdmVySW5mbyxcbiAgICBzcGxpdE1hcHM6IG5ld01hcHNcbiAgICAvLyBUT0RPOiB1cGRhdGUgZmlsdGVycywgY3JlYXRlIGhlbHBlciB0byByZW1vdmUgbGF5ZXIgZm9ybSBmaWx0ZXIgKHJlbW92ZSBsYXllcmlkIGFuZCBkYXRhaWQpIGlmIG1hcHBlZFxuICB9O1xuXG4gIHJldHVybiB1cGRhdGVBbmltYXRpb25Eb21haW4obmV3U3RhdGUpO1xufTtcblxuLyoqXG4gKiBSZW9yZGVyIGxheWVyXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5PE51bWJlcj59IGFjdGlvbi5vcmRlciBhbiBhcnJheSBvZiBsYXllciBpbmRleGVzXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHJlb3JkZXJMYXllclVwZGF0ZXIgPSAoc3RhdGUsIHtvcmRlcn0pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBsYXllck9yZGVyOiBvcmRlclxufSk7XG5cbi8qKlxuICogUmVtb3ZlIGEgZGF0YXNldCBhbmQgYWxsIGxheWVycywgZmlsdGVycywgdG9vbHRpcCBjb25maWdzIHRoYXQgYmFzZWQgb24gaXRcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24ua2V5IGRhdGFzZXQgaWRcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgcmVtb3ZlRGF0YXNldFVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICAvLyBleHRyYWN0IGRhdGFzZXQga2V5XG4gIGNvbnN0IHtrZXk6IGRhdGFzZXRLZXl9ID0gYWN0aW9uO1xuICBjb25zdCB7ZGF0YXNldHN9ID0gc3RhdGU7XG5cbiAgLy8gY2hlY2sgaWYgZGF0YXNldCBpcyBwcmVzZW50XG4gIGlmICghZGF0YXNldHNbZGF0YXNldEtleV0pIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuICBjb25zdCB7XG4gICAgbGF5ZXJzLFxuICAgIHdpZGdldHMsXG4gICAgZGF0YXNldHM6IHtbZGF0YXNldEtleV06IGRhdGFzZXQsIC4uLm5ld0RhdGFzZXRzfVxuICB9ID0gc3RhdGU7XG4gIC8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuICBjb25zdCBpbmRleGVzID0gbGF5ZXJzLnJlZHVjZSgobGlzdE9mSW5kZXhlcywgbGF5ZXIsIGluZGV4KSA9PiB7XG4gICAgaWYgKGxheWVyLmNvbmZpZy5kYXRhSWQgPT09IGRhdGFzZXRLZXkpIHtcbiAgICAgIGxpc3RPZkluZGV4ZXMucHVzaChpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiBsaXN0T2ZJbmRleGVzO1xuICB9LCBbXSk7XG5cbiAgY29uc3Qgd2lkZ2V0SW5kZXhlcyA9IHdpZGdldHMucmVkdWNlKChsaXN0T2ZJbmRleGVzLCB3aWRnZXQsIGluZGV4KSA9PiB7XG4gICAgaWYgKHdpZGdldC5jb25maWcuZGF0YUlkID09PSBkYXRhc2V0S2V5KSB7XG4gICAgICBsaXN0T2ZJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gbGlzdE9mSW5kZXhlcztcbiAgfSwgW10pO1xuXG4gIC8vIHJlbW92ZSBsYXllcnMgYW5kIGRhdGFzZXRzXG4gIGNvbnN0IHtuZXdTdGF0ZX0gPSBpbmRleGVzLnJlZHVjZShcbiAgICAoe25ld1N0YXRlOiBjdXJyZW50U3RhdGUsIGluZGV4Q291bnRlcn0sIGlkeCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gaWR4IC0gaW5kZXhDb3VudGVyO1xuICAgICAgY3VycmVudFN0YXRlID0gcmVtb3ZlTGF5ZXJVcGRhdGVyKGN1cnJlbnRTdGF0ZSwge2lkeDogY3VycmVudEluZGV4fSk7XG4gICAgICBpbmRleENvdW50ZXIrKztcbiAgICAgIHJldHVybiB7bmV3U3RhdGU6IGN1cnJlbnRTdGF0ZSwgaW5kZXhDb3VudGVyfTtcbiAgICB9LFxuICAgIHtuZXdTdGF0ZTogey4uLnN0YXRlLCBkYXRhc2V0czogbmV3RGF0YXNldHN9LCBpbmRleENvdW50ZXI6IDB9XG4gICk7XG5cbiAgLy8gcmVtb3ZlIHdpZGdldHNcbiAgLy8gbmV3U3RhdGUgPSB7XG4gIC8vICAgLi4ubmV3U3RhdGUsXG4gIC8vICAgd2lkZ2V0czogd2lkZ2V0SW5kZXhlcy5tYXAoaWR4ID0+IFtcbiAgLy8gICAgIC4uLndpZGdldHMuc2xpY2UoMCwgaWR4KSxcbiAgLy8gICAgIC4uLndpZGdldHMuc2xpY2UoaWR4ICsgMSwgd2lkZ2V0cy5sZW5ndGgpXG4gIC8vICAgXSlcbiAgLy8gfTtcblxuICAvLyBjb25zdCB3aWRnZXRzID0gc3RhdGUud2lkZ2V0cy5maWx0ZXIoXG4gIC8vICAgd2lkZ2V0ID0+IHdpZGdldC5jb25maWcuZGF0YUlkICE9PSBkYXRhc2V0S2V5XG4gIC8vICk7XG5cbiAgY29uc3Qge2ZpbmFsU3RhdGV9ID0gd2lkZ2V0SW5kZXhlcy5yZWR1Y2UoXG4gICAgKHtmaW5hbFN0YXRlOiBzdGF0ZSwgaW5kZXhDb3VudGVyfSwgaWR4KSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSBpZHggLSBpbmRleENvdW50ZXI7XG4gICAgICBzdGF0ZSA9IHJlbW92ZVdpZGdldFVwZGF0ZXIoc3RhdGUsIHtpZHg6IGN1cnJlbnRJbmRleH0pO1xuICAgICAgaW5kZXhDb3VudGVyKys7XG4gICAgICByZXR1cm4ge2ZpbmFsU3RhdGU6IHN0YXRlLCBpbmRleENvdW50ZXJ9O1xuICAgIH0sXG4gICAge2ZpbmFsU3RhdGU6IHsuLi5uZXdTdGF0ZX0sIGluZGV4Q291bnRlcjogMH1cbiAgKTtcblxuICAvLyByZW1vdmUgZmlsdGVyc1xuICBjb25zdCBmaWx0ZXJzID0gc3RhdGUuZmlsdGVycy5maWx0ZXIoXG4gICAgZmlsdGVyID0+ICFkYXRhc2V0S2V5LmluY2x1ZGVzKGZpbHRlci5kYXRhSWQpXG4gICk7XG5cbiAgLy8gdXBkYXRlIGludGVyYWN0aW9uQ29uZmlnXG4gIGxldCB7aW50ZXJhY3Rpb25Db25maWd9ID0gc3RhdGU7XG4gIGNvbnN0IHt0b29sdGlwfSA9IGludGVyYWN0aW9uQ29uZmlnO1xuICBpZiAodG9vbHRpcCkge1xuICAgIGNvbnN0IHtjb25maWd9ID0gdG9vbHRpcDtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuICAgIGNvbnN0IHtbZGF0YXNldEtleV06IGZpZWxkcywgLi4uZmllbGRzVG9TaG93fSA9IGNvbmZpZy5maWVsZHNUb1Nob3c7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xuICAgIGludGVyYWN0aW9uQ29uZmlnID0ge1xuICAgICAgLi4uaW50ZXJhY3Rpb25Db25maWcsXG4gICAgICB0b29sdGlwOiB7Li4udG9vbHRpcCwgY29uZmlnOiB7Li4uY29uZmlnLCBmaWVsZHNUb1Nob3d9fVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gey4uLmZpbmFsU3RhdGUsIGZpbHRlcnMsIGludGVyYWN0aW9uQ29uZmlnfTtcbn07XG5cbi8qKlxuICogdXBkYXRlIGxheWVyIGJsZW5kaW5nIG1vZGVcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24ubW9kZSBvbmUgb2YgYGFkZGl0aXZlYCwgYG5vcm1hbGAgYW5kIGBzdWJ0cmFjdGl2ZWBcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdXBkYXRlTGF5ZXJCbGVuZGluZ1VwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4gKHtcbiAgLi4uc3RhdGUsXG4gIGxheWVyQmxlbmRpbmc6IGFjdGlvbi5tb2RlXG59KTtcblxuLyoqXG4gKiBEaXNwbGF5IGRhdGFzZXQgdGFibGUgaW4gYSBtb2RhbFxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbi5kYXRhSWQgZGF0YXNldCBpZCB0byBzaG93IGluIHRhYmxlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHNob3dEYXRhc2V0VGFibGVVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBlZGl0aW5nRGF0YXNldDogYWN0aW9uLmRhdGFJZFxuICB9O1xufTtcblxuLyoqXG4gKiByZXNldCB2aXNTdGF0ZSB0byBpbml0aWFsIFN0YXRlXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgcmVzZXRNYXBDb25maWdVcGRhdGVyID0gc3RhdGUgPT4gKHtcbiAgLi4uSU5JVElBTF9WSVNfU1RBVEUsXG4gIC4uLnN0YXRlLmluaXRpYWxTdGF0ZSxcbiAgaW5pdGlhbFN0YXRlOiBzdGF0ZS5pbml0aWFsU3RhdGVcbn0pO1xuXG4vKipcbiAqIFByb3BhZ2F0ZSBgdmlzU3RhdGVgIHJlZHVjZXIgd2l0aCBhIG5ldyBjb25maWd1cmF0aW9uLiBDdXJyZW50IGNvbmZpZyB3aWxsIGJlIG92ZXJyaWRlLlxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5wYXlsb2FkIG1hcCBjb25maWcgdG8gYmUgcHJvcGFnYXRlZFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5wYXlsb2FkLmNvbmZpZyBtYXAgY29uZmlnIHRvIGJlIHByb3BhZ2F0ZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24ucGF5bG9hZC5vcHRpb24ge2tlZXBFeGlzdGluZ0NvbmZpZzogdHJ1ZSB8IGZhbHNlfVxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCByZWNlaXZlTWFwQ29uZmlnVXBkYXRlciA9IChcbiAgc3RhdGUsXG4gIHtwYXlsb2FkOiB7Y29uZmlnID0ge30sIG9wdGlvbnMgPSB7fX19XG4pID0+IHtcbiAgaWYgKCFjb25maWcudmlzU3RhdGUpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICBjb25zdCB7XG4gICAgZmlsdGVycyxcbiAgICBsYXllcnMsXG4gICAgd2lkZ2V0cyxcbiAgICBpbnRlcmFjdGlvbkNvbmZpZyxcbiAgICBsYXllckJsZW5kaW5nLFxuICAgIHNwbGl0TWFwcyxcbiAgICBhbmltYXRpb25Db25maWdcbiAgfSA9IGNvbmZpZy52aXNTdGF0ZTtcblxuICBjb25zdCB7a2VlcEV4aXN0aW5nQ29uZmlnfSA9IG9wdGlvbnM7XG5cbiAgLy8gcmVzZXQgY29uZmlnIGlmIGtlZXBFeGlzdGluZ0NvbmZpZyBpcyBmYWxzeVxuICBsZXQgbWVyZ2VkU3RhdGUgPSAha2VlcEV4aXN0aW5nQ29uZmlnID8gcmVzZXRNYXBDb25maWdVcGRhdGVyKHN0YXRlKSA6IHN0YXRlO1xuICBtZXJnZWRTdGF0ZSA9IG1lcmdlRmlsdGVycyhtZXJnZWRTdGF0ZSwgZmlsdGVycyk7XG4gIC8vIGNvbnNvbGUubG9nKCdBZnRlciBNZXJnZUZpbHRlcnMnLCBtZXJnZWRTdGF0ZSk7XG4gIG1lcmdlZFN0YXRlID0gbWVyZ2VMYXllcnMobWVyZ2VkU3RhdGUsIGxheWVycyk7XG4gIC8vIGNvbnNvbGUubG9nKCdBZnRlciBNZXJnZUxheWVycycsIG1lcmdlZFN0YXRlKTtcbiAgbWVyZ2VkU3RhdGUgPSBtZXJnZUludGVyYWN0aW9ucyhtZXJnZWRTdGF0ZSwgaW50ZXJhY3Rpb25Db25maWcpO1xuICBtZXJnZWRTdGF0ZSA9IG1lcmdlTGF5ZXJCbGVuZGluZyhtZXJnZWRTdGF0ZSwgbGF5ZXJCbGVuZGluZyk7XG4gIG1lcmdlZFN0YXRlID0gbWVyZ2VTcGxpdE1hcHMobWVyZ2VkU3RhdGUsIHNwbGl0TWFwcyk7XG4gIG1lcmdlZFN0YXRlID0gbWVyZ2VBbmltYXRpb25Db25maWcobWVyZ2VkU3RhdGUsIGFuaW1hdGlvbkNvbmZpZyk7XG4gIG1lcmdlZFN0YXRlID0gbWVyZ2VXaWRnZXRzKG1lcmdlZFN0YXRlLCB3aWRnZXRzKTtcblxuICByZXR1cm4gbWVyZ2VkU3RhdGU7XG59O1xuXG4vKipcbiAqIFRyaWdnZXIgbGF5ZXIgaG92ZXIgZXZlbnQgd2l0aCBob3ZlcmVkIG9iamVjdFxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5pbmZvIE9iamVjdCBob3ZlcmVkLCByZXR1cm5lZCBieSBkZWNrLmdsXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGxheWVySG92ZXJVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBob3ZlckluZm86IGFjdGlvbi5pbmZvXG59KTtcblxuLyoqXG4gKiBUcmlnZ2VyIGxheWVyIGNsaWNrIGV2ZW50IHdpdGggY2xpY2tlZCBvYmplY3RcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24uaW5mbyBPYmplY3QgY2xpY2tlZCwgcmV0dXJuZWQgYnkgZGVjay5nbFxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBsYXllckNsaWNrVXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgbW91c2VQb3M6IHN0YXRlLmludGVyYWN0aW9uQ29uZmlnLmNvb3JkaW5hdGUuZW5hYmxlZFxuICAgID8ge1xuICAgICAgICAuLi5zdGF0ZS5tb3VzZVBvcyxcbiAgICAgICAgcGlubmVkOiBzdGF0ZS5tb3VzZVBvcy5waW5uZWQgPyBudWxsIDogY2xvbmVEZWVwKHN0YXRlLm1vdXNlUG9zKVxuICAgICAgfVxuICAgIDogc3RhdGUubW91c2VQb3MsXG4gIGNsaWNrZWQ6IGFjdGlvbi5pbmZvICYmIGFjdGlvbi5pbmZvLnBpY2tlZCA/IGFjdGlvbi5pbmZvIDogbnVsbFxufSk7XG5cbi8qKlxuICogVHJpZ2dlciBtYXAgY2xpY2sgZXZlbnQsIHVuc2VsZWN0IGNsaWNrZWQgb2JqZWN0XG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgbWFwQ2xpY2tVcGRhdGVyID0gc3RhdGUgPT4ge1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGNsaWNrZWQ6IG51bGxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBtb3VzZU1vdmVVcGRhdGVyID0gKHN0YXRlLCB7ZXZ0fSkgPT4ge1xuICBpZiAoT2JqZWN0LnZhbHVlcyhzdGF0ZS5pbnRlcmFjdGlvbkNvbmZpZykuc29tZShjb25maWcgPT4gY29uZmlnLmVuYWJsZWQpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN0YXRlLFxuICAgICAgbW91c2VQb3M6IHtcbiAgICAgICAgLi4uc3RhdGUubW91c2VQb3MsXG4gICAgICAgIG1vdXNlUG9zaXRpb246IFsuLi5ldnQucG9pbnRdLFxuICAgICAgICBjb29yZGluYXRlOiBbLi4uZXZ0LmxuZ0xhdF1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlO1xufTtcbi8qKlxuICogVG9nZ2xlIHZpc2liaWxpdHkgb2YgYSBsYXllciBmb3IgYSBzcGxpdCBtYXBcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7TnVtYmVyfHVuZGVmaW5lZH0gYWN0aW9uLnBheWxvYWQgaW5kZXggb2YgdGhlIHNwbGl0IG1hcFxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCB0b2dnbGVTcGxpdE1hcFVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT5cbiAgc3RhdGUuc3BsaXRNYXBzICYmIHN0YXRlLnNwbGl0TWFwcy5sZW5ndGggPT09IDBcbiAgICA/IHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIC8vIG1heWJlIHdlIHNob3VsZCB1c2UgYW4gYXJyYXkgdG8gc3RvcmUgc3RhdGUgZm9yIGEgc2luZ2xlIG1hcCBhcyB3ZWxsXG4gICAgICAgIC8vIGlmIGN1cnJlbnQgbWFwcyBsZW5ndGggaXMgZXF1YWwgdG8gMCBpdCBtZWFucyB0aGF0IHdlIGFyZSBhYm91dCB0byBzcGxpdCB0aGUgdmlld1xuICAgICAgICBzcGxpdE1hcHM6IGNvbXB1dGVTcGxpdE1hcExheWVycyhzdGF0ZS5sYXllcnMpXG4gICAgICB9XG4gICAgOiBjbG9zZVNwZWNpZmljTWFwQXRJbmRleChzdGF0ZSwgYWN0aW9uKTtcblxuLyoqXG4gKiBUb2dnbGUgdmlzaWJpbGl0eSBvZiBhIGxheWVyIGluIGEgc3BsaXQgbWFwXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYWN0aW9uLm1hcEluZGV4IGluZGV4IG9mIHRoZSBzcGxpdCBtYXBcbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24ubGF5ZXJJZCBpZCBvZiB0aGUgbGF5ZXJcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlTGF5ZXJGb3JNYXBVcGRhdGVyID0gKHN0YXRlLCB7bWFwSW5kZXgsIGxheWVySWR9KSA9PiB7XG4gIGNvbnN0IHtzcGxpdE1hcHN9ID0gc3RhdGU7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBzcGxpdE1hcHM6IHNwbGl0TWFwcy5tYXAoKHNtLCBpKSA9PlxuICAgICAgaSA9PT0gbWFwSW5kZXhcbiAgICAgICAgPyB7XG4gICAgICAgICAgICAuLi5zcGxpdE1hcHNbaV0sXG4gICAgICAgICAgICBsYXllcnM6IHtcbiAgICAgICAgICAgICAgLi4uc3BsaXRNYXBzW2ldLmxheWVycyxcbiAgICAgICAgICAgICAgLy8gaWYgbGF5ZXJJZCBub3QgaW4gbGF5ZXJzLCBzZXQgaXQgdG8gdmlzaWJsZVxuICAgICAgICAgICAgICBbbGF5ZXJJZF06ICFzcGxpdE1hcHNbaV0ubGF5ZXJzW2xheWVySWRdXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA6IHNtXG4gICAgKVxuICB9O1xufTtcblxuLyoqXG4gKiBBZGQgbmV3IGRhdGFzZXQgdG8gYHZpc1N0YXRlYCwgd2l0aCBvcHRpb24gdG8gbG9hZCBhIG1hcCBjb25maWcgYWxvbmcgd2l0aCB0aGUgZGF0YXNldHNcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0PnxPYmplY3R9IGFjdGlvbi5kYXRhc2V0cyAtICoqKnJlcXVpcmVkKiogZGF0YXNldHMgY2FuIGJlIGEgZGF0YXNldCBvciBhbiBhcnJheSBvZiBkYXRhc2V0c1xuICogRWFjaCBkYXRhc2V0IG9iamVjdCBuZWVkcyB0byBoYXZlIGBpbmZvYCBhbmQgYGRhdGFgIHByb3BlcnR5LlxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5kYXRhc2V0cy5pbmZvIC1pbmZvIG9mIGEgZGF0YXNldFxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbi5kYXRhc2V0cy5pbmZvLmlkIC0gaWQgb2YgdGhpcyBkYXRhc2V0LiBJZiBjb25maWcgaXMgZGVmaW5lZCwgYGlkYCBzaG91bGQgbWF0Y2hlcyB0aGUgYGRhdGFJZGAgaW4gY29uZmlnLlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbi5kYXRhc2V0cy5pbmZvLmxhYmVsIC0gQSBkaXNwbGF5IG5hbWUgb2YgdGhpcyBkYXRhc2V0XG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uLmRhdGFzZXRzLmRhdGEgLSAqKipyZXF1aXJlZCoqIFRoZSBkYXRhIG9iamVjdCwgaW4gYSB0YWJ1bGFyIGZvcm1hdCB3aXRoIDIgcHJvcGVydGllcyBgZmllbGRzYCBhbmQgYHJvd3NgXG4gKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGFjdGlvbi5kYXRhc2V0cy5kYXRhLmZpZWxkcyAtICoqKnJlcXVpcmVkKiogQXJyYXkgb2YgZmllbGRzLFxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbi5kYXRhc2V0cy5kYXRhLmZpZWxkcy5uYW1lIC0gKioqcmVxdWlyZWQqKiBOYW1lIG9mIHRoZSBmaWVsZCxcbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk+fSBhY3Rpb24uZGF0YXNldHMuZGF0YS5yb3dzIC0gKioqcmVxdWlyZWQqKiBBcnJheSBvZiByb3dzLCBpbiBhIHRhYnVsYXIgZm9ybWF0IHdpdGggYGZpZWxkc2AgYW5kIGByb3dzYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5vcHRpb25zIG9wdGlvbiBvYmplY3QgYHtjZW50ZXJNYXA6IHRydWUsIGtlZXBFeGlzdGluZ0NvbmZpZzogZmFsc2V9YFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvbi5jb25maWcgbWFwIGNvbmZpZ1xuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG1heC1zdGF0ZW1lbnRzICovXG5leHBvcnQgY29uc3QgdXBkYXRlVmlzRGF0YVVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICAvLyBkYXRhc2V0cyBjYW4gYmUgYSBzaW5nbGUgZGF0YSBlbnRyaWVzIG9yIGFuIGFycmF5IG9mIG11bHRpcGxlIGRhdGEgZW50cmllc1xuICBjb25zdCB7Y29uZmlnLCBvcHRpb25zfSA9IGFjdGlvbjtcblxuICBjb25zdCBkYXRhc2V0cyA9IEFycmF5LmlzQXJyYXkoYWN0aW9uLmRhdGFzZXRzKVxuICAgID8gYWN0aW9uLmRhdGFzZXRzXG4gICAgOiBbYWN0aW9uLmRhdGFzZXRzXTtcblxuICBjb25zdCBuZXdEYXRlRW50cmllcyA9IGRhdGFzZXRzLnJlZHVjZShcbiAgICAoYWNjdSwge2luZm8gPSB7fSwgZGF0YX0pID0+ICh7XG4gICAgICAuLi5hY2N1LFxuICAgICAgLi4uKGNyZWF0ZU5ld0RhdGFFbnRyeSh7aW5mbywgZGF0YX0sIHN0YXRlLmRhdGFzZXRzKSB8fCB7fSlcbiAgICB9KSxcbiAgICB7fVxuICApO1xuXG4gIGlmICghT2JqZWN0LmtleXMobmV3RGF0ZUVudHJpZXMpLmxlbmd0aCkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8vIGFwcGx5IGNvbmZpZyBpZiBwYXNzZWQgZnJvbSBhY3Rpb25cbiAgY29uc3QgcHJldmlvdXNTdGF0ZSA9IGNvbmZpZ1xuICAgID8gcmVjZWl2ZU1hcENvbmZpZ1VwZGF0ZXIoc3RhdGUsIHtcbiAgICAgICAgcGF5bG9hZDoge2NvbmZpZywgb3B0aW9uc31cbiAgICAgIH0pXG4gICAgOiBzdGF0ZTtcblxuICBjb25zdCBzdGF0ZVdpdGhOZXdEYXRhID0ge1xuICAgIC4uLnByZXZpb3VzU3RhdGUsXG4gICAgZGF0YXNldHM6IHtcbiAgICAgIC4uLnByZXZpb3VzU3RhdGUuZGF0YXNldHMsXG4gICAgICAuLi5uZXdEYXRlRW50cmllc1xuICAgIH1cbiAgfTtcblxuICAvLyBwcmV2aW91c2x5IHNhdmVkIGNvbmZpZyBiZWZvcmUgZGF0YSBsb2FkZWRcbiAgY29uc3Qge1xuICAgIGZpbHRlclRvQmVNZXJnZWQgPSBbXSxcbiAgICBsYXllclRvQmVNZXJnZWQgPSBbXSxcbiAgICB3aWRnZXRUb0JlTWVyZ2VkID0gW10sXG4gICAgaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkID0ge30sXG4gICAgc3BsaXRNYXBzVG9CZU1lcmdlZCA9IFtdXG4gIH0gPSBzdGF0ZVdpdGhOZXdEYXRhO1xuXG4gIC8vIG1lcmdlIHN0YXRlIHdpdGggc2F2ZWQgbGF5ZXJzXG4gIC8vIG1ha2Ugc3VyZSBsYXllcnMgYXJlIG1lcmdlZCBmaXJzdFxuICBsZXQgbWVyZ2VkU3RhdGUgPSBtZXJnZUxheWVycyhzdGF0ZVdpdGhOZXdEYXRhLCBsYXllclRvQmVNZXJnZWQpO1xuXG4gIC8vIG1lcmdlIHN0YXRlIHdpdGggc2F2ZWQgZmlsdGVyc1xuICBtZXJnZWRTdGF0ZSA9IG1lcmdlRmlsdGVycyhtZXJnZWRTdGF0ZSwgZmlsdGVyVG9CZU1lcmdlZCk7XG5cbiAgLy8gbWVyZ2Ugc3RhdGUgd2l0aCBzYXZlZCBzcGxpdE1hcHNcbiAgbWVyZ2VkU3RhdGUgPSBtZXJnZVNwbGl0TWFwcyhtZXJnZWRTdGF0ZSwgc3BsaXRNYXBzVG9CZU1lcmdlZCk7XG5cbiAgbGV0IG5ld0xheWVycyA9IG1lcmdlZFN0YXRlLmxheWVycy5maWx0ZXIoXG4gICAgbCA9PiBsLmNvbmZpZy5kYXRhSWQgaW4gbmV3RGF0ZUVudHJpZXNcbiAgKTtcblxuICBpZiAoIW5ld0xheWVycy5sZW5ndGgpIHtcbiAgICAvLyBubyBsYXllciBtZXJnZWQsIGZpbmQgZGVmYXVsdHNcbiAgICBjb25zdCByZXN1bHQgPSBhZGREZWZhdWx0TGF5ZXJzKG1lcmdlZFN0YXRlLCBuZXdEYXRlRW50cmllcyk7XG4gICAgLy8gY29uc3QgcmVzdWx0ID0gbWVyZ2VkU3RhdGU7XG4gICAgbWVyZ2VkU3RhdGUgPSByZXN1bHQuc3RhdGU7XG4gICAgbmV3TGF5ZXJzID0gcmVzdWx0Lm5ld0xheWVycztcbiAgfVxuXG4gIC8vIGlmIChtZXJnZWRTdGF0ZS53aWRnZXRzLmxlbmd0aCA9PT0gc3RhdGUud2lkZ2V0cy5sZW5ndGgpIHtcbiAgLy8gICBtZXJnZWRTdGF0ZSA9IGFkZERlZmF1bHRXaWRnZXQobWVyZ2VkU3RhdGUsIG5ld0RhdGVFbnRyaWVzKTtcbiAgLy8gfVxuXG4gIGlmIChtZXJnZWRTdGF0ZS5zcGxpdE1hcHMubGVuZ3RoKSB7XG4gICAgLy8gaWYgbWFwIGlzIHNwbGl0LCBhZGQgbmV3IGxheWVycyB0byBzcGxpdE1hcHNcbiAgICBuZXdMYXllcnMgPSBtZXJnZWRTdGF0ZS5sYXllcnMuZmlsdGVyKFxuICAgICAgbCA9PiBsLmNvbmZpZy5kYXRhSWQgaW4gbmV3RGF0ZUVudHJpZXNcbiAgICApO1xuICAgIG1lcmdlZFN0YXRlID0ge1xuICAgICAgLi4ubWVyZ2VkU3RhdGUsXG4gICAgICBzcGxpdE1hcHM6IGFkZE5ld0xheWVyc1RvU3BsaXRNYXAobWVyZ2VkU3RhdGUuc3BsaXRNYXBzLCBuZXdMYXllcnMpXG4gICAgfTtcbiAgfVxuICAvLyBjb25zb2xlLmxvZyhtZXJnZWRTdGF0ZSk7XG5cbiAgLy8gbWVyZ2Ugc3RhdGUgd2l0aCBzYXZlZCBpbnRlcmFjdGlvbnNcbiAgbWVyZ2VkU3RhdGUgPSBtZXJnZUludGVyYWN0aW9ucyhtZXJnZWRTdGF0ZSwgaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkKTtcblxuICAvLyBtZXJnZSBzdGF0ZSB3aXRoIHNhdmVkIHdpZGdldHNcbiAgbWVyZ2VkU3RhdGUgPSBtZXJnZVdpZGdldHMobWVyZ2VkU3RhdGUsIHdpZGdldFRvQmVNZXJnZWQpO1xuXG4gIC8vIGlmIG5vIHRvb2x0aXBzIG1lcmdlZCBhZGQgZGVmYXVsdCB0b29sdGlwc1xuICBPYmplY3Qua2V5cyhuZXdEYXRlRW50cmllcykuZm9yRWFjaChkYXRhSWQgPT4ge1xuICAgIGNvbnN0IHRvb2x0aXBGaWVsZHMgPVxuICAgICAgbWVyZ2VkU3RhdGUuaW50ZXJhY3Rpb25Db25maWcudG9vbHRpcC5jb25maWcuZmllbGRzVG9TaG93W2RhdGFJZF07XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRvb2x0aXBGaWVsZHMpIHx8ICF0b29sdGlwRmllbGRzLmxlbmd0aCkge1xuICAgICAgbWVyZ2VkU3RhdGUgPSBhZGREZWZhdWx0VG9vbHRpcHMobWVyZ2VkU3RhdGUsIG5ld0RhdGVFbnRyaWVzW2RhdGFJZF0pO1xuICAgIH1cbiAgfSk7XG5cbiAgbGV0IHVwZGF0ZWRTdGF0ZSA9IHVwZGF0ZUFsbExheWVyRG9tYWluRGF0YShcbiAgICBtZXJnZWRTdGF0ZSxcbiAgICBPYmplY3Qua2V5cyhuZXdEYXRlRW50cmllcylcbiAgKTtcblxuICAvLyByZWdpc3RlciBsYXllciBhbmltYXRpb24gZG9tYWluLFxuICAvLyBuZWVkIHRvIGJlIGNhbGxlZCBhZnRlciBsYXllciBkYXRhIGlzIGNhbGN1bGF0ZWRcbiAgdXBkYXRlZFN0YXRlID0gdXBkYXRlQW5pbWF0aW9uRG9tYWluKHVwZGF0ZWRTdGF0ZSk7XG5cbiAgcmV0dXJuIHVwZGF0ZWRTdGF0ZTtcbn07XG4vKiBlc2xpbnQtZW5hYmxlIG1heC1zdGF0ZW1lbnRzICovXG5cbi8qKlxuICogSGlkZSBhbiBleGlzdGluZyBsYXllcnMgZnJvbSBjdXN0b20gbWFwIGxheWVyIG9iamVjdHNcbiAqIEBwYXJhbSBzdGF0ZVxuICogQHBhcmFtIHdpZGdldFxuICogQHJldHVybnMge1sqLCpdfSBNYXBzIG9mIGN1c3RvbSBsYXllciBvYmplY3RzXG4gKi9cbmZ1bmN0aW9uIHRvZ2dsZVdpZGdldEZyb21TcGxpdE1hcHMoc3RhdGUsIGxheWVyKSB7XG4gIC8vIGNvbnNvbGUubG9nKCcwJyk7XG4gIHJldHVybiBzdGF0ZS5zcGxpdE1hcHMubWFwKHNldHRpbmdzID0+IHtcbiAgICBjb25zdCB7d2lkZ2V0c30gPSBzZXR0aW5ncztcbiAgICBjb25zdCBuZXdXaWRnZXRzID0ge1xuICAgICAgLi4ud2lkZ2V0cyxcbiAgICAgIFt3aWRnZXQuaWRdOiBnZW5lcmF0ZUxheWVyTWV0YUZvclNwbGl0Vmlld3Mod2lkZ2V0KVxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2V0dGluZ3MsXG4gICAgICB3aWRnZXRzOiBuZXdXaWRnZXRzXG4gICAgfTtcbiAgfSk7XG59XG5cbi8qKlxuICogV2hlbiBhIHVzZXIgY2xpY2tzIG9uIHRoZSBzcGVjaWZpYyBtYXAgY2xvc2luZyBpY29uXG4gKiB0aGUgYXBwbGljYXRpb24gd2lsbCBjbG9zZSB0aGUgc2VsZWN0ZWQgbWFwXG4gKiBhbmQgd2lsbCBtZXJnZSB0aGUgcmVtYWluaW5nIG9uZSB3aXRoIHRoZSBnbG9iYWwgc3RhdGVcbiAqIFRPRE86IGkgdGhpbmsgaW4gdGhlIGZ1dHVyZSB0aGlzIGFjdGlvbiBzaG91bGQgYmUgY2FsbGVkIG1lcmdlIG1hcCBsYXllcnMgd2l0aCBnbG9iYWwgc2V0dGluZ3NcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdmlzU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIGFjdGlvblxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKi9cbmZ1bmN0aW9uIGNsb3NlU3BlY2lmaWNNYXBBdEluZGV4KHN0YXRlLCBhY3Rpb24pIHtcbiAgLy8gcmV0cmlldmUgbGF5ZXJzIG1ldGEgZGF0YSBmcm9tIHRoZSByZW1haW5pbmcgbWFwIHRoYXQgd2UgbmVlZCB0byBrZWVwXG4gIGNvbnN0IGluZGV4VG9SZXRyaWV2ZSA9IDEgLSBhY3Rpb24ucGF5bG9hZDtcbiAgY29uc3QgbWFwTGF5ZXJzID0gc3RhdGUuc3BsaXRNYXBzW2luZGV4VG9SZXRyaWV2ZV0ubGF5ZXJzO1xuICBjb25zdCB7bGF5ZXJzfSA9IHN0YXRlO1xuXG4gIC8vIHVwZGF0ZSBsYXllciB2aXNpYmlsaXR5XG4gIGNvbnN0IG5ld0xheWVycyA9IGxheWVycy5tYXAobGF5ZXIgPT5cbiAgICAhbWFwTGF5ZXJzW2xheWVyLmlkXSAmJiBsYXllci5jb25maWcuaXNWaXNpYmxlXG4gICAgICA/IGxheWVyLnVwZGF0ZUxheWVyQ29uZmlnKHtcbiAgICAgICAgICAvLyBpZiBsYXllci5pZCBpcyBub3QgaW4gbWFwTGF5ZXJzLCBpdCBzaG91bGQgYmUgaW5WaXNpYmxlXG4gICAgICAgICAgaXNWaXNpYmxlOiBmYWxzZVxuICAgICAgICB9KVxuICAgICAgOiBsYXllclxuICApO1xuXG4gIC8vIGRlbGV0ZSBtYXBcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBsYXllcnM6IG5ld0xheWVycyxcbiAgICBzcGxpdE1hcHM6IFtdXG4gIH07XG59XG5cbi8qKlxuICogVHJpZ2dlciBmaWxlIGxvYWRpbmcgZGlzcGF0Y2ggYGFkZERhdGFUb01hcGAgaWYgc3VjY2VlZCwgb3IgYGxvYWRGaWxlc0VycmAgaWYgZmFpbGVkXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGFjdGlvbi5maWxlcyBhcnJheSBvZiBmaWxlYmxvYlxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBsb2FkRmlsZXNVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgY29uc3Qge2ZpbGVzfSA9IGFjdGlvbjtcbiAgY29uc3QgZmlsZXNUb0xvYWQgPSBmaWxlcy5tYXAoZmlsZUJsb2IgPT4gcHJvY2Vzc0ZpbGVUb0xvYWQoZmlsZUJsb2IpKTtcbiAgLy8gcmVhZGVyIC0+IHBhcnNlciAtPiBhdWdtZW50IC0+IHJlY2VpdmVWaXNEYXRhXG4gIC8vIGNvbnNvbGUubG9nKCdMT0FEX0ZJTEVfVEFTSyBpbnNpZGUgbG9hZEZpbGVzVXBkYXRlcicsIExPQURfRklMRV9UQVNLKTtcbiAgY29uc3QgbG9hZEZpbGVUYXNrcyA9IFtcbiAgICBUYXNrLmFsbChmaWxlc1RvTG9hZC5tYXAoTE9BRF9GSUxFX1RBU0spKS5iaW1hcChyZXN1bHRzID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSByZXN1bHRzLnJlZHVjZShcbiAgICAgICAgKGYsIGMpID0+ICh7XG4gICAgICAgICAgLy8gdXNpbmcgY29uY2F0IGhlcmUgYmVjYXVzZSB0aGUgY3VycmVudCBkYXRhc2V0cyBjb3VsZCBiZSBhbiBhcnJheSBvciBhIHNpbmdsZSBpdGVtXG4gICAgICAgICAgZGF0YXNldHM6IGYuZGF0YXNldHMuY29uY2F0KGMuZGF0YXNldHMpLFxuICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZGVlcCBtZXJnZSB0aGlzIHRoaW5nIHVubGVzcyB3ZSBmaW5kIGEgYmV0dGVyIHNvbHV0aW9uXG4gICAgICAgICAgLy8gdGhpcyBjYXNlIHdpbGwgb25seSBoYXBwZW4gaWYgd2UgYWxsb3cgdG8gbG9hZCBtdWx0aXBsZSBrZXBsZXJnbCBqc29uIGZpbGVzXG4gICAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgICAuLi5mLmNvbmZpZyxcbiAgICAgICAgICAgIC4uLihjLmNvbmZpZyB8fCB7fSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgICB7ZGF0YXNldHM6IFtdLCBjb25maWc6IHt9LCBvcHRpb25zOiB7Y2VudGVyTWFwOiB0cnVlfX1cbiAgICAgICk7XG4gICAgICByZXR1cm4gYWRkRGF0YVRvTWFwKGRhdGEpO1xuICAgIH0sIGxvYWRGaWxlc0VycilcbiAgXTtcblxuICAvLyBjb25zb2xlLmxvZygnbG9hZEZpbGVUYXNrcyBpbnNpZGUgbG9hZEZpbGVzVXBkYXRlcicsIGxvYWRGaWxlVGFza3MpO1xuXG4gIHJldHVybiB3aXRoVGFzayhzdGF0ZSwgbG9hZEZpbGVUYXNrcyk7XG59O1xuXG4vKipcbiAqIFRyaWdnZXIgbG9hZGluZyBmaWxlIGVycm9yXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0geyp9IGFjdGlvbi5lcnJvclxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBsb2FkRmlsZXNFcnJVcGRhdGVyID0gKHN0YXRlLCB7ZXJyb3J9KSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgZmlsZUxvYWRpbmc6IGZhbHNlLFxuICBmaWxlTG9hZGluZ0VycjogZXJyb3Jcbn0pO1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtvYmplY3R9IGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSB7VGV4dDxPYmplY3Q+fSBhY3Rpb24uVVJMIHVybCBvZiBtYXBCb3ggdmVjdG9yIHRpbGVzXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqIEBwdWJsaWNcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbG9hZFVSTFVwZGF0ZXIoc3RhdGUsIGFjdGlvbikge1xuICBjb25zdCB7VVJMLCByYW5nZX0gPSBhY3Rpb247XG4gIHZhciBuZXdMYXllcjtcbiAgaWYgKFVSTCkge1xuICAgIGNvbnN0IGRhdGFJZCA9IGdlbmVyYXRlSGFzaElkKDQpO1xuICAgIGNvbnN0IGRhdGFzZXRzID0ge1xuICAgICAgW2RhdGFJZF06IHtcbiAgICAgICAgVVJMLFxuICAgICAgICBwb3B1bGF0aW9uUmFuZ2U6IHJhbmdlLFxuICAgICAgICBmaWVsZHM6IFtcbiAgICAgICAgICAvLyB7XG4gICAgICAgICAgLy8gICBmb3JtYXQ6ICcnLFxuICAgICAgICAgIC8vICAgaWQ6ICdfZ2VvanNvbicsXG4gICAgICAgICAgLy8gICBuYW1lOiAnX2dlb2pzb24nLFxuICAgICAgICAgIC8vICAgdGFibGVGaWVsZEluZGV4OiAxLFxuICAgICAgICAgIC8vICAgdHlwZTogJ2dlb2pzb24nXG4gICAgICAgICAgLy8gfSxcbiAgICAgICAgICAvLyB7XG4gICAgICAgICAgLy8gICBmb3JtYXQ6ICcnLFxuICAgICAgICAgIC8vICAgaWQ6ICdwb3B1bGF0aW9uJyxcbiAgICAgICAgICAvLyAgIG5hbWU6ICdQb3B1bGF0aW9uJyxcbiAgICAgICAgICAvLyAgIHRhYmxlRmllbGRJbmRleDogMixcbiAgICAgICAgICAvLyAgIHR5cGU6ICdpbnRlZ2VyJ1xuICAgICAgICAgIC8vIH1cbiAgICAgICAgXSxcbiAgICAgICAgaWQ6IGRhdGFJZCxcbiAgICAgICAgZXh0ZXJuYWxEYXRhOiB0cnVlLFxuICAgICAgICBjb2xvcjogZ2V0TmV3RGF0YXNldENvbG9yKHN0YXRlLmRhdGFzZXRzKSxcbiAgICAgICAgbGFiZWw6ICdwb3B1bGF0aW9uIGRhdGEnXG4gICAgICB9XG4gICAgfTtcbiAgICBzdGF0ZSA9IHsuLi5zdGF0ZSwgLi4uc3RhdGUuZGF0YXNldHMsIGRhdGFzZXRzfTtcbiAgICBuZXdMYXllciA9IG5ldyBzdGF0ZS5sYXllckNsYXNzZXMuTVZUKHtcbiAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgIGlzQ29uZmlnQWN0aXZlOiB0cnVlLFxuICAgICAgZGF0YUlkLFxuICAgICAgdXJsOiBVUkxcbiAgICB9KTtcblxuICAgIC8vIG5ld0xheWVyID0gbmV3IHN0YXRlLmxheWVyQ2xhc3Nlc1snbXZ0J10oKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJzOiBbLi4uc3RhdGUubGF5ZXJzLCBuZXdMYXllcl0sXG4gICAgbGF5ZXJEYXRhOiBbLi4uc3RhdGUubGF5ZXJEYXRhLCB7fV0sXG4gICAgbGF5ZXJPcmRlcjogWy4uLnN0YXRlLmxheWVyT3JkZXIsIHN0YXRlLmxheWVyT3JkZXIubGVuZ3RoXSxcbiAgICBzcGxpdE1hcHM6IGFkZE5ld0xheWVyc1RvU3BsaXRNYXAoc3RhdGUuc3BsaXRNYXBzLCBuZXdMYXllcilcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IGxvYWRFRExpbmtEYXRhID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgY29uc3Qge2RhdGEsIGRhdGFJZCwgaWR4fSA9IGFjdGlvbjtcbiAgY29uc3QgZGF0YXNldCA9IHByb2Nlc3NHZW9qc29uKGRhdGEpO1xuICBjb25zdCB2YWxpZGF0ZWREYXRhID0gdmFsaWRhdGVJbnB1dERhdGEoZGF0YXNldCk7XG4gIGlmICghdmFsaWRhdGVkRGF0YSkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuICBjb25zdCBhbGxEYXRhID0gdmFsaWRhdGVkRGF0YS5yb3dzO1xuICBjb25zdCBmaWVsZHMgPSB2YWxpZGF0ZWREYXRhLmZpZWxkcy5tYXAoKGYsIGkpID0+ICh7XG4gICAgLi4uZixcbiAgICBpZDogZi5uYW1lLFxuICAgIHRhYmxlRmllbGRJbmRleDogaSArIDFcbiAgfSkpO1xuXG4gIC8vIGNvbnN0IGlkeCA9IHN0YXRlLmxheWVycy5maW5kSW5kZXgobCA9PiBsLmNvbmZpZy5kYXRhSWQgPT09IGRhdGFJZCk7XG5cbiAgaWYgKHN0YXRlLmZpbHRlcnMubGVuZ3RoKSB7XG4gICAgY29uc3QgZmlsdGVycyA9IHN0YXRlLmZpbHRlcnMubWFwKGZpbHRlciA9PiB7XG4gICAgICBpZiAoZmlsdGVyLmRhdGFJZCA9PT0gZGF0YUlkKSB7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gZGF0YXNldC5maWVsZHNbZmlsdGVyLmZpZWxkSWR4XTtcbiAgICAgICAgZmlsdGVyID0ge1xuICAgICAgICAgIC4uLmZpbHRlcixcbiAgICAgICAgICAuLi5nZXRGaWx0ZXJQcm9wcyhhbGxEYXRhLCBmaWVsZCksXG4gICAgICAgICAgdmFsdWU6IGZpbHRlci52YWx1ZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZpbHRlcjtcbiAgICB9KTtcbiAgICBzdGF0ZSA9IHtcbiAgICAgIC4uLnN0YXRlLFxuICAgICAgZmlsdGVyc1xuICAgIH07XG4gIH1cbiAgLy8gZmlsdGVycy5tYXAoZiA9PntcbiAgLy8gICB2YXIgZmlsdGVyID0gZlxuICAvLyAgIGNvbnN0IGZpZWxkID0gZGF0YXNldC5maWVsZHNbZi5maWVsZElkeF1cbiAgLy8gICBmaWx0ZXIgPXtcbiAgLy8gICAgIC4uLmZpbHRlcixcbiAgLy8gICAgIC4uLmdldEZpbHRlclByb3BzKGRhdGFzZXRbYWxsRGF0YV0sZmllbGQpXG4gIC8vICAgfVxuICAvLyB9KVxuXG4gIC8vIGRhdGFzZXQgPSB7XG4gIC8vICAgLi4uZGF0YXNldFtkYXRhSWRdLCBhbGxEYXRhOiBhbGxEYXRhLFxuICAvLyAgIGZpZWxkczogZmllbGRzLFxuICAvLyAgIGRhdGE6IGFsbERhdGEuc2xpY2UoKSwgZmlsdGVyZWRJbmRleDogYWxsRGF0YS5tYXAoKF8sIGkpID0+IGkpLFxuICAvLyAgIGZpbHRlcmVkSW5kZXhGb3JEb21haW46IGFsbERhdGEubWFwKChfLCBpKSA9PiBpKSxcbiAgLy8gICBmaWVsZFBhaXJzOiBmaW5kUG9pbnRGaWVsZFBhaXJzKGZpZWxkcylcbiAgLy8gfVxuXG4gIC8vIGxldCBsYXllckRhdGEgPU9iamVjdC5hc3NpZ24oc3RhdGUubGF5ZXJEYXRhKTtcbiAgLy8gbGF5ZXJEYXRhW2lkeF0gPSBkYXRhLmZlYXR1cmVzO1xuXG4gIGNvbnN0IHN0YXRlV2l0aE5ld0RhdGEgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgZGF0YXNldHM6IHtcbiAgICAgIC4uLnN0YXRlLmRhdGFzZXRzLFxuICAgICAgW2RhdGFJZF06IHtcbiAgICAgICAgLi4uc3RhdGUuZGF0YXNldHNbZGF0YUlkXSxcbiAgICAgICAgYWxsRGF0YSxcbiAgICAgICAgZmllbGRzLFxuICAgICAgICAuLi5maWx0ZXJUaWxlTGF5ZXJEYXRhKFxuICAgICAgICAgIGFsbERhdGEsXG4gICAgICAgICAgc3RhdGUuZmlsdGVycyxcbiAgICAgICAgICBzdGF0ZS5sYXllcnMuZmlsdGVyKGwgPT4gbC5jb25maWcuZGF0YUlkID09PSBkYXRhSWQpXG4gICAgICAgICksXG4gICAgICAgIGZpZWxkUGFpcnM6IGZpbmRQb2ludEZpZWxkUGFpcnMoZmllbGRzKVxuICAgICAgfVxuICAgIH0sXG4gICAgbGF5ZXJEYXRhOiBzdGF0ZS5sYXllckRhdGEubWFwKChseXJEYXRhLCBpKSA9PlxuICAgICAgaSA9PT0gaWR4ID8gW2RhdGEuZmVhdHVyZXNdIDogbHlyRGF0YVxuICAgIClcbiAgfTtcblxuICByZXR1cm4gc3RhdGVXaXRoTmV3RGF0YTtcbn07XG5cbi8qKlxuICogaGVscGVyIGZ1bmN0aW9uIHRvIHVwZGF0ZSBBbGwgbGF5ZXIgZG9tYWluIGFuZCBsYXllciBkYXRhIG9mIHN0YXRlXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0YXNldHNcbiAqIEByZXR1cm5zIHtvYmplY3R9IHN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGREZWZhdWx0TGF5ZXJzKHN0YXRlLCBkYXRhc2V0cykge1xuICBjb25zdCBkZWZhdWx0TGF5ZXJzID0gT2JqZWN0LnZhbHVlcyhkYXRhc2V0cykucmVkdWNlKFxuICAgIChhY2N1LCBkYXRhc2V0KSA9PiBbXG4gICAgICAuLi5hY2N1LFxuICAgICAgLi4uKGZpbmREZWZhdWx0TGF5ZXIoZGF0YXNldCwgc3RhdGUubGF5ZXJDbGFzc2VzKSB8fCBbXSlcbiAgICBdLFxuICAgIFtdXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICBzdGF0ZToge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBsYXllcnM6IFsuLi5zdGF0ZS5sYXllcnMsIC4uLmRlZmF1bHRMYXllcnNdLFxuICAgICAgbGF5ZXJPcmRlcjogW1xuICAgICAgICAvLyBwdXQgbmV3IGxheWVycyBvbiB0b3Agb2Ygb2xkIG9uZXNcbiAgICAgICAgLi4uZGVmYXVsdExheWVycy5tYXAoKF8sIGkpID0+IHN0YXRlLmxheWVycy5sZW5ndGggKyBpKSxcbiAgICAgICAgLi4uc3RhdGUubGF5ZXJPcmRlclxuICAgICAgXVxuICAgIH0sXG4gICAgbmV3TGF5ZXJzOiBkZWZhdWx0TGF5ZXJzXG4gIH07XG59XG5cbi8qKlxuICogaGVscGVyIGZ1bmN0aW9uIHRvIHVwZGF0ZSBBbGwgbGF5ZXIgZG9tYWluIGFuZCBsYXllciBkYXRhIG9mIHN0YXRlXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0YXNldHNcbiAqIEByZXR1cm5zIHtvYmplY3R9IHN0YXRlXG4gKi9cbi8vIGV4cG9ydCBmdW5jdGlvbiBhZGREZWZhdWx0V2lkZ2V0KHN0YXRlLCBkYXRhc2V0cykge1xuLy8gICBjb25zdCBkZWZhdWx0V2lkZ2V0ID0gT2JqZWN0LnZhbHVlcyhkYXRhc2V0cykucmVkdWNlKFxuLy8gICAgIChhY2N1LCBkYXRhc2V0KSA9PiBbXG4vLyAgICAgICAuLi5hY2N1LFxuLy8gICAgICAgLi4uKGZpbmREZWZhdWx0TGF5ZXIoZGF0YXNldCwgc3RhdGUud2lkZ2V0Q2xhc3NlcykgfHwgW10pXG4vLyAgICAgXSxcbi8vICAgICBbXVxuLy8gICApO1xuLy8gICByZXR1cm4ge1xuLy8gICAgIC4uLnN0YXRlLFxuLy8gICAgIHdpZGdldHM6IFsuLi5zdGF0ZS53aWRnZXRzLCAuLi5kZWZhdWx0V2lkZ2V0XSxcbi8vICAgICBsYXllck9yZGVyOiBbXG4vLyAgICAgICAvLyBwdXQgbmV3IGxheWVycyBvbiB0b3Agb2Ygb2xkIG9uZXNcbi8vICAgICAgIC4uLmRlZmF1bHRXaWRnZXQubWFwKChfLCBpKSA9PiBzdGF0ZS53aWRnZXRzLmxlbmd0aCArIGkpLFxuLy8gICAgICAgLi4uc3RhdGUud2lkZ2V0T3JkZXJcbi8vICAgICBdXG4vLyAgIH07XG4vLyB9XG5cbi8qKlxuICogaGVscGVyIGZ1bmN0aW9uIHRvIGZpbmQgZGVmYXVsdCB0b29sdGlwc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YXNldFxuICogQHJldHVybnMge09iamVjdH0gbmV4dFN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGREZWZhdWx0VG9vbHRpcHMoc3RhdGUsIGRhdGFzZXQpIHtcbiAgY29uc3QgdG9vbHRpcEZpZWxkcyA9IGZpbmRGaWVsZHNUb1Nob3coZGF0YXNldCk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBpbnRlcmFjdGlvbkNvbmZpZzoge1xuICAgICAgLi4uc3RhdGUuaW50ZXJhY3Rpb25Db25maWcsXG4gICAgICB0b29sdGlwOiB7XG4gICAgICAgIC4uLnN0YXRlLmludGVyYWN0aW9uQ29uZmlnLnRvb2x0aXAsXG4gICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgIC8vIGZpbmQgZGVmYXVsdCBmaWVsZHMgdG8gc2hvdyBpbiB0b29sdGlwXG4gICAgICAgICAgZmllbGRzVG9TaG93OiB7XG4gICAgICAgICAgICAuLi5zdGF0ZS5pbnRlcmFjdGlvbkNvbmZpZy50b29sdGlwLmNvbmZpZy5maWVsZHNUb1Nob3csXG4gICAgICAgICAgICAuLi50b29sdGlwRmllbGRzXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byB1cGRhdGUgbGF5ZXIgZG9tYWlucyBmb3IgYW4gYXJyYXkgb2YgZGF0YXNldHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZVxuICogQHBhcmFtIHtBcnJheXxBcnJheTxzdHJpbmc+fSBkYXRhSWQgZGF0YXNldCBpZCBvciBhcnJheSBvZiBkYXRhc2V0IGlkc1xuICogQHBhcmFtIHtPYmplY3R9IG5ld0ZpbHRlciBpZiBpcyBjYWxsZWQgYnkgc2V0RmlsdGVyLCB0aGUgZmlsdGVyIHRoYXQgaGFzIGNoYW5nZWRcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQWxsTGF5ZXJEb21haW5EYXRhKHN0YXRlLCBkYXRhSWQsIG5ld0ZpbHRlcikge1xuICBjb25zdCBkYXRhSWRzID0gdHlwZW9mIGRhdGFJZCA9PT0gJ3N0cmluZycgPyBbZGF0YUlkXSA6IGRhdGFJZDtcbiAgY29uc3QgbmV3TGF5ZXJzID0gW107XG4gIGNvbnN0IG5ld0xheWVyRGF0YSA9IFtdO1xuICBzdGF0ZS5sYXllcnMuZm9yRWFjaCgob2xkTGF5ZXIsIGkpID0+IHtcbiAgICBpZiAob2xkTGF5ZXIuY29uZmlnLmRhdGFJZCAmJiBkYXRhSWRzLmluY2x1ZGVzKG9sZExheWVyLmNvbmZpZy5kYXRhSWQpKSB7XG4gICAgICAvLyBObyBuZWVkIHRvIHJlY2FsY3VsYXRlIGxheWVyIGRvbWFpbiBpZiBmaWx0ZXIgaGFzIGZpeGVkIGRvbWFpblxuICAgICAgdmFyIG5ld0xheWVyO1xuICAgICAgaWYgKG9sZExheWVyLnR5cGUgPT09ICdib3VuZGFyeScpIHtcbiAgICAgICAgbmV3TGF5ZXIgPVxuICAgICAgICAgIG5ld0ZpbHRlciAmJiBuZXdGaWx0ZXIuZml4ZWREb21haW5cbiAgICAgICAgICAgID8gb2xkTGF5ZXJcbiAgICAgICAgICAgIDogb2xkTGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oXG4gICAgICAgICAgICAgICAgc3RhdGUuZGF0YXNldHNbb2xkTGF5ZXIuY29uZmlnLmRhdGFJZF0sXG4gICAgICAgICAgICAgICAgc3RhdGUubGF5ZXJEYXRhW2ldLFxuICAgICAgICAgICAgICAgIG5ld0ZpbHRlclxuICAgICAgICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3TGF5ZXIgPVxuICAgICAgICAgIG5ld0ZpbHRlciAmJiBuZXdGaWx0ZXIuZml4ZWREb21haW5cbiAgICAgICAgICAgID8gb2xkTGF5ZXJcbiAgICAgICAgICAgIDogb2xkTGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oXG4gICAgICAgICAgICAgICAgc3RhdGUuZGF0YXNldHNbb2xkTGF5ZXIuY29uZmlnLmRhdGFJZF0sXG4gICAgICAgICAgICAgICAgbmV3RmlsdGVyXG4gICAgICAgICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YXIge2xheWVyRGF0YSwgbGF5ZXJ9ID0gY2FsY3VsYXRlTGF5ZXJEYXRhKFxuICAgICAgICBuZXdMYXllcixcbiAgICAgICAgc3RhdGUsXG4gICAgICAgIHN0YXRlLmxheWVyRGF0YVtpXVxuICAgICAgKTtcblxuICAgICAgLy8gY29uc29sZS5sb2coJ0xheWVyRGF0YScsIGxheWVyRGF0YSk7XG4gICAgICBuZXdMYXllcnMucHVzaChsYXllcik7XG4gICAgICBuZXdMYXllckRhdGEucHVzaChsYXllckRhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdMYXllcnMucHVzaChvbGRMYXllcik7XG4gICAgICBuZXdMYXllckRhdGEucHVzaChzdGF0ZS5sYXllckRhdGFbaV0pO1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJzOiBuZXdMYXllcnMsXG4gICAgbGF5ZXJEYXRhOiBuZXdMYXllckRhdGFcbiAgfTtcblxuICByZXR1cm4gbmV3U3RhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVBbmltYXRpb25Eb21haW4oc3RhdGUpIHtcbiAgLy8gbWVyZ2UgYWxsIGFuaW1hdGFibGUgbGF5ZXIgZG9tYWluIGFuZCB1cGRhdGUgZ2xvYmFsIGNvbmZpZ1xuICBjb25zdCBhbmltYXRhYmxlTGF5ZXJzID0gc3RhdGUubGF5ZXJzLmZpbHRlcihcbiAgICBsID0+XG4gICAgICBsLmNvbmZpZy5pc1Zpc2libGUgJiZcbiAgICAgIGwuY29uZmlnLmFuaW1hdGlvbiAmJlxuICAgICAgbC5jb25maWcuYW5pbWF0aW9uLmVuYWJsZWQgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkobC5hbmltYXRpb25Eb21haW4pXG4gICk7XG5cbiAgaWYgKCFhbmltYXRhYmxlTGF5ZXJzLmxlbmd0aCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIGFuaW1hdGlvbkNvbmZpZzogZGVmYXVsdEFuaW1hdGlvbkNvbmZpZ1xuICAgIH07XG4gIH1cblxuICBjb25zdCBtZXJnZWREb21haW4gPSBhbmltYXRhYmxlTGF5ZXJzLnJlZHVjZShcbiAgICAoYWNjdSwgbGF5ZXIpID0+IFtcbiAgICAgIE1hdGgubWluKGFjY3VbMF0sIGxheWVyLmFuaW1hdGlvbkRvbWFpblswXSksXG4gICAgICBNYXRoLm1heChhY2N1WzFdLCBsYXllci5hbmltYXRpb25Eb21haW5bMV0pXG4gICAgXSxcbiAgICBbTnVtYmVyKEluZmluaXR5KSwgLUluZmluaXR5XVxuICApO1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgYW5pbWF0aW9uQ29uZmlnOiB7XG4gICAgICAuLi5zdGF0ZS5hbmltYXRpb25Db25maWcsXG4gICAgICBjdXJyZW50VGltZTogaXNJblJhbmdlKHN0YXRlLmFuaW1hdGlvbkNvbmZpZy5jdXJyZW50VGltZSwgbWVyZ2VkRG9tYWluKVxuICAgICAgICA/IHN0YXRlLmFuaW1hdGlvbkNvbmZpZy5jdXJyZW50VGltZVxuICAgICAgICA6IG1lcmdlZERvbWFpblswXSxcbiAgICAgIGRvbWFpbjogbWVyZ2VkRG9tYWluXG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIGhlbHBlciBmdW5jdGlvbiB0byByZWNhbGN1bHRlIHdpZGdldCBhZ2dyZWdhdGlvbkRhdGEgZXZlcnl0aW1lIGxheWVyRGF0YSBpcyB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlXG4gKiBAcmV0dXJucyB7b2JqZWN0fSBzdGF0ZVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVXaWRnZXRBZ2dyZWdhdGlvbkRhdGEoc3RhdGUsIG1hcFN0YXRlLCBhdXRoLCBwcm9qZWN0KSB7XG4gIHZhciB3aWRnZXRzID0gc3RhdGUud2lkZ2V0cztcbiAgdmFyIG5ld1dpZGdldHMgPSBbXTtcblxuICB3aWRnZXRzLm1hcCh3ID0+IHtcbiAgICBjb25zdCB7bmV3V2lkZ2V0fSA9IHcuY2FsY3VsYXRlQWdncmVnYXRpb25EYXRhKFxuICAgICAgdyxcbiAgICAgIHN0YXRlLFxuICAgICAgbWFwU3RhdGUsXG4gICAgICBhdXRoLFxuICAgICAgcHJvamVjdFxuICAgICk7XG4gICAgbmV3V2lkZ2V0cy5wdXNoKG5ld1dpZGdldCk7XG4gIH0pO1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIHdpZGdldHM6IG5ld1dpZGdldHNcbiAgfTtcbn1cblxuLyoqXG4gKiBoZWxwZXIgZnVuY3Rpb24gdG8gdXBkYXRlIHN0YXRlc1xuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdGF0ZVxuICogQHJldHVybnMge29iamVjdH0gc3RhdGVcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoTGF5ZXJEYXRhVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtjb2xsZWN0ZWR9ID0gYWN0aW9uO1xuICBjb25zdCBuZXdMYXllciA9IGFjdGlvbi5sYXllcjtcbiAgY29uc3QgaWR4ID0gc3RhdGUubGF5ZXJzLmZpbmRJbmRleChsID0+IGwuaWQgPT09IG5ld0xheWVyLmlkKTtcbiAgdmFyIHtsYXllckRhdGEsIGxheWVyfSA9IGNhbGN1bGF0ZUxheWVyRGF0YUFmdGVyQVBJQ2FsbChcbiAgICBuZXdMYXllcixcbiAgICBzdGF0ZSxcbiAgICBzdGF0ZS5sYXllckRhdGFbaWR4XSxcbiAgICBjb2xsZWN0ZWQsXG4gICAge3NhbWVEYXRhOiB0cnVlfVxuICApO1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyRGF0YTogc3RhdGUubGF5ZXJEYXRhLm1hcCgobHlyRGF0YSwgaSkgPT5cbiAgICAgIGkgPT09IGlkeCA/IGxheWVyRGF0YSA6IGx5ckRhdGFcbiAgICApXG4gIH07XG59XG5cbi8qKlxuICogaGVscGVyIGZ1bmN0aW9uIGZvciBhc3luYyBBUEkgY2FsbFxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdGF0ZVxuICogQHJldHVybnMge29iamVjdH0gZGF0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBpQ2FsbERhdGEoc3RhdGUsIGFjdGlvbikge1xuICAvLyBjb25zb2xlLmxvZyhzdGF0ZSwgYWN0aW9uKTtcbiAgY29uc3Qge2xheWVyfSA9IGFjdGlvbjtcbiAgY29uc3Qge2FsbERhdGF9ID0gc3RhdGUuZGF0YXNldHNbbGF5ZXIuY29uZmlnLmRhdGFJZF07XG4gIC8vIGNvbnNvbGUubG9nKGFsbERhdGEpO1xuICByZXR1cm4gc3RhdGU7XG59XG5cbi8qKlxuICogdXBkYXRlIGRhdGFzZXQgbGFzdCBydW4gdGltZVxuICogQG1lbWJlcm9mIHZpc1N0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSBzdGF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWRcbiAqIEByZXR1cm4ge09iamVjdH0gbmV4dFN0YXRlXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZURhdGFzZXRJbmZvKHN0YXRlLCBhY3Rpb24pIHtcbiAgY29uc3Qge2RhdGFJZCwgdXBkYXRlZEF0fSA9IGFjdGlvbjtcblxuICBjb25zdCBuZXdTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBkYXRhc2V0czoge1xuICAgICAgLi4uc3RhdGUuZGF0YXNldHMsXG4gICAgICBbZGF0YUlkXToge1xuICAgICAgICAuLi5zdGF0ZS5kYXRhc2V0c1tkYXRhSWRdLFxuICAgICAgICBsYXN0VXBkYXRlZEF0OiB1cGRhdGVkQXRcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHJldHVybiBuZXdTdGF0ZTtcbn1cblxuLyoqXG4gKiBVcGRhdGUgdGhlIHN0YXR1cyBvZiB0aGUgZWRpdG9yXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlIHRvIHNldCB0byBlZGl0b3IgdG9cbiAqIEByZXR1cm4ge09iamVjdH0gbmV4dFN0YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBzZXRFZGl0b3JNb2RlVXBkYXRlciA9IChzdGF0ZSwge21vZGV9KSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgZWRpdG9yOiB7XG4gICAgLi4uc3RhdGUuZWRpdG9yLFxuICAgIG1vZGUsXG4gICAgc2VsZWN0ZWRGZWF0dXJlOiBudWxsXG4gIH1cbn0pO1xuXG4vLyBjb25zdCBmZWF0dXJlVG9GaWx0ZXJWYWx1ZSA9IChmZWF0dXJlKSA9PiAoey4uLmZlYXR1cmUsIGlkOiBmZWF0dXJlLmlkfSk7XG4vKipcbiAqIFVwZGF0ZSBlZGl0b3IgZmVhdHVyZXNcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHtbT2JqZWN0XX0gZmVhdHVyZXMgdG8gc3RvcmVcbiAqIEByZXR1cm4ge09iamVjdH0gbmV4dFN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRGZWF0dXJlc1VwZGF0ZXIoXG4gIHN0YXRlLFxuICB7ZmVhdHVyZXMgPSBbXSwgYXV0aCwgcHJvamVjdCwgbWFwU3RhdGV9XG4pIHtcbiAgY29uc3QgbGFzdEZlYXR1cmUgPSBmZWF0dXJlcy5sZW5ndGggJiYgZmVhdHVyZXNbZmVhdHVyZXMubGVuZ3RoIC0gMV07XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgZWRpdG9yOiB7XG4gICAgICAuLi5zdGF0ZS5lZGl0b3IsXG4gICAgICAvLyBvbmx5IHNhdmUgbm9uZSBmaWx0ZXIgZmVhdHVyZXMgdG8gZWRpdG9yXG4gICAgICBmZWF0dXJlczogZmVhdHVyZXMuZmlsdGVyKGYgPT4gIWdldEZpbHRlcklkSW5GZWF0dXJlKGYpKSxcbiAgICAgIG1vZGU6XG4gICAgICAgIGxhc3RGZWF0dXJlICYmIGxhc3RGZWF0dXJlLnByb3BlcnRpZXMuaXNDbG9zZWRcbiAgICAgICAgICA/IEVESVRPUl9NT0RFUy5FRElUXG4gICAgICAgICAgOiBzdGF0ZS5lZGl0b3IubW9kZVxuICAgIH1cbiAgfTtcblxuICAvLyBSZXRyaWV2ZSBleGlzdGluZyBmZWF0dXJlXG4gIGNvbnN0IHtzZWxlY3RlZEZlYXR1cmV9ID0gc3RhdGUuZWRpdG9yO1xuXG4gIC8vIElmIG5vIGZlYXR1cmUgaXMgc2VsZWN0ZWQgd2UgY2FuIHNpbXBseSByZXR1cm4gc2luY2Ugbm8gb3BlcmF0aW9uc1xuICBpZiAoIXNlbGVjdGVkRmVhdHVyZSkge1xuICAgIHJldHVybiBuZXdTdGF0ZTtcbiAgfVxuXG4gIC8vIFRPRE86IGNoZWNrIGlmIHRoZSBmZWF0dXJlIGhhcyBjaGFuZ2VkXG4gIGNvbnN0IGZlYXR1cmUgPSBmZWF0dXJlcy5maW5kKGYgPT4gZi5pZCA9PT0gc2VsZWN0ZWRGZWF0dXJlLmlkKTtcblxuICAvLyBpZiBmZWF0dXJlIGlzIHBhcnQgb2YgYSBmaWx0ZXJcbiAgY29uc3QgZmlsdGVySWQgPSBmZWF0dXJlICYmIGdldEZpbHRlcklkSW5GZWF0dXJlKGZlYXR1cmUpO1xuICBpZiAoZmlsdGVySWQpIHtcbiAgICBjb25zdCBmZWF0dXJlVmFsdWUgPSBmZWF0dXJlVG9GaWx0ZXJWYWx1ZShmZWF0dXJlLCBmaWx0ZXJJZCk7XG4gICAgY29uc3QgZmlsdGVySWR4ID0gc3RhdGUuZmlsdGVycy5maW5kSW5kZXgoZmlsID0+IGZpbC5pZCA9PT0gZmlsdGVySWQpO1xuICAgIHJldHVybiBzZXRGaWx0ZXJVcGRhdGVyKG5ld1N0YXRlLCB7XG4gICAgICBpZHg6IGZpbHRlcklkeCxcbiAgICAgIHByb3A6ICd2YWx1ZScsXG4gICAgICB2YWx1ZTogZmVhdHVyZVZhbHVlLFxuICAgICAgYXV0aCxcbiAgICAgIHByb2plY3QsXG4gICAgICBtYXBTdGF0ZVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG5ld1N0YXRlO1xufVxuXG4vKipcbiAqIFNldCB0aGUgY3VycmVudCBzZWxlY3RlZCBmZWF0dXJlXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHVpU3RhdGVgXG4gKiBAcGFyYW0ge1tPYmplY3RdfSBmZWF0dXJlcyB0byBzdG9yZVxuICogQHJldHVybiB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IHNldFNlbGVjdGVkRmVhdHVyZVVwZGF0ZXIgPSAoc3RhdGUsIHtmZWF0dXJlfSkgPT4gKHtcbiAgLi4uc3RhdGUsXG4gIGVkaXRvcjoge1xuICAgIC4uLnN0YXRlLmVkaXRvcixcbiAgICBzZWxlY3RlZEZlYXR1cmU6IGZlYXR1cmVcbiAgfVxufSk7XG5cbi8qKlxuICogRGVsZXRlIGV4aXN0aW5nIGZlYXR1cmUgZnJvbSBmaWx0ZXJzXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB2aXNTdGF0ZWBcbiAqIEBwYXJhbSB7c3RyaW5nfSBzZWxlY3RlZEZlYXR1cmVJZCBmZWF0dXJlIHRvIGRlbGV0ZVxuICogQHJldHVybiB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZUZlYXR1cmVVcGRhdGVyKHN0YXRlLCB7ZmVhdHVyZX0pIHtcbiAgaWYgKCFmZWF0dXJlKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgZWRpdG9yOiB7XG4gICAgICAuLi5zdGF0ZS5lZGl0b3IsXG4gICAgICBzZWxlY3RlZEZlYXR1cmU6IG51bGxcbiAgICB9XG4gIH07XG5cbiAgaWYgKGdldEZpbHRlcklkSW5GZWF0dXJlKGZlYXR1cmUpKSB7XG4gICAgY29uc3QgZmlsdGVySWR4ID0gbmV3U3RhdGUuZmlsdGVycy5maW5kSW5kZXgoXG4gICAgICBmID0+IGYuaWQgPT09IGdldEZpbHRlcklkSW5GZWF0dXJlKGZlYXR1cmUpXG4gICAgKTtcblxuICAgIHJldHVybiBmaWx0ZXJJZHggPiAtMVxuICAgICAgPyByZW1vdmVGaWx0ZXJVcGRhdGVyKG5ld1N0YXRlLCB7aWR4OiBmaWx0ZXJJZHh9KVxuICAgICAgOiBuZXdTdGF0ZTtcbiAgfVxuXG4gIC8vIG1vZGlmeSBlZGl0b3Igb2JqZWN0XG4gIGNvbnN0IG5ld0VkaXRvciA9IHtcbiAgICAuLi5zdGF0ZS5lZGl0b3IsXG4gICAgZmVhdHVyZXM6IHN0YXRlLmVkaXRvci5mZWF0dXJlcy5maWx0ZXIoZiA9PiBmLmlkICE9PSBmZWF0dXJlLmlkKSxcbiAgICBzZWxlY3RlZEZlYXR1cmU6IG51bGxcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGVkaXRvcjogbmV3RWRpdG9yXG4gIH07XG59XG5cbi8qKlxuICogVG9nZ2xlIGZlYXR1cmUgYXMgbGF5ZXIgZmlsdGVyXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHN0YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZFxuICogQHBhcmFtIHtzdHJpbmd9IHBheWxvYWQuZmVhdHVyZUlkXG4gKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZC5sYXllclxuICogQHJldHVybiB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFBvbHlnb25GaWx0ZXJMYXllclVwZGF0ZXIoc3RhdGUsIHBheWxvYWQpIHtcbiAgY29uc3Qge2xheWVyLCBmZWF0dXJlLCBhdXRoLCBwcm9qZWN0LCBtYXBTdGF0ZX0gPSBwYXlsb2FkO1xuICBjb25zdCBmaWx0ZXJJZCA9IGdldEZpbHRlcklkSW5GZWF0dXJlKGZlYXR1cmUpO1xuXG4gIC8vIGxldCBuZXdGaWx0ZXIgPSBudWxsO1xuICBsZXQgZmlsdGVySWR4O1xuICBsZXQgbmV3TGF5ZXJJZCA9IFtsYXllci5pZF07XG4gIGxldCBuZXdTdGF0ZSA9IHN0YXRlO1xuICAvLyBJZiBwb2x5Z29uIGZpbHRlciBhbHJlYWR5IGV4aXN0cywgd2UgbmVlZCB0byBmaW5kIG91dCBpZiB0aGUgY3VycmVudCBsYXllciBpcyBhbHJlYWR5IGluY2x1ZGVkXG4gIGlmIChmaWx0ZXJJZCkge1xuICAgIGZpbHRlcklkeCA9IHN0YXRlLmZpbHRlcnMuZmluZEluZGV4KGYgPT4gZi5pZCA9PT0gZmlsdGVySWQpO1xuXG4gICAgaWYgKCFzdGF0ZS5maWx0ZXJzW2ZpbHRlcklkeF0pIHtcbiAgICAgIC8vIHdoYXQgaWYgZmlsdGVyIGRvZXNuJ3QgZXhpc3Q/Li4uIG5vdCBwb3NzaWJsZS5cbiAgICAgIC8vIGJlY2F1c2UgZmVhdHVyZXMgaW4gdGhlIGVkaXRvciBpcyBwYXNzZWQgaW4gZnJvbSBmaWx0ZXJzIGFuZCBlZGl0b3JzLlxuICAgICAgLy8gYnV0IHdlIHdpbGwgbW92ZSB0aGlzIGZlYXR1cmUgYmFjayB0byBlZGl0b3IganVzdCBpbiBjYXNlXG4gICAgICBjb25zdCBub25lRmlsdGVyRmVhdHVyZSA9IHtcbiAgICAgICAgLi4uZmVhdHVyZSxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIC4uLmZlYXR1cmUucHJvcGVydGllcyxcbiAgICAgICAgICBmaWx0ZXJJZDogbnVsbFxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgZWRpdG9yOiB7XG4gICAgICAgICAgLi4uc3RhdGUuZWRpdG9yLFxuICAgICAgICAgIGZlYXR1cmVzOiBbLi4uc3RhdGUuZWRpdG9yLmZlYXR1cmVzLCBub25lRmlsdGVyRmVhdHVyZV0sXG4gICAgICAgICAgc2VsZWN0ZWRGZWF0dXJlOiBub25lRmlsdGVyRmVhdHVyZVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHtsYXllcklkfSA9IHN0YXRlLmZpbHRlcnNbZmlsdGVySWR4XSB8fCBbXTtcbiAgICBjb25zdCBpc0xheWVySW5jbHVkZWQgPSBsYXllcklkLmluY2x1ZGVzKGxheWVyLmlkKTtcbiAgICBjb25zdCBmaWx0ZXIgPSBzdGF0ZS5maWx0ZXJzW2ZpbHRlcklkeF07XG5cbiAgICBuZXdMYXllcklkID0gaXNMYXllckluY2x1ZGVkXG4gICAgICA/IC8vIGlmIGxheWVyIGlzIGluY2x1ZGVkLCByZW1vdmUgaXRcbiAgICAgICAgZmlsdGVyLmxheWVySWQuZmlsdGVyKGwgPT4gbCAhPT0gbGF5ZXIuaWQpXG4gICAgICA6IFsuLi5maWx0ZXIubGF5ZXJJZCwgbGF5ZXIuaWRdO1xuICB9IGVsc2Uge1xuICAgIC8vIGlmIHdlIGhhdmVuJ3QgY3JlYXRlIHRoZSBwb2x5Z29uIGZpbHRlciwgY3JlYXRlIGl0XG4gICAgY29uc3QgbmV3RmlsdGVyID0gZ2VuZXJhdGVQb2x5Z29uRmlsdGVyKFtdLCBmZWF0dXJlKTtcbiAgICBmaWx0ZXJJZHggPSBzdGF0ZS5maWx0ZXJzLmxlbmd0aDtcblxuICAgIC8vIGFkZCBmZWF0dXJlLCByZW1vdmUgZmVhdHVyZSBmcm9tIGVpZHRvclxuICAgIG5ld1N0YXRlID0ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBmaWx0ZXJzOiBbLi4uc3RhdGUuZmlsdGVycywgbmV3RmlsdGVyXSxcbiAgICAgIGVkaXRvcjoge1xuICAgICAgICAuLi5zdGF0ZS5lZGl0b3IsXG4gICAgICAgIGZlYXR1cmVzOiBzdGF0ZS5lZGl0b3IuZmVhdHVyZXMuZmlsdGVyKGYgPT4gZi5pZCAhPT0gZmVhdHVyZS5pZCksXG4gICAgICAgIHNlbGVjdGVkRmVhdHVyZTogbmV3RmlsdGVyLnZhbHVlXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBzZXRGaWx0ZXJVcGRhdGVyKG5ld1N0YXRlLCB7XG4gICAgaWR4OiBmaWx0ZXJJZHgsXG4gICAgcHJvcDogJ2xheWVySWQnLFxuICAgIHZhbHVlOiBuZXdMYXllcklkLFxuICAgIGF1dGgsXG4gICAgcHJvamVjdCxcbiAgICBtYXBTdGF0ZVxuICB9KTtcbn1cblxuLyoqXG4gKiBVcGRhdGUgZWRpdG9yXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHZpc1N0YXRlYFxuICogQHBhcmFtIHZpc2libGVcbiAqIEByZXR1cm4ge09iamVjdH0gbmV4dFN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b2dnbGVFZGl0b3JWaXNpYmlsaXR5KHN0YXRlLCB7dmlzaWJsZX0pIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBlZGl0b3I6IHtcbiAgICAgIC4uLnN0YXRlLmVkaXRvcixcbiAgICAgIHZpc2libGU6ICFzdGF0ZS5lZGl0b3IudmlzaWJsZVxuICAgIH1cbiAgfTtcbn1cbiJdfQ==