UNPKG

matrix-react-sdk

Version:
201 lines (198 loc) 39.2 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 _logger = require("matrix-js-sdk/src/logger"); var _call = require("matrix-js-sdk/src/webrtc/call"); var _languageHandler = require("../../../../../languageHandler"); var _MediaDeviceHandler = _interopRequireWildcard(require("../../../../../MediaDeviceHandler")); var _Field = _interopRequireDefault(require("../../../elements/Field")); var _AccessibleButton = _interopRequireDefault(require("../../../elements/AccessibleButton")); var _SettingLevel = require("../../../../../settings/SettingLevel"); var _SettingsFlag = _interopRequireDefault(require("../../../elements/SettingsFlag")); var _LabelledToggleSwitch = _interopRequireDefault(require("../../../elements/LabelledToggleSwitch")); var _requestMediaPermissions = require("../../../../../utils/media/requestMediaPermissions"); var _SettingsTab = _interopRequireDefault(require("../SettingsTab")); var _SettingsSection = require("../../shared/SettingsSection"); var _SettingsSubsection = _interopRequireDefault(require("../../shared/SettingsSubsection")); var _MatrixClientContext = _interopRequireDefault(require("../../../../../contexts/MatrixClientContext")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /* Copyright 2024 New Vector Ltd. Copyright 2020 The Matrix.org Foundation C.I.C. Copyright 2019 New Vector Ltd SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ /** * Maps deviceKind to the right get method on MediaDeviceHandler * Helpful for setting state */ const mapDeviceKindToHandlerValue = deviceKind => { switch (deviceKind) { case _MediaDeviceHandler.MediaDeviceKindEnum.AudioOutput: return _MediaDeviceHandler.default.getAudioOutput(); case _MediaDeviceHandler.MediaDeviceKindEnum.AudioInput: return _MediaDeviceHandler.default.getAudioInput(); case _MediaDeviceHandler.MediaDeviceKindEnum.VideoInput: return _MediaDeviceHandler.default.getVideoInput(); } }; class VoiceUserSettingsTab extends _react.default.Component { constructor(props, context) { super(props, context); (0, _defineProperty2.default)(this, "refreshMediaDevices", async stream => { this.setState({ mediaDevices: (await _MediaDeviceHandler.default.getDevices()) ?? null, [_MediaDeviceHandler.MediaDeviceKindEnum.AudioOutput]: mapDeviceKindToHandlerValue(_MediaDeviceHandler.MediaDeviceKindEnum.AudioOutput), [_MediaDeviceHandler.MediaDeviceKindEnum.AudioInput]: mapDeviceKindToHandlerValue(_MediaDeviceHandler.MediaDeviceKindEnum.AudioInput), [_MediaDeviceHandler.MediaDeviceKindEnum.VideoInput]: mapDeviceKindToHandlerValue(_MediaDeviceHandler.MediaDeviceKindEnum.VideoInput) }); if (stream) { // kill stream (after we've enumerated the devices, otherwise we'd get empty labels again) // so that we don't leave it lingering around with webcam enabled etc // as here we called gUM to ask user for permission to their device names only stream.getTracks().forEach(track => track.stop()); } }); (0, _defineProperty2.default)(this, "requestMediaPermissions", async () => { const stream = await (0, _requestMediaPermissions.requestMediaPermissions)(); if (stream) { await this.refreshMediaDevices(stream); } }); (0, _defineProperty2.default)(this, "setDevice", async (deviceId, kind) => { // set state immediately so UI is responsive this.setState({ [kind]: deviceId }); try { await _MediaDeviceHandler.default.instance.setDevice(deviceId, kind); } catch (error) { _logger.logger.error(`Failed to set device ${kind}: ${deviceId}`); // reset state to current value this.setState({ [kind]: mapDeviceKindToHandlerValue(kind) }); } }); (0, _defineProperty2.default)(this, "changeWebRtcMethod", p2p => { this.context.setForceTURN(!p2p); }); this.state = { mediaDevices: null, [_MediaDeviceHandler.MediaDeviceKindEnum.AudioOutput]: null, [_MediaDeviceHandler.MediaDeviceKindEnum.AudioInput]: null, [_MediaDeviceHandler.MediaDeviceKindEnum.VideoInput]: null, audioAutoGainControl: _MediaDeviceHandler.default.getAudioAutoGainControl(), audioEchoCancellation: _MediaDeviceHandler.default.getAudioEchoCancellation(), audioNoiseSuppression: _MediaDeviceHandler.default.getAudioNoiseSuppression() }; } async componentDidMount() { const canSeeDeviceLabels = await _MediaDeviceHandler.default.hasAnyLabeledDevices(); if (canSeeDeviceLabels) { await this.refreshMediaDevices(); } } renderDeviceOptions(devices, category) { return devices.map(d => { return /*#__PURE__*/_react.default.createElement("option", { key: `${category}-${d.deviceId}`, value: d.deviceId }, d.label); }); } renderDropdown(kind, label) { const devices = this.state.mediaDevices?.[kind].slice(0); if (!devices?.length) return null; const defaultDevice = _MediaDeviceHandler.default.getDefaultDevice(devices); return /*#__PURE__*/_react.default.createElement(_Field.default, { element: "select", label: label, value: this.state[kind] || defaultDevice, onChange: e => this.setDevice(e.target.value, kind) }, this.renderDeviceOptions(devices, kind)); } render() { let requestButton; let speakerDropdown; let microphoneDropdown; let webcamDropdown; if (!this.state.mediaDevices) { requestButton = /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("settings|voip|missing_permissions_prompt")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: this.requestMediaPermissions, kind: "primary" }, (0, _languageHandler._t)("settings|voip|request_permissions"))); } else if (this.state.mediaDevices) { speakerDropdown = this.renderDropdown(_MediaDeviceHandler.MediaDeviceKindEnum.AudioOutput, (0, _languageHandler._t)("settings|voip|audio_output")) || /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("settings|voip|audio_output_empty")); microphoneDropdown = this.renderDropdown(_MediaDeviceHandler.MediaDeviceKindEnum.AudioInput, (0, _languageHandler._t)("common|microphone")) || /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("settings|voip|audio_input_empty")); webcamDropdown = this.renderDropdown(_MediaDeviceHandler.MediaDeviceKindEnum.VideoInput, (0, _languageHandler._t)("common|camera")) || /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("settings|voip|video_input_empty")); } return /*#__PURE__*/_react.default.createElement(_SettingsTab.default, null, /*#__PURE__*/_react.default.createElement(_SettingsSection.SettingsSection, null, requestButton, /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|voip|voice_section"), stretchContent: true }, speakerDropdown, microphoneDropdown, /*#__PURE__*/_react.default.createElement(_LabelledToggleSwitch.default, { value: this.state.audioAutoGainControl, onChange: async v => { await _MediaDeviceHandler.default.setAudioAutoGainControl(v); this.setState({ audioAutoGainControl: _MediaDeviceHandler.default.getAudioAutoGainControl() }); }, label: (0, _languageHandler._t)("settings|voip|voice_agc"), "data-testid": "voice-auto-gain" })), /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|voip|video_section"), stretchContent: true }, webcamDropdown, /*#__PURE__*/_react.default.createElement(_SettingsFlag.default, { name: "VideoView.flipVideoHorizontally", level: _SettingLevel.SettingLevel.ACCOUNT }))), /*#__PURE__*/_react.default.createElement(_SettingsSection.SettingsSection, { heading: (0, _languageHandler._t)("common|advanced") }, /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|voip|voice_processing") }, /*#__PURE__*/_react.default.createElement(_LabelledToggleSwitch.default, { value: this.state.audioNoiseSuppression, onChange: async v => { await _MediaDeviceHandler.default.setAudioNoiseSuppression(v); this.setState({ audioNoiseSuppression: _MediaDeviceHandler.default.getAudioNoiseSuppression() }); }, label: (0, _languageHandler._t)("settings|voip|noise_suppression"), "data-testid": "voice-noise-suppression" }), /*#__PURE__*/_react.default.createElement(_LabelledToggleSwitch.default, { value: this.state.audioEchoCancellation, onChange: async v => { await _MediaDeviceHandler.default.setAudioEchoCancellation(v); this.setState({ audioEchoCancellation: _MediaDeviceHandler.default.getAudioEchoCancellation() }); }, label: (0, _languageHandler._t)("settings|voip|echo_cancellation"), "data-testid": "voice-echo-cancellation" })), /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("settings|voip|connection_section") }, /*#__PURE__*/_react.default.createElement(_SettingsFlag.default, { name: "webRtcAllowPeerToPeer", level: _SettingLevel.SettingLevel.DEVICE, onChange: this.changeWebRtcMethod }), /*#__PURE__*/_react.default.createElement(_SettingsFlag.default, { name: "fallbackICEServerAllowed", label: (0, _languageHandler._t)("settings|voip|enable_fallback_ice_server", { server: new URL(_call.FALLBACK_ICE_SERVER).pathname }), level: _SettingLevel.SettingLevel.DEVICE, hideIfCannotSet: true })))); } } exports.default = VoiceUserSettingsTab; (0, _defineProperty2.default)(VoiceUserSettingsTab, "contextType", _MatrixClientContext.default); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2dnZXIiLCJfY2FsbCIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfTWVkaWFEZXZpY2VIYW5kbGVyIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJfRmllbGQiLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9TZXR0aW5nTGV2ZWwiLCJfU2V0dGluZ3NGbGFnIiwiX0xhYmVsbGVkVG9nZ2xlU3dpdGNoIiwiX3JlcXVlc3RNZWRpYVBlcm1pc3Npb25zIiwiX1NldHRpbmdzVGFiIiwiX1NldHRpbmdzU2VjdGlvbiIsIl9TZXR0aW5nc1N1YnNlY3Rpb24iLCJfTWF0cml4Q2xpZW50Q29udGV4dCIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIm1hcERldmljZUtpbmRUb0hhbmRsZXJWYWx1ZSIsImRldmljZUtpbmQiLCJNZWRpYURldmljZUtpbmRFbnVtIiwiQXVkaW9PdXRwdXQiLCJNZWRpYURldmljZUhhbmRsZXIiLCJnZXRBdWRpb091dHB1dCIsIkF1ZGlvSW5wdXQiLCJnZXRBdWRpb0lucHV0IiwiVmlkZW9JbnB1dCIsImdldFZpZGVvSW5wdXQiLCJWb2ljZVVzZXJTZXR0aW5nc1RhYiIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsImNvbnRleHQiLCJfZGVmaW5lUHJvcGVydHkyIiwic3RyZWFtIiwic2V0U3RhdGUiLCJtZWRpYURldmljZXMiLCJnZXREZXZpY2VzIiwiZ2V0VHJhY2tzIiwiZm9yRWFjaCIsInRyYWNrIiwic3RvcCIsInJlcXVlc3RNZWRpYVBlcm1pc3Npb25zIiwicmVmcmVzaE1lZGlhRGV2aWNlcyIsImRldmljZUlkIiwia2luZCIsImluc3RhbmNlIiwic2V0RGV2aWNlIiwiZXJyb3IiLCJsb2dnZXIiLCJwMnAiLCJzZXRGb3JjZVRVUk4iLCJzdGF0ZSIsImF1ZGlvQXV0b0dhaW5Db250cm9sIiwiZ2V0QXVkaW9BdXRvR2FpbkNvbnRyb2wiLCJhdWRpb0VjaG9DYW5jZWxsYXRpb24iLCJnZXRBdWRpb0VjaG9DYW5jZWxsYXRpb24iLCJhdWRpb05vaXNlU3VwcHJlc3Npb24iLCJnZXRBdWRpb05vaXNlU3VwcHJlc3Npb24iLCJjb21wb25lbnREaWRNb3VudCIsImNhblNlZURldmljZUxhYmVscyIsImhhc0FueUxhYmVsZWREZXZpY2VzIiwicmVuZGVyRGV2aWNlT3B0aW9ucyIsImRldmljZXMiLCJjYXRlZ29yeSIsIm1hcCIsImQiLCJjcmVhdGVFbGVtZW50Iiwia2V5IiwidmFsdWUiLCJsYWJlbCIsInJlbmRlckRyb3Bkb3duIiwic2xpY2UiLCJsZW5ndGgiLCJkZWZhdWx0RGV2aWNlIiwiZ2V0RGVmYXVsdERldmljZSIsImVsZW1lbnQiLCJvbkNoYW5nZSIsInRhcmdldCIsInJlbmRlciIsInJlcXVlc3RCdXR0b24iLCJzcGVha2VyRHJvcGRvd24iLCJtaWNyb3Bob25lRHJvcGRvd24iLCJ3ZWJjYW1Ecm9wZG93biIsIl90Iiwib25DbGljayIsIlNldHRpbmdzU2VjdGlvbiIsImhlYWRpbmciLCJzdHJldGNoQ29udGVudCIsInYiLCJzZXRBdWRpb0F1dG9HYWluQ29udHJvbCIsIm5hbWUiLCJsZXZlbCIsIlNldHRpbmdMZXZlbCIsIkFDQ09VTlQiLCJzZXRBdWRpb05vaXNlU3VwcHJlc3Npb24iLCJzZXRBdWRpb0VjaG9DYW5jZWxsYXRpb24iLCJERVZJQ0UiLCJjaGFuZ2VXZWJSdGNNZXRob2QiLCJzZXJ2ZXIiLCJVUkwiLCJGQUxMQkFDS19JQ0VfU0VSVkVSIiwicGF0aG5hbWUiLCJoaWRlSWZDYW5ub3RTZXQiLCJleHBvcnRzIiwiTWF0cml4Q2xpZW50Q29udGV4dCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3NldHRpbmdzL3RhYnMvdXNlci9Wb2ljZVVzZXJTZXR0aW5nc1RhYi50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbkNvcHlyaWdodCAyMDE5IE5ldyBWZWN0b3IgTHRkXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyBSZWFjdE5vZGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcbmltcG9ydCB7IEZBTExCQUNLX0lDRV9TRVJWRVIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvd2VicnRjL2NhbGxcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgTWVkaWFEZXZpY2VIYW5kbGVyLCB7IElNZWRpYURldmljZXMsIE1lZGlhRGV2aWNlS2luZEVudW0gfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vTWVkaWFEZXZpY2VIYW5kbGVyXCI7XG5pbXBvcnQgRmllbGQgZnJvbSBcIi4uLy4uLy4uL2VsZW1lbnRzL0ZpZWxkXCI7XG5pbXBvcnQgQWNjZXNzaWJsZUJ1dHRvbiBmcm9tIFwiLi4vLi4vLi4vZWxlbWVudHMvQWNjZXNzaWJsZUJ1dHRvblwiO1xuaW1wb3J0IHsgU2V0dGluZ0xldmVsIH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdMZXZlbFwiO1xuaW1wb3J0IFNldHRpbmdzRmxhZyBmcm9tIFwiLi4vLi4vLi4vZWxlbWVudHMvU2V0dGluZ3NGbGFnXCI7XG5pbXBvcnQgTGFiZWxsZWRUb2dnbGVTd2l0Y2ggZnJvbSBcIi4uLy4uLy4uL2VsZW1lbnRzL0xhYmVsbGVkVG9nZ2xlU3dpdGNoXCI7XG5pbXBvcnQgeyByZXF1ZXN0TWVkaWFQZXJtaXNzaW9ucyB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi91dGlscy9tZWRpYS9yZXF1ZXN0TWVkaWFQZXJtaXNzaW9uc1wiO1xuaW1wb3J0IFNldHRpbmdzVGFiIGZyb20gXCIuLi9TZXR0aW5nc1RhYlwiO1xuaW1wb3J0IHsgU2V0dGluZ3NTZWN0aW9uIH0gZnJvbSBcIi4uLy4uL3NoYXJlZC9TZXR0aW5nc1NlY3Rpb25cIjtcbmltcG9ydCBTZXR0aW5nc1N1YnNlY3Rpb24gZnJvbSBcIi4uLy4uL3NoYXJlZC9TZXR0aW5nc1N1YnNlY3Rpb25cIjtcbmltcG9ydCBNYXRyaXhDbGllbnRDb250ZXh0IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9jb250ZXh0cy9NYXRyaXhDbGllbnRDb250ZXh0XCI7XG5cbmludGVyZmFjZSBJU3RhdGUge1xuICAgIG1lZGlhRGV2aWNlczogSU1lZGlhRGV2aWNlcyB8IG51bGw7XG4gICAgW01lZGlhRGV2aWNlS2luZEVudW0uQXVkaW9PdXRwdXRdOiBzdHJpbmcgfCBudWxsO1xuICAgIFtNZWRpYURldmljZUtpbmRFbnVtLkF1ZGlvSW5wdXRdOiBzdHJpbmcgfCBudWxsO1xuICAgIFtNZWRpYURldmljZUtpbmRFbnVtLlZpZGVvSW5wdXRdOiBzdHJpbmcgfCBudWxsO1xuICAgIGF1ZGlvQXV0b0dhaW5Db250cm9sOiBib29sZWFuO1xuICAgIGF1ZGlvRWNob0NhbmNlbGxhdGlvbjogYm9vbGVhbjtcbiAgICBhdWRpb05vaXNlU3VwcHJlc3Npb246IGJvb2xlYW47XG59XG5cbi8qKlxuICogTWFwcyBkZXZpY2VLaW5kIHRvIHRoZSByaWdodCBnZXQgbWV0aG9kIG9uIE1lZGlhRGV2aWNlSGFuZGxlclxuICogSGVscGZ1bCBmb3Igc2V0dGluZyBzdGF0ZVxuICovXG5jb25zdCBtYXBEZXZpY2VLaW5kVG9IYW5kbGVyVmFsdWUgPSAoZGV2aWNlS2luZDogTWVkaWFEZXZpY2VLaW5kRW51bSk6IHN0cmluZyB8IG51bGwgPT4ge1xuICAgIHN3aXRjaCAoZGV2aWNlS2luZCkge1xuICAgICAgICBjYXNlIE1lZGlhRGV2aWNlS2luZEVudW0uQXVkaW9PdXRwdXQ6XG4gICAgICAgICAgICByZXR1cm4gTWVkaWFEZXZpY2VIYW5kbGVyLmdldEF1ZGlvT3V0cHV0KCk7XG4gICAgICAgIGNhc2UgTWVkaWFEZXZpY2VLaW5kRW51bS5BdWRpb0lucHV0OlxuICAgICAgICAgICAgcmV0dXJuIE1lZGlhRGV2aWNlSGFuZGxlci5nZXRBdWRpb0lucHV0KCk7XG4gICAgICAgIGNhc2UgTWVkaWFEZXZpY2VLaW5kRW51bS5WaWRlb0lucHV0OlxuICAgICAgICAgICAgcmV0dXJuIE1lZGlhRGV2aWNlSGFuZGxlci5nZXRWaWRlb0lucHV0KCk7XG4gICAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVm9pY2VVc2VyU2V0dGluZ3NUYWIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8e30sIElTdGF0ZT4ge1xuICAgIHB1YmxpYyBzdGF0aWMgY29udGV4dFR5cGUgPSBNYXRyaXhDbGllbnRDb250ZXh0O1xuICAgIHB1YmxpYyBkZWNsYXJlIGNvbnRleHQ6IFJlYWN0LkNvbnRleHRUeXBlPHR5cGVvZiBNYXRyaXhDbGllbnRDb250ZXh0PjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczoge30sIGNvbnRleHQ6IFJlYWN0LkNvbnRleHRUeXBlPHR5cGVvZiBNYXRyaXhDbGllbnRDb250ZXh0Pikge1xuICAgICAgICBzdXBlcihwcm9wcywgY29udGV4dCk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIG1lZGlhRGV2aWNlczogbnVsbCxcbiAgICAgICAgICAgIFtNZWRpYURldmljZUtpbmRFbnVtLkF1ZGlvT3V0cHV0XTogbnVsbCxcbiAgICAgICAgICAgIFtNZWRpYURldmljZUtpbmRFbnVtLkF1ZGlvSW5wdXRdOiBudWxsLFxuICAgICAgICAgICAgW01lZGlhRGV2aWNlS2luZEVudW0uVmlkZW9JbnB1dF06IG51bGwsXG4gICAgICAgICAgICBhdWRpb0F1dG9HYWluQ29udHJvbDogTWVkaWFEZXZpY2VIYW5kbGVyLmdldEF1ZGlvQXV0b0dhaW5Db250cm9sKCksXG4gICAgICAgICAgICBhdWRpb0VjaG9DYW5jZWxsYXRpb246IE1lZGlhRGV2aWNlSGFuZGxlci5nZXRBdWRpb0VjaG9DYW5jZWxsYXRpb24oKSxcbiAgICAgICAgICAgIGF1ZGlvTm9pc2VTdXBwcmVzc2lvbjogTWVkaWFEZXZpY2VIYW5kbGVyLmdldEF1ZGlvTm9pc2VTdXBwcmVzc2lvbigpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjb21wb25lbnREaWRNb3VudCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgY2FuU2VlRGV2aWNlTGFiZWxzID0gYXdhaXQgTWVkaWFEZXZpY2VIYW5kbGVyLmhhc0FueUxhYmVsZWREZXZpY2VzKCk7XG4gICAgICAgIGlmIChjYW5TZWVEZXZpY2VMYWJlbHMpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1lZGlhRGV2aWNlcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWZyZXNoTWVkaWFEZXZpY2VzID0gYXN5bmMgKHN0cmVhbT86IE1lZGlhU3RyZWFtKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbWVkaWFEZXZpY2VzOiAoYXdhaXQgTWVkaWFEZXZpY2VIYW5kbGVyLmdldERldmljZXMoKSkgPz8gbnVsbCxcbiAgICAgICAgICAgIFtNZWRpYURldmljZUtpbmRFbnVtLkF1ZGlvT3V0cHV0XTogbWFwRGV2aWNlS2luZFRvSGFuZGxlclZhbHVlKE1lZGlhRGV2aWNlS2luZEVudW0uQXVkaW9PdXRwdXQpLFxuICAgICAgICAgICAgW01lZGlhRGV2aWNlS2luZEVudW0uQXVkaW9JbnB1dF06IG1hcERldmljZUtpbmRUb0hhbmRsZXJWYWx1ZShNZWRpYURldmljZUtpbmRFbnVtLkF1ZGlvSW5wdXQpLFxuICAgICAgICAgICAgW01lZGlhRGV2aWNlS2luZEVudW0uVmlkZW9JbnB1dF06IG1hcERldmljZUtpbmRUb0hhbmRsZXJWYWx1ZShNZWRpYURldmljZUtpbmRFbnVtLlZpZGVvSW5wdXQpLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHN0cmVhbSkge1xuICAgICAgICAgICAgLy8ga2lsbCBzdHJlYW0gKGFmdGVyIHdlJ3ZlIGVudW1lcmF0ZWQgdGhlIGRldmljZXMsIG90aGVyd2lzZSB3ZSdkIGdldCBlbXB0eSBsYWJlbHMgYWdhaW4pXG4gICAgICAgICAgICAvLyBzbyB0aGF0IHdlIGRvbid0IGxlYXZlIGl0IGxpbmdlcmluZyBhcm91bmQgd2l0aCB3ZWJjYW0gZW5hYmxlZCBldGNcbiAgICAgICAgICAgIC8vIGFzIGhlcmUgd2UgY2FsbGVkIGdVTSB0byBhc2sgdXNlciBmb3IgcGVybWlzc2lvbiB0byB0aGVpciBkZXZpY2UgbmFtZXMgb25seVxuICAgICAgICAgICAgc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB0cmFjay5zdG9wKCkpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByaXZhdGUgcmVxdWVzdE1lZGlhUGVybWlzc2lvbnMgPSBhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHJlcXVlc3RNZWRpYVBlcm1pc3Npb25zKCk7XG4gICAgICAgIGlmIChzdHJlYW0pIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1lZGlhRGV2aWNlcyhzdHJlYW0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByaXZhdGUgc2V0RGV2aWNlID0gYXN5bmMgKGRldmljZUlkOiBzdHJpbmcsIGtpbmQ6IE1lZGlhRGV2aWNlS2luZEVudW0pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgLy8gc2V0IHN0YXRlIGltbWVkaWF0ZWx5IHNvIFVJIGlzIHJlc3BvbnNpdmVcbiAgICAgICAgdGhpcy5zZXRTdGF0ZTxhbnk+KHsgW2tpbmRdOiBkZXZpY2VJZCB9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IE1lZGlhRGV2aWNlSGFuZGxlci5pbnN0YW5jZS5zZXREZXZpY2UoZGV2aWNlSWQsIGtpbmQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc2V0IGRldmljZSAke2tpbmR9OiAke2RldmljZUlkfWApO1xuICAgICAgICAgICAgLy8gcmVzZXQgc3RhdGUgdG8gY3VycmVudCB2YWx1ZVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZTxhbnk+KHsgW2tpbmRdOiBtYXBEZXZpY2VLaW5kVG9IYW5kbGVyVmFsdWUoa2luZCkgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBjaGFuZ2VXZWJSdGNNZXRob2QgPSAocDJwOiBib29sZWFuKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuY29udGV4dC5zZXRGb3JjZVRVUk4oIXAycCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgcmVuZGVyRGV2aWNlT3B0aW9ucyhkZXZpY2VzOiBBcnJheTxNZWRpYURldmljZUluZm8+LCBjYXRlZ29yeTogTWVkaWFEZXZpY2VLaW5kRW51bSk6IEFycmF5PEpTWC5FbGVtZW50PiB7XG4gICAgICAgIHJldHVybiBkZXZpY2VzLm1hcCgoZCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8b3B0aW9uIGtleT17YCR7Y2F0ZWdvcnl9LSR7ZC5kZXZpY2VJZH1gfSB2YWx1ZT17ZC5kZXZpY2VJZH0+XG4gICAgICAgICAgICAgICAgICAgIHtkLmxhYmVsfVxuICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW5kZXJEcm9wZG93bihraW5kOiBNZWRpYURldmljZUtpbmRFbnVtLCBsYWJlbDogc3RyaW5nKTogUmVhY3ROb2RlIHtcbiAgICAgICAgY29uc3QgZGV2aWNlcyA9IHRoaXMuc3RhdGUubWVkaWFEZXZpY2VzPy5ba2luZF0uc2xpY2UoMCk7XG4gICAgICAgIGlmICghZGV2aWNlcz8ubGVuZ3RoKSByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCBkZWZhdWx0RGV2aWNlID0gTWVkaWFEZXZpY2VIYW5kbGVyLmdldERlZmF1bHREZXZpY2UoZGV2aWNlcyk7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8RmllbGRcbiAgICAgICAgICAgICAgICBlbGVtZW50PVwic2VsZWN0XCJcbiAgICAgICAgICAgICAgICBsYWJlbD17bGFiZWx9XG4gICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuc3RhdGVba2luZF0gfHwgZGVmYXVsdERldmljZX1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHRoaXMuc2V0RGV2aWNlKGUudGFyZ2V0LnZhbHVlLCBraW5kKX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7dGhpcy5yZW5kZXJEZXZpY2VPcHRpb25zKGRldmljZXMsIGtpbmQpfVxuICAgICAgICAgICAgPC9GaWVsZD5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0Tm9kZSB7XG4gICAgICAgIGxldCByZXF1ZXN0QnV0dG9uOiBSZWFjdE5vZGUgfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBzcGVha2VyRHJvcGRvd246IFJlYWN0Tm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IG1pY3JvcGhvbmVEcm9wZG93bjogUmVhY3ROb2RlIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgd2ViY2FtRHJvcGRvd246IFJlYWN0Tm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLm1lZGlhRGV2aWNlcykge1xuICAgICAgICAgICAgcmVxdWVzdEJ1dHRvbiA9IChcbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICA8cD57X3QoXCJzZXR0aW5nc3x2b2lwfG1pc3NpbmdfcGVybWlzc2lvbnNfcHJvbXB0XCIpfTwvcD5cbiAgICAgICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24gb25DbGljaz17dGhpcy5yZXF1ZXN0TWVkaWFQZXJtaXNzaW9uc30ga2luZD1cInByaW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcInNldHRpbmdzfHZvaXB8cmVxdWVzdF9wZXJtaXNzaW9uc1wiKX1cbiAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLm1lZGlhRGV2aWNlcykge1xuICAgICAgICAgICAgc3BlYWtlckRyb3Bkb3duID0gdGhpcy5yZW5kZXJEcm9wZG93bihcbiAgICAgICAgICAgICAgICBNZWRpYURldmljZUtpbmRFbnVtLkF1ZGlvT3V0cHV0LFxuICAgICAgICAgICAgICAgIF90KFwic2V0dGluZ3N8dm9pcHxhdWRpb19vdXRwdXRcIiksXG4gICAgICAgICAgICApIHx8IDxwPntfdChcInNldHRpbmdzfHZvaXB8YXVkaW9fb3V0cHV0X2VtcHR5XCIpfTwvcD47XG4gICAgICAgICAgICBtaWNyb3Bob25lRHJvcGRvd24gPSB0aGlzLnJlbmRlckRyb3Bkb3duKE1lZGlhRGV2aWNlS2luZEVudW0uQXVkaW9JbnB1dCwgX3QoXCJjb21tb258bWljcm9waG9uZVwiKSkgfHwgKFxuICAgICAgICAgICAgICAgIDxwPntfdChcInNldHRpbmdzfHZvaXB8YXVkaW9faW5wdXRfZW1wdHlcIil9PC9wPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHdlYmNhbURyb3Bkb3duID0gdGhpcy5yZW5kZXJEcm9wZG93bihNZWRpYURldmljZUtpbmRFbnVtLlZpZGVvSW5wdXQsIF90KFwiY29tbW9ufGNhbWVyYVwiKSkgfHwgKFxuICAgICAgICAgICAgICAgIDxwPntfdChcInNldHRpbmdzfHZvaXB8dmlkZW9faW5wdXRfZW1wdHlcIil9PC9wPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8U2V0dGluZ3NUYWI+XG4gICAgICAgICAgICAgICAgPFNldHRpbmdzU2VjdGlvbj5cbiAgICAgICAgICAgICAgICAgICAge3JlcXVlc3RCdXR0b259XG4gICAgICAgICAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb24gaGVhZGluZz17X3QoXCJzZXR0aW5nc3x2b2lwfHZvaWNlX3NlY3Rpb25cIil9IHN0cmV0Y2hDb250ZW50PlxuICAgICAgICAgICAgICAgICAgICAgICAge3NwZWFrZXJEcm9wZG93bn1cbiAgICAgICAgICAgICAgICAgICAgICAgIHttaWNyb3Bob25lRHJvcGRvd259XG4gICAgICAgICAgICAgICAgICAgICAgICA8TGFiZWxsZWRUb2dnbGVTd2l0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5hdWRpb0F1dG9HYWluQ29udHJvbH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17YXN5bmMgKHYpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgTWVkaWFEZXZpY2VIYW5kbGVyLnNldEF1ZGlvQXV0b0dhaW5Db250cm9sKHYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYXVkaW9BdXRvR2FpbkNvbnRyb2w6IE1lZGlhRGV2aWNlSGFuZGxlci5nZXRBdWRpb0F1dG9HYWluQ29udHJvbCgpIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwic2V0dGluZ3N8dm9pcHx2b2ljZV9hZ2NcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJ2b2ljZS1hdXRvLWdhaW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9TZXR0aW5nc1N1YnNlY3Rpb24+XG4gICAgICAgICAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb24gaGVhZGluZz17X3QoXCJzZXR0aW5nc3x2b2lwfHZpZGVvX3NlY3Rpb25cIil9IHN0cmV0Y2hDb250ZW50PlxuICAgICAgICAgICAgICAgICAgICAgICAge3dlYmNhbURyb3Bkb3dufVxuICAgICAgICAgICAgICAgICAgICAgICAgPFNldHRpbmdzRmxhZyBuYW1lPVwiVmlkZW9WaWV3LmZsaXBWaWRlb0hvcml6b250YWxseVwiIGxldmVsPXtTZXR0aW5nTGV2ZWwuQUNDT1VOVH0gLz5cbiAgICAgICAgICAgICAgICAgICAgPC9TZXR0aW5nc1N1YnNlY3Rpb24+XG4gICAgICAgICAgICAgICAgPC9TZXR0aW5nc1NlY3Rpb24+XG5cbiAgICAgICAgICAgICAgICA8U2V0dGluZ3NTZWN0aW9uIGhlYWRpbmc9e190KFwiY29tbW9ufGFkdmFuY2VkXCIpfT5cbiAgICAgICAgICAgICAgICAgICAgPFNldHRpbmdzU3Vic2VjdGlvbiBoZWFkaW5nPXtfdChcInNldHRpbmdzfHZvaXB8dm9pY2VfcHJvY2Vzc2luZ1wiKX0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8TGFiZWxsZWRUb2dnbGVTd2l0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5hdWRpb05vaXNlU3VwcHJlc3Npb259XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e2FzeW5jICh2KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IE1lZGlhRGV2aWNlSGFuZGxlci5zZXRBdWRpb05vaXNlU3VwcHJlc3Npb24odik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBhdWRpb05vaXNlU3VwcHJlc3Npb246IE1lZGlhRGV2aWNlSGFuZGxlci5nZXRBdWRpb05vaXNlU3VwcHJlc3Npb24oKSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcInNldHRpbmdzfHZvaXB8bm9pc2Vfc3VwcHJlc3Npb25cIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJ2b2ljZS1ub2lzZS1zdXBwcmVzc2lvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPExhYmVsbGVkVG9nZ2xlU3dpdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuc3RhdGUuYXVkaW9FY2hvQ2FuY2VsbGF0aW9ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXthc3luYyAodik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBNZWRpYURldmljZUhhbmRsZXIuc2V0QXVkaW9FY2hvQ2FuY2VsbGF0aW9uKHYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYXVkaW9FY2hvQ2FuY2VsbGF0aW9uOiBNZWRpYURldmljZUhhbmRsZXIuZ2V0QXVkaW9FY2hvQ2FuY2VsbGF0aW9uKCkgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJzZXR0aW5nc3x2b2lwfGVjaG9fY2FuY2VsbGF0aW9uXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwidm9pY2UtZWNoby1jYW5jZWxsYXRpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9TZXR0aW5nc1N1YnNlY3Rpb24+XG4gICAgICAgICAgICAgICAgICAgIDxTZXR0aW5nc1N1YnNlY3Rpb24gaGVhZGluZz17X3QoXCJzZXR0aW5nc3x2b2lwfGNvbm5lY3Rpb25fc2VjdGlvblwiKX0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8U2V0dGluZ3NGbGFnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cIndlYlJ0Y0FsbG93UGVlclRvUGVlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWw9e1NldHRpbmdMZXZlbC5ERVZJQ0V9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e3RoaXMuY2hhbmdlV2ViUnRjTWV0aG9kfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxTZXR0aW5nc0ZsYWdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiZmFsbGJhY2tJQ0VTZXJ2ZXJBbGxvd2VkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJzZXR0aW5nc3x2b2lwfGVuYWJsZV9mYWxsYmFja19pY2Vfc2VydmVyXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyOiBuZXcgVVJMKEZBTExCQUNLX0lDRV9TRVJWRVIpLnBhdGhuYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsPXtTZXR0aW5nTGV2ZWwuREVWSUNFfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGVJZkNhbm5vdFNldFxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9TZXR0aW5nc1N1YnNlY3Rpb24+XG4gICAgICAgICAgICAgICAgPC9TZXR0aW5nc1NlY3Rpb24+XG4gICAgICAgICAgICA8L1NldHRpbmdzVGFiPlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFTQSxJQUFBQSxNQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxLQUFBLEdBQUFGLE9BQUE7QUFFQSxJQUFBRyxnQkFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksbUJBQUEsR0FBQUMsdUJBQUEsQ0FBQUwsT0FBQTtBQUNBLElBQUFNLE1BQUEsR0FBQVAsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFPLGlCQUFBLEdBQUFSLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBUSxhQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyxhQUFBLEdBQUFWLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBVSxxQkFBQSxHQUFBWCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVcsd0JBQUEsR0FBQVgsT0FBQTtBQUNBLElBQUFZLFlBQUEsR0FBQWIsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFhLGdCQUFBLEdBQUFiLE9BQUE7QUFDQSxJQUFBYyxtQkFBQSxHQUFBZixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQWUsb0JBQUEsR0FBQWhCLHNCQUFBLENBQUFDLE9BQUE7QUFBOEUsU0FBQWdCLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLENB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QUM7TUFDM0YsQ0FBRTtNQUNGWSxLQUFLLEVBQUUsSUFBQWMsbUJBQUUsRUFBQyxpQ0FBaUMsQ0FBRTtNQUM3QyxlQUFZO0lBQXlCLENBQ3hDLENBQUMsZUFDRnpHLE1BQUEsQ0FBQXdCLE9BQUEsQ0FBQWdFLGFBQUEsQ0FBQzVFLHFCQUFBLENBQUFZLE9BQW9CO01BQ2pCa0UsS0FBSyxFQUFFLElBQUksQ0FBQ2pCLEtBQUssQ0FBQ0cscUJBQXNCO01BQ3hDc0IsUUFBUSxFQUFFLE1BQU9ZLENBQUMsSUFBb0I7UUFDbEMsTUFBTXBFLDJCQUFrQixDQUFDMkUsd0JBQXdCLENBQUNQLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUN0RCxRQUFRLENBQUM7VUFBRW9CLHFCQUFxQixFQUFFbEMsMkJBQWtCLENBQUNtQyx3QkFBd0IsQ0FBQztRQUFFLENBQUMsQ0FBQztNQUMzRixDQUFFO01BQ0ZjLEtBQUssRUFBRSxJQUFBYyxtQkFBRSxFQUFDLGlDQUFpQyxDQUFFO01BQzdDLGVBQVk7SUFBeUIsQ0FDeEMsQ0FDZSxDQUFDLGVBQ3JCekcsTUFBQSxDQUFBd0IsT0FBQSxDQUFBZ0UsYUFBQSxDQUFDeEUsbUJBQUEsQ0FBQVEsT0FBa0I7TUFBQ29GLE9BQU8sRUFBRSxJQUFBSCxtQkFBRSxFQUFDLGtDQUFrQztJQUFFLGdCQUNoRXpHLE1BQUEsQ0FBQXdCLE9BQUEsQ0FBQWdFLGFBQUEsQ0FBQzdFLGFBQUEsQ0FBQWEsT0FBWTtNQUNUd0YsSUFBSSxFQUFDLHVCQUF1QjtNQUM1QkMsS0FBSyxFQUFFQywwQkFBWSxDQUFDSSxNQUFPO01BQzNCcEIsUUFBUSxFQUFFLElBQUksQ0FBQ3FCO0lBQW1CLENBQ3JDLENBQUMsZUFDRnZILE1BQUEsQ0FBQXdCLE9BQUEsQ0FBQWdFLGFBQUEsQ0FBQzdFLGFBQUEsQ0FBQWEsT0FBWTtNQUNUd0YsSUFBSSxFQUFDLDBCQUEwQjtNQUMvQnJCLEtBQUssRUFBRSxJQUFBYyxtQkFBRSxFQUFDLDBDQUEwQyxFQUFFO1FBQ2xEZSxNQUFNLEVBQUUsSUFBSUMsR0FBRyxDQUFDQyx5QkFBbUIsQ0FBQyxDQUFDQztNQUN6QyxDQUFDLENBQUU7TUFDSFYsS0FBSyxFQUFFQywwQkFBWSxDQUFDSSxNQUFPO01BQzNCTSxlQUFlO0lBQUEsQ0FDbEIsQ0FDZSxDQUNQLENBQ1IsQ0FBQztFQUV0QjtBQUNKO0FBQUNDLE9BQUEsQ0FBQXJHLE9BQUEsR0FBQXdCLG9CQUFBO0FBQUEsSUFBQU0sZ0JBQUEsQ0FBQTlCLE9BQUEsRUFwTG9Cd0Isb0JBQW9CLGlCQUNUOEUsNEJBQW1CIiwiaWdub3JlTGlzdCI6W119