kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
474 lines (389 loc) • 54.3 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
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 _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
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 _exportConfigModal = _interopRequireDefault(require("./modals/export-config-modal"));
var _addMapStyleModal = _interopRequireDefault(require("./modals/add-map-style-modal"));
var _defaultSettings = require("../constants/default-settings");
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; }
function _templateObject3() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n top: 60px;\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n width: 40%;\n padding: 40px 40px 32px 40px;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n height: 85%;\n width: 90%;\n top: 80px;\n padding: 32px 0 0 0;\n max-width: unset;\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
var DataTableModalStyle = (0, _styledComponents.css)(_templateObject());
var DeleteDatasetModalStyled = (0, _styledComponents.css)(_templateObject2());
var LoadDataModalStyle = (0, _styledComponents.css)(_templateObject3());
ModalContainerFactory.deps = [_loadExternalDataModal["default"], _dataTableModal["default"], _deleteDataModal["default"], _loadDataModal["default"], _exportImageModal["default"], _exportDataModal["default"], _exportConfigModal["default"], _addMapStyleModal["default"]];
function ModalContainerFactory(LoadExternalDataModal, DataTableModal, DeleteDatasetModal, LoadDataModal, ExportImageModal, ExportDataModal, ExportConfigModal, AddMapStyleModal) {
var ModalWrapper =
/*#__PURE__*/
function (_Component) {
(0, _inherits2["default"])(ModalWrapper, _Component);
function ModalWrapper() {
var _getPrototypeOf2;
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 = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(ModalWrapper)).call.apply(_getPrototypeOf2, [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), "_onExportConfig", function () {
var data = _this.props.uiState.exportData.data; // we pass all props because we avoid to create new variables
var dump = data ? _schemas["default"].save(_this.props) : _schemas["default"].getConfigToSave(_this.props);
_this._downloadFile(JSON.stringify(dump, null, 2), 'application/json', 'keplergl.json');
_this._closeModal();
});
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",
/* eslint-disable complexity */
value: 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({}, 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 = _react["default"].createElement(currentModal.template, null);
modalProps = currentModal.modalProps;
} else {
switch (currentModal) {
case _defaultSettings.DATA_TABLE_ID:
template = _react["default"].createElement(DataTableModal, {
width: containerW * 0.9,
height: containerH * 0.85,
datasets: datasets,
dataId: editingDataset,
showDatasetTable: visStateActions.showDatasetTable
});
modalProps.cssStyle = DataTableModalStyle;
break;
case _defaultSettings.ADD_EXTERNAL_DATA_ID:
template = _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 = _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 = _react["default"].createElement(LoadDataModal, {
onClose: this._closeModal,
onFileUpload: this._onFileUpload
});
modalProps = {
title: 'Add Data To Map',
cssStyle: LoadDataModalStyle,
footer: false,
onConfirm: this._closeModal
};
break;
case _defaultSettings.EXPORT_IMAGE_ID:
var _uiState$exportImage = uiState.exportImage,
ratio = _uiState$exportImage.ratio,
legend = _uiState$exportImage.legend,
resolution = _uiState$exportImage.resolution,
exporting = _uiState$exportImage.exporting,
imageDataUri = _uiState$exportImage.imageDataUri;
template = _react["default"].createElement(ExportImageModal, {
width: containerW,
height: containerH,
legend: legend,
ratio: ratio,
resolution: resolution,
exporting: exporting,
imageDataUri: imageDataUri,
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: exporting,
children: 'Download'
}
};
break;
case _defaultSettings.EXPORT_DATA_ID:
template = _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_CONFIG_ID:
var keplerGlConfig = _schemas["default"].getConfigToSave({
mapStyle: mapStyle,
visState: visState,
mapState: mapState,
uiState: uiState
});
template = _react["default"].createElement(ExportConfigModal, {
config: keplerGlConfig,
data: uiState.exportData.data,
onClose: this._closeModal,
onChangeExportData: this.props.uiStateActions.setExportData
});
modalProps = {
close: false,
title: 'Export Config',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onExportConfig,
confirmButton: {
large: true,
children: 'Export'
}
};
break;
case _defaultSettings.ADD_MAP_STYLE_ID:
template = _react["default"].createElement(AddMapStyleModal, {
mapboxApiAccessToken: this.props.mapboxApiAccessToken,
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;
case _defaultSettings.ADD_WIDGET_ID:
template = _react["default"].createElement(LoadDataModal, {
onClose: this._closeModal,
onFileUpload: this._onFileUpload
});
modalProps = {
title: 'Add Widget',
cssStyle: LoadDataModalStyle,
footer: false,
onConfirm: this._closeModal
};
break;
// TODO: add this options once we merge dropbox onto kepelr.gl core
// case SAVE_TO_CLOUD_ID
default:
break;
}
}
return this.props.rootNode ? _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,
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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL21vZGFsLWNvbnRhaW5lci5qcyJdLCJuYW1lcyI6WyJEYXRhVGFibGVNb2RhbFN0eWxlIiwiY3NzIiwiRGVsZXRlRGF0YXNldE1vZGFsU3R5bGVkIiwiTG9hZERhdGFNb2RhbFN0eWxlIiwiTW9kYWxDb250YWluZXJGYWN0b3J5IiwiZGVwcyIsIkxvYWRFeHRlcm5hbERhdGFNb2RhbEZhY3RvcnkiLCJEYXRhVGFibGVNb2RhbEZhY3RvcnkiLCJEZWxldGVEYXRhc2V0TW9kYWxGYWN0b3J5IiwiTG9hZERhdGFNb2RhbEZhY3RvcnkiLCJFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSIsIkV4cG9ydERhdGFNb2RhbEZhY3RvcnkiLCJFeHBvcnRDb25maWdNb2RhbEZhY3RvcnkiLCJBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeSIsIkxvYWRFeHRlcm5hbERhdGFNb2RhbCIsIkRhdGFUYWJsZU1vZGFsIiwiRGVsZXRlRGF0YXNldE1vZGFsIiwiTG9hZERhdGFNb2RhbCIsIkV4cG9ydEltYWdlTW9kYWwiLCJFeHBvcnREYXRhTW9kYWwiLCJFeHBvcnRDb25maWdNb2RhbCIsIkFkZE1hcFN0eWxlTW9kYWwiLCJNb2RhbFdyYXBwZXIiLCJwcm9wcyIsInVpU3RhdGVBY3Rpb25zIiwidG9nZ2xlTW9kYWwiLCJrZXkiLCJ2aXNTdGF0ZUFjdGlvbnMiLCJyZW1vdmVEYXRhc2V0IiwiX2Nsb3NlTW9kYWwiLCJtYXBTdHlsZUFjdGlvbnMiLCJhZGRDdXN0b21NYXBTdHlsZSIsImJsb2IiLCJsb2FkRmlsZXMiLCJ1aVN0YXRlIiwiZXhwb3J0SW1hZ2UiLCJleHBvcnRpbmciLCJpbWFnZURhdGFVcmkiLCJmaWxlIiwiREVGQVVMVF9FWFBPUlRfSU1BR0VfTkFNRSIsImNsZWFudXBFeHBvcnRJbWFnZSIsInZpc1N0YXRlIiwiZGF0YXNldHMiLCJleHBvcnREYXRhIiwic2VsZWN0ZWREYXRhc2V0IiwiZGF0YVR5cGUiLCJmaWx0ZXJlZCIsImZpbGVuYW1lIiwic2VsZWN0ZWREYXRhc2V0cyIsIk9iamVjdCIsInZhbHVlcyIsImxlbmd0aCIsImZvckVhY2giLCJzZWxlY3RlZERhdGEiLCJhbGxEYXRhIiwiZGF0YSIsImZpZWxkcyIsImxhYmVsIiwiZXh0ZXJuYWxEYXRhIiwiRVhQT1JUX0RBVEFfVFlQRSIsIkNTViIsInR5cGUiLCJjc3YiLCJfZG93bmxvYWRGaWxlIiwiZHVtcCIsIktlcGxlckdsU2NoZW1hIiwic2F2ZSIsImdldENvbmZpZ1RvU2F2ZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJmaWxlQmxvYiIsIkJsb2IiLCJjb250YWluZXJXIiwiY29udGFpbmVySCIsIm1hcFN0eWxlIiwibWFwU3RhdGUiLCJyb290Tm9kZSIsImN1cnJlbnRNb2RhbCIsImRhdGFzZXRLZXlUb1JlbW92ZSIsImxheWVycyIsImVkaXRpbmdEYXRhc2V0IiwiZXhwb3J0RGF0YXNldHMiLCJkYXRhc2V0S2V5cyIsImtleXMiLCJtYXAiLCJkayIsInRlbXBsYXRlIiwibW9kYWxQcm9wcyIsImlkIiwiREFUQV9UQUJMRV9JRCIsInNob3dEYXRhc2V0VGFibGUiLCJjc3NTdHlsZSIsIkFERF9FWFRFUk5BTF9EQVRBX0lEIiwidGl0bGUiLCJmb290ZXIiLCJERUxFVEVfREFUQV9JRCIsIm9uQ29uZmlybSIsIl9kZWxldGVEYXRhc2V0Iiwib25DYW5jZWwiLCJjb25maXJtQnV0dG9uIiwibmVnYXRpdmUiLCJsYXJnZSIsImNoaWxkcmVuIiwiQUREX0RBVEFfSUQiLCJfb25GaWxlVXBsb2FkIiwiRVhQT1JUX0lNQUdFX0lEIiwicmF0aW8iLCJsZWdlbmQiLCJyZXNvbHV0aW9uIiwic2V0UmF0aW8iLCJzZXRSZXNvbHV0aW9uIiwidG9nZ2xlTGVnZW5kIiwiY2xvc2UiLCJfb25FeHBvcnRJbWFnZSIsImRpc2FibGVkIiwiRVhQT1JUX0RBVEFfSUQiLCJzZXRFeHBvcnREYXRhVHlwZSIsInNldEV4cG9ydFNlbGVjdGVkRGF0YXNldCIsInNldEV4cG9ydEZpbHRlcmVkIiwiX29uRXhwb3J0RGF0YSIsIkVYUE9SVF9DT05GSUdfSUQiLCJrZXBsZXJHbENvbmZpZyIsInNldEV4cG9ydERhdGEiLCJfb25FeHBvcnRDb25maWciLCJBRERfTUFQX1NUWUxFX0lEIiwibWFwYm94QXBpQWNjZXNzVG9rZW4iLCJpbnB1dFN0eWxlIiwiaW5wdXRNYXBTdHlsZSIsImxvYWRDdXN0b21NYXBTdHlsZSIsIl9vbkFkZEN1c3RvbU1hcFN0eWxlIiwic3R5bGUiLCJBRERfV0lER0VUX0lEIiwiQm9vbGVhbiIsIkNvbXBvbmVudCIsIlByb3BUeXBlcyIsIm9iamVjdCIsIm51bWJlciIsInN0cmluZyIsImlzUmVxdWlyZWQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjQSxJQUFNQSxtQkFBbUIsT0FBR0MscUJBQUgsb0JBQXpCO0FBUUEsSUFBTUMsd0JBQXdCLE9BQUdELHFCQUFILHFCQUE5QjtBQUtBLElBQU1FLGtCQUFrQixPQUFHRixxQkFBSCxxQkFBeEI7QUFJQUcscUJBQXFCLENBQUNDLElBQXRCLEdBQTZCLENBQzNCQyxpQ0FEMkIsRUFFM0JDLDBCQUYyQixFQUczQkMsMkJBSDJCLEVBSTNCQyx5QkFKMkIsRUFLM0JDLDRCQUwyQixFQU0zQkMsMkJBTjJCLEVBTzNCQyw2QkFQMkIsRUFRM0JDLDRCQVIyQixDQUE3Qjs7QUFXZSxTQUFTVCxxQkFBVCxDQUNiVSxxQkFEYSxFQUViQyxjQUZhLEVBR2JDLGtCQUhhLEVBSWJDLGFBSmEsRUFLYkMsZ0JBTGEsRUFNYkMsZUFOYSxFQU9iQyxpQkFQYSxFQVFiQyxnQkFSYSxFQVNiO0FBQUEsTUFDTUMsWUFETjtBQUFBO0FBQUE7QUFBQTs7QUFBQTtBQUFBOztBQUFB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LFVBQUEsTUFBTSxFQUFFd0QsT0FBTyxDQUFDdkQsWUFBRCxDQUhqQjtBQUlFLFVBQUEsS0FBSyxFQUFFLEtBQUtoRDtBQUpkLFlBTUd5RCxRQU5ILENBREssR0FTSCxJQVRKO0FBVUQ7QUFDRDs7QUFoV0Y7QUFBQTtBQUFBLElBQzJCK0MsZ0JBRDNCOztBQUFBLG1DQUNNL0csWUFETixlQUVxQjtBQUNqQnNELElBQUFBLFFBQVEsRUFBRTBELHNCQUFVQyxNQURIO0FBRWpCL0QsSUFBQUEsVUFBVSxFQUFFOEQsc0JBQVVFLE1BRkw7QUFHakIvRCxJQUFBQSxVQUFVLEVBQUU2RCxzQkFBVUUsTUFITDtBQUlqQlgsSUFBQUEsb0JBQW9CLEVBQUVTLHNCQUFVRyxNQUFWLENBQWlCQyxVQUp0QjtBQUtqQi9ELElBQUFBLFFBQVEsRUFBRTJELHNCQUFVQyxNQUFWLENBQWlCRyxVQUxWO0FBTWpCaEUsSUFBQUEsUUFBUSxFQUFFNEQsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBTlY7QUFPakJ4RyxJQUFBQSxPQUFPLEVBQUVvRyxzQkFBVUMsTUFBVixDQUFpQkcsVUFQVDtBQVFqQmpHLElBQUFBLFFBQVEsRUFBRTZGLHNCQUFVQyxNQUFWLENBQWlCRyxVQVJWO0FBU2pCL0csSUFBQUEsZUFBZSxFQUFFMkcsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBVGpCO0FBVWpCbEgsSUFBQUEsY0FBYyxFQUFFOEcsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBVmhCO0FBV2pCNUcsSUFBQUEsZUFBZSxFQUFFd0csc0JBQVVDLE1BQVYsQ0FBaUJHO0FBWGpCLEdBRnJCO0FBbVdBLFNBQU9wSCxZQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMTkgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgUmVhY3QsIHtDb21wb25lbnR9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQge2Nzc30gZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IHtmaW5kRE9NTm9kZX0gZnJvbSAncmVhY3QtZG9tJztcbmltcG9ydCB7QmxvYn0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5cbmltcG9ydCBNb2RhbERpYWxvZyBmcm9tICcuL2NvbW1vbi9tb2RhbCc7XG5pbXBvcnQge2Zvcm1hdENzdn0gZnJvbSAncHJvY2Vzc29ycy9kYXRhLXByb2Nlc3Nvcic7XG5pbXBvcnQgS2VwbGVyR2xTY2hlbWEgZnJvbSAnc2NoZW1hcyc7XG5pbXBvcnQge2Rvd25sb2FkRmlsZSwgZGF0YVVSSXRvQmxvYn0gZnJvbSAndXRpbHMvZXhwb3J0LWltYWdlLXV0aWxzJztcbi8vIG1vZGFsc1xuaW1wb3J0IERlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvZGVsZXRlLWRhdGEtbW9kYWwnO1xuaW1wb3J0IERhdGFUYWJsZU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9kYXRhLXRhYmxlLW1vZGFsJztcbmltcG9ydCBMb2FkRGF0YU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9sb2FkLWRhdGEtbW9kYWwnO1xuaW1wb3J0IExvYWRFeHRlcm5hbERhdGFNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvbG9hZC1leHRlcm5hbC1kYXRhLW1vZGFsJztcbmltcG9ydCBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtaW1hZ2UtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydERhdGFNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvZXhwb3J0LWRhdGEtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydENvbmZpZ01vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtY29uZmlnLW1vZGFsJztcbmltcG9ydCBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9hZGQtbWFwLXN0eWxlLW1vZGFsJztcblxuaW1wb3J0IHtcbiAgQUREX0RBVEFfSUQsXG4gIERBVEFfVEFCTEVfSUQsXG4gIERFRkFVTFRfRVhQT1JUX0lNQUdFX05BTUUsXG4gIERFTEVURV9EQVRBX0lELFxuICBFWFBPUlRfREFUQV9JRCxcbiAgRVhQT1JUX0RBVEFfVFlQRSxcbiAgRVhQT1JUX0lNQUdFX0lELFxuICBFWFBPUlRfQ09ORklHX0lELFxuICBBRERfTUFQX1NUWUxFX0lELFxuICBBRERfV0lER0VUX0lELFxuICBBRERfRVhURVJOQUxfREFUQV9JRFxufSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5cbmNvbnN0IERhdGFUYWJsZU1vZGFsU3R5bGUgPSBjc3NgXG4gIGhlaWdodDogODUlO1xuICB3aWR0aDogOTAlO1xuICB0b3A6IDgwcHg7XG4gIHBhZGRpbmc6IDMycHggMCAwIDA7XG4gIG1heC13aWR0aDogdW5zZXQ7XG5gO1xuXG5jb25zdCBEZWxldGVEYXRhc2V0TW9kYWxTdHlsZWQgPSBjc3NgXG4gIHdpZHRoOiA0MCU7XG4gIHBhZGRpbmc6IDQwcHggNDBweCAzMnB4IDQwcHg7XG5gO1xuXG5jb25zdCBMb2FkRGF0YU1vZGFsU3R5bGUgPSBjc3NgXG4gIHRvcDogNjBweDtcbmA7XG5cbk1vZGFsQ29udGFpbmVyRmFjdG9yeS5kZXBzID0gW1xuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWxGYWN0b3J5LFxuICBEYXRhVGFibGVNb2RhbEZhY3RvcnksXG4gIERlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnksXG4gIExvYWREYXRhTW9kYWxGYWN0b3J5LFxuICBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0Q29uZmlnTW9kYWxGYWN0b3J5LFxuICBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeVxuXTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kYWxDb250YWluZXJGYWN0b3J5KFxuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWwsXG4gIERhdGFUYWJsZU1vZGFsLFxuICBEZWxldGVEYXRhc2V0TW9kYWwsXG4gIExvYWREYXRhTW9kYWwsXG4gIEV4cG9ydEltYWdlTW9kYWwsXG4gIEV4cG9ydERhdGFNb2RhbCxcbiAgRXhwb3J0Q29uZmlnTW9kYWwsXG4gIEFkZE1hcFN0eWxlTW9kYWxcbikge1xuICBjbGFzcyBNb2RhbFdyYXBwZXIgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgICByb290Tm9kZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgIGNvbnRhaW5lclc6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgICBjb250YWluZXJIOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgICAgbWFwYm94QXBpQWNjZXNzVG9rZW46IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgIG1hcFN0YXRlOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBtYXBTdHlsZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdmlzU3RhdGU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIHZpc1N0YXRlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZUFjdGlvbnM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIG1hcFN0eWxlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG4gICAgfTtcblxuICAgIF9jbG9zZU1vZGFsID0gKCkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy50b2dnbGVNb2RhbChudWxsKTtcbiAgICB9O1xuXG4gICAgX2RlbGV0ZURhdGFzZXQgPSBrZXkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy52aXNTdGF0ZUFjdGlvbnMucmVtb3ZlRGF0YXNldChrZXkpO1xuICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgIH07XG5cbiAgICBfb25BZGRDdXN0b21NYXBTdHlsZSA9ICgpID0+IHtcbiAgICAgIHRoaXMucHJvcHMubWFwU3R5bGVBY3Rpb25zLmFkZEN1c3RvbU1hcFN0eWxlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkZpbGVVcGxvYWQgPSBibG9iID0+IHtcbiAgICAgIHRoaXMucHJvcHMudmlzU3RhdGVBY3Rpb25zLmxvYWRGaWxlcyhibG9iKTtcbiAgICB9O1xuXG4gICAgX29uRXhwb3J0SW1hZ2UgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7ZXhwb3J0aW5nLCBpbWFnZURhdGFVcml9ID0gdGhpcy5wcm9wcy51aVN0YXRlLmV4cG9ydEltYWdlO1xuICAgICAgaWYgKCFleHBvcnRpbmcgJiYgaW1hZ2VEYXRhVXJpKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBkYXRhVVJJdG9CbG9iKGltYWdlRGF0YVVyaSk7XG4gICAgICAgIGRvd25sb2FkRmlsZShmaWxlLCBERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucHJvcHMudWlTdGF0ZUFjdGlvbnMuY2xlYW51cEV4cG9ydEltYWdlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9kb3dubG9hZEZpbGUoZGF0YSwgdHlwZSwgZmlsZW5hbWUpIHtcbiAgICAgIGNvbnN0IGZpbGVCbG9iID0gbmV3IEJsb2IoW2RhdGFdLCB7dHlwZX0pO1xuICAgICAgZG93bmxvYWRGaWxlKGZpbGVCbG9iLCBmaWxlbmFtZSk7XG4gICAgfVxuXG4gICAgX29uRXhwb3J0RGF0YSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHt2aXNTdGF0ZSwgdWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2RhdGFzZXRzfSA9IHZpc1N0YXRlO1xuICAgICAgY29uc3Qge3NlbGVjdGVkRGF0YXNldCwgZGF0YVR5cGUsIGZpbHRlcmVkfSA9IHVpU3RhdGUuZXhwb3J0RGF0YTtcbiAgICAgIC8vIGdldCB0aGUgc2VsZWN0ZWQgZGF0YVxuICAgICAgY29uc3QgZmlsZW5hbWUgPSAnZ2VvaXEuaW8nO1xuICAgICAgY29uc3Qgc2VsZWN0ZWREYXRhc2V0cyA9IGRhdGFzZXRzW3NlbGVjdGVkRGF0YXNldF1cbiAgICAgICAgPyBbZGF0YXNldHNbc2VsZWN0ZWREYXRhc2V0XV1cbiAgICAgICAgOiBPYmplY3QudmFsdWVzKGRhdGFzZXRzKTtcbiAgICAgIGlmICghc2VsZWN0ZWREYXRhc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgLy8gZXJyb3I6IHNlbGVjdGVkIGRhdGFzZXQgbm90IGZvdW5kLlxuICAgICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgICB9XG5cbiAgICAgIHNlbGVjdGVkRGF0YXNldHMuZm9yRWFjaChzZWxlY3RlZERhdGEgPT4ge1xuICAgICAgICBjb25zdCB7YWxsRGF0YSwgZGF0YSwgZmllbGRzLCBsYWJlbCwgZXh0ZXJuYWxEYXRhfSA9IHNlbGVjdGVkRGF0YTtcbiAgICAgICAgY29uc3QgZXhwb3J0RGF0YSA9IGZpbHRlcmVkID8gZGF0YSA6IGFsbERhdGE7XG4gICAgICAgIGlmIChleHRlcm5hbERhdGEgJiYgZXh0ZXJuYWxEYXRhID09PSB0cnVlKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3RhcnQgdG8gZXhwb3J0IGRhdGEgYWNjb3JkaW5nIHRvIHNlbGVjdGVkIGRhdGEgdHlwZVxuICAgICAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICAgICAgY2FzZSBFWFBPUlRfREFUQV9UWVBFLkNTVjoge1xuICAgICAgICAgICAgY29uc3QgdHlwZSA9ICd0ZXh0L2Nzdic7XG4gICAgICAgICAgICBjb25zdCBjc3YgPSBmb3JtYXRDc3YoZXhwb3J0RGF0YSwgZmllbGRzKTtcbiAgICAgICAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShjc3YsIHR5cGUsIGAke2ZpbGVuYW1lfV8ke2xhYmVsfS5jc3ZgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBUT0RPOiBzdXBwb3J0IG1vcmUgZmlsZSB0eXBlcy5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkV4cG9ydENvbmZpZyA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHtkYXRhfSA9IHRoaXMucHJvcHMudWlTdGF0ZS5leHBvcnREYXRhO1xuXG4gICAgICAvLyB3ZSBwYXNzIGFsbCBwcm9wcyBiZWNhdXNlIHdlIGF2b2lkIHRvIGNyZWF0ZSBuZXcgdmFyaWFibGVzXG4gICAgICBjb25zdCBkdW1wID0gZGF0YVxuICAgICAgICA/IEtlcGxlckdsU2NoZW1hLnNhdmUodGhpcy5wcm9wcylcbiAgICAgICAgOiBLZXBsZXJHbFNjaGVtYS5nZXRDb25maWdUb1NhdmUodGhpcy5wcm9wcyk7XG5cbiAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZHVtcCwgbnVsbCwgMiksXG4gICAgICAgICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ2tlcGxlcmdsLmpzb24nXG4gICAgICApO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbiAgICByZW5kZXIoKSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGNvbnRhaW5lclcsXG4gICAgICAgIGNvbnRhaW5lckgsXG4gICAgICAgIG1hcFN0eWxlLFxuICAgICAgICBtYXBTdGF0ZSxcbiAgICAgICAgdWlTdGF0ZSxcbiAgICAgICAgdmlzU3RhdGUsXG4gICAgICAgIHJvb3ROb2RlLFxuICAgICAgICB2aXNTdGF0ZUFjdGlvbnNcbiAgICAgIH0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2N1cnJlbnRNb2RhbCwgZGF0YXNldEtleVRvUmVtb3ZlfSA9IHVpU3RhdGU7XG4gICAgICBjb25zdCB7ZGF0YXNldHMsIGxheWVycywgZWRpdGluZ0RhdGFzZXR9ID0gdmlzU3RhdGU7XG4gICAgICB2YXIgZXhwb3J0RGF0YXNldHMgPSB7fTtcbiAgICAgIGNvbnN0IGRhdGFzZXRLZXlzID0gT2JqZWN0LmtleXMoZGF0YXNldHMpO1xuICAgICAgZGF0YXNldEtleXMubWFwKGRrID0+IHtcbiAgICAgICAgY29uc3QgZXh0ZXJuYWxEYXRhID0gZGF0YXNldHNbZGtdLmV4dGVybmFsRGF0YTtcbiAgICAgICAgZXh0ZXJuYWxEYXRhICYmIGV4dGVybmFsRGF0YSA9PT0gdHJ1ZVxuICAgICAgICAgID8gbnVsbFxuICAgICAgICAgIDogKGV4cG9ydERhdGFzZXRzID0gey4uLmV4cG9ydERhdGFzZXRzLCBbZGtdOiBkYXRhc2V0c1tka119KTtcbiAgICAgIH0pO1xuICAgICAgbGV0IHRlbXBsYXRlID0gbnVsbDtcbiAgICAgIGxldCBtb2RhbFByb3BzID0ge307XG5cbiAgICAgIGlmIChjdXJyZW50TW9kYWwgJiYgY3VycmVudE1vZGFsLmlkICYmIGN1cnJlbnRNb2RhbC50ZW1wbGF0ZSkge1xuICAgICAgICAvLyBpZiBjdXJyZW50TWRvYWwgdGVtcGxhdGUgaXMgYWxyZWFkeSBwcm92aWRlZFxuICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGVtcGxhdGUgaXMgdmFsaWRcbiAgICAgICAgdGVtcGxhdGUgPSA8Y3VycmVudE1vZGFsLnRlbXBsYXRlIC8+O1xuICAgICAgICBtb2RhbFByb3BzID0gY3VycmVudE1vZGFsLm1vZGFsUHJvcHM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2l0Y2ggKGN1cnJlbnRNb2RhbCkge1xuICAgICAgICAgIGNhc2UgREFUQV9UQUJMRV9JRDpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gKFxuICAgICAgICAgICAgICA8RGF0YVRhYmxlTW9kYWxcbiAgICAgICAgICAgICAgICB3aWR0aD17Y29udGFpbmVyVyAqIDAuOX1cbiAgICAgICAgICAgICAgICBoZWlnaHQ9e2NvbnRhaW5lckggKiAwLjg1fVxuICAgICAgICAgICAgICAgIGRhdGFzZXRzPXtkYXRhc2V0c31cbiAgICAgICAgICAgICAgICBkYXRhSWQ9e2VkaXRpbmdEYXRhc2V0fVxuICAgICAgICAgICAgICAgIHNob3dEYXRhc2V0VGFibGU9e3Zpc1N0YXRlQWN0aW9ucy5zaG93RGF0YXNldFRhYmxlfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG1vZGFsUHJvcHMuY3NzU3R5bGUgPSBEYXRhVGFibGVNb2RhbFN0eWxlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBBRERfRVhURVJOQUxfREFUQV9JRDpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gPExvYWRFeHRlcm5hbERhdGFNb2RhbCAvPjtcbiAgICAgICAgICAgIG1vZGFsUHJvcHMgPSB7XG4gICAgICAgICAgICAgIHRpdGxlOiAnQWRkIEV4dGVybmFsIERhdGEgVG8gTWFwJyxcbiAgICAgICAgICAgICAgZm9vdGVyOiBmYWxzZVxuICAgICAgICAgICAgICAvLyBjb25maXJtQnV0dG9uOiB7XG4gICAgICAgICAgICAgIC8vICAgbGFyZ2U6IHRydWUsXG4gICAgICAgICAgICAgIC8vICAgY2hpbGRyZW46ICdBZGQgRXh0ZXJuYWwgRGF0YXNldCdcbiAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgREVMRVRFX0RBVEFfSUQ6XG4gICAgICAgICAgICAvLyB2YWxpZGF0ZSBvcHRpb25zXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIGRhdGFzZXRLZXlUb1JlbW92ZSAmJlxuICAgICAgICAgICAgICBkYXRhc2V0cyAmJlxuICAgICAgICAgICAgICBkYXRhc2V0c1tkYXRhc2V0S2V5VG9SZW1vdmVdXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgICAgPERlbGV0ZURhdGFzZXRNb2RhbFxuICAgICAgICAgICAgICAgICAgZGF0YXNldD17ZGF0YXNldHNbZGF0YXNldEtleVRvUmVtb3ZlXX1cbiAgICAgICAgICAgICAgICAgIGxheWVycz17bGF5ZXJzfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgbW9kYWxQcm9wcyA9IHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0RlbGV0ZSBEYXRhc2V0JyxcbiAgICAgICAgICAgICAgICBjc3NTdHlsZTogRGVsZXRlRGF0YXNldE1vZGFsU3R5bGVkLFxuICAgICAgICAgICAgICAgIGZvb3RlcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvbkNvbmZpcm06ICgpID0+IHRoaXMuX2RlbGV0ZURhdGFzZXQoZGF0YXNldEtleVRvUmVtb3ZlKSxcbiAgICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5fY2xvc2VNb2RhbCxcbiAgICAgICAgICAgICAgICBjb25maXJtQnV0dG9uOiB7XG4gICAgICAgICAgICAgICAgICBuZWdhdGl2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIGxhcmdlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgY2hpbGRyZW46ICdEZWxldGUnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7IC8vIGluIGNhc2Ugd2UgYWRkIGEgbmV3IGNhc2UgYWZ0ZXIgdGhpcyBvbmVcbiAgICAgICAgICBjYXNlIEFERF9EQVRBX0lEOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgIDxMb2FkRGF0YU1vZGFsXG4gICAgICAgICAgICAgICAgb25DbG9zZT17dGhpcy5fY2xvc2VNb2RhbH1cbiAgICAgICAgICAgICAgICBvbkZpbGVVcGxvYWQ9e3RoaXMuX29uRmlsZVVwbG9hZH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBtb2RhbFByb3BzID0ge1xuICAgICAgICAgICAgICB0aXRsZTogJ0FkZCBEYXRhIFRvIE1hcCcsXG4gICAgICAgICAgICAgIGNzc1N0eWxlOiBMb2FkRGF0YU1vZGFsU3R5bGUsXG4gICAgICAgICAgICAgIGZvb3RlcjogZmFsc2UsXG4gICAgICAgICAgICAgIG9uQ29uZmlybTogdGhpcy5fY2xvc2VNb2RhbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBFWFBPUlRfSU1BR0VfSUQ6XG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHJhdGlvLFxuICAgICAgICAgICAgICBsZWdlbmQsXG4gICAgICAgICAgICAgIHJlc29sdXRpb24sXG4gICAgICAgICAgICAgIGV4cG9ydGluZyxcbiAgICAgICAgICAgICAgaW1hZ2VEYXRhVXJpXG4gICAgICAgICAgICB9ID0gdWlTdGF0ZS5leHBvcnRJbWFnZTtcbiAgICAgICAgICAgIHRlbXBsYXRlID0gKFxuICAgICAgICAgICAgICA8RXhwb3J0SW1hZ2VNb2RhbFxuICAgICAgICAgICAgICAgIHdpZHRoPXtjb250YWluZXJXfVxuICAgICAgICAgICAgICAgIGhlaWdodD17Y29udGFpbmVySH1cbiAgICAgICAgICAgICAgICBsZWdlbmQ9e2xlZ2VuZH1cbiAgICAgICAgICAgICAgICByYXRpbz17cmF0aW99XG4gICAgICAgICAgICAgICAgcmVzb2x1dGlvbj17cmVzb2x1dGlvbn1cbiAgICAgICAgICAgICAgICBleHBvcnRpbmc9e2V4cG9ydGluZ31cbiAgICAgICAgICAgICAgICBpbWFnZURhdGFVcmk9e2ltYWdlRGF0YVVyaX1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZVJhdGlvPXt0aGlzLnByb3BzLnVpU3RhdGVBY3Rpb25zLnNldFJhdGlvfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlUmVzb2x1dGlvbj17dGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy5zZXRSZXNvbHV0aW9ufVxuICAgICAgICAgICAgICAgIG9uVG9nZ2xlTGVnZW5kPXt0aGlzLnByb3BzLnVpU3RhdGVBY3Rpb25zLnRvZ2dsZUxlZ2VuZH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBtb2RhbFByb3BzID0ge1xuICAgICAgICAgICAgICBjbG9zZTogZmFsc2UsXG4gICAgICAgICAgICAgIHRpdGxlOiAnRXhwb3J0IEltYWdlJyxcbiAgICAgICAgICAgICAgZm9vdGVyOiB0cnVlLFxuICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5fY2xvc2VNb2RhbCxcbiAgICAgICAgICAgICAgb25Db25maXJtOiB0aGlzLl9vbkV4cG9ydEltYWdlLFxuICAgICAgICAgICAgICBjb25maXJtQnV0dG9uOiB7XG4gICAgICAgICAgICAgICAgbGFyZ2U6IHRydWUsXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGV4cG9ydGluZyxcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogJ0Rvd25sb2FkJ1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIEVYUE9SVF9EQVRBX0lEOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgIDxFeHBvcnREYXRhTW9kYWxcbiAgICAgICAgICAgICAgICB7Li4udWlTdGF0ZS5leHBvcnREYXRhfVxuICAgICAgICAgICAgICAgIGRhdGFzZXRzPXtleHBvcnREYXRhc2V0c31cbiAgICAgICAgICAgICAgICBvbkNsb3NlPXt0aGlzLl9jbG9zZU1vZGFsfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlRXhwb3J0RGF0YVR5cGU9e1xuICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy5zZXRFeHBvcnREYXRhVHlwZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZUV4cG9ydFNlbGVjdGVkRGF0YXNldD17XG4gICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnVpU3RhdGVBY3Rpb25zLnNldEV4cG9ydFNlbGVjdGVkRGF0YXNldFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZUV4cG9ydEZpbHRlcmVkPXtcbiAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMudWlTdGF0ZUFjdGlvbnMuc2V0RXhwb3J0RmlsdGV