UNPKG

kepler.gl.geoiq

Version:

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

194 lines (181 loc) 21.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.resetMapConfig = exports.receiveMapConfig = exports.keplerGlInit = exports.addDataToMap = void 0; var _actionTypes = _interopRequireDefault(require("../constants/action-types")); var _reduxActions = require("redux-actions"); // Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. /** * Add data to kepler.gl reducer, prepare map with preset configuration if config is passed. * Kepler.gl provides a handy set of utils to parse data from different format to the `data` object required in dataset. You rarely need to manually format the data obejct. * * Use `KeplerGlSchema.getConfigToSave` to generate a json blob of the currents instance config. * The config object value will always have higher precedence than the options properties. * * Kepler.gl uses `dataId` in the config to match with loaded dataset. If you pass a config object, you need * to match the `info.id` of your dataset to the `dataId` in each `layer`, `filter` and `interactionConfig.tooltips.fieldsToShow` * * @memberof main * @param {Object} data * @param {Array<Object>|Object} data.datasets - ***required** datasets can be a dataset or an array of datasets * Each dataset object needs to have `info` and `data` property. * @param {Object} data.datasets.info -info of a dataset * @param {string} data.datasets.info.id - id of this dataset. If config is defined, `id` should matches the `dataId` in config. * @param {string} data.datasets.info.label - A display name of this dataset * @param {Object} data.datasets.data - ***required** The data object, in a tabular format with 2 properties `fields` and `rows` * @param {Array<Object>} data.datasets.data.fields - ***required** Array of fields, * @param {string} data.datasets.data.fields.name - ***required** Name of the field, * @param {Array<Array>} data.datasets.data.rows - ***required** Array of rows, in a tabular format with `fields` and `rows` * * @param {Object} data.options * @param {boolean} data.options.centerMap `default: true` if `centerMap` is set to `true` kepler.gl will * place the map view within the data points boundaries. `options.centerMap` will override `config.mapState` if passed in. * @param {boolean} data.options.readOnly `default: false` if `readOnly` is set to `true` * the left setting panel will be hidden * @param {boolean} data.options.keepExistingConfig whether to keep exiting map data and associated layer filter interaction config `default: false`. * @param {Object} data.config this object will contain the full kepler.gl instance configuration {mapState, mapStyle, visState} * @public * @example * * // app.js * import {addDataToMap} from 'kepler.gl/actions'; * * const sampleTripData = { * fields: [ * {name: 'tpep_pickup_datetime', format: 'YYYY-M-D H:m:s', type: 'timestamp'}, * {name: 'pickup_longitude', format: '', type: 'real'}, * {name: 'pickup_latitude', format: '', type: 'real'} * ], * rows: [ * ['2015-01-15 19:05:39 +00:00', -73.99389648, 40.75011063], * ['2015-01-15 19:05:39 +00:00', -73.97642517, 40.73981094], * ['2015-01-15 19:05:40 +00:00', -73.96870422, 40.75424576], * ] * }; * * const sampleConfig = { * visState: { * filters: [ * { * id: 'me', * dataId: 'test_trip_data', * name: 'tpep_pickup_datetime', * type: 'timeRange', * enlarged: true * } * ] * } * } * * this.props.dispatch( * addDataToMap({ * datasets: { * info: { * label: 'Sample Taxi Trips in New York City', * id: 'test_trip_data' * }, * data: sampleTripData * }, * option: { * centerMap: true, * readOnly: false, * keepExistingConfig: false * }, * config: sampleConfig * }) * ); */ var addDataToMap = exports.addDataToMap = (0, _reduxActions.createAction)(_actionTypes["default"].ADD_DATA_TO_MAP, function (data) { return data; }); /** * Reset all sub-reducers to its initial state. This can be used to clear out all configuration in the reducer. * @memberof main * @public */ var resetMapConfig = exports.resetMapConfig = (0, _reduxActions.createAction)(_actionTypes["default"].RESET_MAP_CONFIG); /** * Pass config to kepler.gl instance, prepare the state with preset configs. * Calling `KeplerGlSchema.parseSavedConfig` to convert saved config before passing it in is required. * * You can call `receiveMapConfig` before passing in any data. The reducer will store layer and filter config, waiting for * data to come in. When data arrives, you can call `addDataToMap` without passing any config, and the reducer will try to match * preloaded configs. This behavior is designed to allow asynchronous data loading. * * It is also useful when you want to prepare the kepler.gl instance with some preset layer and filter settings. * **Note** Sequence is important, `receiveMapConfig` needs to be called __before__ data is loaded. Currently kepler.gl doesn't allow calling `receiveMapConfig` after data is loaded. * It will reset current configuration first then apply config to it. * @memberof main * @param {Object} config - ***required** The Config Object * @param {Object} options - ***optional** The Option object * @param {boolean} options.centerMap `default: true` if `centerMap` is set to `true` kepler.gl will * place the map view within the data points boundaries * @param {boolean} options.readOnly `default: false` if `readOnly` is set to `true` * the left setting panel will be hidden * @param {boolean} options.keepExistingConfig whether to keep exiting layer filter and interaction config `default: false`. * @public * @example * import {receiveMapConfig} from 'kepler.gl/actions'; * import KeplerGlSchema from 'kepler.gl/schemas'; * * const parsedConfig = KeplerGlSchema.parseSavedConfig(config); * this.props.dispatch(receiveMapConfig(parsedConfig)); */ var receiveMapConfig = exports.receiveMapConfig = (0, _reduxActions.createAction)(_actionTypes["default"].RECEIVE_MAP_CONFIG, function (config, options) { return { config: config, options: options }; }); /** * Initialize kepler.gl reducer. It is used to pass in `mapboxApiAccessToken` to `mapStyle` reducer. * @memberof main * @param {Object} payload * @param {string} payload.mapboxApiAccessToken - mapboxApiAccessToken to be saved to mapStyle reducer * @param {string} payload.mapboxApiUrl - mapboxApiUrl to be saved to mapStyle reducer. * @param {Boolean} payload.mapStylesReplaceDefault - mapStylesReplaceDefault to be saved to mapStyle reducer * @public */ var keplerGlInit = exports.keplerGlInit = (0, _reduxActions.createAction)(_actionTypes["default"].INIT, function () { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, mapboxApiAccessToken = _ref.mapboxApiAccessToken, mapboxApiUrl = _ref.mapboxApiUrl, mapStylesReplaceDefault = _ref.mapStylesReplaceDefault; return { mapboxApiAccessToken: mapboxApiAccessToken, mapboxApiUrl: mapboxApiUrl, mapStylesReplaceDefault: mapStylesReplaceDefault }; }); /** * This declaration is needed to group actions in docs */ /** * Main kepler.gl actions, these actions handles loading data and config into kepler.gl reducer. These actions * is listened by all subreducers, * @public */ /* eslint-disable no-unused-vars */ var main = null; /* eslint-enable no-unused-vars */ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hY3Rpb25zL2FjdGlvbnMuanMiXSwibmFtZXMiOlsiYWRkRGF0YVRvTWFwIiwiQWN0aW9uVHlwZXMiLCJBRERfREFUQV9UT19NQVAiLCJkYXRhIiwicmVzZXRNYXBDb25maWciLCJSRVNFVF9NQVBfQ09ORklHIiwicmVjZWl2ZU1hcENvbmZpZyIsIlJFQ0VJVkVfTUFQX0NPTkZJRyIsImNvbmZpZyIsIm9wdGlvbnMiLCJrZXBsZXJHbEluaXQiLCJJTklUIiwibWFwYm94QXBpQWNjZXNzVG9rZW4iLCJtYXBib3hBcGlVcmwiLCJtYXBTdHlsZXNSZXBsYWNlRGVmYXVsdCIsIm1haW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBS0U7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0ZLLElBQU1BLFlBQVksMEJBQUcsZ0NBQzFCQyx3QkFBWUMsZUFEYyxFQUUxQixVQUFBQyxJQUFJO0FBQUEsU0FBSUEsSUFBSjtBQUFBLENBRnNCLENBQXJCO0FBS1A7Ozs7OztBQUtPLElBQU1DLGNBQWMsNEJBQUcsZ0NBQzVCSCx3QkFBWUksZ0JBRGdCLENBQXZCO0FBSVA7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEyQk8sSUFBTUMsZ0JBQWdCLDhCQUFHLGdDQUM5Qkwsd0JBQVlNLGtCQURrQixFQUU5QixVQUFDQyxNQUFELEVBQVNDLE9BQVQ7QUFBQSxTQUFzQjtBQUFDRCxJQUFBQSxNQUFNLEVBQU5BLE1BQUQ7QUFBU0MsSUFBQUEsT0FBTyxFQUFQQTtBQUFULEdBQXRCO0FBQUEsQ0FGOEIsQ0FBekI7QUFLUDs7Ozs7Ozs7OztBQVNPLElBQU1DLFlBQVksMEJBQUcsZ0NBQzFCVCx3QkFBWVUsSUFEYyxFQUUxQjtBQUFBLGlGQUFpRSxFQUFqRTtBQUFBLE1BQUVDLG9CQUFGLFFBQUVBLG9CQUFGO0FBQUEsTUFBd0JDLFlBQXhCLFFBQXdCQSxZQUF4QjtBQUFBLE1BQXNDQyx1QkFBdEMsUUFBc0NBLHVCQUF0Qzs7QUFBQSxTQUF5RTtBQUFDRixJQUFBQSxvQkFBb0IsRUFBcEJBLG9CQUFEO0FBQXVCQyxJQUFBQSxZQUFZLEVBQVpBLFlBQXZCO0FBQXFDQyxJQUFBQSx1QkFBdUIsRUFBdkJBO0FBQXJDLEdBQXpFO0FBQUEsQ0FGMEIsQ0FBckI7QUFLUDs7OztBQUdBOzs7Ozs7QUFLQTs7QUFDQSxJQUFNQyxJQUFJLEdBQUcsSUFBYjtBQUNBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIzIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IEFjdGlvblR5cGVzIGZyb20gJ2NvbnN0YW50cy9hY3Rpb24tdHlwZXMnO1xuaW1wb3J0IHtjcmVhdGVBY3Rpb259IGZyb20gJ3JlZHV4LWFjdGlvbnMnO1xuXG4gIC8qKlxuICAgKiBBZGQgZGF0YSB0byBrZXBsZXIuZ2wgcmVkdWNlciwgcHJlcGFyZSBtYXAgd2l0aCBwcmVzZXQgY29uZmlndXJhdGlvbiBpZiBjb25maWcgaXMgcGFzc2VkLlxuICAgKiBLZXBsZXIuZ2wgcHJvdmlkZXMgYSBoYW5keSBzZXQgb2YgdXRpbHMgdG8gcGFyc2UgZGF0YSBmcm9tIGRpZmZlcmVudCBmb3JtYXQgdG8gdGhlIGBkYXRhYCBvYmplY3QgcmVxdWlyZWQgaW4gZGF0YXNldC4gWW91IHJhcmVseSBuZWVkIHRvIG1hbnVhbGx5IGZvcm1hdCB0aGUgZGF0YSBvYmVqY3QuXG4gICAqXG4gICAqIFVzZSBgS2VwbGVyR2xTY2hlbWEuZ2V0Q29uZmlnVG9TYXZlYCB0byBnZW5lcmF0ZSBhIGpzb24gYmxvYiBvZiB0aGUgY3VycmVudHMgaW5zdGFuY2UgY29uZmlnLlxuICAgKiBUaGUgY29uZmlnIG9iamVjdCB2YWx1ZSB3aWxsIGFsd2F5cyBoYXZlIGhpZ2hlciBwcmVjZWRlbmNlIHRoYW4gdGhlIG9wdGlvbnMgcHJvcGVydGllcy5cbiAgICpcbiAgICogS2VwbGVyLmdsIHVzZXMgYGRhdGFJZGAgaW4gdGhlIGNvbmZpZyB0byBtYXRjaCB3aXRoIGxvYWRlZCBkYXRhc2V0LiBJZiB5b3UgcGFzcyBhIGNvbmZpZyBvYmplY3QsIHlvdSBuZWVkXG4gICAqIHRvIG1hdGNoIHRoZSBgaW5mby5pZGAgb2YgeW91ciBkYXRhc2V0IHRvIHRoZSBgZGF0YUlkYCBpbiBlYWNoIGBsYXllcmAsIGBmaWx0ZXJgIGFuZCBgaW50ZXJhY3Rpb25Db25maWcudG9vbHRpcHMuZmllbGRzVG9TaG93YFxuICAgKlxuICAgKiBAbWVtYmVyb2YgbWFpblxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICAgKiBAcGFyYW0ge0FycmF5PE9iamVjdD58T2JqZWN0fSBkYXRhLmRhdGFzZXRzIC0gKioqcmVxdWlyZWQqKiBkYXRhc2V0cyBjYW4gYmUgYSBkYXRhc2V0IG9yIGFuIGFycmF5IG9mIGRhdGFzZXRzXG4gICAqIEVhY2ggZGF0YXNldCBvYmplY3QgbmVlZHMgdG8gaGF2ZSBgaW5mb2AgYW5kIGBkYXRhYCBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEuZGF0YXNldHMuaW5mbyAtaW5mbyBvZiBhIGRhdGFzZXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEuZGF0YXNldHMuaW5mby5pZCAtIGlkIG9mIHRoaXMgZGF0YXNldC4gSWYgY29uZmlnIGlzIGRlZmluZWQsIGBpZGAgc2hvdWxkIG1hdGNoZXMgdGhlIGBkYXRhSWRgIGluIGNvbmZpZy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEuZGF0YXNldHMuaW5mby5sYWJlbCAtIEEgZGlzcGxheSBuYW1lIG9mIHRoaXMgZGF0YXNldFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YS5kYXRhc2V0cy5kYXRhIC0gKioqcmVxdWlyZWQqKiBUaGUgZGF0YSBvYmplY3QsIGluIGEgdGFidWxhciBmb3JtYXQgd2l0aCAyIHByb3BlcnRpZXMgYGZpZWxkc2AgYW5kIGByb3dzYFxuICAgKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGRhdGEuZGF0YXNldHMuZGF0YS5maWVsZHMgLSAqKipyZXF1aXJlZCoqIEFycmF5IG9mIGZpZWxkcyxcbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEuZGF0YXNldHMuZGF0YS5maWVsZHMubmFtZSAtICoqKnJlcXVpcmVkKiogTmFtZSBvZiB0aGUgZmllbGQsXG4gICAqIEBwYXJhbSB7QXJyYXk8QXJyYXk+fSBkYXRhLmRhdGFzZXRzLmRhdGEucm93cyAtICoqKnJlcXVpcmVkKiogQXJyYXkgb2Ygcm93cywgaW4gYSB0YWJ1bGFyIGZvcm1hdCB3aXRoIGBmaWVsZHNgIGFuZCBgcm93c2BcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEub3B0aW9uc1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGRhdGEub3B0aW9ucy5jZW50ZXJNYXAgYGRlZmF1bHQ6IHRydWVgIGlmIGBjZW50ZXJNYXBgIGlzIHNldCB0byBgdHJ1ZWAga2VwbGVyLmdsIHdpbGxcbiAgICogcGxhY2UgdGhlIG1hcCB2aWV3IHdpdGhpbiB0aGUgZGF0YSBwb2ludHMgYm91bmRhcmllcy4gIGBvcHRpb25zLmNlbnRlck1hcGAgd2lsbCBvdmVycmlkZSBgY29uZmlnLm1hcFN0YXRlYCBpZiBwYXNzZWQgaW4uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZGF0YS5vcHRpb25zLnJlYWRPbmx5IGBkZWZhdWx0OiBmYWxzZWAgaWYgYHJlYWRPbmx5YCBpcyBzZXQgdG8gYHRydWVgXG4gICAqIHRoZSBsZWZ0IHNldHRpbmcgcGFuZWwgd2lsbCBiZSBoaWRkZW5cbiAgICogQHBhcmFtIHtib29sZWFufSBkYXRhLm9wdGlvbnMua2VlcEV4aXN0aW5nQ29uZmlnIHdoZXRoZXIgdG8ga2VlcCBleGl0aW5nIG1hcCBkYXRhIGFuZCBhc3NvY2lhdGVkIGxheWVyIGZpbHRlciAgaW50ZXJhY3Rpb24gY29uZmlnIGBkZWZhdWx0OiBmYWxzZWAuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhLmNvbmZpZyB0aGlzIG9iamVjdCB3aWxsIGNvbnRhaW4gdGhlIGZ1bGwga2VwbGVyLmdsIGluc3RhbmNlIGNvbmZpZ3VyYXRpb24ge21hcFN0YXRlLCBtYXBTdHlsZSwgdmlzU3RhdGV9XG4gICAqIEBwdWJsaWNcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogLy8gYXBwLmpzXG4gICAqIGltcG9ydCB7YWRkRGF0YVRvTWFwfSBmcm9tICdrZXBsZXIuZ2wvYWN0aW9ucyc7XG4gICAqXG4gICAqIGNvbnN0IHNhbXBsZVRyaXBEYXRhID0ge1xuICAgKiAgZmllbGRzOiBbXG4gICAqICAgIHtuYW1lOiAndHBlcF9waWNrdXBfZGF0ZXRpbWUnLCBmb3JtYXQ6ICdZWVlZLU0tRCBIOm06cycsIHR5cGU6ICd0aW1lc3RhbXAnfSxcbiAgICogICAge25hbWU6ICdwaWNrdXBfbG9uZ2l0dWRlJywgZm9ybWF0OiAnJywgdHlwZTogJ3JlYWwnfSxcbiAgICogICAge25hbWU6ICdwaWNrdXBfbGF0aXR1ZGUnLCBmb3JtYXQ6ICcnLCB0eXBlOiAncmVhbCd9XG4gICAqICBdLFxuICAgKiAgcm93czogW1xuICAgKiAgICBbJzIwMTUtMDEtMTUgMTk6MDU6MzkgKzAwOjAwJywgLTczLjk5Mzg5NjQ4LCA0MC43NTAxMTA2M10sXG4gICAqICAgIFsnMjAxNS0wMS0xNSAxOTowNTozOSArMDA6MDAnLCAtNzMuOTc2NDI1MTcsIDQwLjczOTgxMDk0XSxcbiAgICogICAgWycyMDE1LTAxLTE1IDE5OjA1OjQwICswMDowMCcsIC03My45Njg3MDQyMiwgNDAuNzU0MjQ1NzZdLFxuICAgKiAgXVxuICAgKiB9O1xuICAgKlxuICAgKiBjb25zdCBzYW1wbGVDb25maWcgPSB7XG4gICAqICAgdmlzU3RhdGU6IHtcbiAgICogICAgIGZpbHRlcnM6IFtcbiAgICogICAgICAge1xuICAgKiAgICAgICAgIGlkOiAnbWUnLFxuICAgKiAgICAgICAgIGRhdGFJZDogJ3Rlc3RfdHJpcF9kYXRhJyxcbiAgICogICAgICAgICBuYW1lOiAndHBlcF9waWNrdXBfZGF0ZXRpbWUnLFxuICAgKiAgICAgICAgIHR5cGU6ICd0aW1lUmFuZ2UnLFxuICAgKiAgICAgICAgIGVubGFyZ2VkOiB0cnVlXG4gICAqICAgICAgIH1cbiAgICogICAgIF1cbiAgICogICB9XG4gICAqIH1cbiAgICpcbiAgICogdGhpcy5wcm9wcy5kaXNwYXRjaChcbiAgICogICBhZGREYXRhVG9NYXAoe1xuICAgKiAgICAgZGF0YXNldHM6IHtcbiAgICogICAgICAgaW5mbzoge1xuICAgKiAgICAgICAgIGxhYmVsOiAnU2FtcGxlIFRheGkgVHJpcHMgaW4gTmV3IFlvcmsgQ2l0eScsXG4gICAqICAgICAgICAgaWQ6ICd0ZXN0X3RyaXBfZGF0YSdcbiAgICogICAgICAgfSxcbiAgICogICAgICAgZGF0YTogc2FtcGxlVHJpcERhdGFcbiAgICogICAgIH0sXG4gICAqICAgICBvcHRpb246IHtcbiAgICogICAgICAgY2VudGVyTWFwOiB0cnVlLFxuICAgKiAgICAgICByZWFkT25seTogZmFsc2UsXG4gICAqICAgICAgIGtlZXBFeGlzdGluZ0NvbmZpZzogZmFsc2VcbiAgICogICAgIH0sXG4gICAqICAgICBjb25maWc6IHNhbXBsZUNvbmZpZ1xuICAgKiAgIH0pXG4gICAqICk7XG4gICAqL1xuZXhwb3J0IGNvbnN0IGFkZERhdGFUb01hcCA9IGNyZWF0ZUFjdGlvbihcbiAgQWN0aW9uVHlwZXMuQUREX0RBVEFfVE9fTUFQLFxuICBkYXRhID0+IGRhdGFcbik7XG5cbi8qKlxuICogUmVzZXQgYWxsIHN1Yi1yZWR1Y2VycyB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gVGhpcyBjYW4gYmUgdXNlZCB0byBjbGVhciBvdXQgYWxsIGNvbmZpZ3VyYXRpb24gaW4gdGhlIHJlZHVjZXIuXG4gKiBAbWVtYmVyb2YgbWFpblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgcmVzZXRNYXBDb25maWcgPSBjcmVhdGVBY3Rpb24oXG4gIEFjdGlvblR5cGVzLlJFU0VUX01BUF9DT05GSUdcbik7XG5cbi8qKlxuICogUGFzcyBjb25maWcgdG8ga2VwbGVyLmdsIGluc3RhbmNlLCBwcmVwYXJlIHRoZSBzdGF0ZSB3aXRoIHByZXNldCBjb25maWdzLlxuICogQ2FsbGluZyBgS2VwbGVyR2xTY2hlbWEucGFyc2VTYXZlZENvbmZpZ2AgdG8gY29udmVydCBzYXZlZCBjb25maWcgYmVmb3JlIHBhc3NpbmcgaXQgaW4gaXMgcmVxdWlyZWQuXG4gKlxuICogWW91IGNhbiBjYWxsIGByZWNlaXZlTWFwQ29uZmlnYCBiZWZvcmUgcGFzc2luZyBpbiBhbnkgZGF0YS4gVGhlIHJlZHVjZXIgd2lsbCBzdG9yZSBsYXllciBhbmQgZmlsdGVyIGNvbmZpZywgd2FpdGluZyBmb3JcbiAqIGRhdGEgdG8gY29tZSBpbi4gV2hlbiBkYXRhIGFycml2ZXMsIHlvdSBjYW4gY2FsbCBgYWRkRGF0YVRvTWFwYCB3aXRob3V0IHBhc3NpbmcgYW55IGNvbmZpZywgYW5kIHRoZSByZWR1Y2VyIHdpbGwgdHJ5IHRvIG1hdGNoXG4gKiBwcmVsb2FkZWQgY29uZmlncy4gVGhpcyBiZWhhdmlvciBpcyBkZXNpZ25lZCB0byBhbGxvdyBhc3luY2hyb25vdXMgZGF0YSBsb2FkaW5nLlxuICpcbiAqIEl0IGlzIGFsc28gdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gcHJlcGFyZSB0aGUga2VwbGVyLmdsIGluc3RhbmNlIHdpdGggc29tZSBwcmVzZXQgbGF5ZXIgYW5kIGZpbHRlciBzZXR0aW5ncy5cbiAqICoqTm90ZSoqIFNlcXVlbmNlIGlzIGltcG9ydGFudCwgYHJlY2VpdmVNYXBDb25maWdgIG5lZWRzIHRvIGJlIGNhbGxlZCBfX2JlZm9yZV9fIGRhdGEgaXMgbG9hZGVkLiBDdXJyZW50bHkga2VwbGVyLmdsIGRvZXNuJ3QgYWxsb3cgY2FsbGluZyBgcmVjZWl2ZU1hcENvbmZpZ2AgYWZ0ZXIgZGF0YSBpcyBsb2FkZWQuXG4gKiBJdCB3aWxsIHJlc2V0IGN1cnJlbnQgY29uZmlndXJhdGlvbiBmaXJzdCB0aGVuIGFwcGx5IGNvbmZpZyB0byBpdC5cbiAqIEBtZW1iZXJvZiBtYWluXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gKioqcmVxdWlyZWQqKiBUaGUgQ29uZmlnIE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSAqKipvcHRpb25hbCoqIFRoZSBPcHRpb24gb2JqZWN0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMuY2VudGVyTWFwIGBkZWZhdWx0OiB0cnVlYCBpZiBgY2VudGVyTWFwYCBpcyBzZXQgdG8gYHRydWVgIGtlcGxlci5nbCB3aWxsXG4gKiBwbGFjZSB0aGUgbWFwIHZpZXcgd2l0aGluIHRoZSBkYXRhIHBvaW50cyBib3VuZGFyaWVzXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMucmVhZE9ubHkgYGRlZmF1bHQ6IGZhbHNlYCBpZiBgcmVhZE9ubHlgIGlzIHNldCB0byBgdHJ1ZWBcbiAqIHRoZSBsZWZ0IHNldHRpbmcgcGFuZWwgd2lsbCBiZSBoaWRkZW5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0aW9ucy5rZWVwRXhpc3RpbmdDb25maWcgd2hldGhlciB0byBrZWVwIGV4aXRpbmcgbGF5ZXIgZmlsdGVyIGFuZCBpbnRlcmFjdGlvbiBjb25maWcgYGRlZmF1bHQ6IGZhbHNlYC5cbiAqIEBwdWJsaWNcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQge3JlY2VpdmVNYXBDb25maWd9IGZyb20gJ2tlcGxlci5nbC9hY3Rpb25zJztcbiAqIGltcG9ydCBLZXBsZXJHbFNjaGVtYSBmcm9tICdrZXBsZXIuZ2wvc2NoZW1hcyc7XG4gKlxuICogY29uc3QgcGFyc2VkQ29uZmlnID0gS2VwbGVyR2xTY2hlbWEucGFyc2VTYXZlZENvbmZpZyhjb25maWcpO1xuICogdGhpcy5wcm9wcy5kaXNwYXRjaChyZWNlaXZlTWFwQ29uZmlnKHBhcnNlZENvbmZpZykpO1xuICovXG5leHBvcnQgY29uc3QgcmVjZWl2ZU1hcENvbmZpZyA9IGNyZWF0ZUFjdGlvbihcbiAgQWN0aW9uVHlwZXMuUkVDRUlWRV9NQVBfQ09ORklHLFxuICAoY29uZmlnLCBvcHRpb25zKSA9PiAoe2NvbmZpZywgb3B0aW9uc30pXG4pO1xuXG4vKipcbiAqIEluaXRpYWxpemUga2VwbGVyLmdsIHJlZHVjZXIuIEl0IGlzIHVzZWQgdG8gcGFzcyBpbiBgbWFwYm94QXBpQWNjZXNzVG9rZW5gIHRvIGBtYXBTdHlsZWAgcmVkdWNlci5cbiAqIEBtZW1iZXJvZiBtYWluXG4gKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZFxuICogQHBhcmFtIHtzdHJpbmd9IHBheWxvYWQubWFwYm94QXBpQWNjZXNzVG9rZW4gLSBtYXBib3hBcGlBY2Nlc3NUb2tlbiB0byBiZSBzYXZlZCB0byBtYXBTdHlsZSByZWR1Y2VyXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF5bG9hZC5tYXBib3hBcGlVcmwgLSBtYXBib3hBcGlVcmwgdG8gYmUgc2F2ZWQgdG8gbWFwU3R5bGUgcmVkdWNlci5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcGF5bG9hZC5tYXBTdHlsZXNSZXBsYWNlRGVmYXVsdCAtIG1hcFN0eWxlc1JlcGxhY2VEZWZhdWx0IHRvIGJlIHNhdmVkIHRvIG1hcFN0eWxlIHJlZHVjZXJcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGtlcGxlckdsSW5pdCA9IGNyZWF0ZUFjdGlvbihcbiAgQWN0aW9uVHlwZXMuSU5JVCxcbiAgKHttYXBib3hBcGlBY2Nlc3NUb2tlbiwgbWFwYm94QXBpVXJsLCBtYXBTdHlsZXNSZXBsYWNlRGVmYXVsdH0gPSB7fSkgPT4gKHttYXBib3hBcGlBY2Nlc3NUb2tlbiwgbWFwYm94QXBpVXJsLCBtYXBTdHlsZXNSZXBsYWNlRGVmYXVsdH0pXG4pO1xuXG4vKipcbiAqIFRoaXMgZGVjbGFyYXRpb24gaXMgbmVlZGVkIHRvIGdyb3VwIGFjdGlvbnMgaW4gZG9jc1xuICovXG4vKipcbiAqIE1haW4ga2VwbGVyLmdsIGFjdGlvbnMsIHRoZXNlIGFjdGlvbnMgaGFuZGxlcyBsb2FkaW5nIGRhdGEgYW5kIGNvbmZpZyBpbnRvIGtlcGxlci5nbCByZWR1Y2VyLiBUaGVzZSBhY3Rpb25zXG4gKiBpcyBsaXN0ZW5lZCBieSBhbGwgc3VicmVkdWNlcnMsXG4gKiBAcHVibGljXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5jb25zdCBtYWluID0gbnVsbDtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cbiJdfQ==