kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
614 lines (501 loc) • 64.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mergeFilters = mergeFilters;
exports.createLayerFromConfig = createLayerFromConfig;
exports.serializeLayer = serializeLayer;
exports.mergeLayers = mergeLayers;
exports.insertLayerAtRightOrder = insertLayerAtRightOrder;
exports.mergeInteractions = mergeInteractions;
exports.mergeSplitMaps = mergeSplitMaps;
exports.mergeInteractionTooltipConfig = mergeInteractionTooltipConfig;
exports.mergeLayerBlending = mergeLayerBlending;
exports.mergeAnimationConfig = mergeAnimationConfig;
exports.validateSavedLayerColumns = validateSavedLayerColumns;
exports.validateColumn = validateColumn;
exports.validateSavedTextLabel = validateSavedTextLabel;
exports.validateSavedVisualChannels = validateSavedVisualChannels;
exports.validateLayersByDatasets = validateLayersByDatasets;
exports.validateLayerWithData = validateLayerWithData;
exports.isValidMerger = isValidMerger;
exports.VIS_STATE_MERGERS = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _lodash = _interopRequireDefault(require("lodash.uniq"));
var _lodash2 = _interopRequireDefault(require("lodash.pick"));
var _lodash3 = _interopRequireDefault(require("lodash.flattendeep"));
var _utils = require("../utils/utils");
var _filterUtils = require("../utils/filter-utils");
var _splitMapUtils = require("../utils/split-map-utils");
var _gpuFilterUtils = require("../utils/gpu-filter-utils");
var _defaultSettings = require("../constants/default-settings");
var _schemas = require("../schemas");
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Merge loaded filters with current state, if no fields or data are loaded
* save it for later
*
* @type {typeof import('./vis-state-merger').mergeFilters}
*/
function mergeFilters(state, filtersToMerge) {
if (!Array.isArray(filtersToMerge) || !filtersToMerge.length) {
return state;
}
var _validateFiltersUpdat = (0, _filterUtils.validateFiltersUpdateDatasets)(state, filtersToMerge),
validated = _validateFiltersUpdat.validated,
failed = _validateFiltersUpdat.failed,
updatedDatasets = _validateFiltersUpdat.updatedDatasets; // merge filter with existing
var updatedFilters = [].concat((0, _toConsumableArray2["default"])(state.filters || []), (0, _toConsumableArray2["default"])(validated));
updatedFilters = (0, _gpuFilterUtils.resetFilterGpuMode)(updatedFilters);
updatedFilters = (0, _gpuFilterUtils.assignGpuChannels)(updatedFilters); // filter data
var datasetsToFilter = (0, _lodash["default"])((0, _lodash3["default"])(validated.map(function (f) {
return f.dataId;
})));
var filtered = (0, _filterUtils.applyFiltersToDatasets)(datasetsToFilter, updatedDatasets, updatedFilters, state.layers);
return _objectSpread(_objectSpread({}, state), {}, {
filters: updatedFilters,
datasets: filtered,
filterToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.filterToBeMerged), (0, _toConsumableArray2["default"])(failed))
});
}
function createLayerFromConfig(state, layerConfig) {
// first validate config against dataset
var _validateLayersByData = validateLayersByDatasets(state.datasets, state.layerClasses, [layerConfig]),
validated = _validateLayersByData.validated,
failed = _validateLayersByData.failed;
if (failed.length || !validated.length) {
// failed
return null;
}
var newLayer = validated[0];
newLayer.updateLayerDomain(state.datasets);
return newLayer;
}
function serializeLayer(newLayer) {
var savedVisState = _schemas.visStateSchema[_schemas.CURRENT_VERSION].save({
layers: [newLayer],
layerOrder: [0]
}).visState;
var loadedLayer = _schemas.visStateSchema[_schemas.CURRENT_VERSION].load(savedVisState).visState.layers[0];
return loadedLayer;
}
/**
* Merge layers from de-serialized state, if no fields or data are loaded
* save it for later
*
* @type {typeof import('./vis-state-merger').mergeLayers}
*/
function mergeLayers(state, layersToMerge, fromConfig) {
var preserveLayerOrder = fromConfig ? layersToMerge.map(function (l) {
return l.id;
}) : state.preserveLayerOrder;
if (!Array.isArray(layersToMerge) || !layersToMerge.length) {
return state;
}
var _validateLayersByData2 = validateLayersByDatasets(state.datasets, state.layerClasses, layersToMerge),
mergedLayer = _validateLayersByData2.validated,
unmerged = _validateLayersByData2.failed; // put new layers in front of current layers
var _insertLayerAtRightOr = insertLayerAtRightOrder(state.layers, mergedLayer, state.layerOrder, preserveLayerOrder),
newLayerOrder = _insertLayerAtRightOr.newLayerOrder,
newLayers = _insertLayerAtRightOr.newLayers;
return _objectSpread(_objectSpread({}, state), {}, {
layers: newLayers,
layerOrder: newLayerOrder,
preserveLayerOrder: preserveLayerOrder,
layerToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.layerToBeMerged), (0, _toConsumableArray2["default"])(unmerged))
});
}
function insertLayerAtRightOrder(currentLayers, layersToInsert, currentOrder) {
var preservedOrder = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
// perservedOrder ['a', 'b', 'c'];
// layerOrder [1, 0, 3]
// layerOrderMap ['a', 'c']
var layerOrderQueue = currentOrder.map(function (i) {
return currentLayers[i].id;
});
var newLayers = currentLayers;
var _iterator = _createForOfIteratorHelper(layersToInsert),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var newLayer = _step.value;
// find where to insert it
var expectedIdx = preservedOrder.indexOf(newLayer.id); // if cant find place to insert, insert at the font
var insertAt = 0;
if (expectedIdx > 0) {
// look for layer to insert after
var i = expectedIdx + 1;
var preceedIdx = null;
while (i-- > 0 && preceedIdx === null) {
var preceedLayer = preservedOrder[expectedIdx - 1];
preceedIdx = layerOrderQueue.indexOf(preceedLayer);
}
if (preceedIdx > -1) {
insertAt = preceedIdx + 1;
}
}
layerOrderQueue = (0, _utils.arrayInsert)(layerOrderQueue, insertAt, newLayer.id);
newLayers = newLayers.concat(newLayer);
} // reconstruct layerOrder after insert
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
var newLayerOrder = layerOrderQueue.map(function (id) {
return newLayers.findIndex(function (l) {
return l.id === id;
});
});
return {
newLayerOrder: newLayerOrder,
newLayers: newLayers
};
}
/**
* Merge interactions with saved config
*
* @type {typeof import('./vis-state-merger').mergeInteractions}
*/
function mergeInteractions(state, interactionToBeMerged) {
var merged = {};
var unmerged = {};
if (interactionToBeMerged) {
Object.keys(interactionToBeMerged).forEach(function (key) {
if (!state.interactionConfig[key]) {
return;
}
var currentConfig = state.interactionConfig[key].config;
var _ref = interactionToBeMerged[key] || {},
enabled = _ref.enabled,
configSaved = (0, _objectWithoutProperties2["default"])(_ref, ["enabled"]);
var configToMerge = configSaved;
if (key === 'tooltip') {
var _mergeInteractionTool = mergeInteractionTooltipConfig(state, configSaved),
mergedTooltip = _mergeInteractionTool.mergedTooltip,
unmergedTooltip = _mergeInteractionTool.unmergedTooltip; // merge new dataset tooltips with original dataset tooltips
configToMerge = {
fieldsToShow: _objectSpread(_objectSpread({}, currentConfig.fieldsToShow), mergedTooltip)
};
if (Object.keys(unmergedTooltip).length) {
unmerged.tooltip = {
fieldsToShow: unmergedTooltip,
enabled: enabled
};
}
}
merged[key] = _objectSpread(_objectSpread({}, state.interactionConfig[key]), {}, {
enabled: enabled
}, currentConfig ? {
config: (0, _lodash2["default"])(_objectSpread(_objectSpread({}, currentConfig), configToMerge), Object.keys(currentConfig))
} : {});
});
}
return _objectSpread(_objectSpread({}, state), {}, {
interactionConfig: _objectSpread(_objectSpread({}, state.interactionConfig), merged),
interactionToBeMerged: unmerged
});
}
/**
* Merge splitMaps config with current visStete.
* 1. if current map is split, but splitMap DOESNOT contain maps
* : don't merge anything
* 2. if current map is NOT split, but splitMaps contain maps
* : add to splitMaps, and add current layers to splitMaps
* @type {typeof import('./vis-state-merger').mergeInteractions}
*/
function mergeSplitMaps(state) {
var splitMaps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var merged = (0, _toConsumableArray2["default"])(state.splitMaps);
var unmerged = [];
splitMaps.forEach(function (sm, i) {
Object.entries(sm.layers).forEach(function (_ref2) {
var _ref3 = (0, _slicedToArray2["default"])(_ref2, 2),
id = _ref3[0],
value = _ref3[1];
// check if layer exists
var pushTo = state.layers.find(function (l) {
return l.id === id;
}) ? merged : unmerged; // create map panel if current map is not split
pushTo[i] = pushTo[i] || {
layers: pushTo === merged ? (0, _splitMapUtils.getInitialMapLayersForSplitMap)(state.layers) : []
};
pushTo[i].layers = _objectSpread(_objectSpread({}, pushTo[i].layers), {}, (0, _defineProperty2["default"])({}, id, value));
});
});
return _objectSpread(_objectSpread({}, state), {}, {
splitMaps: merged,
splitMapsToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.splitMapsToBeMerged), unmerged)
});
}
/**
* Merge interactionConfig.tooltip with saved config,
* validate fieldsToShow
*
* @param {object} state
* @param {object} tooltipConfig
* @return {object} - {mergedTooltip: {}, unmergedTooltip: {}}
*/
function mergeInteractionTooltipConfig(state) {
var tooltipConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var unmergedTooltip = {};
var mergedTooltip = {};
if (!tooltipConfig.fieldsToShow || !Object.keys(tooltipConfig.fieldsToShow).length) {
return {
mergedTooltip: mergedTooltip,
unmergedTooltip: unmergedTooltip
};
}
for (var dataId in tooltipConfig.fieldsToShow) {
if (!state.datasets[dataId]) {
// is not yet loaded
unmergedTooltip[dataId] = tooltipConfig.fieldsToShow[dataId];
} else {
(function () {
// if dataset is loaded
var allFields = state.datasets[dataId].fields.map(function (d) {
return d.name;
});
var foundFieldsToShow = tooltipConfig.fieldsToShow[dataId].filter(function (field) {
return allFields.includes(field.name);
});
mergedTooltip[dataId] = foundFieldsToShow;
})();
}
}
return {
mergedTooltip: mergedTooltip,
unmergedTooltip: unmergedTooltip
};
}
/**
* Merge layerBlending with saved
*
* @type {typeof import('./vis-state-merger').mergeLayerBlending}
*/
function mergeLayerBlending(state, layerBlending) {
if (layerBlending && _defaultSettings.LAYER_BLENDINGS[layerBlending]) {
return _objectSpread(_objectSpread({}, state), {}, {
layerBlending: layerBlending
});
}
return state;
}
/**
* Merge animation config
* @type {typeof import('./vis-state-merger').mergeAnimationConfig}
*/
function mergeAnimationConfig(state, animation) {
if (animation && animation.currentTime) {
return _objectSpread(_objectSpread({}, state), {}, {
animationConfig: _objectSpread(_objectSpread(_objectSpread({}, state.animationConfig), animation), {}, {
domain: null
})
});
}
return state;
}
/**
* Validate saved layer columns with new data,
* update fieldIdx based on new fields
*
* @param {Array<Object>} fields
* @param {Object} savedCols
* @param {Object} emptyCols
* @return {null | Object} - validated columns or null
*/
function validateSavedLayerColumns(fields) {
var savedCols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var emptyCols = arguments.length > 2 ? arguments[2] : undefined;
// Prepare columns for the validator
var columns = {};
var _loop = function _loop() {
var key = _Object$keys[_i];
columns[key] = _objectSpread({}, emptyCols[key]);
var saved = savedCols[key];
if (saved) {
var fieldIdx = fields.findIndex(function (_ref4) {
var name = _ref4.name;
return name === saved;
});
if (fieldIdx > -1) {
// update found columns
columns[key].fieldIdx = fieldIdx;
columns[key].value = saved;
}
}
};
for (var _i = 0, _Object$keys = Object.keys(emptyCols); _i < _Object$keys.length; _i++) {
_loop();
} // find actual column fieldIdx, in case it has changed
var allColFound = Object.keys(columns).every(function (key) {
return validateColumn(columns[key], columns, fields);
});
if (allColFound) {
return columns;
}
return null;
}
function validateColumn(column, columns, allFields) {
if (column.optional || column.value) {
return true;
}
if (column.validator) {
return column.validator(column, columns, allFields);
}
return false;
}
/**
* Validate saved text label config with new data
* refer to vis-state-schema.js TextLabelSchemaV1
*
* @param {Array<Object>} fields
* @param {Object} savedTextLabel
* @return {Object} - validated textlabel
*/
function validateSavedTextLabel(fields, _ref5, savedTextLabel) {
var _ref6 = (0, _slicedToArray2["default"])(_ref5, 1),
layerTextLabel = _ref6[0];
var savedTextLabels = Array.isArray(savedTextLabel) ? savedTextLabel : [savedTextLabel]; // validate field
return savedTextLabels.map(function (textLabel) {
var field = textLabel.field ? fields.find(function (fd) {
return Object.keys(textLabel.field).every(function (key) {
return textLabel.field[key] === fd[key];
});
}) : null;
return Object.keys(layerTextLabel).reduce(function (accu, key) {
return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, key === 'field' ? field : textLabel[key] || layerTextLabel[key]));
}, {});
});
}
/**
* Validate saved visual channels config with new data,
* refer to vis-state-schema.js VisualChannelSchemaV1
* @type {typeof import('./vis-state-merger').validateSavedVisualChannels}
*/
function validateSavedVisualChannels(fields, newLayer, savedLayer) {
Object.values(newLayer.visualChannels).forEach(function (_ref7) {
var field = _ref7.field,
scale = _ref7.scale,
key = _ref7.key;
var foundField;
if (savedLayer.config) {
if (savedLayer.config[field]) {
foundField = fields.find(function (fd) {
return savedLayer.config && fd.name === savedLayer.config[field].name;
});
}
var foundChannel = _objectSpread(_objectSpread({}, foundField ? (0, _defineProperty2["default"])({}, field, foundField) : {}), savedLayer.config[scale] ? (0, _defineProperty2["default"])({}, scale, savedLayer.config[scale]) : {});
if (Object.keys(foundChannel).length) {
newLayer.updateLayerConfig(foundChannel);
}
newLayer.validateVisualChannel(key);
}
});
return newLayer;
}
function validateLayersByDatasets(datasets, layerClasses, layers) {
var validated = [];
var failed = [];
layers.forEach(function (layer) {
var validateLayer;
if (!layer || !layer.config) {
validateLayer = null;
} else if (datasets[layer.config.dataId]) {
// datasets are already loaded
validateLayer = validateLayerWithData(datasets[layer.config.dataId], layer, layerClasses);
}
if (validateLayer) {
validated.push(validateLayer);
} else {
// datasets not yet loaded
failed.push(layer);
}
});
return {
validated: validated,
failed: failed
};
}
/**
* Validate saved layer config with new data,
* update fieldIdx based on new fields
* @type {typeof import('./vis-state-merger').validateLayerWithData}
*/
function validateLayerWithData(_ref10, savedLayer, layerClasses) {
var fields = _ref10.fields,
dataId = _ref10.id;
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var type = savedLayer.type; // layer doesnt have a valid type
if (!type || !layerClasses.hasOwnProperty(type) || !savedLayer.config) {
return null;
}
var newLayer = new layerClasses[type]({
id: savedLayer.id,
dataId: dataId,
label: savedLayer.config.label,
color: savedLayer.config.color,
isVisible: savedLayer.config.isVisible,
hidden: savedLayer.config.hidden,
highlightColor: savedLayer.config.highlightColor
}); // find column fieldIdx
var columnConfig = newLayer.getLayerColumns();
if (Object.keys(columnConfig).length) {
var columns = validateSavedLayerColumns(fields, savedLayer.config.columns, columnConfig);
if (columns) {
newLayer.updateLayerConfig({
columns: columns
});
} else if (!options.allowEmptyColumn) {
return null;
}
} // visual channel field is saved to be {name, type}
// find visual channel field by matching both name and type
// refer to vis-state-schema.js VisualChannelSchemaV1
newLayer = validateSavedVisualChannels(fields, newLayer, savedLayer);
var textLabel = savedLayer.config.textLabel && newLayer.config.textLabel ? validateSavedTextLabel(fields, newLayer.config.textLabel, savedLayer.config.textLabel) : newLayer.config.textLabel; // copy visConfig over to emptyLayer to make sure it has all the props
var visConfig = newLayer.copyLayerConfig(newLayer.config.visConfig, savedLayer.config.visConfig || {}, {
shallowCopy: ['colorRange', 'strokeColorRange']
});
newLayer.updateLayerConfig({
visConfig: visConfig,
textLabel: textLabel
});
return newLayer;
}
function isValidMerger(merger) {
return (0, _utils.isObject)(merger) && typeof merger.merge === 'function' && typeof merger.prop === 'string';
}
var VIS_STATE_MERGERS = [{
merge: mergeLayers,
prop: 'layers',
toMergeProp: 'layerToBeMerged'
}, {
merge: mergeFilters,
prop: 'filters',
toMergeProp: 'filterToBeMerged'
}, {
merge: mergeInteractions,
prop: 'interactionConfig',
toMergeProp: 'interactionToBeMerged'
}, {
merge: mergeLayerBlending,
prop: 'layerBlending'
}, {
merge: mergeSplitMaps,
prop: 'splitMaps',
toMergeProp: 'splitMapsToBeMerged'
}, {
merge: mergeAnimationConfig,
prop: 'animationConfig'
}];
exports.VIS_STATE_MERGERS = VIS_STATE_MERGERS;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy92aXMtc3RhdGUtbWVyZ2VyLmpzIl0sIm5hbWVzIjpbIm1lcmdlRmlsdGVycyIsInN0YXRlIiwiZmlsdGVyc1RvTWVyZ2UiLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJ2YWxpZGF0ZWQiLCJmYWlsZWQiLCJ1cGRhdGVkRGF0YXNldHMiLCJ1cGRhdGVkRmlsdGVycyIsImZpbHRlcnMiLCJkYXRhc2V0c1RvRmlsdGVyIiwibWFwIiwiZiIsImRhdGFJZCIsImZpbHRlcmVkIiwibGF5ZXJzIiwiZGF0YXNldHMiLCJmaWx0ZXJUb0JlTWVyZ2VkIiwiY3JlYXRlTGF5ZXJGcm9tQ29uZmlnIiwibGF5ZXJDb25maWciLCJ2YWxpZGF0ZUxheWVyc0J5RGF0YXNldHMiLCJsYXllckNsYXNzZXMiLCJuZXdMYXllciIsInVwZGF0ZUxheWVyRG9tYWluIiwic2VyaWFsaXplTGF5ZXIiLCJzYXZlZFZpc1N0YXRlIiwidmlzU3RhdGVTY2hlbWEiLCJDVVJSRU5UX1ZFUlNJT04iLCJzYXZlIiwibGF5ZXJPcmRlciIsInZpc1N0YXRlIiwibG9hZGVkTGF5ZXIiLCJsb2FkIiwibWVyZ2VMYXllcnMiLCJsYXllcnNUb01lcmdlIiwiZnJvbUNvbmZpZyIsInByZXNlcnZlTGF5ZXJPcmRlciIsImwiLCJpZCIsIm1lcmdlZExheWVyIiwidW5tZXJnZWQiLCJpbnNlcnRMYXllckF0UmlnaHRPcmRlciIsIm5ld0xheWVyT3JkZXIiLCJuZXdMYXllcnMiLCJsYXllclRvQmVNZXJnZWQiLCJjdXJyZW50TGF5ZXJzIiwibGF5ZXJzVG9JbnNlcnQiLCJjdXJyZW50T3JkZXIiLCJwcmVzZXJ2ZWRPcmRlciIsImxheWVyT3JkZXJRdWV1ZSIsImkiLCJleHBlY3RlZElkeCIsImluZGV4T2YiLCJpbnNlcnRBdCIsInByZWNlZWRJZHgiLCJwcmVjZWVkTGF5ZXIiLCJjb25jYXQiLCJmaW5kSW5kZXgiLCJtZXJnZUludGVyYWN0aW9ucyIsImludGVyYWN0aW9uVG9CZU1lcmdlZCIsIm1lcmdlZCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwia2V5IiwiaW50ZXJhY3Rpb25Db25maWciLCJjdXJyZW50Q29uZmlnIiwiY29uZmlnIiwiZW5hYmxlZCIsImNvbmZpZ1NhdmVkIiwiY29uZmlnVG9NZXJnZSIsIm1lcmdlSW50ZXJhY3Rpb25Ub29sdGlwQ29uZmlnIiwibWVyZ2VkVG9vbHRpcCIsInVubWVyZ2VkVG9vbHRpcCIsImZpZWxkc1RvU2hvdyIsInRvb2x0aXAiLCJtZXJnZVNwbGl0TWFwcyIsInNwbGl0TWFwcyIsInNtIiwiZW50cmllcyIsInZhbHVlIiwicHVzaFRvIiwiZmluZCIsInNwbGl0TWFwc1RvQmVNZXJnZWQiLCJ0b29sdGlwQ29uZmlnIiwiYWxsRmllbGRzIiwiZmllbGRzIiwiZCIsIm5hbWUiLCJmb3VuZEZpZWxkc1RvU2hvdyIsImZpbHRlciIsImZpZWxkIiwiaW5jbHVkZXMiLCJtZXJnZUxheWVyQmxlbmRpbmciLCJsYXllckJsZW5kaW5nIiwiTEFZRVJfQkxFTkRJTkdTIiwibWVyZ2VBbmltYXRpb25Db25maWciLCJhbmltYXRpb24iLCJjdXJyZW50VGltZSIsImFuaW1hdGlvbkNvbmZpZyIsImRvbWFpbiIsInZhbGlkYXRlU2F2ZWRMYXllckNvbHVtbnMiLCJzYXZlZENvbHMiLCJlbXB0eUNvbHMiLCJjb2x1bW5zIiwic2F2ZWQiLCJmaWVsZElkeCIsImFsbENvbEZvdW5kIiwiZXZlcnkiLCJ2YWxpZGF0ZUNvbHVtbiIsImNvbHVtbiIsIm9wdGlvbmFsIiwidmFsaWRhdG9yIiwidmFsaWRhdGVTYXZlZFRleHRMYWJlbCIsInNhdmVkVGV4dExhYmVsIiwibGF5ZXJUZXh0TGFiZWwiLCJzYXZlZFRleHRMYWJlbHMiLCJ0ZXh0TGFiZWwiLCJmZCIsInJlZHVjZSIsImFjY3UiLCJ2YWxpZGF0ZVNhdmVkVmlzdWFsQ2hhbm5lbHMiLCJzYXZlZExheWVyIiwidmFsdWVzIiwidmlzdWFsQ2hhbm5lbHMiLCJzY2FsZSIsImZvdW5kRmllbGQiLCJmb3VuZENoYW5uZWwiLCJ1cGRhdGVMYXllckNvbmZpZyIsInZhbGlkYXRlVmlzdWFsQ2hhbm5lbCIsImxheWVyIiwidmFsaWRhdGVMYXllciIsInZhbGlkYXRlTGF5ZXJXaXRoRGF0YSIsInB1c2giLCJvcHRpb25zIiwidHlwZSIsImhhc093blByb3BlcnR5IiwibGFiZWwiLCJjb2xvciIsImlzVmlzaWJsZSIsImhpZGRlbiIsImhpZ2hsaWdodENvbG9yIiwiY29sdW1uQ29uZmlnIiwiZ2V0TGF5ZXJDb2x1bW5zIiwiYWxsb3dFbXB0eUNvbHVtbiIsInZpc0NvbmZpZyIsImNvcHlMYXllckNvbmZpZyIsInNoYWxsb3dDb3B5IiwiaXNWYWxpZE1lcmdlciIsIm1lcmdlciIsIm1lcmdlIiwicHJvcCIsIlZJU19TVEFURV9NRVJHRVJTIiwidG9NZXJnZVByb3AiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNBLFlBQVQsQ0FBc0JDLEtBQXRCLEVBQTZCQyxjQUE3QixFQUE2QztBQUNsRCxNQUFJLENBQUNDLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixjQUFkLENBQUQsSUFBa0MsQ0FBQ0EsY0FBYyxDQUFDRyxNQUF0RCxFQUE4RDtBQUM1RCxXQUFPSixLQUFQO0FBQ0Q7O0FBSGlELDhCQUtMLGdEQUE4QkEsS0FBOUIsRUFBcUNDLGNBQXJDLENBTEs7QUFBQSxNQUszQ0ksU0FMMkMseUJBSzNDQSxTQUwyQztBQUFBLE1BS2hDQyxNQUxnQyx5QkFLaENBLE1BTGdDO0FBQUEsTUFLeEJDLGVBTHdCLHlCQUt4QkEsZUFMd0IsRUFPbEQ7OztBQUNBLE1BQUlDLGNBQWMsaURBQVFSLEtBQUssQ0FBQ1MsT0FBTixJQUFpQixFQUF6Qix1Q0FBaUNKLFNBQWpDLEVBQWxCO0FBQ0FHLEVBQUFBLGNBQWMsR0FBRyx3Q0FBbUJBLGNBQW5CLENBQWpCO0FBQ0FBLEVBQUFBLGNBQWMsR0FBRyx1Q0FBa0JBLGNBQWxCLENBQWpCLENBVmtELENBV2xEOztBQUNBLE1BQU1FLGdCQUFnQixHQUFHLHdCQUFLLHlCQUFZTCxTQUFTLENBQUNNLEdBQVYsQ0FBYyxVQUFBQyxDQUFDO0FBQUEsV0FBSUEsQ0FBQyxDQUFDQyxNQUFOO0FBQUEsR0FBZixDQUFaLENBQUwsQ0FBekI7QUFFQSxNQUFNQyxRQUFRLEdBQUcseUNBQ2ZKLGdCQURlLEVBRWZILGVBRmUsRUFHZkMsY0FIZSxFQUlmUixLQUFLLENBQUNlLE1BSlMsQ0FBakI7QUFPQSx5Q0FDS2YsS0FETDtBQUVFUyxJQUFBQSxPQUFPLEVBQUVELGNBRlg7QUFHRVEsSUFBQUEsUUFBUSxFQUFFRixRQUhaO0FBSUVHLElBQUFBLGdCQUFnQixnREFBTWpCLEtBQUssQ0FBQ2lCLGdCQUFaLHVDQUFpQ1gsTUFBakM7QUFKbEI7QUFNRDs7QUFFTSxTQUFTWSxxQkFBVCxDQUErQmxCLEtBQS9CLEVBQXNDbUIsV0FBdEMsRUFBbUQ7QUFDeEQ7QUFEd0QsOEJBRTVCQyx3QkFBd0IsQ0FBQ3BCLEtBQUssQ0FBQ2dCLFFBQVAsRUFBaUJoQixLQUFLLENBQUNxQixZQUF2QixFQUFxQyxDQUN2RkYsV0FEdUYsQ0FBckMsQ0FGSTtBQUFBLE1BRWpEZCxTQUZpRCx5QkFFakRBLFNBRmlEO0FBQUEsTUFFdENDLE1BRnNDLHlCQUV0Q0EsTUFGc0M7O0FBTXhELE1BQUlBLE1BQU0sQ0FBQ0YsTUFBUCxJQUFpQixDQUFDQyxTQUFTLENBQUNELE1BQWhDLEVBQXdDO0FBQ3RDO0FBQ0EsV0FBTyxJQUFQO0FBQ0Q7O0FBRUQsTUFBTWtCLFFBQVEsR0FBR2pCLFNBQVMsQ0FBQyxDQUFELENBQTFCO0FBQ0FpQixFQUFBQSxRQUFRLENBQUNDLGlCQUFULENBQTJCdkIsS0FBSyxDQUFDZ0IsUUFBakM7QUFDQSxTQUFPTSxRQUFQO0FBQ0Q7O0FBRU0sU0FBU0UsY0FBVCxDQUF3QkYsUUFBeEIsRUFBa0M7QUFDdkMsTUFBTUcsYUFBYSxHQUFHQyx3QkFBZUMsd0JBQWYsRUFBZ0NDLElBQWhDLENBQXFDO0FBQ3pEYixJQUFBQSxNQUFNLEVBQUUsQ0FBQ08sUUFBRCxDQURpRDtBQUV6RE8sSUFBQUEsVUFBVSxFQUFFLENBQUMsQ0FBRDtBQUY2QyxHQUFyQyxFQUduQkMsUUFISDs7QUFJQSxNQUFNQyxXQUFXLEdBQUdMLHdCQUFlQyx3QkFBZixFQUFnQ0ssSUFBaEMsQ0FBcUNQLGFBQXJDLEVBQW9ESyxRQUFwRCxDQUE2RGYsTUFBN0QsQ0FBb0UsQ0FBcEUsQ0FBcEI7O0FBQ0EsU0FBT2dCLFdBQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBU0UsV0FBVCxDQUFxQmpDLEtBQXJCLEVBQTRCa0MsYUFBNUIsRUFBMkNDLFVBQTNDLEVBQXVEO0FBQzVELE1BQU1DLGtCQUFrQixHQUFHRCxVQUFVLEdBQUdELGFBQWEsQ0FBQ3ZCLEdBQWQsQ0FBa0IsVUFBQTBCLENBQUM7QUFBQSxXQUFJQSxDQUFDLENBQUNDLEVBQU47QUFBQSxHQUFuQixDQUFILEdBQWtDdEMsS0FBSyxDQUFDb0Msa0JBQTdFOztBQUVBLE1BQUksQ0FBQ2xDLEtBQUssQ0FBQ0MsT0FBTixDQUFjK0IsYUFBZCxDQUFELElBQWlDLENBQUNBLGFBQWEsQ0FBQzlCLE1BQXBELEVBQTREO0FBQzFELFdBQU9KLEtBQVA7QUFDRDs7QUFMMkQsK0JBT1RvQix3QkFBd0IsQ0FDekVwQixLQUFLLENBQUNnQixRQURtRSxFQUV6RWhCLEtBQUssQ0FBQ3FCLFlBRm1FLEVBR3pFYSxhQUh5RSxDQVBmO0FBQUEsTUFPMUNLLFdBUDBDLDBCQU9yRGxDLFNBUHFEO0FBQUEsTUFPckJtQyxRQVBxQiwwQkFPN0JsQyxNQVA2QixFQWE1RDs7O0FBYjRELDhCQWN6Qm1DLHVCQUF1QixDQUN4RHpDLEtBQUssQ0FBQ2UsTUFEa0QsRUFFeER3QixXQUZ3RCxFQUd4RHZDLEtBQUssQ0FBQzZCLFVBSGtELEVBSXhETyxrQkFKd0QsQ0FkRTtBQUFBLE1BY3JETSxhQWRxRCx5QkFjckRBLGFBZHFEO0FBQUEsTUFjdENDLFNBZHNDLHlCQWN0Q0EsU0Fkc0M7O0FBcUI1RCx5Q0FDSzNDLEtBREw7QUFFRWUsSUFBQUEsTUFBTSxFQUFFNEIsU0FGVjtBQUdFZCxJQUFBQSxVQUFVLEVBQUVhLGFBSGQ7QUFJRU4sSUFBQUEsa0JBQWtCLEVBQWxCQSxrQkFKRjtBQUtFUSxJQUFBQSxlQUFlLGdEQUFNNUMsS0FBSyxDQUFDNEMsZUFBWix1Q0FBZ0NKLFFBQWhDO0FBTGpCO0FBT0Q7O0FBRU0sU0FBU0MsdUJBQVQsQ0FDTEksYUFESyxFQUVMQyxjQUZLLEVBR0xDLFlBSEssRUFLTDtBQUFBLE1BREFDLGNBQ0EsdUVBRGlCLEVBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSUMsZUFBZSxHQUFHRixZQUFZLENBQUNwQyxHQUFiLENBQWlCLFVBQUF1QyxDQUFDO0FBQUEsV0FBSUwsYUFBYSxDQUFDSyxDQUFELENBQWIsQ0FBaUJaLEVBQXJCO0FBQUEsR0FBbEIsQ0FBdEI7QUFDQSxNQUFJSyxTQUFTLEdBQUdFLGFBQWhCOztBQUxBLDZDQU91QkMsY0FQdkI7QUFBQTs7QUFBQTtBQU9BLHdEQUF1QztBQUFBLFVBQTVCeEIsUUFBNEI7QUFDckM7QUFDQSxVQUFNNkIsV0FBVyxHQUFHSCxjQUFjLENBQUNJLE9BQWYsQ0FBdUI5QixRQUFRLENBQUNnQixFQUFoQyxDQUFwQixDQUZxQyxDQUdyQzs7QUFDQSxVQUFJZSxRQUFRLEdBQUcsQ0FBZjs7QUFFQSxVQUFJRixXQUFXLEdBQUcsQ0FBbEIsRUFBcUI7QUFDbkI7QUFDQSxZQUFJRCxDQUFDLEdBQUdDLFdBQVcsR0FBRyxDQUF0QjtBQUNBLFlBQUlHLFVBQVUsR0FBRyxJQUFqQjs7QUFDQSxlQUFPSixDQUFDLEtBQUssQ0FBTixJQUFXSSxVQUFVLEtBQUssSUFBakMsRUFBdUM7QUFDckMsY0FBTUMsWUFBWSxHQUFHUCxjQUFjLENBQUNHLFdBQVcsR0FBRyxDQUFmLENBQW5DO0FBQ0FHLFVBQUFBLFVBQVUsR0FBR0wsZUFBZSxDQUFDRyxPQUFoQixDQUF3QkcsWUFBeEIsQ0FBYjtBQUNEOztBQUVELFlBQUlELFVBQVUsR0FBRyxDQUFDLENBQWxCLEVBQXFCO0FBQ25CRCxVQUFBQSxRQUFRLEdBQUdDLFVBQVUsR0FBRyxDQUF4QjtBQUNEO0FBQ0Y7O0FBRURMLE1BQUFBLGVBQWUsR0FBRyx3QkFBWUEsZUFBWixFQUE2QkksUUFBN0IsRUFBdUMvQixRQUFRLENBQUNnQixFQUFoRCxDQUFsQjtBQUNBSyxNQUFBQSxTQUFTLEdBQUdBLFNBQVMsQ0FBQ2EsTUFBVixDQUFpQmxDLFFBQWpCLENBQVo7QUFDRCxLQTdCRCxDQStCQTs7QUEvQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFnQ0EsTUFBTW9CLGFBQWEsR0FBR08sZUFBZSxDQUFDdEMsR0FBaEIsQ0FBb0IsVUFBQTJCLEVBQUU7QUFBQSxXQUFJSyxTQUFTLENBQUNjLFNBQVYsQ0FBb0IsVUFBQXBCLENBQUM7QUFBQSxhQUFJQSxDQUFDLENBQUNDLEVBQUYsS0FBU0EsRUFBYjtBQUFBLEtBQXJCLENBQUo7QUFBQSxHQUF0QixDQUF0QjtBQUVBLFNBQU87QUFDTEksSUFBQUEsYUFBYSxFQUFiQSxhQURLO0FBRUxDLElBQUFBLFNBQVMsRUFBVEE7QUFGSyxHQUFQO0FBSUQ7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDTyxTQUFTZSxpQkFBVCxDQUEyQjFELEtBQTNCLEVBQWtDMkQscUJBQWxDLEVBQXlEO0FBQzlELE1BQU1DLE1BQU0sR0FBRyxFQUFmO0FBQ0EsTUFBTXBCLFFBQVEsR0FBRyxFQUFqQjs7QUFFQSxNQUFJbUIscUJBQUosRUFBMkI7QUFDekJFLElBQUFBLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZSCxxQkFBWixFQUFtQ0ksT0FBbkMsQ0FBMkMsVUFBQUMsR0FBRyxFQUFJO0FBQ2hELFVBQUksQ0FBQ2hFLEtBQUssQ0FBQ2lFLGlCQUFOLENBQXdCRCxHQUF4QixDQUFMLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBRUQsVUFBTUUsYUFBYSxHQUFHbEUsS0FBSyxDQUFDaUUsaUJBQU4sQ0FBd0JELEdBQXhCLEVBQTZCRyxNQUFuRDs7QUFMZ0QsaUJBT2RSLHFCQUFxQixDQUFDSyxHQUFELENBQXJCLElBQThCLEVBUGhCO0FBQUEsVUFPekNJLE9BUHlDLFFBT3pDQSxPQVB5QztBQUFBLFVBTzdCQyxXQVA2Qjs7QUFRaEQsVUFBSUMsYUFBYSxHQUFHRCxXQUFwQjs7QUFFQSxVQUFJTCxHQUFHLEtBQUssU0FBWixFQUF1QjtBQUFBLG9DQUNvQk8sNkJBQTZCLENBQUN2RSxLQUFELEVBQVFxRSxXQUFSLENBRGpEO0FBQUEsWUFDZEcsYUFEYyx5QkFDZEEsYUFEYztBQUFBLFlBQ0NDLGVBREQseUJBQ0NBLGVBREQsRUFHckI7OztBQUNBSCxRQUFBQSxhQUFhLEdBQUc7QUFDZEksVUFBQUEsWUFBWSxrQ0FDUFIsYUFBYSxDQUFDUSxZQURQLEdBRVBGLGFBRk87QUFERSxTQUFoQjs7QUFPQSxZQUFJWCxNQUFNLENBQUNDLElBQVAsQ0FBWVcsZUFBWixFQUE2QnJFLE1BQWpDLEVBQXlDO0FBQ3ZDb0MsVUFBQUEsUUFBUSxDQUFDbUMsT0FBVCxHQUFtQjtBQUFDRCxZQUFBQSxZQUFZLEVBQUVELGVBQWY7QUFBZ0NMLFlBQUFBLE9BQU8sRUFBUEE7QUFBaEMsV0FBbkI7QUFDRDtBQUNGOztBQUVEUixNQUFBQSxNQUFNLENBQUNJLEdBQUQsQ0FBTixtQ0FDS2hFLEtBQUssQ0FBQ2lFLGlCQUFOLENBQXdCRCxHQUF4QixDQURMO0FBRUVJLFFBQUFBLE9BQU8sRUFBUEE7QUFGRixTQUdNRixhQUFhLEdBQ2I7QUFDRUMsUUFBQUEsTUFBTSxFQUFFLHlEQUVERCxhQUZDLEdBR0RJLGFBSEMsR0FLTlQsTUFBTSxDQUFDQyxJQUFQLENBQVlJLGFBQVosQ0FMTTtBQURWLE9BRGEsR0FVYixFQWJOO0FBZUQsS0F6Q0Q7QUEwQ0Q7O0FBRUQseUNBQ0tsRSxLQURMO0FBRUVpRSxJQUFBQSxpQkFBaUIsa0NBQ1pqRSxLQUFLLENBQUNpRSxpQkFETSxHQUVaTCxNQUZZLENBRm5CO0FBTUVELElBQUFBLHFCQUFxQixFQUFFbkI7QUFOekI7QUFRRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNvQyxjQUFULENBQXdCNUUsS0FBeEIsRUFBK0M7QUFBQSxNQUFoQjZFLFNBQWdCLHVFQUFKLEVBQUk7QUFDcEQsTUFBTWpCLE1BQU0sdUNBQU81RCxLQUFLLENBQUM2RSxTQUFiLENBQVo7QUFDQSxNQUFNckMsUUFBUSxHQUFHLEVBQWpCO0FBQ0FxQyxFQUFBQSxTQUFTLENBQUNkLE9BQVYsQ0FBa0IsVUFBQ2UsRUFBRCxFQUFLNUIsQ0FBTCxFQUFXO0FBQzNCVyxJQUFBQSxNQUFNLENBQUNrQixPQUFQLENBQWVELEVBQUUsQ0FBQy9ELE1BQWxCLEVBQTBCZ0QsT0FBMUIsQ0FBa0MsaUJBQWlCO0FBQUE7QUFBQSxVQUFmekIsRUFBZTtBQUFBLFVBQVgwQyxLQUFXOztBQUNqRDtBQUNBLFVBQU1DLE1BQU0sR0FBR2pGLEtBQUssQ0FBQ2UsTUFBTixDQUFhbUUsSUFBYixDQUFrQixVQUFBN0MsQ0FBQztBQUFBLGVBQUlBLENBQUMsQ0FBQ0MsRUFBRixLQUFTQSxFQUFiO0FBQUEsT0FBbkIsSUFBc0NzQixNQUF0QyxHQUErQ3BCLFFBQTlELENBRmlELENBSWpEOztBQUNBeUMsTUFBQUEsTUFBTSxDQUFDL0IsQ0FBRCxDQUFOLEdBQVkrQixNQUFNLENBQUMvQixDQUFELENBQU4sSUFBYTtBQUN2Qm5DLFFBQUFBLE1BQU0sRUFBRWtFLE1BQU0sS0FBS3JCLE1BQVgsR0FBb0IsbURBQStCNUQsS0FBSyxDQUFDZSxNQUFyQyxDQUFwQixHQUFtRTtBQURwRCxPQUF6QjtBQUdBa0UsTUFBQUEsTUFBTSxDQUFDL0IsQ0FBRCxDQUFOLENBQVVuQyxNQUFWLG1DQUNLa0UsTUFBTSxDQUFDL0IsQ0FBRCxDQUFOLENBQVVuQyxNQURmLDRDQUVHdUIsRUFGSCxFQUVRMEMsS0FGUjtBQUlELEtBWkQ7QUFhRCxHQWREO0FBZ0JBLHlDQUNLaEYsS0FETDtBQUVFNkUsSUFBQUEsU0FBUyxFQUFFakIsTUFGYjtBQUdFdUIsSUFBQUEsbUJBQW1CLGdEQUFNbkYsS0FBSyxDQUFDbUYsbUJBQVosR0FBb0MzQyxRQUFwQztBQUhyQjtBQUtEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBUytCLDZCQUFULENBQXVDdkUsS0FBdkMsRUFBa0U7QUFBQSxNQUFwQm9GLGFBQW9CLHVFQUFKLEVBQUk7QUFDdkUsTUFBTVgsZUFBZSxHQUFHLEVBQXhCO0FBQ0EsTUFBTUQsYUFBYSxHQUFHLEVBQXRCOztBQUVBLE1BQUksQ0FBQ1ksYUFBYSxDQUFDVixZQUFmLElBQStCLENBQUNiLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZc0IsYUFBYSxDQUFDVixZQUExQixFQUF3Q3RFLE1BQTVFLEVBQW9GO0FBQ2xGLFdBQU87QUFBQ29FLE1BQUFBLGFBQWEsRUFBYkEsYUFBRDtBQUFnQkMsTUFBQUEsZUFBZSxFQUFmQTtBQUFoQixLQUFQO0FBQ0Q7O0FBRUQsT0FBSyxJQUFNNUQsTUFBWCxJQUFxQnVFLGFBQWEsQ0FBQ1YsWUFBbkMsRUFBaUQ7QUFDL0MsUUFBSSxDQUFDMUUsS0FBSyxDQUFDZ0IsUUFBTixDQUFlSCxNQUFmLENBQUwsRUFBNkI7QUFDM0I7QUFDQTRELE1BQUFBLGVBQWUsQ0FBQzVELE1BQUQsQ0FBZixHQUEwQnVFLGFBQWEsQ0FBQ1YsWUFBZCxDQUEyQjdELE1BQTNCLENBQTFCO0FBQ0QsS0FIRCxNQUdPO0FBQUE7QUFDTDtBQUNBLFlBQU13RSxTQUFTLEdBQUdyRixLQUFLLENBQUNnQixRQUFOLENBQWVILE1BQWYsRUFBdUJ5RSxNQUF2QixDQUE4QjNFLEdBQTlCLENBQWtDLFVBQUE0RSxDQUFDO0FBQUEsaUJBQUlBLENBQUMsQ0FBQ0MsSUFBTjtBQUFBLFNBQW5DLENBQWxCO0FBQ0EsWUFBTUMsaUJBQWlCLEdBQUdMLGFBQWEsQ0FBQ1YsWUFBZCxDQUEyQjdELE1BQTNCLEVBQW1DNkUsTUFBbkMsQ0FBMEMsVUFBQUMsS0FBSztBQUFBLGlCQUN2RU4sU0FBUyxDQUFDTyxRQUFWLENBQW1CRCxLQUFLLENBQUNILElBQXpCLENBRHVFO0FBQUEsU0FBL0MsQ0FBMUI7QUFJQWhCLFFBQUFBLGFBQWEsQ0FBQzNELE1BQUQsQ0FBYixHQUF3QjRFLGlCQUF4QjtBQVBLO0FBUU47QUFDRjs7QUFFRCxTQUFPO0FBQUNqQixJQUFBQSxhQUFhLEVBQWJBLGFBQUQ7QUFBZ0JDLElBQUFBLGVBQWUsRUFBZkE7QUFBaEIsR0FBUDtBQUNEO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBU29CLGtCQUFULENBQTRCN0YsS0FBNUIsRUFBbUM4RixhQUFuQyxFQUFrRDtBQUN2RCxNQUFJQSxhQUFhLElBQUlDLGlDQUFnQkQsYUFBaEIsQ0FBckIsRUFBcUQ7QUFDbkQsMkNBQ0s5RixLQURMO0FBRUU4RixNQUFBQSxhQUFhLEVBQWJBO0FBRkY7QUFJRDs7QUFFRCxTQUFPOUYsS0FBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNnRyxvQkFBVCxDQUE4QmhHLEtBQTlCLEVBQXFDaUcsU0FBckMsRUFBZ0Q7QUFDckQsTUFBSUEsU0FBUyxJQUFJQSxTQUFTLENBQUNDLFdBQTNCLEVBQXdDO0FBQ3RDLDJDQUNLbEcsS0FETDtBQUVFbUcsTUFBQUEsZUFBZSxnREFDVm5HLEtBQUssQ0FBQ21HLGVBREksR0FFVkYsU0FGVTtBQUdiRyxRQUFBQSxNQUFNLEVBQUU7QUFISztBQUZqQjtBQVFEOztBQUVELFNBQU9wRyxLQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUVPLFNBQVNxRyx5QkFBVCxDQUFtQ2YsTUFBbkMsRUFBc0U7QUFBQSxNQUEzQmdCLFNBQTJCLHVFQUFmLEVBQWU7QUFBQSxNQUFYQyxTQUFXO0FBQzNFO0FBQ0EsTUFBTUMsT0FBTyxHQUFHLEVBQWhCOztBQUYyRTtBQUd0RSxRQUFNeEMsR0FBRyxtQkFBVDtBQUNId0MsSUFBQUEsT0FBTyxDQUFDeEMsR0FBRCxDQUFQLHFCQUFtQnVDLFNBQVMsQ0FBQ3ZDLEdBQUQsQ0FBNUI7QUFFQSxRQUFNeUMsS0FBSyxHQUFHSCxTQUFTLENBQUN0QyxHQUFELENBQXZCOztBQUNBLFFBQUl5QyxLQUFKLEVBQVc7QUFDVCxVQUFNQyxRQUFRLEdBQUdwQixNQUFNLENBQUM3QixTQUFQLENBQWlCO0FBQUEsWUFBRStCLElBQUYsU0FBRUEsSUFBRjtBQUFBLGVBQVlBLElBQUksS0FBS2lCLEtBQXJCO0FBQUEsT0FBakIsQ0FBakI7O0FBRUEsVUFBSUMsUUFBUSxHQUFHLENBQUMsQ0FBaEIsRUFBbUI7QUFDakI7QUFDQUYsUUFBQUEsT0FBTyxDQUFDeEMsR0FBRCxDQUFQLENBQWEwQyxRQUFiLEdBQXdCQSxRQUF4QjtBQUNBRixRQUFBQSxPQUFPLENBQUN4QyxHQUFELENBQVAsQ0FBYWdCLEtBQWIsR0FBcUJ5QixLQUFyQjtBQUNEO0FBQ0Y7QUFmd0U7O0FBRzNFLGtDQUFrQjVDLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZeUMsU0FBWixDQUFsQixrQ0FBMEM7QUFBQTtBQWF6QyxHQWhCMEUsQ0FrQjNFOzs7QUFDQSxNQUFNSSxXQUFXLEdBQUc5QyxNQUFNLENBQUNDLElBQVAsQ0FBWTBDLE9BQVosRUFBcUJJLEtBQXJCLENBQTJCLFVBQUE1QyxHQUFHO0FBQUEsV0FDaEQ2QyxjQUFjLENBQUNMLE9BQU8sQ0FBQ3hDLEdBQUQsQ0FBUixFQUFld0MsT0FBZixFQUF3QmxCLE1BQXhCLENBRGtDO0FBQUEsR0FBOUIsQ0FBcEI7O0FBSUEsTUFBSXFCLFdBQUosRUFBaUI7QUFDZixXQUFPSCxPQUFQO0FBQ0Q7O0FBRUQsU0FBTyxJQUFQO0FBQ0Q7O0FBRU0sU0FBU0ssY0FBVCxDQUF3QkMsTUFBeEIsRUFBZ0NOLE9BQWhDLEVBQXlDbkIsU0FBekMsRUFBb0Q7QUFDekQsTUFBSXlCLE1BQU0sQ0FBQ0MsUUFBUCxJQUFtQkQsTUFBTSxDQUFDOUIsS0FBOUIsRUFBcUM7QUFDbkMsV0FBTyxJQUFQO0FBQ0Q7O0FBQ0QsTUFBSThCLE1BQU0sQ0FBQ0UsU0FBWCxFQUFzQjtBQUNwQixXQUFPRixNQUFNLENBQUNFLFNBQVAsQ0FBaUJGLE1BQWpCLEVBQXlCTixPQUF6QixFQUFrQ25CLFNBQWxDLENBQVA7QUFDRDs7QUFDRCxTQUFPLEtBQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVM0QixzQkFBVCxDQUFnQzNCLE1BQWhDLFNBQTBENEIsY0FBMUQsRUFBMEU7QUFBQTtBQUFBLE1BQWpDQyxjQUFpQzs7QUFDL0UsTUFBTUMsZUFBZSxHQUFHbEgsS0FBSyxDQUFDQyxPQUFOLENBQWMrRyxjQUFkLElBQWdDQSxjQUFoQyxHQUFpRCxDQUFDQSxjQUFELENBQXpFLENBRCtFLENBRy9FOztBQUNBLFNBQU9FLGVBQWUsQ0FBQ3pHLEdBQWhCLENBQW9CLFVBQUEwRyxTQUFTLEVBQUk7QUFDdEMsUUFBTTFCLEtBQUssR0FBRzBCLFNBQVMsQ0FBQzFCLEtBQVYsR0FDVkwsTUFBTSxDQUFDSixJQUFQLENBQVksVUFBQW9DLEVBQUU7QUFBQSxhQUNaekQsTUFBTSxDQUFDQyxJQUFQLENBQVl1RCxTQUFTLENBQUMxQixLQUF0QixFQUE2QmlCLEtBQTdCLENBQW1DLFVBQUE1QyxHQUFHO0FBQUEsZUFBSXFELFNBQVMsQ0FBQzFCLEtBQVYsQ0FBZ0IzQixHQUFoQixNQUF5QnNELEVBQUUsQ0FBQ3RELEdBQUQsQ0FBL0I7QUFBQSxPQUF0QyxDQURZO0FBQUEsS0FBZCxDQURVLEdBSVYsSUFKSjtBQU1BLFdBQU9ILE1BQU0sQ0FBQ0MsSUFBUCxDQUFZcUQsY0FBWixFQUE0QkksTUFBNUIsQ0FDTCxVQUFDQyxJQUFELEVBQU94RCxHQUFQO0FBQUEsNkNBQ0t3RCxJQURMLDRDQUVHeEQsR0FGSCxFQUVTQSxHQUFHLEtBQUssT0FBUixHQUFrQjJCLEtBQWxCLEdBQTBCMEIsU0FBUyxDQUFDckQsR0FBRCxDQUFULElBQWtCbUQsY0FBYyxDQUFDbkQsR0FBRCxDQUZuRTtBQUFBLEtBREssRUFLTCxFQUxLLENBQVA7QUFPRCxHQWRNLENBQVA7QUFlRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVN5RCwyQkFBVCxDQUFxQ25DLE1BQXJDLEVBQTZDaEUsUUFBN0MsRUFBdURvRyxVQUF2RCxFQUFtRTtBQUN4RTdELEVBQUFBLE1BQU0sQ0FBQzhELE1BQVAsQ0FBY3JHLFFBQVEsQ0FBQ3NHLGNBQXZCLEVBQXVDN0QsT0FBdkMsQ0FBK0MsaUJBQXlCO0FBQUEsUUFBdkI0QixLQUF1QixTQUF2QkEsS0FBdUI7QUFBQSxRQUFoQmtDLEtBQWdCLFNBQWhCQSxLQUFnQjtBQUFBLFFBQVQ3RCxHQUFTLFNBQVRBLEdBQVM7QUFDdEUsUUFBSThELFVBQUo7O0FBQ0EsUUFBSUosVUFBVSxDQUFDdkQsTUFBZixFQUF1QjtBQUNyQixVQUFJdUQsVUFBVSxDQUFDdkQsTUFBWCxDQUFrQndCLEtBQWxCLENBQUosRUFBOEI7QUFDNUJtQyxRQUFBQSxVQUFVLEdBQUd4QyxNQUFNLENBQUNKLElBQVAsQ0FDWCxVQUFBb0MsRUFBRTtBQUFBLGlCQUFJSSxVQUFVLENBQUN2RCxNQUFYLElBQXFCbUQsRUFBRSxDQUFDOUIsSUFBSCxLQUFZa0MsVUFBVSxDQUFDdkQsTUFBWCxDQUFrQndCLEtBQWxCLEVBQXlCSCxJQUE5RDtBQUFBLFNBRFMsQ0FBYjtBQUdEOztBQUVELFVBQU11QyxZQUFZLG1DQUNaRCxVQUFVLHdDQUFLbkMsS0FBTCxFQUFhbUMsVUFBYixJQUEyQixFQUR6QixHQUVaSixVQUFVLENBQUN2RCxNQUFYLENBQWtCMEQsS0FBbEIseUNBQTZCQSxLQUE3QixFQUFxQ0gsVUFBVSxDQUFDdkQsTUFBWCxDQUFrQjBELEtBQWxCLENBQXJDLElBQWlFLEVBRnJELENBQWxCOztBQUlBLFVBQUloRSxNQUFNLENBQUNDLElBQVAsQ0FBWWlFLFlBQVosRUFBMEIzSCxNQUE5QixFQUFzQztBQUNwQ2tCLFFBQUFBLFFBQVEsQ0FBQzBHLGlCQUFULENBQTJCRCxZQUEzQjtBQUNEOztBQUVEekcsTUFBQUEsUUFBUSxDQUFDMkcscUJBQVQsQ0FBK0JqRSxHQUEvQjtBQUNEO0FBQ0YsR0FuQkQ7QUFvQkEsU0FBTzFDLFFBQVA7QUFDRDs7QUFFTSxTQUFTRix3QkFBVCxDQUFrQ0osUUFBbEMsRUFBNENLLFlBQTVDLEVBQTBETixNQUExRCxFQUFrRTtBQUN2RSxNQUFNVixTQUFTLEdBQUcsRUFBbEI7QUFDQSxNQUFNQyxNQUFNLEdBQUcsRUFBZjtBQUVBUyxFQUFBQSxNQUFNLENBQUNnRCxPQUFQLENBQWUsVUFBQW1FLEtBQUssRUFBSTtBQUN0QixRQUFJQyxhQUFKOztBQUNBLFFBQUksQ0FBQ0QsS0FBRCxJQUFVLENBQUNBLEtBQUssQ0FBQy9ELE1BQXJCLEVBQTZCO0FBQzNCZ0UsTUFBQUEsYUFBYSxHQUFHLElBQWhCO0FBQ0QsS0FGRCxNQUVPLElBQUluSCxRQUFRLENBQUNrSCxLQUFLLENBQUMvRCxNQUFOLENBQWF0RCxNQUFkLENBQVosRUFBbUM7QUFDeEM7QUFDQXNILE1BQUFBLGFBQWEsR0FBR0MscUJBQXFCLENBQUNwSCxRQUFRLENBQUNrSCxLQUFLLENBQUMvRCxNQUFOLENBQWF0RCxNQUFkLENBQVQsRUFBZ0NxSCxLQUFoQyxFQUF1QzdHLFlBQXZDLENBQXJDO0FBQ0Q7O0FBRUQsUUFBSThHLGFBQUosRUFBbUI7QUFDakI5SCxNQUFBQSxTQUFTLENBQUNnSSxJQUFWLENBQWVGLGFBQWY7QUFDRCxLQUZELE1BRU87QUFDTDtBQUNBN0gsTUFBQUEsTUFBTSxDQUFDK0gsSUFBUCxDQUFZSCxLQUFaO0FBQ0Q7QUFDRixHQWZEO0FBaUJBLFNBQU87QUFBQzdILElBQUFBLFNBQVMsRUFBVEEsU0FBRDtBQUFZQyxJQUFBQSxNQUFNLEVBQU5BO0FBQVosR0FBUDtBQUNEO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBUzhILHFCQUFULFNBRUxWLFVBRkssRUFHTHJHLFlBSEssRUFLTDtBQUFBLE1BSkNpRSxNQUlELFVBSkNBLE1BSUQ7QUFBQSxNQUphekUsTUFJYixVQUpTeUIsRUFJVDtBQUFBLE1BREFnRyxPQUNBLHVFQURVLEVBQ1Y7QUFBQSxNQUNPQyxJQURQLEdBQ2ViLFVBRGYsQ0FDT2EsSUFEUCxFQUVBOztBQUNBLE1BQUksQ0FBQ0EsSUFBRCxJQUFTLENBQUNsSCxZQUFZLENBQUNtSCxjQUFiLENBQTRCRCxJQUE1QixDQUFWLElBQStDLENBQUNiLFVBQVUsQ0FBQ3ZELE1BQS9ELEVBQXVFO0FBQ3JFLFdBQU8sSUFBUDtBQUNEOztBQUVELE1BQUk3QyxRQUFRLEdBQUcsSUFBSUQsWUFBWSxDQUFDa0gsSUFBRCxDQUFoQixDQUF1QjtBQUNwQ2pHLElBQUFBLEVBQUUsRUFBRW9GLFVBQVUsQ0FBQ3BGLEVBRHFCO0FBRXBDekIsSUFBQUEsTUFBTSxFQUFOQSxNQUZvQztBQUdwQzRILElBQUFBLEtBQUssRUFBRWYsVUFBVSxDQUFDdkQsTUFBWCxDQUFrQnNFLEtBSFc7QUFJcENDLElBQUFBLEtBQUssRUFBRWhCLFVBQVUsQ0FBQ3ZELE1BQVgsQ0FBa0J1RSxLQUpXO0FBS3BDQyxJQUFBQSxTQUFTLEVBQUVqQixVQUFVLENBQUN2RCxNQUFYLENBQWtCd0UsU0FMTztBQU1wQ0MsSUFBQUEsTUFBTSxFQUFFbEIsVUFBVSxDQUFDdkQsTUFBWCxDQUFrQnlFLE1BTlU7QUFPcENDLElBQUFBLGNBQWMsRUFBRW5CLFVBQVUsQ0FBQ3ZELE1BQVgsQ0FBa0IwRTtBQVBFLEdBQXZCLENBQWYsQ0FQQSxDQWlCQTs7QUFDQSxNQUFNQyxZQUFZLEdBQUd4SCxRQUFRLENBQUN5SCxlQUFULEVBQXJCOztBQUNBLE1BQUlsRixNQUFNLENBQUNDLElBQVAsQ0FBWWdGLFlBQVosRUFBMEIxSSxNQUE5QixFQUFzQztBQUNwQyxRQUFNb0csT0FBTyxHQUFHSCx5QkFBeUIsQ0FBQ2YsTUFBRCxFQUFTb0MsVUFBVSxDQUFDdkQsTUFBWCxDQUFrQnFDLE9BQTNCLEVBQW9Dc0MsWUFBcEMsQ0FBekM7O0FBQ0EsUUFBSXRDLE9BQUosRUFBYTtBQUNYbEYsTUFBQUEsUUFBUSxDQUFDMEcsaUJBQVQsQ0FBMkI7QUFBQ3hCLFFBQUFBLE9BQU8sRUFBUEE7QUFBRCxPQUEzQjtBQUNELEtBRkQsTUFFTyxJQUFJLENBQUM4QixPQUFPLENBQUNVLGdCQUFiLEVBQStCO0FBQ3BDLGFBQU8sSUFBUDtBQUNEO0FBQ0YsR0ExQkQsQ0E0QkE7QUFDQTtBQUNBOzs7QUFDQTFILEVBQUFBLFFBQVEsR0FBR21HLDJCQUEyQixDQUFDbkMsTUFBRCxFQUFTaEUsUUFBVCxFQUFtQm9HLFVBQW5CLENBQXRDO0FBRUEsTUFBTUwsU0FBUyxHQUNiSyxVQUFVLENBQUN2RCxNQUFYLENBQWtCa0QsU0FBbEIsSUFBK0IvRixRQUFRLENBQUM2QyxNQUFULENBQWdCa0QsU0FBL0MsR0FDSUosc0JBQXNCLENBQUMzQixNQUFELEVBQVNoRSxRQUFRLENBQUM2QyxNQUFULENBQWdCa0QsU0FBekIsRUFBb0NLLFVBQVUsQ0FBQ3ZELE1BQVgsQ0FBa0JrRCxTQUF0RCxDQUQxQixHQUVJL0YsUUFBUSxDQUFDNkMsTUFBVCxDQUFnQmtELFNBSHRCLENBakNBLENBc0NBOztBQUNBLE1BQU00QixTQUFTLEdBQUczSCxRQUFRLENBQUM0SCxlQUFULENBQ2hCNUgsUUFBUSxDQUFDNkMsTUFBVCxDQUFnQjhFLFNBREEsRUFFaEJ2QixVQUFVLENBQUN2RCxNQUFYLENBQWtCOEUsU0FBbEIsSUFBK0IsRUFGZixFQUdoQjtBQUFDRSxJQUFBQSxXQUFXLEVBQUUsQ0FBQyxZQUFELEVBQWUsa0JBQWY7QUFBZCxHQUhnQixDQUFsQjtBQU1BN0gsRUFBQUEsUUFBUSxDQUFDMEcsaUJBQVQsQ0FBMkI7QUFDekJpQixJQUFBQSxTQUFTLEVBQVRBLFNBRHlCO0FBRXpCNUIsSUFBQUEsU0FBUyxFQUFUQTtBQUZ5QixHQUEzQjtBQUtBLFNBQU8vRixRQUFQO0FBQ0Q7O0FBRU0sU0FBUzhILGFBQVQsQ0FBdUJDLE1BQXZCLEVBQStCO0FBQ3BDLFNBQU8scUJBQVNBLE1BQVQsS0FBb0IsT0FBT0EsTUFBTSxDQUFDQyxLQUFkLEtBQXdCLFVBQTVDLElBQTBELE9BQU9ELE1BQU0sQ0FBQ0UsSUFBZCxLQUF1QixRQUF4RjtBQUNEOztBQUVNLElBQU1DLGlCQUFpQixHQUFHLENBQy9CO0FBQUNGLEVBQUFBLEtBQUssRUFBRXJILFdBQVI7QUFBcUJzSCxFQUFBQSxJQUFJLEVBQUUsUUFBM0I7QUFBcUNFLEVBQUFBLFdBQVcsRUFBRTtBQUFsRCxDQUQrQixFQUUvQjtBQUFDSCxFQUFBQSxLQUFLLEVBQUV2SixZQUFSO0FBQXNCd0osRUFBQUEsSUFBSSxFQUFFLFNBQTVCO0FBQXVDRSxFQUFBQSxXQUFXLEVBQUU7QUFBcEQsQ0FGK0IsRUFHL0I7QUFBQ0gsRUFBQUEsS0FBSyxFQUFFNUYsaUJBQVI7QUFBMkI2RixFQUFBQSxJQUFJLEVBQUUsbUJBQWpDO0FBQXNERSxFQUFBQSxXQUFXLEVBQUU7QUFBbkUsQ0FIK0IsRUFJL0I7QUFBQ0gsRUFBQUEsS0FBSyxFQUFFekQsa0JBQVI7QUFBNEIwRCxFQUFBQSxJQUFJLEVBQUU7QUFBbEMsQ0FKK0IsRUFLL0I7QUFBQ0QsRUFBQUEsS0FBSyxFQUFFMUUsY0FBUjtBQUF3QjJFLEVBQUFBLElBQUksRUFBRSxXQUE5QjtBQUEyQ0UsRUFBQUEsV0FBVyxFQUFFO0FBQXhELENBTCtCLEVBTS9CO0FBQUNILEVBQUFBLEtBQUssRUFBRXRELG9CQUFSO0FBQThCdUQsRUFBQUEsSUFBSSxFQUFFO0FBQXBDLENBTitCLENBQTFCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIxIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHVuaXEgZnJvbSAnbG9kYXNoLnVuaXEnO1xuaW1wb3J0IHBpY2sgZnJvbSAnbG9kYXNoLnBpY2snO1xuaW1wb3J0IGZsYXR0ZW5EZWVwIGZyb20gJ2xvZGFzaC5mbGF0dGVuZGVlcCc7XG5pbXBvcnQge2lzT2JqZWN0LCBhcnJheUluc2VydH0gZnJvbSAndXRpbHMvdXRpbHMnO1xuaW1wb3J0IHthcHBseUZpbHRlcnNUb0RhdGFzZXRzLCB2YWxpZGF0ZUZpbHRlcnNVcGRhdGVEYXRhc2V0c30gZnJvbSAndXRpbHMvZmlsdGVyLXV0aWxzJztcblxuaW1wb3J0IHtnZXRJbml0aWFsTWFwTGF5ZXJzRm9yU3BsaXRNYXB9IGZyb20gJ3V0aWxzL3NwbGl0LW1hcC11dGlscyc7XG5pbXBvcnQge3Jlc2V0RmlsdGVyR3B1TW9kZSwgYXNzaWduR3B1Q2hhbm5lbHN9IGZyb20gJ3V0aWxzL2dwdS1maWx0ZXItdXRpbHMnO1xuaW1wb3J0IHtMQVlFUl9CTEVORElOR1N9IGZyb20gJ2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcbmltcG9ydCB7Q1VSUkVOVF9WRVJTSU9OLCB2aXNTdGF0ZVNjaGVtYX0gZnJvbSAnc2NoZW1hcyc7XG5cbi8qKlxuICogTWVyZ2UgbG9hZGVkIGZpbHRlcnMgd2l0aCBjdXJyZW50IHN0YXRlLCBpZiBubyBmaWVsZHMgb3IgZGF0YSBhcmUgbG9hZGVkXG4gKiBzYXZlIGl0IGZvciBsYXRlclxuICpcbiAqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KCcuL3Zpcy1zdGF0ZS1tZXJnZXInKS5tZXJnZUZpbHRlcnN9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUZpbHRlcnMoc3RhdGUsIGZpbHRlcnNUb01lcmdlKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShmaWx0ZXJzVG9NZXJnZSkgfHwgIWZpbHRlcnNUb01lcmdlLmxlbmd0aCkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIGNvbnN0IHt2YWxpZGF0ZWQsIGZhaWxlZCwgdXBkYXRlZERhdGFzZXRzfSA9IHZhbGlkYXRlRmlsdGVyc1VwZGF0ZURhdGFzZXRzKHN0YXRlLCBmaWx0ZXJzVG9NZXJnZSk7XG5cbiAgLy8gbWVyZ2UgZmlsdGVyIHdpdGggZXhpc3RpbmdcbiAgbGV0IHVwZGF0ZWRGaWx0ZXJzID0gWy4uLihzdGF0ZS5maWx0ZXJzIHx8IFtdKSwgLi4udmFsaWRhdGVkXTtcbiAgdXBkYXRlZEZpbHRlcnMgPSByZXNldEZpbHRlckdwdU1vZGUodXBkYXRlZEZpbHRlcnMpO1xuICB1cGRhdGVkRmlsdGVycyA9IGFzc2lnbkdwdUNoYW5uZWxzKHVwZGF0ZWRGaWx0ZXJzKTtcbiAgLy8gZmlsdGVyIGRhdGFcbiAgY29uc3QgZGF0YXNldHNUb0ZpbHRlciA9IHVuaXEoZmxhdHRlbkRlZXAodmFsaWRhdGVkLm1hcChmID0+IGYuZGF0YUlkKSkpO1xuXG4gIGNvbnN0IGZpbHRlcmVkID0gYXBwbHlGaWx0ZXJzVG9EYXRhc2V0cyhcbiAgICBkYXRhc2V0c1RvRmlsdGVyLFxuICAgIHVwZGF0ZWREYXRhc2V0cyxcbiAgICB1cGRhdGVkRmlsdGVycyxcbiAgICBzdGF0ZS5sYXllcnNcbiAgKTtcblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGZpbHRlcnM6IHVwZGF0ZWRGaWx0ZXJzLFxuICAgIGRhdGFzZXRzOiBmaWx0ZXJlZCxcbiAgICBmaWx0ZXJUb0JlTWVyZ2VkOiBbLi4uc3RhdGUuZmlsdGVyVG9CZU1lcmdlZCwgLi4uZmFpbGVkXVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTGF5ZXJGcm9tQ29uZmlnKHN0YXRlLCBsYXllckNvbmZpZykge1xuICAvLyBmaXJzdCB2YWxpZGF0ZSBjb25maWcgYWdhaW5zdCBkYXRhc2V0XG4gIGNvbnN0IHt2YWxpZGF0ZWQsIGZhaWxlZH0gPSB2YWxpZGF0ZUxheWVyc0J5RGF0YXNldHMoc3RhdGUuZGF0YXNldHMsIHN0YXRlLmxheWVyQ2xhc3NlcywgW1xuICAgIGxheWVyQ29uZmlnXG4gIF0pO1xuXG4gIGlmIChmYWlsZWQubGVuZ3RoIHx8ICF2YWxpZGF0ZWQubGVuZ3RoKSB7XG4gICAgLy8gZmFpbGVkXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBuZXdMYXllciA9IHZhbGlkYXRlZFswXTtcbiAgbmV3TGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oc3RhdGUuZGF0YXNldHMpO1xuICByZXR1cm4gbmV3TGF5ZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVMYXllcihuZXdMYXllcikge1xuICBjb25zdCBzYXZlZFZpc1N0YXRlID0gdmlzU3RhdGVTY2hlbWFbQ1VSUkVOVF9WRVJTSU9OXS5zYXZlKHtcbiAgICBsYXllcnM6IFtuZXdMYXllcl0sXG4gICAgbGF5ZXJPcmRlcjogWzBdXG4gIH0pLnZpc1N0YXRlO1xuICBjb25zdCBsb2FkZWRMYXllciA9IHZpc1N0YXRlU2NoZW1hW0NVUlJFTlRfVkVSU0lPTl0ubG9hZChzYXZlZFZpc1N0YXRlKS52aXNTdGF0ZS5sYXllcnNbMF07XG4gIHJldHVybiBsb2FkZWRMYXllcjtcbn1cblxuLyoqXG4gKiBNZXJnZSBsYXllcnMgZnJvbSBkZS1zZXJpYWxpemVkIHN0YXRlLCBpZiBubyBmaWVsZHMgb3IgZGF0YSBhcmUgbG9hZGVkXG4gKiBzYXZlIGl0IGZvciBsYXRlclxuICpcbiAqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KCcuL3Zpcy1zdGF0ZS1tZXJnZXInKS5tZXJnZUxheWVyc31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlTGF5ZXJzKHN0YXRlLCBsYXllcnNUb01lcmdlLCBmcm9tQ29uZmlnKSB7XG4gIGNvbnN0IHByZXNlcnZlTGF5ZXJPcmRlciA9IGZyb21Db25maWcgPyBsYXllcnNUb01lcmdlLm1hcChsID0+IGwuaWQpIDogc3RhdGUucHJlc2VydmVMYXllck9yZGVyO1xuXG4gIGlmICghQXJyYXkuaXNBcnJheShsYXllcnNUb01lcmdlKSB8fCAhbGF5ZXJzVG9NZXJnZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICBjb25zdCB7dmFsaWRhdGVkOiBtZXJnZWRMYXllciwgZmFpbGVkOiB1bm1lcmdlZH0gPSB2YWxpZGF0ZUxheWVyc0J5RGF0YXNldHMoXG4gICAgc3RhdGUuZGF0YXNldHMsXG4gICAgc3RhdGUubGF5ZXJDbGFzc2VzLFxuICAgIGxheWVyc1RvTWVyZ2VcbiAgKTtcblxuICAvLyBwdXQgbmV3IGxheWVycyBpbiBmcm9udCBvZiBjdXJyZW50IGxheWVyc1xuICBjb25zdCB7bmV3TGF5ZXJPcmRlciwgbmV3TGF5ZXJzfSA9IGluc2VydExheWVyQXRSaWdodE9yZGVyKFxuICAgIHN0YXRlLmxheWVycyxcbiAgICBtZXJnZWRMYXllcixcbiAgICBzdGF0ZS5sYXllck9yZGVyLFxuICAgIHByZXNlcnZlTGF5ZXJPcmRlclxuICApO1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJzOiBuZXdMYXllcnMsXG4gICAgbGF5ZXJPcmRlcjogbmV3TGF5ZXJPcmRlcixcbiAgICBwcmVzZXJ2ZUxheWVyT3JkZXIsXG4gICAgbGF5ZXJUb0JlTWVyZ2VkOiBbLi4uc3RhdGUubGF5ZXJUb0JlTWVyZ2VkLCAuLi51bm1lcmdlZF1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydExheWVyQXRSaWdodE9yZGVyKFxuICBjdXJyZW50TGF5ZXJzLFxuICBsYXllcnNUb0luc2VydCxcbiAgY3VycmVudE9yZGVyLFxuICBwcmVzZXJ2ZWRPcmRlciA9IFtdXG4pIHtcbiAgLy8gcGVyc2VydmVkT3JkZXIgWydhJywgJ2InLCAnYyddO1xuICAvLyBsYXllck9yZGVyIFsxLCAwLCAzXVxuICAvLyBsYXllck9yZGVyTWFwIFsnYScsICdjJ11cbiAgbGV0IGxheWVyT3JkZXJRdWV1ZSA9IGN1cnJlbnRPcmRlci5tYXAoaSA9PiBjdXJyZW50TGF5ZXJzW2ldLmlkKTtcbiAgbGV0IG5ld0xheWVycyA9IGN1cnJlbnRMYXllcnM7XG5cbiAgZm9yIChjb25zdCBuZXdMYXllciBvZiBsYXllcnNUb0luc2VydCkge1xuICAgIC8vIGZpbmQgd2hlcmUgdG8gaW5zZXJ0IGl0XG4gICAgY29uc3QgZXhwZWN0ZWRJZHggPSBwcmVzZXJ2ZWRPcmRlci5pbmRleE9mKG5ld0xheWVyLmlkKTtcbiAgICAvLyBpZiBjYW50IGZpbmQgcGxhY2UgdG8gaW5zZXJ0LCBpbnNlcnQgYXQgdGhlIGZvbnRcbiAgICBsZXQgaW5zZXJ0QXQgPSAwO1xuXG4gICAgaWYgKGV4cGVjdGVkSWR4ID4gMCkge1xuICAgICAgLy8gbG9vayBmb3IgbGF5ZXIgdG8gaW5zZXJ0IGFmdGVyXG4gICAgICBsZXQgaSA9IGV4cGVjdGVkSWR4ICsgMTtcbiAgICAgIGxldCBwcmVjZWVkSWR4ID0gbnVsbDtcbiAgICAgIHdoaWxlIChpLS0gPiAwICYmIHByZWNlZWRJZHggPT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgcHJlY2VlZExheWVyID0gcHJlc2VydmVkT3JkZXJbZXhwZWN0ZWRJZHggLSAxXTtcbiAgICAgICAgcHJlY2VlZElkeCA9IGxheWVyT3JkZXJRdWV1ZS5pbmRleE9mKHByZWNlZWRMYXllcik7XG4gICAgICB9