UNPKG

matrix-react-sdk

Version:
234 lines (229 loc) 44.5 kB
"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 = _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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