matrix-react-sdk
Version:
SDK for matrix.org using React
338 lines (335 loc) • 62.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _SdkConfig = _interopRequireDefault(require("../../../SdkConfig"));
var _Validation = _interopRequireDefault(require("../elements/Validation"));
var _languageHandler = require("../../../languageHandler");
var _MatrixClientPeg = require("../../../MatrixClientPeg");
var _createRoom = require("../../../createRoom");
var _Field = _interopRequireDefault(require("../elements/Field"));
var _RoomAliasField = _interopRequireDefault(require("../elements/RoomAliasField"));
var _LabelledToggleSwitch = _interopRequireDefault(require("../elements/LabelledToggleSwitch"));
var _DialogButtons = _interopRequireDefault(require("../elements/DialogButtons"));
var _BaseDialog = _interopRequireDefault(require("../dialogs/BaseDialog"));
var _JoinRuleDropdown = _interopRequireDefault(require("../elements/JoinRuleDropdown"));
var _KeyBindingsManager = require("../../../KeyBindingsManager");
var _KeyboardShortcuts = require("../../../accessibility/KeyboardShortcuts");
var _rooms = require("../../../utils/rooms");
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
var _LabelledCheckbox = _interopRequireDefault(require("../elements/LabelledCheckbox"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/*
Copyright 2024 New Vector Ltd.
Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
class CreateRoomDialog extends _react.default.Component {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "askToJoinEnabled", void 0);
(0, _defineProperty2.default)(this, "supportsRestricted", void 0);
(0, _defineProperty2.default)(this, "nameField", /*#__PURE__*/(0, _react.createRef)());
(0, _defineProperty2.default)(this, "aliasField", /*#__PURE__*/(0, _react.createRef)());
(0, _defineProperty2.default)(this, "onKeyDown", event => {
const action = (0, _KeyBindingsManager.getKeyBindingsManager)().getAccessibilityAction(event);
switch (action) {
case _KeyboardShortcuts.KeyBindingAction.Enter:
this.onOk();
event.preventDefault();
event.stopPropagation();
break;
}
});
(0, _defineProperty2.default)(this, "onOk", async () => {
if (!this.nameField.current) return;
const activeElement = document.activeElement;
activeElement?.blur();
await this.nameField.current.validate({
allowEmpty: false
});
if (this.aliasField.current) {
await this.aliasField.current.validate({
allowEmpty: false
});
}
// Validation and state updates are async, so we need to wait for them to complete
// first. Queue a `setState` callback and wait for it to resolve.
await new Promise(resolve => this.setState({}, resolve));
if (this.state.nameIsValid && (!this.aliasField.current || this.aliasField.current.isValid)) {
this.props.onFinished(true, this.roomCreateOptions());
} else {
let field = null;
if (!this.state.nameIsValid) {
field = this.nameField.current;
} else if (this.aliasField.current && !this.aliasField.current.isValid) {
field = this.aliasField.current;
}
if (field) {
field.focus();
await field.validate({
allowEmpty: false,
focused: true
});
}
}
});
(0, _defineProperty2.default)(this, "onCancel", () => {
this.props.onFinished(false);
});
(0, _defineProperty2.default)(this, "onNameChange", ev => {
this.setState({
name: ev.target.value
});
});
(0, _defineProperty2.default)(this, "onTopicChange", ev => {
this.setState({
topic: ev.target.value
});
});
(0, _defineProperty2.default)(this, "onJoinRuleChange", joinRule => {
this.setState({
joinRule
});
});
(0, _defineProperty2.default)(this, "onEncryptedChange", isEncrypted => {
this.setState({
isEncrypted
});
});
(0, _defineProperty2.default)(this, "onAliasChange", alias => {
this.setState({
alias
});
});
(0, _defineProperty2.default)(this, "onDetailsToggled", ev => {
this.setState({
detailsOpen: ev.target.open
});
});
(0, _defineProperty2.default)(this, "onNoFederateChange", noFederate => {
this.setState({
noFederate
});
});
(0, _defineProperty2.default)(this, "onNameValidate", async fieldState => {
const result = await CreateRoomDialog.validateRoomName(fieldState);
this.setState({
nameIsValid: !!result.valid
});
return result;
});
(0, _defineProperty2.default)(this, "onIsPublicKnockRoomChange", isPublicKnockRoom => {
this.setState({
isPublicKnockRoom
});
});
this.askToJoinEnabled = _SettingsStore.default.getValue("feature_ask_to_join");
this.supportsRestricted = !!this.props.parentSpace;
let _joinRule = _matrix.JoinRule.Invite;
if (this.props.defaultPublic) {
_joinRule = _matrix.JoinRule.Public;
} else if (this.supportsRestricted) {
_joinRule = _matrix.JoinRule.Restricted;
}
const cli = _MatrixClientPeg.MatrixClientPeg.safeGet();
this.state = {
isPublicKnockRoom: this.props.defaultPublic || false,
isEncrypted: this.props.defaultEncrypted ?? (0, _rooms.privateShouldBeEncrypted)(cli),
joinRule: _joinRule,
name: this.props.defaultName || "",
topic: "",
alias: "",
detailsOpen: false,
noFederate: _SdkConfig.default.get().default_federate === false,
nameIsValid: false,
canChangeEncryption: false
};
(0, _createRoom.checkUserIsAllowedToChangeEncryption)(cli, _matrix.Preset.PrivateChat).then(({
allowChange,
forcedValue
}) => this.setState(state => ({
canChangeEncryption: allowChange,
// override with forcedValue if it is set
isEncrypted: forcedValue ?? state.isEncrypted
})));
}
roomCreateOptions() {
const opts = {};
const createOpts = opts.createOpts = {};
opts.roomType = this.props.type;
createOpts.name = this.state.name;
if (this.state.joinRule === _matrix.JoinRule.Public) {
createOpts.visibility = _matrix.Visibility.Public;
createOpts.preset = _matrix.Preset.PublicChat;
opts.guestAccess = false;
const {
alias
} = this.state;
createOpts.room_alias_name = alias.substring(1, alias.indexOf(":"));
} else {
opts.encryption = this.state.isEncrypted;
}
if (this.state.topic) {
createOpts.topic = this.state.topic;
}
if (this.state.noFederate) {
createOpts.creation_content = {
"m.federate": false
};
}
opts.parentSpace = this.props.parentSpace;
if (this.props.parentSpace && this.state.joinRule === _matrix.JoinRule.Restricted) {
opts.joinRule = _matrix.JoinRule.Restricted;
}
if (this.state.joinRule === _matrix.JoinRule.Knock) {
opts.joinRule = _matrix.JoinRule.Knock;
createOpts.visibility = this.state.isPublicKnockRoom ? _matrix.Visibility.Public : _matrix.Visibility.Private;
}
return opts;
}
componentDidMount() {
// move focus to first field when showing dialog
this.nameField.current?.focus();
}
render() {
const isVideoRoom = this.props.type === _matrix.RoomType.ElementVideo;
let aliasField;
if (this.state.joinRule === _matrix.JoinRule.Public) {
const domain = _MatrixClientPeg.MatrixClientPeg.safeGet().getDomain();
aliasField = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CreateRoomDialog_aliasContainer"
}, /*#__PURE__*/_react.default.createElement(_RoomAliasField.default, {
ref: this.aliasField,
onChange: this.onAliasChange,
domain: domain,
value: this.state.alias
}));
}
let publicPrivateLabel;
if (this.state.joinRule === _matrix.JoinRule.Restricted) {
publicPrivateLabel = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("create_room|join_rule_restricted_label", {}, {
SpaceName: () => /*#__PURE__*/_react.default.createElement("strong", null, this.props.parentSpace?.name ?? (0, _languageHandler._t)("common|unnamed_space"))
}), "\xA0", (0, _languageHandler._t)("create_room|join_rule_change_notice"));
} else if (this.state.joinRule === _matrix.JoinRule.Public && this.props.parentSpace) {
publicPrivateLabel = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("create_room|join_rule_public_parent_space_label", {}, {
SpaceName: () => /*#__PURE__*/_react.default.createElement("strong", null, this.props.parentSpace?.name ?? (0, _languageHandler._t)("common|unnamed_space"))
}), "\xA0", (0, _languageHandler._t)("create_room|join_rule_change_notice"));
} else if (this.state.joinRule === _matrix.JoinRule.Public) {
publicPrivateLabel = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("create_room|join_rule_public_label"), "\xA0", (0, _languageHandler._t)("create_room|join_rule_change_notice"));
} else if (this.state.joinRule === _matrix.JoinRule.Invite) {
publicPrivateLabel = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("create_room|join_rule_invite_label"), "\xA0", (0, _languageHandler._t)("create_room|join_rule_change_notice"));
} else if (this.state.joinRule === _matrix.JoinRule.Knock) {
publicPrivateLabel = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("create_room|join_rule_knock_label"));
}
let visibilitySection;
if (this.state.joinRule === _matrix.JoinRule.Knock) {
visibilitySection = /*#__PURE__*/_react.default.createElement(_LabelledCheckbox.default, {
className: "mx_CreateRoomDialog_labelledCheckbox",
label: (0, _languageHandler._t)("room_settings|security|publish_room"),
onChange: this.onIsPublicKnockRoomChange,
value: this.state.isPublicKnockRoom
});
}
let e2eeSection;
if (this.state.joinRule !== _matrix.JoinRule.Public) {
let microcopy;
if ((0, _rooms.privateShouldBeEncrypted)(_MatrixClientPeg.MatrixClientPeg.safeGet())) {
if (this.state.canChangeEncryption) {
microcopy = isVideoRoom ? (0, _languageHandler._t)("create_room|encrypted_video_room_warning") : (0, _languageHandler._t)("create_room|encrypted_warning");
} else {
microcopy = (0, _languageHandler._t)("create_room|encryption_forced");
}
} else {
microcopy = (0, _languageHandler._t)("settings|security|e2ee_default_disabled_warning");
}
e2eeSection = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_LabelledToggleSwitch.default, {
label: (0, _languageHandler._t)("create_room|encryption_label"),
onChange: this.onEncryptedChange,
value: this.state.isEncrypted,
className: "mx_CreateRoomDialog_e2eSwitch" // for end-to-end tests
,
disabled: !this.state.canChangeEncryption
}), /*#__PURE__*/_react.default.createElement("p", null, microcopy));
}
let federateLabel = (0, _languageHandler._t)("create_room|unfederated_label_default_off");
if (_SdkConfig.default.get().default_federate === false) {
// We only change the label if the default setting is different to avoid jarring text changes to the
// user. They will have read the implications of turning this off/on, so no need to rephrase for them.
federateLabel = (0, _languageHandler._t)("create_room|unfederated_label_default_on");
}
let title;
if (isVideoRoom) {
title = (0, _languageHandler._t)("create_room|title_video_room");
} else if (this.props.parentSpace || this.state.joinRule === _matrix.JoinRule.Knock) {
title = (0, _languageHandler._t)("action|create_a_room");
} else {
title = this.state.joinRule === _matrix.JoinRule.Public ? (0, _languageHandler._t)("create_room|title_public_room") : (0, _languageHandler._t)("create_room|title_private_room");
}
return /*#__PURE__*/_react.default.createElement(_BaseDialog.default, {
className: "mx_CreateRoomDialog",
onFinished: this.props.onFinished,
title: title,
screenName: "CreateRoom"
}, /*#__PURE__*/_react.default.createElement("form", {
onSubmit: this.onOk,
onKeyDown: this.onKeyDown
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dialog_content"
}, /*#__PURE__*/_react.default.createElement(_Field.default, {
ref: this.nameField,
label: (0, _languageHandler._t)("common|name"),
onChange: this.onNameChange,
onValidate: this.onNameValidate,
value: this.state.name,
className: "mx_CreateRoomDialog_name"
}), /*#__PURE__*/_react.default.createElement(_Field.default, {
label: (0, _languageHandler._t)("create_room|topic_label"),
onChange: this.onTopicChange,
value: this.state.topic,
className: "mx_CreateRoomDialog_topic"
}), /*#__PURE__*/_react.default.createElement(_JoinRuleDropdown.default, {
label: (0, _languageHandler._t)("create_room|room_visibility_label"),
labelInvite: (0, _languageHandler._t)("create_room|join_rule_invite"),
labelKnock: this.askToJoinEnabled ? (0, _languageHandler._t)("room_settings|security|join_rule_knock") : undefined,
labelPublic: (0, _languageHandler._t)("common|public_room"),
labelRestricted: this.supportsRestricted ? (0, _languageHandler._t)("create_room|join_rule_restricted") : undefined,
value: this.state.joinRule,
onChange: this.onJoinRuleChange
}), publicPrivateLabel, visibilitySection, e2eeSection, aliasField, /*#__PURE__*/_react.default.createElement("details", {
onToggle: this.onDetailsToggled,
className: "mx_CreateRoomDialog_details"
}, /*#__PURE__*/_react.default.createElement("summary", {
className: "mx_CreateRoomDialog_details_summary"
}, this.state.detailsOpen ? (0, _languageHandler._t)("action|hide_advanced") : (0, _languageHandler._t)("action|show_advanced")), /*#__PURE__*/_react.default.createElement(_LabelledToggleSwitch.default, {
label: (0, _languageHandler._t)("create_room|unfederated", {
serverName: _MatrixClientPeg.MatrixClientPeg.safeGet().getDomain()
}),
onChange: this.onNoFederateChange,
value: this.state.noFederate
}), /*#__PURE__*/_react.default.createElement("p", null, federateLabel)))), /*#__PURE__*/_react.default.createElement(_DialogButtons.default, {
primaryButton: isVideoRoom ? (0, _languageHandler._t)("create_room|action_create_video_room") : (0, _languageHandler._t)("create_room|action_create_room"),
onPrimaryButtonClick: this.onOk,
onCancel: this.onCancel
}));
}
}
exports.default = CreateRoomDialog;
(0, _defineProperty2.default)(CreateRoomDialog, "validateRoomName", (0, _Validation.default)({
rules: [{
key: "required",
test: async ({
value
}) => !!value,
invalid: () => (0, _languageHandler._t)("create_room|name_validation_required")
}]
}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfbWF0cml4IiwiX1Nka0NvbmZpZyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfVmFsaWRhdGlvbiIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfTWF0cml4Q2xpZW50UGVnIiwiX2NyZWF0ZVJvb20iLCJfRmllbGQiLCJfUm9vbUFsaWFzRmllbGQiLCJfTGFiZWxsZWRUb2dnbGVTd2l0Y2giLCJfRGlhbG9nQnV0dG9ucyIsIl9CYXNlRGlhbG9nIiwiX0pvaW5SdWxlRHJvcGRvd24iLCJfS2V5QmluZGluZ3NNYW5hZ2VyIiwiX0tleWJvYXJkU2hvcnRjdXRzIiwiX3Jvb21zIiwiX1NldHRpbmdzU3RvcmUiLCJfTGFiZWxsZWRDaGVja2JveCIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIkNyZWF0ZVJvb21EaWFsb2ciLCJSZWFjdCIsIkNvbXBvbmVudCIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJfZGVmaW5lUHJvcGVydHkyIiwiY3JlYXRlUmVmIiwiZXZlbnQiLCJhY3Rpb24iLCJnZXRLZXlCaW5kaW5nc01hbmFnZXIiLCJnZXRBY2Nlc3NpYmlsaXR5QWN0aW9uIiwiS2V5QmluZGluZ0FjdGlvbiIsIkVudGVyIiwib25PayIsInByZXZlbnREZWZhdWx0Iiwic3RvcFByb3BhZ2F0aW9uIiwibmFtZUZpZWxkIiwiY3VycmVudCIsImFjdGl2ZUVsZW1lbnQiLCJkb2N1bWVudCIsImJsdXIiLCJ2YWxpZGF0ZSIsImFsbG93RW1wdHkiLCJhbGlhc0ZpZWxkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJzZXRTdGF0ZSIsInN0YXRlIiwibmFtZUlzVmFsaWQiLCJpc1ZhbGlkIiwib25GaW5pc2hlZCIsInJvb21DcmVhdGVPcHRpb25zIiwiZmllbGQiLCJmb2N1cyIsImZvY3VzZWQiLCJldiIsIm5hbWUiLCJ0YXJnZXQiLCJ2YWx1ZSIsInRvcGljIiwiam9pblJ1bGUiLCJpc0VuY3J5cHRlZCIsImFsaWFzIiwiZGV0YWlsc09wZW4iLCJvcGVuIiwibm9GZWRlcmF0ZSIsImZpZWxkU3RhdGUiLCJyZXN1bHQiLCJ2YWxpZGF0ZVJvb21OYW1lIiwidmFsaWQiLCJpc1B1YmxpY0tub2NrUm9vbSIsImFza1RvSm9pbkVuYWJsZWQiLCJTZXR0aW5nc1N0b3JlIiwiZ2V0VmFsdWUiLCJzdXBwb3J0c1Jlc3RyaWN0ZWQiLCJwYXJlbnRTcGFjZSIsIkpvaW5SdWxlIiwiSW52aXRlIiwiZGVmYXVsdFB1YmxpYyIsIlB1YmxpYyIsIlJlc3RyaWN0ZWQiLCJjbGkiLCJNYXRyaXhDbGllbnRQZWciLCJzYWZlR2V0IiwiZGVmYXVsdEVuY3J5cHRlZCIsInByaXZhdGVTaG91bGRCZUVuY3J5cHRlZCIsImRlZmF1bHROYW1lIiwiU2RrQ29uZmlnIiwiZGVmYXVsdF9mZWRlcmF0ZSIsImNhbkNoYW5nZUVuY3J5cHRpb24iLCJjaGVja1VzZXJJc0FsbG93ZWRUb0NoYW5nZUVuY3J5cHRpb24iLCJQcmVzZXQiLCJQcml2YXRlQ2hhdCIsInRoZW4iLCJhbGxvd0NoYW5nZSIsImZvcmNlZFZhbHVlIiwib3B0cyIsImNyZWF0ZU9wdHMiLCJyb29tVHlwZSIsInR5cGUiLCJ2aXNpYmlsaXR5IiwiVmlzaWJpbGl0eSIsInByZXNldCIsIlB1YmxpY0NoYXQiLCJndWVzdEFjY2VzcyIsInJvb21fYWxpYXNfbmFtZSIsInN1YnN0cmluZyIsImluZGV4T2YiLCJlbmNyeXB0aW9uIiwiY3JlYXRpb25fY29udGVudCIsIktub2NrIiwiUHJpdmF0ZSIsImNvbXBvbmVudERpZE1vdW50IiwicmVuZGVyIiwiaXNWaWRlb1Jvb20iLCJSb29tVHlwZSIsIkVsZW1lbnRWaWRlbyIsImRvbWFpbiIsImdldERvbWFpbiIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJyZWYiLCJvbkNoYW5nZSIsIm9uQWxpYXNDaGFuZ2UiLCJwdWJsaWNQcml2YXRlTGFiZWwiLCJfdCIsIlNwYWNlTmFtZSIsInZpc2liaWxpdHlTZWN0aW9uIiwibGFiZWwiLCJvbklzUHVibGljS25vY2tSb29tQ2hhbmdlIiwiZTJlZVNlY3Rpb24iLCJtaWNyb2NvcHkiLCJGcmFnbWVudCIsIm9uRW5jcnlwdGVkQ2hhbmdlIiwiZGlzYWJsZWQiLCJmZWRlcmF0ZUxhYmVsIiwidGl0bGUiLCJzY3JlZW5OYW1lIiwib25TdWJtaXQiLCJvbktleURvd24iLCJvbk5hbWVDaGFuZ2UiLCJvblZhbGlkYXRlIiwib25OYW1lVmFsaWRhdGUiLCJvblRvcGljQ2hhbmdlIiwibGFiZWxJbnZpdGUiLCJsYWJlbEtub2NrIiwidW5kZWZpbmVkIiwibGFiZWxQdWJsaWMiLCJsYWJlbFJlc3RyaWN0ZWQiLCJvbkpvaW5SdWxlQ2hhbmdlIiwib25Ub2dnbGUiLCJvbkRldGFpbHNUb2dnbGVkIiwic2VydmVyTmFtZSIsIm9uTm9GZWRlcmF0ZUNoYW5nZSIsInByaW1hcnlCdXR0b24iLCJvblByaW1hcnlCdXR0b25DbGljayIsIm9uQ2FuY2VsIiwiZXhwb3J0cyIsIndpdGhWYWxpZGF0aW9uIiwicnVsZXMiLCJrZXkiLCJ0ZXN0IiwiaW52YWxpZCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL2RpYWxvZ3MvQ3JlYXRlUm9vbURpYWxvZy50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAsIDIwMjEgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbkNvcHlyaWdodCAyMDE3IE1pY2hhZWwgVGVsYXR5bnNraSA8N3QzY2hndXlAZ21haWwuY29tPlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHsgQ2hhbmdlRXZlbnQsIGNyZWF0ZVJlZiwgS2V5Ym9hcmRFdmVudCwgU3ludGhldGljRXZlbnQgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IFJvb20sIFJvb21UeXBlLCBKb2luUnVsZSwgUHJlc2V0LCBWaXNpYmlsaXR5IH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuXG5pbXBvcnQgU2RrQ29uZmlnIGZyb20gXCIuLi8uLi8uLi9TZGtDb25maWdcIjtcbmltcG9ydCB3aXRoVmFsaWRhdGlvbiwgeyBJRmllbGRTdGF0ZSwgSVZhbGlkYXRpb25SZXN1bHQgfSBmcm9tIFwiLi4vZWxlbWVudHMvVmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgeyBNYXRyaXhDbGllbnRQZWcgfSBmcm9tIFwiLi4vLi4vLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgeyBjaGVja1VzZXJJc0FsbG93ZWRUb0NoYW5nZUVuY3J5cHRpb24sIElPcHRzIH0gZnJvbSBcIi4uLy4uLy4uL2NyZWF0ZVJvb21cIjtcbmltcG9ydCBGaWVsZCBmcm9tIFwiLi4vZWxlbWVudHMvRmllbGRcIjtcbmltcG9ydCBSb29tQWxpYXNGaWVsZCBmcm9tIFwiLi4vZWxlbWVudHMvUm9vbUFsaWFzRmllbGRcIjtcbmltcG9ydCBMYWJlbGxlZFRvZ2dsZVN3aXRjaCBmcm9tIFwiLi4vZWxlbWVudHMvTGFiZWxsZWRUb2dnbGVTd2l0Y2hcIjtcbmltcG9ydCBEaWFsb2dCdXR0b25zIGZyb20gXCIuLi9lbGVtZW50cy9EaWFsb2dCdXR0b25zXCI7XG5pbXBvcnQgQmFzZURpYWxvZyBmcm9tIFwiLi4vZGlhbG9ncy9CYXNlRGlhbG9nXCI7XG5pbXBvcnQgSm9pblJ1bGVEcm9wZG93biBmcm9tIFwiLi4vZWxlbWVudHMvSm9pblJ1bGVEcm9wZG93blwiO1xuaW1wb3J0IHsgZ2V0S2V5QmluZGluZ3NNYW5hZ2VyIH0gZnJvbSBcIi4uLy4uLy4uL0tleUJpbmRpbmdzTWFuYWdlclwiO1xuaW1wb3J0IHsgS2V5QmluZGluZ0FjdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9hY2Nlc3NpYmlsaXR5L0tleWJvYXJkU2hvcnRjdXRzXCI7XG5pbXBvcnQgeyBwcml2YXRlU2hvdWxkQmVFbmNyeXB0ZWQgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvcm9vbXNcIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgTGFiZWxsZWRDaGVja2JveCBmcm9tIFwiLi4vZWxlbWVudHMvTGFiZWxsZWRDaGVja2JveFwiO1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICB0eXBlPzogUm9vbVR5cGU7XG4gICAgZGVmYXVsdFB1YmxpYz86IGJvb2xlYW47XG4gICAgZGVmYXVsdE5hbWU/OiBzdHJpbmc7XG4gICAgcGFyZW50U3BhY2U/OiBSb29tO1xuICAgIGRlZmF1bHRFbmNyeXB0ZWQ/OiBib29sZWFuO1xuICAgIG9uRmluaXNoZWQocHJvY2VlZD86IGZhbHNlKTogdm9pZDtcbiAgICBvbkZpbmlzaGVkKHByb2NlZWQ6IHRydWUsIG9wdHM6IElPcHRzKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgLyoqXG4gICAgICogVGhlIHNlbGVjdGVkIHJvb20gam9pbiBydWxlLlxuICAgICAqL1xuICAgIGpvaW5SdWxlOiBKb2luUnVsZTtcbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY3JlYXRlZCByb29tIHNob3VsZCBoYXZlIHB1YmxpYyB2aXNpYmlsaXR5IChpZSwgaXQgc2hvdWxkIGJlXG4gICAgICogc2hvd24gaW4gdGhlIHB1YmxpYyByb29tIGxpc3QpLiBPbmx5IGFwcGxpY2FibGUgaWYgYGpvaW5SdWxlYCA9PSBgSm9pblJ1bGUuS25vY2tgLlxuICAgICAqL1xuICAgIGlzUHVibGljS25vY2tSb29tOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyB3aGV0aGVyIGVuZC10by1lbmQgZW5jcnlwdGlvbiBpcyBlbmFibGVkIGZvciB0aGUgcm9vbS5cbiAgICAgKi9cbiAgICBpc0VuY3J5cHRlZDogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBUaGUgcm9vbSBuYW1lLlxuICAgICAqL1xuICAgIG5hbWU6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgcm9vbSB0b3BpYy5cbiAgICAgKi9cbiAgICB0b3BpYzogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFRoZSByb29tIGFsaWFzLlxuICAgICAqL1xuICAgIGFsaWFzOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGRldGFpbHMgc2VjdGlvbiBpcyBvcGVuLlxuICAgICAqL1xuICAgIGRldGFpbHNPcGVuOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyB3aGV0aGVyIGZlZGVyYXRpb24gaXMgZGlzYWJsZWQgZm9yIHRoZSByb29tLlxuICAgICAqL1xuICAgIG5vRmVkZXJhdGU6IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHJvb20gbmFtZSBpcyB2YWxpZC5cbiAgICAgKi9cbiAgICBuYW1lSXNWYWxpZDogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgdXNlciBjYW4gY2hhbmdlIGVuY3J5cHRpb24gc2V0dGluZ3MgZm9yIHRoZSByb29tLlxuICAgICAqL1xuICAgIGNhbkNoYW5nZUVuY3J5cHRpb246IGJvb2xlYW47XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENyZWF0ZVJvb21EaWFsb2cgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFza1RvSm9pbkVuYWJsZWQ6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSByZWFkb25seSBzdXBwb3J0c1Jlc3RyaWN0ZWQ6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBuYW1lRmllbGQgPSBjcmVhdGVSZWY8RmllbGQ+KCk7XG4gICAgcHJpdmF0ZSBhbGlhc0ZpZWxkID0gY3JlYXRlUmVmPFJvb21BbGlhc0ZpZWxkPigpO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBJUHJvcHMpIHtcbiAgICAgICAgc3VwZXIocHJvcHMpO1xuXG4gICAgICAgIHRoaXMuYXNrVG9Kb2luRW5hYmxlZCA9IFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJmZWF0dXJlX2Fza190b19qb2luXCIpO1xuICAgICAgICB0aGlzLnN1cHBvcnRzUmVzdHJpY3RlZCA9ICEhdGhpcy5wcm9wcy5wYXJlbnRTcGFjZTtcblxuICAgICAgICBsZXQgam9pblJ1bGUgPSBKb2luUnVsZS5JbnZpdGU7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmRlZmF1bHRQdWJsaWMpIHtcbiAgICAgICAgICAgIGpvaW5SdWxlID0gSm9pblJ1bGUuUHVibGljO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3VwcG9ydHNSZXN0cmljdGVkKSB7XG4gICAgICAgICAgICBqb2luUnVsZSA9IEpvaW5SdWxlLlJlc3RyaWN0ZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpO1xuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgaXNQdWJsaWNLbm9ja1Jvb206IHRoaXMucHJvcHMuZGVmYXVsdFB1YmxpYyB8fCBmYWxzZSxcbiAgICAgICAgICAgIGlzRW5jcnlwdGVkOiB0aGlzLnByb3BzLmRlZmF1bHRFbmNyeXB0ZWQgPz8gcHJpdmF0ZVNob3VsZEJlRW5jcnlwdGVkKGNsaSksXG4gICAgICAgICAgICBqb2luUnVsZSxcbiAgICAgICAgICAgIG5hbWU6IHRoaXMucHJvcHMuZGVmYXVsdE5hbWUgfHwgXCJcIixcbiAgICAgICAgICAgIHRvcGljOiBcIlwiLFxuICAgICAgICAgICAgYWxpYXM6IFwiXCIsXG4gICAgICAgICAgICBkZXRhaWxzT3BlbjogZmFsc2UsXG4gICAgICAgICAgICBub0ZlZGVyYXRlOiBTZGtDb25maWcuZ2V0KCkuZGVmYXVsdF9mZWRlcmF0ZSA9PT0gZmFsc2UsXG4gICAgICAgICAgICBuYW1lSXNWYWxpZDogZmFsc2UsXG4gICAgICAgICAgICBjYW5DaGFuZ2VFbmNyeXB0aW9uOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjaGVja1VzZXJJc0FsbG93ZWRUb0NoYW5nZUVuY3J5cHRpb24oY2xpLCBQcmVzZXQuUHJpdmF0ZUNoYXQpLnRoZW4oKHsgYWxsb3dDaGFuZ2UsIGZvcmNlZFZhbHVlIH0pID0+XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBjYW5DaGFuZ2VFbmNyeXB0aW9uOiBhbGxvd0NoYW5nZSxcbiAgICAgICAgICAgICAgICAvLyBvdmVycmlkZSB3aXRoIGZvcmNlZFZhbHVlIGlmIGl0IGlzIHNldFxuICAgICAgICAgICAgICAgIGlzRW5jcnlwdGVkOiBmb3JjZWRWYWx1ZSA/PyBzdGF0ZS5pc0VuY3J5cHRlZCxcbiAgICAgICAgICAgIH0pKSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJvb21DcmVhdGVPcHRpb25zKCk6IElPcHRzIHtcbiAgICAgICAgY29uc3Qgb3B0czogSU9wdHMgPSB7fTtcbiAgICAgICAgY29uc3QgY3JlYXRlT3B0czogSU9wdHNbXCJjcmVhdGVPcHRzXCJdID0gKG9wdHMuY3JlYXRlT3B0cyA9IHt9KTtcbiAgICAgICAgb3B0cy5yb29tVHlwZSA9IHRoaXMucHJvcHMudHlwZTtcbiAgICAgICAgY3JlYXRlT3B0cy5uYW1lID0gdGhpcy5zdGF0ZS5uYW1lO1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmpvaW5SdWxlID09PSBKb2luUnVsZS5QdWJsaWMpIHtcbiAgICAgICAgICAgIGNyZWF0ZU9wdHMudmlzaWJpbGl0eSA9IFZpc2liaWxpdHkuUHVibGljO1xuICAgICAgICAgICAgY3JlYXRlT3B0cy5wcmVzZXQgPSBQcmVzZXQuUHVibGljQ2hhdDtcbiAgICAgICAgICAgIG9wdHMuZ3Vlc3RBY2Nlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHsgYWxpYXMgfSA9IHRoaXMuc3RhdGU7XG4gICAgICAgICAgICBjcmVhdGVPcHRzLnJvb21fYWxpYXNfbmFtZSA9IGFsaWFzLnN1YnN0cmluZygxLCBhbGlhcy5pbmRleE9mKFwiOlwiKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvcHRzLmVuY3J5cHRpb24gPSB0aGlzLnN0YXRlLmlzRW5jcnlwdGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUudG9waWMpIHtcbiAgICAgICAgICAgIGNyZWF0ZU9wdHMudG9waWMgPSB0aGlzLnN0YXRlLnRvcGljO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLm5vRmVkZXJhdGUpIHtcbiAgICAgICAgICAgIGNyZWF0ZU9wdHMuY3JlYXRpb25fY29udGVudCA9IHsgXCJtLmZlZGVyYXRlXCI6IGZhbHNlIH07XG4gICAgICAgIH1cblxuICAgICAgICBvcHRzLnBhcmVudFNwYWNlID0gdGhpcy5wcm9wcy5wYXJlbnRTcGFjZTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucGFyZW50U3BhY2UgJiYgdGhpcy5zdGF0ZS5qb2luUnVsZSA9PT0gSm9pblJ1bGUuUmVzdHJpY3RlZCkge1xuICAgICAgICAgICAgb3B0cy5qb2luUnVsZSA9IEpvaW5SdWxlLlJlc3RyaWN0ZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5qb2luUnVsZSA9PT0gSm9pblJ1bGUuS25vY2spIHtcbiAgICAgICAgICAgIG9wdHMuam9pblJ1bGUgPSBKb2luUnVsZS5Lbm9jaztcbiAgICAgICAgICAgIGNyZWF0ZU9wdHMudmlzaWJpbGl0eSA9IHRoaXMuc3RhdGUuaXNQdWJsaWNLbm9ja1Jvb20gPyBWaXNpYmlsaXR5LlB1YmxpYyA6IFZpc2liaWxpdHkuUHJpdmF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBvcHRzO1xuICAgIH1cblxuICAgIHB1YmxpYyBjb21wb25lbnREaWRNb3VudCgpOiB2b2lkIHtcbiAgICAgICAgLy8gbW92ZSBmb2N1cyB0byBmaXJzdCBmaWVsZCB3aGVuIHNob3dpbmcgZGlhbG9nXG4gICAgICAgIHRoaXMubmFtZUZpZWxkLmN1cnJlbnQ/LmZvY3VzKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbktleURvd24gPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgYWN0aW9uID0gZ2V0S2V5QmluZGluZ3NNYW5hZ2VyKCkuZ2V0QWNjZXNzaWJpbGl0eUFjdGlvbihldmVudCk7XG4gICAgICAgIHN3aXRjaCAoYWN0aW9uKSB7XG4gICAgICAgICAgICBjYXNlIEtleUJpbmRpbmdBY3Rpb24uRW50ZXI6XG4gICAgICAgICAgICAgICAgdGhpcy5vbk9rKCk7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uT2sgPSBhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGlmICghdGhpcy5uYW1lRmllbGQuY3VycmVudCkgcmV0dXJuO1xuICAgICAgICBjb25zdCBhY3RpdmVFbGVtZW50ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgYWN0aXZlRWxlbWVudD8uYmx1cigpO1xuICAgICAgICBhd2FpdCB0aGlzLm5hbWVGaWVsZC5jdXJyZW50LnZhbGlkYXRlKHsgYWxsb3dFbXB0eTogZmFsc2UgfSk7XG4gICAgICAgIGlmICh0aGlzLmFsaWFzRmllbGQuY3VycmVudCkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hbGlhc0ZpZWxkLmN1cnJlbnQudmFsaWRhdGUoeyBhbGxvd0VtcHR5OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBWYWxpZGF0aW9uIGFuZCBzdGF0ZSB1cGRhdGVzIGFyZSBhc3luYywgc28gd2UgbmVlZCB0byB3YWl0IGZvciB0aGVtIHRvIGNvbXBsZXRlXG4gICAgICAgIC8vIGZpcnN0LiBRdWV1ZSBhIGBzZXRTdGF0ZWAgY2FsbGJhY2sgYW5kIHdhaXQgZm9yIGl0IHRvIHJlc29sdmUuXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB0aGlzLnNldFN0YXRlKHt9LCByZXNvbHZlKSk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLm5hbWVJc1ZhbGlkICYmICghdGhpcy5hbGlhc0ZpZWxkLmN1cnJlbnQgfHwgdGhpcy5hbGlhc0ZpZWxkLmN1cnJlbnQuaXNWYWxpZCkpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25GaW5pc2hlZCh0cnVlLCB0aGlzLnJvb21DcmVhdGVPcHRpb25zKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGZpZWxkOiBSb29tQWxpYXNGaWVsZCB8IEZpZWxkIHwgbnVsbCA9IG51bGw7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUubmFtZUlzVmFsaWQpIHtcbiAgICAgICAgICAgICAgICBmaWVsZCA9IHRoaXMubmFtZUZpZWxkLmN1cnJlbnQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYWxpYXNGaWVsZC5jdXJyZW50ICYmICF0aGlzLmFsaWFzRmllbGQuY3VycmVudC5pc1ZhbGlkKSB7XG4gICAgICAgICAgICAgICAgZmllbGQgPSB0aGlzLmFsaWFzRmllbGQuY3VycmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmaWVsZCkge1xuICAgICAgICAgICAgICAgIGZpZWxkLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgZmllbGQudmFsaWRhdGUoeyBhbGxvd0VtcHR5OiBmYWxzZSwgZm9jdXNlZDogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uQ2FuY2VsID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnByb3BzLm9uRmluaXNoZWQoZmFsc2UpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uTmFtZUNoYW5nZSA9IChldjogQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG5hbWU6IGV2LnRhcmdldC52YWx1ZSB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblRvcGljQ2hhbmdlID0gKGV2OiBDaGFuZ2VFdmVudDxIVE1MSW5wdXRFbGVtZW50Pik6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgdG9waWM6IGV2LnRhcmdldC52YWx1ZSB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkpvaW5SdWxlQ2hhbmdlID0gKGpvaW5SdWxlOiBKb2luUnVsZSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgam9pblJ1bGUgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25FbmNyeXB0ZWRDaGFuZ2UgPSAoaXNFbmNyeXB0ZWQ6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzRW5jcnlwdGVkIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uQWxpYXNDaGFuZ2UgPSAoYWxpYXM6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgYWxpYXMgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25EZXRhaWxzVG9nZ2xlZCA9IChldjogU3ludGhldGljRXZlbnQ8SFRNTERldGFpbHNFbGVtZW50Pik6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGV0YWlsc09wZW46IChldi50YXJnZXQgYXMgSFRNTERldGFpbHNFbGVtZW50KS5vcGVuIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uTm9GZWRlcmF0ZUNoYW5nZSA9IChub0ZlZGVyYXRlOiBib29sZWFuKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBub0ZlZGVyYXRlIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uTmFtZVZhbGlkYXRlID0gYXN5bmMgKGZpZWxkU3RhdGU6IElGaWVsZFN0YXRlKTogUHJvbWlzZTxJVmFsaWRhdGlvblJlc3VsdD4gPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBDcmVhdGVSb29tRGlhbG9nLnZhbGlkYXRlUm9vbU5hbWUoZmllbGRTdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBuYW1lSXNWYWxpZDogISFyZXN1bHQudmFsaWQgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Jc1B1YmxpY0tub2NrUm9vbUNoYW5nZSA9IChpc1B1YmxpY0tub2NrUm9vbTogYm9vbGVhbik6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNQdWJsaWNLbm9ja1Jvb20gfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlUm9vbU5hbWUgPSB3aXRoVmFsaWRhdGlvbih7XG4gICAgICAgIHJ1bGVzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2V5OiBcInJlcXVpcmVkXCIsXG4gICAgICAgICAgICAgICAgdGVzdDogYXN5bmMgKHsgdmFsdWUgfSkgPT4gISF2YWx1ZSxcbiAgICAgICAgICAgICAgICBpbnZhbGlkOiAoKSA9PiBfdChcImNyZWF0ZV9yb29tfG5hbWVfdmFsaWRhdGlvbl9yZXF1aXJlZFwiKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gICAgICAgIGNvbnN0IGlzVmlkZW9Sb29tID0gdGhpcy5wcm9wcy50eXBlID09PSBSb29tVHlwZS5FbGVtZW50VmlkZW87XG5cbiAgICAgICAgbGV0IGFsaWFzRmllbGQ6IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5qb2luUnVsZSA9PT0gSm9pblJ1bGUuUHVibGljKSB7XG4gICAgICAgICAgICBjb25zdCBkb21haW4gPSBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmdldERvbWFpbigpITtcbiAgICAgICAgICAgIGFsaWFzRmllbGQgPSAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9DcmVhdGVSb29tRGlhbG9nX2FsaWFzQ29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxSb29tQWxpYXNGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmPXt0aGlzLmFsaWFzRmllbGR9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5vbkFsaWFzQ2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluPXtkb21haW59XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5hbGlhc31cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcHVibGljUHJpdmF0ZUxhYmVsOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuam9pblJ1bGUgPT09IEpvaW5SdWxlLlJlc3RyaWN0ZWQpIHtcbiAgICAgICAgICAgIHB1YmxpY1ByaXZhdGVMYWJlbCA9IChcbiAgICAgICAgICAgICAgICA8cD5cbiAgICAgICAgICAgICAgICAgICAge190KFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJjcmVhdGVfcm9vbXxqb2luX3J1bGVfcmVzdHJpY3RlZF9sYWJlbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3BhY2VOYW1lOiAoKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3RoaXMucHJvcHMucGFyZW50U3BhY2U/Lm5hbWUgPz8gX3QoXCJjb21tb258dW5uYW1lZF9zcGFjZVwiKX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgJm5ic3A7XG4gICAgICAgICAgICAgICAgICAgIHtfdChcImNyZWF0ZV9yb29tfGpvaW5fcnVsZV9jaGFuZ2Vfbm90aWNlXCIpfVxuICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5qb2luUnVsZSA9PT0gSm9pblJ1bGUuUHVibGljICYmIHRoaXMucHJvcHMucGFyZW50U3BhY2UpIHtcbiAgICAgICAgICAgIHB1YmxpY1ByaXZhdGVMYWJlbCA9IChcbiAgICAgICAgICAgICAgICA8cD5cbiAgICAgICAgICAgICAgICAgICAge190KFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJjcmVhdGVfcm9vbXxqb2luX3J1bGVfcHVibGljX3BhcmVudF9zcGFjZV9sYWJlbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3BhY2VOYW1lOiAoKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3RoaXMucHJvcHMucGFyZW50U3BhY2U/Lm5hbWUgPz8gX3QoXCJjb21tb258dW5uYW1lZF9zcGFjZVwiKX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgJm5ic3A7XG4gICAgICAgICAgICAgICAgICAgIHtfdChcImNyZWF0ZV9yb29tfGpvaW5fcnVsZV9jaGFuZ2Vfbm90aWNlXCIpfVxuICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5qb2luUnVsZSA9PT0gSm9pblJ1bGUuUHVibGljKSB7XG4gICAgICAgICAgICBwdWJsaWNQcml2YXRlTGFiZWwgPSAoXG4gICAgICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcImNyZWF0ZV9yb29tfGpvaW5fcnVsZV9wdWJsaWNfbGFiZWxcIil9XG4gICAgICAgICAgICAgICAgICAgICZuYnNwO1xuICAgICAgICAgICAgICAgICAgICB7X3QoXCJjcmVhdGVfcm9vbXxqb2luX3J1bGVfY2hhbmdlX25vdGljZVwiKX1cbiAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuam9pblJ1bGUgPT09IEpvaW5SdWxlLkludml0ZSkge1xuICAgICAgICAgICAgcHVibGljUHJpdmF0ZUxhYmVsID0gKFxuICAgICAgICAgICAgICAgIDxwPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJjcmVhdGVfcm9vbXxqb2luX3J1bGVfaW52aXRlX2xhYmVsXCIpfVxuICAgICAgICAgICAgICAgICAgICAmbmJzcDtcbiAgICAgICAgICAgICAgICAgICAge190KFwiY3JlYXRlX3Jvb218am9pbl9ydWxlX2NoYW5nZV9ub3RpY2VcIil9XG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmpvaW5SdWxlID09PSBKb2luUnVsZS5Lbm9jaykge1xuICAgICAgICAgICAgcHVibGljUHJpdmF0ZUxhYmVsID0gPHA+e190KFwiY3JlYXRlX3Jvb218am9pbl9ydWxlX2tub2NrX2xhYmVsXCIpfTwvcD47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmlzaWJpbGl0eVNlY3Rpb246IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5qb2luUnVsZSA9PT0gSm9pblJ1bGUuS25vY2spIHtcbiAgICAgICAgICAgIHZpc2liaWxpdHlTZWN0aW9uID0gKFxuICAgICAgICAgICAgICAgIDxMYWJlbGxlZENoZWNrYm94XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X0NyZWF0ZVJvb21EaWFsb2dfbGFiZWxsZWRDaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcInJvb21fc2V0dGluZ3N8c2VjdXJpdHl8cHVibGlzaF9yb29tXCIpfVxuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5vbklzUHVibGljS25vY2tSb29tQ2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5pc1B1YmxpY0tub2NrUm9vbX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBlMmVlU2VjdGlvbjogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmpvaW5SdWxlICE9PSBKb2luUnVsZS5QdWJsaWMpIHtcbiAgICAgICAgICAgIGxldCBtaWNyb2NvcHk6IHN0cmluZztcbiAgICAgICAgICAgIGlmIChwcml2YXRlU2hvdWxkQmVFbmNyeXB0ZWQoTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKSkpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5jYW5DaGFuZ2VFbmNyeXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIG1pY3JvY29weSA9IGlzVmlkZW9Sb29tXG4gICAgICAgICAgICAgICAgICAgICAgICA/IF90KFwiY3JlYXRlX3Jvb218ZW5jcnlwdGVkX3ZpZGVvX3Jvb21fd2FybmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcImNyZWF0ZV9yb29tfGVuY3J5cHRlZF93YXJuaW5nXCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG1pY3JvY29weSA9IF90KFwiY3JlYXRlX3Jvb218ZW5jcnlwdGlvbl9mb3JjZWRcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtaWNyb2NvcHkgPSBfdChcInNldHRpbmdzfHNlY3VyaXR5fGUyZWVfZGVmYXVsdF9kaXNhYmxlZF93YXJuaW5nXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZTJlZVNlY3Rpb24gPSAoXG4gICAgICAgICAgICAgICAgPFJlYWN0LkZyYWdtZW50PlxuICAgICAgICAgICAgICAgICAgICA8TGFiZWxsZWRUb2dnbGVTd2l0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImNyZWF0ZV9yb29tfGVuY3J5cHRpb25fbGFiZWxcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5vbkVuY3J5cHRlZENoYW5nZX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXt0aGlzLnN0YXRlLmlzRW5jcnlwdGVkfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfQ3JlYXRlUm9vbURpYWxvZ19lMmVTd2l0Y2hcIiAvLyBmb3IgZW5kLXRvLWVuZCB0ZXN0c1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9eyF0aGlzLnN0YXRlLmNhbkNoYW5nZUVuY3J5cHRpb259XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDxwPnttaWNyb2NvcHl9PC9wPlxuICAgICAgICAgICAgICAgIDwvUmVhY3QuRnJhZ21lbnQ+XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZlZGVyYXRlTGFiZWwgPSBfdChcImNyZWF0ZV9yb29tfHVuZmVkZXJhdGVkX2xhYmVsX2RlZmF1bHRfb2ZmXCIpO1xuICAgICAgICBpZiAoU2RrQ29uZmlnLmdldCgpLmRlZmF1bHRfZmVkZXJhdGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAvLyBXZSBvbmx5IGNoYW5nZSB0aGUgbGFiZWwgaWYgdGhlIGRlZmF1bHQgc2V0dGluZyBpcyBkaWZmZXJlbnQgdG8gYXZvaWQgamFycmluZyB0ZXh0IGNoYW5nZXMgdG8gdGhlXG4gICAgICAgICAgICAvLyB1c2VyLiBUaGV5IHdpbGwgaGF2ZSByZWFkIHRoZSBpbXBsaWNhdGlvbnMgb2YgdHVybmluZyB0aGlzIG9mZi9vbiwgc28gbm8gbmVlZCB0byByZXBocmFzZSBmb3IgdGhlbS5cbiAgICAgICAgICAgIGZlZGVyYXRlTGFiZWwgPSBfdChcImNyZWF0ZV9yb29tfHVuZmVkZXJhdGVkX2xhYmVsX2RlZmF1bHRfb25cIik7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdGl0bGU6IHN0cmluZztcbiAgICAgICAgaWYgKGlzVmlkZW9Sb29tKSB7XG4gICAgICAgICAgICB0aXRsZSA9IF90KFwiY3JlYXRlX3Jvb218dGl0bGVfdmlkZW9fcm9vbVwiKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLnBhcmVudFNwYWNlIHx8IHRoaXMuc3RhdGUuam9pblJ1bGUgPT09IEpvaW5SdWxlLktub2NrKSB7XG4gICAgICAgICAgICB0aXRsZSA9IF90KFwiYWN0aW9ufGNyZWF0ZV9hX3Jvb21cIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aXRsZSA9XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5qb2luUnVsZSA9PT0gSm9pblJ1bGUuUHVibGljXG4gICAgICAgICAgICAgICAgICAgID8gX3QoXCJjcmVhdGVfcm9vbXx0aXRsZV9wdWJsaWNfcm9vbVwiKVxuICAgICAgICAgICAgICAgICAgICA6IF90KFwiY3JlYXRlX3Jvb218dGl0bGVfcHJpdmF0ZV9yb29tXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxCYXNlRGlhbG9nXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfQ3JlYXRlUm9vbURpYWxvZ1wiXG4gICAgICAgICAgICAgICAgb25GaW5pc2hlZD17dGhpcy5wcm9wcy5vbkZpbmlzaGVkfVxuICAgICAgICAgICAgICAgIHRpdGxlPXt0aXRsZX1cbiAgICAgICAgICAgICAgICBzY3JlZW5OYW1lPVwiQ3JlYXRlUm9vbVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGZvcm0gb25TdWJtaXQ9e3RoaXMub25Pa30gb25LZXlEb3duPXt0aGlzLm9uS2V5RG93bn0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfRGlhbG9nX2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZj17dGhpcy5uYW1lRmllbGR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwiY29tbW9ufG5hbWVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e3RoaXMub25OYW1lQ2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVmFsaWRhdGU9e3RoaXMub25OYW1lVmFsaWRhdGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuc3RhdGUubmFtZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9DcmVhdGVSb29tRGlhbG9nX25hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImNyZWF0ZV9yb29tfHRvcGljX2xhYmVsXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLm9uVG9waWNDaGFuZ2V9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuc3RhdGUudG9waWN9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfQ3JlYXRlUm9vbURpYWxvZ190b3BpY1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8Sm9pblJ1bGVEcm9wZG93blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImNyZWF0ZV9yb29tfHJvb21fdmlzaWJpbGl0eV9sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbEludml0ZT17X3QoXCJjcmVhdGVfcm9vbXxqb2luX3J1bGVfaW52aXRlXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsS25vY2s9e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFza1RvSm9pbkVuYWJsZWQgPyBfdChcInJvb21fc2V0dGluZ3N8c2VjdXJpdHl8am9pbl9ydWxlX2tub2NrXCIpIDogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsUHVibGljPXtfdChcImNvbW1vbnxwdWJsaWNfcm9vbVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFJlc3RyaWN0ZWQ9e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN1cHBvcnRzUmVzdHJpY3RlZCA/IF90KFwiY3JlYXRlX3Jvb218am9pbl9ydWxlX3Jlc3RyaWN0ZWRcIikgOiB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuc3RhdGUuam9pblJ1bGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e3RoaXMub25Kb2luUnVsZUNoYW5nZX1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtwdWJsaWNQcml2YXRlTGFiZWx9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dmlzaWJpbGl0eVNlY3Rpb259XG4gICAgICAgICAgICAgICAgICAgICAgICB7ZTJlZVNlY3Rpb259XG4gICAgICAgICAgICAgICAgICAgICAgICB7YWxpYXNGaWVsZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkZXRhaWxzIG9uVG9nZ2xlPXt0aGlzLm9uRGV0YWlsc1RvZ2dsZWR9IGNsYXNzTmFtZT1cIm14X0NyZWF0ZVJvb21EaWFsb2dfZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdW1tYXJ5IGNsYXNzTmFtZT1cIm14X0NyZWF0ZVJvb21EaWFsb2dfZGV0YWlsc19zdW1tYXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnN0YXRlLmRldGFpbHNPcGVuID8gX3QoXCJhY3Rpb258aGlkZV9hZHZhbmNlZFwiKSA6IF90KFwiYWN0aW9ufHNob3dfYWR2YW5jZWRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdW1tYXJ5PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxMYWJlbGxlZFRvZ2dsZVN3aXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJjcmVhdGVfcm9vbXx1bmZlZGVyYXRlZFwiLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJOYW1lOiBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmdldERvbWFpbigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e3RoaXMub25Ob0ZlZGVyYXRlQ2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5ub0ZlZGVyYXRlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+e2ZlZGVyYXRlTGFiZWx9PC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICAgICAgPERpYWxvZ0J1dHRvbnNcbiAgICAgICAgICAgICAgICAgICAgcHJpbWFyeUJ1dHRvbj17XG4gICAgICAgICAgICAgICAgICAgICAgICBpc1ZpZGVvUm9vbSA/IF90KFwiY3JlYXRlX3Jvb218YWN0aW9uX2NyZWF0ZV92aWRlb19yb29tXCIpIDogX3QoXCJjcmVhdGVfcm9vbXxhY3Rpb25fY3JlYXRlX3Jvb21cIilcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvblByaW1hcnlCdXR0b25DbGljaz17dGhpcy5vbk9rfVxuICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbD17dGhpcy5vbkNhbmNlbH1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9CYXNlRGlhbG9nPlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFTQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxVQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxXQUFBLEdBQUFELHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSyxnQkFBQSxHQUFBTCxPQUFBO0FBQ0EsSUFBQU0sZ0JBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLFdBQUEsR0FBQVAsT0FBQTtBQUNBLElBQUFRLE1BQUEsR0FBQUwsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFTLGVBQUEsR0FBQU4sc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFVLHFCQUFBLEdBQUFQLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBVyxjQUFBLEdBQUFSLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBWSxXQUFBLEdBQUFULHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBYSxpQkFBQSxHQUFBVixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQWMsbUJBQUEsR0FBQWQsT0FBQTtBQUNBLElBQUFlLGtCQUFBLEdBQUFmLE9BQUE7QUFDQSxJQUFBZ0IsTUFBQSxHQUFBaEIsT0FBQTtBQUNBLElBQUFpQixjQUFBLEdBQUFkLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBa0IsaUJBQUEsR0FBQWYsc0JBQUEsQ0FBQUgsT0FBQTtBQUE0RCxTQUFBbUIseUJBQUFDLENBQUEsNkJBQUFDLE9BQUEsbUJBQUFDLENBQUEsT0FBQUQsT0FBQSxJQUFBRSxDQUFBLE9BQUFGLE9BQUEsWUFBQUYsd0JBQUEsWUFBQUEsQ0FBQUMsQ0FBQSxXQUFBQSxDQUFBLEdBQUFHLENBQUEsR0FBQUQsQ0FBQSxLQUFBRixDQUFBO0FBQUEsU0FBQXJCLHdC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