UNPKG

kepler.gl

Version:

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

1,132 lines (1,125 loc) 109 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.addEffect = addEffect; exports.addFilter = addFilter; exports.addLayer = addLayer; exports.applyCPUFilter = applyCPUFilter; exports.applyFilterConfig = applyFilterConfig; exports.applyLayerConfig = applyLayerConfig; exports.copyTableColumn = copyTableColumn; exports.createNewDatasetSuccess = void 0; exports.createOrUpdateFilter = createOrUpdateFilter; exports.deleteFeature = deleteFeature; exports.duplicateLayer = duplicateLayer; exports.interactionConfigChange = interactionConfigChange; exports.layerColorUIChange = layerColorUIChange; exports.layerConfigChange = layerConfigChange; exports.layerFilteredItemsChange = layerFilteredItemsChange; exports.layerSetIsValid = layerSetIsValid; exports.layerTextLabelChange = layerTextLabelChange; exports.layerToggleVisibility = layerToggleVisibility; exports.layerTypeChange = layerTypeChange; exports.layerVisConfigChange = layerVisConfigChange; exports.layerVisualChannelConfigChange = layerVisualChannelConfigChange; exports.loadFileStepSuccess = loadFileStepSuccess; exports.loadFiles = loadFiles; exports.loadFilesErr = loadFilesErr; exports.loadFilesSuccess = loadFilesSuccess; exports.loadNextFile = loadNextFile; exports.nextFileBatch = nextFileBatch; exports.onLayerClick = onLayerClick; exports.onLayerHover = onLayerHover; exports.onMapClick = onMapClick; exports.onMouseMove = onMouseMove; exports.pinTableColumn = pinTableColumn; exports.processFileContent = processFileContent; exports.removeDataset = removeDataset; exports.removeEffect = removeEffect; exports.removeFilter = removeFilter; exports.removeLayer = removeLayer; exports.renameDataset = renameDataset; exports.reorderEffect = reorderEffect; exports.reorderLayer = reorderLayer; exports.setAnimationConfig = setAnimationConfig; exports.setColumnDisplayFormat = setColumnDisplayFormat; exports.setEditorMode = setEditorMode; exports.setFeatures = setFeatures; exports.setFilter = setFilter; exports.setFilterAnimationTime = setFilterAnimationTime; exports.setFilterAnimationTimeConfig = setFilterAnimationTimeConfig; exports.setFilterAnimationWindow = setFilterAnimationWindow; exports.setFilterPlot = setFilterPlot; exports.setFilterView = setFilterView; exports.setLayerAnimationTime = setLayerAnimationTime; exports.setLayerAnimationTimeConfig = setLayerAnimationTimeConfig; exports.setMapInfo = setMapInfo; exports.setPolygonFilterLayer = setPolygonFilterLayer; exports.setSelectedFeature = setSelectedFeature; exports.setTimeFilterSyncTimelineMode = setTimeFilterSyncTimelineMode; exports.showDatasetTable = showDatasetTable; exports.sortTableColumn = sortTableColumn; exports.syncTimeFilterWithLayerTimeline = syncTimeFilterWithLayerTimeline; exports.toggleEditorVisibility = toggleEditorVisibility; exports.toggleFilterAnimation = toggleFilterAnimation; exports.toggleFilterFeature = toggleFilterFeature; exports.toggleLayerAnimation = toggleLayerAnimation; exports.toggleLayerAnimationControl = toggleLayerAnimationControl; exports.toggleLayerForMap = toggleLayerForMap; exports.updateDatasetProps = updateDatasetProps; exports.updateEffect = updateEffect; exports.updateFilterAnimationSpeed = updateFilterAnimationSpeed; exports.updateLayerAnimationSpeed = updateLayerAnimationSpeed; exports.updateLayerBlending = updateLayerBlending; exports.updateOverlayBlending = updateOverlayBlending; exports.updateTableColor = updateTableColor; exports.updateVisData = updateVisData; var _actionTypes = _interopRequireDefault(require("./action-types")); var _toolkit = require("@reduxjs/toolkit"); // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project // vis-state-reducer // TODO - import LoaderObject type from @loaders.gl/core when supported // TODO - import LoadOptions type from @loaders.gl/core when supported /** * Update layer base config: dataId, label, column, isVisible * @param oldLayerId - layer id to be updated * @param newLayerConfig - new layer config * @param layerIndex - (Optional) Index of the layer to be updated (can be useful in some cases, because * the layer id might change during update, e.g. when the type of the layer changes) * @returns action * @public */ function applyLayerConfig(oldLayerId, newLayerConfig, layerIndex) { return { type: _actionTypes["default"].APPLY_LAYER_CONFIG, oldLayerId: oldLayerId, newLayerConfig: newLayerConfig, layerIndex: layerIndex }; } /** * Update layer base config: dataId, label, column, isVisible * @param oldLayer - layer to be updated * @param newConfig - new config to be merged with old config * @returns action * @public */ function layerConfigChange(oldLayer, newConfig) { return { type: _actionTypes["default"].LAYER_CONFIG_CHANGE, oldLayer: oldLayer, newConfig: newConfig }; } /** * Update layer visibility depends on splitMap single or dual * @param layerId - layerId to be updated * @param isVisible - whether this layer is visible globally * @param splitMapId - id for this splitMap * @returns action * @public */ function layerToggleVisibility(layerId, isVisible, splitMapId) { return { type: _actionTypes["default"].LAYER_TOGGLE_VISIBILITY, layerId: layerId, isVisible: isVisible, splitMapId: splitMapId }; } /** * Update layer text label * @param oldLayer - layer to be updated * @param idx -`idx` of text label to be updated * @param prop - `prop` of text label, e,g, `anchor`, `alignment`, `color`, `size`, `field`, `outlineWidth`, `outlineColor` * @param value - new value * @returns action * @public */ function layerTextLabelChange(oldLayer, idx, prop, value) { return { type: _actionTypes["default"].LAYER_TEXT_LABEL_CHANGE, oldLayer: oldLayer, idx: idx, prop: prop, value: value }; } /** * Changes value of isValid flag for a layer. * The action also updates visibility of the layer based on isValid. * @param oldLayer - layer to be updated * @param isValid - new value for isValid flag * @returns action * @public */ function layerSetIsValid(oldLayer, isValid) { return { type: _actionTypes["default"].LAYER_SET_IS_VALID, oldLayer: oldLayer, isValid: isValid }; } /** * Update layer type. Previews layer config will be copied if applicable. * @param oldLayer - layer to be updated * @param newType - new type * @returns action * @public */ function layerTypeChange(oldLayer, newType) { return { type: _actionTypes["default"].LAYER_TYPE_CHANGE, oldLayer: oldLayer, newType: newType }; } /** * Update layer visual channel * @memberof visStateActions * @param oldLayer - layer to be updated * @param newConfig - new visual channel config * @param channel - channel to be updated * @returns action * @public */ function layerVisualChannelConfigChange(oldLayer, newConfig, channel, newVisConfig) { return { type: _actionTypes["default"].LAYER_VISUAL_CHANNEL_CHANGE, oldLayer: oldLayer, newConfig: newConfig, channel: channel, newVisConfig: newVisConfig }; } /** * Update layer `visConfig` * @memberof visStateActions * @param oldLayer - layer to be updated * @param newVisConfig - new visConfig as a key value map: e.g. `{opacity: 0.8}` * @returns action * @public */ function layerVisConfigChange(oldLayer, newVisConfig) { return { type: _actionTypes["default"].LAYER_VIS_CONFIG_CHANGE, oldLayer: oldLayer, newVisConfig: newVisConfig }; } /** * Set the color palette ui for layer color * @memberof visStateActions * @param oldLayer - layer to be updated * @param prop - which color prop * @param newConfig - to be merged * @returns action * @public */ function layerColorUIChange(oldLayer, prop, newConfig) { return { type: _actionTypes["default"].LAYER_COLOR_UI_CHANGE, oldLayer: oldLayer, prop: prop, newConfig: newConfig }; } /** * Update layer blending mode * @memberof visStateActions * @param mode one of `additive`, `normal` and `subtractive` * @returns action * @public */ function updateLayerBlending(mode) { return { type: _actionTypes["default"].UPDATE_LAYER_BLENDING, mode: mode }; } /** * Update overlay blending mode * @memberof visStateActions * @param mode one of `screen`, `normal` and `darken` * @returns action * @public */ function updateOverlayBlending(mode) { return { type: _actionTypes["default"].UPDATE_OVERLAY_BLENDING, mode: mode }; } /** * Update `interactionConfig` * @memberof visStateActions * @param config - new config as key value map: `{tooltip: {enabled: true}}` * @returns action * @public */ function interactionConfigChange(config) { return { type: _actionTypes["default"].INTERACTION_CONFIG_CHANGE, config: config }; } /** * Update filter config * @param filterId - id of the filter to be updated * @param newFilter - new filter config * @returns action * @public */ function applyFilterConfig(filterId, newFilter) { return { type: _actionTypes["default"].APPLY_FILTER_CONFIG, filterId: filterId, newFilter: newFilter }; } /** * Update filter property * @memberof visStateActions * @param idx -`idx` of filter to be updated * @param prop - `prop` of filter, e,g, `dataId`, `name`, `value` * or an array e.g. ['idx', 'name']. in that case the value * should also be an array of the corresponding values (by index) * @param value - new value * @param valueIndex - dataId index * @returns action * @public */ function setFilter(idx, prop, value, valueIndex) { return { type: _actionTypes["default"].SET_FILTER, idx: idx, prop: prop, value: value, valueIndex: valueIndex }; } /** * Same as Update filter * @memberof visStateActions * @param idx -`idx` of filter to be updated * @param prop - `prop` of filter, e,g, `dataId`, `name`, `value` * @param value - new value * @param valueIndex - dataId index * @returns action * @public */ function setFilterAnimationTime(idx, prop, value, valueIndex) { return { type: _actionTypes["default"].SET_FILTER_ANIMATION_TIME, idx: idx, prop: prop, value: value, valueIndex: valueIndex }; } /** * Same as Update filter * @memberof visStateActions * @public */ function setFilterAnimationWindow(_ref) { var id = _ref.id, animationWindow = _ref.animationWindow; return { type: _actionTypes["default"].SET_FILTER_ANIMATION_WINDOW, id: id, animationWindow: animationWindow }; } /** * Add a new filter * @memberof visStateActions * @param dataId - dataset `id` this new filter is associated with * @param id - `id` for the new filter * @returns action * @public */ function addFilter(dataId, id) { return { type: _actionTypes["default"].ADD_FILTER, dataId: dataId, id: id }; } /** * Create or updates a filter * @memberof visStateActions * @param dataId - dataset `id` this new filter is associated with * @returns action * @public */ function createOrUpdateFilter(id, dataId, field, value) { return { type: _actionTypes["default"].CREATE_OR_UPDATE_FILTER, id: id, dataId: dataId, field: field, value: value }; } /** * Add a new layer * @memberof visStateActions * @param config - new layer config * @param datasetId - dataset id used for creating an empty layer * @returns action * @public */ function addLayer(config, datasetId) { return { type: _actionTypes["default"].ADD_LAYER, config: config, datasetId: datasetId }; } /** * Reorder layer, order is an array of layer indexes, index 0 will be the one at the bottom * @memberof visStateActions * @param order an array of layer indexes * @returns action * @public * @example * * bring `layers[1]` below `layers[0]`, the sequence layers will be rendered is `layers[1].id`, `layers[0].id`, `layers[2].id`, `layers[3].id`. * `layers[1]` will be at the bottom, `layers[13]` will be at the top. * this.props.dispatch(reorderLayer([`layers[1].id`, `layers[0].id`, `layers[2].id`, `layers[3].id`])); */ function reorderLayer(order) { return { type: _actionTypes["default"].REORDER_LAYER, order: order }; } /** * Remove a filter from `visState.filters`, once a filter is removed, data will be re-filtered and layer will be updated * @memberof visStateActions * @param idx idx of filter to be removed * @returns action * @public */ function removeFilter(idx) { return { type: _actionTypes["default"].REMOVE_FILTER, idx: idx }; } /** * Remove a layer * @memberof visStateActions * @param id idx of layer to be removed * @returns action * @public */ function removeLayer(id) { return { type: _actionTypes["default"].REMOVE_LAYER, id: id }; } /** * Duplicate a layer * @memberof visStateActions * @param id id of layer to be duplicated * @returns action * @public */ function duplicateLayer(id) { return { type: _actionTypes["default"].DUPLICATE_LAYER, id: id }; } /** * Add a new effect * @memberof visStateActions * @param config - new effect config * @returns action * @public */ function addEffect(config) { return { type: _actionTypes["default"].ADD_EFFECT, config: config }; } /** * Reorder effects * @memberof visStateActions * @param order an array of effect ids * @returns action * @public */ function reorderEffect(order) { return { type: _actionTypes["default"].REORDER_EFFECT, order: order }; } /** * Remove an effect * @memberof visStateActions * @param id idx of the effect to be removed * @returns action * @public */ function removeEffect(id) { return { type: _actionTypes["default"].REMOVE_EFFECT, id: id }; } /** * Update an effect * @memberof visStateActions * @param props idx of the effect to be updated with specified props * @returns action * @public */ function updateEffect(id, props) { return { type: _actionTypes["default"].UPDATE_EFFECT, id: id, props: props }; } /** * Remove a dataset and all layers, filters, tooltip configs that based on it * @memberof visStateActions * @param dataId dataset id * @returns action * @public */ function removeDataset(dataId) { return { type: _actionTypes["default"].REMOVE_DATASET, dataId: dataId }; } /** * Display dataset table in a modal * @memberof visStateActions * @param dataId dataset id to show in table * @returns action * @public */ function showDatasetTable(dataId) { return { type: _actionTypes["default"].SHOW_DATASET_TABLE, dataId: dataId }; } /** * Update dataset color to custom by means of color picker * @memberof visStateActions * @param dataId dataset `id` this custom color is associated with * @param newColor custom color in RGBformat * @returns action * @public */ function updateTableColor(dataId, newColor) { return { type: _actionTypes["default"].UPDATE_TABLE_COLOR, dataId: dataId, newColor: newColor }; } /** * Sort dataset column, for table display * @memberof visStateActions * @param dataId * @param column * @param mode * @returns action * @public */ function sortTableColumn(dataId, column, mode) { return { type: _actionTypes["default"].SORT_TABLE_COLUMN, dataId: dataId, column: column, mode: mode }; } /** * Pin dataset column, for table display * @param dataId * @param column * @returns action * @public */ function pinTableColumn(dataId, column) { return { type: _actionTypes["default"].PIN_TABLE_COLUMN, dataId: dataId, column: column }; } /** * Copy column, for table display * @param dataId * @param column * @returns action * @public */ function copyTableColumn(dataId, column) { return { type: _actionTypes["default"].COPY_TABLE_COLUMN, dataId: dataId, column: column }; } /** * Set column display format * @param dataId * @param formats * @returns action * @public */ function setColumnDisplayFormat(dataId, formats) { return { type: _actionTypes["default"].SET_COLUMN_DISPLAY_FORMAT, dataId: dataId, formats: formats }; } // * @param dataset.info -info of a dataset // * @param dataset.info.id - id of this dataset. If config is defined, `id` should matches the `dataId` in config. // * @param dataset.info.label - A display name of this dataset // * @param dataset.data - ***required** The data object, in a tabular format with 2 properties `fields` and `rows` // * @param dataset.data.fields - ***required** Array of fields, // * @param dataset.data.fields.name - ***required** Name of the field, // * @param dataset.data.rows - ***required** Array of rows, in a tabular format with `fields` and `rows` /** * Add new dataset to `visState`, with option to load a map config along with the datasets * @memberof visStateActions * @param datasets - ***required** datasets can be a dataset or an array of datasets * Each dataset object needs to have `info` and `data` property. * @param {object} options * @param options.centerMap `default: true` if `centerMap` is set to `true` kepler.gl will * place the map view within the data points boundaries * @param options.readOnly `default: false` if `readOnly` is set to `true` * the left setting panel will be hidden * @param config this object will contain the full kepler.gl instance configuration {mapState, mapStyle, visState} * @returns action * @public */ function updateVisData(datasets, options, config) { return { type: _actionTypes["default"].UPDATE_VIS_DATA, datasets: datasets, options: options, config: config }; } /** * Rename an existing dataset in `visState` * @memberof visStateActions * @param dataId - ***required** Id of the dataset to update * @param label - ***required** New name for the dataset * @returns action * @public */ function renameDataset(dataId, label) { return { type: _actionTypes["default"].RENAME_DATASET, dataId: dataId, label: label }; } /** * Update an existing dataset props in `visState` * @param dataId - ***required** Id of the dataset to update * @param props - ***required** New props to update * @returns action */ function updateDatasetProps(dataId, props) { return { type: _actionTypes["default"].UPDATE_DATASET_PROPS, dataId: dataId, props: props }; } /** * Start and end filter animation * @memberof visStateActions * @param {Number} idx of filter * @returns action * @public */ function toggleFilterAnimation(idx) { return { type: _actionTypes["default"].TOGGLE_FILTER_ANIMATION, idx: idx }; } /** * Change filter animation speed * @memberof visStateActions * @param idx - `idx` of filter * @param speed - `speed` to change it to. `speed` is a multiplier * @returns action * @public */ function updateFilterAnimationSpeed(idx, speed) { return { type: _actionTypes["default"].UPDATE_FILTER_ANIMATION_SPEED, idx: idx, speed: speed }; } /** * Set animation config: works with both layer animation and filter animation * @param config * @returns action */ function setAnimationConfig(config) { return { type: _actionTypes["default"].SET_ANIMATION_CONFIG, config: config }; } /** * Reset animation * @memberof visStateActions * @param value - Current value of the slider * @returns action * @public */ function setLayerAnimationTime(value) { return { type: _actionTypes["default"].SET_LAYER_ANIMATION_TIME, value: value }; } /** * update trip layer animation speed * @memberof visStateActions * @param speed - `speed` to change it to. `speed` is a multiplier * @returns action * @public */ function updateLayerAnimationSpeed(speed) { return { type: _actionTypes["default"].UPDATE_LAYER_ANIMATION_SPEED, speed: speed }; } /** * start end end layer animation * @memberof visStateActions * @returns action * @public */ function toggleLayerAnimation() { return { type: _actionTypes["default"].TOGGLE_LAYER_ANIMATION }; } /** * hide and show layer animation control * @memberof visStateActions * @returns action * @public */ function toggleLayerAnimationControl() { return { type: _actionTypes["default"].TOGGLE_LAYER_ANIMATION_CONTROL }; } /** * Show larger time filter at bottom for time playback (apply to time filter only) * @memberof visStateActions * @param idx - index of filter to enlarge * @param view - type of filter view * @returns action * @public */ function setFilterView(idx, view) { return { type: _actionTypes["default"].SET_FILTER_VIEW, idx: idx, view: view }; } /** * Show/hide filter feature on map * @memberof visStateActions * @param idx - index of filter feature to show/hide * @return action */ function toggleFilterFeature(idx) { return { type: _actionTypes["default"].TOGGLE_FILTER_FEATURE, idx: idx }; } /** * Trigger layer hover event with hovered object * @memberof visStateActions * @param info - Object hovered, returned by deck.gl. * @param mapIndex - Optional property for limiting the display of the `<MapPopover>` to the `<MapContainer>` the user is interacting with. * @returns action * @public */ function onLayerHover(info, mapIndex) { return { type: _actionTypes["default"].LAYER_HOVER, info: info, mapIndex: mapIndex }; } /** * Trigger layer click event with clicked object * @memberof visStateActions * @param info - Object clicked, returned by deck.gl * @returns action * @public */ function onLayerClick(info) { return { type: _actionTypes["default"].LAYER_CLICK, info: info }; } /** * Trigger map click event, unselect clicked object * @memberof visStateActions * @returns action * @public */ function onMapClick() { return { type: _actionTypes["default"].MAP_CLICK }; } /** * Trigger map mouse moveevent, payload would be * React-map-gl MapLayerMouseEvent * https://visgl.github.io/react-map-gl/docs/api-reference/types#maplayermouseevent * * @memberof visStateActions * @param evt - MapLayerMouseEvent * @returns action * @public */ function onMouseMove(evt) { return { type: _actionTypes["default"].MOUSE_MOVE, evt: evt }; } /** * Toggle visibility of a layer in a split map * @memberof visStateActions * @param mapIndex - index of the split map * @param layerId - id of the layer * @returns action * @public */ function toggleLayerForMap(mapIndex, layerId) { return { type: _actionTypes["default"].TOGGLE_LAYER_FOR_MAP, mapIndex: mapIndex, layerId: layerId }; } /** * Set the property of a filter plot * @memberof visStateActions * @param idx * @param newProp key value mapping of new prop `{yAxis: 'histogram'}` * @param valueIndex dataId index * @returns action * @public */ function setFilterPlot(idx, newProp, valueIndex) { return { type: _actionTypes["default"].SET_FILTER_PLOT, idx: idx, newProp: newProp, valueIndex: valueIndex }; } /** * Set the property of a filter plot * @memberof visStateActions * @param info * @returns action * @public */ function setMapInfo(info) { return { type: _actionTypes["default"].SET_MAP_INFO, info: info }; } /** * Trigger file loading dispatch `addDataToMap` if succeed, or `loadFilesErr` if failed * @memberof visStateActions * @param files array of fileblob * @returns action * @public */ function loadFiles(files, onFinish) { return { type: _actionTypes["default"].LOAD_FILES, files: files, onFinish: onFinish }; } /** * Called with next file to load * @memberof visStateActions * @returns action * @public */ function loadNextFile() { return { type: _actionTypes["default"].LOAD_NEXT_FILE }; } /** * called when all files are processed and loaded * @memberof visStateActions * @param result * @returns action */ function loadFilesSuccess(result) { return { type: _actionTypes["default"].LOAD_FILES_SUCCESS, result: result }; } /** * called when successfully loaded one file, ready to move on to the next one * @memberof visStateActions * @param result * @returns action */ function loadFileStepSuccess(_ref2) { var fileName = _ref2.fileName, fileCache = _ref2.fileCache; return { type: _actionTypes["default"].LOAD_FILE_STEP_SUCCESS, fileName: fileName, fileCache: fileCache }; } /** * Trigger loading file error * @memberof visStateActions * @param error * @returns action * @public */ function loadFilesErr(fileName, error) { return { type: _actionTypes["default"].LOAD_FILES_ERR, fileName: fileName, error: error }; } /** * Store features to state * @memberof visStateActions * @param features * @returns action */ function setFeatures(features) { return { type: _actionTypes["default"].SET_FEATURES, features: features }; } /** * It will apply the provide feature as filter to the given layer. * If the given feature is already applied as filter to the layer, it will remove the layer from the filter * @memberof visStateActions * @param layer * @param feature * @returns action */ function setPolygonFilterLayer(layer, feature) { return { type: _actionTypes["default"].SET_POLYGON_FILTER_LAYER, layer: layer, feature: feature }; } /** * Set the current feature to be edited/deleted, * and the context of how the feature was selected. * @memberof visStateActions * @param feature * @param selectionContext * @returns action */ function setSelectedFeature(feature, selectionContext) { return { type: _actionTypes["default"].SET_SELECTED_FEATURE, feature: feature, selectionContext: selectionContext }; } /** * Delete the given feature * @memberof visStateActions * @param feature * @returns action */ function deleteFeature(feature) { return { type: _actionTypes["default"].DELETE_FEATURE, feature: feature }; } /** Set the map mode * @memberof visStateActions * @param mode one of EDITOR_MODES * @returns action * @public * @example * import {setMapMode} from 'kepler.gl/actions'; * import {EDITOR_MODES} from 'kepler.gl/constants'; * * this.props.dispatch(setMapMode(EDITOR_MODES.DRAW_POLYGON)); */ function setEditorMode(mode) { return { type: _actionTypes["default"].SET_EDITOR_MODE, mode: mode }; } /** * Trigger CPU filter of selected dataset * @memberof visStateActions * @param dataId - single dataId or an array of dataIds * @returns action * @public */ function applyCPUFilter(dataId) { return { type: _actionTypes["default"].APPLY_CPU_FILTER, dataId: dataId }; } /** * Toggle editor layer visibility * @memberof visStateActions * @return action */ function toggleEditorVisibility() { return { type: _actionTypes["default"].TOGGLE_EDITOR_VISIBILITY }; } /** * Process the next file batch * @memberof visStateActions * @param payload - batch payload * @return action */ function nextFileBatch(payload) { return { type: _actionTypes["default"].NEXT_FILE_BATCH, payload: payload }; } /** * Process the file content * @memberof visStateActions * @param payload - the file content * @return action */ function processFileContent(payload) { return { type: _actionTypes["default"].PROCESS_FILE_CONTENT, payload: payload }; } /** * Set layer animation time format and timezone * @memberof visStateActions * @param config - {timeFormat: string, timezone: string} * @return action */ function setLayerAnimationTimeConfig(config) { return { type: _actionTypes["default"].SET_LAYER_ANIMATION_TIME_CONFIG, config: config }; } /** * Set Filter animation time format and timezone * @memberof visStateActions * @param idx * @param config * @return action */ function setFilterAnimationTimeConfig(idx, config) { return { type: _actionTypes["default"].SET_FILTER_ANIMATION_TIME_CONFIG, idx: idx, config: config }; } /** * deck.gl layer gpu filter callback * @memberof visStateActions * @param layer * @param event * @return action */ function layerFilteredItemsChange(layer, event) { return { type: _actionTypes["default"].LAYER_FILTERED_ITEMS_CHANGE, layer: layer, event: event }; } function syncTimeFilterWithLayerTimeline(idx, enable) { return { type: _actionTypes["default"].SYNC_TIME_FILTER_WITH_LAYER_TIMELINE, idx: idx, enable: enable }; } function setTimeFilterSyncTimelineMode(_ref3) { var id = _ref3.id, mode = _ref3.mode; return { type: _actionTypes["default"].SYNC_TIME_FILTER_TIMELINE_MODE, id: id, mode: mode }; } /** * Called when a new dataset is created successfully via async table methods * @param payload * @param payload.results - results of promises.allSettlted * @returns */ var createNewDatasetSuccess = exports.createNewDatasetSuccess = (0, _toolkit.createAction)(_actionTypes["default"].CREATE_NEW_DATASET_SUCCESS); /** * This declaration is needed to group actions in docs */ /** * Actions handled mostly by `visState` reducer. * They manage how data is processed, filtered and displayed on the map by operates on layers, * filters and interaction settings. * * @public */ /* eslint-disable @typescript-eslint/no-unused-vars */ // @ts-ignore var visStateActions = null; /* eslint-enable @typescript-eslint/no-unused-vars */ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYWN0aW9uVHlwZXMiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl90b29sa2l0IiwiYXBwbHlMYXllckNvbmZpZyIsIm9sZExheWVySWQiLCJuZXdMYXllckNvbmZpZyIsImxheWVySW5kZXgiLCJ0eXBlIiwiQWN0aW9uVHlwZXMiLCJBUFBMWV9MQVlFUl9DT05GSUciLCJsYXllckNvbmZpZ0NoYW5nZSIsIm9sZExheWVyIiwibmV3Q29uZmlnIiwiTEFZRVJfQ09ORklHX0NIQU5HRSIsImxheWVyVG9nZ2xlVmlzaWJpbGl0eSIsImxheWVySWQiLCJpc1Zpc2libGUiLCJzcGxpdE1hcElkIiwiTEFZRVJfVE9HR0xFX1ZJU0lCSUxJVFkiLCJsYXllclRleHRMYWJlbENoYW5nZSIsImlkeCIsInByb3AiLCJ2YWx1ZSIsIkxBWUVSX1RFWFRfTEFCRUxfQ0hBTkdFIiwibGF5ZXJTZXRJc1ZhbGlkIiwiaXNWYWxpZCIsIkxBWUVSX1NFVF9JU19WQUxJRCIsImxheWVyVHlwZUNoYW5nZSIsIm5ld1R5cGUiLCJMQVlFUl9UWVBFX0NIQU5HRSIsImxheWVyVmlzdWFsQ2hhbm5lbENvbmZpZ0NoYW5nZSIsImNoYW5uZWwiLCJuZXdWaXNDb25maWciLCJMQVlFUl9WSVNVQUxfQ0hBTk5FTF9DSEFOR0UiLCJsYXllclZpc0NvbmZpZ0NoYW5nZSIsIkxBWUVSX1ZJU19DT05GSUdfQ0hBTkdFIiwibGF5ZXJDb2xvclVJQ2hhbmdlIiwiTEFZRVJfQ09MT1JfVUlfQ0hBTkdFIiwidXBkYXRlTGF5ZXJCbGVuZGluZyIsIm1vZGUiLCJVUERBVEVfTEFZRVJfQkxFTkRJTkciLCJ1cGRhdGVPdmVybGF5QmxlbmRpbmciLCJVUERBVEVfT1ZFUkxBWV9CTEVORElORyIsImludGVyYWN0aW9uQ29uZmlnQ2hhbmdlIiwiY29uZmlnIiwiSU5URVJBQ1RJT05fQ09ORklHX0NIQU5HRSIsImFwcGx5RmlsdGVyQ29uZmlnIiwiZmlsdGVySWQiLCJuZXdGaWx0ZXIiLCJBUFBMWV9GSUxURVJfQ09ORklHIiwic2V0RmlsdGVyIiwidmFsdWVJbmRleCIsIlNFVF9GSUxURVIiLCJzZXRGaWx0ZXJBbmltYXRpb25UaW1lIiwiU0VUX0ZJTFRFUl9BTklNQVRJT05fVElNRSIsInNldEZpbHRlckFuaW1hdGlvbldpbmRvdyIsIl9yZWYiLCJpZCIsImFuaW1hdGlvbldpbmRvdyIsIlNFVF9GSUxURVJfQU5JTUFUSU9OX1dJTkRPVyIsImFkZEZpbHRlciIsImRhdGFJZCIsIkFERF9GSUxURVIiLCJjcmVhdGVPclVwZGF0ZUZpbHRlciIsImZpZWxkIiwiQ1JFQVRFX09SX1VQREFURV9GSUxURVIiLCJhZGRMYXllciIsImRhdGFzZXRJZCIsIkFERF9MQVlFUiIsInJlb3JkZXJMYXllciIsIm9yZGVyIiwiUkVPUkRFUl9MQVlFUiIsInJlbW92ZUZpbHRlciIsIlJFTU9WRV9GSUxURVIiLCJyZW1vdmVMYXllciIsIlJFTU9WRV9MQVlFUiIsImR1cGxpY2F0ZUxheWVyIiwiRFVQTElDQVRFX0xBWUVSIiwiYWRkRWZmZWN0IiwiQUREX0VGRkVDVCIsInJlb3JkZXJFZmZlY3QiLCJSRU9SREVSX0VGRkVDVCIsInJlbW92ZUVmZmVjdCIsIlJFTU9WRV9FRkZFQ1QiLCJ1cGRhdGVFZmZlY3QiLCJwcm9wcyIsIlVQREFURV9FRkZFQ1QiLCJyZW1vdmVEYXRhc2V0IiwiUkVNT1ZFX0RBVEFTRVQiLCJzaG93RGF0YXNldFRhYmxlIiwiU0hPV19EQVRBU0VUX1RBQkxFIiwidXBkYXRlVGFibGVDb2xvciIsIm5ld0NvbG9yIiwiVVBEQVRFX1RBQkxFX0NPTE9SIiwic29ydFRhYmxlQ29sdW1uIiwiY29sdW1uIiwiU09SVF9UQUJMRV9DT0xVTU4iLCJwaW5UYWJsZUNvbHVtbiIsIlBJTl9UQUJMRV9DT0xVTU4iLCJjb3B5VGFibGVDb2x1bW4iLCJDT1BZX1RBQkxFX0NPTFVNTiIsInNldENvbHVtbkRpc3BsYXlGb3JtYXQiLCJmb3JtYXRzIiwiU0VUX0NPTFVNTl9ESVNQTEFZX0ZPUk1BVCIsInVwZGF0ZVZpc0RhdGEiLCJkYXRhc2V0cyIsIm9wdGlvbnMiLCJVUERBVEVfVklTX0RBVEEiLCJyZW5hbWVEYXRhc2V0IiwibGFiZWwiLCJSRU5BTUVfREFUQVNFVCIsInVwZGF0ZURhdGFzZXRQcm9wcyIsIlVQREFURV9EQVRBU0VUX1BST1BTIiwidG9nZ2xlRmlsdGVyQW5pbWF0aW9uIiwiVE9HR0xFX0ZJTFRFUl9BTklNQVRJT04iLCJ1cGRhdGVGaWx0ZXJBbmltYXRpb25TcGVlZCIsInNwZWVkIiwiVVBEQVRFX0ZJTFRFUl9BTklNQVRJT05fU1BFRUQiLCJzZXRBbmltYXRpb25Db25maWciLCJTRVRfQU5JTUFUSU9OX0NPTkZJRyIsInNldExheWVyQW5pbWF0aW9uVGltZSIsIlNFVF9MQVlFUl9BTklNQVRJT05fVElNRSIsInVwZGF0ZUxheWVyQW5pbWF0aW9uU3BlZWQiLCJVUERBVEVfTEFZRVJfQU5JTUFUSU9OX1NQRUVEIiwidG9nZ2xlTGF5ZXJBbmltYXRpb24iLCJUT0dHTEVfTEFZRVJfQU5JTUFUSU9OIiwidG9nZ2xlTGF5ZXJBbmltYXRpb25Db250cm9sIiwiVE9HR0xFX0xBWUVSX0FOSU1BVElPTl9DT05UUk9MIiwic2V0RmlsdGVyVmlldyIsInZpZXciLCJTRVRfRklMVEVSX1ZJRVciLCJ0b2dnbGVGaWx0ZXJGZWF0dXJlIiwiVE9HR0xFX0ZJTFRFUl9GRUFUVVJFIiwib25MYXllckhvdmVyIiwiaW5mbyIsIm1hcEluZGV4IiwiTEFZRVJfSE9WRVIiLCJvbkxheWVyQ2xpY2siLCJMQVlFUl9DTElDSyIsIm9uTWFwQ2xpY2siLCJNQVBfQ0xJQ0siLCJvbk1vdXNlTW92ZSIsImV2dCIsIk1PVVNFX01PVkUiLCJ0b2dnbGVMYXllckZvck1hcCIsIlRPR0dMRV9MQVlFUl9GT1JfTUFQIiwic2V0RmlsdGVyUGxvdCIsIm5ld1Byb3AiLCJTRVRfRklMVEVSX1BMT1QiLCJzZXRNYXBJbmZvIiwiU0VUX01BUF9JTkZPIiwibG9hZEZpbGVzIiwiZmlsZXMiLCJvbkZpbmlzaCIsIkxPQURfRklMRVMiLCJsb2FkTmV4dEZpbGUiLCJMT0FEX05FWFRfRklMRSIsImxvYWRGaWxlc1N1Y2Nlc3MiLCJyZXN1bHQiLCJMT0FEX0ZJTEVTX1NVQ0NFU1MiLCJsb2FkRmlsZVN0ZXBTdWNjZXNzIiwiX3JlZjIiLCJmaWxlTmFtZSIsImZpbGVDYWNoZSIsIkxPQURfRklMRV9TVEVQX1NVQ0NFU1MiLCJsb2FkRmlsZXNFcnIiLCJlcnJvciIsIkxPQURfRklMRVNfRVJSIiwic2V0RmVhdHVyZXMiLCJmZWF0dXJlcyIsIlNFVF9GRUFUVVJFUyIsInNldFBvbHlnb25GaWx0ZXJMYXllciIsImxheWVyIiwiZmVhdHVyZSIsIlNFVF9QT0xZR09OX0ZJTFRFUl9MQVlFUiIsInNldFNlbGVjdGVkRmVhdHVyZSIsInNlbGVjdGlvbkNvbnRleHQiLCJTRVRfU0VMRUNURURfRkVBVFVSRSIsImRlbGV0ZUZlYXR1cmUiLCJERUxFVEVfRkVBVFVSRSIsInNldEVkaXRvck1vZGUiLCJTRVRfRURJVE9SX01PREUiLCJhcHBseUNQVUZpbHRlciIsIkFQUExZX0NQVV9GSUxURVIiLCJ0b2dnbGVFZGl0b3JWaXNpYmlsaXR5IiwiVE9HR0xFX0VESVRPUl9WSVNJQklMSVRZIiwibmV4dEZpbGVCYXRjaCIsInBheWxvYWQiLCJORVhUX0ZJTEVfQkFUQ0giLCJwcm9jZXNzRmlsZUNvbnRlbnQiLCJQUk9DRVNTX0ZJTEVfQ09OVEVOVCIsInNldExheWVyQW5pbWF0aW9uVGltZUNvbmZpZyIsIlNFVF9MQVlFUl9BTklNQVRJT05fVElNRV9DT05GSUciLCJzZXRGaWx0ZXJBbmltYXRpb25UaW1lQ29uZmlnIiwiU0VUX0ZJTFRFUl9BTklNQVRJT05fVElNRV9DT05GSUciLCJsYXllckZpbHRlcmVkSXRlbXNDaGFuZ2UiLCJldmVudCIsIkxBWUVSX0ZJTFRFUkVEX0lURU1TX0NIQU5HRSIsInN5bmNUaW1lRmlsdGVyV2l0aExheWVyVGltZWxpbmUiLCJlbmFibGUiLCJTWU5DX1RJTUVfRklMVEVSX1dJVEhfTEFZRVJfVElNRUxJTkUiLCJzZXRUaW1lRmlsdGVyU3luY1RpbWVsaW5lTW9kZSIsIl9yZWYzIiwiU1lOQ19USU1FX0ZJTFRFUl9USU1FTElORV9NT0RFIiwiY3JlYXRlTmV3RGF0YXNldFN1Y2Nlc3MiLCJleHBvcnRzIiwiY3JlYXRlQWN0aW9uIiwiQ1JFQVRFX05FV19EQVRBU0VUX1NVQ0NFU1MiLCJ2aXNTdGF0ZUFjdGlvbnMiXSwic291cmNlcyI6WyIuLi9zcmMvdmlzLXN0YXRlLWFjdGlvbnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuLy8gdmlzLXN0YXRlLXJlZHVjZXJcbmltcG9ydCB7UGlja0luZm99IGZyb20gJ0BkZWNrLmdsL2NvcmUvbGliL2RlY2snO1xuaW1wb3J0IHtkZWZhdWx0IGFzIEFjdGlvblR5cGVzfSBmcm9tICcuL2FjdGlvbi10eXBlcyc7XG5pbXBvcnQge0ZpbGVDYWNoZUl0ZW19IGZyb20gJ0BrZXBsZXIuZ2wvcHJvY2Vzc29ycyc7XG5pbXBvcnQge0xheWVyLCBMYXllckJhc2VDb25maWd9IGZyb20gJ0BrZXBsZXIuZ2wvbGF5ZXJzJztcbmltcG9ydCB7S2VwbGVyVGFibGV9IGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuaW1wb3J0IHtcbiAgQWRkRGF0YVRvTWFwUGF5bG9hZCxcbiAgVmFsdWVPZixcbiAgTWVyZ2UsXG4gIFJHQkNvbG9yLFxuICBOZXN0ZWRQYXJ0aWFsLFxuICBMYXllclZpc0NvbmZpZyxcbiAgQ29sb3JVSSxcbiAgRmVhdHVyZSxcbiAgRmVhdHVyZVNlbGVjdGlvbkNvbnRleHQsXG4gIEludGVyYWN0aW9uQ29uZmlnLFxuICBGaWx0ZXIsXG4gIFBhcnNlZENvbmZpZyxcbiAgUGFyc2VkTGF5ZXIsXG4gIEVmZmVjdFByb3BzUGFydGlhbCxcbiAgU3luY1RpbWVsaW5lTW9kZSxcbiAgQW5pbWF0aW9uQ29uZmlnLFxuICBGaWx0ZXJBbmltYXRpb25Db25maWdcbn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge2NyZWF0ZUFjdGlvbn0gZnJvbSAnQHJlZHV4anMvdG9vbGtpdCc7XG5cbi8vIFRPRE8gLSBpbXBvcnQgTG9hZGVyT2JqZWN0IHR5cGUgZnJvbSBAbG9hZGVycy5nbC9jb3JlIHdoZW4gc3VwcG9ydGVkXG4vLyBUT0RPIC0gaW1wb3J0IExvYWRPcHRpb25zIHR5cGUgZnJvbSBAbG9hZGVycy5nbC9jb3JlIHdoZW4gc3VwcG9ydGVkXG5cbmV4cG9ydCB0eXBlIEFwcGx5TGF5ZXJDb25maWdVcGRhdGVyQWN0aW9uID0ge1xuICBvbGRMYXllcklkOiBzdHJpbmc7XG4gIG5ld0xheWVyQ29uZmlnOiBQYXJzZWRMYXllcjtcbiAgbGF5ZXJJbmRleD86IG51bWJlcjtcbn07XG5cbi8qKlxuICogVXBkYXRlIGxheWVyIGJhc2UgY29uZmlnOiBkYXRhSWQsIGxhYmVsLCBjb2x1bW4sIGlzVmlzaWJsZVxuICogQHBhcmFtIG9sZExheWVySWQgLSBsYXllciBpZCB0byBiZSB1cGRhdGVkXG4gKiBAcGFyYW0gbmV3TGF5ZXJDb25maWcgLSBuZXcgbGF5ZXIgY29uZmlnXG4gKiBAcGFyYW0gbGF5ZXJJbmRleCAtIChPcHRpb25hbCkgSW5kZXggb2YgdGhlIGxheWVyIHRvIGJlIHVwZGF0ZWQgKGNhbiBiZSB1c2VmdWwgaW4gc29tZSBjYXNlcywgYmVjYXVzZVxuICogICAgICAgICAgICAgICAgICAgICB0aGUgbGF5ZXIgaWQgbWlnaHQgY2hhbmdlIGR1cmluZyB1cGRhdGUsIGUuZy4gd2hlbiB0aGUgdHlwZSBvZiB0aGUgbGF5ZXIgY2hhbmdlcylcbiAqIEByZXR1cm5zIGFjdGlvblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlMYXllckNvbmZpZyhcbiAgb2xkTGF5ZXJJZDogc3RyaW5nLFxuICBuZXdMYXllckNvbmZpZzogUGFyc2VkTGF5ZXIsXG4gIGxheWVySW5kZXg/OiBudW1iZXJcbik6IE1lcmdlPEFwcGx5TGF5ZXJDb25maWdVcGRhdGVyQWN0aW9uLCB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLkFQUExZX0xBWUVSX0NPTkZJR30+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5BUFBMWV9MQVlFUl9DT05GSUcsXG4gICAgb2xkTGF5ZXJJZCxcbiAgICBuZXdMYXllckNvbmZpZyxcbiAgICBsYXllckluZGV4XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIExheWVyQ29uZmlnQ2hhbmdlVXBkYXRlckFjdGlvbiA9IHtcbiAgb2xkTGF5ZXI6IExheWVyO1xuICBuZXdDb25maWc6IFBhcnRpYWw8TGF5ZXJbJ2NvbmZpZyddPjtcbn07XG4vKipcbiAqIFVwZGF0ZSBsYXllciBiYXNlIGNvbmZpZzogZGF0YUlkLCBsYWJlbCwgY29sdW1uLCBpc1Zpc2libGVcbiAqIEBwYXJhbSBvbGRMYXllciAtIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSBuZXdDb25maWcgLSBuZXcgY29uZmlnIHRvIGJlIG1lcmdlZCB3aXRoIG9sZCBjb25maWdcbiAqIEByZXR1cm5zIGFjdGlvblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJDb25maWdDaGFuZ2UoXG4gIG9sZExheWVyOiBMYXllcixcbiAgbmV3Q29uZmlnOiBQYXJ0aWFsPExheWVyQmFzZUNvbmZpZz5cbik6IE1lcmdlPExheWVyQ29uZmlnQ2hhbmdlVXBkYXRlckFjdGlvbiwge3R5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5MQVlFUl9DT05GSUdfQ0hBTkdFfT4ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkxBWUVSX0NPTkZJR19DSEFOR0UsXG4gICAgb2xkTGF5ZXIsXG4gICAgbmV3Q29uZmlnXG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIExheWVyVG9nZ2xlVmlzaWJpbGl0eVVwZGF0ZXJBY3Rpb24gPSB7XG4gIGxheWVySWQ6IHN0cmluZztcbiAgaXNWaXNpYmxlOiBib29sZWFuO1xuICBzcGxpdE1hcElkPzogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgdmlzaWJpbGl0eSBkZXBlbmRzIG9uIHNwbGl0TWFwIHNpbmdsZSBvciBkdWFsXG4gKiBAcGFyYW0gbGF5ZXJJZCAtIGxheWVySWQgdG8gYmUgdXBkYXRlZFxuICogQHBhcmFtIGlzVmlzaWJsZSAtIHdoZXRoZXIgdGhpcyBsYXllciBpcyB2aXNpYmxlIGdsb2JhbGx5XG4gKiBAcGFyYW0gc3BsaXRNYXBJZCAtIGlkIGZvciB0aGlzIHNwbGl0TWFwXG4gKiBAcmV0dXJucyBhY3Rpb25cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxheWVyVG9nZ2xlVmlzaWJpbGl0eShcbiAgbGF5ZXJJZDogc3RyaW5nLFxuICBpc1Zpc2libGU6IGJvb2xlYW4sXG4gIHNwbGl0TWFwSWQ/OiBzdHJpbmdcbik6IE1lcmdlPExheWVyVG9nZ2xlVmlzaWJpbGl0eVVwZGF0ZXJBY3Rpb24sIHt0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuTEFZRVJfVE9HR0xFX1ZJU0lCSUxJVFl9PiB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuTEFZRVJfVE9HR0xFX1ZJU0lCSUxJVFksXG4gICAgbGF5ZXJJZCxcbiAgICBpc1Zpc2libGUsXG4gICAgc3BsaXRNYXBJZFxuICB9O1xufVxuXG5leHBvcnQgdHlwZSBMYXllclRleHRMYWJlbENoYW5nZVVwZGF0ZXJBY3Rpb24gPSB7XG4gIG9sZExheWVyOiBMYXllcjtcbiAgaWR4OiBudW1iZXIgfCAnYWxsJztcbiAgcHJvcDogc3RyaW5nO1xuICB2YWx1ZTogYW55O1xufTtcblxuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgdGV4dCBsYWJlbFxuICogQHBhcmFtIG9sZExheWVyIC0gbGF5ZXIgdG8gYmUgdXBkYXRlZFxuICogQHBhcmFtIGlkeCAtYGlkeGAgb2YgdGV4dCBsYWJlbCB0byBiZSB1cGRhdGVkXG4gKiBAcGFyYW0gcHJvcCAtIGBwcm9wYCBvZiB0ZXh0IGxhYmVsLCBlLGcsIGBhbmNob3JgLCBgYWxpZ25tZW50YCwgYGNvbG9yYCwgYHNpemVgLCBgZmllbGRgLCBgb3V0bGluZVdpZHRoYCwgYG91dGxpbmVDb2xvcmBcbiAqIEBwYXJhbSB2YWx1ZSAtIG5ldyB2YWx1ZVxuICogQHJldHVybnMgYWN0aW9uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllclRleHRMYWJlbENoYW5nZShcbiAgb2xkTGF5ZXI6IExheWVyLFxuICBpZHg6IG51bWJlciB8ICdhbGwnLFxuICBwcm9wOiBzdHJpbmcsXG4gIHZhbHVlOiBhbnlcbik6IE1lcmdlPExheWVyVGV4dExhYmVsQ2hhbmdlVXBkYXRlckFjdGlvbiwge3R5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5MQVlFUl9URVhUX0xBQkVMX0NIQU5HRX0+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9URVhUX0xBQkVMX0NIQU5HRSxcbiAgICBvbGRMYXllcixcbiAgICBpZHgsXG4gICAgcHJvcCxcbiAgICB2YWx1ZVxuICB9O1xufVxuXG5leHBvcnQgdHlwZSBMYXllclNldElzVmFsaWRVcGRhdGVyQWN0aW9uID0ge1xuICBvbGRMYXllcjogTGF5ZXI7XG4gIGlzVmFsaWQ6IGJvb2xlYW47XG59O1xuXG4vKipcbiAqIENoYW5nZXMgdmFsdWUgb2YgaXNWYWxpZCBmbGFnIGZvciBhIGxheWVyLlxuICogVGhlIGFjdGlvbiBhbHNvIHVwZGF0ZXMgdmlzaWJpbGl0eSBvZiB0aGUgbGF5ZXIgYmFzZWQgb24gaXNWYWxpZC5cbiAqIEBwYXJhbSBvbGRMYXllciAtIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSBpc1ZhbGlkIC0gbmV3IHZhbHVlIGZvciBpc1ZhbGlkIGZsYWdcbiAqIEByZXR1cm5zIGFjdGlvblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJTZXRJc1ZhbGlkKFxuICBvbGRMYXllcjogTGF5ZXIsXG4gIGlzVmFsaWQ6IGJvb2xlYW5cbik6IE1lcmdlPExheWVyU2V0SXNWYWxpZFVwZGF0ZXJBY3Rpb24sIHt0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuTEFZRVJfU0VUX0lTX1ZBTElEfT4ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkxBWUVSX1NFVF9JU19WQUxJRCxcbiAgICBvbGRMYXllcixcbiAgICBpc1ZhbGlkXG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIExheWVyVHlwZUNoYW5nZVVwZGF0ZXJBY3Rpb24gPSB7XG4gIG9sZExheWVyOiBMYXllcjtcbiAgbmV3VHlwZTogc3RyaW5nO1xufTtcbi8qKlxuICogVXBkYXRlIGxheWVyIHR5cGUuIFByZXZpZXdzIGxheWVyIGNvbmZpZyB3aWxsIGJlIGNvcGllZCBpZiBhcHBsaWNhYmxlLlxuICogQHBhcmFtIG9sZExheWVyIC0gbGF5ZXIgdG8gYmUgdXBkYXRlZFxuICogQHBhcmFtIG5ld1R5cGUgLSBuZXcgdHlwZVxuICogQHJldHVybnMgYWN0aW9uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllclR5cGVDaGFuZ2UoXG4gIG9sZExheWVyOiBMYXllcixcbiAgbmV3VHlwZTogc3RyaW5nXG4pOiBNZXJnZTxMYXllclR5cGVDaGFuZ2VVcGRhdGVyQWN0aW9uLCB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLkxBWUVSX1RZUEVfQ0hBTkdFfT4ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkxBWUVSX1RZUEVfQ0hBTkdFLFxuICAgIG9sZExheWVyLFxuICAgIG5ld1R5cGVcbiAgfTtcbn1cbmV4cG9ydCB0eXBlIExheWVyVmlzdWFsQ2hhbm5lbENvbmZpZ0NoYW5nZVVwZGF0ZXJBY3Rpb24gPSB7XG4gIG9sZExheWVyOiBMYXllcjtcbiAgbmV3Q29uZmlnOiBQYXJ0aWFsPExheWVyWydjb25maWcnXT47XG4gIGNoYW5uZWw6IHN0cmluZztcbiAgbmV3VmlzQ29uZmlnPzogUGFydGlhbDxMYXllclZpc0NvbmZpZz47XG59O1xuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgdmlzdWFsIGNoYW5uZWxcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSBvbGRMYXllciAtIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSBuZXdDb25maWcgLSBuZXcgdmlzdWFsIGNoYW5uZWwgY29uZmlnXG4gKiBAcGFyYW0gY2hhbm5lbCAtIGNoYW5uZWwgdG8gYmUgdXBkYXRlZFxuICogQHJldHVybnMgYWN0aW9uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllclZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2UoXG4gIG9sZExheWVyOiBMYXllcixcbiAgbmV3Q29uZmlnOiBQYXJ0aWFsPExheWVyQmFzZUNvbmZpZz4sXG4gIGNoYW5uZWw6IHN0cmluZyxcbiAgbmV3VmlzQ29uZmlnPzogUGFydGlhbDxMYXllclZpc0NvbmZpZz5cbik6IE1lcmdlPFxuICBMYXllclZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2VVcGRhdGVyQWN0aW9uLFxuICB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLkxBWUVSX1ZJU1VBTF9DSEFOTkVMX0NIQU5HRX1cbj4ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkxBWUVSX1ZJU1VBTF9DSEFOTkVMX0NIQU5HRSxcbiAgICBvbGRMYXllcixcbiAgICBuZXdDb25maWcsXG4gICAgY2hhbm5lbCxcbiAgICBuZXdWaXNDb25maWdcbiAgfTtcbn1cbmV4cG9ydCB0eXBlIExheWVyVmlzQ29uZmlnQ2hhbmdlVXBkYXRlckFjdGlvbiA9IHtcbiAgb2xkTGF5ZXI6IExheWVyO1xuICBuZXdWaXNDb25maWc6IFBhcnRpYWw8TGF5ZXJWaXNDb25maWc+O1xufTtcbi8qKlxuICogVXBkYXRlIGxheWVyIGB2aXNDb25maWdgXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0gb2xkTGF5ZXIgLSBsYXllciB0byBiZSB1cGRhdGVkXG4gKiBAcGFyYW0gbmV3VmlzQ29uZmlnIC0gbmV3IHZpc0NvbmZpZyBhcyBhIGtleSB2YWx1ZSBtYXA6IGUuZy4gYHtvcGFjaXR5OiAwLjh9YFxuICogQHJldHVybnMgYWN0aW9uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllclZpc0NvbmZpZ0NoYW5nZShcbiAgb2xkTGF5ZXI6IExheWVyLFxuICBuZXdWaXNDb25maWc6IFBhcnRpYWw8TGF5ZXJWaXNDb25maWc+XG4pOiBNZXJnZTxMYXllclZpc0NvbmZpZ0NoYW5nZVVwZGF0ZXJBY3Rpb24sIHt0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuTEFZRVJfVklTX0NPTkZJR19DSEFOR0V9PiB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuTEFZRVJfVklTX0NPTkZJR19DSEFOR0UsXG4gICAgb2xkTGF5ZXIsXG4gICAgbmV3VmlzQ29uZmlnXG4gIH07XG59XG5leHBvcnQgdHlwZSBMYXllckNvbG9yVUlDaGFuZ2VVcGRhdGVyQWN0aW9uID0ge1xuICBvbGRMYXllcjogTGF5ZXI7XG4gIHByb3A6IHN0cmluZztcbiAgbmV3Q29uZmlnOiBOZXN0ZWRQYXJ0aWFsPENvbG9yVUk+O1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIGNvbG9yIHBhbGV0dGUgdWkgZm9yIGxheWVyIGNvbG9yXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0gb2xkTGF5ZXIgLSBsYXllciB0byBiZSB1cGRhdGVkXG4gKiBAcGFyYW0gcHJvcCAtIHdoaWNoIGNvbG9yIHByb3BcbiAqIEBwYXJhbSBuZXdDb25maWcgLSB0byBiZSBtZXJnZWRcbiAqIEByZXR1cm5zIGFjdGlvblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJDb2xvclVJQ2hhbmdlKFxuICBvbGRMYXllcjogTGF5ZXIsXG4gIHByb3A6IHN0cmluZyxcbiAgbmV3Q29uZmlnOiBOZXN0ZWRQYXJ0aWFsPENvbG9yVUk+XG4pOiBNZXJnZTxMYXllckNvbG9yVUlDaGFuZ2VVcGRhdGVyQWN0aW9uLCB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLkxBWUVSX0NPTE9SX1VJX0NIQU5HRX0+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9DT0xPUl9VSV9DSEFOR0UsXG4gICAgb2xkTGF5ZXIsXG4gICAgcHJvcCxcbiAgICBuZXdDb25maWdcbiAgfTtcbn1cblxuZXhwb3J0IHR5cGUgVXBkYXRlTGF5ZXJCbGVuZGluZ1VwZGF0ZXJBY3Rpb24gPSB7XG4gIG1vZGU6ICdhZGRpdGl2ZScgfCAnbm9ybWFsJyB8ICdzdWJ0cmFjdGl2ZSc7XG59O1xuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgYmxlbmRpbmcgbW9kZVxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIG1vZGUgb25lIG9mIGBhZGRpdGl2ZWAsIGBub3JtYWxgIGFuZCBgc3VidHJhY3RpdmVgXG4gKiBAcmV0dXJucyBhY3Rpb25cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUxheWVyQmxlbmRpbmcoXG4gIG1vZGU6ICdhZGRpdGl2ZScgfCAnbm9ybWFsJyB8ICdzdWJ0cmFjdGl2ZSdcbik6IE1lcmdlPFVwZGF0ZUxheWVyQmxlbmRpbmdVcGRhdGVyQWN0aW9uLCB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLlVQREFURV9MQVlFUl9CTEVORElOR30+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5VUERBVEVfTEFZRVJfQkxFTkRJTkcsXG4gICAgbW9kZVxuICB9O1xufVxuXG5leHBvcnQgdHlwZSBVcGRhdGVPdmVybGF5QmxlbmRpbmdVcGRhdGVyQWN0aW9uID0ge1xuICBtb2RlOiAnc2NyZWVuJyB8ICdub3JtYWwnIHwgJ2Rhcmtlbic7XG59O1xuXG4vKipcbiAqIFVwZGF0ZSBvdmVybGF5IGJsZW5kaW5nIG1vZGVcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSBtb2RlIG9uZSBvZiBgc2NyZWVuYCwgYG5vcm1hbGAgYW5kIGBkYXJrZW5gXG4gKiBAcmV0dXJucyBhY3Rpb25cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZU92ZXJsYXlCbGVuZGluZyhcbiAgbW9kZTogJ3NjcmVlbicgfCAnbm9ybWFsJyB8ICdkYXJrZW4nXG4pOiBNZXJnZTxVcGRhdGVPdmVybGF5QmxlbmRpbmdVcGRhdGVyQWN0aW9uLCB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLlVQREFURV9PVkVSTEFZX0JMRU5ESU5HfT4ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLlVQREFURV9PVkVSTEFZX0JMRU5ESU5HLFxuICAgIG1vZGVcbiAgfTtcbn1cblxuZXhwb3J0IHR5cGUgSW50ZXJhY3Rpb25Db25maWdDaGFuZ2VVcGRhdGVyQWN0aW9uID0ge1xuICBjb25maWc6IFZhbHVlT2Y8SW50ZXJhY3Rpb25Db25maWc+O1xufTtcbi8qKlxuICogVXBkYXRlIGBpbnRlcmFjdGlvbkNvbmZpZ2BcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSBjb25maWcgLSBuZXcgY29uZmlnIGFzIGtleSB2YWx1ZSBtYXA6IGB7dG9vbHRpcDoge2VuYWJsZWQ6IHRydWV9fWBcbiAqIEByZXR1cm5zIGFjdGlvblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJhY3Rpb25Db25maWdDaGFuZ2UoXG4gIGNvbmZpZzogVmFsdWVPZjxJbnRlcmFjdGlvbkNvbmZpZz5cbik6IE1lcmdlPFxuICBJbnRlcmFjdGlvbkNvbmZpZ0NoYW5nZVVwZGF0ZXJBY3Rpb24sXG4gIHt0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuSU5URVJBQ1RJT05fQ09ORklHX0NIQU5HRX1cbj4ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLklOVEVSQUNUSU9OX0NPTkZJR19DSEFOR0UsXG4gICAgY29uZmlnXG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIEFwcGx5RmlsdGVyQ29uZmlnVXBkYXRlckFjdGlvbiA9IHtcbiAgZmlsdGVySWQ6IHN0cmluZztcbiAgbmV3RmlsdGVyOiBGaWx0ZXI7XG59O1xuXG4vKipcbiAqIFVwZGF0ZSBmaWx0ZXIgY29uZmlnXG4gKiBAcGFyYW0gZmlsdGVySWQgLSBpZCBvZiB0aGUgZmlsdGVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSBuZXdGaWx0ZXIgLSBuZXcgZmlsdGVyIGNvbmZpZ1xuICogQHJldHVybnMgYWN0aW9uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseUZpbHRlckNvbmZpZyhcbiAgZmlsdGVySWQ6IHN0cmluZyxcbiAgbmV3RmlsdGVyOiBGaWx0ZXJcbik6IE1lcmdlPEFwcGx5RmlsdGVyQ29uZmlnVXBkYXRlckFjdGlvbiwge3R5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5BUFBMWV9GSUxURVJfQ09ORklHfT4ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkFQUExZX0ZJTFRFUl9DT05GSUcsXG4gICAgZmlsdGVySWQsXG4gICAgbmV3RmlsdGVyXG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIFNldEZpbHRlclVwZGF0ZXJBY3Rpb24gPSB7XG4gIGlkeDogbnVtYmVyO1xuICBwcm9wOiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgdmFsdWU6IGFueTtcbiAgdmFsdWVJbmRleD86IG51bWJlcjtcbn07XG4vKipcbiAqIFVwZGF0ZSBmaWx0ZXIgcHJvcGVydHlcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSBpZHggLWBpZHhgIG9mIGZpbHRlciB0byBiZSB1cGRhdGVkXG4gKiBAcGFyYW0gcHJvcCAtIGBwcm9wYCBvZiBmaWx0ZXIsIGUsZywgYGRhdGFJZGAsIGBuYW1lYCwgYHZhbHVlYFxuICogICAgICAgICAgICAgICAgb3IgYW4gYXJyYXkgZS5nLiBbJ2lkeCcsICduYW1lJ10uIGluIHRoYXQgY2FzZSB0aGUgdmFsdWVcbiAqICAgICAgICAgICAgICAgIHNob3VsZCBhbHNvIGJlIGFuIGFycmF5IG9mIHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlcyAoYnkgaW5kZXgpXG4gKiBAcGFyYW0gdmFsdWUgLSBuZXcgdmFsdWVcbiAqIEBwYXJhbSB2YWx1ZUluZGV4IC0gZGF0YUlkIGluZGV4XG4gKiBAcmV0dXJucyBhY3Rpb25cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEZpbHRlcihcbiAgaWR4OiBudW1iZXIsXG4gIHByb3A6IHN0cmluZyB8IHN0cmluZ1tdLFxuICB2YWx1ZTogYW55LFxuICB2YWx1ZUluZGV4PzogbnVtYmVyXG4pOiBNZXJnZTxTZXRGaWx0ZXJVcGRhdGVyQWN0aW9uLCB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLlNFVF9GSUxURVJ9PiB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuU0VUX0ZJTFRFUixcbiAgICBpZHgsXG4gICAgcHJvcCxcbiAgICB2YWx1ZSxcbiAgICB2YWx1ZUluZGV4XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIFNldEZpbHRlckFuaW1hdGlvblRpbWVVcGRhdGVyQWN0aW9uID0ge1xuICBpZHg6IG51bWJlcjtcbiAgcHJvcDogc3RyaW5nO1xuICB2YWx1ZTogYW55O1xuICB2YWx1ZUluZGV4PzogbnVtYmVyO1xufTtcbi8qKlxuICogU2FtZSBhcyBVcGRhdGUgZmlsdGVyXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0gaWR4IC1gaWR4YCBvZiBmaWx0ZXIgdG8gYmUgdXBkYXRlZFxuICogQHBhcmFtIHByb3AgLSBgcHJvcGAgb2YgZmlsdGVyLCBlLGcsIGBkYXRhSWRgLCBgbmFtZWAsIGB2YWx1ZWBcbiAqIEBwYXJhbSB2YWx1ZSAtIG5ldyB2YWx1ZVxuICogQHBhcmFtIHZhbHVlSW5kZXggLSBkYXRhSWQgaW5kZXhcbiAqIEByZXR1cm5zIGFjdGlvblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0RmlsdGVyQW5pbWF0aW9uVGltZShcbiAgaWR4OiBudW1iZXIsXG4gIHByb3A6IHN0cmluZyxcbiAgdmFsdWU6IGFueSxcbiAgdmFsdWVJbmRleD86IG51bWJlclxuKTogTWVyZ2U8XG4gIFNldEZpbHRlckFuaW1hdGlvblRpbWVVcGRhdGVyQWN0aW9uLFxuICB7dHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLlNFVF9GSUxURVJfQU5JTUFUSU9OX1RJTUV9XG4+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5TRVRfRklMVEVSX0FOSU1BVElPTl9USU1FLFxuICAgIGlkeCxcbiAgICBwcm9wLFxuICAgIHZhbHVlLFxuICAgIHZhbHVlSW5kZXhcbiAgfTtcbn1cblxuZXhwb3J0IHR5cGUgU2V0RmlsdGVyQW5pbWF0aW9uV2luZG93VXBkYXRlckFjdGlvbiA9IHtcbiAgaWQ6IHN0cmluZztcbiAgYW5pbWF0aW9uV2luZG93OiBzdHJpbmc7XG59O1xuLyoqXG4gKiBTYW1lIGFzIFVwZGF0ZSBmaWx0ZXJcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEZpbHRlckFuaW1hdGlvbldpbmRvdyh7XG4gIGlkLFxuICBhbmltYXRpb25XaW5kb3dcbn06IFNldEZpbHRlckFuaW1hdGlvbldpbmRvd1VwZGF0ZXJBY3Rpb24pOiBNZXJnZTxcbiAgU2V0RmlsdGVyQW5pbWF0aW9uV2luZG93VXBkYXRlckFjdGlvbixcbiAge3R5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5TRVRfRklMVEVSX0FOSU1BVElPTl9XSU5ET1d9XG4+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5TRVRfRklMVEVSX0FOSU1BVElPTl9XSU5ET1csXG4gICAgaWQsXG4gICAgYW5pbWF0aW9uV2luZG93XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIEFkZEZpbHRlclVwZGF0ZXJBY3Rpb24gPSB7XG4gIGRhdGFJZD86IHN0cmluZyB8IHN0cmluZ1tdIHwgbnVsbDtcbiAgaWQ/OiBzdHJpbmc7XG59O1xuLyoqXG4gKiBBZGQgYSBuZXcgZmlsdGVyXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0gZGF0YUlkIC0gZGF0YXNldCBgaWRgIHRoaXM