adui
Version:
<div> <img src="https://wxa.wxs.qq.com/mpweb/delivery/legacy/wxadtouch/upload/t1/od834zef_52939fc6.png" style="margin:40px 0 0 -8px; background-color: #fcfcfc; box-shadow: none;" /> </div>
560 lines (463 loc) • 68.5 kB
JavaScript
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var React = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _getScrollBarSize = _interopRequireDefault(require("rc-util/lib/getScrollBarSize"));
var _classnames = _interopRequireDefault(require("classnames"));
var _rcMotion = _interopRequireDefault(require("rc-motion"));
var _omit = _interopRequireDefault(require("../_util/omit"));
var _portal = _interopRequireDefault(require("../portal"));
var _channelsButton = _interopRequireDefault(require("../channels-button"));
var _icon = _interopRequireDefault(require("../icon"));
require("./style");
var _excluded = ["bodyClassName", "bodyStyle", "children", "className", "destroyAfterClose", "footerClassName", "footerElement", "footerStyle", "headerClassName", "headerContent", "headerElement", "headerStyle", "maskClosable", "steps", "style", "title", "zIndex"];
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
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(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); 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 = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
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; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var prefix = "adui-channels-dialog";
var Dialog = function (_React$Component) {
_inherits(Dialog, _React$Component);
var _super = _createSuper(Dialog);
function Dialog(_props) {
var _this;
_classCallCheck(this, Dialog);
_this = _super.call(this, _props);
_this.container = void 0;
_this.bodyIsOverflowing = void 0;
_this.scrollbarWidth = void 0;
_this.dialog = void 0;
_this.wrapper = void 0;
_this.isUnmounted = false;
_this.saveDialog = function (node) {
_this.dialog = node;
};
_this.resetScrollbarPadding = function () {
var changeBodyStyle = _this.props.changeBodyStyle;
if (changeBodyStyle) {
document.body.style.overflow = "";
document.body.style.paddingRight = "";
}
};
_this.setScrollbarPadding = function () {
var changeBodyStyle = _this.props.changeBodyStyle;
if (changeBodyStyle) {
var _window = window,
innerWidth = _window.innerWidth;
_this.bodyIsOverflowing = document.body.clientWidth < innerWidth;
if (_this.bodyIsOverflowing && !document.body.style.paddingRight) {
_this.scrollbarWidth = (0, _getScrollBarSize["default"])();
if (_this.scrollbarWidth !== undefined) {
document.body.style.paddingRight = "".concat(_this.scrollbarWidth, "px");
}
}
document.body.style.overflow = "hidden";
}
};
_this.getCancelButton = function () {
var _this$props = _this.props,
cancelProps = _this$props.cancelProps,
cancelText = _this$props.cancelText,
steps = _this$props.steps,
type = _this$props.type;
var currentStep = _this.state.currentStep;
var defaultText = currentStep === 0 ? "取消" : "上一步";
var generateButton = function generateButton(props) {
var text = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultText;
return React.createElement(_channelsButton["default"], _extends({
key: "cancel",
theme: "light",
onClick: _this.handleCancel
}, props), text);
};
if (steps && steps.length) {
var props = steps[currentStep].cancelProps;
var text = steps[currentStep].cancelText;
return generateButton(props, text);
}
if (type === "inform") {
return null;
}
return generateButton(cancelProps, cancelText);
};
_this.getConfirmButton = function () {
var _this$props2 = _this.props,
confirmProps = _this$props2.confirmProps,
confirmText = _this$props2.confirmText,
steps = _this$props2.steps;
var currentStep = _this.state.currentStep;
var generateButton = function generateButton(props, text) {
return React.createElement(_channelsButton["default"], _extends({
key: "primary",
intent: "primary",
onClick: _this.handleConfirm
}, props), text);
};
if (steps && steps.length) {
var props = steps[currentStep].confirmProps;
var text = steps[currentStep].confirmText || (currentStep === steps.length - 1 ? "完成" : "下一步");
return generateButton(props, text);
}
return generateButton(confirmProps, confirmText || "确认");
};
_this.handleKeyDown = function (e) {
var escapeKeyClosable = _this.props.escapeKeyClosable;
if (escapeKeyClosable && e.key === "Escape") {
e.stopPropagation();
_this.handleCancel();
}
};
_this.handleCancel = function (type) {
var _this$props3 = _this.props,
onCancel = _this$props3.onCancel,
steps = _this$props3.steps,
visible = _this$props3.visible;
var currentStep = _this.state.currentStep;
if (type === "close" || !steps || !steps.length) {
if (visible === null) {
_this.setState({
visible: false
});
}
if (onCancel) {
onCancel();
}
} else {
var onStepCancel = steps[currentStep].onCancel;
if (onStepCancel) {
onStepCancel();
}
if (currentStep === 0) {
if (visible === null) {
_this.setState({
visible: false
});
}
} else {
_this.setState({
currentStep: currentStep - 1
});
}
}
};
_this.handleConfirm = function () {
var _this$props4 = _this.props,
onConfirm = _this$props4.onConfirm,
steps = _this$props4.steps,
visible = _this$props4.visible;
var currentStep = _this.state.currentStep;
if (steps && steps.length) {
var onStepConfirm = steps[currentStep].onConfirm;
if (onStepConfirm) {
onStepConfirm();
}
if (currentStep === steps.length - 1) {
if (visible === null) {
_this.setState({
visible: false
});
}
} else {
_this.setState({
currentStep: currentStep + 1
});
}
} else {
if (visible === null) {
_this.setState({
visible: false
});
}
if (onConfirm) {
onConfirm();
}
}
};
_this.onLeave = function () {
var _this$props5 = _this.props,
afterClose = _this$props5.afterClose,
destroyAfterClose = _this$props5.destroyAfterClose;
if (_this.wrapper) {
_this.wrapper.style.display = "none";
}
_this.resetScrollbarPadding();
if (afterClose) {
afterClose();
}
if (destroyAfterClose && !_this.isUnmounted) {
_this.setState({
hasEverOpened: false
});
}
};
_this.handleEnter = function () {
var escapeKeyClosable = _this.props.escapeKeyClosable;
if (_this.wrapper) {
if (escapeKeyClosable) {
_this.wrapper.focus();
}
}
};
_this.getComponent = function (options) {
var _this$props6 = _this.props,
bodyClassName = _this$props6.bodyClassName,
bodyStyle = _this$props6.bodyStyle,
children = _this$props6.children,
className = _this$props6.className,
destroyAfterClose = _this$props6.destroyAfterClose,
footerClassName = _this$props6.footerClassName,
footerElement = _this$props6.footerElement,
footerStyle = _this$props6.footerStyle,
headerClassName = _this$props6.headerClassName,
headerContent = _this$props6.headerContent,
headerElement = _this$props6.headerElement,
headerStyle = _this$props6.headerStyle,
maskClosable = _this$props6.maskClosable,
steps = _this$props6.steps,
style = _this$props6.style,
title = _this$props6.title,
zIndexProp = _this$props6.zIndex,
otherProps = _objectWithoutProperties(_this$props6, _excluded);
var zIndex = zIndexProp;
var restProps = (0, _omit["default"])(otherProps, ["afterClose", "cancelProps", "cancelText", "changeBodyStyle", "confirmProps", "confirmText", "currentStep", "defaultCurrentStep", "defaultVisible", "escapeKeyClosable", "getContainer", "onCancel", "onConfirm", "type", "visible"]);
var classSet = (0, _classnames["default"])(className, "".concat(prefix, "-inner"));
var currentStep = _this.state.currentStep;
var visible = _this.state.visible;
if (options && Object.keys(options).includes("visible")) {
;
visible = options.visible;
}
return React.createElement("div", {
ref: _this.saveDialog
}, React.createElement("div", {
className: "".concat(prefix, "-wrapper"),
ref: function ref(wrapper) {
if (wrapper) {
_this.wrapper = wrapper;
}
},
style: {
display: visible ? "flex" : "",
zIndex: zIndex
},
tabIndex: 0,
role: "none",
onKeyDown: _this.handleKeyDown
}, React.createElement(_rcMotion["default"], {
motionName: "".concat(prefix, "-mask"),
visible: visible,
removeOnLeave: destroyAfterClose
}, function (_ref, ref) {
var cls = _ref.className;
return React.createElement("div", {
ref: ref,
className: (0, _classnames["default"])("".concat(prefix, "-mask"), cls),
role: "none",
onClick: function onClick() {
if (maskClosable) {
_this.handleCancel("close");
}
}
});
}), React.createElement(_rcMotion["default"], {
onAppearStart: _this.handleEnter,
onEnterStart: _this.handleEnter,
onLeaveEnd: _this.onLeave,
motionName: prefix,
visible: visible,
removeOnLeave: destroyAfterClose
}, function (_ref2, ref) {
var cls = _ref2.className;
return React.createElement("div", _extends({
ref: ref,
className: (0, _classnames["default"])(classSet, cls),
style: _objectSpread({
margin: "auto",
zIndex: 1
}, style)
}, restProps), headerElement === null ? null : headerElement || React.createElement("div", {
className: "".concat(prefix, "-header ").concat(headerClassName),
style: headerStyle
}, [React.createElement("div", {
key: 0,
className: "".concat(prefix, "-title")
}, title), React.createElement("div", {
key: 1
}, headerContent && React.createElement("div", {
className: "".concat(prefix, "-headerContent")
}, headerContent)), React.createElement(_icon["default"], {
key: 2,
className: "".concat(prefix, "-close"),
size: 24,
icon: "cancel",
onClick: function onClick() {
return _this.handleCancel("close");
}
})]), React.createElement("div", {
className: "".concat(prefix, "-body ").concat(bodyClassName),
style: bodyStyle
}, steps && steps.length ? steps[currentStep].children : children), footerElement === null ? null : React.createElement("div", {
className: "".concat(prefix, "-footer ").concat(footerClassName),
style: footerStyle
}, footerElement || [_this.getCancelButton(), _this.getConfirmButton()]));
})));
};
_this.handleChildrenMount = function () {
var visible = _this.state.visible;
if (visible && _this.wrapper) {
_this.setScrollbarPadding();
}
};
_this.componentDidUpdate = function (_, _ref3) {
var visiblePrev = _ref3.visible;
var visible = _this.state.visible;
if (visible !== visiblePrev && visible && _this.wrapper) {
_this.setScrollbarPadding();
}
};
_this.componentWillUnmount = function () {
var visible = _this.state.visible;
_this.isUnmounted = true;
if (visible) {
_this.resetScrollbarPadding();
}
};
var _currentStep = _props.currentStep,
defaultCurrentStep = _props.defaultCurrentStep,
_visible = _props.visible,
defaultVisible = _props.defaultVisible;
var visibleState = _visible !== null ? !!_visible : !!defaultVisible;
var currentStepState = _currentStep !== null ? _currentStep : defaultCurrentStep;
_this.state = {
visible: visibleState,
currentStep: currentStepState || 0,
hasEverOpened: visibleState
};
return _this;
}
_createClass(Dialog, [{
key: "render",
value: function render() {
var getContainer = this.props.getContainer;
var hasEverOpened = this.state.hasEverOpened;
if (!hasEverOpened) {
return null;
}
return React.createElement(_portal["default"], {
onChildrenMount: this.handleChildrenMount,
getContainer: getContainer
}, this.getComponent());
}
}]);
return Dialog;
}(React.Component);
Dialog.propTypes = {
afterClose: _propTypes["default"].func,
bodyClassName: _propTypes["default"].string,
bodyStyle: _propTypes["default"].object,
cancelProps: _propTypes["default"].object,
cancelText: _propTypes["default"].node,
changeBodyStyle: _propTypes["default"].bool,
children: _propTypes["default"].node,
className: _propTypes["default"].string,
confirmProps: _propTypes["default"].object,
confirmText: _propTypes["default"].node,
currentStep: _propTypes["default"].number,
defaultCurrentStep: _propTypes["default"].number,
defaultVisible: _propTypes["default"].bool,
destroyAfterClose: _propTypes["default"].bool,
escapeKeyClosable: _propTypes["default"].bool,
footerElement: _propTypes["default"].node,
footerClassName: _propTypes["default"].string,
footerStyle: _propTypes["default"].object,
getContainer: _propTypes["default"].func,
headerContent: _propTypes["default"].node,
headerElement: _propTypes["default"].node,
headerClassName: _propTypes["default"].string,
headerStyle: _propTypes["default"].object,
maskClosable: _propTypes["default"].bool,
onCancel: _propTypes["default"].func,
onConfirm: _propTypes["default"].func,
style: _propTypes["default"].object,
title: _propTypes["default"].node,
type: _propTypes["default"].oneOf(["confirm", "inform"]),
visible: _propTypes["default"].bool,
zIndex: _propTypes["default"].any
};
Dialog.defaultProps = {
afterClose: null,
bodyClassName: "",
bodyStyle: {},
cancelProps: {},
cancelText: "取消",
changeBodyStyle: true,
children: null,
className: undefined,
confirmProps: {},
confirmText: "确认",
currentStep: null,
defaultCurrentStep: null,
defaultVisible: null,
destroyAfterClose: false,
escapeKeyClosable: true,
footerElement: undefined,
footerClassName: "",
footerStyle: {},
getContainer: undefined,
headerContent: null,
headerClassName: "",
headerElement: undefined,
headerStyle: {},
maskClosable: false,
onCancel: null,
onConfirm: null,
style: {},
title: null,
type: "confirm",
visible: null,
zIndex: "var(--z-index-dialog)"
};
Dialog.info = void 0;
Dialog.success = void 0;
Dialog.warning = void 0;
Dialog.danger = void 0;
Dialog.confirm = void 0;
Dialog.inform = void 0;
Dialog.getDerivedStateFromProps = function (_ref4, _ref5) {
var currentStep = _ref4.currentStep,
visible = _ref4.visible;
var hasEverOpened = _ref5.hasEverOpened;
var newState = {};
if (currentStep !== null) {
newState.currentStep = currentStep;
}
if (visible !== null) {
newState.visible = visible;
if (!hasEverOpened && visible) {
newState.hasEverOpened = true;
}
}
return Object.keys(newState).length > 0 ? newState : null;
};
var _default = Dialog;
exports["default"] = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwcmVmaXgiLCJEaWFsb2ciLCJwcm9wcyIsImNvbnRhaW5lciIsImJvZHlJc092ZXJmbG93aW5nIiwic2Nyb2xsYmFyV2lkdGgiLCJkaWFsb2ciLCJ3cmFwcGVyIiwiaXNVbm1vdW50ZWQiLCJzYXZlRGlhbG9nIiwibm9kZSIsInJlc2V0U2Nyb2xsYmFyUGFkZGluZyIsImNoYW5nZUJvZHlTdHlsZSIsImRvY3VtZW50IiwiYm9keSIsInN0eWxlIiwib3ZlcmZsb3ciLCJwYWRkaW5nUmlnaHQiLCJzZXRTY3JvbGxiYXJQYWRkaW5nIiwid2luZG93IiwiaW5uZXJXaWR0aCIsImNsaWVudFdpZHRoIiwiZ2V0U2Nyb2xsQmFyU2l6ZSIsInVuZGVmaW5lZCIsImdldENhbmNlbEJ1dHRvbiIsImNhbmNlbFByb3BzIiwiY2FuY2VsVGV4dCIsInN0ZXBzIiwidHlwZSIsImN1cnJlbnRTdGVwIiwic3RhdGUiLCJkZWZhdWx0VGV4dCIsImdlbmVyYXRlQnV0dG9uIiwidGV4dCIsImhhbmRsZUNhbmNlbCIsImxlbmd0aCIsImdldENvbmZpcm1CdXR0b24iLCJjb25maXJtUHJvcHMiLCJjb25maXJtVGV4dCIsImhhbmRsZUNvbmZpcm0iLCJoYW5kbGVLZXlEb3duIiwiZSIsImVzY2FwZUtleUNsb3NhYmxlIiwia2V5Iiwic3RvcFByb3BhZ2F0aW9uIiwib25DYW5jZWwiLCJ2aXNpYmxlIiwic2V0U3RhdGUiLCJvblN0ZXBDYW5jZWwiLCJvbkNvbmZpcm0iLCJvblN0ZXBDb25maXJtIiwib25MZWF2ZSIsImFmdGVyQ2xvc2UiLCJkZXN0cm95QWZ0ZXJDbG9zZSIsImRpc3BsYXkiLCJoYXNFdmVyT3BlbmVkIiwiaGFuZGxlRW50ZXIiLCJmb2N1cyIsImdldENvbXBvbmVudCIsIm9wdGlvbnMiLCJib2R5Q2xhc3NOYW1lIiwiYm9keVN0eWxlIiwiY2hpbGRyZW4iLCJjbGFzc05hbWUiLCJmb290ZXJDbGFzc05hbWUiLCJmb290ZXJFbGVtZW50IiwiZm9vdGVyU3R5bGUiLCJoZWFkZXJDbGFzc05hbWUiLCJoZWFkZXJDb250ZW50IiwiaGVhZGVyRWxlbWVudCIsImhlYWRlclN0eWxlIiwibWFza0Nsb3NhYmxlIiwidGl0bGUiLCJ6SW5kZXhQcm9wIiwiekluZGV4Iiwib3RoZXJQcm9wcyIsInJlc3RQcm9wcyIsIm9taXQiLCJjbGFzc1NldCIsImNsYXNzTmFtZXMiLCJPYmplY3QiLCJrZXlzIiwiaW5jbHVkZXMiLCJyZWYiLCJjbHMiLCJtYXJnaW4iLCJoYW5kbGVDaGlsZHJlbk1vdW50IiwiY29tcG9uZW50RGlkVXBkYXRlIiwiXyIsInZpc2libGVQcmV2IiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJkZWZhdWx0Q3VycmVudFN0ZXAiLCJkZWZhdWx0VmlzaWJsZSIsInZpc2libGVTdGF0ZSIsImN1cnJlbnRTdGVwU3RhdGUiLCJnZXRDb250YWluZXIiLCJSZWFjdCIsIkNvbXBvbmVudCIsInByb3BUeXBlcyIsIlByb3BUeXBlcyIsImZ1bmMiLCJzdHJpbmciLCJvYmplY3QiLCJib29sIiwibnVtYmVyIiwib25lT2YiLCJhbnkiLCJkZWZhdWx0UHJvcHMiLCJpbmZvIiwic3VjY2VzcyIsIndhcm5pbmciLCJkYW5nZXIiLCJjb25maXJtIiwiaW5mb3JtIiwiZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzIiwibmV3U3RhdGUiXSwic291cmNlcyI6WyIuLi8uLi9jb21wb25lbnRzL2NoYW5uZWxzLWRpYWxvZy9EaWFsb2cudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFJlYWN0IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gXCJwcm9wLXR5cGVzXCJcbmltcG9ydCBnZXRTY3JvbGxCYXJTaXplIGZyb20gXCJyYy11dGlsL2xpYi9nZXRTY3JvbGxCYXJTaXplXCJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gXCJjbGFzc25hbWVzXCJcbmltcG9ydCBDU1NNb3Rpb24gZnJvbSBcInJjLW1vdGlvblwiXG5pbXBvcnQgb21pdCBmcm9tIFwiLi4vX3V0aWwvb21pdFwiXG5pbXBvcnQgUG9ydGFsIGZyb20gXCIuLi9wb3J0YWxcIlxuaW1wb3J0IEJ1dHRvbiwgeyBJQnV0dG9uUHJvcHMgfSBmcm9tIFwiLi4vY2hhbm5lbHMtYnV0dG9uXCJcbmltcG9ydCBJY29uIGZyb20gXCIuLi9pY29uXCJcbmltcG9ydCBcIi4vc3R5bGVcIlxuXG5jb25zdCBwcmVmaXggPSBcImFkdWktY2hhbm5lbHMtZGlhbG9nXCJcblxuaW50ZXJmYWNlIElTdGVwUHJvcHMge1xuICAvKipcbiAgICog5Y+W5raI5oyJ6ZKu55qEIHByb3Bz77yM5Y+C6ICDIEJ1dHRvbiBQcm9wc1xuICAgKi9cbiAgY2FuY2VsUHJvcHM/OiBQYXJ0aWFsPElCdXR0b25Qcm9wcz5cbiAgLyoqXG4gICAqIOWPlua2iOaMiemSrueahCDmloflrZdcbiAgICovXG4gIGNhbmNlbFRleHQ/OiBzdHJpbmdcbiAgLyoqXG4gICAqIOWtkOiKgueCuVxuICAgKi9cbiAgY2hpbGRyZW4/OiBSZWFjdC5SZWFjdE5vZGVcbiAgLyoqXG4gICAqIOehruiupOaMiemSrueahCBwcm9wc++8jOWPguiAgyBCdXR0b24gUHJvcHNcbiAgICovXG4gIGNvbmZpcm1Qcm9wcz86IFBhcnRpYWw8SUJ1dHRvblByb3BzPlxuICAvKipcbiAgICog56Gu6K6k5oyJ6ZKu55qEIOaWh+Wtl1xuICAgKi9cbiAgY29uZmlybVRleHQ/OiBzdHJpbmdcbiAgLyoqXG4gICAqIOeCueWHu+WPlua2iOaMiemSruOAgeWPs+S4iuinkuWFs+mXreaXtueahCBoYW5kbGVyXG4gICAqL1xuICBvbkNhbmNlbD86ICgoKSA9PiB2b2lkKSB8IG51bGxcbiAgLyoqXG4gICAqIOeCueWHu+ehruiupOaMiemSruaXtueahCBoYW5kbGVyXG4gICAqL1xuICBvbkNvbmZpcm0/OiAoKCkgPT4gdm9pZCkgfCBudWxsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSURpYWxvZ1Byb3BzIGV4dGVuZHMgSVN0ZXBQcm9wcyB7XG4gIFtrZXk6IHN0cmluZ106IGFueVxuICAvKipcbiAgICog5YWz6Zet5ZCO77yIdHJhbnNpdGlvbiDnu5PmnZ/lkI7vvInnmoQgaGFuZGxlclxuICAgKi9cbiAgYWZ0ZXJDbG9zZT86ICgoKSA9PiB2b2lkKSB8IG51bGxcbiAgLyoqXG4gICAqIOiuvue9riBib2R5IGNsYXNzTmFtZVxuICAgKi9cbiAgYm9keUNsYXNzTmFtZT86IHN0cmluZ1xuICAvKipcbiAgICog6K6+572uIGJvZHkgc3R5bGVcbiAgICovXG4gIGJvZHlTdHlsZT86IFJlYWN0LkNTU1Byb3BlcnRpZXNcbiAgLyoqXG4gICAqIGRpYWxvZyDmiZPlvIDlkozlhbPpl63ml7bpg73kvJrmm7TmlLkgZG9jdW1lbnQuYm9keS5zdHlsZeOAguWPr+S7peS7peatpCBwcm9wIOaOp+WItuaYr+WQpuS/ruaUueOAguS9v+eUqOWcuuaZr+Wmgu+8mua1ruWxguWGheW8ueWHuiBkaWFsb2dcbiAgICovXG4gIGNoYW5nZUJvZHlTdHlsZT86IGJvb2xlYW5cbiAgLyoqXG4gICAqIOmZhOWKoOexu+WQje+8jOazqOaEjyBEaWFsb2cg5omA5pyJ55qE5bGe5oCn5Lya6ZmE5Yqg5Yiw5YaF6YOo55qE5YaF5a655YWD57Sg5LiK77yM6ICM5LiN5piv5YyF5ZCrIG1hc2sg55qE5pyA5aSW5bGC5YWD57SgXG4gICAqL1xuICBjbGFzc05hbWU/OiBzdHJpbmdcbiAgLyoqXG4gICAqIOaMh+WumuW9k+WJjeeahCBzdGVw77yM5LuF5Zyo5L2/55SoIHN0ZXBzIHByb3Ag5pe25pyJ5L2c55SoXG4gICAqL1xuICBjdXJyZW50U3RlcD86IG51bGwgfCBudW1iZXJcbiAgLyoqXG4gICAqIOaMh+Wumum7mOiupOeahOi1t+WniyBzdGVw77yM5LuF5Zyo5L2/55SoIHN0ZXBzIHByb3Ag5pe25pyJ5L2c55SoXG4gICAqL1xuICBkZWZhdWx0Q3VycmVudFN0ZXA/OiBudWxsIHwgbnVtYmVyXG4gIC8qKlxuICAgKiDlhoXpg6jpqbHliqjvvJrmmK/lkKbpu5jorqTmmL7npLpcbiAgICovXG4gIGRlZmF1bHRWaXNpYmxlPzogbnVsbCB8IGJvb2xlYW5cbiAgLyoqXG4gICAqIOaYr+WQpuavj+asoSB2aXNpYmxlOiBmYWxzZSDpg73plIDmr4EgZG9tXG4gICAqL1xuICBkZXN0cm95QWZ0ZXJDbG9zZT86IGJvb2xlYW5cbiAgLyoqXG4gICAqIOaYr+WQpuaUr+aMgSBFU0Mg5YWz6ZetXG4gICAqL1xuICBlc2NhcGVLZXlDbG9zYWJsZT86IGJvb2xlYW5cbiAgLyoqXG4gICAqIOWujOWFqOiHquWumuS5iSBmb290ZXIg55qE5YaF5a6577yM5aaC5p6c5oOz6KaB5pS55Y+YIGZvb3RlciDniLbnuqfnmoTmoLflvI/vvIzkvb/nlKggZm9vdGVyU3R5bGUgUHJvcFxuICAgKi9cbiAgZm9vdGVyRWxlbWVudD86IFJlYWN0LlJlYWN0Tm9kZVxuICAvKipcbiAgICog6K6+572uIGZvb3RlciBjbGFzc05hbWVcbiAgICovXG4gIGZvb3RlckNsYXNzTmFtZT86IHN0cmluZ1xuICAvKipcbiAgICog6K6+572uIGZvb3RlciBzdHlsZVxuICAgKi9cbiAgZm9vdGVyU3R5bGU/OiBSZWFjdC5DU1NQcm9wZXJ0aWVzXG4gIC8qKlxuICAgKiDmjIflrprlvLnlh7rlsYLnmoTniLbnuqfvvIzpu5jorqTkuLogZG9jdW1lbnQuYm9kee+8jOexu+S8vOS6jiBUb29sdGlwIOeahCBnZXRQb3B1cENvbnRhaW5lclxuICAgKi9cbiAgZ2V0Q29udGFpbmVyPzogKCkgPT4gSFRNTEVsZW1lbnRcbiAgLyoqXG4gICAqIGhlYWRlciDmoIfpopjkuIvnmoTlhoXlrrlcbiAgICovXG4gIGhlYWRlckNvbnRlbnQ/OiBSZWFjdC5SZWFjdE5vZGVcbiAgLyoqXG4gICAqIOWujOWFqOiHquWumuS5iSBoZWFkZXIg55qE5YaF5a65XG4gICAqL1xuICBoZWFkZXJFbGVtZW50PzogUmVhY3QuUmVhY3ROb2RlXG4gIC8qKlxuICAgKiDorr7nva4gaGVhZGVyIGNsYXNzTmFtZVxuICAgKi9cbiAgaGVhZGVyQ2xhc3NOYW1lPzogc3RyaW5nXG4gIC8qKlxuICAgKiDorr7nva4gaGVhZGVyIHN0eWxlXG4gICAqL1xuICBoZWFkZXJTdHlsZT86IFJlYWN0LkNTU1Byb3BlcnRpZXNcbiAgLyoqXG4gICAqIOeCueWHuyBtYXNrIOaYr+WQpuinpuWPkSBjYW5jZWwg5LqL5Lu2XG4gICAqL1xuICBtYXNrQ2xvc2FibGU/OiBib29sZWFuXG4gIC8qKlxuICAgKiDmjIflrprmraXpqqTvvIznlKjku6Xlv6vmjbfkuIrkuIDmraXjgIHkuIvkuIDmraXnmoTpnIDmsYLjgIJcbiAgICovXG4gIHN0ZXBzPzogQXJyYXk8SVN0ZXBQcm9wcz5cbiAgLyoqXG4gICAqIOmZhOWKoOagt+W8j++8jOazqOaEjyBEaWFsb2cg5omA5pyJ55qE5bGe5oCn5Lya6ZmE5Yqg5Yiw5YaF6YOo55qE5YaF5a655YWD57Sg5LiK77yM6ICM5LiN5piv5YyF5ZCrIG1hc2sg55qE5pyA5aSW5bGC5YWD57SgXG4gICAqL1xuICBzdHlsZT86IFJlYWN0LkNTU1Byb3BlcnRpZXNcbiAgLyoqXG4gICAqIOWvueivneahhuagh+mimFxuICAgKi9cbiAgdGl0bGU/OiBudWxsIHwgUmVhY3QuUmVhY3ROb2RlXG4gIC8qKlxuICAgKiBjb25maXJtIOS4uuWPlua2iOOAgeehruiupOaMiemSru+8m2luZm9ybSDkuLrlj6rmnInnoa7orqTmjInpkq5cbiAgICovXG4gIHR5cGU/OiBcImNvbmZpcm1cIiB8IFwiaW5mb3JtXCJcbiAgLyoqXG4gICAqIOWklumDqOaOp+WItu+8muaYr+WQpuaYvuekulxuICAgKi9cbiAgdmlzaWJsZT86IG51bGwgfCBib29sZWFuXG4gIC8qKlxuICAgKiDorr7nva4gei1pbmRleCDlsYLnuqfvvIzpu5jorqTkuLogdmFyKC0tei1pbmRleC1kaWFsb2cpXG4gICAqL1xuICB6SW5kZXg/OiBSZWFjdC5SZWFjdE5vZGVcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRGlhbG9nU3RhdGUge1xuICB2aXNpYmxlPzogYm9vbGVhblxuICBjdXJyZW50U3RlcDogbnVtYmVyXG4gIGhhc0V2ZXJPcGVuZWQ/OiBib29sZWFuXG59XG5cbi8qKlxuICog5a+56K+d5qGG55So5LqO5YWo5bGA5oCn55qE5Y+N6aaI77yM6YCa5bi45YiG5Li64oCc56Gu6K6k5pON5L2c4oCd5LiO4oCc5ZGK55+l5L+h5oGv4oCd44CCXG4gKiDnoa7orqTmk43kvZznlKjkuo7or6Lpl67nlKjmiLfigJzmk43kvZzmmK/lkKbnu6fnu63ov5vooYzvvJ/igJ3vvIzlpoLlpKfpg6jliIbnmoTkuozmrKHnoa7orqTlj43ppojjgILlkYrnn6Xkv6Hmga/liJnnlKjkuo7nn6XkvJrnlKjmiLfmn5DkuKrlj4rml7blj43ppojvvIzlpoLkv6Hmga/mj5DkuqTmiJDlip/jgIHlpLHotKXnrYnjgIJcbiAqL1xuY2xhc3MgRGlhbG9nIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50PElEaWFsb2dQcm9wcywgSURpYWxvZ1N0YXRlPiB7XG4gIHB1YmxpYyBzdGF0aWMgcHJvcFR5cGVzID0ge1xuICAgIC8qKlxuICAgICAqIOWFs+mXreWQju+8iHRyYW5zaXRpb24g57uT5p2f5ZCO77yJ55qEIGhhbmRsZXJcbiAgICAgKi9cbiAgICBhZnRlckNsb3NlOiBQcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiDorr7nva4gYm9keSBjbGFzc05hbWVcbiAgICAgKi9cbiAgICBib2R5Q2xhc3NOYW1lOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIOiuvue9riBib2R5IHN0eWxlXG4gICAgICovXG4gICAgYm9keVN0eWxlOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIOWPlua2iOaMiemSrueahCBwcm9wc++8jOWPguiAgyBCdXR0b24gUHJvcHNcbiAgICAgKi9cbiAgICBjYW5jZWxQcm9wczogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiDlj5bmtojmjInpkq7nmoQg5paH5a2XXG4gICAgICovXG4gICAgY2FuY2VsVGV4dDogUHJvcFR5cGVzLm5vZGUsXG4gICAgLyoqXG4gICAgICogZGlhbG9nIOaJk+W8gOWSjOWFs+mXreaXtumDveS8muabtOaUuSBkb2N1bWVudC5ib2R5LnN0eWxl44CC5Y+v5Lul5Lul5q2kIHByb3Ag5o6n5Yi25piv5ZCm5L+u5pS544CC5L2/55So5Zy65pmv5aaC77ya5rWu5bGC5YaF5by55Ye6IGRpYWxvZ1xuICAgICAqL1xuICAgIGNoYW5nZUJvZHlTdHlsZTogUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICog5a2Q6IqC54K5XG4gICAgICovXG4gICAgY2hpbGRyZW46IFByb3BUeXBlcy5ub2RlLFxuICAgIC8qKlxuICAgICAqIOmZhOWKoOexu+WQje+8jOazqOaEjyBEaWFsb2cg5omA5pyJ55qE5bGe5oCn5Lya6ZmE5Yqg5Yiw5YaF6YOo55qE5YaF5a655YWD57Sg5LiK77yM6ICM5LiN5piv5YyF5ZCrIG1hc2sg55qE5pyA5aSW5bGC5YWD57SgXG4gICAgICovXG4gICAgY2xhc3NOYW1lOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIOehruiupOaMiemSrueahCBwcm9wc++8jOWPguiAgyBCdXR0b24gUHJvcHNcbiAgICAgKi9cbiAgICBjb25maXJtUHJvcHM6IFByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICog56Gu6K6k5oyJ6ZKu55qEIOaWh+Wtl1xuICAgICAqL1xuICAgIGNvbmZpcm1UZXh0OiBQcm9wVHlwZXMubm9kZSxcbiAgICAvKipcbiAgICAgKiDmjIflrprlvZPliY3nmoQgc3RlcO+8jOS7heWcqOS9v+eUqCBzdGVwcyBwcm9wIOaXtuacieS9nOeUqFxuICAgICAqL1xuICAgIGN1cnJlbnRTdGVwOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgIC8qKlxuICAgICAqIOaMh+Wumum7mOiupOeahOi1t+WniyBzdGVw77yM5LuF5Zyo5L2/55SoIHN0ZXBzIHByb3Ag5pe25pyJ5L2c55SoXG4gICAgICovXG4gICAgZGVmYXVsdEN1cnJlbnRTdGVwOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgIC8qKlxuICAgICAqIOWGhemDqOmpseWKqO+8muaYr+WQpum7mOiupOaYvuekulxuICAgICAqL1xuICAgIGRlZmF1bHRWaXNpYmxlOiBQcm9wVHlwZXMuYm9vbCxcbiAgICAvKipcbiAgICAgKiDmmK/lkKbmr4/mrKEgdmlzaWJsZTogZmFsc2Ug6YO96ZSA5q+BIGRvbVxuICAgICAqL1xuICAgIGRlc3Ryb3lBZnRlckNsb3NlOiBQcm9wVHlwZXMuYm9vbCxcbiAgICAvKipcbiAgICAgKiDmmK/lkKbmlK/mjIEgRVNDIOWFs+mXrVxuICAgICAqL1xuICAgIGVzY2FwZUtleUNsb3NhYmxlOiBQcm9wVHlwZXMuYm9vbCxcbiAgICAvKipcbiAgICAgKiDlrozlhajoh6rlrprkuYkgZm9vdGVyIOeahOWGheWuue+8jOWmguaenOaDs+imgeaUueWPmCBmb290ZXIg54i257qn55qE5qC35byP77yM5L2/55SoIGZvb3RlclN0eWxlIFByb3BcbiAgICAgKi9cbiAgICBmb290ZXJFbGVtZW50OiBQcm9wVHlwZXMubm9kZSxcbiAgICAvKipcbiAgICAgKiDorr7nva4gZm9vdGVyIGNsYXNzTmFtZVxuICAgICAqL1xuICAgIGZvb3RlckNsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZyxcbiAgICAvKipcbiAgICAgKiDorr7nva4gZm9vdGVyIHN0eWxlXG4gICAgICovXG4gICAgZm9vdGVyU3R5bGU6IFByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICog5oyH5a6a5by55Ye65bGC55qE54i257qn77yM6buY6K6k5Li6IGRvY3VtZW50LmJvZHnvvIznsbvkvLzkuo4gVG9vbHRpcCDnmoQgZ2V0UG9wdXBDb250YWluZXJcbiAgICAgKi9cbiAgICBnZXRDb250YWluZXI6IFByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIGhlYWRlciDmoIfpopjkuIvnmoTlhoXlrrlcbiAgICAgKi9cbiAgICBoZWFkZXJDb250ZW50OiBQcm9wVHlwZXMubm9kZSxcbiAgICAvKipcbiAgICAgKiDlrozlhajoh6rlrprkuYkgaGVhZGVyIOeahOWGheWuuVxuICAgICAqL1xuICAgIGhlYWRlckVsZW1lbnQ6IFByb3BUeXBlcy5ub2RlLFxuICAgIC8qKlxuICAgICAqIOiuvue9riBoZWFkZXIgY2xhc3NOYW1lXG4gICAgICovXG4gICAgaGVhZGVyQ2xhc3NOYW1lOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIOiuvue9riBoZWFkZXIgc3R5bGVcbiAgICAgKi9cbiAgICBoZWFkZXJTdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiDngrnlh7sgbWFzayDmmK/lkKbop6blj5EgY2FuY2VsIOS6i+S7tlxuICAgICAqL1xuICAgIG1hc2tDbG9zYWJsZTogUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICog54K55Ye75Y+W5raI5oyJ6ZKu44CB5Y+z5LiK6KeS5YWz6Zet5pe255qEIGhhbmRsZXJcbiAgICAgKi9cbiAgICBvbkNhbmNlbDogUHJvcFR5cGVzLmZ1bmMsXG4gICAgLyoqXG4gICAgICog54K55Ye756Gu6K6k5oyJ6ZKu5pe255qEIGhhbmRsZXJcbiAgICAgKi9cbiAgICBvbkNvbmZpcm06IFByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIOmZhOWKoOagt+W8j++8jOazqOaEjyBEaWFsb2cg5omA5pyJ55qE5bGe5oCn5Lya6ZmE5Yqg5Yiw5YaF6YOo55qE5YaF5a655YWD57Sg5LiK77yM6ICM5LiN5piv5YyF5ZCrIG1hc2sg55qE5pyA5aSW5bGC5YWD57SgXG4gICAgICovXG4gICAgc3R5bGU6IFByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICog5a+56K+d5qGG5qCH6aKYXG4gICAgICovXG4gICAgdGl0bGU6IFByb3BUeXBlcy5ub2RlLFxuICAgIC8qKlxuICAgICAqIGNvbmZpcm0g5Li65Y+W5raI44CB56Gu6K6k5oyJ6ZKu77ybaW5mb3JtIOS4uuWPquacieehruiupOaMiemSrlxuICAgICAqL1xuICAgIHR5cGU6IFByb3BUeXBlcy5vbmVPZihbXCJjb25maXJtXCIsIFwiaW5mb3JtXCJdKSxcbiAgICAvKipcbiAgICAgKiDlpJbpg6jmjqfliLbvvJrmmK/lkKbmmL7npLpcbiAgICAgKi9cbiAgICB2aXNpYmxlOiBQcm9wVHlwZXMuYm9vbCxcbiAgICAvKipcbiAgICAgKiDorr7nva4gei1pbmRleCDlsYLnuqfvvIzpu5jorqTkuLogdmFyKC0tei1pbmRleC1kaWFsb2cpXG4gICAgICovXG4gICAgekluZGV4OiBQcm9wVHlwZXMuYW55LFxuICB9XG5cbiAgcHVibGljIHN0YXRpYyBkZWZhdWx0UHJvcHM6IElEaWFsb2dQcm9wcyA9IHtcbiAgICBhZnRlckNsb3NlOiBudWxsLFxuICAgIGJvZHlDbGFzc05hbWU6IFwiXCIsXG4gICAgYm9keVN0eWxlOiB7fSxcbiAgICBjYW5jZWxQcm9wczoge30sXG4gICAgY2FuY2VsVGV4dDogXCLlj5bmtohcIixcbiAgICBjaGFuZ2VCb2R5U3R5bGU6IHRydWUsXG4gICAgY2hpbGRyZW46IG51bGwsXG4gICAgY2xhc3NOYW1lOiB1bmRlZmluZWQsXG4gICAgY29uZmlybVByb3BzOiB7fSxcbiAgICBjb25maXJtVGV4dDogXCLnoa7orqRcIixcbiAgICBjdXJyZW50U3RlcDogbnVsbCxcbiAgICBkZWZhdWx0Q3VycmVudFN0ZXA6IG51bGwsXG4gICAgZGVmYXVsdFZpc2libGU6IG51bGwsXG4gICAgZGVzdHJveUFmdGVyQ2xvc2U6IGZhbHNlLFxuICAgIGVzY2FwZUtleUNsb3NhYmxlOiB0cnVlLFxuICAgIGZvb3RlckVsZW1lbnQ6IHVuZGVmaW5lZCxcbiAgICBmb290ZXJDbGFzc05hbWU6IFwiXCIsXG4gICAgZm9vdGVyU3R5bGU6IHt9LFxuICAgIGdldENvbnRhaW5lcjogdW5kZWZpbmVkLFxuICAgIGhlYWRlckNvbnRlbnQ6IG51bGwsXG4gICAgaGVhZGVyQ2xhc3NOYW1lOiBcIlwiLFxuICAgIGhlYWRlckVsZW1lbnQ6IHVuZGVmaW5lZCxcbiAgICBoZWFkZXJTdHlsZToge30sXG4gICAgbWFza0Nsb3NhYmxlOiBmYWxzZSxcbiAgICBvbkNhbmNlbDogbnVsbCxcbiAgICBvbkNvbmZpcm06IG51bGwsXG4gICAgc3R5bGU6IHt9LFxuICAgIHRpdGxlOiBudWxsLFxuICAgIHR5cGU6IFwiY29uZmlybVwiLFxuICAgIHZpc2libGU6IG51bGwsXG4gICAgekluZGV4OiBcInZhcigtLXotaW5kZXgtZGlhbG9nKVwiLFxuICB9XG5cbiAgcHVibGljIHN0YXRpYyBpbmZvOiBhbnlcblxuICBwdWJsaWMgc3RhdGljIHN1Y2Nlc3M6IGFueVxuXG4gIHB1YmxpYyBzdGF0aWMgd2FybmluZzogYW55XG5cbiAgcHVibGljIHN0YXRpYyBkYW5nZXI6IGFueVxuXG4gIHB1YmxpYyBzdGF0aWMgY29uZmlybTogYW55XG5cbiAgcHVibGljIHN0YXRpYyBpbmZvcm06IGFueVxuXG4gIHB1YmxpYyBzdGF0aWMgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID0gKFxuICAgIHsgY3VycmVudFN0ZXAsIHZpc2libGUgfTogSURpYWxvZ1Byb3BzLFxuICAgIHsgaGFzRXZlck9wZW5lZCB9OiBJRGlhbG9nU3RhdGVcbiAgKSA9PiB7XG4gICAgY29uc3QgbmV3U3RhdGU6IFBhcnRpYWw8SURpYWxvZ1N0YXRlPiA9IHt9XG4gICAgaWYgKGN1cnJlbnRTdGVwICE9PSBudWxsKSB7XG4gICAgICBuZXdTdGF0ZS5jdXJyZW50U3RlcCA9IGN1cnJlbnRTdGVwXG4gICAgfVxuICAgIGlmICh2aXNpYmxlICE9PSBudWxsKSB7XG4gICAgICBuZXdTdGF0ZS52aXNpYmxlID0gdmlzaWJsZVxuICAgICAgaWYgKCFoYXNFdmVyT3BlbmVkICYmIHZpc2libGUpIHtcbiAgICAgICAgbmV3U3RhdGUuaGFzRXZlck9wZW5lZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG5ld1N0YXRlKS5sZW5ndGggPiAwID8gbmV3U3RhdGUgOiBudWxsXG4gIH1cblxuICAvKipcbiAgICog5L+d5a2Y6IqC54K55oyC6L2955qE5a+56LGhXG4gICAqL1xuICBwdWJsaWMgY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGxcblxuICAvKipcbiAgICog5L+d5a2Y6aG16Z2i5piv5ZCmIG92ZXJmbG93XG4gICAqL1xuICBwdWJsaWMgYm9keUlzT3ZlcmZsb3dpbmc6IGJvb2xlYW5cblxuICAvKipcbiAgICog5L+d5a2Y5b2T5YmN5rWP6KeI5Zmo55qE5rua5Yqo5p2h5a695bqmXG4gICAqL1xuICBwdWJsaWMgc2Nyb2xsYmFyV2lkdGg6IG51bWJlclxuXG4gIHB1YmxpYyBkaWFsb2c6IEhUTUxEaXZFbGVtZW50XG5cbiAgcHVibGljIHdyYXBwZXI6IEhUTUxEaXZFbGVtZW50XG5cbiAgcHVibGljIGlzVW5tb3VudGVkOiBib29sZWFuID0gZmFsc2VcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogSURpYWxvZ1Byb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpXG4gICAgY29uc3QgeyBjdXJyZW50U3RlcCwgZGVmYXVsdEN1cnJlbnRTdGVwLCB2aXNpYmxlLCBkZWZhdWx0VmlzaWJsZSB9ID0gcHJvcHNcbiAgICBjb25zdCB2aXNpYmxlU3RhdGUgPSB2aXNpYmxlICE9PSBudWxsID8gISF2aXNpYmxlIDogISFkZWZhdWx0VmlzaWJsZVxuICAgIGNvbnN0IGN1cnJlbnRTdGVwU3RhdGUgPVxuICAgICAgY3VycmVudFN0ZXAgIT09IG51bGwgPyBjdXJyZW50U3RlcCA6IGRlZmF1bHRDdXJyZW50U3RlcFxuXG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIHZpc2libGU6IHZpc2libGVTdGF0ZSxcbiAgICAgIGN1cnJlbnRTdGVwOiBjdXJyZW50U3RlcFN0YXRlIHx8IDAsXG4gICAgICBoYXNFdmVyT3BlbmVkOiB2aXNpYmxlU3RhdGUsXG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNhdmVEaWFsb2cgPSAobm9kZTogSFRNTERpdkVsZW1lbnQpID0+IHtcbiAgICB0aGlzLmRpYWxvZyA9IG5vZGVcbiAgfVxuXG4gIHB1YmxpYyByZXNldFNjcm9sbGJhclBhZGRpbmcgPSAoKSA9PiB7XG4gICAgY29uc3QgeyBjaGFuZ2VCb2R5U3R5bGUgfSA9IHRoaXMucHJvcHNcbiAgICBpZiAoY2hhbmdlQm9keVN0eWxlKSB7XG4gICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gXCJcIlxuICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSBcIlwiXG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNldFNjcm9sbGJhclBhZGRpbmcgPSAoKSA9PiB7XG4gICAgY29uc3QgeyBjaGFuZ2VCb2R5U3R5bGUgfSA9IHRoaXMucHJvcHNcbiAgICBpZiAoY2hhbmdlQm9keVN0eWxlKSB7XG4gICAgICBjb25zdCB7IGlubmVyV2lkdGggfSA9IHdpbmRvd1xuICAgICAgdGhpcy5ib2R5SXNPdmVyZmxvd2luZyA9IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGggPCBpbm5lcldpZHRoXG4gICAgICBpZiAodGhpcy5ib2R5SXNPdmVyZmxvd2luZyAmJiAhZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxiYXJXaWR0aCA9IGdldFNjcm9sbEJhclNpemUoKVxuICAgICAgICBpZiAodGhpcy5zY3JvbGxiYXJXaWR0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSBgJHt0aGlzLnNjcm9sbGJhcldpZHRofXB4YFxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIlxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRDYW5jZWxCdXR0b24gPSAoKSA9PiB7XG4gICAgY29uc3QgeyBjYW5jZWxQcm9wcywgY2FuY2VsVGV4dCwgc3RlcHMsIHR5cGUgfSA9IHRoaXMucHJvcHNcbiAgICBjb25zdCB7IGN1cnJlbnRTdGVwIH0gPSB0aGlzLnN0YXRlXG4gICAgY29uc3QgZGVmYXVsdFRleHQgPSBjdXJyZW50U3RlcCA9PT0gMCA/IFwi5Y+W5raIXCIgOiBcIuS4iuS4gOatpVwiXG4gICAgY29uc3QgZ2VuZXJhdGVCdXR0b24gPSAocHJvcHM/OiBJQnV0dG9uUHJvcHMsIHRleHQgPSBkZWZhdWx0VGV4dCkgPT4gKFxuICAgICAgPEJ1dHRvbiBrZXk9XCJjYW5jZWxcIiB0aGVtZT1cImxpZ2h0XCIgb25DbGljaz17dGhpcy5oYW5kbGVDYW5jZWx9IHsuLi5wcm9wc30+XG4gICAgICAgIHt0ZXh0fVxuICAgICAgPC9CdXR0b24+XG4gICAgKVxuXG4gICAgaWYgKHN0ZXBzICYmIHN0ZXBzLmxlbmd0aCkge1xuICAgICAgY29uc3QgcHJvcHMgPSBzdGVwc1tjdXJyZW50U3RlcF0uY2FuY2VsUHJvcHNcbiAgICAgIGNvbnN0IHRleHQgPSBzdGVwc1tjdXJyZW50U3RlcF0uY2FuY2VsVGV4dFxuICAgICAgcmV0dXJuIGdlbmVyYXRlQnV0dG9uKHByb3BzLCB0ZXh0KVxuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gXCJpbmZvcm1cIikge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gICAgcmV0dXJuIGdlbmVyYXRlQnV0dG9uKGNhbmNlbFByb3BzLCBjYW5jZWxUZXh0KVxuICB9XG5cbiAgcHVibGljIGdldENvbmZpcm1CdXR0b24gPSAoKSA9PiB7XG4gICAgY29uc3QgeyBjb25maXJtUHJvcHMsIGNvbmZpcm1UZXh0LCBzdGVwcyB9ID0gdGhpcy5wcm9wc1xuICAgIGNvbnN0IHsgY3VycmVudFN0ZXAgfSA9IHRoaXMuc3RhdGVcbiAgICBjb25zdCBnZW5lcmF0ZUJ1dHRvbiA9IChwcm9wcz86IElCdXR0b25Qcm9wcywgdGV4dD86IHN0cmluZykgPT4gKFxuICAgICAgPEJ1dHRvblxuICAgICAgICBrZXk9XCJwcmltYXJ5XCJcbiAgICAgICAgaW50ZW50PVwicHJpbWFyeVwiXG4gICAgICAgIG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ29uZmlybX1cbiAgICAgICAgey4uLnByb3BzfVxuICAgICAgPlxuICAgICAgICB7dGV4dH1cbiAgICAgIDwvQnV0dG9uPlxuICAgIClcblxuICAgIGlmIChzdGVwcyAmJiBzdGVwcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHByb3BzID0gc3RlcHNbY3VycmVudFN0ZXBdLmNvbmZpcm1Qcm9wc1xuICAgICAgY29uc3QgdGV4dCA9XG4gICAgICAgIHN0ZXBzW2N1cnJlbnRTdGVwXS5jb25maXJtVGV4dCB8fFxuICAgICAgICAoY3VycmVudFN0ZXAgPT09IHN0ZXBzLmxlbmd0aCAtIDEgPyBcIuWujOaIkFwiIDogXCLkuIvkuIDmraVcIilcbiAgICAgIHJldHVybiBnZW5lcmF0ZUJ1dHRvbihwcm9wcywgdGV4dClcbiAgICB9XG4gICAgcmV0dXJuIGdlbmVyYXRlQnV0dG9uKGNvbmZpcm1Qcm9wcywgY29uZmlybVRleHQgfHwgXCLnoa7orqRcIilcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVLZXlEb3duID0gKGU6IFJlYWN0LktleWJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCB7IGVzY2FwZUtleUNsb3NhYmxlIH0gPSB0aGlzLnByb3BzXG4gICAgaWYgKGVzY2FwZUtleUNsb3NhYmxlICYmIGUua2V5ID09PSBcIkVzY2FwZVwiKSB7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICB0aGlzLmhhbmRsZUNhbmNlbCgpXG4gICAgfVxuICB9XG5cbiAgcHVibGljIGhhbmRsZUNhbmNlbCA9ICh0eXBlPzogYW55KSA9PiB7XG4gICAgY29uc3QgeyBvbkNhbmNlbCwgc3RlcHMsIHZpc2libGUgfSA9IHRoaXMucHJvcHNcbiAgICBjb25zdCB7IGN1cnJlbnRTdGVwIH0gPSB0aGlzLnN0YXRlXG4gICAgaWYgKHR5cGUgPT09IFwiY2xvc2VcIiB8fCAhc3RlcHMgfHwgIXN0ZXBzLmxlbmd0aCkge1xuICAgICAgaWYgKHZpc2libGUgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpc2libGU6IGZhbHNlIH0pXG4gICAgICB9XG4gICAgICBpZiAob25DYW5jZWwpIHtcbiAgICAgICAgb25DYW5jZWwoKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IG9uQ2FuY2VsOiBvblN0ZXBDYW5jZWwgfSA9IHN0ZXBzW2N1cnJlbnRTdGVwXVxuICAgICAgaWYgKG9uU3RlcENhbmNlbCkge1xuICAgICAgICBvblN0ZXBDYW5jZWwoKVxuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRTdGVwID09PSAwKSB7XG4gICAgICAgIGlmICh2aXNpYmxlID09PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpc2libGU6IGZhbHNlIH0pXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjdXJyZW50U3RlcDogY3VycmVudFN0ZXAgLSAxIH0pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGhhbmRsZUNvbmZpcm0gPSAoKSA9PiB7XG4gICAgY29uc3QgeyBvbkNvbmZpcm0sIHN0ZXBzLCB2aXNpYmxlIH0gPSB0aGlzLnByb3BzXG4gICAgY29uc3QgeyBjdXJyZW50U3RlcCB9ID0gdGhpcy5zdGF0ZVxuICAgIGlmIChzdGVwcyAmJiBzdGVwcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHsgb25Db25maXJtOiBvblN0ZXBDb25maXJtIH0gPSBzdGVwc1tjdXJyZW50U3RlcF1cbiAgICAgIGlmIChvblN0ZXBDb25maXJtKSB7XG4gICAgICAgIG9uU3RlcENvbmZpcm0oKVxuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRTdGVwID09PSBzdGVwcy5sZW5ndGggLSAxKSB7XG4gICAgICAgIGlmICh2aXNpYmxlID09PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpc2libGU6IGZhbHNlIH0pXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjdXJyZW50U3RlcDogY3VycmVudFN0ZXAgKyAxIH0pXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh2aXNpYmxlID09PSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyB2aXNpYmxlOiBmYWxzZSB9KVxuICAgICAgfVxuICAgICAgaWYgKG9uQ29uZmlybSkge1xuICAgICAgICBvbkNvbmZpcm0oKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvbkxlYXZlID0gKCkgPT4ge1xuICAgIGNvbnN0IHsgYWZ0ZXJDbG9zZSwgZGVzdHJveUFmdGVyQ2xvc2UgfSA9IHRoaXMucHJvcHNcbiAgICBpZiAodGhpcy53cmFwcGVyKSB7XG4gICAgICB0aGlzLndyYXBwZXIuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiXG4gICAgfVxuICAgIHRoaXMucmVzZXRTY3JvbGxiYXJQYWRkaW5nKClcblxuICAgIGlmIChhZnRlckNsb3NlKSB7XG4gICAgICBhZnRlckNsb3NlKClcbiAgICB9XG5cbiAgICBpZiAoZGVzdHJveUFmdGVyQ2xvc2UgJiYgIXRoaXMuaXNVbm1vdW50ZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBoYXNFdmVyT3BlbmVkOiBmYWxzZSB9KVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVFbnRlciA9ICgpID0+IHtcbiAgICBjb25zdCB7IGVzY2FwZUtleUNsb3NhYmxlIH0gPSB0aGlzLnByb3BzXG4gICAgaWYgKHRoaXMud3JhcHBlcikge1xuICAgICAgaWYgKGVzY2FwZUtleUNsb3NhYmxlKSB7XG4gICAgICAgIHRoaXMud3JhcHBlci5mb2N1cygpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldENvbXBvbmVudCA9IChvcHRpb25zPzogeyB2aXNpYmxlOiBib29sZWFuIH0pID0+IHtcbiAgICBjb25zdCB7XG4gICAgICBib2R5Q2xhc3NOYW1lLFxuICAgICAgYm9keVN0eWxlLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBkZXN0cm95QWZ0ZXJDbG9zZSxcbiAgICAgIGZvb3RlckNsYXNzTmFtZSxcbiAgICAgIGZvb3RlckVsZW1lbnQsXG4gICAgICBmb290ZXJTdHlsZSxcbiAgICAgIGhlYWRlckNsYXNzTmFtZSxcbiAgICAgIGhlYWRlckNvbnRlbnQsXG4gICAgICBoZWFkZXJFbGVtZW50LFxuICAgICAgaGVhZGVyU3R5bGUsXG4gICAgICBtYXNrQ2xvc2FibGUsXG4gICAgICBzdGVwcyxcbiAgICAgIHN0eWxlLFxuICAgICAgdGl0bGUsXG4gICAgICB6SW5kZXg6IHpJbmRleFByb3AsXG4gICAgICAuLi5vdGhlclByb3BzXG4gICAgfSA9IHRoaXMucHJvcHNcblxuICAgIGNvbnN0IHpJbmRleCA9IHpJbmRleFByb3AgYXMgUmVhY3QuQ1NTUHJvcGVydGllc1tcInpJbmRleFwiXVxuXG4gICAgY29uc3QgcmVzdFByb3BzID0gb21pdChvdGhlclByb3BzLCBbXG4gICAgICBcImFmdGVyQ2xvc2VcIixcbiAgICAgIFwiY2FuY2VsUHJvcHNcIixcbiAgICAgIFwiY2FuY2VsVGV4dFwiLFxuICAgICAgXCJjaGFuZ2VCb2R5U3R5bGVcIixcbiAgICAgIFwiY29uZmlybVByb3BzXCIsXG4gICAgICBcImNvbmZpcm1UZXh0XCIsXG4gICAgICBcImN1cnJlbnRTdGVwXCIsXG4gICAgICBcImRlZmF1bHRDdXJyZW50U3RlcFwiLFxuICAgICAgXCJkZWZhdWx0VmlzaWJsZVwiLFxuICAgICAgXCJlc2NhcGVLZXlDbG9zYWJsZVwiLFxuICAgICAgXCJnZXRDb250YWluZXJcIixcbiAgICAgIFwib25DYW5jZWxcIixcbiAgICAgIFwib25Db25maXJtXCIsXG4gICAgICBcInR5cGVcIixcbiAgICAgIFwidmlzaWJsZVwiLFxuICAgIF0pXG5cbiAgICBjb25zdCBjbGFzc1NldCA9IGNsYXNzTmFtZXMoY2xhc3NOYW1lLCBgJHtwcmVmaXh9LWlubmVyYClcbiAgICBjb25zdCB7IGN1cnJlbnRTdGVwIH0gPSB0aGlzLnN0YXRlXG4gICAgbGV0IHsgdmlzaWJsZSB9ID0gdGhpcy5zdGF0ZVxuICAgIGlmIChvcHRpb25zICYmIE9iamVjdC5rZXlzKG9wdGlvbnMpLmluY2x1ZGVzKFwidmlzaWJsZVwiKSkge1xuICAgICAgOyh7IHZpc2libGUgfSA9IG9wdGlvbnMpXG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgcmVmPXt0aGlzLnNhdmVEaWFsb2d9PlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3NOYW1lPXtgJHtwcmVmaXh9LXdyYXBwZXJgfVxuICAgICAgICAgIHJlZj17KHdyYXBwZXIpID0+IHtcbiAgICAgICAgICAgIGlmICh3cmFwcGVyKSB7XG4gICAgICAgICAgICAgIHRoaXMud3JhcHBlciA9IHdyYXBwZXJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9fVxuICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICBkaXNwbGF5OiB2aXNpYmxlID8gXCJmbGV4XCIgOiBcIlwiLFxuICAgICAgICAgICAgekluZGV4LFxuICAgICAgICAgIH19XG4gICAgICAgICAgdGFiSW5kZXg9ezB9XG4gICAgICAgICAgcm9sZT1cIm5vbmVcIlxuICAgICAgICAgIG9uS2V5RG93bj17dGhpcy5oYW5kbGVLZXlEb3dufVxuICAgICAgICA+XG4gICAgICAgICAgPENTU01vdGlvblxuICAgICAgICAgICAgbW90aW9uTmFtZT17YCR7cHJlZml4fS1tYXNrYH1cbiAgICAgICAgICAgIHZpc2libGU9e3Zpc2libGV9XG4gICAgICAgICAgICByZW1vdmVPbkxlYXZlPXtkZXN0cm95QWZ0ZXJDbG9zZX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICB7KHsgY2xhc3NOYW1lOiBjbHMgfSwgcmVmKSA9PiAoXG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICByZWY9e3JlZn1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZXMoYCR7cHJlZml4fS1tYXNrYCwgY2xzKX1cbiAgICAgICAgICAgICAgICByb2xlPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKG1hc2tDbG9zYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUNhbmNlbChcImNsb3NlXCIpXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgPC9DU1NNb3Rpb24+XG4gICAgICAgICAgey8qKlxuICAgICAgICAgICAqIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zMzQ1NTM0MlxuICAgICAgICAgICAqIDEuIOacgOWkluWxgiBtYXJnaW46IGF1dG8g6Z2e5bi46YeN6KaB44CCXG4gICAgICAgICAgICogRGlhbG9nIOeahOWuveW6puaYr+iHqumAguW6lOeahO+8jOWboOatpOS9v+eUqOS6hiBkaXNwbGF5OiBmbGV4IOWkhOeQhuWxheS4re+8jOi/meS9v+W+l+WtkOWFg+e0oOWFt+acieWMheijueaAp++8jOWboOatpOWuveW6puaJjeiDveeUseWGheWuueaJgOWGs+Wumu+8m1xuICAgICAgICAgICAqIG1hcmdpbjogYXV0bzsg5piv5Li65LqG5a6M5ZaEIGZsZXhib3ggb3ZlcmZsb3cg55qE5qC35byP44CCXG4gICAgICAgICAgICogMi4gekluZGV4OiAxIOaYr+S4uuS6huimhuebluWcqCBtYXNrIOS4iuOAglxuICAgICAgICAgICAqL31cbiAgICAgICAgICA8Q1NTTW90aW9uXG4gICAgICAgICAgICBvbkFwcGVhclN0YXJ0PXt0aGlzLmhhbmRsZUVudGVyfVxuICAgICAgICAgICAgb25FbnRlclN0YXJ0PXt0aGlzLmhhbmRsZUVudGVyfVxuICAgICAgICAgICAgb25MZWF2ZUVuZD17dGhpcy5vbkxlYXZlfVxuICAgICAgICAgICAgbW90aW9uTmFtZT17cHJlZml4fVxuICAgICAgICAgICAgdmlzaWJsZT17dmlzaWJsZX1cbiAgICAgICAgICAgIHJlbW92ZU9uTGVhdmU9e2Rlc3Ryb3lBZnRlckNsb3NlfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIHsoeyBjbGFzc05hbWU6IGNscyB9LCByZWYpID0+IChcbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIHJlZj17cmVmfVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhjbGFzc1NldCwgY2xzKX1cbiAgICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgICAgbWFyZ2luOiBcImF1dG9cIixcbiAgICAgICAgICAgICAgICAgIHpJbmRleDogMSxcbiAgICAgICAgICAgICAgICAgIC4uLnN0eWxlLFxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgey4uLnJlc3RQcm9wc31cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHtoZWFkZXJFbGVtZW50ID09PSBudWxsXG4gICAgICAgICAgICAgICAgICA/IG51bGxcbiAgICAgICAgICAgICAgICAgIDogaGVhZGVyRWxlbWVudCB8fCAoXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtgJHtwcmVmaXh9LWhlYWRlciAke2hlYWRlckNsYXNzTmFtZX1gfVxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9e2hlYWRlclN0eWxlfVxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtbXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYga2V5PXswfSBjbGFzc05hbWU9e2Ake3ByZWZpeH0tdGl0bGVgfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dGl0bGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBrZXk9ezF9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtoZWFkZXJDb250ZW50ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtgJHtwcmVmaXh9LWhlYWRlckNvbnRlbnRgfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2hlYWRlckNvbnRlbnR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxJY29uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5PXsyfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17YCR7cHJlZml4fS1jbG9zZWB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT17MjR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cImNhbmNlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4gdGhpcy5oYW5kbGVDYW5jZWwoXCJjbG9zZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgLz4sXG4gICAgICAgICAgICAgICAgICAgICAgICBdfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17YCR7cHJlZml4fS1ib2R5ICR7Ym9keUNsYXNzTmFtZX1gfVxuICAgICAgICAgICAgICAgICAgc3R5bGU9e2JvZHlTd