UNPKG

matrix-react-sdk

Version:
321 lines (312 loc) 55.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.IgnoredUser = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _utils = require("matrix-js-sdk/src/utils"); var _matrix = require("matrix-js-sdk/src/matrix"); var _types = require("matrix-js-sdk/src/types"); var _logger = require("matrix-js-sdk/src/logger"); var _languageHandler = require("../../../../../languageHandler"); var _MatrixClientPeg = require("../../../../../MatrixClientPeg"); var _AccessibleButton = _interopRequireDefault(require("../../../elements/AccessibleButton")); var _dispatcher = _interopRequireDefault(require("../../../../../dispatcher/dispatcher")); var _SettingLevel = require("../../../../../settings/SettingLevel"); var _SecureBackupPanel = _interopRequireDefault(require("../../SecureBackupPanel")); var _SettingsStore = _interopRequireDefault(require("../../../../../settings/SettingsStore")); var _UIFeature = require("../../../../../settings/UIFeature"); var _CryptographyPanel = _interopRequireDefault(require("../../CryptographyPanel")); var _SettingsFlag = _interopRequireDefault(require("../../../elements/SettingsFlag")); var _CrossSigningPanel = _interopRequireDefault(require("../../CrossSigningPanel")); var _EventIndexPanel = _interopRequireDefault(require("../../EventIndexPanel")); var _InlineSpinner = _interopRequireDefault(require("../../../elements/InlineSpinner")); var _PosthogAnalytics = require("../../../../../PosthogAnalytics"); var _AnalyticsLearnMoreDialog = require("../../../dialogs/AnalyticsLearnMoreDialog"); var _rooms = require("../../../../../utils/rooms"); var _SettingsTab = _interopRequireDefault(require("../SettingsTab")); var _SettingsSection = require("../../shared/SettingsSection"); var _SettingsSubsection = _interopRequireWildcard(require("../../shared/SettingsSubsection")); var _useOwnDevices = require("../../devices/useOwnDevices"); var _DiscoverySettings = _interopRequireDefault(require("../../discovery/DiscoverySettings")); var _SetIntegrationManager = _interopRequireDefault(require("../../SetIntegrationManager")); 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 2019-2023 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. */ const DehydratedDeviceStatus = () => { const { dehydratedDeviceId } = (0, _useOwnDevices.useOwnDevices)(); if (dehydratedDeviceId) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_SettingsSubsection_content" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_SettingsFlag_label" }, (0, _languageHandler._t)("settings|security|dehydrated_device_enabled")), /*#__PURE__*/_react.default.createElement("div", { className: "mx_SettingsSubsection_text" }, (0, _languageHandler._t)("settings|security|dehydrated_device_description"))); } else { return null; } }; class IgnoredUser extends _react.default.Component { constructor(...args) { super(...args); (0, _defineProperty2.default)(this, "onUnignoreClicked", () => { this.props.onUnignored(this.props.userId); }); } render() { const id = `mx_SecurityUserSettingsTab_ignoredUser_${this.props.userId}`; return /*#__PURE__*/_react.default.createElement("div", { className: "mx_SecurityUserSettingsTab_ignoredUser" }, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: this.onUnignoreClicked, kind: "primary_sm", "aria-describedby": id, disabled: this.props.inProgress }, (0, _languageHandler._t)("action|unignore")), /*#__PURE__*/_react.default.createElement("span", { id: id }, this.props.userId)); } } exports.IgnoredUser = IgnoredUser; class SecurityUserSettingsTab extends _react.default.Component { constructor(props) { super(props); // Get rooms we're invited to (0, _defineProperty2.default)(this, "dispatcherRef", void 0); (0, _defineProperty2.default)(this, "onAction", ({ action }) => { if (action === "ignore_state_changed") { const ignoredUserIds = _MatrixClientPeg.MatrixClientPeg.safeGet().getIgnoredUsers(); const newWaitingUnignored = this.state.waitingUnignored.filter(e => ignoredUserIds.includes(e)); this.setState({ ignoredUserIds, waitingUnignored: newWaitingUnignored }); } }); (0, _defineProperty2.default)(this, "onMyMembership", (room, membership) => { if (room.isSpaceRoom()) { return; } if (membership === _types.KnownMembership.Invite) { this.addInvitedRoom(room); } else if (this.state.invitedRoomIds.has(room.roomId)) { // The user isn't invited anymore this.removeInvitedRoom(room.roomId); } }); (0, _defineProperty2.default)(this, "addInvitedRoom", room => { this.setState(({ invitedRoomIds }) => ({ invitedRoomIds: new Set(invitedRoomIds).add(room.roomId) })); }); (0, _defineProperty2.default)(this, "removeInvitedRoom", roomId => { this.setState(({ invitedRoomIds }) => { const newInvitedRoomIds = new Set(invitedRoomIds); newInvitedRoomIds.delete(roomId); return { invitedRoomIds: newInvitedRoomIds }; }); }); (0, _defineProperty2.default)(this, "onUserUnignored", async userId => { const { ignoredUserIds, waitingUnignored } = this.state; const currentlyIgnoredUserIds = ignoredUserIds.filter(e => !waitingUnignored.includes(e)); const index = currentlyIgnoredUserIds.indexOf(userId); if (index !== -1) { currentlyIgnoredUserIds.splice(index, 1); this.setState(({ waitingUnignored }) => ({ waitingUnignored: [...waitingUnignored, userId] })); _MatrixClientPeg.MatrixClientPeg.safeGet().setIgnoredUsers(currentlyIgnoredUserIds); } }); (0, _defineProperty2.default)(this, "getInvitedRooms", () => { return _MatrixClientPeg.MatrixClientPeg.safeGet().getRooms().filter(r => { return r.hasMembershipState(_MatrixClientPeg.MatrixClientPeg.safeGet().getUserId(), _types.KnownMembership.Invite); }); }); (0, _defineProperty2.default)(this, "manageInvites", async accept => { this.setState({ managingInvites: true }); // iterate with a normal for loop in order to retry on action failure const invitedRoomIdsValues = Array.from(this.state.invitedRoomIds); // Execute all acceptances/rejections sequentially const cli = _MatrixClientPeg.MatrixClientPeg.safeGet(); const action = accept ? cli.joinRoom.bind(cli) : cli.leave.bind(cli); for (let i = 0; i < invitedRoomIdsValues.length; i++) { const roomId = invitedRoomIdsValues[i]; // Accept/reject invite await action(roomId).then(() => { // No error, update invited rooms button this.removeInvitedRoom(roomId); }, async e => { // Action failure if (e.errcode === "M_LIMIT_EXCEEDED") { // Add a delay between each invite change in order to avoid rate // limiting by the server. await (0, _utils.sleep)(e.retry_after_ms || 2500); // Redo last action i--; } else { // Print out error with joining/leaving room _logger.logger.warn(e); } }); } this.setState({ managingInvites: false }); }); (0, _defineProperty2.default)(this, "onAcceptAllInvitesClicked", () => { this.manageInvites(true); }); (0, _defineProperty2.default)(this, "onRejectAllInvitesClicked", () => { this.manageInvites(false); }); const _invitedRoomIds = new Set(this.getInvitedRooms().map(room => room.roomId)); this.state = { ignoredUserIds: _MatrixClientPeg.MatrixClientPeg.safeGet().getIgnoredUsers(), waitingUnignored: [], managingInvites: false, invitedRoomIds: _invitedRoomIds }; } componentDidMount() { this.dispatcherRef = _dispatcher.default.register(this.onAction); _MatrixClientPeg.MatrixClientPeg.safeGet().on(_matrix.RoomEvent.MyMembership, this.onMyMembership); _MatrixClientPeg.MatrixClientPeg.safeGet().getVersions().then(versions => this.setState({ versions })); } componentWillUnmount() { if (this.dispatcherRef) _dispatcher.default.unregister(this.dispatcherRef); _MatrixClientPeg.MatrixClientPeg.safeGet().removeListener(_matrix.RoomEvent.MyMembership, this.onMyMembership); } renderIgnoredUsers() { const { waitingUnignored, ignoredUserIds } = this.state; const userIds = !ignoredUserIds?.length ? (0, _languageHandler._t)("settings|security|ignore_users_empty") : ignoredUserIds.map(u => { return /*#__PURE__*/_react.default.createElement(IgnoredUser, { userId: u, onUnignored: this.onUserUnignored, key: u, inProgress: waitingUnignored.includes(u) }); }); return /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|security|ignore_users_section") }, /*#__PURE__*/_react.default.createElement(_SettingsSubsection.SettingsSubsectionText, null, userIds)); } renderManageInvites() { const { invitedRoomIds } = this.state; if (invitedRoomIds.size === 0) { return null; } return /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|security|bulk_options_section") }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_SecurityUserSettingsTab_bulkOptions" }, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: this.onAcceptAllInvitesClicked, kind: "primary_outline", disabled: this.state.managingInvites }, (0, _languageHandler._t)("settings|security|bulk_options_accept_all_invites", { invitedRooms: invitedRoomIds.size })), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: this.onRejectAllInvitesClicked, kind: "danger_outline", disabled: this.state.managingInvites }, (0, _languageHandler._t)("settings|security|bulk_options_reject_all_invites", { invitedRooms: invitedRoomIds.size })), this.state.managingInvites ? /*#__PURE__*/_react.default.createElement(_InlineSpinner.default, null) : /*#__PURE__*/_react.default.createElement("div", null))); } render() { const secureBackup = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("common|secure_backup") }, /*#__PURE__*/_react.default.createElement(_SecureBackupPanel.default, null), /*#__PURE__*/_react.default.createElement(DehydratedDeviceStatus, null)); const eventIndex = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|security|message_search_section") }, /*#__PURE__*/_react.default.createElement(_EventIndexPanel.default, null)); // XXX: There's no such panel in the current cross-signing designs, but // it's useful to have for testing the feature. If there's no interest // in having advanced details here once all flows are implemented, we // can remove this. const crossSigning = /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("common|cross_signing") }, /*#__PURE__*/_react.default.createElement(_CrossSigningPanel.default, null)); let warning; if (!(0, _rooms.privateShouldBeEncrypted)(_MatrixClientPeg.MatrixClientPeg.safeGet())) { warning = /*#__PURE__*/_react.default.createElement("div", { className: "mx_SecurityUserSettingsTab_warning" }, (0, _languageHandler._t)("settings|security|e2ee_default_disabled_warning")); } let privacySection; if (_PosthogAnalytics.PosthogAnalytics.instance.isEnabled()) { const onClickAnalyticsLearnMore = () => { (0, _AnalyticsLearnMoreDialog.showDialog)({ primaryButton: (0, _languageHandler._t)("action|ok"), hasCancel: false }); }; privacySection = /*#__PURE__*/_react.default.createElement(_SettingsSection.SettingsSection, { heading: (0, _languageHandler._t)("common|privacy") }, /*#__PURE__*/_react.default.createElement(_DiscoverySettings.default, null), /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("common|analytics"), description: (0, _languageHandler._t)("settings|security|analytics_description") }, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { kind: "link", onClick: onClickAnalyticsLearnMore }, (0, _languageHandler._t)("action|learn_more")), _PosthogAnalytics.PosthogAnalytics.instance.isEnabled() && /*#__PURE__*/_react.default.createElement(_SettingsFlag.default, { name: "pseudonymousAnalyticsOptIn", level: _SettingLevel.SettingLevel.ACCOUNT })), /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|sessions|title") }, /*#__PURE__*/_react.default.createElement(_SettingsFlag.default, { name: "deviceClientInformationOptIn", level: _SettingLevel.SettingLevel.ACCOUNT }))); } let advancedSection; if (_SettingsStore.default.getValue(_UIFeature.UIFeature.AdvancedSettings)) { const ignoreUsersPanel = this.renderIgnoredUsers(); const invitesPanel = this.renderManageInvites(); // only show the section if there's something to show if (ignoreUsersPanel || invitesPanel) { advancedSection = /*#__PURE__*/_react.default.createElement(_SettingsSection.SettingsSection, { heading: (0, _languageHandler._t)("common|advanced") }, ignoreUsersPanel, invitesPanel); } } return /*#__PURE__*/_react.default.createElement(_SettingsTab.default, null, warning, /*#__PURE__*/_react.default.createElement(_SetIntegrationManager.default, null), /*#__PURE__*/_react.default.createElement(_SettingsSection.SettingsSection, { heading: (0, _languageHandler._t)("settings|security|encryption_section") }, secureBackup, eventIndex, crossSigning, /*#__PURE__*/_react.default.createElement(_CryptographyPanel.default, null)), privacySection, advancedSection); } } exports.default = SecurityUserSettingsTab; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl91dGlscyIsIl9tYXRyaXgiLCJfdHlwZXMiLCJfbG9nZ2VyIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9NYXRyaXhDbGllbnRQZWciLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9kaXNwYXRjaGVyIiwiX1NldHRpbmdMZXZlbCIsIl9TZWN1cmVCYWNrdXBQYW5lbCIsIl9TZXR0aW5nc1N0b3JlIiwiX1VJRmVhdHVyZSIsIl9DcnlwdG9ncmFwaHlQYW5lbCIsIl9TZXR0aW5nc0ZsYWciLCJfQ3Jvc3NTaWduaW5nUGFuZWwiLCJfRXZlbnRJbmRleFBhbmVsIiwiX0lubGluZVNwaW5uZXIiLCJfUG9zdGhvZ0FuYWx5dGljcyIsIl9BbmFseXRpY3NMZWFybk1vcmVEaWFsb2ciLCJfcm9vbXMiLCJfU2V0dGluZ3NUYWIiLCJfU2V0dGluZ3NTZWN0aW9uIiwiX1NldHRpbmdzU3Vic2VjdGlvbiIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX3VzZU93bkRldmljZXMiLCJfRGlzY292ZXJ5U2V0dGluZ3MiLCJfU2V0SW50ZWdyYXRpb25NYW5hZ2VyIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiRGVoeWRyYXRlZERldmljZVN0YXR1cyIsImRlaHlkcmF0ZWREZXZpY2VJZCIsInVzZU93bkRldmljZXMiLCJjcmVhdGVFbGVtZW50IiwiY2xhc3NOYW1lIiwiX3QiLCJJZ25vcmVkVXNlciIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJhcmdzIiwiX2RlZmluZVByb3BlcnR5MiIsInByb3BzIiwib25Vbmlnbm9yZWQiLCJ1c2VySWQiLCJyZW5kZXIiLCJpZCIsIm9uQ2xpY2siLCJvblVuaWdub3JlQ2xpY2tlZCIsImtpbmQiLCJkaXNhYmxlZCIsImluUHJvZ3Jlc3MiLCJleHBvcnRzIiwiU2VjdXJpdHlVc2VyU2V0dGluZ3NUYWIiLCJhY3Rpb24iLCJpZ25vcmVkVXNlcklkcyIsIk1hdHJpeENsaWVudFBlZyIsInNhZmVHZXQiLCJnZXRJZ25vcmVkVXNlcnMiLCJuZXdXYWl0aW5nVW5pZ25vcmVkIiwic3RhdGUiLCJ3YWl0aW5nVW5pZ25vcmVkIiwiZmlsdGVyIiwiaW5jbHVkZXMiLCJzZXRTdGF0ZSIsInJvb20iLCJtZW1iZXJzaGlwIiwiaXNTcGFjZVJvb20iLCJLbm93bk1lbWJlcnNoaXAiLCJJbnZpdGUiLCJhZGRJbnZpdGVkUm9vbSIsImludml0ZWRSb29tSWRzIiwicm9vbUlkIiwicmVtb3ZlSW52aXRlZFJvb20iLCJTZXQiLCJhZGQiLCJuZXdJbnZpdGVkUm9vbUlkcyIsImRlbGV0ZSIsImN1cnJlbnRseUlnbm9yZWRVc2VySWRzIiwiaW5kZXgiLCJpbmRleE9mIiwic3BsaWNlIiwic2V0SWdub3JlZFVzZXJzIiwiZ2V0Um9vbXMiLCJoYXNNZW1iZXJzaGlwU3RhdGUiLCJnZXRVc2VySWQiLCJhY2NlcHQiLCJtYW5hZ2luZ0ludml0ZXMiLCJpbnZpdGVkUm9vbUlkc1ZhbHVlcyIsIkFycmF5IiwiZnJvbSIsImNsaSIsImpvaW5Sb29tIiwiYmluZCIsImxlYXZlIiwibGVuZ3RoIiwidGhlbiIsImVycmNvZGUiLCJzbGVlcCIsInJldHJ5X2FmdGVyX21zIiwibG9nZ2VyIiwid2FybiIsIm1hbmFnZUludml0ZXMiLCJnZXRJbnZpdGVkUm9vbXMiLCJtYXAiLCJjb21wb25lbnREaWRNb3VudCIsImRpc3BhdGNoZXJSZWYiLCJkaXMiLCJyZWdpc3RlciIsIm9uQWN0aW9uIiwib24iLCJSb29tRXZlbnQiLCJNeU1lbWJlcnNoaXAiLCJvbk15TWVtYmVyc2hpcCIsImdldFZlcnNpb25zIiwidmVyc2lvbnMiLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInVucmVnaXN0ZXIiLCJyZW1vdmVMaXN0ZW5lciIsInJlbmRlcklnbm9yZWRVc2VycyIsInVzZXJJZHMiLCJvblVzZXJVbmlnbm9yZWQiLCJrZXkiLCJoZWFkaW5nIiwiU2V0dGluZ3NTdWJzZWN0aW9uVGV4dCIsInJlbmRlck1hbmFnZUludml0ZXMiLCJzaXplIiwib25BY2NlcHRBbGxJbnZpdGVzQ2xpY2tlZCIsImludml0ZWRSb29tcyIsIm9uUmVqZWN0QWxsSW52aXRlc0NsaWNrZWQiLCJzZWN1cmVCYWNrdXAiLCJldmVudEluZGV4IiwiY3Jvc3NTaWduaW5nIiwid2FybmluZyIsInByaXZhdGVTaG91bGRCZUVuY3J5cHRlZCIsInByaXZhY3lTZWN0aW9uIiwiUG9zdGhvZ0FuYWx5dGljcyIsImluc3RhbmNlIiwiaXNFbmFibGVkIiwib25DbGlja0FuYWx5dGljc0xlYXJuTW9yZSIsInNob3dBbmFseXRpY3NMZWFybk1vcmVEaWFsb2ciLCJwcmltYXJ5QnV0dG9uIiwiaGFzQ2FuY2VsIiwiU2V0dGluZ3NTZWN0aW9uIiwiZGVzY3JpcHRpb24iLCJuYW1lIiwibGV2ZWwiLCJTZXR0aW5nTGV2ZWwiLCJBQ0NPVU5UIiwiYWR2YW5jZWRTZWN0aW9uIiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwiVUlGZWF0dXJlIiwiQWR2YW5jZWRTZXR0aW5ncyIsImlnbm9yZVVzZXJzUGFuZWwiLCJpbnZpdGVzUGFuZWwiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9zZXR0aW5ncy90YWJzL3VzZXIvU2VjdXJpdHlVc2VyU2V0dGluZ3NUYWIudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE5LTIwMjMgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvdXRpbHNcIjtcbmltcG9ydCB7IFJvb20sIFJvb21FdmVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IEtub3duTWVtYmVyc2hpcCwgTWVtYmVyc2hpcCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy90eXBlc1wiO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL2xvZ2dlclwiO1xuXG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCB7IE1hdHJpeENsaWVudFBlZyB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9NYXRyaXhDbGllbnRQZWdcIjtcbmltcG9ydCBBY2Nlc3NpYmxlQnV0dG9uIGZyb20gXCIuLi8uLi8uLi9lbGVtZW50cy9BY2Nlc3NpYmxlQnV0dG9uXCI7XG5pbXBvcnQgZGlzIGZyb20gXCIuLi8uLi8uLi8uLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXJcIjtcbmltcG9ydCB7IFNldHRpbmdMZXZlbCB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nTGV2ZWxcIjtcbmltcG9ydCBTZWN1cmVCYWNrdXBQYW5lbCBmcm9tIFwiLi4vLi4vU2VjdXJlQmFja3VwUGFuZWxcIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBVSUZlYXR1cmUgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vc2V0dGluZ3MvVUlGZWF0dXJlXCI7XG5pbXBvcnQgeyBBY3Rpb25QYXlsb2FkIH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2Rpc3BhdGNoZXIvcGF5bG9hZHNcIjtcbmltcG9ydCBDcnlwdG9ncmFwaHlQYW5lbCBmcm9tIFwiLi4vLi4vQ3J5cHRvZ3JhcGh5UGFuZWxcIjtcbmltcG9ydCBTZXR0aW5nc0ZsYWcgZnJvbSBcIi4uLy4uLy4uL2VsZW1lbnRzL1NldHRpbmdzRmxhZ1wiO1xuaW1wb3J0IENyb3NzU2lnbmluZ1BhbmVsIGZyb20gXCIuLi8uLi9Dcm9zc1NpZ25pbmdQYW5lbFwiO1xuaW1wb3J0IEV2ZW50SW5kZXhQYW5lbCBmcm9tIFwiLi4vLi4vRXZlbnRJbmRleFBhbmVsXCI7XG5pbXBvcnQgSW5saW5lU3Bpbm5lciBmcm9tIFwiLi4vLi4vLi4vZWxlbWVudHMvSW5saW5lU3Bpbm5lclwiO1xuaW1wb3J0IHsgUG9zdGhvZ0FuYWx5dGljcyB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9Qb3N0aG9nQW5hbHl0aWNzXCI7XG5pbXBvcnQgeyBzaG93RGlhbG9nIGFzIHNob3dBbmFseXRpY3NMZWFybk1vcmVEaWFsb2cgfSBmcm9tIFwiLi4vLi4vLi4vZGlhbG9ncy9BbmFseXRpY3NMZWFybk1vcmVEaWFsb2dcIjtcbmltcG9ydCB7IHByaXZhdGVTaG91bGRCZUVuY3J5cHRlZCB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi91dGlscy9yb29tc1wiO1xuaW1wb3J0IHR5cGUgeyBJU2VydmVyVmVyc2lvbnMgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgU2V0dGluZ3NUYWIgZnJvbSBcIi4uL1NldHRpbmdzVGFiXCI7XG5pbXBvcnQgeyBTZXR0aW5nc1NlY3Rpb24gfSBmcm9tIFwiLi4vLi4vc2hhcmVkL1NldHRpbmdzU2VjdGlvblwiO1xuaW1wb3J0IFNldHRpbmdzU3Vic2VjdGlvbiwgeyBTZXR0aW5nc1N1YnNlY3Rpb25UZXh0IH0gZnJvbSBcIi4uLy4uL3NoYXJlZC9TZXR0aW5nc1N1YnNlY3Rpb25cIjtcbmltcG9ydCB7IHVzZU93bkRldmljZXMgfSBmcm9tIFwiLi4vLi4vZGV2aWNlcy91c2VPd25EZXZpY2VzXCI7XG5pbXBvcnQgRGlzY292ZXJ5U2V0dGluZ3MgZnJvbSBcIi4uLy4uL2Rpc2NvdmVyeS9EaXNjb3ZlcnlTZXR0aW5nc1wiO1xuaW1wb3J0IFNldEludGVncmF0aW9uTWFuYWdlciBmcm9tIFwiLi4vLi4vU2V0SW50ZWdyYXRpb25NYW5hZ2VyXCI7XG5cbmludGVyZmFjZSBJSWdub3JlZFVzZXJQcm9wcyB7XG4gICAgdXNlcklkOiBzdHJpbmc7XG4gICAgb25Vbmlnbm9yZWQ6ICh1c2VySWQ6IHN0cmluZykgPT4gdm9pZDtcbiAgICBpblByb2dyZXNzOiBib29sZWFuO1xufVxuXG5jb25zdCBEZWh5ZHJhdGVkRGV2aWNlU3RhdHVzOiBSZWFjdC5GQyA9ICgpID0+IHtcbiAgICBjb25zdCB7IGRlaHlkcmF0ZWREZXZpY2VJZCB9ID0gdXNlT3duRGV2aWNlcygpO1xuXG4gICAgaWYgKGRlaHlkcmF0ZWREZXZpY2VJZCkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9TZXR0aW5nc1N1YnNlY3Rpb25fY29udGVudFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfU2V0dGluZ3NGbGFnX2xhYmVsXCI+e190KFwic2V0dGluZ3N8c2VjdXJpdHl8ZGVoeWRyYXRlZF9kZXZpY2VfZW5hYmxlZFwiKX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1NldHRpbmdzU3Vic2VjdGlvbl90ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcInNldHRpbmdzfHNlY3VyaXR5fGRlaHlkcmF0ZWRfZGV2aWNlX2Rlc2NyaXB0aW9uXCIpfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufTtcblxuZXhwb3J0IGNsYXNzIElnbm9yZWRVc2VyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50PElJZ25vcmVkVXNlclByb3BzPiB7XG4gICAgcHJpdmF0ZSBvblVuaWdub3JlQ2xpY2tlZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVuaWdub3JlZCh0aGlzLnByb3BzLnVzZXJJZCk7XG4gICAgfTtcblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgY29uc3QgaWQgPSBgbXhfU2VjdXJpdHlVc2VyU2V0dGluZ3NUYWJfaWdub3JlZFVzZXJfJHt0aGlzLnByb3BzLnVzZXJJZH1gO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9TZWN1cml0eVVzZXJTZXR0aW5nc1RhYl9pZ25vcmVkVXNlclwiPlxuICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMub25Vbmlnbm9yZUNsaWNrZWR9XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJwcmltYXJ5X3NtXCJcbiAgICAgICAgICAgICAgICAgICAgYXJpYS1kZXNjcmliZWRieT17aWR9XG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0aGlzLnByb3BzLmluUHJvZ3Jlc3N9XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJhY3Rpb258dW5pZ25vcmVcIil9XG4gICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgICAgIDxzcGFuIGlkPXtpZH0+e3RoaXMucHJvcHMudXNlcklkfTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cbn1cblxuaW50ZXJmYWNlIElQcm9wcyB7XG4gICAgY2xvc2VTZXR0aW5nc0ZuOiAoKSA9PiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBpZ25vcmVkVXNlcklkczogc3RyaW5nW107XG4gICAgd2FpdGluZ1VuaWdub3JlZDogc3RyaW5nW107XG4gICAgbWFuYWdpbmdJbnZpdGVzOiBib29sZWFuO1xuICAgIGludml0ZWRSb29tSWRzOiBTZXQ8c3RyaW5nPjtcbiAgICB2ZXJzaW9ucz86IElTZXJ2ZXJWZXJzaW9ucztcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VjdXJpdHlVc2VyU2V0dGluZ3NUYWIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwcml2YXRlIGRpc3BhdGNoZXJSZWY/OiBzdHJpbmc7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IElQcm9wcykge1xuICAgICAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAgICAgLy8gR2V0IHJvb21zIHdlJ3JlIGludml0ZWQgdG9cbiAgICAgICAgY29uc3QgaW52aXRlZFJvb21JZHMgPSBuZXcgU2V0KHRoaXMuZ2V0SW52aXRlZFJvb21zKCkubWFwKChyb29tKSA9PiByb29tLnJvb21JZCkpO1xuXG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBpZ25vcmVkVXNlcklkczogTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5nZXRJZ25vcmVkVXNlcnMoKSxcbiAgICAgICAgICAgIHdhaXRpbmdVbmlnbm9yZWQ6IFtdLFxuICAgICAgICAgICAgbWFuYWdpbmdJbnZpdGVzOiBmYWxzZSxcbiAgICAgICAgICAgIGludml0ZWRSb29tSWRzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgb25BY3Rpb24gPSAoeyBhY3Rpb24gfTogQWN0aW9uUGF5bG9hZCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoYWN0aW9uID09PSBcImlnbm9yZV9zdGF0ZV9jaGFuZ2VkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGlnbm9yZWRVc2VySWRzID0gTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5nZXRJZ25vcmVkVXNlcnMoKTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1dhaXRpbmdVbmlnbm9yZWQgPSB0aGlzLnN0YXRlLndhaXRpbmdVbmlnbm9yZWQuZmlsdGVyKChlKSA9PiBpZ25vcmVkVXNlcklkcy5pbmNsdWRlcyhlKSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaWdub3JlZFVzZXJJZHMsIHdhaXRpbmdVbmlnbm9yZWQ6IG5ld1dhaXRpbmdVbmlnbm9yZWQgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHVibGljIGNvbXBvbmVudERpZE1vdW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc3BhdGNoZXJSZWYgPSBkaXMucmVnaXN0ZXIodGhpcy5vbkFjdGlvbik7XG4gICAgICAgIE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCkub24oUm9vbUV2ZW50Lk15TWVtYmVyc2hpcCwgdGhpcy5vbk15TWVtYmVyc2hpcCk7XG4gICAgICAgIE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KClcbiAgICAgICAgICAgIC5nZXRWZXJzaW9ucygpXG4gICAgICAgICAgICAudGhlbigodmVyc2lvbnMpID0+IHRoaXMuc2V0U3RhdGUoeyB2ZXJzaW9ucyB9KSk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kaXNwYXRjaGVyUmVmKSBkaXMudW5yZWdpc3Rlcih0aGlzLmRpc3BhdGNoZXJSZWYpO1xuICAgICAgICBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLnJlbW92ZUxpc3RlbmVyKFJvb21FdmVudC5NeU1lbWJlcnNoaXAsIHRoaXMub25NeU1lbWJlcnNoaXApO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25NeU1lbWJlcnNoaXAgPSAocm9vbTogUm9vbSwgbWVtYmVyc2hpcDogTWVtYmVyc2hpcCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAocm9vbS5pc1NwYWNlUm9vbSgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWVtYmVyc2hpcCA9PT0gS25vd25NZW1iZXJzaGlwLkludml0ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnZpdGVkUm9vbShyb29tKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmludml0ZWRSb29tSWRzLmhhcyhyb29tLnJvb21JZCkpIHtcbiAgICAgICAgICAgIC8vIFRoZSB1c2VyIGlzbid0IGludml0ZWQgYW55bW9yZVxuICAgICAgICAgICAgdGhpcy5yZW1vdmVJbnZpdGVkUm9vbShyb29tLnJvb21JZCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBhZGRJbnZpdGVkUm9vbSA9IChyb29tOiBSb29tKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKHsgaW52aXRlZFJvb21JZHMgfSkgPT4gKHtcbiAgICAgICAgICAgIGludml0ZWRSb29tSWRzOiBuZXcgU2V0KGludml0ZWRSb29tSWRzKS5hZGQocm9vbS5yb29tSWQpLFxuICAgICAgICB9KSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgcmVtb3ZlSW52aXRlZFJvb20gPSAocm9vbUlkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgoeyBpbnZpdGVkUm9vbUlkcyB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdJbnZpdGVkUm9vbUlkcyA9IG5ldyBTZXQoaW52aXRlZFJvb21JZHMpO1xuICAgICAgICAgICAgbmV3SW52aXRlZFJvb21JZHMuZGVsZXRlKHJvb21JZCk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaW52aXRlZFJvb21JZHM6IG5ld0ludml0ZWRSb29tSWRzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Vc2VyVW5pZ25vcmVkID0gYXN5bmMgKHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGNvbnN0IHsgaWdub3JlZFVzZXJJZHMsIHdhaXRpbmdVbmlnbm9yZWQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRseUlnbm9yZWRVc2VySWRzID0gaWdub3JlZFVzZXJJZHMuZmlsdGVyKChlKSA9PiAhd2FpdGluZ1VuaWdub3JlZC5pbmNsdWRlcyhlKSk7XG5cbiAgICAgICAgY29uc3QgaW5kZXggPSBjdXJyZW50bHlJZ25vcmVkVXNlcklkcy5pbmRleE9mKHVzZXJJZCk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGN1cnJlbnRseUlnbm9yZWRVc2VySWRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKCh7IHdhaXRpbmdVbmlnbm9yZWQgfSkgPT4gKHsgd2FpdGluZ1VuaWdub3JlZDogWy4uLndhaXRpbmdVbmlnbm9yZWQsIHVzZXJJZF0gfSkpO1xuICAgICAgICAgICAgTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5zZXRJZ25vcmVkVXNlcnMoY3VycmVudGx5SWdub3JlZFVzZXJJZHMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByaXZhdGUgZ2V0SW52aXRlZFJvb21zID0gKCk6IFJvb21bXSA9PiB7XG4gICAgICAgIHJldHVybiBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpXG4gICAgICAgICAgICAuZ2V0Um9vbXMoKVxuICAgICAgICAgICAgLmZpbHRlcigocikgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByLmhhc01lbWJlcnNoaXBTdGF0ZShNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmdldFVzZXJJZCgpISwgS25vd25NZW1iZXJzaGlwLkludml0ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBtYW5hZ2VJbnZpdGVzID0gYXN5bmMgKGFjY2VwdDogYm9vbGVhbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIG1hbmFnaW5nSW52aXRlczogdHJ1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gaXRlcmF0ZSB3aXRoIGEgbm9ybWFsIGZvciBsb29wIGluIG9yZGVyIHRvIHJldHJ5IG9uIGFjdGlvbiBmYWlsdXJlXG4gICAgICAgIGNvbnN0IGludml0ZWRSb29tSWRzVmFsdWVzID0gQXJyYXkuZnJvbSh0aGlzLnN0YXRlLmludml0ZWRSb29tSWRzKTtcblxuICAgICAgICAvLyBFeGVjdXRlIGFsbCBhY2NlcHRhbmNlcy9yZWplY3Rpb25zIHNlcXVlbnRpYWxseVxuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpO1xuICAgICAgICBjb25zdCBhY3Rpb24gPSBhY2NlcHQgPyBjbGkuam9pblJvb20uYmluZChjbGkpIDogY2xpLmxlYXZlLmJpbmQoY2xpKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnZpdGVkUm9vbUlkc1ZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgcm9vbUlkID0gaW52aXRlZFJvb21JZHNWYWx1ZXNbaV07XG5cbiAgICAgICAgICAgIC8vIEFjY2VwdC9yZWplY3QgaW52aXRlXG4gICAgICAgICAgICBhd2FpdCBhY3Rpb24ocm9vbUlkKS50aGVuKFxuICAgICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm8gZXJyb3IsIHVwZGF0ZSBpbnZpdGVkIHJvb21zIGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUludml0ZWRSb29tKHJvb21JZCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBhc3luYyAoZSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBBY3Rpb24gZmFpbHVyZVxuICAgICAgICAgICAgICAgICAgICBpZiAoZS5lcnJjb2RlID09PSBcIk1fTElNSVRfRVhDRUVERURcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGEgZGVsYXkgYmV0d2VlbiBlYWNoIGludml0ZSBjaGFuZ2UgaW4gb3JkZXIgdG8gYXZvaWQgcmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGltaXRpbmcgYnkgdGhlIHNlcnZlci5cbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHNsZWVwKGUucmV0cnlfYWZ0ZXJfbXMgfHwgMjUwMCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlZG8gbGFzdCBhY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByaW50IG91dCBlcnJvciB3aXRoIGpvaW5pbmcvbGVhdmluZyByb29tXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBtYW5hZ2luZ0ludml0ZXM6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkFjY2VwdEFsbEludml0ZXNDbGlja2VkID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLm1hbmFnZUludml0ZXModHJ1ZSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25SZWplY3RBbGxJbnZpdGVzQ2xpY2tlZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5tYW5hZ2VJbnZpdGVzKGZhbHNlKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSByZW5kZXJJZ25vcmVkVXNlcnMoKTogSlNYLkVsZW1lbnQge1xuICAgICAgICBjb25zdCB7IHdhaXRpbmdVbmlnbm9yZWQsIGlnbm9yZWRVc2VySWRzIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICAgIGNvbnN0IHVzZXJJZHMgPSAhaWdub3JlZFVzZXJJZHM/Lmxlbmd0aFxuICAgICAgICAgICAgPyBfdChcInNldHRpbmdzfHNlY3VyaXR5fGlnbm9yZV91c2Vyc19lbXB0eVwiKVxuICAgICAgICAgICAgOiBpZ25vcmVkVXNlcklkcy5tYXAoKHUpID0+IHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgPElnbm9yZWRVc2VyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJJZD17dX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgb25Vbmlnbm9yZWQ9e3RoaXMub25Vc2VyVW5pZ25vcmVkfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk9e3V9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGluUHJvZ3Jlc3M9e3dhaXRpbmdVbmlnbm9yZWQuaW5jbHVkZXModSl9XG4gICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8U2V0dGluZ3NTdWJzZWN0aW9uIGhlYWRpbmc9e190KFwic2V0dGluZ3N8c2VjdXJpdHl8aWdub3JlX3VzZXJzX3NlY3Rpb25cIil9PlxuICAgICAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb25UZXh0Pnt1c2VySWRzfTwvU2V0dGluZ3NTdWJzZWN0aW9uVGV4dD5cbiAgICAgICAgICAgIDwvU2V0dGluZ3NTdWJzZWN0aW9uPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVuZGVyTWFuYWdlSW52aXRlcygpOiBSZWFjdE5vZGUge1xuICAgICAgICBjb25zdCB7IGludml0ZWRSb29tSWRzIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICAgIGlmIChpbnZpdGVkUm9vbUlkcy5zaXplID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8U2V0dGluZ3NTdWJzZWN0aW9uIGhlYWRpbmc9e190KFwic2V0dGluZ3N8c2VjdXJpdHl8YnVsa19vcHRpb25zX3NlY3Rpb25cIil9PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfU2VjdXJpdHlVc2VyU2V0dGluZ3NUYWJfYnVsa09wdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMub25BY2NlcHRBbGxJbnZpdGVzQ2xpY2tlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJwcmltYXJ5X291dGxpbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RoaXMuc3RhdGUubWFuYWdpbmdJbnZpdGVzfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJzZXR0aW5nc3xzZWN1cml0eXxidWxrX29wdGlvbnNfYWNjZXB0X2FsbF9pbnZpdGVzXCIsIHsgaW52aXRlZFJvb21zOiBpbnZpdGVkUm9vbUlkcy5zaXplIH0pfVxuICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLm9uUmVqZWN0QWxsSW52aXRlc0NsaWNrZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICBraW5kPVwiZGFuZ2VyX291dGxpbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RoaXMuc3RhdGUubWFuYWdpbmdJbnZpdGVzfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJzZXR0aW5nc3xzZWN1cml0eXxidWxrX29wdGlvbnNfcmVqZWN0X2FsbF9pbnZpdGVzXCIsIHsgaW52aXRlZFJvb21zOiBpbnZpdGVkUm9vbUlkcy5zaXplIH0pfVxuICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnN0YXRlLm1hbmFnaW5nSW52aXRlcyA/IDxJbmxpbmVTcGlubmVyIC8+IDogPGRpdiAvPn1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvU2V0dGluZ3NTdWJzZWN0aW9uPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgY29uc3Qgc2VjdXJlQmFja3VwID0gKFxuICAgICAgICAgICAgPFNldHRpbmdzU3Vic2VjdGlvbiBoZWFkaW5nPXtfdChcImNvbW1vbnxzZWN1cmVfYmFja3VwXCIpfT5cbiAgICAgICAgICAgICAgICA8U2VjdXJlQmFja3VwUGFuZWwgLz5cbiAgICAgICAgICAgICAgICA8RGVoeWRyYXRlZERldmljZVN0YXR1cyAvPlxuICAgICAgICAgICAgPC9TZXR0aW5nc1N1YnNlY3Rpb24+XG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgZXZlbnRJbmRleCA9IChcbiAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb24gaGVhZGluZz17X3QoXCJzZXR0aW5nc3xzZWN1cml0eXxtZXNzYWdlX3NlYXJjaF9zZWN0aW9uXCIpfT5cbiAgICAgICAgICAgICAgICA8RXZlbnRJbmRleFBhbmVsIC8+XG4gICAgICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvbj5cbiAgICAgICAgKTtcblxuICAgICAgICAvLyBYWFg6IFRoZXJlJ3Mgbm8gc3VjaCBwYW5lbCBpbiB0aGUgY3VycmVudCBjcm9zcy1zaWduaW5nIGRlc2lnbnMsIGJ1dFxuICAgICAgICAvLyBpdCdzIHVzZWZ1bCB0byBoYXZlIGZvciB0ZXN0aW5nIHRoZSBmZWF0dXJlLiBJZiB0aGVyZSdzIG5vIGludGVyZXN0XG4gICAgICAgIC8vIGluIGhhdmluZyBhZHZhbmNlZCBkZXRhaWxzIGhlcmUgb25jZSBhbGwgZmxvd3MgYXJlIGltcGxlbWVudGVkLCB3ZVxuICAgICAgICAvLyBjYW4gcmVtb3ZlIHRoaXMuXG4gICAgICAgIGNvbnN0IGNyb3NzU2lnbmluZyA9IChcbiAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb24gaGVhZGluZz17X3QoXCJjb21tb258Y3Jvc3Nfc2lnbmluZ1wiKX0+XG4gICAgICAgICAgICAgICAgPENyb3NzU2lnbmluZ1BhbmVsIC8+XG4gICAgICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvbj5cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgd2FybmluZztcbiAgICAgICAgaWYgKCFwcml2YXRlU2hvdWxkQmVFbmNyeXB0ZWQoTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKSkpIHtcbiAgICAgICAgICAgIHdhcm5pbmcgPSAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9TZWN1cml0eVVzZXJTZXR0aW5nc1RhYl93YXJuaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcInNldHRpbmdzfHNlY3VyaXR5fGUyZWVfZGVmYXVsdF9kaXNhYmxlZF93YXJuaW5nXCIpfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwcml2YWN5U2VjdGlvbjtcbiAgICAgICAgaWYgKFBvc3Rob2dBbmFseXRpY3MuaW5zdGFuY2UuaXNFbmFibGVkKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IG9uQ2xpY2tBbmFseXRpY3NMZWFybk1vcmUgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgICAgc2hvd0FuYWx5dGljc0xlYXJuTW9yZURpYWxvZyh7XG4gICAgICAgICAgICAgICAgICAgIHByaW1hcnlCdXR0b246IF90KFwiYWN0aW9ufG9rXCIpLFxuICAgICAgICAgICAgICAgICAgICBoYXNDYW5jZWw6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHByaXZhY3lTZWN0aW9uID0gKFxuICAgICAgICAgICAgICAgIDxTZXR0aW5nc1NlY3Rpb24gaGVhZGluZz17X3QoXCJjb21tb258cHJpdmFjeVwiKX0+XG4gICAgICAgICAgICAgICAgICAgIDxEaXNjb3ZlcnlTZXR0aW5ncyAvPlxuICAgICAgICAgICAgICAgICAgICA8U2V0dGluZ3NTdWJzZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkaW5nPXtfdChcImNvbW1vbnxhbmFseXRpY3NcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbj17X3QoXCJzZXR0aW5nc3xzZWN1cml0eXxhbmFseXRpY3NfZGVzY3JpcHRpb25cIil9XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGtpbmQ9XCJsaW5rXCIgb25DbGljaz17b25DbGlja0FuYWx5dGljc0xlYXJuTW9yZX0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGxlYXJuX21vcmVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICB7UG9zdGhvZ0FuYWx5dGljcy5pbnN0YW5jZS5pc0VuYWJsZWQoKSAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPFNldHRpbmdzRmxhZyBuYW1lPVwicHNldWRvbnltb3VzQW5hbHl0aWNzT3B0SW5cIiBsZXZlbD17U2V0dGluZ0xldmVsLkFDQ09VTlR9IC8+XG4gICAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPFNldHRpbmdzU3Vic2VjdGlvbiBoZWFkaW5nPXtfdChcInNldHRpbmdzfHNlc3Npb25zfHRpdGxlXCIpfT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxTZXR0aW5nc0ZsYWcgbmFtZT1cImRldmljZUNsaWVudEluZm9ybWF0aW9uT3B0SW5cIiBsZXZlbD17U2V0dGluZ0xldmVsLkFDQ09VTlR9IC8+XG4gICAgICAgICAgICAgICAgICAgIDwvU2V0dGluZ3NTdWJzZWN0aW9uPlxuICAgICAgICAgICAgICAgIDwvU2V0dGluZ3NTZWN0aW9uPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBhZHZhbmNlZFNlY3Rpb247XG4gICAgICAgIGlmIChTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFVJRmVhdHVyZS5BZHZhbmNlZFNldHRpbmdzKSkge1xuICAgICAgICAgICAgY29uc3QgaWdub3JlVXNlcnNQYW5lbCA9IHRoaXMucmVuZGVySWdub3JlZFVzZXJzKCk7XG4gICAgICAgICAgICBjb25zdCBpbnZpdGVzUGFuZWwgPSB0aGlzLnJlbmRlck1hbmFnZUludml0ZXMoKTtcbiAgICAgICAgICAgIC8vIG9ubHkgc2hvdyB0aGUgc2VjdGlvbiBpZiB0aGVyZSdzIHNvbWV0aGluZyB0byBzaG93XG4gICAgICAgICAgICBpZiAoaWdub3JlVXNlcnNQYW5lbCB8fCBpbnZpdGVzUGFuZWwpIHtcbiAgICAgICAgICAgICAgICBhZHZhbmNlZFNlY3Rpb24gPSAoXG4gICAgICAgICAgICAgICAgICAgIDxTZXR0aW5nc1NlY3Rpb24gaGVhZGluZz17X3QoXCJjb21tb258YWR2YW5jZWRcIil9PlxuICAgICAgICAgICAgICAgICAgICAgICAge2lnbm9yZVVzZXJzUGFuZWx9XG4gICAgICAgICAgICAgICAgICAgICAgICB7aW52aXRlc1BhbmVsfVxuICAgICAgICAgICAgICAgICAgICA8L1NldHRpbmdzU2VjdGlvbj5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxTZXR0aW5nc1RhYj5cbiAgICAgICAgICAgICAgICB7d2FybmluZ31cbiAgICAgICAgICAgICAgICA8U2V0SW50ZWdyYXRpb25NYW5hZ2VyIC8+XG4gICAgICAgICAgICAgICAgPFNldHRpbmdzU2VjdGlvbiBoZWFkaW5nPXtfdChcInNldHRpbmdzfHNlY3VyaXR5fGVuY3J5cHRpb25fc2VjdGlvblwiKX0+XG4gICAgICAgICAgICAgICAgICAgIHtzZWN1cmVCYWNrdXB9XG4gICAgICAgICAgICAgICAgICAgIHtldmVudEluZGV4fVxuICAgICAgICAgICAgICAgICAgICB7Y3Jvc3NTaWduaW5nfVxuICAgICAgICAgICAgICAgICAgICA8Q3J5cHRvZ3JhcGh5UGFuZWwgLz5cbiAgICAgICAgICAgICAgICA8L1NldHRpbmdzU2VjdGlvbj5cbiAgICAgICAgICAgICAgICB7cHJpdmFjeVNlY3Rpb259XG4gICAgICAgICAgICAgICAge2FkdmFuY2VkU2VjdGlvbn1cbiAgICAgICAgICAgIDwvU2V0dGluZ3NUYWI+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLE1BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLE9BQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLE1BQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLE9BQUEsR0FBQUosT0FBQTtBQUVBLElBQUFLLGdCQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxnQkFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8saUJBQUEsR0FBQVIsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFRLFdBQUEsR0FBQVQsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFTLGFBQUEsR0FBQVQsT0FBQTtBQUNBLElBQUFVLGtCQUFBLEdBQUFYLHNC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