kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
460 lines (374 loc) • 60 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = ModalContainerFactory;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _styledComponents = require("styled-components");
var _reactDom = require("react-dom");
var _window = require("global/window");
var _modal = _interopRequireDefault(require("./common/modal"));
var _dataProcessor = require("../processors/data-processor");
var _schemas = _interopRequireDefault(require("../schemas"));
var _exportImageUtils = require("../utils/export-image-utils");
var _deleteDataModal = _interopRequireDefault(require("./modals/delete-data-modal"));
var _dataTableModal = _interopRequireDefault(require("./modals/data-table-modal"));
var _loadDataModal = _interopRequireDefault(require("./modals/load-data-modal"));
var _loadExternalDataModal = _interopRequireDefault(require("./modals/load-external-data-modal"));
var _exportImageModal = _interopRequireDefault(require("./modals/export-image-modal"));
var _exportDataModal = _interopRequireDefault(require("./modals/export-data-modal"));
var _exportMapModal = _interopRequireDefault(require("./modals/export-map-modal"));
var _addMapStyleModal = _interopRequireDefault(require("./modals/add-map-style-modal"));
var _mediaBreakpoints = require("../styles/media-breakpoints");
var _exportMapHtml = require("../templates/export-map-html");
var _defaultSettings = require("../constants/default-settings");
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
var DataTableModalStyle = (0, _styledComponents.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n top: 80px;\n padding: 32px 0 0 0;\n\n ", "\n\n ", "\n"])), _mediaBreakpoints.media.portable(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 0;\n "]))), _mediaBreakpoints.media.palm(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 0;\n margin: 0 auto;\n "]))));
var DeleteDatasetModalStyled = (0, _styledComponents.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n width: 40%;\n padding: 40px 40px 32px 40px;\n"])));
var LoadDataModalStyle = (0, _styledComponents.css)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n top: 110px;\n"])));
ModalContainerFactory.deps = [_loadExternalDataModal["default"], _dataTableModal["default"], _deleteDataModal["default"], _loadDataModal["default"], _exportImageModal["default"], _exportDataModal["default"], _exportMapModal["default"], _addMapStyleModal["default"]];
function ModalContainerFactory(LoadExternalDataModal, DataTableModal, DeleteDatasetModal, LoadDataModal, ExportImageModal, ExportDataModal, ExportMapModal, AddMapStyleModal) {
var ModalWrapper = /*#__PURE__*/function (_Component) {
(0, _inherits2["default"])(ModalWrapper, _Component);
var _super = _createSuper(ModalWrapper);
function ModalWrapper() {
var _this;
(0, _classCallCheck2["default"])(this, ModalWrapper);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_closeModal", function () {
_this.props.uiStateActions.toggleModal(null);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_deleteDataset", function (key) {
_this.props.visStateActions.removeDataset(key);
_this._closeModal();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onAddCustomMapStyle", function () {
_this.props.mapStyleActions.addCustomMapStyle();
_this._closeModal();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onFileUpload", function (blob) {
_this.props.visStateActions.loadFiles(blob);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportImage", function () {
var _this$props$uiState$e = _this.props.uiState.exportImage,
exporting = _this$props$uiState$e.exporting,
imageDataUri = _this$props$uiState$e.imageDataUri;
if (!exporting && imageDataUri) {
var file = (0, _exportImageUtils.dataURItoBlob)(imageDataUri);
(0, _exportImageUtils.downloadFile)(file, _defaultSettings.DEFAULT_EXPORT_IMAGE_NAME);
}
_this.props.uiStateActions.cleanupExportImage();
_this._closeModal();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportData", function () {
var _this$props = _this.props,
visState = _this$props.visState,
uiState = _this$props.uiState;
var datasets = visState.datasets;
var _uiState$exportData = uiState.exportData,
selectedDataset = _uiState$exportData.selectedDataset,
dataType = _uiState$exportData.dataType,
filtered = _uiState$exportData.filtered; // get the selected data
var filename = 'geoiq.io';
var selectedDatasets = datasets[selectedDataset] ? [datasets[selectedDataset]] : Object.values(datasets);
if (!selectedDatasets.length) {
// error: selected dataset not found.
_this._closeModal();
}
selectedDatasets.forEach(function (selectedData) {
var allData = selectedData.allData,
data = selectedData.data,
fields = selectedData.fields,
label = selectedData.label,
externalData = selectedData.externalData;
var exportData = filtered ? data : allData;
if (externalData && externalData === true) {
return null;
} // start to export data according to selected data type
switch (dataType) {
case _defaultSettings.EXPORT_DATA_TYPE.CSV:
{
var type = 'text/csv';
var csv = (0, _dataProcessor.formatCsv)(exportData, fields);
_this._downloadFile(csv, type, "".concat(filename, "_").concat(label, ".csv"));
break;
}
// TODO: support more file types.
default:
break;
}
});
_this._closeModal();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportJSONMap", function () {
var uiState = _this.props.uiState;
var hasData = uiState.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.JSON].hasData; // we pass all props because we avoid to create new variables
var data = hasData ? _schemas["default"].save(_this.props) : _schemas["default"].getConfigToSave(_this.props);
_this._downloadFile(JSON.stringify(data, null, 2), 'application/json', 'keplergl.json');
_this._closeModal();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportHTMLMap", function () {
var uiState = _this.props.uiState;
var _uiState$exportMap$EX = uiState.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.HTML],
userMapboxToken = _uiState$exportMap$EX.userMapboxToken,
exportMapboxAccessToken = _uiState$exportMap$EX.exportMapboxAccessToken,
mode = _uiState$exportMap$EX.mode;
var data = _objectSpread(_objectSpread({}, _schemas["default"].save(_this.props)), {}, {
mapboxApiAccessToken: (userMapboxToken || '') !== '' ? userMapboxToken : exportMapboxAccessToken,
mode: mode
});
_this._downloadFile((0, _exportMapHtml.exportMapToHTML)(data), 'text/html', 'kepler.gl.html');
_this._closeModal();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportMap", function () {
var _EXPORT_MAP_FORMATS$H;
var uiState = _this.props.uiState;
var format = uiState.exportMap.format;
var downloader = (_EXPORT_MAP_FORMATS$H = {}, (0, _defineProperty2["default"])(_EXPORT_MAP_FORMATS$H, _defaultSettings.EXPORT_MAP_FORMATS.HTML, _this._onExportHTMLMap), (0, _defineProperty2["default"])(_EXPORT_MAP_FORMATS$H, _defaultSettings.EXPORT_MAP_FORMATS.JSON, _this._onExportJSONMap), _EXPORT_MAP_FORMATS$H)[format];
downloader && downloader();
});
return _this;
}
(0, _createClass2["default"])(ModalWrapper, [{
key: "_downloadFile",
value: function _downloadFile(data, type, filename) {
var fileBlob = new _window.Blob([data], {
type: type
});
(0, _exportImageUtils.downloadFile)(fileBlob, filename);
}
}, {
key: "render",
value:
/* eslint-disable complexity */
function render() {
var _this2 = this;
var _this$props2 = this.props,
containerW = _this$props2.containerW,
containerH = _this$props2.containerH,
mapStyle = _this$props2.mapStyle,
mapState = _this$props2.mapState,
uiState = _this$props2.uiState,
visState = _this$props2.visState,
rootNode = _this$props2.rootNode,
visStateActions = _this$props2.visStateActions;
var currentModal = uiState.currentModal,
datasetKeyToRemove = uiState.datasetKeyToRemove;
var datasets = visState.datasets,
layers = visState.layers,
editingDataset = visState.editingDataset;
var exportDatasets = {};
var datasetKeys = Object.keys(datasets);
datasetKeys.map(function (dk) {
var externalData = datasets[dk].externalData;
externalData && externalData === true ? null : exportDatasets = _objectSpread(_objectSpread({}, exportDatasets), {}, (0, _defineProperty2["default"])({}, dk, datasets[dk]));
});
var template = null;
var modalProps = {};
if (currentModal && currentModal.id && currentModal.template) {
// if currentMdoal template is already provided
// TODO: need to check whether template is valid
template = /*#__PURE__*/_react["default"].createElement(currentModal.template, null);
modalProps = currentModal.modalProps;
} else {
switch (currentModal) {
case _defaultSettings.DATA_TABLE_ID:
var width = containerW * 0.9;
template = /*#__PURE__*/_react["default"].createElement(DataTableModal, {
width: containerW * 0.9,
height: containerH * 0.85,
datasets: datasets,
dataId: editingDataset,
showDatasetTable: visStateActions.showDatasetTable
}); // TODO: we need to make this width consistent with the css rule defined modal.js:32 max-width: 70vw
modalProps.cssStyle = (0, _styledComponents.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n ", ";\n ", "\n "])), DataTableModalStyle, _mediaBreakpoints.media.palm(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n width: ", "px;\n "])), width));
break;
case _defaultSettings.ADD_EXTERNAL_DATA_ID:
template = /*#__PURE__*/_react["default"].createElement(LoadExternalDataModal, null);
modalProps = {
title: 'Add External Data To Map',
footer: false // confirmButton: {
// large: true,
// children: 'Add External Dataset'
// }
};
break;
case _defaultSettings.DELETE_DATA_ID:
// validate options
if (datasetKeyToRemove && datasets && datasets[datasetKeyToRemove]) {
template = /*#__PURE__*/_react["default"].createElement(DeleteDatasetModal, {
dataset: datasets[datasetKeyToRemove],
layers: layers
});
modalProps = {
title: 'Delete Dataset',
cssStyle: DeleteDatasetModalStyled,
footer: true,
onConfirm: function onConfirm() {
return _this2._deleteDataset(datasetKeyToRemove);
},
onCancel: this._closeModal,
confirmButton: {
negative: true,
large: true,
children: 'Delete'
}
};
}
break;
// in case we add a new case after this one
case _defaultSettings.ADD_DATA_ID:
template = /*#__PURE__*/_react["default"].createElement(LoadDataModal, (0, _extends2["default"])({
onClose: this._closeModal,
onFileUpload: this._onFileUpload
}, uiState.loadFiles));
modalProps = {
title: 'Add Data From Datahub',
cssStyle: LoadDataModalStyle,
footer: false,
onConfirm: this._closeModal
};
break;
case _defaultSettings.EXPORT_IMAGE_ID:
template = /*#__PURE__*/_react["default"].createElement(ExportImageModal, (0, _extends2["default"])({}, uiState.exportImage, {
width: containerW,
height: containerH,
onChangeRatio: this.props.uiStateActions.setRatio,
onChangeResolution: this.props.uiStateActions.setResolution,
onToggleLegend: this.props.uiStateActions.toggleLegend
}));
modalProps = {
close: false,
title: 'Export Image',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onExportImage,
confirmButton: {
large: true,
disabled: uiState.exportImage.exporting,
children: 'Download'
}
};
break;
case _defaultSettings.EXPORT_DATA_ID:
template = /*#__PURE__*/_react["default"].createElement(ExportDataModal, (0, _extends2["default"])({}, uiState.exportData, {
datasets: exportDatasets,
onClose: this._closeModal,
onChangeExportDataType: this.props.uiStateActions.setExportDataType,
onChangeExportSelectedDataset: this.props.uiStateActions.setExportSelectedDataset,
onChangeExportFiltered: this.props.uiStateActions.setExportFiltered
}));
modalProps = {
close: false,
title: 'Export Data',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onExportData,
confirmButton: {
large: true,
children: 'Export'
}
};
break;
case _defaultSettings.EXPORT_MAP_ID:
var keplerGlConfig = _schemas["default"].getConfigToSave({
mapStyle: mapStyle,
visState: visState,
mapState: mapState,
uiState: uiState
});
template = /*#__PURE__*/_react["default"].createElement(ExportMapModal, {
config: keplerGlConfig,
options: uiState.exportMap,
onChangeExportMapFormat: this.props.uiStateActions.setExportMapFormat,
onEditUserMapboxAccessToken: this.props.uiStateActions.setUserMapboxAccessToken,
onChangeExportMapHTMLMode: this.props.uiStateActions.setExportHTMLMapMode
});
modalProps = {
close: false,
title: 'Export Map',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onExportMap,
confirmButton: {
large: true,
children: 'Export'
}
};
break;
case _defaultSettings.ADD_MAP_STYLE_ID:
template = /*#__PURE__*/_react["default"].createElement(AddMapStyleModal, {
mapboxApiAccessToken: this.props.mapboxApiAccessToken,
mapboxApiUrl: this.props.mapboxApiUrl,
mapState: this.props.mapState,
inputStyle: mapStyle.inputStyle,
inputMapStyle: this.props.mapStyleActions.inputMapStyle,
loadCustomMapStyle: this.props.mapStyleActions.loadCustomMapStyle
});
modalProps = {
close: false,
title: 'Add Custom Mapbox Style',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onAddCustomMapStyle,
confirmButton: {
large: true,
disabled: !mapStyle.inputStyle.style,
children: 'Add Style'
}
};
break;
default:
break;
}
}
return this.props.rootNode ? /*#__PURE__*/_react["default"].createElement(_modal["default"], (0, _extends2["default"])({}, modalProps, {
parentSelector: function parentSelector() {
return (0, _reactDom.findDOMNode)(rootNode);
},
isOpen: Boolean(currentModal),
close: this._closeModal
}), template) : null;
}
/* eslint-enable complexity */
}]);
return ModalWrapper;
}(_react.Component);
(0, _defineProperty2["default"])(ModalWrapper, "propTypes", {
rootNode: _propTypes["default"].object,
containerW: _propTypes["default"].number,
containerH: _propTypes["default"].number,
mapboxApiAccessToken: _propTypes["default"].string.isRequired,
mapboxApiUrl: _propTypes["default"].string,
mapState: _propTypes["default"].object.isRequired,
mapStyle: _propTypes["default"].object.isRequired,
uiState: _propTypes["default"].object.isRequired,
visState: _propTypes["default"].object.isRequired,
visStateActions: _propTypes["default"].object.isRequired,
uiStateActions: _propTypes["default"].object.isRequired,
mapStyleActions: _propTypes["default"].object.isRequired
});
return ModalWrapper;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL21vZGFsLWNvbnRhaW5lci5qcyJdLCJuYW1lcyI6WyJEYXRhVGFibGVNb2RhbFN0eWxlIiwiY3NzIiwibWVkaWEiLCJwb3J0YWJsZSIsInBhbG0iLCJEZWxldGVEYXRhc2V0TW9kYWxTdHlsZWQiLCJMb2FkRGF0YU1vZGFsU3R5bGUiLCJNb2RhbENvbnRhaW5lckZhY3RvcnkiLCJkZXBzIiwiTG9hZEV4dGVybmFsRGF0YU1vZGFsRmFjdG9yeSIsIkRhdGFUYWJsZU1vZGFsRmFjdG9yeSIsIkRlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnkiLCJMb2FkRGF0YU1vZGFsRmFjdG9yeSIsIkV4cG9ydEltYWdlTW9kYWxGYWN0b3J5IiwiRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSIsIkV4cG9ydE1hcE1vZGFsRmFjdG9yeSIsIkFkZE1hcFN0eWxlTW9kYWxGYWN0b3J5IiwiTG9hZEV4dGVybmFsRGF0YU1vZGFsIiwiRGF0YVRhYmxlTW9kYWwiLCJEZWxldGVEYXRhc2V0TW9kYWwiLCJMb2FkRGF0YU1vZGFsIiwiRXhwb3J0SW1hZ2VNb2RhbCIsIkV4cG9ydERhdGFNb2RhbCIsIkV4cG9ydE1hcE1vZGFsIiwiQWRkTWFwU3R5bGVNb2RhbCIsIk1vZGFsV3JhcHBlciIsInByb3BzIiwidWlTdGF0ZUFjdGlvbnMiLCJ0b2dnbGVNb2RhbCIsImtleSIsInZpc1N0YXRlQWN0aW9ucyIsInJlbW92ZURhdGFzZXQiLCJfY2xvc2VNb2RhbCIsIm1hcFN0eWxlQWN0aW9ucyIsImFkZEN1c3RvbU1hcFN0eWxlIiwiYmxvYiIsImxvYWRGaWxlcyIsInVpU3RhdGUiLCJleHBvcnRJbWFnZSIsImV4cG9ydGluZyIsImltYWdlRGF0YVVyaSIsImZpbGUiLCJERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FIiwiY2xlYW51cEV4cG9ydEltYWdlIiwidmlzU3RhdGUiLCJkYXRhc2V0cyIsImV4cG9ydERhdGEiLCJzZWxlY3RlZERhdGFzZXQiLCJkYXRhVHlwZSIsImZpbHRlcmVkIiwiZmlsZW5hbWUiLCJzZWxlY3RlZERhdGFzZXRzIiwiT2JqZWN0IiwidmFsdWVzIiwibGVuZ3RoIiwiZm9yRWFjaCIsInNlbGVjdGVkRGF0YSIsImFsbERhdGEiLCJkYXRhIiwiZmllbGRzIiwibGFiZWwiLCJleHRlcm5hbERhdGEiLCJFWFBPUlRfREFUQV9UWVBFIiwiQ1NWIiwidHlwZSIsImNzdiIsIl9kb3dubG9hZEZpbGUiLCJoYXNEYXRhIiwiZXhwb3J0TWFwIiwiRVhQT1JUX01BUF9GT1JNQVRTIiwiSlNPTiIsIktlcGxlckdsU2NoZW1hIiwic2F2ZSIsImdldENvbmZpZ1RvU2F2ZSIsInN0cmluZ2lmeSIsIkhUTUwiLCJ1c2VyTWFwYm94VG9rZW4iLCJleHBvcnRNYXBib3hBY2Nlc3NUb2tlbiIsIm1vZGUiLCJtYXBib3hBcGlBY2Nlc3NUb2tlbiIsImZvcm1hdCIsImRvd25sb2FkZXIiLCJfb25FeHBvcnRIVE1MTWFwIiwiX29uRXhwb3J0SlNPTk1hcCIsImZpbGVCbG9iIiwiQmxvYiIsImNvbnRhaW5lclciLCJjb250YWluZXJIIiwibWFwU3R5bGUiLCJtYXBTdGF0ZSIsInJvb3ROb2RlIiwiY3VycmVudE1vZGFsIiwiZGF0YXNldEtleVRvUmVtb3ZlIiwibGF5ZXJzIiwiZWRpdGluZ0RhdGFzZXQiLCJleHBvcnREYXRhc2V0cyIsImRhdGFzZXRLZXlzIiwia2V5cyIsIm1hcCIsImRrIiwidGVtcGxhdGUiLCJtb2RhbFByb3BzIiwiaWQiLCJEQVRBX1RBQkxFX0lEIiwid2lkdGgiLCJzaG93RGF0YXNldFRhYmxlIiwiY3NzU3R5bGUiLCJBRERfRVhURVJOQUxfREFUQV9JRCIsInRpdGxlIiwiZm9vdGVyIiwiREVMRVRFX0RBVEFfSUQiLCJvbkNvbmZpcm0iLCJfZGVsZXRlRGF0YXNldCIsIm9uQ2FuY2VsIiwiY29uZmlybUJ1dHRvbiIsIm5lZ2F0aXZlIiwibGFyZ2UiLCJjaGlsZHJlbiIsIkFERF9EQVRBX0lEIiwiX29uRmlsZVVwbG9hZCIsIkVYUE9SVF9JTUFHRV9JRCIsInNldFJhdGlvIiwic2V0UmVzb2x1dGlvbiIsInRvZ2dsZUxlZ2VuZCIsImNsb3NlIiwiX29uRXhwb3J0SW1hZ2UiLCJkaXNhYmxlZCIsIkVYUE9SVF9EQVRBX0lEIiwic2V0RXhwb3J0RGF0YVR5cGUiLCJzZXRFeHBvcnRTZWxlY3RlZERhdGFzZXQiLCJzZXRFeHBvcnRGaWx0ZXJlZCIsIl9vbkV4cG9ydERhdGEiLCJFWFBPUlRfTUFQX0lEIiwia2VwbGVyR2xDb25maWciLCJzZXRFeHBvcnRNYXBGb3JtYXQiLCJzZXRVc2VyTWFwYm94QWNjZXNzVG9rZW4iLCJzZXRFeHBvcnRIVE1MTWFwTW9kZSIsIl9vbkV4cG9ydE1hcCIsIkFERF9NQVBfU1RZTEVfSUQiLCJtYXBib3hBcGlVcmwiLCJpbnB1dFN0eWxlIiwiaW5wdXRNYXBTdHlsZSIsImxvYWRDdXN0b21NYXBTdHlsZSIsIl9vbkFkZEN1c3RvbU1hcFN0eWxlIiwic3R5bGUiLCJCb29sZWFuIiwiQ29tcG9uZW50IiwiUHJvcFR5cGVzIiwib2JqZWN0IiwibnVtYmVyIiwic3RyaW5nIiwiaXNSZXF1aXJlZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0E7O0FBR0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjQSxJQUFNQSxtQkFBbUIsT0FBR0MscUJBQUgsb0pBSXJCQyx3QkFBTUMsUUFKZSwrR0FRckJELHdCQUFNRSxJQVJlLG1JQUF6QjtBQWNBLElBQU1DLHdCQUF3QixPQUFHSixxQkFBSCwySUFBOUI7QUFLQSxJQUFNSyxrQkFBa0IsT0FBR0wscUJBQUgsMEdBQXhCO0FBSUFNLHFCQUFxQixDQUFDQyxJQUF0QixHQUE2QixDQUMzQkMsaUNBRDJCLEVBRTNCQywwQkFGMkIsRUFHM0JDLDJCQUgyQixFQUkzQkMseUJBSjJCLEVBSzNCQyw0QkFMMkIsRUFNM0JDLDJCQU4yQixFQU8zQkMsMEJBUDJCLEVBUTNCQyw0QkFSMkIsQ0FBN0I7O0FBV2UsU0FBU1QscUJBQVQsQ0FDYlUscUJBRGEsRUFFYkMsY0FGYSxFQUdiQyxrQkFIYSxFQUliQyxhQUphLEVBS2JDLGdCQUxhLEVBTWJDLGVBTmEsRUFPYkMsY0FQYSxFQVFiQyxnQkFSYSxFQVNiO0FBQUEsTUFDTUMsWUFETjtBQUFBOztBQUFBOztBQUFBO0FBQUE7O0FBQUE7O0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQUEsc0dBaUJnQixZQUFNO0FBQ2xCLGNBQUtDLEtBQUwsQ0FBV0MsY0FBWCxDQUEwQkMsV0FBMUIsQ0FBc0MsSUFBdEM7QUFDRCxPQW5CSDtBQUFBLHlHQXFCbUIsVUFBQUMsR0FBRyxFQUFJO0FBQ3RCLGNBQUtILEtBQUwsQ0FBV0ksZUFBWCxDQUEyQkMsYUFBM0IsQ0FBeUNGLEdBQXpDOztBQUNBLGNBQUtHLFdBQUw7QUFDRCxPQXhCSDtBQUFBLCtHQTBCeUIsWUFBTTtBQUMzQixjQUFLTixLQUFMLENBQVdPLGVBQVgsQ0FBMkJDLGlCQUEzQjs7QUFDQSxjQUFLRixXQUFMO0FBQ0QsT0E3Qkg7QUFBQSx3R0ErQmtCLFVBQUFHLElBQUksRUFBSTtBQUN0QixjQUFLVCxLQUFMLENBQVdJLGVBQVgsQ0FBMkJNLFNBQTNCLENBQXFDRCxJQUFyQztBQUNELE9BakNIO0FBQUEseUdBbUNtQixZQUFNO0FBQ3JCLG9DQUFrQyxNQUFLVCxLQUFMLENBQVdXLE9BQVgsQ0FBbUJDLFdBQXJEO0FBQUEsWUFBT0MsU0FBUCx5QkFBT0EsU0FBUDtBQUFBLFlBQWtCQyxZQUFsQix5QkFBa0JBLFlBQWxCOztBQUNBLFlBQUksQ0FBQ0QsU0FBRCxJQUFjQyxZQUFsQixFQUFnQztBQUM5QixjQUFNQyxJQUFJLEdBQUcscUNBQWNELFlBQWQsQ0FBYjtBQUNBLDhDQUFhQyxJQUFiLEVBQW1CQywwQ0FBbkI7QUFDRDs7QUFDRCxjQUFLaEIsS0FBTCxDQUFXQyxjQUFYLENBQTBCZ0Isa0JBQTFCOztBQUNBLGNBQUtYLFdBQUw7QUFDRCxPQTNDSDtBQUFBLHdHQWtEa0IsWUFBTTtBQUNwQiwwQkFBNEIsTUFBS04sS0FBakM7QUFBQSxZQUFPa0IsUUFBUCxlQUFPQSxRQUFQO0FBQUEsWUFBaUJQLE9BQWpCLGVBQWlCQSxPQUFqQjtBQUNBLFlBQU9RLFFBQVAsR0FBbUJELFFBQW5CLENBQU9DLFFBQVA7QUFDQSxrQ0FBOENSLE9BQU8sQ0FBQ1MsVUFBdEQ7QUFBQSxZQUFPQyxlQUFQLHVCQUFPQSxlQUFQO0FBQUEsWUFBd0JDLFFBQXhCLHVCQUF3QkEsUUFBeEI7QUFBQSxZQUFrQ0MsUUFBbEMsdUJBQWtDQSxRQUFsQyxDQUhvQixDQUlwQjs7QUFDQSxZQUFNQyxRQUFRLEdBQUcsVUFBakI7QUFDQSxZQUFNQyxnQkFBZ0IsR0FBR04sUUFBUSxDQUFDRSxlQUFELENBQVIsR0FDckIsQ0FBQ0YsUUFBUSxDQUFDRSxlQUFELENBQVQsQ0FEcUIsR0FFckJLLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjUixRQUFkLENBRko7O0FBR0EsWUFBSSxDQUFDTSxnQkFBZ0IsQ0FBQ0csTUFBdEIsRUFBOEI7QUFDNUI7QUFDQSxnQkFBS3RCLFdBQUw7QUFDRDs7QUFFRG1CLFFBQUFBLGdCQUFnQixDQUFDSSxPQUFqQixDQUF5QixVQUFBQyxZQUFZLEVBQUk7QUFDdkMsY0FBT0MsT0FBUCxHQUFxREQsWUFBckQsQ0FBT0MsT0FBUDtBQUFBLGNBQWdCQyxJQUFoQixHQUFxREYsWUFBckQsQ0FBZ0JFLElBQWhCO0FBQUEsY0FBc0JDLE1BQXRCLEdBQXFESCxZQUFyRCxDQUFzQkcsTUFBdEI7QUFBQSxjQUE4QkMsS0FBOUIsR0FBcURKLFlBQXJELENBQThCSSxLQUE5QjtBQUFBLGNBQXFDQyxZQUFyQyxHQUFxREwsWUFBckQsQ0FBcUNLLFlBQXJDO0FBQ0EsY0FBTWYsVUFBVSxHQUFHRyxRQUFRLEdBQUdTLElBQUgsR0FBVUQsT0FBckM7O0FBQ0EsY0FBSUksWUFBWSxJQUFJQSxZQUFZLEtBQUssSUFBckMsRUFBMkM7QUFDekMsbUJBQU8sSUFBUDtBQUNELFdBTHNDLENBTXZDOzs7QUFDQSxrQkFBUWIsUUFBUjtBQUNFLGlCQUFLYyxrQ0FBaUJDLEdBQXRCO0FBQTJCO0FBQ3pCLG9CQUFNQyxJQUFJLEdBQUcsVUFBYjtBQUNBLG9CQUFNQyxHQUFHLEdBQUcsOEJBQVVuQixVQUFWLEVBQXNCYSxNQUF0QixDQUFaOztBQUNBLHNCQUFLTyxhQUFMLENBQW1CRCxHQUFuQixFQUF3QkQsSUFBeEIsWUFBaUNkLFFBQWpDLGNBQTZDVSxLQUE3Qzs7QUFDQTtBQUNEO0FBQ0Q7O0FBQ0E7QUFDRTtBQVRKO0FBV0QsU0FsQkQ7O0FBb0JBLGNBQUs1QixXQUFMO0FBQ0QsT0FyRkg7QUFBQSwyR0F1RnFCLFlBQU07QUFDdkIsWUFBT0ssT0FBUCxHQUFrQixNQUFLWCxLQUF2QixDQUFPVyxPQUFQO0FBQ0EsWUFBTzhCLE9BQVAsR0FBa0I5QixPQUFPLENBQUMrQixTQUFSLENBQWtCQyxvQ0FBbUJDLElBQXJDLENBQWxCLENBQU9ILE9BQVAsQ0FGdUIsQ0FJdkI7O0FBQ0EsWUFBTVQsSUFBSSxHQUFHUyxPQUFPLEdBQ2hCSSxvQkFBZUMsSUFBZixDQUFvQixNQUFLOUMsS0FBekIsQ0FEZ0IsR0FFaEI2QyxvQkFBZUUsZUFBZixDQUErQixNQUFLL0MsS0FBcEMsQ0FGSjs7QUFJQSxjQUFLd0MsYUFBTCxDQUNFSSxJQUFJLENBQUNJLFNBQUwsQ0FBZWhCLElBQWYsRUFBcUIsSUFBckIsRUFBMkIsQ0FBM0IsQ0FERixFQUVFLGtCQUZGLEVBR0UsZUFIRjs7QUFNQSxjQUFLMUIsV0FBTDtBQUNELE9BdkdIO0FBQUEsMkdBeUdxQixZQUFNO0FBQ3ZCLFlBQU9LLE9BQVAsR0FBa0IsTUFBS1gsS0FBdkIsQ0FBT1csT0FBUDtBQUNBLG9DQUlJQSxPQUFPLENBQUMrQixTQUFSLENBQWtCQyxvQ0FBbUJNLElBQXJDLENBSko7QUFBQSxZQUNFQyxlQURGLHlCQUNFQSxlQURGO0FBQUEsWUFFRUMsdUJBRkYseUJBRUVBLHVCQUZGO0FBQUEsWUFHRUMsSUFIRix5QkFHRUEsSUFIRjs7QUFNQSxZQUFNcEIsSUFBSSxtQ0FDTGEsb0JBQWVDLElBQWYsQ0FBb0IsTUFBSzlDLEtBQXpCLENBREs7QUFFUnFELFVBQUFBLG9CQUFvQixFQUNsQixDQUFDSCxlQUFlLElBQUksRUFBcEIsTUFBNEIsRUFBNUIsR0FDSUEsZUFESixHQUVJQyx1QkFMRTtBQU1SQyxVQUFBQSxJQUFJLEVBQUpBO0FBTlEsVUFBVjs7QUFTQSxjQUFLWixhQUFMLENBQW1CLG9DQUFnQlIsSUFBaEIsQ0FBbkIsRUFBMEMsV0FBMUMsRUFBdUQsZ0JBQXZEOztBQUVBLGNBQUsxQixXQUFMO0FBQ0QsT0E3SEg7QUFBQSx1R0ErSGlCLFlBQU07QUFBQTs7QUFDbkIsWUFBT0ssT0FBUCxHQUFrQixNQUFLWCxLQUF2QixDQUFPVyxPQUFQO0FBQ0EsWUFBTzJDLE1BQVAsR0FBaUIzQyxPQUFPLENBQUMrQixTQUF6QixDQUFPWSxNQUFQO0FBRUEsWUFBTUMsVUFBVSxHQUFHLHFGQUNoQlosb0NBQW1CTSxJQURILEVBQ1UsTUFBS08sZ0JBRGYsMkRBRWhCYixvQ0FBbUJDLElBRkgsRUFFVSxNQUFLYSxnQkFGZiwwQkFHakJILE1BSGlCLENBQW5CO0FBS0FDLFFBQUFBLFVBQVUsSUFBSUEsVUFBVSxFQUF4QjtBQUNELE9BeklIO0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUEsYUE2Q0UsdUJBQWN2QixJQUFkLEVBQW9CTSxJQUFwQixFQUEwQmQsUUFBMUIsRUFBb0M7QUFDbEMsWUFBTWtDLFFBQVEsR0FBRyxJQUFJQyxZQUFKLENBQVMsQ0FBQzNCLElBQUQsQ0FBVCxFQUFpQjtBQUFDTSxVQUFBQSxJQUFJLEVBQUpBO0FBQUQsU0FBakIsQ0FBakI7QUFDQSw0Q0FBYW9CLFFBQWIsRUFBdUJsQyxRQUF2QjtBQUNEO0FBaERIO0FBQUE7QUFBQTtBQTJJRTtBQUNBLHdCQUFTO0FBQUE7O0FBQ1AsMkJBU0ksS0FBS3hCLEtBVFQ7QUFBQSxZQUNFNEQsVUFERixnQkFDRUEsVUFERjtBQUFBLFlBRUVDLFVBRkYsZ0JBRUVBLFVBRkY7QUFBQSxZQUdFQyxRQUhGLGdCQUdFQSxRQUhGO0FBQUEsWUFJRUMsUUFKRixnQkFJRUEsUUFKRjtBQUFBLFlBS0VwRCxPQUxGLGdCQUtFQSxPQUxGO0FBQUEsWUFNRU8sUUFORixnQkFNRUEsUUFORjtBQUFBLFlBT0U4QyxRQVBGLGdCQU9FQSxRQVBGO0FBQUEsWUFRRTVELGVBUkYsZ0JBUUVBLGVBUkY7QUFVQSxZQUFPNkQsWUFBUCxHQUEyQ3RELE9BQTNDLENBQU9zRCxZQUFQO0FBQUEsWUFBcUJDLGtCQUFyQixHQUEyQ3ZELE9BQTNDLENBQXFCdUQsa0JBQXJCO0FBQ0EsWUFBTy9DLFFBQVAsR0FBMkNELFFBQTNDLENBQU9DLFFBQVA7QUFBQSxZQUFpQmdELE1BQWpCLEdBQTJDakQsUUFBM0MsQ0FBaUJpRCxNQUFqQjtBQUFBLFlBQXlCQyxjQUF6QixHQUEyQ2xELFFBQTNDLENBQXlCa0QsY0FBekI7QUFDQSxZQUFJQyxjQUFjLEdBQUcsRUFBckI7QUFDQSxZQUFNQyxXQUFXLEdBQUc1QyxNQUFNLENBQUM2QyxJQUFQLENBQVlwRCxRQUFaLENBQXBCO0FBQ0FtRCxRQUFBQSxXQUFXLENBQUNFLEdBQVosQ0FBZ0IsVUFBQUMsRUFBRSxFQUFJO0FBQ3BCLGNBQU10QyxZQUFZLEdBQUdoQixRQUFRLENBQUNzRCxFQUFELENBQVIsQ0FBYXRDLFlBQWxDO0FBQ0FBLFVBQUFBLFlBQVksSUFBSUEsWUFBWSxLQUFLLElBQWpDLEdBQ0ksSUFESixHQUVLa0MsY0FBYyxtQ0FBT0EsY0FBUCw0Q0FBd0JJLEVBQXhCLEVBQTZCdEQsUUFBUSxDQUFDc0QsRUFBRCxDQUFyQyxFQUZuQjtBQUdELFNBTEQ7QUFNQSxZQUFJQyxRQUFRLEdBQUcsSUFBZjtBQUNBLFlBQUlDLFVBQVUsR0FBRyxFQUFqQjs7QUFFQSxZQUFJVixZQUFZLElBQUlBLFlBQVksQ0FBQ1csRUFBN0IsSUFBbUNYLFlBQVksQ0FBQ1MsUUFBcEQsRUFBOEQ7QUFDNUQ7QUFDQTtBQUNBQSxVQUFBQSxRQUFRLGdCQUFHLGdDQUFDLFlBQUQsQ0FBYyxRQUFkLE9BQVg7QUFDQUMsVUFBQUEsVUFBVSxHQUFHVixZQUFZLENBQUNVLFVBQTFCO0FBQ0QsU0FMRCxNQUtPO0FBQ0wsa0JBQVFWLFlBQVI7QUFDRSxpQkFBS1ksOEJBQUw7QUFDRSxrQkFBTUMsS0FBSyxHQUFHbEIsVUFBVSxHQUFHLEdBQTNCO0FBQ0FjLGNBQUFBLFFBQVEsZ0JBQ04sZ0NBQUMsY0FBRDtBQUNFLGdCQUFBLEtBQUssRUFBRWQsVUFBVSxHQUFHLEdBRHRCO0FBRUUsZ0JBQUEsTUFBTSxFQUFFQyxVQUFVLEdBQUcsSUFGdkI7QUFHRSxnQkFBQSxRQUFRLEVBQUUxQyxRQUhaO0FBSUUsZ0JBQUEsTUFBTSxFQUFFaUQsY0FKVjtBQUtFLGdCQUFBLGdCQUFnQixFQUFFaEUsZUFBZSxDQUFDMkU7QUFMcEMsZ0JBREYsQ0FGRixDQVlFOztBQUNBSixjQUFBQSxVQUFVLENBQUNLLFFBQVgsT0FBc0J6RyxxQkFBdEIsaUpBQ0lELG1CQURKLEVBRUlFLHdCQUFNRSxJQUZWLHlJQUdhb0csS0FIYjtBQU1BOztBQUNGLGlCQUFLRyxxQ0FBTDtBQUNFUCxjQUFBQSxRQUFRLGdCQUFHLGdDQUFDLHFCQUFELE9BQVg7QUFDQUMsY0FBQUEsVUFBVSxHQUFHO0FBQ1hPLGdCQUFBQSxLQUFLLEVBQUUsMEJBREk7QUFFWEMsZ0JBQUFBLE1BQU0sRUFBRSxLQUZHLENBR1g7QUFDQTtBQUNBO0FBQ0E7O0FBTlcsZUFBYjtBQVFBOztBQUNGLGlCQUFLQywrQkFBTDtBQUNFO0FBQ0Esa0JBQ0VsQixrQkFBa0IsSUFDbEIvQyxRQURBLElBRUFBLFFBQVEsQ0FBQytDLGtCQUFELENBSFYsRUFJRTtBQUNBUSxnQkFBQUEsUUFBUSxnQkFDTixnQ0FBQyxrQkFBRDtBQUNFLGtCQUFBLE9BQU8sRUFBRXZELFFBQVEsQ0FBQytDLGtCQUFELENBRG5CO0FBRUUsa0JBQUEsTUFBTSxFQUFFQztBQUZWLGtCQURGO0FBT0FRLGdCQUFBQSxVQUFVLEdBQUc7QUFDWE8sa0JBQUFBLEtBQUssRUFBRSxnQkFESTtBQUVYRixrQkFBQUEsUUFBUSxFQUFFckcsd0JBRkM7QUFHWHdHLGtCQUFBQSxNQUFNLEVBQUUsSUFIRztBQUlYRSxrQkFBQUEsU0FBUyxFQUFFO0FBQUEsMkJBQU0sTUFBSSxDQUFDQyxjQUFMLENBQW9CcEIsa0JBQXBCLENBQU47QUFBQSxtQkFKQTtBQUtYcUIsa0JBQUFBLFFBQVEsRUFBRSxLQUFLakYsV0FMSjtBQU1Ya0Ysa0JBQUFBLGFBQWEsRUFBRTtBQUNiQyxvQkFBQUEsUUFBUSxFQUFFLElBREc7QUFFYkMsb0JBQUFBLEtBQUssRUFBRSxJQUZNO0FBR2JDLG9CQUFBQSxRQUFRLEVBQUU7QUFIRztBQU5KLGlCQUFiO0FBWUQ7O0FBQ0Q7QUFBTzs7QUFDVCxpQkFBS0MsNEJBQUw7QUFDRWxCLGNBQUFBLFFBQVEsZ0JBQ04sZ0NBQUMsYUFBRDtBQUNFLGdCQUFBLE9BQU8sRUFBRSxLQUFLcEUsV0FEaEI7QUFFRSxnQkFBQSxZQUFZLEVBQUUsS0FBS3VGO0FBRnJCLGlCQUdNbEYsT0FBTyxDQUFDRCxTQUhkLEVBREY7QUFPQWlFLGNBQUFBLFVBQVUsR0FBRztBQUNYTyxnQkFBQUEsS0FBSyxFQUFFLHVCQURJO0FBRVhGLGdCQUFBQSxRQUFRLEVBQUVwRyxrQkFGQztBQUdYdUcsZ0JBQUFBLE1BQU0sRUFBRSxLQUhHO0FBSVhFLGdCQUFBQSxTQUFTLEVBQUUsS0FBSy9FO0FBSkwsZUFBYjtBQU1BOztBQUNGLGlCQUFLd0YsZ0NBQUw7QUFDRXBCLGNBQUFBLFFBQVEsZ0JBQ04sZ0NBQUMsZ0JBQUQsZ0NBQ00vRCxPQUFPLENBQUNDLFdBRGQ7QUFFRSxnQkFBQSxLQUFLLEVBQUVnRCxVQUZUO0FBR0UsZ0JBQUEsTUFBTSxFQUFFQyxVQUhWO0FBSUUsZ0JBQUEsYUFBYSxFQUFFLEtBQUs3RCxLQUFMLENBQVdDLGNBQVgsQ0FBMEI4RixRQUozQztBQUtFLGdCQUFBLGtCQUFrQixFQUFFLEtBQUsvRixLQUFMLENBQVdDLGNBQVgsQ0FBMEIrRixhQUxoRDtBQU1FLGdCQUFBLGNBQWMsRUFBRSxLQUFLaEcsS0FBTCxDQUFXQyxjQUFYLENBQTBCZ0c7QUFONUMsaUJBREY7QUFVQXRCLGNBQUFBLFVBQVUsR0FBRztBQUNYdUIsZ0JBQUFBLEtBQUssRUFBRSxLQURJO0FBRVhoQixnQkFBQUEsS0FBSyxFQUFFLGNBRkk7QUFHWEMsZ0JBQUFBLE1BQU0sRUFBRSxJQUhHO0FBSVhJLGdCQUFBQSxRQUFRLEVBQUUsS0FBS2pGLFdBSko7QUFLWCtFLGdCQUFBQSxTQUFTLEVBQUUsS0FBS2MsY0FMTDtBQU1YWCxnQkFBQUEsYUFBYSxFQUFFO0FBQ2JFLGtCQUFBQSxLQUFLLEVBQUUsSUFETTtBQUViVSxrQkFBQUEsUUFBUSxFQUFFekYsT0FBTyxDQUFDQyxXQUFSLENBQW9CQyxTQUZqQjtBQUdiOEUsa0JBQUFBLFFBQVEsRUFBRTtBQUhHO0FBTkosZUFBYjtBQVlBOztBQUNGLGlCQUFLVSwrQkFBTDtBQUNFM0IsY0FBQUEsUUFBUSxnQkFDTixnQ0FBQyxlQUFELGdDQUNNL0QsT0FBTyxDQUFDUyxVQURkO0FBRUUsZ0JBQUEsUUFBUSxFQUFFaUQsY0FGWjtBQUdFLGdCQUFBLE9BQU8sRUFBRSxLQUFLL0QsV0FIaEI7QUFJRSxnQkFBQSxzQkFBc0IsRUFDcEIsS0FBS04sS0FBTCxDQUFXQyxjQUFYLENBQTBCcUcsaUJBTDlCO0FBT0UsZ0JBQUEsNkJBQTZCLEVBQzNCLEtBQUt0RyxLQUFMLENBQVdDLGNBQVgsQ0FBMEJzRyx3QkFSOUI7QUFVRSxnQkFBQSxzQkFBc0IsRUFDcEIsS0FBS3ZHLEtBQUwsQ0FBV0MsY0FBWCxDQUEwQnVHO0FBWDlCLGlCQURGO0FBZ0JBN0IsY0FBQUEsVUFBVSxHQUFHO0FBQ1h1QixnQkFBQUEsS0FBSyxFQUFFLEtBREk7QUFFWGhCLGdCQUFBQSxLQUFLLEVBQUUsYUFGSTtBQUdYQyxnQkFBQUEsTUFBTSxFQUFFLElBSEc7QUFJWEksZ0JBQUFBLFFBQVEsRUFBRSxLQUFLakYsV0FKSjtBQUtYK0UsZ0JBQUFBLFNBQVMsRUFBRSxLQUFLb0IsYUFMTDtBQU1YakIsZ0JBQUFBLGFBQWEsRUFBRTtBQUNiRSxrQkFBQUEsS0FBSyxFQUFFLElBRE07QUFFYkMsa0JBQUFBLFFBQVEsRUFBRTtBQUZHO0FBTkosZUFBYjtBQVdBOztBQUNGLGlCQUFLZSw4QkFBTDtBQUNFLGtCQUFNQyxjQUFjLEdBQUc5RCxvQkFBZUUsZUFBZixDQUErQjtBQUNwRGUsZ0JBQUFBLFFBQVEsRUFBUkEsUUFEb0Q7QUFFcEQ1QyxnQkFBQUEsUUFBUSxFQUFSQSxRQUZvRDtBQUdwRDZDLGdCQUFBQSxRQUFRLEVBQVJBLFFBSG9EO0FBSXBEcEQsZ0JBQUFBLE9BQU8sRUFBUEE7QUFKb0QsZUFBL0IsQ0FBdkI7O0FBTUErRCxjQUFBQSxRQUFRLGdCQUNOLGdDQUFDLGNBQUQ7QUFDRSxnQkFBQSxNQUFNLEVBQUVpQyxjQURWO0FBRUUsZ0JBQUEsT0FBTyxFQUFFaEcsT0FBTyxDQUFDK0IsU0FGbkI7QUFHRSxnQkFBQSx1QkFBdUIsRUFDckIsS0FBSzFDLEtBQUwsQ0FBV0MsY0FBWCxDQUEwQjJHLGtCQUo5QjtBQU1FLGdCQUFBLDJCQUEyQixFQUN6QixLQUFLNUcsS0FBTCxDQUFXQyxjQUFYLENBQTBCNEcsd0JBUDlCO0FBU0UsZ0JBQUEseUJBQXlCLEVBQ3ZCLEtBQUs3RyxLQUFMLENBQVdDLGNBQVgsQ0FBMEI2RztBQVY5QixnQkFERjtBQWVBbkMsY0FBQUEsVUFBVSxHQUFHO0FBQ1h1QixnQkFBQUEsS0FBSyxFQUFFLEtBREk7QUFFWGhCLGdCQUFBQSxLQUFLLEVBQUUsWUFGSTtBQUdYQyxnQkFBQUEsTUFBTSxFQUFFLElBSEc7QUFJWEksZ0JBQUFBLFFBQVEsRUFBRSxLQUFLakYsV0FKSjtBQUtYK0UsZ0JBQUFBLFNBQVMsRUFBRSxLQUFLMEIsWUFMTDtBQU1YdkIsZ0JBQUFBLGFBQWEsRUFBRTtBQUNiRSxrQkFBQUEsS0FBSyxFQUFFLElBRE07QUFFYkMsa0JBQUFBLFFBQVEsRUFBRTtBQUZHO0FBTkosZUFBYjtBQVdBOztBQUNGLGlCQUFLcUIsaUNBQUw7QUFDRXRDLGNBQUFBLFFBQVEsZ0JBQ04sZ0NBQUMsZ0JBQUQ7QUFDRSxnQkFBQSxvQkFBb0IsRUFBRSxLQUFLMUUsS0FBTCxDQUFXcUQsb0JBRG5DO0FBRUUsZ0JBQUEsWUFBWSxFQUFFLEtBQUtyRCxLQUFMLENBQVdpSCxZQUYzQjtBQUdFLGdCQUFBLFFBQVEsRUFBRSxLQUFLakgsS0FBTCxDQUFXK0QsUUFIdkI7QUFJRSxnQkFBQSxVQUFVLEVBQUVELFFBQVEsQ0FBQ29ELFVBSnZCO0FBS0UsZ0JBQUEsYUFBYSxFQUFFLEtBQUtsSCxLQUFMLENBQVdPLGVBQVgsQ0FBMkI0RyxhQUw1QztBQU1FLGdCQUFBLGtCQUFrQixFQUNoQixLQUFLbkgsS0FBTCxDQUFXTyxlQUFYLENBQTJCNkc7QUFQL0IsZ0JBREY7QUFZQXpDLGNBQUFBLFVBQVUsR0FBRztBQUNYdUIsZ0JBQUFBLEtBQUssRUFBRSxLQURJO0FBRVhoQixnQkFBQUEsS0FBSyxFQUFFLHlCQUZJO0FBR1hDLGdCQUFBQSxNQUFNLEVBQUUsSUFIRztBQUlYSSxnQkFBQUEsUUFBUSxFQUFFLEtBQUtqRixXQUpKO0FBS1grRSxnQkFBQUEsU0FBUyxFQUFFLEtBQUtnQyxvQkFMTDtBQU1YN0IsZ0JBQUFBLGFBQWEsRUFBRTtBQUNiRSxrQkFBQUEsS0FBSyxFQUFFLElBRE07QUFFYlUsa0JBQUFBLFFBQVEsRUFBRSxDQUFDdEMsUUFBUSxDQUFDb0QsVUFBVCxDQUFvQkksS0FGbEI7QUFHYjNCLGtCQUFBQSxRQUFRLEVBQUU7QUFIRztBQU5KLGVBQWI7QUFZQTs7QUFDRjtBQUNFO0FBN0xKO0FBK0xEOztBQUVELGVBQU8sS0FBSzNGLEtBQUwsQ0FBV2dFLFFBQVgsZ0JBQ0wsZ0NBQUMsaUJBQUQsZ0NBQ01XLFVBRE47QUFFRSxVQUFBLGNBQWMsRUFBRTtBQUFBLG1CQUFNLDJCQUFZWCxRQUFaLENBQU47QUFBQSxXQUZsQjtBQUdFLFVBQUEsTUFBTSxFQUFFdUQsT0FBTyxDQUFDdEQsWUFBRCxDQUhqQjtBQUlFLFVBQUEsS0FBSyxFQUFFLEtBQUszRDtBQUpkLFlBTUdvRSxRQU5ILENBREssR0FTSCxJQVRKO0FBVUQ7QUFDRDs7QUF0WEY7QUFBQTtBQUFBLElBQzJCOEMsZ0JBRDNCOztBQUFBLG1DQUNNekgsWUFETixlQUVxQjtBQUNqQmlFLElBQUFBLFFBQVEsRUFBRXlELHNCQUFVQyxNQURIO0FBRWpCOUQsSUFBQUEsVUFBVSxFQUFFNkQsc0JBQVVFLE1BRkw7QUFHakI5RCxJQUFBQSxVQUFVLEVBQUU0RCxzQkFBVUUsTUFITDtBQUlqQnRFLElBQUFBLG9CQUFvQixFQUFFb0Usc0JBQVVHLE1BQVYsQ0FBaUJDLFVBSnRCO0FBS2pCWixJQUFBQSxZQUFZLEVBQUVRLHNCQUFVRyxNQUxQO0FBTWpCN0QsSUFBQUEsUUFBUSxFQUFFMEQsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBTlY7QUFPakIvRCxJQUFBQSxRQUFRLEVBQUUyRCxzQkFBVUMsTUFBVixDQUFpQkcsVUFQVjtBQVFqQmxILElBQUFBLE9BQU8sRUFBRThHLHNCQUFVQyxNQUFWLENBQWlCRyxVQVJUO0FBU2pCM0csSUFBQUEsUUFBUSxFQUFFdUcsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBVFY7QUFVakJ6SCxJQUFBQSxlQUFlLEVBQUVxSCxzQkFBVUMsTUFBVixDQUFpQkcsVUFWakI7QUFXakI1SCxJQUFBQSxjQUFjLEVBQUV3SCxzQkFBVUMsTUFBVixDQUFpQkcsVUFYaEI7QUFZakJ0SCxJQUFBQSxlQUFlLEVBQUVrSCxzQkFBVUMsTUFBVixDQUFpQkc7QUFaakIsR0FGckI7QUF5WEEsU0FBTzlILFlBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBSZWFjdCwge0NvbXBvbmVudH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCB7Y3NzfSBmcm9tICdzdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQge2ZpbmRET01Ob2RlfSBmcm9tICdyZWFjdC1kb20nO1xuaW1wb3J0IHtCbG9ifSBmcm9tICdnbG9iYWwvd2luZG93JztcblxuaW1wb3J0IE1vZGFsRGlhbG9nIGZyb20gJy4vY29tbW9uL21vZGFsJztcbmltcG9ydCB7Zm9ybWF0Q3N2fSBmcm9tICdwcm9jZXNzb3JzL2RhdGEtcHJvY2Vzc29yJztcbmltcG9ydCBLZXBsZXJHbFNjaGVtYSBmcm9tICdzY2hlbWFzJztcbmltcG9ydCB7ZG93bmxvYWRGaWxlLCBkYXRhVVJJdG9CbG9ifSBmcm9tICd1dGlscy9leHBvcnQtaW1hZ2UtdXRpbHMnO1xuLy8gbW9kYWxzXG5pbXBvcnQgRGVsZXRlRGF0YXNldE1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9kZWxldGUtZGF0YS1tb2RhbCc7XG5pbXBvcnQgRGF0YVRhYmxlTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2RhdGEtdGFibGUtbW9kYWwnO1xuaW1wb3J0IExvYWREYXRhTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2xvYWQtZGF0YS1tb2RhbCc7XG5pbXBvcnQgTG9hZEV4dGVybmFsRGF0YU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9sb2FkLWV4dGVybmFsLWRhdGEtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydEltYWdlTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2V4cG9ydC1pbWFnZS1tb2RhbCc7XG5pbXBvcnQgRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtZGF0YS1tb2RhbCc7XG5pbXBvcnQgRXhwb3J0TWFwTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2V4cG9ydC1tYXAtbW9kYWwnO1xuaW1wb3J0IEFkZE1hcFN0eWxlTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2FkZC1tYXAtc3R5bGUtbW9kYWwnO1xuXG4vLyBCcmVha3BvaW50c1xuaW1wb3J0IHttZWRpYX0gZnJvbSAnc3R5bGVzL21lZGlhLWJyZWFrcG9pbnRzJztcblxuLy8gVGVtcGxhdGVcbmltcG9ydCB7ZXhwb3J0TWFwVG9IVE1MfSBmcm9tICd0ZW1wbGF0ZXMvZXhwb3J0LW1hcC1odG1sJztcbmltcG9ydCB7XG4gIEFERF9EQVRBX0lELFxuICBEQVRBX1RBQkxFX0lELFxuICBERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FLFxuICBERUxFVEVfREFUQV9JRCxcbiAgRVhQT1JUX0RBVEFfSUQsXG4gIEVYUE9SVF9EQVRBX1RZUEUsXG4gIEVYUE9SVF9JTUFHRV9JRCxcbiAgRVhQT1JUX01BUF9JRCxcbiAgQUREX01BUF9TVFlMRV9JRCxcbiAgQUREX0VYVEVSTkFMX0RBVEFfSURcbn0gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuaW1wb3J0IHtFWFBPUlRfTUFQX0ZPUk1BVFN9IGZyb20gJy4uL2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcblxuY29uc3QgRGF0YVRhYmxlTW9kYWxTdHlsZSA9IGNzc2BcbiAgdG9wOiA4MHB4O1xuICBwYWRkaW5nOiAzMnB4IDAgMCAwO1xuXG4gICR7bWVkaWEucG9ydGFibGVgXG4gICAgcGFkZGluZzogMDtcbiAgYH1cblxuICAke21lZGlhLnBhbG1gXG4gICAgcGFkZGluZzogMDtcbiAgICBtYXJnaW46IDAgYXV0bztcbiAgYH1cbmA7XG5cbmNvbnN0IERlbGV0ZURhdGFzZXRNb2RhbFN0eWxlZCA9IGNzc2BcbiAgd2lkdGg6IDQwJTtcbiAgcGFkZGluZzogNDBweCA0MHB4IDMycHggNDBweDtcbmA7XG5cbmNvbnN0IExvYWREYXRhTW9kYWxTdHlsZSA9IGNzc2BcbiAgdG9wOiAxMTBweDtcbmA7XG5cbk1vZGFsQ29udGFpbmVyRmFjdG9yeS5kZXBzID0gW1xuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWxGYWN0b3J5LFxuICBEYXRhVGFibGVNb2RhbEZhY3RvcnksXG4gIERlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnksXG4gIExvYWREYXRhTW9kYWxGYWN0b3J5LFxuICBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0TWFwTW9kYWxGYWN0b3J5LFxuICBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeVxuXTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kYWxDb250YWluZXJGYWN0b3J5KFxuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWwsXG4gIERhdGFUYWJsZU1vZGFsLFxuICBEZWxldGVEYXRhc2V0TW9kYWwsXG4gIExvYWREYXRhTW9kYWwsXG4gIEV4cG9ydEltYWdlTW9kYWwsXG4gIEV4cG9ydERhdGFNb2RhbCxcbiAgRXhwb3J0TWFwTW9kYWwsXG4gIEFkZE1hcFN0eWxlTW9kYWxcbikge1xuICBjbGFzcyBNb2RhbFdyYXBwZXIgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgICByb290Tm9kZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgIGNvbnRhaW5lclc6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgICBjb250YWluZXJIOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgICAgbWFwYm94QXBpQWNjZXNzVG9rZW46IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgIG1hcGJveEFwaVVybDogUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgIG1hcFN0YXRlOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBtYXBTdHlsZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdmlzU3RhdGU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIHZpc1N0YXRlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZUFjdGlvbnM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIG1hcFN0eWxlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG4gICAgfTtcblxuICAgIF9jbG9zZU1vZGFsID0gKCkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy50b2dnbGVNb2RhbChudWxsKTtcbiAgICB9O1xuXG4gICAgX2RlbGV0ZURhdGFzZXQgPSBrZXkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy52aXNTdGF0ZUFjdGlvbnMucmVtb3ZlRGF0YXNldChrZXkpO1xuICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgIH07XG5cbiAgICBfb25BZGRDdXN0b21NYXBTdHlsZSA9ICgpID0+IHtcbiAgICAgIHRoaXMucHJvcHMubWFwU3R5bGVBY3Rpb25zLmFkZEN1c3RvbU1hcFN0eWxlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkZpbGVVcGxvYWQgPSBibG9iID0+IHtcbiAgICAgIHRoaXMucHJvcHMudmlzU3RhdGVBY3Rpb25zLmxvYWRGaWxlcyhibG9iKTtcbiAgICB9O1xuXG4gICAgX29uRXhwb3J0SW1hZ2UgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7ZXhwb3J0aW5nLCBpbWFnZURhdGFVcml9ID0gdGhpcy5wcm9wcy51aVN0YXRlLmV4cG9ydEltYWdlO1xuICAgICAgaWYgKCFleHBvcnRpbmcgJiYgaW1hZ2VEYXRhVXJpKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBkYXRhVVJJdG9CbG9iKGltYWdlRGF0YVVyaSk7XG4gICAgICAgIGRvd25sb2FkRmlsZShmaWxlLCBERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucHJvcHMudWlTdGF0ZUFjdGlvbnMuY2xlYW51cEV4cG9ydEltYWdlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9kb3dubG9hZEZpbGUoZGF0YSwgdHlwZSwgZmlsZW5hbWUpIHtcbiAgICAgIGNvbnN0IGZpbGVCbG9iID0gbmV3IEJsb2IoW2RhdGFdLCB7dHlwZX0pO1xuICAgICAgZG93bmxvYWRGaWxlKGZpbGVCbG9iLCBmaWxlbmFtZSk7XG4gICAgfVxuXG4gICAgX29uRXhwb3J0RGF0YSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHt2aXNTdGF0ZSwgdWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2RhdGFzZXRzfSA9IHZpc1N0YXRlO1xuICAgICAgY29uc3Qge3NlbGVjdGVkRGF0YXNldCwgZGF0YVR5cGUsIGZpbHRlcmVkfSA9IHVpU3RhdGUuZXhwb3J0RGF0YTtcbiAgICAgIC8vIGdldCB0aGUgc2VsZWN0ZWQgZGF0YVxuICAgICAgY29uc3QgZmlsZW5hbWUgPSAnZ2VvaXEuaW8nO1xuICAgICAgY29uc3Qgc2VsZWN0ZWREYXRhc2V0cyA9IGRhdGFzZXRzW3NlbGVjdGVkRGF0YXNldF1cbiAgICAgICAgPyBbZGF0YXNldHNbc2VsZWN0ZWREYXRhc2V0XV1cbiAgICAgICAgOiBPYmplY3QudmFsdWVzKGRhdGFzZXRzKTtcbiAgICAgIGlmICghc2VsZWN0ZWREYXRhc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgLy8gZXJyb3I6IHNlbGVjdGVkIGRhdGFzZXQgbm90IGZvdW5kLlxuICAgICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgICB9XG5cbiAgICAgIHNlbGVjdGVkRGF0YXNldHMuZm9yRWFjaChzZWxlY3RlZERhdGEgPT4ge1xuICAgICAgICBjb25zdCB7YWxsRGF0YSwgZGF0YSwgZmllbGRzLCBsYWJlbCwgZXh0ZXJuYWxEYXRhfSA9IHNlbGVjdGVkRGF0YTtcbiAgICAgICAgY29uc3QgZXhwb3J0RGF0YSA9IGZpbHRlcmVkID8gZGF0YSA6IGFsbERhdGE7XG4gICAgICAgIGlmIChleHRlcm5hbERhdGEgJiYgZXh0ZXJuYWxEYXRhID09PSB0cnVlKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3RhcnQgdG8gZXhwb3J0IGRhdGEgYWNjb3JkaW5nIHRvIHNlbGVjdGVkIGRhdGEgdHlwZVxuICAgICAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICAgICAgY2FzZSBFWFBPUlRfREFUQV9UWVBFLkNTVjoge1xuICAgICAgICAgICAgY29uc3QgdHlwZSA9ICd0ZXh0L2Nzdic7XG4gICAgICAgICAgICBjb25zdCBjc3YgPSBmb3JtYXRDc3YoZXhwb3J0RGF0YSwgZmllbGRzKTtcbiAgICAgICAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShjc3YsIHR5cGUsIGAke2ZpbGVuYW1lfV8ke2xhYmVsfS5jc3ZgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBUT0RPOiBzdXBwb3J0IG1vcmUgZmlsZSB0eXBlcy5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkV4cG9ydEpTT05NYXAgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7dWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2hhc0RhdGF9ID0gdWlTdGF0ZS5leHBvcnRNYXBbRVhQT1JUX01BUF9GT1JNQVRTLkpTT05dO1xuXG4gICAgICAvLyB3ZSBwYXNzIGFsbCBwcm9wcyBiZWNhdXNlIHdlIGF2b2lkIHRvIGNyZWF0ZSBuZXcgdmFyaWFibGVzXG4gICAgICBjb25zdCBkYXRhID0gaGFzRGF0YVxuICAgICAgICA/IEtlcGxlckdsU2NoZW1hLnNhdmUodGhpcy5wcm9wcylcbiAgICAgICAgOiBLZXBsZXJHbFNjaGVtYS5nZXRDb25maWdUb1NhdmUodGhpcy5wcm9wcyk7XG5cbiAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMiksXG4gICAgICAgICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ2tlcGxlcmdsLmpzb24nXG4gICAgICApO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkV4cG9ydEhUTUxNYXAgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7dWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge1xuICAgICAgICB1c2VyTWFwYm94VG9rZW4sXG4gICAgICAgIGV4cG9ydE1hcGJveEFjY2Vzc1Rva2VuLFxuICAgICAgICBtb2RlXG4gICAgICB9ID0gdWlTdGF0ZS5leHBvcnRNYXBbRVhQT1JUX01BUF9GT1JNQVRTLkhUTUxdO1xuXG4gICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAuLi5LZXBsZXJHbFNjaGVtYS5zYXZlKHRoaXMucHJvcHMpLFxuICAgICAgICBtYXBib3hBcGlBY2Nlc3NUb2tlbjpcbiAgICAgICAgICAodXNlck1hcGJveFRva2VuIHx8ICcnKSAhPT0gJydcbiAgICAgICAgICAgID8gdXNlck1hcGJveFRva2VuXG4gICAgICAgICAgICA6IGV4cG9ydE1hcGJveEFjY2Vzc1Rva2VuLFxuICAgICAgICBtb2RlXG4gICAgICB9O1xuXG4gICAgICB0aGlzLl9kb3dubG9hZEZpbGUoZXhwb3J0TWFwVG9IVE1MKGRhdGEpLCAndGV4dC9odG1sJywgJ2tlcGxlci5nbC5odG1sJyk7XG5cbiAgICAgIHRoaXMuX2Nsb3NlTW9kYWwoKTtcbiAgICB9O1xuXG4gICAgX29uRXhwb3J0TWFwID0gKCkgPT4ge1xuICAgICAgY29uc3Qge3VpU3RhdGV9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHtmb3JtYXR9ID0gdWlTdGF0ZS5leHBvcnRNYXA7XG5cbiAgICAgIGNvbnN0IGRvd25sb2FkZXIgPSB7XG4gICAgICAgIFtFWFBPUlRfTUFQX0ZPUk1BVFMuSFRNTF06IHRoaXMuX29uRXhwb3J0SFRNTE1hcCxcbiAgICAgICAgW0VYUE9SVF9NQVBfRk9STUFUUy5KU09OXTogdGhpcy5fb25FeHBvcnRKU09OTWFwXG4gICAgICB9W2Zvcm1hdF07XG5cbiAgICAgIGRvd25sb2FkZXIgJiYgZG93bmxvYWRlcigpO1xuICAgIH07XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG4gICAgcmVuZGVyKCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBjb250YWluZXJXLFxuICAgICAgICBjb250YWluZXJILFxuICAgICAgICBtYXBTdHlsZSxcbiAgICAgICAgbWFwU3RhdGUsXG4gICAgICAgIHVpU3RhdGUsXG4gICAgICAgIHZpc1N0YXRlLFxuICAgICAgICByb290Tm9kZSxcbiAgICAgICAgdmlzU3RhdGVBY3Rpb25zXG4gICAgICB9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHtjdXJyZW50TW9kYWwsIGRhdGFzZXRLZXlUb1JlbW92ZX0gPSB1aVN0YXRlO1xuICAgICAgY29uc3Qge2RhdGFzZXRzLCBsYXllcnMsIGVkaXRpbmdEYXRhc2V0fSA9IHZpc1N0YXRlO1xuICAgICAgdmFyIGV4cG9ydERhdGFzZXRzID0ge307XG4gICAgICBjb25zdCBkYXRhc2V0S2V5cyA9IE9iamVjdC5rZXlzKGRhdGFzZXRzKTtcbiAgICAgIGRhdGFzZXRLZXlzLm1hcChkayA9PiB7XG4gICAgICAgIGNvbnN0IGV4dGVybmFsRGF0YSA9IGRhdGFzZXRzW2RrXS5leHRlcm5hbERhdGE7XG4gICAgICA