matrix-react-sdk
Version:
SDK for matrix.org using React
234 lines (229 loc) • 44.5 kB
JavaScript
;
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 = _interopRequireDefault(require("react"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _logger = require("matrix-js-sdk/src/logger");
var _crypto = require("matrix-js-sdk/src/crypto");
var _MatrixClientPeg = require("../../../MatrixClientPeg");
var _languageHandler = require("../../../languageHandler");
var _Modal = _interopRequireDefault(require("../../../Modal"));
var _Spinner = _interopRequireDefault(require("../elements/Spinner"));
var _InteractiveAuthDialog = _interopRequireDefault(require("../dialogs/InteractiveAuthDialog"));
var _ConfirmDestroyCrossSigningDialog = _interopRequireDefault(require("../dialogs/security/ConfirmDestroyCrossSigningDialog"));
var _SetupEncryptionDialog = _interopRequireDefault(require("../dialogs/security/SetupEncryptionDialog"));
var _SecurityManager = require("../../../SecurityManager");
var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton"));
var _SettingsSubsection = require("./shared/SettingsSubsection");
/*
Copyright 2024 New Vector Ltd.
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
class CrossSigningPanel extends _react.default.PureComponent {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "unmounted", false);
(0, _defineProperty2.default)(this, "onAccountData", event => {
const type = event.getType();
if (type.startsWith("m.cross_signing") || type.startsWith("m.secret_storage")) {
this.getUpdatedStatus();
}
});
(0, _defineProperty2.default)(this, "onBootstrapClick", () => {
if (this.state.crossSigningPrivateKeysInStorage) {
_Modal.default.createDialog(_SetupEncryptionDialog.default, {}, undefined, /* priority = */false, /* static = */true);
} else {
// Trigger the flow to set up secure backup, which is what this will do when in
// the appropriate state.
(0, _SecurityManager.accessSecretStorage)();
}
});
(0, _defineProperty2.default)(this, "onStatusChanged", () => {
this.getUpdatedStatus();
});
/**
* Callback for when the user clicks the "reset cross signing" button.
*
* Shows a confirmation dialog, and then does the reset if confirmed.
*/
(0, _defineProperty2.default)(this, "onResetCrossSigningClick", () => {
_Modal.default.createDialog(_ConfirmDestroyCrossSigningDialog.default, {
onFinished: async act => {
if (!act) return;
this.resetCrossSigning();
}
});
});
this.state = {
error: false
};
}
componentDidMount() {
const cli = _MatrixClientPeg.MatrixClientPeg.safeGet();
cli.on(_matrix.ClientEvent.AccountData, this.onAccountData);
cli.on(_crypto.CryptoEvent.UserTrustStatusChanged, this.onStatusChanged);
cli.on(_crypto.CryptoEvent.KeysChanged, this.onStatusChanged);
this.getUpdatedStatus();
}
componentWillUnmount() {
this.unmounted = true;
const cli = _MatrixClientPeg.MatrixClientPeg.get();
if (!cli) return;
cli.removeListener(_matrix.ClientEvent.AccountData, this.onAccountData);
cli.removeListener(_crypto.CryptoEvent.UserTrustStatusChanged, this.onStatusChanged);
cli.removeListener(_crypto.CryptoEvent.KeysChanged, this.onStatusChanged);
}
async getUpdatedStatus() {
const cli = _MatrixClientPeg.MatrixClientPeg.safeGet();
const crypto = cli.getCrypto();
if (!crypto) return;
const crossSigningStatus = await crypto.getCrossSigningStatus();
const crossSigningPublicKeysOnDevice = crossSigningStatus.publicKeysOnDevice;
const crossSigningPrivateKeysInStorage = crossSigningStatus.privateKeysInSecretStorage;
const masterPrivateKeyCached = crossSigningStatus.privateKeysCachedLocally.masterKey;
const selfSigningPrivateKeyCached = crossSigningStatus.privateKeysCachedLocally.selfSigningKey;
const userSigningPrivateKeyCached = crossSigningStatus.privateKeysCachedLocally.userSigningKey;
const homeserverSupportsCrossSigning = await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing");
const crossSigningReady = await crypto.isCrossSigningReady();
this.setState({
crossSigningPublicKeysOnDevice,
crossSigningPrivateKeysInStorage,
masterPrivateKeyCached,
selfSigningPrivateKeyCached,
userSigningPrivateKeyCached,
homeserverSupportsCrossSigning,
crossSigningReady
});
}
/**
* Reset the user's cross-signing keys.
*/
async resetCrossSigning() {
this.setState({
error: false
});
try {
const cli = _MatrixClientPeg.MatrixClientPeg.safeGet();
await (0, _SecurityManager.withSecretStorageKeyCache)(async () => {
await cli.getCrypto().bootstrapCrossSigning({
authUploadDeviceSigningKeys: async makeRequest => {
const {
finished
} = _Modal.default.createDialog(_InteractiveAuthDialog.default, {
title: (0, _languageHandler._t)("encryption|bootstrap_title"),
matrixClient: cli,
makeRequest
});
const [confirmed] = await finished;
if (!confirmed) {
throw new Error("Cross-signing key upload auth canceled");
}
},
setupNewCrossSigning: true
});
});
} catch (e) {
this.setState({
error: true
});
_logger.logger.error("Error bootstrapping cross-signing", e);
}
if (this.unmounted) return;
this.getUpdatedStatus();
}
render() {
const {
error,
crossSigningPublicKeysOnDevice,
crossSigningPrivateKeysInStorage,
masterPrivateKeyCached,
selfSigningPrivateKeyCached,
userSigningPrivateKeyCached,
homeserverSupportsCrossSigning,
crossSigningReady
} = this.state;
let errorSection;
if (error) {
errorSection = /*#__PURE__*/_react.default.createElement("div", {
className: "error"
}, error.toString());
}
let summarisedStatus;
if (homeserverSupportsCrossSigning === undefined) {
summarisedStatus = /*#__PURE__*/_react.default.createElement(_Spinner.default, null);
} else if (!homeserverSupportsCrossSigning) {
summarisedStatus = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.SettingsSubsectionText, {
"data-testid": "summarised-status"
}, (0, _languageHandler._t)("encryption|cross_signing_unsupported"));
} else if (crossSigningReady && crossSigningPrivateKeysInStorage) {
summarisedStatus = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.SettingsSubsectionText, {
"data-testid": "summarised-status"
}, "\u2705 ", (0, _languageHandler._t)("encryption|cross_signing_ready"));
} else if (crossSigningReady && !crossSigningPrivateKeysInStorage) {
summarisedStatus = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.SettingsSubsectionText, {
"data-testid": "summarised-status"
}, "\u26A0\uFE0F ", (0, _languageHandler._t)("encryption|cross_signing_ready_no_backup"));
} else if (crossSigningPrivateKeysInStorage) {
summarisedStatus = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.SettingsSubsectionText, {
"data-testid": "summarised-status"
}, (0, _languageHandler._t)("encryption|cross_signing_untrusted"));
} else {
summarisedStatus = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.SettingsSubsectionText, {
"data-testid": "summarised-status"
}, (0, _languageHandler._t)("encryption|cross_signing_not_ready"));
}
const keysExistAnywhere = crossSigningPublicKeysOnDevice || crossSigningPrivateKeysInStorage || masterPrivateKeyCached || selfSigningPrivateKeyCached || userSigningPrivateKeyCached;
const keysExistEverywhere = crossSigningPublicKeysOnDevice && crossSigningPrivateKeysInStorage && masterPrivateKeyCached && selfSigningPrivateKeyCached && userSigningPrivateKeyCached;
const actions = [];
// TODO: determine how better to expose this to users in addition to prompts at login/toast
if (!keysExistEverywhere && homeserverSupportsCrossSigning) {
let buttonCaption = (0, _languageHandler._t)("encryption|set_up_toast_title");
if (crossSigningPrivateKeysInStorage) {
buttonCaption = (0, _languageHandler._t)("encryption|verify_toast_title");
}
actions.push( /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
key: "setup",
kind: "primary_outline",
onClick: this.onBootstrapClick
}, buttonCaption));
}
if (keysExistAnywhere) {
actions.push( /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
key: "reset",
kind: "danger_outline",
onClick: this.onResetCrossSigningClick
}, (0, _languageHandler._t)("action|reset")));
}
let actionRow;
if (actions.length) {
actionRow = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CrossSigningPanel_buttonRow"
}, actions);
}
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, summarisedStatus, /*#__PURE__*/_react.default.createElement("details", null, /*#__PURE__*/_react.default.createElement("summary", {
className: "mx_CrossSigningPanel_advanced"
}, (0, _languageHandler._t)("common|advanced")), /*#__PURE__*/_react.default.createElement("table", {
className: "mx_CrossSigningPanel_statusList"
}, /*#__PURE__*/_react.default.createElement("tbody", null, /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", {
scope: "row"
}, (0, _languageHandler._t)("settings|security|cross_signing_public_keys")), /*#__PURE__*/_react.default.createElement("td", null, crossSigningPublicKeysOnDevice ? (0, _languageHandler._t)("settings|security|cross_signing_in_memory") : (0, _languageHandler._t)("settings|security|cross_signing_not_found"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", {
scope: "row"
}, (0, _languageHandler._t)("settings|security|cross_signing_private_keys")), /*#__PURE__*/_react.default.createElement("td", null, crossSigningPrivateKeysInStorage ? (0, _languageHandler._t)("settings|security|cross_signing_in_4s") : (0, _languageHandler._t)("settings|security|cross_signing_not_in_4s"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", {
scope: "row"
}, (0, _languageHandler._t)("settings|security|cross_signing_master_private_Key")), /*#__PURE__*/_react.default.createElement("td", null, masterPrivateKeyCached ? (0, _languageHandler._t)("settings|security|cross_signing_cached") : (0, _languageHandler._t)("settings|security|cross_signing_not_cached"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", {
scope: "row"
}, (0, _languageHandler._t)("settings|security|cross_signing_self_signing_private_key")), /*#__PURE__*/_react.default.createElement("td", null, selfSigningPrivateKeyCached ? (0, _languageHandler._t)("settings|security|cross_signing_cached") : (0, _languageHandler._t)("settings|security|cross_signing_not_cached"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", {
scope: "row"
}, (0, _languageHandler._t)("settings|security|cross_signing_user_signing_private_key")), /*#__PURE__*/_react.default.createElement("td", null, userSigningPrivateKeyCached ? (0, _languageHandler._t)("settings|security|cross_signing_cached") : (0, _languageHandler._t)("settings|security|cross_signing_not_cached"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("th", {
scope: "row"
}, (0, _languageHandler._t)("settings|security|cross_signing_homeserver_support")), /*#__PURE__*/_react.default.createElement("td", null, homeserverSupportsCrossSigning ? (0, _languageHandler._t)("settings|security|cross_signing_homeserver_support_exists") : (0, _languageHandler._t)("settings|security|cross_signing_not_found")))))), errorSection, actionRow);
}
}
exports.default = CrossSigningPanel;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9tYXRyaXgiLCJfbG9nZ2VyIiwiX2NyeXB0byIsIl9NYXRyaXhDbGllbnRQZWciLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX01vZGFsIiwiX1NwaW5uZXIiLCJfSW50ZXJhY3RpdmVBdXRoRGlhbG9nIiwiX0NvbmZpcm1EZXN0cm95Q3Jvc3NTaWduaW5nRGlhbG9nIiwiX1NldHVwRW5jcnlwdGlvbkRpYWxvZyIsIl9TZWN1cml0eU1hbmFnZXIiLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9TZXR0aW5nc1N1YnNlY3Rpb24iLCJDcm9zc1NpZ25pbmdQYW5lbCIsIlJlYWN0IiwiUHVyZUNvbXBvbmVudCIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJfZGVmaW5lUHJvcGVydHkyIiwiZGVmYXVsdCIsImV2ZW50IiwidHlwZSIsImdldFR5cGUiLCJzdGFydHNXaXRoIiwiZ2V0VXBkYXRlZFN0YXR1cyIsInN0YXRlIiwiY3Jvc3NTaWduaW5nUHJpdmF0ZUtleXNJblN0b3JhZ2UiLCJNb2RhbCIsImNyZWF0ZURpYWxvZyIsIlNldHVwRW5jcnlwdGlvbkRpYWxvZyIsInVuZGVmaW5lZCIsImFjY2Vzc1NlY3JldFN0b3JhZ2UiLCJDb25maXJtRGVzdHJveUNyb3NzU2lnbmluZ0RpYWxvZyIsIm9uRmluaXNoZWQiLCJhY3QiLCJyZXNldENyb3NzU2lnbmluZyIsImVycm9yIiwiY29tcG9uZW50RGlkTW91bnQiLCJjbGkiLCJNYXRyaXhDbGllbnRQZWciLCJzYWZlR2V0Iiwib24iLCJDbGllbnRFdmVudCIsIkFjY291bnREYXRhIiwib25BY2NvdW50RGF0YSIsIkNyeXB0b0V2ZW50IiwiVXNlclRydXN0U3RhdHVzQ2hhbmdlZCIsIm9uU3RhdHVzQ2hhbmdlZCIsIktleXNDaGFuZ2VkIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJ1bm1vdW50ZWQiLCJnZXQiLCJyZW1vdmVMaXN0ZW5lciIsImNyeXB0byIsImdldENyeXB0byIsImNyb3NzU2lnbmluZ1N0YXR1cyIsImdldENyb3NzU2lnbmluZ1N0YXR1cyIsImNyb3NzU2lnbmluZ1B1YmxpY0tleXNPbkRldmljZSIsInB1YmxpY0tleXNPbkRldmljZSIsInByaXZhdGVLZXlzSW5TZWNyZXRTdG9yYWdlIiwibWFzdGVyUHJpdmF0ZUtleUNhY2hlZCIsInByaXZhdGVLZXlzQ2FjaGVkTG9jYWxseSIsIm1hc3RlcktleSIsInNlbGZTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCIsInNlbGZTaWduaW5nS2V5IiwidXNlclNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkIiwidXNlclNpZ25pbmdLZXkiLCJob21lc2VydmVyU3VwcG9ydHNDcm9zc1NpZ25pbmciLCJkb2VzU2VydmVyU3VwcG9ydFVuc3RhYmxlRmVhdHVyZSIsImNyb3NzU2lnbmluZ1JlYWR5IiwiaXNDcm9zc1NpZ25pbmdSZWFkeSIsInNldFN0YXRlIiwid2l0aFNlY3JldFN0b3JhZ2VLZXlDYWNoZSIsImJvb3RzdHJhcENyb3NzU2lnbmluZyIsImF1dGhVcGxvYWREZXZpY2VTaWduaW5nS2V5cyIsIm1ha2VSZXF1ZXN0IiwiZmluaXNoZWQiLCJJbnRlcmFjdGl2ZUF1dGhEaWFsb2ciLCJ0aXRsZSIsIl90IiwibWF0cml4Q2xpZW50IiwiY29uZmlybWVkIiwiRXJyb3IiLCJzZXR1cE5ld0Nyb3NzU2lnbmluZyIsImUiLCJsb2dnZXIiLCJyZW5kZXIiLCJlcnJvclNlY3Rpb24iLCJjcmVhdGVFbGVtZW50IiwiY2xhc3NOYW1lIiwidG9TdHJpbmciLCJzdW1tYXJpc2VkU3RhdHVzIiwiU2V0dGluZ3NTdWJzZWN0aW9uVGV4dCIsImtleXNFeGlzdEFueXdoZXJlIiwia2V5c0V4aXN0RXZlcnl3aGVyZSIsImFjdGlvbnMiLCJidXR0b25DYXB0aW9uIiwicHVzaCIsImtleSIsImtpbmQiLCJvbkNsaWNrIiwib25Cb290c3RyYXBDbGljayIsIm9uUmVzZXRDcm9zc1NpZ25pbmdDbGljayIsImFjdGlvblJvdyIsImxlbmd0aCIsIkZyYWdtZW50Iiwic2NvcGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3Mvc2V0dGluZ3MvQ3Jvc3NTaWduaW5nUGFuZWwudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE5LCAyMDIwIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IENsaWVudEV2ZW50LCBNYXRyaXhFdmVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcbmltcG9ydCB7IENyeXB0b0V2ZW50IH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL2NyeXB0b1wiO1xuXG5pbXBvcnQgeyBNYXRyaXhDbGllbnRQZWcgfSBmcm9tIFwiLi4vLi4vLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCBNb2RhbCBmcm9tIFwiLi4vLi4vLi4vTW9kYWxcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuLi9lbGVtZW50cy9TcGlubmVyXCI7XG5pbXBvcnQgSW50ZXJhY3RpdmVBdXRoRGlhbG9nIGZyb20gXCIuLi9kaWFsb2dzL0ludGVyYWN0aXZlQXV0aERpYWxvZ1wiO1xuaW1wb3J0IENvbmZpcm1EZXN0cm95Q3Jvc3NTaWduaW5nRGlhbG9nIGZyb20gXCIuLi9kaWFsb2dzL3NlY3VyaXR5L0NvbmZpcm1EZXN0cm95Q3Jvc3NTaWduaW5nRGlhbG9nXCI7XG5pbXBvcnQgU2V0dXBFbmNyeXB0aW9uRGlhbG9nIGZyb20gXCIuLi9kaWFsb2dzL3NlY3VyaXR5L1NldHVwRW5jcnlwdGlvbkRpYWxvZ1wiO1xuaW1wb3J0IHsgYWNjZXNzU2VjcmV0U3RvcmFnZSwgd2l0aFNlY3JldFN0b3JhZ2VLZXlDYWNoZSB9IGZyb20gXCIuLi8uLi8uLi9TZWN1cml0eU1hbmFnZXJcIjtcbmltcG9ydCBBY2Nlc3NpYmxlQnV0dG9uIGZyb20gXCIuLi9lbGVtZW50cy9BY2Nlc3NpYmxlQnV0dG9uXCI7XG5pbXBvcnQgeyBTZXR0aW5nc1N1YnNlY3Rpb25UZXh0IH0gZnJvbSBcIi4vc2hhcmVkL1NldHRpbmdzU3Vic2VjdGlvblwiO1xuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBlcnJvcjogYm9vbGVhbjtcbiAgICBjcm9zc1NpZ25pbmdQdWJsaWNLZXlzT25EZXZpY2U/OiBib29sZWFuO1xuICAgIGNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlPzogYm9vbGVhbjtcbiAgICBtYXN0ZXJQcml2YXRlS2V5Q2FjaGVkPzogYm9vbGVhbjtcbiAgICBzZWxmU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQ/OiBib29sZWFuO1xuICAgIHVzZXJTaWduaW5nUHJpdmF0ZUtleUNhY2hlZD86IGJvb2xlYW47XG4gICAgaG9tZXNlcnZlclN1cHBvcnRzQ3Jvc3NTaWduaW5nPzogYm9vbGVhbjtcbiAgICBjcm9zc1NpZ25pbmdSZWFkeT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENyb3NzU2lnbmluZ1BhbmVsIGV4dGVuZHMgUmVhY3QuUHVyZUNvbXBvbmVudDx7fSwgSVN0YXRlPiB7XG4gICAgcHJpdmF0ZSB1bm1vdW50ZWQgPSBmYWxzZTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczoge30pIHtcbiAgICAgICAgc3VwZXIocHJvcHMpO1xuXG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBlcnJvcjogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZE1vdW50KCk6IHZvaWQge1xuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpO1xuICAgICAgICBjbGkub24oQ2xpZW50RXZlbnQuQWNjb3VudERhdGEsIHRoaXMub25BY2NvdW50RGF0YSk7XG4gICAgICAgIGNsaS5vbihDcnlwdG9FdmVudC5Vc2VyVHJ1c3RTdGF0dXNDaGFuZ2VkLCB0aGlzLm9uU3RhdHVzQ2hhbmdlZCk7XG4gICAgICAgIGNsaS5vbihDcnlwdG9FdmVudC5LZXlzQ2hhbmdlZCwgdGhpcy5vblN0YXR1c0NoYW5nZWQpO1xuICAgICAgICB0aGlzLmdldFVwZGF0ZWRTdGF0dXMoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudW5tb3VudGVkID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgY2xpID0gTWF0cml4Q2xpZW50UGVnLmdldCgpO1xuICAgICAgICBpZiAoIWNsaSkgcmV0dXJuO1xuICAgICAgICBjbGkucmVtb3ZlTGlzdGVuZXIoQ2xpZW50RXZlbnQuQWNjb3VudERhdGEsIHRoaXMub25BY2NvdW50RGF0YSk7XG4gICAgICAgIGNsaS5yZW1vdmVMaXN0ZW5lcihDcnlwdG9FdmVudC5Vc2VyVHJ1c3RTdGF0dXNDaGFuZ2VkLCB0aGlzLm9uU3RhdHVzQ2hhbmdlZCk7XG4gICAgICAgIGNsaS5yZW1vdmVMaXN0ZW5lcihDcnlwdG9FdmVudC5LZXlzQ2hhbmdlZCwgdGhpcy5vblN0YXR1c0NoYW5nZWQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25BY2NvdW50RGF0YSA9IChldmVudDogTWF0cml4RXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgdHlwZSA9IGV2ZW50LmdldFR5cGUoKTtcbiAgICAgICAgaWYgKHR5cGUuc3RhcnRzV2l0aChcIm0uY3Jvc3Nfc2lnbmluZ1wiKSB8fCB0eXBlLnN0YXJ0c1dpdGgoXCJtLnNlY3JldF9zdG9yYWdlXCIpKSB7XG4gICAgICAgICAgICB0aGlzLmdldFVwZGF0ZWRTdGF0dXMoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uQm9vdHN0cmFwQ2xpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlKSB7XG4gICAgICAgICAgICBNb2RhbC5jcmVhdGVEaWFsb2coU2V0dXBFbmNyeXB0aW9uRGlhbG9nLCB7fSwgdW5kZWZpbmVkLCAvKiBwcmlvcml0eSA9ICovIGZhbHNlLCAvKiBzdGF0aWMgPSAqLyB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRyaWdnZXIgdGhlIGZsb3cgdG8gc2V0IHVwIHNlY3VyZSBiYWNrdXAsIHdoaWNoIGlzIHdoYXQgdGhpcyB3aWxsIGRvIHdoZW4gaW5cbiAgICAgICAgICAgIC8vIHRoZSBhcHByb3ByaWF0ZSBzdGF0ZS5cbiAgICAgICAgICAgIGFjY2Vzc1NlY3JldFN0b3JhZ2UoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uU3RhdHVzQ2hhbmdlZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5nZXRVcGRhdGVkU3RhdHVzKCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0VXBkYXRlZFN0YXR1cygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgY2xpID0gTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKTtcbiAgICAgICAgY29uc3QgY3J5cHRvID0gY2xpLmdldENyeXB0bygpO1xuICAgICAgICBpZiAoIWNyeXB0bykgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGNyb3NzU2lnbmluZ1N0YXR1cyA9IGF3YWl0IGNyeXB0by5nZXRDcm9zc1NpZ25pbmdTdGF0dXMoKTtcbiAgICAgICAgY29uc3QgY3Jvc3NTaWduaW5nUHVibGljS2V5c09uRGV2aWNlID0gY3Jvc3NTaWduaW5nU3RhdHVzLnB1YmxpY0tleXNPbkRldmljZTtcbiAgICAgICAgY29uc3QgY3Jvc3NTaWduaW5nUHJpdmF0ZUtleXNJblN0b3JhZ2UgPSBjcm9zc1NpZ25pbmdTdGF0dXMucHJpdmF0ZUtleXNJblNlY3JldFN0b3JhZ2U7XG4gICAgICAgIGNvbnN0IG1hc3RlclByaXZhdGVLZXlDYWNoZWQgPSBjcm9zc1NpZ25pbmdTdGF0dXMucHJpdmF0ZUtleXNDYWNoZWRMb2NhbGx5Lm1hc3RlcktleTtcbiAgICAgICAgY29uc3Qgc2VsZlNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkID0gY3Jvc3NTaWduaW5nU3RhdHVzLnByaXZhdGVLZXlzQ2FjaGVkTG9jYWxseS5zZWxmU2lnbmluZ0tleTtcbiAgICAgICAgY29uc3QgdXNlclNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkID0gY3Jvc3NTaWduaW5nU3RhdHVzLnByaXZhdGVLZXlzQ2FjaGVkTG9jYWxseS51c2VyU2lnbmluZ0tleTtcbiAgICAgICAgY29uc3QgaG9tZXNlcnZlclN1cHBvcnRzQ3Jvc3NTaWduaW5nID1cbiAgICAgICAgICAgIGF3YWl0IGNsaS5kb2VzU2VydmVyU3VwcG9ydFVuc3RhYmxlRmVhdHVyZShcIm9yZy5tYXRyaXguZTJlX2Nyb3NzX3NpZ25pbmdcIik7XG4gICAgICAgIGNvbnN0IGNyb3NzU2lnbmluZ1JlYWR5ID0gYXdhaXQgY3J5cHRvLmlzQ3Jvc3NTaWduaW5nUmVhZHkoKTtcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1B1YmxpY0tleXNPbkRldmljZSxcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlLFxuICAgICAgICAgICAgbWFzdGVyUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIHNlbGZTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIHVzZXJTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIGhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZyxcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1JlYWR5LFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNldCB0aGUgdXNlcidzIGNyb3NzLXNpZ25pbmcga2V5cy5cbiAgICAgKi9cbiAgICBwcml2YXRlIGFzeW5jIHJlc2V0Q3Jvc3NTaWduaW5nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3I6IGZhbHNlIH0pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgY2xpID0gTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKTtcbiAgICAgICAgICAgIGF3YWl0IHdpdGhTZWNyZXRTdG9yYWdlS2V5Q2FjaGUoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNsaS5nZXRDcnlwdG8oKSEuYm9vdHN0cmFwQ3Jvc3NTaWduaW5nKHtcbiAgICAgICAgICAgICAgICAgICAgYXV0aFVwbG9hZERldmljZVNpZ25pbmdLZXlzOiBhc3luYyAobWFrZVJlcXVlc3QpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZmluaXNoZWQgfSA9IE1vZGFsLmNyZWF0ZURpYWxvZyhJbnRlcmFjdGl2ZUF1dGhEaWFsb2csIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogX3QoXCJlbmNyeXB0aW9ufGJvb3RzdHJhcF90aXRsZVwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXhDbGllbnQ6IGNsaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlUmVxdWVzdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgW2NvbmZpcm1lZF0gPSBhd2FpdCBmaW5pc2hlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29uZmlybWVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ3Jvc3Mtc2lnbmluZyBrZXkgdXBsb2FkIGF1dGggY2FuY2VsZWRcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNldHVwTmV3Q3Jvc3NTaWduaW5nOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvcjogdHJ1ZSB9KTtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkVycm9yIGJvb3RzdHJhcHBpbmcgY3Jvc3Mtc2lnbmluZ1wiLCBlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51bm1vdW50ZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5nZXRVcGRhdGVkU3RhdHVzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZm9yIHdoZW4gdGhlIHVzZXIgY2xpY2tzIHRoZSBcInJlc2V0IGNyb3NzIHNpZ25pbmdcIiBidXR0b24uXG4gICAgICpcbiAgICAgKiBTaG93cyBhIGNvbmZpcm1hdGlvbiBkaWFsb2csIGFuZCB0aGVuIGRvZXMgdGhlIHJlc2V0IGlmIGNvbmZpcm1lZC5cbiAgICAgKi9cbiAgICBwcml2YXRlIG9uUmVzZXRDcm9zc1NpZ25pbmdDbGljayA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgTW9kYWwuY3JlYXRlRGlhbG9nKENvbmZpcm1EZXN0cm95Q3Jvc3NTaWduaW5nRGlhbG9nLCB7XG4gICAgICAgICAgICBvbkZpbmlzaGVkOiBhc3luYyAoYWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFhY3QpIHJldHVybjtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2V0Q3Jvc3NTaWduaW5nKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHVibGljIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1B1YmxpY0tleXNPbkRldmljZSxcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlLFxuICAgICAgICAgICAgbWFzdGVyUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIHNlbGZTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIHVzZXJTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIGhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZyxcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1JlYWR5LFxuICAgICAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgICBsZXQgZXJyb3JTZWN0aW9uO1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yU2VjdGlvbiA9IDxkaXYgY2xhc3NOYW1lPVwiZXJyb3JcIj57ZXJyb3IudG9TdHJpbmcoKX08L2Rpdj47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3VtbWFyaXNlZFN0YXR1cztcbiAgICAgICAgaWYgKGhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdW1tYXJpc2VkU3RhdHVzID0gPFNwaW5uZXIgLz47XG4gICAgICAgIH0gZWxzZSBpZiAoIWhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZykge1xuICAgICAgICAgICAgc3VtbWFyaXNlZFN0YXR1cyA9IChcbiAgICAgICAgICAgICAgICA8U2V0dGluZ3NTdWJzZWN0aW9uVGV4dCBkYXRhLXRlc3RpZD1cInN1bW1hcmlzZWQtc3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcImVuY3J5cHRpb258Y3Jvc3Nfc2lnbmluZ191bnN1cHBvcnRlZFwiKX1cbiAgICAgICAgICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvblRleHQ+XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKGNyb3NzU2lnbmluZ1JlYWR5ICYmIGNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlKSB7XG4gICAgICAgICAgICBzdW1tYXJpc2VkU3RhdHVzID0gKFxuICAgICAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb25UZXh0IGRhdGEtdGVzdGlkPVwic3VtbWFyaXNlZC1zdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAg4pyFIHtfdChcImVuY3J5cHRpb258Y3Jvc3Nfc2lnbmluZ19yZWFkeVwiKX1cbiAgICAgICAgICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvblRleHQ+XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKGNyb3NzU2lnbmluZ1JlYWR5ICYmICFjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZSkge1xuICAgICAgICAgICAgc3VtbWFyaXNlZFN0YXR1cyA9IChcbiAgICAgICAgICAgICAgICA8U2V0dGluZ3NTdWJzZWN0aW9uVGV4dCBkYXRhLXRlc3RpZD1cInN1bW1hcmlzZWQtc3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgIOKaoO+4jyB7X3QoXCJlbmNyeXB0aW9ufGNyb3NzX3NpZ25pbmdfcmVhZHlfbm9fYmFja3VwXCIpfVxuICAgICAgICAgICAgICAgIDwvU2V0dGluZ3NTdWJzZWN0aW9uVGV4dD5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoY3Jvc3NTaWduaW5nUHJpdmF0ZUtleXNJblN0b3JhZ2UpIHtcbiAgICAgICAgICAgIHN1bW1hcmlzZWRTdGF0dXMgPSAoXG4gICAgICAgICAgICAgICAgPFNldHRpbmdzU3Vic2VjdGlvblRleHQgZGF0YS10ZXN0aWQ9XCJzdW1tYXJpc2VkLXN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJlbmNyeXB0aW9ufGNyb3NzX3NpZ25pbmdfdW50cnVzdGVkXCIpfVxuICAgICAgICAgICAgICAgIDwvU2V0dGluZ3NTdWJzZWN0aW9uVGV4dD5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdW1tYXJpc2VkU3RhdHVzID0gKFxuICAgICAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb25UZXh0IGRhdGEtdGVzdGlkPVwic3VtbWFyaXNlZC1zdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAge190KFwiZW5jcnlwdGlvbnxjcm9zc19zaWduaW5nX25vdF9yZWFkeVwiKX1cbiAgICAgICAgICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvblRleHQ+XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qga2V5c0V4aXN0QW55d2hlcmUgPVxuICAgICAgICAgICAgY3Jvc3NTaWduaW5nUHVibGljS2V5c09uRGV2aWNlIHx8XG4gICAgICAgICAgICBjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZSB8fFxuICAgICAgICAgICAgbWFzdGVyUHJpdmF0ZUtleUNhY2hlZCB8fFxuICAgICAgICAgICAgc2VsZlNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkIHx8XG4gICAgICAgICAgICB1c2VyU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQ7XG4gICAgICAgIGNvbnN0IGtleXNFeGlzdEV2ZXJ5d2hlcmUgPVxuICAgICAgICAgICAgY3Jvc3NTaWduaW5nUHVibGljS2V5c09uRGV2aWNlICYmXG4gICAgICAgICAgICBjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZSAmJlxuICAgICAgICAgICAgbWFzdGVyUHJpdmF0ZUtleUNhY2hlZCAmJlxuICAgICAgICAgICAgc2VsZlNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkICYmXG4gICAgICAgICAgICB1c2VyU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQ7XG5cbiAgICAgICAgY29uc3QgYWN0aW9uczogSlNYLkVsZW1lbnRbXSA9IFtdO1xuXG4gICAgICAgIC8vIFRPRE86IGRldGVybWluZSBob3cgYmV0dGVyIHRvIGV4cG9zZSB0aGlzIHRvIHVzZXJzIGluIGFkZGl0aW9uIHRvIHByb21wdHMgYXQgbG9naW4vdG9hc3RcbiAgICAgICAgaWYgKCFrZXlzRXhpc3RFdmVyeXdoZXJlICYmIGhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZykge1xuICAgICAgICAgICAgbGV0IGJ1dHRvbkNhcHRpb24gPSBfdChcImVuY3J5cHRpb258c2V0X3VwX3RvYXN0X3RpdGxlXCIpO1xuICAgICAgICAgICAgaWYgKGNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlKSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uQ2FwdGlvbiA9IF90KFwiZW5jcnlwdGlvbnx2ZXJpZnlfdG9hc3RfdGl0bGVcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24ga2V5PVwic2V0dXBcIiBraW5kPVwicHJpbWFyeV9vdXRsaW5lXCIgb25DbGljaz17dGhpcy5vbkJvb3RzdHJhcENsaWNrfT5cbiAgICAgICAgICAgICAgICAgICAge2J1dHRvbkNhcHRpb259XG4gICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPixcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoa2V5c0V4aXN0QW55d2hlcmUpIHtcbiAgICAgICAgICAgIGFjdGlvbnMucHVzaChcbiAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvbiBrZXk9XCJyZXNldFwiIGtpbmQ9XCJkYW5nZXJfb3V0bGluZVwiIG9uQ2xpY2s9e3RoaXMub25SZXNldENyb3NzU2lnbmluZ0NsaWNrfT5cbiAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufHJlc2V0XCIpfVxuICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj4sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGFjdGlvblJvdztcbiAgICAgICAgaWYgKGFjdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBhY3Rpb25Sb3cgPSA8ZGl2IGNsYXNzTmFtZT1cIm14X0Nyb3NzU2lnbmluZ1BhbmVsX2J1dHRvblJvd1wiPnthY3Rpb25zfTwvZGl2PjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIHtzdW1tYXJpc2VkU3RhdHVzfVxuICAgICAgICAgICAgICAgIDxkZXRhaWxzPlxuICAgICAgICAgICAgICAgICAgICA8c3VtbWFyeSBjbGFzc05hbWU9XCJteF9Dcm9zc1NpZ25pbmdQYW5lbF9hZHZhbmNlZFwiPntfdChcImNvbW1vbnxhZHZhbmNlZFwiKX08L3N1bW1hcnk+XG4gICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzc05hbWU9XCJteF9Dcm9zc1NpZ25pbmdQYW5lbF9zdGF0dXNMaXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJyb3dcIj57X3QoXCJzZXR0aW5nc3xzZWN1cml0eXxjcm9zc19zaWduaW5nX3B1YmxpY19rZXlzXCIpfTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtjcm9zc1NpZ25pbmdQdWJsaWNLZXlzT25EZXZpY2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF90KFwic2V0dGluZ3N8c2VjdXJpdHl8Y3Jvc3Nfc2lnbmluZ19pbl9tZW1vcnlcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF90KFwic2V0dGluZ3N8c2VjdXJpdHl8Y3Jvc3Nfc2lnbmluZ19ub3RfZm91bmRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cInJvd1wiPntfdChcInNldHRpbmdzfHNlY3VyaXR5fGNyb3NzX3NpZ25pbmdfcHJpdmF0ZV9rZXlzXCIpfTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJzZXR0aW5nc3xzZWN1cml0eXxjcm9zc19zaWduaW5nX2luXzRzXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInNldHRpbmdzfHNlY3VyaXR5fGNyb3NzX3NpZ25pbmdfbm90X2luXzRzXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJyb3dcIj57X3QoXCJzZXR0aW5nc3xzZWN1cml0eXxjcm9zc19zaWduaW5nX21hc3Rlcl9wcml2YXRlX0tleVwiKX08L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7bWFzdGVyUHJpdmF0ZUtleUNhY2hlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJzZXR0aW5nc3xzZWN1cml0eXxjcm9zc19zaWduaW5nX2NhY2hlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogX3QoXCJzZXR0aW5nc3xzZWN1cml0eXxjcm9zc19zaWduaW5nX25vdF9jYWNoZWRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cInJvd1wiPntfdChcInNldHRpbmdzfHNlY3VyaXR5fGNyb3NzX3NpZ25pbmdfc2VsZl9zaWduaW5nX3ByaXZhdGVfa2V5XCIpfTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtzZWxmU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF90KFwic2V0dGluZ3N8c2VjdXJpdHl8Y3Jvc3Nfc2lnbmluZ19jYWNoZWRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF90KFwic2V0dGluZ3N8c2VjdXJpdHl8Y3Jvc3Nfc2lnbmluZ19ub3RfY2FjaGVkXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJyb3dcIj57X3QoXCJzZXR0aW5nc3xzZWN1cml0eXxjcm9zc19zaWduaW5nX3VzZXJfc2lnbmluZ19wcml2YXRlX2tleVwiKX08L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dXNlclNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBfdChcInNldHRpbmdzfHNlY3VyaXR5fGNyb3NzX3NpZ25pbmdfY2FjaGVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInNldHRpbmdzfHNlY3VyaXR5fGNyb3NzX3NpZ25pbmdfbm90X2NhY2hlZFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwicm93XCI+e190KFwic2V0dGluZ3N8c2VjdXJpdHl8Y3Jvc3Nfc2lnbmluZ19ob21lc2VydmVyX3N1cHBvcnRcIil9PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2hvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJzZXR0aW5nc3xzZWN1cml0eXxjcm9zc19zaWduaW5nX2hvbWVzZXJ2ZXJfc3VwcG9ydF9leGlzdHNcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF90KFwic2V0dGluZ3N8c2VjdXJpdHl8Y3Jvc3Nfc2lnbmluZ19ub3RfZm91bmRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgICAgICAgICAgIHtlcnJvclNlY3Rpb259XG4gICAgICAgICAgICAgICAge2FjdGlvblJvd31cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxPQUFBLEdBQUFILE9BQUE7QUFFQSxJQUFBSSxnQkFBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssZ0JBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLE1BQUEsR0FBQVAsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFPLFFBQUEsR0FBQVIsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFRLHNCQUFBLEdBQUFULHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBUyxpQ0FBQSxHQUFBVixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVUsc0JBQUEsR0FBQVgsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFXLGdCQUFBLEdBQUFYLE9BQUE7QUFDQSxJQUFBWSxpQkFBQSxHQUFBYixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQWEsbUJBQUEsR0FBQWIsT0FBQTtBQXRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUE2QmUsTUFBTWMsaUJBQWlCLFNBQVNDLGNBQUssQ0FBQ0MsYUFBYSxDQUFhO0VBR3BFQyxXQUFXQSxDQUFDQyxLQUFTLEVBQUU7SUFDMUIsS0FB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