UNPKG

matrix-react-sdk

Version:
293 lines (277 loc) 49 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ThemeChoicePanel = ThemeChoicePanel; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _compoundWeb = require("@vector-im/compound-web"); var _delete = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/delete")); var _classnames = _interopRequireDefault(require("classnames")); var _logger = require("matrix-js-sdk/src/logger"); var _languageHandler = require("../../../languageHandler"); var _SettingsSubsection = _interopRequireDefault(require("./shared/SettingsSubsection")); var _ThemeWatcher = _interopRequireDefault(require("../../../settings/watchers/ThemeWatcher")); var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore")); var _SettingLevel = require("../../../settings/SettingLevel"); var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher")); var _actions = require("../../../dispatcher/actions"); var _useTheme = require("../../../hooks/useTheme"); var _theme2 = require("../../../theme"); var _useSettings = require("../../../hooks/useSettings"); 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; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* * Copyright 2024 New Vector Ltd. * Copyright 2024 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. */ /** * Panel to choose the theme */ function ThemeChoicePanel() { const themeState = (0, _useTheme.useTheme)(); const themeWatcher = (0, _react.useRef)(new _ThemeWatcher.default()); const customThemeEnabled = (0, _useSettings.useSettingValue)("feature_custom_themes"); return /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, { heading: (0, _languageHandler._t)("common|theme"), legacy: false, "data-testid": "themePanel" }, themeWatcher.current.isSystemThemeSupported() && /*#__PURE__*/_react.default.createElement(SystemTheme, { systemThemeActivated: themeState.systemThemeActivated }), /*#__PURE__*/_react.default.createElement(ThemeSelectors, { theme: themeState.theme, disabled: themeState.systemThemeActivated }), customThemeEnabled && /*#__PURE__*/_react.default.createElement(CustomTheme, { theme: themeState.theme })); } /** * Component to toggle the system theme */ /** * Component to toggle the system theme */ function SystemTheme({ systemThemeActivated }) { return /*#__PURE__*/_react.default.createElement(_compoundWeb.Root, { onChange: async evt => { const checked = new FormData(evt.currentTarget).get("systemTheme") === "on"; await _SettingsStore.default.setValue("use_system_theme", null, _SettingLevel.SettingLevel.DEVICE, checked); _dispatcher.default.dispatch({ action: _actions.Action.RecheckTheme }); } }, /*#__PURE__*/_react.default.createElement(_compoundWeb.InlineField, { name: "systemTheme", control: /*#__PURE__*/_react.default.createElement(_compoundWeb.ToggleControl, { name: "systemTheme", defaultChecked: systemThemeActivated }) }, /*#__PURE__*/_react.default.createElement(_compoundWeb.Label, null, _SettingsStore.default.getDisplayName("use_system_theme")))); } /** * Component to select the theme */ /** * Component to select the theme */ function ThemeSelectors({ theme, disabled }) { const themes = useThemes(); return /*#__PURE__*/_react.default.createElement(_compoundWeb.Root, { className: "mx_ThemeChoicePanel_ThemeSelectors", onChange: async evt => { // We don't have any file in the form, we can cast it as string safely const newTheme = new FormData(evt.currentTarget).get("themeSelector"); // Do nothing if the same theme is selected if (!newTheme || theme === newTheme) return; // doing getValue in the .catch will still return the value we failed to set, _SettingsStore.default.setValue("theme", null, _SettingLevel.SettingLevel.DEVICE, newTheme).catch(() => { _dispatcher.default.dispatch({ action: _actions.Action.RecheckTheme }); }); // The settings watcher doesn't fire until the echo comes back from the // server, so to make the theme change immediately we need to manually // do the dispatch now // XXX: The local echoed value appears to be unreliable, in particular // when settings custom themes(!) so adding forceTheme to override // the value from settings. _dispatcher.default.dispatch({ action: _actions.Action.RecheckTheme, forceTheme: newTheme }); } }, themes.map(_theme => { const isChecked = theme === _theme.id; return /*#__PURE__*/_react.default.createElement(_compoundWeb.InlineField, { className: (0, _classnames.default)("mx_ThemeChoicePanel_themeSelector", { [`mx_ThemeChoicePanel_themeSelector_enabled`]: !disabled && theme === _theme.id, [`mx_ThemeChoicePanel_themeSelector_disabled`]: disabled, // We need to force the compound theme to be light or dark // The theme selection doesn't depend on the current theme // For example when the light theme is used, the dark theme selector should be dark "cpd-theme-light": !_theme.isDark, "cpd-theme-dark": _theme.isDark }), name: "themeSelector", key: _theme.id, control: /*#__PURE__*/_react.default.createElement(_compoundWeb.RadioControl, { name: "themeSelector", checked: !disabled && isChecked, disabled: disabled, value: _theme.id }) }, /*#__PURE__*/_react.default.createElement(_compoundWeb.Label, { className: "mx_ThemeChoicePanel_themeSelector_Label" }, _theme.name)); })); } /** * Return all the available themes */ function useThemes() { const customThemes = (0, _useSettings.useSettingValue)("custom_themes"); return (0, _react.useMemo)(() => { // Put the custom theme into a map // To easily find the theme by name when going through the themes list const checkedCustomThemes = customThemes || []; const customThemeMap = checkedCustomThemes.reduce((map, theme) => map.set(theme.name, theme), new Map()); const themes = (0, _theme2.getOrderedThemes)(); // Separate the built-in themes from the custom themes // To insert the high contrast theme between them const builtInThemes = themes.filter(theme => !customThemeMap.has(theme.name)); const otherThemes = themes.filter(theme => customThemeMap.has(theme.name)); const highContrastTheme = makeHighContrastTheme(); if (highContrastTheme) builtInThemes.push(highContrastTheme); const allThemes = builtInThemes.concat(otherThemes); // Check if the themes are dark return allThemes.map(theme => { const customTheme = customThemeMap.get(theme.name); const isDark = (customTheme ? customTheme.is_dark : theme.id.includes("dark")) || false; return _objectSpread(_objectSpread({}, theme), {}, { isDark }); }); }, [customThemes]); } /** * Create the light high contrast theme */ function makeHighContrastTheme() { const lightHighContrastId = (0, _theme2.findHighContrastTheme)("light"); if (lightHighContrastId) { return { name: (0, _languageHandler._t)("settings|appearance|high_contrast"), id: lightHighContrastId }; } } /** * Add and manager custom themes */ function CustomTheme({ theme }) { const [customTheme, setCustomTheme] = (0, _react.useState)(""); const [error, setError] = (0, _react.useState)(); const clear = (0, _react.useCallback)(() => { setError(undefined); setCustomTheme(""); }, [setError, setCustomTheme]); return /*#__PURE__*/_react.default.createElement("div", { className: "mx_ThemeChoicePanel_CustomTheme" }, /*#__PURE__*/_react.default.createElement(_compoundWeb.EditInPlace, { className: "mx_ThemeChoicePanel_CustomTheme_EditInPlace", label: (0, _languageHandler._t)("settings|appearance|custom_theme_add"), cancelButtonLabel: (0, _languageHandler._t)("action|cancel"), saveButtonLabel: (0, _languageHandler._t)("settings|appearance|custom_theme_add"), savingLabel: (0, _languageHandler._t)("settings|appearance|custom_theme_downloading"), value: customTheme, onChange: e => { setError(undefined); setCustomTheme(e.target.value); }, onSave: async () => { // The field empty is empty if (!customTheme) return; // Get the custom themes and do a cheap clone // To avoid to mutate the original array in the settings const currentThemes = _SettingsStore.default.getValue("custom_themes").map(t => t) || []; try { const r = await fetch(customTheme); // XXX: need some schema for this const themeInfo = await r.json(); if (!themeInfo || typeof themeInfo["name"] !== "string" || typeof themeInfo["colors"] !== "object") { setError((0, _languageHandler._t)("settings|appearance|custom_theme_invalid")); return; } // Check if the theme is already existing const isAlreadyExisting = Boolean(currentThemes.find(t => t.name === themeInfo.name)); if (isAlreadyExisting) { clear(); return; } currentThemes.push(themeInfo); } catch (e) { _logger.logger.error(e); setError((0, _languageHandler._t)("settings|appearance|custom_theme_error_downloading")); return; } // Reset the error clear(); await _SettingsStore.default.setValue("custom_themes", null, _SettingLevel.SettingLevel.ACCOUNT, currentThemes); }, onCancel: clear }, /*#__PURE__*/_react.default.createElement(_compoundWeb.HelpMessage, null, (0, _languageHandler._t)("settings|appearance|custom_theme_help")), error && /*#__PURE__*/_react.default.createElement(_compoundWeb.ErrorMessage, null, error)), /*#__PURE__*/_react.default.createElement(CustomThemeList, { theme: theme })); } /** * List of the custom themes */ function CustomThemeList({ theme: currentTheme }) { const customThemes = (0, _useSettings.useSettingValue)("custom_themes") || []; return /*#__PURE__*/_react.default.createElement("ul", { className: "mx_ThemeChoicePanel_CustomThemeList" }, customThemes.map(theme => { return /*#__PURE__*/_react.default.createElement("li", { key: theme.name, className: "mx_ThemeChoicePanel_CustomThemeList_theme", "aria-label": theme.name }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_ThemeChoicePanel_CustomThemeList_name" }, theme.name), /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { destructive: true, "aria-label": (0, _languageHandler._t)("action|delete"), tooltip: (0, _languageHandler._t)("action|delete"), onClick: async () => { // Get the custom themes and do a cheap clone // To avoid to mutate the original array in the settings const currentThemes = _SettingsStore.default.getValue("custom_themes").map(t => t) || []; // Remove the theme from the list const newThemes = currentThemes.filter(t => t.name !== theme.name); await _SettingsStore.default.setValue("custom_themes", null, _SettingLevel.SettingLevel.ACCOUNT, newThemes); // If the delete custom theme is the current theme, reset the theme to the default theme // By settings the theme at null at the device level, we are getting the default theme if (currentTheme === `custom-${theme.name}`) { await _SettingsStore.default.setValue("theme", null, _SettingLevel.SettingLevel.DEVICE, null); _dispatcher.default.dispatch({ action: _actions.Action.RecheckTheme }); } } }, /*#__PURE__*/_react.default.createElement(_delete.default, null))); })); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY29tcG91bmRXZWIiLCJfZGVsZXRlIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9jbGFzc25hbWVzIiwiX2xvZ2dlciIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfU2V0dGluZ3NTdWJzZWN0aW9uIiwiX1RoZW1lV2F0Y2hlciIsIl9TZXR0aW5nc1N0b3JlIiwiX1NldHRpbmdMZXZlbCIsIl9kaXNwYXRjaGVyIiwiX2FjdGlvbnMiLCJfdXNlVGhlbWUiLCJfdGhlbWUyIiwiX3VzZVNldHRpbmdzIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0Iiwib3duS2V5cyIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiVGhlbWVDaG9pY2VQYW5lbCIsInRoZW1lU3RhdGUiLCJ1c2VUaGVtZSIsInRoZW1lV2F0Y2hlciIsInVzZVJlZiIsIlRoZW1lV2F0Y2hlciIsImN1c3RvbVRoZW1lRW5hYmxlZCIsInVzZVNldHRpbmdWYWx1ZSIsImNyZWF0ZUVsZW1lbnQiLCJoZWFkaW5nIiwiX3QiLCJsZWdhY3kiLCJjdXJyZW50IiwiaXNTeXN0ZW1UaGVtZVN1cHBvcnRlZCIsIlN5c3RlbVRoZW1lIiwic3lzdGVtVGhlbWVBY3RpdmF0ZWQiLCJUaGVtZVNlbGVjdG9ycyIsInRoZW1lIiwiZGlzYWJsZWQiLCJDdXN0b21UaGVtZSIsIlJvb3QiLCJvbkNoYW5nZSIsImV2dCIsImNoZWNrZWQiLCJGb3JtRGF0YSIsImN1cnJlbnRUYXJnZXQiLCJTZXR0aW5nc1N0b3JlIiwic2V0VmFsdWUiLCJTZXR0aW5nTGV2ZWwiLCJERVZJQ0UiLCJkaXMiLCJkaXNwYXRjaCIsImFjdGlvbiIsIkFjdGlvbiIsIlJlY2hlY2tUaGVtZSIsIklubGluZUZpZWxkIiwibmFtZSIsImNvbnRyb2wiLCJUb2dnbGVDb250cm9sIiwiZGVmYXVsdENoZWNrZWQiLCJMYWJlbCIsImdldERpc3BsYXlOYW1lIiwidGhlbWVzIiwidXNlVGhlbWVzIiwiY2xhc3NOYW1lIiwibmV3VGhlbWUiLCJjYXRjaCIsImZvcmNlVGhlbWUiLCJtYXAiLCJfdGhlbWUiLCJpc0NoZWNrZWQiLCJpZCIsImNsYXNzTmFtZXMiLCJpc0RhcmsiLCJrZXkiLCJSYWRpb0NvbnRyb2wiLCJ2YWx1ZSIsImN1c3RvbVRoZW1lcyIsInVzZU1lbW8iLCJjaGVja2VkQ3VzdG9tVGhlbWVzIiwiY3VzdG9tVGhlbWVNYXAiLCJyZWR1Y2UiLCJNYXAiLCJnZXRPcmRlcmVkVGhlbWVzIiwiYnVpbHRJblRoZW1lcyIsIm90aGVyVGhlbWVzIiwiaGlnaENvbnRyYXN0VGhlbWUiLCJtYWtlSGlnaENvbnRyYXN0VGhlbWUiLCJhbGxUaGVtZXMiLCJjb25jYXQiLCJjdXN0b21UaGVtZSIsImlzX2RhcmsiLCJpbmNsdWRlcyIsImxpZ2h0SGlnaENvbnRyYXN0SWQiLCJmaW5kSGlnaENvbnRyYXN0VGhlbWUiLCJzZXRDdXN0b21UaGVtZSIsInVzZVN0YXRlIiwiZXJyb3IiLCJzZXRFcnJvciIsImNsZWFyIiwidXNlQ2FsbGJhY2siLCJ1bmRlZmluZWQiLCJFZGl0SW5QbGFjZSIsImxhYmVsIiwiY2FuY2VsQnV0dG9uTGFiZWwiLCJzYXZlQnV0dG9uTGFiZWwiLCJzYXZpbmdMYWJlbCIsInRhcmdldCIsIm9uU2F2ZSIsImN1cnJlbnRUaGVtZXMiLCJnZXRWYWx1ZSIsImZldGNoIiwidGhlbWVJbmZvIiwianNvbiIsImlzQWxyZWFkeUV4aXN0aW5nIiwiQm9vbGVhbiIsImZpbmQiLCJsb2dnZXIiLCJBQ0NPVU5UIiwib25DYW5jZWwiLCJIZWxwTWVzc2FnZSIsIkVycm9yTWVzc2FnZSIsIkN1c3RvbVRoZW1lTGlzdCIsImN1cnJlbnRUaGVtZSIsIkljb25CdXR0b24iLCJkZXN0cnVjdGl2ZSIsInRvb2x0aXAiLCJvbkNsaWNrIiwibmV3VGhlbWVzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3Mvc2V0dGluZ3MvVGhlbWVDaG9pY2VQYW5lbC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuICogQ29weXJpZ2h0IDIwMjQgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcbiAqIFBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4gKi9cblxuaW1wb3J0IFJlYWN0LCB7IENoYW5nZUV2ZW50LCBKU1gsIHVzZUNhbGxiYWNrLCB1c2VNZW1vLCB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQge1xuICAgIElubGluZUZpZWxkLFxuICAgIFRvZ2dsZUNvbnRyb2wsXG4gICAgTGFiZWwsXG4gICAgUm9vdCxcbiAgICBSYWRpb0NvbnRyb2wsXG4gICAgRWRpdEluUGxhY2UsXG4gICAgSWNvbkJ1dHRvbixcbiAgICBFcnJvck1lc3NhZ2UsXG4gICAgSGVscE1lc3NhZ2UsXG59IGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLXdlYlwiO1xuaW1wb3J0IERlbGV0ZUljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2RlbGV0ZVwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgU2V0dGluZ3NTdWJzZWN0aW9uIGZyb20gXCIuL3NoYXJlZC9TZXR0aW5nc1N1YnNlY3Rpb25cIjtcbmltcG9ydCBUaGVtZVdhdGNoZXIgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL3dhdGNoZXJzL1RoZW1lV2F0Y2hlclwiO1xuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcbmltcG9ydCB7IFNldHRpbmdMZXZlbCB9IGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nTGV2ZWxcIjtcbmltcG9ydCBkaXMgZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgUmVjaGVja1RoZW1lUGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzL1JlY2hlY2tUaGVtZVBheWxvYWRcIjtcbmltcG9ydCB7IEFjdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2FjdGlvbnNcIjtcbmltcG9ydCB7IHVzZVRoZW1lIH0gZnJvbSBcIi4uLy4uLy4uL2hvb2tzL3VzZVRoZW1lXCI7XG5pbXBvcnQgeyBmaW5kSGlnaENvbnRyYXN0VGhlbWUsIGdldE9yZGVyZWRUaGVtZXMsIEN1c3RvbVRoZW1lIGFzIEN1c3RvbVRoZW1lVHlwZSwgSVRoZW1lIH0gZnJvbSBcIi4uLy4uLy4uL3RoZW1lXCI7XG5pbXBvcnQgeyB1c2VTZXR0aW5nVmFsdWUgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlU2V0dGluZ3NcIjtcblxuLyoqXG4gKiBQYW5lbCB0byBjaG9vc2UgdGhlIHRoZW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUaGVtZUNob2ljZVBhbmVsKCk6IEpTWC5FbGVtZW50IHtcbiAgICBjb25zdCB0aGVtZVN0YXRlID0gdXNlVGhlbWUoKTtcbiAgICBjb25zdCB0aGVtZVdhdGNoZXIgPSB1c2VSZWYobmV3IFRoZW1lV2F0Y2hlcigpKTtcbiAgICBjb25zdCBjdXN0b21UaGVtZUVuYWJsZWQgPSB1c2VTZXR0aW5nVmFsdWU8Ym9vbGVhbj4oXCJmZWF0dXJlX2N1c3RvbV90aGVtZXNcIik7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8U2V0dGluZ3NTdWJzZWN0aW9uIGhlYWRpbmc9e190KFwiY29tbW9ufHRoZW1lXCIpfSBsZWdhY3k9e2ZhbHNlfSBkYXRhLXRlc3RpZD1cInRoZW1lUGFuZWxcIj5cbiAgICAgICAgICAgIHt0aGVtZVdhdGNoZXIuY3VycmVudC5pc1N5c3RlbVRoZW1lU3VwcG9ydGVkKCkgJiYgKFxuICAgICAgICAgICAgICAgIDxTeXN0ZW1UaGVtZSBzeXN0ZW1UaGVtZUFjdGl2YXRlZD17dGhlbWVTdGF0ZS5zeXN0ZW1UaGVtZUFjdGl2YXRlZH0gLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8VGhlbWVTZWxlY3RvcnMgdGhlbWU9e3RoZW1lU3RhdGUudGhlbWV9IGRpc2FibGVkPXt0aGVtZVN0YXRlLnN5c3RlbVRoZW1lQWN0aXZhdGVkfSAvPlxuICAgICAgICAgICAge2N1c3RvbVRoZW1lRW5hYmxlZCAmJiA8Q3VzdG9tVGhlbWUgdGhlbWU9e3RoZW1lU3RhdGUudGhlbWV9IC8+fVxuICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvbj5cbiAgICApO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCB0byB0b2dnbGUgdGhlIHN5c3RlbSB0aGVtZVxuICovXG5pbnRlcmZhY2UgU3lzdGVtVGhlbWVQcm9wcyB7XG4gICAgLyogV2hldGhlciB0aGUgc3lzdGVtIHRoZW1lIGlzIGFjdGl2YXRlZCAqL1xuICAgIHN5c3RlbVRoZW1lQWN0aXZhdGVkOiBib29sZWFuO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCB0byB0b2dnbGUgdGhlIHN5c3RlbSB0aGVtZVxuICovXG5mdW5jdGlvbiBTeXN0ZW1UaGVtZSh7IHN5c3RlbVRoZW1lQWN0aXZhdGVkIH06IFN5c3RlbVRoZW1lUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPFJvb3RcbiAgICAgICAgICAgIG9uQ2hhbmdlPXthc3luYyAoZXZ0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hlY2tlZCA9IG5ldyBGb3JtRGF0YShldnQuY3VycmVudFRhcmdldCkuZ2V0KFwic3lzdGVtVGhlbWVcIikgPT09IFwib25cIjtcbiAgICAgICAgICAgICAgICBhd2FpdCBTZXR0aW5nc1N0b3JlLnNldFZhbHVlKFwidXNlX3N5c3RlbV90aGVtZVwiLCBudWxsLCBTZXR0aW5nTGV2ZWwuREVWSUNFLCBjaGVja2VkKTtcbiAgICAgICAgICAgICAgICBkaXMuZGlzcGF0Y2g8UmVjaGVja1RoZW1lUGF5bG9hZD4oeyBhY3Rpb246IEFjdGlvbi5SZWNoZWNrVGhlbWUgfSk7XG4gICAgICAgICAgICB9fVxuICAgICAgICA+XG4gICAgICAgICAgICA8SW5saW5lRmllbGRcbiAgICAgICAgICAgICAgICBuYW1lPVwic3lzdGVtVGhlbWVcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2w9ezxUb2dnbGVDb250cm9sIG5hbWU9XCJzeXN0ZW1UaGVtZVwiIGRlZmF1bHRDaGVja2VkPXtzeXN0ZW1UaGVtZUFjdGl2YXRlZH0gLz59XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPExhYmVsPntTZXR0aW5nc1N0b3JlLmdldERpc3BsYXlOYW1lKFwidXNlX3N5c3RlbV90aGVtZVwiKX08L0xhYmVsPlxuICAgICAgICAgICAgPC9JbmxpbmVGaWVsZD5cbiAgICAgICAgPC9Sb290PlxuICAgICk7XG59XG5cbi8qKlxuICogQ29tcG9uZW50IHRvIHNlbGVjdCB0aGUgdGhlbWVcbiAqL1xuaW50ZXJmYWNlIFRoZW1lU2VsZWN0b3JQcm9wcyB7XG4gICAgLyogVGhlIGN1cnJlbnQgdGhlbWUgKi9cbiAgICB0aGVtZTogc3RyaW5nO1xuICAgIC8qIFRoZSB0aGVtZSBjYW4ndCBiZSBzZWxlY3RlZCAqL1xuICAgIGRpc2FibGVkOiBib29sZWFuO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCB0byBzZWxlY3QgdGhlIHRoZW1lXG4gKi9cbmZ1bmN0aW9uIFRoZW1lU2VsZWN0b3JzKHsgdGhlbWUsIGRpc2FibGVkIH06IFRoZW1lU2VsZWN0b3JQcm9wcyk6IEpTWC5FbGVtZW50IHtcbiAgICBjb25zdCB0aGVtZXMgPSB1c2VUaGVtZXMoKTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIDxSb290XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJteF9UaGVtZUNob2ljZVBhbmVsX1RoZW1lU2VsZWN0b3JzXCJcbiAgICAgICAgICAgIG9uQ2hhbmdlPXthc3luYyAoZXZ0KSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgaGF2ZSBhbnkgZmlsZSBpbiB0aGUgZm9ybSwgd2UgY2FuIGNhc3QgaXQgYXMgc3RyaW5nIHNhZmVseVxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1RoZW1lID0gbmV3IEZvcm1EYXRhKGV2dC5jdXJyZW50VGFyZ2V0KS5nZXQoXCJ0aGVtZVNlbGVjdG9yXCIpIGFzIHN0cmluZyB8IG51bGw7XG5cbiAgICAgICAgICAgICAgICAvLyBEbyBub3RoaW5nIGlmIHRoZSBzYW1lIHRoZW1lIGlzIHNlbGVjdGVkXG4gICAgICAgICAgICAgICAgaWYgKCFuZXdUaGVtZSB8fCB0aGVtZSA9PT0gbmV3VGhlbWUpIHJldHVybjtcblxuICAgICAgICAgICAgICAgIC8vIGRvaW5nIGdldFZhbHVlIGluIHRoZSAuY2F0Y2ggd2lsbCBzdGlsbCByZXR1cm4gdGhlIHZhbHVlIHdlIGZhaWxlZCB0byBzZXQsXG4gICAgICAgICAgICAgICAgU2V0dGluZ3NTdG9yZS5zZXRWYWx1ZShcInRoZW1lXCIsIG51bGwsIFNldHRpbmdMZXZlbC5ERVZJQ0UsIG5ld1RoZW1lKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRpcy5kaXNwYXRjaDxSZWNoZWNrVGhlbWVQYXlsb2FkPih7IGFjdGlvbjogQWN0aW9uLlJlY2hlY2tUaGVtZSB9KTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIFRoZSBzZXR0aW5ncyB3YXRjaGVyIGRvZXNuJ3QgZmlyZSB1bnRpbCB0aGUgZWNobyBjb21lcyBiYWNrIGZyb20gdGhlXG4gICAgICAgICAgICAgICAgLy8gc2VydmVyLCBzbyB0byBtYWtlIHRoZSB0aGVtZSBjaGFuZ2UgaW1tZWRpYXRlbHkgd2UgbmVlZCB0byBtYW51YWxseVxuICAgICAgICAgICAgICAgIC8vIGRvIHRoZSBkaXNwYXRjaCBub3dcbiAgICAgICAgICAgICAgICAvLyBYWFg6IFRoZSBsb2NhbCBlY2hvZWQgdmFsdWUgYXBwZWFycyB0byBiZSB1bnJlbGlhYmxlLCBpbiBwYXJ0aWN1bGFyXG4gICAgICAgICAgICAgICAgLy8gd2hlbiBzZXR0aW5ncyBjdXN0b20gdGhlbWVzKCEpIHNvIGFkZGluZyBmb3JjZVRoZW1lIHRvIG92ZXJyaWRlXG4gICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGZyb20gc2V0dGluZ3MuXG4gICAgICAgICAgICAgICAgZGlzLmRpc3BhdGNoPFJlY2hlY2tUaGVtZVBheWxvYWQ+KHsgYWN0aW9uOiBBY3Rpb24uUmVjaGVja1RoZW1lLCBmb3JjZVRoZW1lOiBuZXdUaGVtZSB9KTtcbiAgICAgICAgICAgIH19XG4gICAgICAgID5cbiAgICAgICAgICAgIHt0aGVtZXMubWFwKChfdGhlbWUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpc0NoZWNrZWQgPSB0aGVtZSA9PT0gX3RoZW1lLmlkO1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxJbmxpbmVGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKFwibXhfVGhlbWVDaG9pY2VQYW5lbF90aGVtZVNlbGVjdG9yXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYG14X1RoZW1lQ2hvaWNlUGFuZWxfdGhlbWVTZWxlY3Rvcl9lbmFibGVkYF06ICFkaXNhYmxlZCAmJiB0aGVtZSA9PT0gX3RoZW1lLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtgbXhfVGhlbWVDaG9pY2VQYW5lbF90aGVtZVNlbGVjdG9yX2Rpc2FibGVkYF06IGRpc2FibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gZm9yY2UgdGhlIGNvbXBvdW5kIHRoZW1lIHRvIGJlIGxpZ2h0IG9yIGRhcmtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgdGhlbWUgc2VsZWN0aW9uIGRvZXNuJ3QgZGVwZW5kIG9uIHRoZSBjdXJyZW50IHRoZW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIGV4YW1wbGUgd2hlbiB0aGUgbGlnaHQgdGhlbWUgaXMgdXNlZCwgdGhlIGRhcmsgdGhlbWUgc2VsZWN0b3Igc2hvdWxkIGJlIGRhcmtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNwZC10aGVtZS1saWdodFwiOiAhX3RoZW1lLmlzRGFyayxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNwZC10aGVtZS1kYXJrXCI6IF90aGVtZS5pc0RhcmssXG4gICAgICAgICAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0aGVtZVNlbGVjdG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleT17X3RoZW1lLmlkfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbD17XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPFJhZGlvQ29udHJvbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwidGhlbWVTZWxlY3RvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrZWQ9eyFkaXNhYmxlZCAmJiBpc0NoZWNrZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXtkaXNhYmxlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e190aGVtZS5pZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8TGFiZWwgY2xhc3NOYW1lPVwibXhfVGhlbWVDaG9pY2VQYW5lbF90aGVtZVNlbGVjdG9yX0xhYmVsXCI+e190aGVtZS5uYW1lfTwvTGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDwvSW5saW5lRmllbGQ+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pfVxuICAgICAgICA8L1Jvb3Q+XG4gICAgKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYWxsIHRoZSBhdmFpbGFibGUgdGhlbWVzXG4gKi9cbmZ1bmN0aW9uIHVzZVRoZW1lcygpOiBBcnJheTxJVGhlbWUgJiB7IGlzRGFyazogYm9vbGVhbiB9PiB7XG4gICAgY29uc3QgY3VzdG9tVGhlbWVzID0gdXNlU2V0dGluZ1ZhbHVlPEN1c3RvbVRoZW1lVHlwZVtdIHwgdW5kZWZpbmVkPihcImN1c3RvbV90aGVtZXNcIik7XG4gICAgcmV0dXJuIHVzZU1lbW8oKCkgPT4ge1xuICAgICAgICAvLyBQdXQgdGhlIGN1c3RvbSB0aGVtZSBpbnRvIGEgbWFwXG4gICAgICAgIC8vIFRvIGVhc2lseSBmaW5kIHRoZSB0aGVtZSBieSBuYW1lIHdoZW4gZ29pbmcgdGhyb3VnaCB0aGUgdGhlbWVzIGxpc3RcbiAgICAgICAgY29uc3QgY2hlY2tlZEN1c3RvbVRoZW1lcyA9IGN1c3RvbVRoZW1lcyB8fCBbXTtcbiAgICAgICAgY29uc3QgY3VzdG9tVGhlbWVNYXAgPSBjaGVja2VkQ3VzdG9tVGhlbWVzLnJlZHVjZShcbiAgICAgICAgICAgIChtYXAsIHRoZW1lKSA9PiBtYXAuc2V0KHRoZW1lLm5hbWUsIHRoZW1lKSxcbiAgICAgICAgICAgIG5ldyBNYXA8c3RyaW5nLCBDdXN0b21UaGVtZVR5cGU+KCksXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgdGhlbWVzID0gZ2V0T3JkZXJlZFRoZW1lcygpO1xuICAgICAgICAvLyBTZXBhcmF0ZSB0aGUgYnVpbHQtaW4gdGhlbWVzIGZyb20gdGhlIGN1c3RvbSB0aGVtZXNcbiAgICAgICAgLy8gVG8gaW5zZXJ0IHRoZSBoaWdoIGNvbnRyYXN0IHRoZW1lIGJldHdlZW4gdGhlbVxuICAgICAgICBjb25zdCBidWlsdEluVGhlbWVzID0gdGhlbWVzLmZpbHRlcigodGhlbWUpID0+ICFjdXN0b21UaGVtZU1hcC5oYXModGhlbWUubmFtZSkpO1xuICAgICAgICBjb25zdCBvdGhlclRoZW1lcyA9IHRoZW1lcy5maWx0ZXIoKHRoZW1lKSA9PiBjdXN0b21UaGVtZU1hcC5oYXModGhlbWUubmFtZSkpO1xuXG4gICAgICAgIGNvbnN0IGhpZ2hDb250cmFzdFRoZW1lID0gbWFrZUhpZ2hDb250cmFzdFRoZW1lKCk7XG4gICAgICAgIGlmIChoaWdoQ29udHJhc3RUaGVtZSkgYnVpbHRJblRoZW1lcy5wdXNoKGhpZ2hDb250cmFzdFRoZW1lKTtcblxuICAgICAgICBjb25zdCBhbGxUaGVtZXMgPSBidWlsdEluVGhlbWVzLmNvbmNhdChvdGhlclRoZW1lcyk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHRoZW1lcyBhcmUgZGFya1xuICAgICAgICByZXR1cm4gYWxsVGhlbWVzLm1hcCgodGhlbWUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbVRoZW1lID0gY3VzdG9tVGhlbWVNYXAuZ2V0KHRoZW1lLm5hbWUpO1xuICAgICAgICAgICAgY29uc3QgaXNEYXJrID0gKGN1c3RvbVRoZW1lID8gY3VzdG9tVGhlbWUuaXNfZGFyayA6IHRoZW1lLmlkLmluY2x1ZGVzKFwiZGFya1wiKSkgfHwgZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4geyAuLi50aGVtZSwgaXNEYXJrIH07XG4gICAgICAgIH0pO1xuICAgIH0sIFtjdXN0b21UaGVtZXNdKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgdGhlIGxpZ2h0IGhpZ2ggY29udHJhc3QgdGhlbWVcbiAqL1xuZnVuY3Rpb24gbWFrZUhpZ2hDb250cmFzdFRoZW1lKCk6IElUaGVtZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgbGlnaHRIaWdoQ29udHJhc3RJZCA9IGZpbmRIaWdoQ29udHJhc3RUaGVtZShcImxpZ2h0XCIpO1xuICAgIGlmIChsaWdodEhpZ2hDb250cmFzdElkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuYW1lOiBfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8aGlnaF9jb250cmFzdFwiKSxcbiAgICAgICAgICAgIGlkOiBsaWdodEhpZ2hDb250cmFzdElkLFxuICAgICAgICB9O1xuICAgIH1cbn1cblxuaW50ZXJmYWNlIEN1c3RvbVRoZW1lUHJvcHMge1xuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRoZW1lXG4gICAgICovXG4gICAgdGhlbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBZGQgYW5kIG1hbmFnZXIgY3VzdG9tIHRoZW1lc1xuICovXG5mdW5jdGlvbiBDdXN0b21UaGVtZSh7IHRoZW1lIH06IEN1c3RvbVRoZW1lUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgY29uc3QgW2N1c3RvbVRoZW1lLCBzZXRDdXN0b21UaGVtZV0gPSB1c2VTdGF0ZTxzdHJpbmc+KFwiXCIpO1xuICAgIGNvbnN0IFtlcnJvciwgc2V0RXJyb3JdID0gdXNlU3RhdGU8c3RyaW5nPigpO1xuICAgIGNvbnN0IGNsZWFyID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgICBzZXRFcnJvcih1bmRlZmluZWQpO1xuICAgICAgICBzZXRDdXN0b21UaGVtZShcIlwiKTtcbiAgICB9LCBbc2V0RXJyb3IsIHNldEN1c3RvbVRoZW1lXSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1RoZW1lQ2hvaWNlUGFuZWxfQ3VzdG9tVGhlbWVcIj5cbiAgICAgICAgICAgIDxFZGl0SW5QbGFjZVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1RoZW1lQ2hvaWNlUGFuZWxfQ3VzdG9tVGhlbWVfRWRpdEluUGxhY2VcIlxuICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8Y3VzdG9tX3RoZW1lX2FkZFwiKX1cbiAgICAgICAgICAgICAgICBjYW5jZWxCdXR0b25MYWJlbD17X3QoXCJhY3Rpb258Y2FuY2VsXCIpfVxuICAgICAgICAgICAgICAgIHNhdmVCdXR0b25MYWJlbD17X3QoXCJzZXR0aW5nc3xhcHBlYXJhbmNlfGN1c3RvbV90aGVtZV9hZGRcIil9XG4gICAgICAgICAgICAgICAgc2F2aW5nTGFiZWw9e190KFwic2V0dGluZ3N8YXBwZWFyYW5jZXxjdXN0b21fdGhlbWVfZG93bmxvYWRpbmdcIil9XG4gICAgICAgICAgICAgICAgdmFsdWU9e2N1c3RvbVRoZW1lfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsoZTogQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0Q3VzdG9tVGhlbWUoZS50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgb25TYXZlPXthc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBmaWVsZCBlbXB0eSBpcyBlbXB0eVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWN1c3RvbVRoZW1lKSByZXR1cm47XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXN0b20gdGhlbWVzIGFuZCBkbyBhIGNoZWFwIGNsb25lXG4gICAgICAgICAgICAgICAgICAgIC8vIFRvIGF2b2lkIHRvIG11dGF0ZSB0aGUgb3JpZ2luYWwgYXJyYXkgaW4gdGhlIHNldHRpbmdzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaGVtZXMgPVxuICAgICAgICAgICAgICAgICAgICAgICAgU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZTxDdXN0b21UaGVtZVR5cGVbXT4oXCJjdXN0b21fdGhlbWVzXCIpLm1hcCgodCkgPT4gdCkgfHwgW107XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBmZXRjaChjdXN0b21UaGVtZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBYWFg6IG5lZWQgc29tZSBzY2hlbWEgZm9yIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRoZW1lSW5mbyA9IGF3YWl0IHIuanNvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICF0aGVtZUluZm8gfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdGhlbWVJbmZvW1wibmFtZVwiXSAhPT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB0aGVtZUluZm9bXCJjb2xvcnNcIl0gIT09IFwib2JqZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEVycm9yKF90KFwic2V0dGluZ3N8YXBwZWFyYW5jZXxjdXN0b21fdGhlbWVfaW52YWxpZFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgdGhlbWUgaXMgYWxyZWFkeSBleGlzdGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNBbHJlYWR5RXhpc3RpbmcgPSBCb29sZWFuKGN1cnJlbnRUaGVtZXMuZmluZCgodCkgPT4gdC5uYW1lID09PSB0aGVtZUluZm8ubmFtZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWxyZWFkeUV4aXN0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUaGVtZXMucHVzaCh0aGVtZUluZm8pO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRFcnJvcihfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8Y3VzdG9tX3RoZW1lX2Vycm9yX2Rvd25sb2FkaW5nXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBlcnJvclxuICAgICAgICAgICAgICAgICAgICBjbGVhcigpO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBTZXR0aW5nc1N0b3JlLnNldFZhbHVlKFwiY3VzdG9tX3RoZW1lc1wiLCBudWxsLCBTZXR0aW5nTGV2ZWwuQUNDT1VOVCwgY3VycmVudFRoZW1lcyk7XG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICBvbkNhbmNlbD17Y2xlYXJ9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPEhlbHBNZXNzYWdlPntfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8Y3VzdG9tX3RoZW1lX2hlbHBcIil9PC9IZWxwTWVzc2FnZT5cbiAgICAgICAgICAgICAgICB7ZXJyb3IgJiYgPEVycm9yTWVzc2FnZT57ZXJyb3J9PC9FcnJvck1lc3NhZ2U+fVxuICAgICAgICAgICAgPC9FZGl0SW5QbGFjZT5cbiAgICAgICAgICAgIDxDdXN0b21UaGVtZUxpc3QgdGhlbWU9e3RoZW1lfSAvPlxuICAgICAgICA8L2Rpdj5cbiAgICApO1xufVxuXG5pbnRlcmZhY2UgQ3VzdG9tVGhlbWVMaXN0UHJvcHMge1xuICAgIC8qXG4gICAgICogVGhlIGN1cnJlbnQgdGhlbWVcbiAgICAgKi9cbiAgICB0aGVtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIExpc3Qgb2YgdGhlIGN1c3RvbSB0aGVtZXNcbiAqL1xuZnVuY3Rpb24gQ3VzdG9tVGhlbWVMaXN0KHsgdGhlbWU6IGN1cnJlbnRUaGVtZSB9OiBDdXN0b21UaGVtZUxpc3RQcm9wcyk6IEpTWC5FbGVtZW50IHtcbiAgICBjb25zdCBjdXN0b21UaGVtZXMgPSB1c2VTZXR0aW5nVmFsdWU8Q3VzdG9tVGhlbWVUeXBlW10+KFwiY3VzdG9tX3RoZW1lc1wiKSB8fCBbXTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIDx1bCBjbGFzc05hbWU9XCJteF9UaGVtZUNob2ljZVBhbmVsX0N1c3RvbVRoZW1lTGlzdFwiPlxuICAgICAgICAgICAge2N1c3RvbVRoZW1lcy5tYXAoKHRoZW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGxpIGtleT17dGhlbWUubmFtZX0gY2xhc3NOYW1lPVwibXhfVGhlbWVDaG9pY2VQYW5lbF9DdXN0b21UaGVtZUxpc3RfdGhlbWVcIiBhcmlhLWxhYmVsPXt0aGVtZS5uYW1lfT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X1RoZW1lQ2hvaWNlUGFuZWxfQ3VzdG9tVGhlbWVMaXN0X25hbWVcIj57dGhlbWUubmFtZX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RydWN0aXZlPXt0cnVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiYWN0aW9ufGRlbGV0ZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwPXtfdChcImFjdGlvbnxkZWxldGVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17YXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGN1c3RvbSB0aGVtZXMgYW5kIGRvIGEgY2hlYXAgY2xvbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVG8gYXZvaWQgdG8gbXV0YXRlIHRoZSBvcmlnaW5hbCBhcnJheSBpbiB0aGUgc2V0dGluZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFRoZW1lcyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXR0aW5nc1N0b3JlLmdldFZhbHVlPEN1c3RvbVRoZW1lVHlwZVtdPihcImN1c3RvbV90aGVtZXNcIikubWFwKCh0KSA9PiB0KSB8fCBbXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIHRoZW1lIGZyb20gdGhlIGxpc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3VGhlbWVzID0gY3VycmVudFRoZW1lcy5maWx0ZXIoKHQpID0+IHQubmFtZSAhPT0gdGhlbWUubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IFNldHRpbmdzU3RvcmUuc2V0VmFsdWUoXCJjdXN0b21fdGhlbWVzXCIsIG51bGwsIFNldHRpbmdMZXZlbC5BQ0NPVU5ULCBuZXdUaGVtZXMpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBkZWxldGUgY3VzdG9tIHRoZW1lIGlzIHRoZSBjdXJyZW50IHRoZW1lLCByZXNldCB0aGUgdGhlbWUgdG8gdGhlIGRlZmF1bHQgdGhlbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnkgc2V0dGluZ3MgdGhlIHRoZW1lIGF0IG51bGwgYXQgdGhlIGRldmljZSBsZXZlbCwgd2UgYXJlIGdldHRpbmcgdGhlIGRlZmF1bHQgdGhlbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRUaGVtZSA9PT0gYGN1c3RvbS0ke3RoZW1lLm5hbWV9YCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgU2V0dGluZ3NTdG9yZS5zZXRWYWx1ZShcInRoZW1lXCIsIG51bGwsIFNldHRpbmdMZXZlbC5ERVZJQ0UsIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzLmRpc3BhdGNoPFJlY2hlY2tUaGVtZVBheWxvYWQ+KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IEFjdGlvbi5SZWNoZWNrVGhlbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPERlbGV0ZUljb24gLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSl9XG4gICAgICAgIDwvdWw+XG4gICAgKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFELE9BQUE7QUFXQSxJQUFBRSxPQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxXQUFBLEdBQUFELHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSyxPQUFBLEdBQUFMLE9BQUE7QUFFQSxJQUFBTSxnQkFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sbUJBQUEsR0FBQUosc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFRLGFBQUEsR0FBQUwsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFTLGNBQUEsR0FBQU4sc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFVLGFBQUEsR0FBQVYsT0FBQTtBQUNBLElBQUFXLFdBQUEsR0FBQVIsc0JBQUEsQ0FBQUgsT0FBQTtBQUVBLElBQUFZLFFBQUEsR0FBQVosT0FBQTtBQUNBLElBQUFhLFNBQUEsR0FBQWIsT0FBQTtBQUNBLElBQUFjLE9BQUEsR0FBQWQsT0FBQTtBQUNBLElBQUFlLFlBQUEsR0FBQWYsT0FBQTtBQUE2RCxTQUFBZ0IseUJBQUFDLENBQUEsNkJBQUFDLE9BQUEsbUJBQUFDLENBQUEsT0FBQUQsT0FBQSxJQUFBRSxDQUFBLE9BQUFGLE9BQUEsWUFBQUYsd0JBQUEsWUFBQUEsQ0FBQUMsQ0FBQSxXQUFBQSxDQUFBLEdBQUFHLENBQUEsR0FBQUQsQ0FBQSxLQUFBRixDQUFBO0FBQUEsU0FBQWxCLHdCQUFBa0IsQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFdBQUFLLE9BQUEsRUFBQUws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