airdcpp-webui 2.11.3 → 2.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.html +1 -1
- package/dist/js/{home.e0a12a5976f765a14bbd.chunk.js → home.78e827952ac599204c53.chunk.js} +3 -3
- package/dist/js/{home.e0a12a5976f765a14bbd.chunk.js.LICENSE.txt → home.78e827952ac599204c53.chunk.js.LICENSE.txt} +0 -0
- package/dist/js/home.78e827952ac599204c53.chunk.js.gz +0 -0
- package/dist/js/home.78e827952ac599204c53.chunk.js.map +1 -0
- package/dist/js/{main.8a24b8852d2731b9b531.entry.js → main.0b5fa9541797f26255d9.entry.js} +3 -3
- package/dist/js/{main.8a24b8852d2731b9b531.entry.js.LICENSE.txt → main.0b5fa9541797f26255d9.entry.js.LICENSE.txt} +0 -0
- package/dist/js/main.0b5fa9541797f26255d9.entry.js.gz +0 -0
- package/dist/js/{main.8a24b8852d2731b9b531.entry.js.map → main.0b5fa9541797f26255d9.entry.js.map} +1 -1
- package/dist/js/{settings.29ee94ab2fe50083c74e.chunk.js → settings.7aeffada3e24ba15d447.chunk.js} +2 -2
- package/dist/js/settings.7aeffada3e24ba15d447.chunk.js.gz +0 -0
- package/dist/js/{settings.29ee94ab2fe50083c74e.chunk.js.map → settings.7aeffada3e24ba15d447.chunk.js.map} +1 -1
- package/dist/sw.js +1 -1
- package/dist/sw.js.gz +0 -0
- package/package.json +1 -1
- package/dist/js/home.e0a12a5976f765a14bbd.chunk.js.gz +0 -0
- package/dist/js/home.e0a12a5976f765a14bbd.chunk.js.map +0 -1
- package/dist/js/main.8a24b8852d2731b9b531.entry.js.gz +0 -0
- package/dist/js/settings.29ee94ab2fe50083c74e.chunk.js.gz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js/settings.29ee94ab2fe50083c74e.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./node_modules/compare-versions/lib/esm/index.js","webpack://airdcpp-webui/./node_modules/fomantic-ui-css/components/item.min.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/System/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/View/style.css","webpack://airdcpp-webui/./src/routes/Settings/style.css","webpack://airdcpp-webui/./node_modules/fomantic-ui-css/components/item.min.css?538d","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/style.css?1643","webpack://airdcpp-webui/./src/routes/Settings/routes/System/style.css?7e6a","webpack://airdcpp-webui/./src/actions/ui/ExtensionActions.ts","webpack://airdcpp-webui/./src/actions/ui/ShareActions.ts","webpack://airdcpp-webui/./src/actions/ui/SystemActions.ts","webpack://airdcpp-webui/./src/components/InstallPrompt.tsx","webpack://airdcpp-webui/./src/components/semantic/Grid.tsx","webpack://airdcpp-webui/./src/constants/ExtensionConstants.ts","webpack://airdcpp-webui/./src/constants/FavoriteDirectoryConstants.ts","webpack://airdcpp-webui/./src/constants/ShareProfileConstants.ts","webpack://airdcpp-webui/./src/decorators/ShareProfileDecorator.tsx","webpack://airdcpp-webui/./src/decorators/StatisticsDecorator.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/LocalSettingForm.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/MenuItems.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/RemoteSettingForm.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingsSideMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingsTopMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingSection.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SaveButton.tsx","webpack://airdcpp-webui/./src/routes/Settings/decorators/SaveDecorator.tsx","webpack://airdcpp-webui/./src/routes/Settings/decorators/SettingsMenuDecorator.tsx","webpack://airdcpp-webui/./src/routes/Settings/style.css?ebc5","webpack://airdcpp-webui/./src/routes/Settings/components/Settings.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/ApplicationPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/HubStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/ShareStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/TransferStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/index.js","webpack://airdcpp-webui/./src/constants/ConnectivityConstants.ts","webpack://airdcpp-webui/./src/actions/ui/ConnectivityActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/style.css?efda","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/DetectPanel.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/DetectionPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/EncryptionPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/IPv4Page.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/IPv6Page.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/PortsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/ProtocolPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/ProxiesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/DownloadOptionsPage.tsx","webpack://airdcpp-webui/./src/actions/ui/FavoriteDirectoryActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/FavoriteDirectoryDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/FavoriteDirectoryTable.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/LocationsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/PrioritiesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchMatchingPage.tsx","webpack://airdcpp-webui/./src/actions/ui/SearchTypeActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchTypeDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchTypesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SkippingOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/EngineStatusMessage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionEnginesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/NpmPackageLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsBrowsePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/LocalExtension.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsManagePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/ExtensionActionButtons.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/Extension.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/ExtensionIcon.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/AwayPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/IgnorePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/style.css?1785","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/MiscPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/UserPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/index.js","webpack://airdcpp-webui/./src/actions/ui/ShareExcludeActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/ExcludePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/HashDatabaseLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/HashingPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/RefreshOptionsPage.tsx","webpack://airdcpp-webui/./src/actions/ui/ShareProfileActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/ShareProfilesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/SharingOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/AutoValuePanel.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/DownloadLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/LimiterPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/SpeedPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/UploadLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/UserLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/AdvancedServerSettingsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LogSection.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LogSectionGroup.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LoggingPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/ServerSettingsPage.tsx","webpack://airdcpp-webui/./src/constants/WebUserConstants.ts","webpack://airdcpp-webui/./src/actions/ui/WebUserActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/users/WebUserDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/users/PermissionSelector.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/WebUsersPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/AppearancePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/EventPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/HistoryPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/MiscellaneousPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/style.css?0d4b","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/NotificationPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/index.js","webpack://airdcpp-webui/./src/services/HttpService.ts"],"sourcesContent":["/**\n * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.\n * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`.\n * @param v1 - First version to compare\n * @param v2 - Second version to compare\n * @returns Numeric value compatible with the [Array.sort(fn) interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters).\n */\nexport const compareVersions = (v1, v2) => {\n // validate input and split into segments\n const n1 = validateAndParse(v1);\n const n2 = validateAndParse(v2);\n // pop off the patch\n const p1 = n1.pop();\n const p2 = n2.pop();\n // validate numbers\n const r = compareSegments(n1, n2);\n if (r !== 0)\n return r;\n // validate pre-release\n if (p1 && p2) {\n return compareSegments(p1.split('.'), p2.split('.'));\n }\n else if (p1 || p2) {\n return p1 ? -1 : 1;\n }\n return 0;\n};\n/**\n * Validate [semver](https://semver.org/) version strings.\n *\n * @param version Version number to validate\n * @returns `true` if the version number is a valid semver version number, `false` otherwise.\n *\n * @example\n * ```\n * validate('1.0.0-rc.1'); // return true\n * validate('1.0-rc.1'); // return false\n * validate('foo'); // return false\n * ```\n */\nexport const validate = (version) => typeof version === 'string' && /^[v\\d]/.test(version) && semver.test(version);\n/**\n * Compare [semver](https://semver.org/) version strings using the specified operator.\n *\n * @param v1 First version to compare\n * @param v2 Second version to compare\n * @param operator Allowed arithmetic operator to use\n * @returns `true` if the comparison between the firstVersion and the secondVersion satisfies the operator, `false` otherwise.\n *\n * @example\n * ```\n * compare('10.1.8', '10.0.4', '>'); // return true\n * compare('10.0.1', '10.0.1', '='); // return true\n * compare('10.1.1', '10.2.2', '<'); // return true\n * compare('10.1.1', '10.2.2', '<='); // return true\n * compare('10.1.1', '10.2.2', '>='); // return false\n * ```\n */\nexport const compare = (v1, v2, operator) => {\n // validate input operator\n assertValidOperator(operator);\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n const res = compareVersions(v1, v2);\n return operatorResMap[operator].includes(res);\n};\n/**\n * Match [npm semver](https://docs.npmjs.com/cli/v6/using-npm/semver) version range.\n *\n * @param version Version number to match\n * @param range Range pattern for version\n * @returns `true` if the version number is within the range, `false` otherwise.\n *\n * @example\n * ```\n * satisfies('1.1.0', '^1.0.0'); // return true\n * satisfies('1.1.0', '~1.0.0'); // return false\n * ```\n */\nexport const satisfies = (version, range) => {\n // if no range operator then \"=\"\n const m = range.match(/^([<>=~^]+)/);\n const op = m ? m[1] : '=';\n // if gt/lt/eq then operator compare\n if (op !== '^' && op !== '~')\n return compare(version, range, op);\n // else range of either \"~\" or \"^\" is assumed\n const [v1, v2, v3] = validateAndParse(version);\n const [r1, r2, r3] = validateAndParse(range);\n if (compareStrings(v1, r1) !== 0)\n return false;\n if (op === '^') {\n return compareSegments([v2, v3], [r2, r3]) >= 0;\n }\n if (compareStrings(v2, r2) !== 0)\n return false;\n return compareStrings(v3, r3) >= 0;\n};\nconst semver = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\nconst validateAndParse = (version) => {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n const match = version.match(semver);\n if (!match) {\n throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n }\n match.shift();\n return match;\n};\nconst isWildcard = (s) => s === '*' || s === 'x' || s === 'X';\nconst tryParse = (v) => {\n const n = parseInt(v, 10);\n return isNaN(n) ? v : n;\n};\nconst forceType = (a, b) => typeof a !== typeof b ? [String(a), String(b)] : [a, b];\nconst compareStrings = (a, b) => {\n if (isWildcard(a) || isWildcard(b))\n return 0;\n const [ap, bp] = forceType(tryParse(a), tryParse(b));\n if (ap > bp)\n return 1;\n if (ap < bp)\n return -1;\n return 0;\n};\nconst compareSegments = (a, b) => {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const r = compareStrings(a[i] || '0', b[i] || '0');\n if (r !== 0)\n return r;\n }\n return 0;\n};\nconst operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1],\n};\nconst allowedOperators = Object.keys(operatorResMap);\nconst assertValidOperator = (op) => {\n if (typeof op !== 'string') {\n throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new Error(`Invalid operator, expected one of ${allowedOperators.join('|')}`);\n }\n};\n//# sourceMappingURL=index.js.map","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/*!\\n * # Fomantic-UI 2.9.0 - Item\\n * http://github.com/fomantic/Fomantic-UI/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.items>.item{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease,-webkit-box-shadow .1s ease;z-index:''}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:'';-ms-flex-item-align:start;align-self:start}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;background:0 0;color:rgba(0,0,0,.87);margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;-ms-flex-item-align:start;align-self:start;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,system-ui,-apple-system,\\\"Segoe UI\\\",Roboto,Oxygen,Ubuntu,Cantarell,\\\"Helvetica Neue\\\",Arial,\\\"Noto Sans\\\",\\\"Liberation Sans\\\",sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\\\"left floated\\\"]{float:left}.ui.items>.item [class*=\\\"right floated\\\"]{float:right}.ui.items>.item .content img{-ms-flex-item-align:center;align-self:center;width:''}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:'';height:'';border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:auto;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:''}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0 0 0;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\\\"right floated\\\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767.98px){.ui.items:not(.unstackable)>.item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\\\"top aligned\\\"].content{-ms-flex-item-align:start;align-self:flex-start}.ui.items>.item>.image+[class*=\\\"middle aligned\\\"].content{-ms-flex-item-align:center;align-self:center}.ui.items>.item>.image+[class*=\\\"bottom aligned\\\"].content{-ms-flex-item-align:end;align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\\\"very relaxed\\\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\\\"very relaxed\\\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}.ui.mini.items>.item{font-size:.78571429em}.ui.tiny.items>.item{font-size:.85714286em}.ui.small.items>.item{font-size:.92857143em}.ui.large.items>.item{font-size:1.14285714em}.ui.big.items>.item{font-size:1.28571429em}.ui.huge.items>.item{font-size:1.42857143em}.ui.massive.items>.item{font-size:1.71428571em}@media only screen and (max-width:767.98px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}.ui.inverted.items>.item{background:0 0}.ui.inverted.items>.item>.content{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.items>.item .extra{background:0 0}.ui.inverted.items>.item>.content>.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>.description{color:rgba(255,255,255,.9)}.ui.inverted.items>.item .meta{color:rgba(255,255,255,.8)}.ui.inverted.items>.item>.content a:not(.ui){color:#57a4ef}.ui.inverted.items>.item>.content a:not(.ui):hover{color:#4183c4}.ui.inverted.items>.item>.content>a.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>a.header:hover{color:#fff}.ui.inverted.items>.item .meta>a:not(.ui){color:rgba(255,255,255,.7)}.ui.inverted.items>.item .meta>a:not(.ui):hover{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content .favorite.icon:hover{color:#ffc63d}.ui.inverted.items>.item>.content .active.favorite.icon{color:#ffec56}.ui.inverted.items>.item>.content .like.icon:hover{color:#ff5a63}.ui.inverted.items>.item>.content .active.like.icon{color:#ff5a63}.ui.inverted.items>.item .extra{color:rgba(255,255,255,.7)}.ui.inverted.items a.item:hover .content .header,.ui.inverted.link.items>.item:hover .content .header{color:#fff}.ui.inverted.divided.items>.item{border-top:1px solid rgba(255,255,255,.1)}.ui.inverted.divided.items>.item:first-child{border-top:none}\", \"\",{\"version\":3,\"sources\":[\"webpack://./node_modules/fomantic-ui-css/components/item.min.css\"],\"names\":[],\"mappings\":\"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\",\"sourcesContent\":[\"/*!\\n * # Fomantic-UI 2.9.0 - Item\\n * http://github.com/fomantic/Fomantic-UI/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.items>.item{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease,-webkit-box-shadow .1s ease;z-index:''}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:'';-ms-flex-item-align:start;align-self:start}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;background:0 0;color:rgba(0,0,0,.87);margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;-ms-flex-item-align:start;align-self:start;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,system-ui,-apple-system,\\\"Segoe UI\\\",Roboto,Oxygen,Ubuntu,Cantarell,\\\"Helvetica Neue\\\",Arial,\\\"Noto Sans\\\",\\\"Liberation Sans\\\",sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\\\"left floated\\\"]{float:left}.ui.items>.item [class*=\\\"right floated\\\"]{float:right}.ui.items>.item .content img{-ms-flex-item-align:center;align-self:center;width:''}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:'';height:'';border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:auto;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:''}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0 0 0;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\\\"right floated\\\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767.98px){.ui.items:not(.unstackable)>.item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\\\"top aligned\\\"].content{-ms-flex-item-align:start;align-self:flex-start}.ui.items>.item>.image+[class*=\\\"middle aligned\\\"].content{-ms-flex-item-align:center;align-self:center}.ui.items>.item>.image+[class*=\\\"bottom aligned\\\"].content{-ms-flex-item-align:end;align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\\\"very relaxed\\\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\\\"very relaxed\\\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}.ui.mini.items>.item{font-size:.78571429em}.ui.tiny.items>.item{font-size:.85714286em}.ui.small.items>.item{font-size:.92857143em}.ui.large.items>.item{font-size:1.14285714em}.ui.big.items>.item{font-size:1.28571429em}.ui.huge.items>.item{font-size:1.42857143em}.ui.massive.items>.item{font-size:1.71428571em}@media only screen and (max-width:767.98px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}.ui.inverted.items>.item{background:0 0}.ui.inverted.items>.item>.content{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.items>.item .extra{background:0 0}.ui.inverted.items>.item>.content>.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>.description{color:rgba(255,255,255,.9)}.ui.inverted.items>.item .meta{color:rgba(255,255,255,.8)}.ui.inverted.items>.item>.content a:not(.ui){color:#57a4ef}.ui.inverted.items>.item>.content a:not(.ui):hover{color:#4183c4}.ui.inverted.items>.item>.content>a.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>a.header:hover{color:#fff}.ui.inverted.items>.item .meta>a:not(.ui){color:rgba(255,255,255,.7)}.ui.inverted.items>.item .meta>a:not(.ui):hover{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content .favorite.icon:hover{color:#ffc63d}.ui.inverted.items>.item>.content .active.favorite.icon{color:#ffec56}.ui.inverted.items>.item>.content .like.icon:hover{color:#ff5a63}.ui.inverted.items>.item>.content .active.like.icon{color:#ff5a63}.ui.inverted.items>.item .extra{color:rgba(255,255,255,.7)}.ui.inverted.items a.item:hover .content .header,.ui.inverted.link.items>.item:hover .content .header{color:#fff}.ui.inverted.divided.items>.item{border-top:1px solid rgba(255,255,255,.1)}.ui.inverted.divided.items>.item:first-child{border-top:none}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .detect-panel {\\n margin-top: 30px;\\n}\\n\\n.settings-layout .detect-panel .header.column > div {\\n overflow: hidden;\\n line-height: inherit !important;\\n}\\n\\n.settings-layout .detect-panel .header.column {\\n max-width: 200px;\\n}\\n\\n.settings-layout .detect-panel .detect-button {\\n margin-top: 20px;\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Connectivity/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;EAChB,+BAA+B;AACjC;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .detect-panel {\\n margin-top: 30px;\\n}\\n\\n.settings-layout .detect-panel .header.column > div {\\n overflow: hidden;\\n line-height: inherit !important;\\n}\\n\\n.settings-layout .detect-panel .header.column {\\n max-width: 200px;\\n}\\n\\n.settings-layout .detect-panel .detect-button {\\n margin-top: 20px;\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .profile.miscellaneous .field-nmdc_encoding li {\\r\\n margin-bottom: 5px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Profile/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,kBAAkB;AACpB\",\"sourcesContent\":[\".settings-layout .profile.miscellaneous .field-nmdc_encoding li {\\r\\n margin-bottom: 5px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .hash-database.grid {\\r\\n padding: 10px 0px 15px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .hash-database.grid .row {\\r\\n padding: 5px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .sharing.excludes .add.button {\\r\\n margin-top: 20px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Sharing/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,0BAA0B;AAC5B;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .hash-database.grid {\\r\\n padding: 10px 0px 15px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .hash-database.grid .row {\\r\\n padding: 5px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .sharing.excludes .add.button {\\r\\n margin-top: 20px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".web-user.modal .ui.checkbox {\\r\\n width: 100%;\\r\\n margin-top: 5px;\\r\\n}\\r\\n\\r\\n.web-user.modal .ui.checkbox.admin {\\r\\n margin-bottom: 10px;\\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .log-section.active {\\r\\n background-color: whitesmoke;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .sections {\\r\\n margin-top: 25px !important;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/System/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,WAAW;EACX,eAAe;AACjB;;AAEA;EACE,mBAAmB;EACnB,iBAAiB;AACnB;;AAEA;EACE,4BAA4B;AAC9B;;AAEA;EACE,2BAA2B;AAC7B\",\"sourcesContent\":[\".web-user.modal .ui.checkbox {\\r\\n width: 100%;\\r\\n margin-top: 5px;\\r\\n}\\r\\n\\r\\n.web-user.modal .ui.checkbox.admin {\\r\\n margin-bottom: 10px;\\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .log-section.active {\\r\\n background-color: whitesmoke;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .sections {\\r\\n margin-top: 25px !important;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .view.notifications .field-notify_events_info {\\r\\n margin-top: 25px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/View/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .view.notifications .field-notify_events_info {\\r\\n margin-top: 25px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout {\\r\\n padding-bottom: 30px;\\r\\n max-height: 100% !important;\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n}\\r\\n\\r\\n.settings-layout .menu-column .menu {\\r\\n max-width: 100%;\\r\\n}\\r\\n\\r\\n.settings-layout .layout.header {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form {\\r\\n margin-top: 30px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form:first-child {\\r\\n margin-top: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout h3 {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout h4 {\\r\\n margin-top: 15px;\\r\\n}\\r\\n\\r\\n.settings-layout > div,\\r\\n.settings-layout .mobile .section-content {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n overflow-y: auto;\\r\\n margin-bottom: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .main.grid {\\r\\n overflow-y: auto;\\r\\n padding: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content {\\r\\n padding-bottom: 5px;\\r\\n /* For possible scrollbar */\\r\\n padding-right: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about {\\r\\n margin-top: 10px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about .options {\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .full .section-content {\\r\\n height: 100%;\\r\\n padding-bottom: 2px;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > .ui.dropdown,\\r\\n.settings-layout .top-menu > .ui.dropdown > .caption {\\r\\n display: flex;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > i {\\r\\n margin: 0px 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .full .top-menu i {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .save.button {\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .options {\\r\\n min-height: 80px;\\r\\n}\\r\\n\\r\\n.settings-layout .options > .ui.grid {\\r\\n margin: 0px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,oBAAoB;EACpB,2BAA2B;EAC3B,aAAa;EACb,sBAAsB;AACxB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;;EAEE,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,YAAY;AACd;;AAEA;EACE,mBAAmB;EACnB,2BAA2B;EAC3B,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,cAAc;AAChB;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,cAAc;AAChB;;AAEA;;EAEE,aAAa;AACf;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,mBAAmB;EACnB,cAAc;AAChB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,WAAW;AACb\",\"sourcesContent\":[\".settings-layout {\\r\\n padding-bottom: 30px;\\r\\n max-height: 100% !important;\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n}\\r\\n\\r\\n.settings-layout .menu-column .menu {\\r\\n max-width: 100%;\\r\\n}\\r\\n\\r\\n.settings-layout .layout.header {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form {\\r\\n margin-top: 30px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form:first-child {\\r\\n margin-top: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout h3 {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout h4 {\\r\\n margin-top: 15px;\\r\\n}\\r\\n\\r\\n.settings-layout > div,\\r\\n.settings-layout .mobile .section-content {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n overflow-y: auto;\\r\\n margin-bottom: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .main.grid {\\r\\n overflow-y: auto;\\r\\n padding: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content {\\r\\n padding-bottom: 5px;\\r\\n /* For possible scrollbar */\\r\\n padding-right: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about {\\r\\n margin-top: 10px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about .options {\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .full .section-content {\\r\\n height: 100%;\\r\\n padding-bottom: 2px;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > .ui.dropdown,\\r\\n.settings-layout .top-menu > .ui.dropdown > .caption {\\r\\n display: flex;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > i {\\r\\n margin: 0px 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .full .top-menu i {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .save.button {\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .options {\\r\\n min-height: 80px;\\r\\n}\\r\\n\\r\\n.settings-layout .options > .ui.grid {\\r\\n margin: 0px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\n import API from \"!../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../css-loader/dist/cjs.js!./item.min.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../css-loader/dist/cjs.js!./item.min.css\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","\r\nimport SocketService from 'services/SocketService';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport History from 'utils/History';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst isManaged = (extension: API.Extension) => extension.managed;\r\nconst isRunning = (extension: API.Extension) => extension.running;\r\nconst hasSettings = (extension: API.Extension) => extension.has_settings;\r\n\r\n\r\nconst handleConfigure: UI.ActionHandler<API.Extension> = ({ data: extension, location }) => {\r\n History.push(`${location.pathname}/extensions/${extension.id}`);\r\n};\r\n\r\nconst handleStart: UI.ActionHandler<API.Extension> = ({ data: extension }) => {\r\n return SocketService.post(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}/start`);\r\n};\r\n\r\nconst handleStop: UI.ActionHandler<API.Extension> = ({ data: extension }) => {\r\n return SocketService.post(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}/stop`);\r\n};\r\n\r\nconst downloadExtension = (url: string, installId?: string, shasum?: string) => {\r\n return SocketService.post(ExtensionConstants.DOWNLOAD_URL, {\r\n install_id: installId ? installId : url,\r\n url,\r\n shasum\r\n });\r\n};\r\n\r\nconst handleNpmAction: UI.ActionHandler<UI.NpmPackage> = async (\r\n { data: npmPackage, ...other }\r\n) => {\r\n const data = await fetchCorsSafeData(ExtensionConstants.NPM_PACKAGE_URL + npmPackage.name + '/latest', true);\r\n\r\n const { tarball, shasum } = data.dist;\r\n\r\n return downloadExtension(tarball, npmPackage.name, shasum);\r\n};\r\n\r\nconst handleInstallUrl: UI.ActionHandler<undefined> = (\r\n { data }, url: string\r\n) => {\r\n return downloadExtension(url);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.Extension> = (\r\n { data }\r\n) => {\r\n return SocketService.delete(ExtensionConstants.EXTENSIONS_URL + '/' + data.name);\r\n};\r\n\r\n\r\nconst ExtensionInstallActions: UI.ActionListType<undefined> = {\r\n installUrl: {\r\n displayName: 'Install from URL',\r\n icon: IconConstants.CREATE,\r\n access: API.AccessEnum.ADMIN,\r\n input: {\r\n approveCaption: 'Install',\r\n content: 'Enter download URL',\r\n inputProps: {\r\n placeholder: 'Enter URL',\r\n type: 'url',\r\n required: true,\r\n }\r\n },\r\n handler: handleInstallUrl\r\n },\r\n};\r\n\r\n\r\nconst ExtensionNpmActions: UI.ActionListType<UI.NpmPackage> = {\r\n installNpm: {\r\n displayName: 'Install',\r\n icon: IconConstants.CREATE,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleNpmAction,\r\n },\r\n updateNpm: {\r\n displayName: 'Update',\r\n icon: IconConstants.REFRESH_COLORED,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleNpmAction,\r\n },\r\n};\r\n\r\nconst ExtensionManageActions: UI.ActionListType<API.Extension> = {\r\n start: {\r\n displayName: 'Start',\r\n icon: IconConstants.PLAY,\r\n filter: ext => isManaged(ext) && !isRunning(ext),\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleStart,\r\n },\r\n stop: {\r\n displayName: 'Stop',\r\n icon: IconConstants.STOP,\r\n filter: ext => isManaged(ext) && isRunning(ext),\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleStop,\r\n },\r\n configure: {\r\n displayName: 'Configure',\r\n icon: IconConstants.EDIT,\r\n filter: hasSettings,\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n handler: handleConfigure,\r\n },\r\n divider: null,\r\n remove: {\r\n displayName: 'Uninstall',\r\n icon: IconConstants.REMOVE,\r\n filter: isManaged,\r\n access: API.AccessEnum.ADMIN,\r\n confirmation: {\r\n // eslint-disable-next-line max-len\r\n content: 'Are you sure that you want to remove the extension {{item.name}}? This will also remove possible extension-specific settings.',\r\n approveCaption: 'Remove extension',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n },\r\n};\r\n\r\n\r\nexport default {\r\n install: {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n actions: ExtensionInstallActions,\r\n },\r\n npm: {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n actions: ExtensionNpmActions,\r\n },\r\n manage: {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n actions: ExtensionManageActions,\r\n }\r\n};\r\n","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareConstants from 'constants/ShareConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleRefresh = () => {\r\n return SocketService.post(ShareConstants.REFRESH_URL);\r\n};\r\n\r\n\r\nconst ShareActions: UI.ActionListType<undefined> = {\r\n refresh: {\r\n displayName: 'Refresh all',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REFRESH_COLORED,\r\n handler: handleRefresh,\r\n },\r\n};\r\n\r\nexport default {\r\n moduleId: UI.Modules.SHARE,\r\n actions: ShareActions,\r\n};\r\n\r\n","import SystemConstants from 'constants/SystemConstants';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleRestartWeb = () => {\r\n return SocketService.post(SystemConstants.MODULE_URL + '/restart_web');\r\n};\r\n\r\nconst handleShutdown = () => {\r\n return SocketService.post(SystemConstants.MODULE_URL + '/shutdown');\r\n};\r\n\r\n\r\n\r\nconst SystemActions: UI.ActionListType<undefined> = {\r\n restartWeb: {\r\n displayName: 'Restart web server',\r\n access: API.AccessEnum.ADMIN,\r\n icon: IconConstants.REFRESH_COLORED,\r\n confirmation: {\r\n content: `When changing the binding options, it's recommended to restart the web server only \r\n when you are able to access the server for troubleshooting. If \\\r\n the web server won't come back online, you should start the application \r\n manually to see if there are any error messages. The configuration file is located in your \\\r\n user directory by default (inside .airdc++ directory) in case you need to edit it manually.`,\r\n approveCaption: 'Continue and restart',\r\n rejectCaption: `Don't restart`,\r\n },\r\n handler: handleRestartWeb\r\n },\r\n shutdown: {\r\n displayName: 'Shut down application',\r\n access: API.AccessEnum.ADMIN,\r\n icon: IconConstants.POWER,\r\n confirmation: {\r\n content: 'Are you sure that you wish to shut down the application?',\r\n approveCaption: 'Continue and shut down',\r\n rejectCaption: 'Cancel',\r\n },\r\n handler: handleShutdown\r\n },\r\n};\r\n\r\n\r\nexport default {\r\n moduleId: UI.Modules.COMMON,\r\n subId: 'system',\r\n actions: SystemActions,\r\n};\r\n","import { useContext } from 'react';\r\nimport * as React from 'react';\r\n\r\n//import ExternalLink from 'components/ExternalLink';\r\n//import LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport Button from 'components/semantic/Button';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport { useStore } from 'effects/StoreListenerEffect';\r\nimport LocalSettingStore from 'stores/LocalSettingStore';\r\nimport { InstallPromptContext } from 'context/InstallPromptContext';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate, toI18nKey } from 'utils/TranslationUtils';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\n\r\ninterface InstallPromptProps {\r\n alwaysShow?: boolean;\r\n}\r\n\r\nconst InstallPrompt: React.FC<InstallPromptProps> = ({ alwaysShow }) => {\r\n const localSettings = useStore<UI.FormValueMap>(LocalSettingStore);\r\n const prompt = useContext(InstallPromptContext);\r\n const { t } = useTranslation();\r\n if (!prompt) {\r\n return null;\r\n }\r\n\r\n if (!alwaysShow && !!localSettings[LocalSettings.NO_INSTALL_PROMPT]) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Message \r\n title={ translate('Install as local application', t, UI.Modules.COMMON) }\r\n description={ (\r\n <div className=\"install-prompt\">\r\n <p>\r\n { t(\r\n toI18nKey('pwaInstallDesc', UI.Modules.COMMON), \r\n 'This web application can be installed locally, providing a better user experience'\r\n ) }\r\n </p>\r\n <Button\r\n className=\"primary\"\r\n caption={ translate('Install', t, UI.Modules.COMMON) }\r\n onClick={ () => prompt!() }\r\n icon={ IconConstants.CREATE }\r\n />\r\n { !alwaysShow && (\r\n <Button\r\n caption={ translate(`Don't install`, t, UI.Modules.COMMON) }\r\n onClick={ () => LocalSettingStore.setValue(LocalSettings.NO_INSTALL_PROMPT, true) }\r\n />\r\n ) }\r\n </div>\r\n ) }\r\n />\r\n );\r\n};\r\n\r\nexport default InstallPrompt;","\r\nimport * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { toI18nKey } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nexport interface RowProps {\r\n title: React.ReactNode;\r\n text?: React.ReactNode;\r\n titleWidth?: string;\r\n className?: string;\r\n noText?: boolean;\r\n}\r\n\r\n\r\n\r\nconst formatText = (text: React.ReactNode) => {\r\n if (!!text) {\r\n return text;\r\n }\r\n \r\n return (\r\n <Trans \r\n i18nKey={ toI18nKey('na', UI.Modules.COMMON) }\r\n >\r\n N/A\r\n </Trans>\r\n );\r\n};\r\n\r\nexport const Row: React.FC<RowProps> = ({ title, text, className, titleWidth = 'four', noText }) => (\r\n <div className={ classNames('ui row', className) }>\r\n <div className={ classNames(noText ? 'sixteen' : titleWidth, 'wide column title') }>\r\n <div className=\"ui tiny header\" style={{ overflow: 'hidden' }}>\r\n { title }\r\n </div>\r\n </div>\r\n { !noText && (\r\n <div className=\"column value\">\r\n { formatText(text) }\r\n </div> \r\n ) }\r\n </div>\r\n);\r\n\r\nexport interface HeaderProps {\r\n title: React.ReactNode;\r\n}\r\n\r\nexport const Header: React.FC<HeaderProps> = ({ title }) => (\r\n <div className=\"ui row\">\r\n <div className=\"sixteen wide column\">\r\n <div className=\"ui blue section header\">\r\n { title }\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\r\n columns?: string;\r\n stackable?: boolean;\r\n}\r\n\r\nexport const Grid: React.FC<GridProps> = ({ className, children, columns, stackable, ...other }) => (\r\n <div \r\n className={ classNames(\r\n 'ui grid', \r\n //`${columns} column`, \r\n { [`${columns} column`]: !!columns },\r\n { stackable: stackable },\r\n className\r\n ) }\r\n { ...other }\r\n >\r\n { children }\r\n </div>\r\n);\r\n","const MODULE_URL = 'extensions';\r\n\r\nconst NPM_URL = 'https://registry.npmjs.org/';\r\n\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n EXTENSIONS_URL: MODULE_URL,\r\n DOWNLOAD_URL: MODULE_URL + '/download',\r\n\r\n ENGINES_URL: MODULE_URL + '/engines',\r\n ENGINES_STATUS_URL: MODULE_URL + '/engines/status',\r\n\r\n DEFAULT_ENGINE: 'node',\r\n\r\n STARTED: 'extension_started',\r\n STOPPED: 'extension_stopped',\r\n\r\n ADDED: 'extension_added',\r\n REMOVED: 'extension_removed',\r\n UPDATED: 'extension_updated',\r\n\r\n INSTALLATION_STARTED: 'extension_installation_started',\r\n INSTALLATION_SUCCEEDED: 'extension_installation_succeeded',\r\n INSTALLATION_FAILED: 'extension_installation_failed',\r\n\r\n NPM_PACKAGES_URL: NPM_URL + '-/v1/search?text=keywords:airdcpp-extensions-public&size=100',\r\n NPM_PACKAGE_URL: NPM_URL,\r\n NPM_HOMEPAGE_URL: 'https://www.npmjs.com/package/',\r\n}\r\n;\r\n","const MODULE_URL = 'favorite_directories';\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n\r\n GROUPED_DIRECTORIES_URL: MODULE_URL + '/grouped_paths',\r\n DIRECTORIES_URL: MODULE_URL,\r\n\r\n DIRECTORIES_UPDATED: 'favorite_directories_updated',\r\n}\r\n;\r\n","const MODULE_URL = 'share_profiles';\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n PROFILES_URL: MODULE_URL,\r\n\r\n PROFILE_ADDED: 'share_profile_added',\r\n PROFILE_UPDATED: 'share_profile_updated',\r\n PROFILE_REMOVED: 'share_profile_removed',\r\n\r\n HIDDEN_PROFILE_ID: 1\r\n}\r\n;\r\n","import * as React from 'react';\r\nimport { merge } from 'lodash';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\n\r\nimport DataProviderDecorator, { \r\n DataProviderDecoratorChildProps, DataProviderDecoratorSettings, DataConverter \r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\ninterface ShareProfileDecoratorDataProps {\r\n profiles: API.ShareProfile[];\r\n}\r\n\r\nexport const profileToEnumValue = (profile: API.ShareProfile) => {\r\n return {\r\n id: profile.id,\r\n name: profile.str,\r\n };\r\n};\r\n\r\nexport type ShareProfileDecoratorChildProps = DataProviderDecoratorChildProps & ShareProfileDecoratorDataProps;\r\n\r\nconst ShareProfileDecorator = function <PropsT extends object>(\r\n Component: React.ComponentType<PropsT & ShareProfileDecoratorChildProps>, \r\n listHidden: boolean, \r\n dataProviderDecoratorSettings?: DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>,\r\n addSize = true\r\n) {\r\n const convertProfile = (profile: API.ShareProfile, t: UI.TranslateF): API.ShareProfile => {\r\n let str = profile.str;\r\n if (addSize && profile.id !== ShareProfileConstants.HIDDEN_PROFILE_ID) {\r\n str += ` (${formatSize(profile.size, t)})`;\r\n }\r\n\r\n return {\r\n ...profile,\r\n str,\r\n };\r\n };\r\n\r\n const convertProfiles: DataConverter<PropsT> = (data: API.ShareProfile[], { t }) => {\r\n const profiles = data\r\n .filter(p => listHidden || p.id !== ShareProfileConstants.HIDDEN_PROFILE_ID)\r\n .map(p => convertProfile(p, t));\r\n\r\n return profiles;\r\n };\r\n\r\n return DataProviderDecorator<PropsT, ShareProfileDecoratorDataProps>(\r\n Component, \r\n merge(dataProviderDecoratorSettings, {\r\n urls: {\r\n profiles: ShareProfileConstants.PROFILES_URL,\r\n },\r\n dataConverters: {\r\n profiles: convertProfiles,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ShareProfileConstants.MODULE_URL, ShareProfileConstants.PROFILE_ADDED, () => refetchData());\r\n addSocketListener(ShareProfileConstants.MODULE_URL, ShareProfileConstants.PROFILE_UPDATED, () => refetchData());\r\n addSocketListener(ShareProfileConstants.MODULE_URL, ShareProfileConstants.PROFILE_REMOVED, () => refetchData());\r\n },\r\n } as DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>)\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator;\r\n","import * as React from 'react';\r\n\r\nimport SocketService from 'services/SocketService';\r\nimport Message from 'components/semantic/Message';\r\nimport { ErrorResponse } from 'airdcpp-apisocket';\r\n\r\nimport { Translation } from 'react-i18next';\r\nimport { translate } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nexport interface StatisticsDecoratorProps<DataT> {\r\n stats?: DataT;\r\n}\r\n\r\nexport interface StatisticsDecoratorChildProps<DataT> {\r\n stats: DataT;\r\n}\r\n\r\n// Decorator for statistics pages that fetch the content from API\r\nconst StatisticsDecorator = function <DataT, PropsT>(\r\n Component: React.ComponentType<StatisticsDecoratorChildProps<DataT> & PropsT>, \r\n fetchUrl: string, \r\n unavailableMessage: ((t: UI.TranslateF, props: PropsT) => string) | null, \r\n fetchIntervalSeconds = 0\r\n) {\r\n class Decorator extends React.Component<StatisticsDecoratorProps<DataT> & PropsT> {\r\n state = {\r\n stats: null\r\n };\r\n\r\n fetchTimeout: number | undefined;\r\n\r\n componentDidMount() {\r\n this.fetchStats();\r\n }\r\n\r\n componentWillUnmount() {\r\n window.clearTimeout(this.fetchTimeout);\r\n }\r\n\r\n fetchStats = () => {\r\n SocketService.get(fetchUrl)\r\n .then(this.onStatsReceived)\r\n .catch((error: ErrorResponse) => console.error('Failed to fetch stats', error.message));\r\n\r\n if (fetchIntervalSeconds > 0) {\r\n this.fetchTimeout = window.setTimeout(this.fetchStats, fetchIntervalSeconds * 1000);\r\n }\r\n }\r\n\r\n onStatsReceived = (data: object) => {\r\n this.setState({ \r\n stats: data \r\n });\r\n }\r\n\r\n render() {\r\n const { stats } = this.state;\r\n if (stats === null) {\r\n return null;\r\n }\r\n\r\n if (this.props.stats) {\r\n Object.assign(stats, this.props.stats);\r\n }\r\n\r\n if (stats === undefined) {\r\n return (\r\n <Translation>\r\n { t => (\r\n <Message\r\n title={ translate('Statistics not available', t, UI.Modules.COMMON) }\r\n description={ !unavailableMessage ? undefined : unavailableMessage(t, this.props) }\r\n />\r\n ) }\r\n </Translation>\r\n );\r\n }\r\n\r\n return (\r\n <Component \r\n { ...this.props } \r\n stats={ stats }\r\n />\r\n );\r\n }\r\n }\r\n\r\n return Decorator;\r\n};\r\n\r\nexport default StatisticsDecorator;\r\n","//import PropTypes from 'prop-types';\r\nimport { Component } from 'react';\r\n\r\nimport LocalSettingStore from 'stores/LocalSettingStore';\r\n\r\nimport Form, { FormProps, FormSaveHandler, FormFieldChangeHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { withSaveContext, SaveContextProps } from '../decorators/SaveDecorator';\r\nimport { RouteComponentProps } from 'react-router';\r\nimport { translateForm } from 'utils/FormUtils';\r\n\r\n\r\nexport interface LocalSettingFormProps extends Omit<FormProps, 'onSave' | 'fieldDefinitions' | 'value'> {\r\n keys: string[];\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\n\r\ntype Props = LocalSettingFormProps & SaveContextProps & RouteComponentProps<UI.EmptyObject>;\r\n\r\nclass LocalSettingForm extends Component<Props> {\r\n /*static propTypes = {\r\n // Form items to list\r\n keys: PropTypes.array.isRequired,\r\n };*/\r\n\r\n definitions: UI.FormFieldDefinition[];\r\n state: {\r\n settings: API.SettingValueMap,\r\n };\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n\r\n this.definitions = translateForm(LocalSettingStore.getDefinitions(props.keys), props.moduleT);\r\n\r\n this.state = {\r\n settings: LocalSettingStore.getValues(),\r\n };\r\n }\r\n\r\n onSave: FormSaveHandler<UI.FormValueMap> = (changedSettingArray, allFields) => {\r\n LocalSettingStore.setValues(changedSettingArray);\r\n\r\n this.setState({\r\n settings: LocalSettingStore.getValues(),\r\n });\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n onFieldChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n const { saveContext, onFieldChanged } = this.props;\r\n saveContext.onFieldChanged(id, value, hasChanges);\r\n if (onFieldChanged) {\r\n return onFieldChanged(id, value, hasChanges);\r\n }\r\n }\r\n\r\n render() {\r\n const { settings } = this.state;\r\n const { saveContext, keys, ...other } = this.props;\r\n return (\r\n <div className=\"local setting-form\">\r\n <Form\r\n { ...other }\r\n ref={ f => saveContext.addFormRef(keys, f) }\r\n onSave={ this.onSave }\r\n fieldDefinitions={ this.definitions }\r\n sourceValue={ settings }\r\n onFieldChanged={ this.onFieldChanged }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default withSaveContext(LocalSettingForm);","import RouterMenuItemLink from 'components/semantic/RouterMenuItemLink';\r\nimport { Location } from 'history';\r\nimport LoginStore from 'stores/LoginStore';\r\nimport { Route, RouteComponentProps } from 'react-router-dom';\r\nimport { SectionType, RootSectionType } from '../decorators/SettingsMenuDecorator';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { getSubModuleT } from 'utils/TranslationUtils';\r\nimport { camelCase } from 'lodash';\r\n\r\n\r\nexport const sectionToUrl = (section: SectionType, parent?: SectionType) => {\r\n if (typeof parent === 'object') {\r\n return `/settings/${parent.url}/${section.url}`;\r\n }\r\n\r\n return `/settings/${section.url}`;\r\n};\r\n\r\nexport const translateSettingSectionTitle = (title: string, settingsT: UI.ModuleTranslator) => {\r\n return settingsT.translate(title, [ UI.SubNamespaces.NAVIGATION ]);\r\n};\r\n\r\nexport const menuItemToLinkComponent = (\r\n menuItemInfo: SectionType, \r\n parent: RootSectionType | undefined, \r\n settingsT: UI.ModuleTranslator,\r\n location: Location\r\n) => {\r\n if (menuItemInfo.debugOnly && process.env.NODE_ENV === 'production') {\r\n return null;\r\n }\r\n\r\n if (menuItemInfo.access && !LoginStore.hasAccess(menuItemInfo.access)) {\r\n return null;\r\n }\r\n\r\n let url = sectionToUrl(menuItemInfo, parent);\r\n\r\n // Browsing is smoother when the child page is loaded directly\r\n // Don't use the child URL for currently active parent so that the route is detected as active correctly\r\n if (menuItemInfo.menuItems && location.pathname.indexOf(url) !== 0) {\r\n url = sectionToUrl(menuItemInfo.menuItems[0], menuItemInfo);\r\n }\r\n\r\n return (\r\n <RouterMenuItemLink \r\n key={ url } \r\n url={ url } \r\n icon={ !!menuItemInfo.icon ? `green ${menuItemInfo.icon}` : null }\r\n >\r\n { translateSettingSectionTitle(menuItemInfo.title, settingsT) }\r\n </RouterMenuItemLink>\r\n );\r\n};\r\n\r\nexport const menuItemsToRouteComponentArray = (\r\n currentMenuItem: SectionType, \r\n menuItems: SectionType[] | undefined,\r\n settingsT: UI.ModuleTranslator,\r\n moduleT: UI.ModuleTranslator | undefined,\r\n parent: SectionType | undefined\r\n) => {\r\n if (!menuItems) {\r\n return null;\r\n }\r\n\r\n return menuItems.map(item => (\r\n <Route\r\n key={ item.url }\r\n path={ sectionToUrl(item, parent) }\r\n render={ (props: RouteComponentProps<UI.EmptyObject>) => (\r\n <item.component\r\n { ...props }\r\n menuItems={ currentMenuItem.menuItems }\r\n advancedMenuItems={ currentMenuItem.advancedMenuItems }\r\n parent={ currentMenuItem }\r\n parentMenuItems={ menuItems }\r\n settingsT={ settingsT }\r\n moduleT={ getSubModuleT(moduleT || settingsT, camelCase(item.url)) }\r\n />\r\n ) }\r\n />\r\n ));\r\n};\r\n\r\n\r\nexport const isItemActive = (\r\n item: SectionType, \r\n parent: RootSectionType | undefined, \r\n location: Location\r\n) => {\r\n return location.pathname.indexOf(sectionToUrl(item, parent)) === 0;\r\n};\r\n\r\nexport const findMenuItem = (\r\n menuItems: SectionType[] | undefined, \r\n parent: RootSectionType | undefined, \r\n location: Location\r\n) => {\r\n if (!menuItems) {\r\n return null;\r\n }\r\n\r\n return menuItems.find(item => isItemActive(item, parent, location));\r\n};\r\n","import { Component } from 'react';\r\nimport SettingConstants from 'constants/SettingConstants';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport Form, { FormProps, FormSaveHandler, FormFieldChangeHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { withSaveContext, SaveContextProps } from '../decorators/SaveDecorator';\r\nimport { RouteComponentProps } from 'react-router';\r\n\r\n\r\nexport interface RemoteSettingFormProps extends Omit<FormProps, 'onSave' | 'value' | 'fieldDefinitions'> {\r\n keys: string[];\r\n onSettingValuesReceived?: (settings: API.SettingValueMap) => void;\r\n valueMode?: API.SettingValueMode;\r\n}\r\n\r\ninterface RemoteSettingFormDataProps extends DataProviderDecoratorChildProps {\r\n settings: API.SettingValueMap;\r\n fieldDefinitions: UI.FormFieldDefinition[];\r\n}\r\n\r\n\r\ntype Props = RemoteSettingFormProps & RemoteSettingFormDataProps & SaveContextProps & RouteComponentProps;\r\n\r\nclass RemoteSettingForm extends Component<Props> {\r\n onSave: FormSaveHandler<UI.FormValueMap> = (changedValues) => {\r\n if (Object.keys(changedValues).length === 0) {\r\n return Promise.resolve();\r\n }\r\n\r\n return SocketService.post(SettingConstants.ITEMS_SET_URL, changedValues)\r\n .then(this.refetchValues);\r\n }\r\n\r\n refetchValues = () => {\r\n this.props.refetchData([ 'settings' ]);\r\n }\r\n\r\n onFieldChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n const { saveContext, onFieldChanged } = this.props;\r\n saveContext.onFieldChanged(id, value, hasChanges);\r\n if (onFieldChanged) {\r\n return onFieldChanged(id, value, hasChanges);\r\n }\r\n }\r\n\r\n render() {\r\n const { settings, fieldDefinitions, saveContext, keys, ...otherProps } = this.props;\r\n return (\r\n <div className=\"remote setting-form\">\r\n <Form\r\n { ...otherProps }\r\n ref={ f => saveContext.addFormRef(keys, f) }\r\n onSave={ this.onSave }\r\n fieldDefinitions={ fieldDefinitions }\r\n sourceValue={ settings }\r\n onFieldChanged={ this.onFieldChanged }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator<RemoteSettingFormProps, RemoteSettingFormDataProps>(\r\n withSaveContext(RemoteSettingForm), \r\n {\r\n urls: {\r\n fieldDefinitions: ({ keys }) => SocketService.post(SettingConstants.ITEMS_DEFINITIONS_URL, { keys }),\r\n settings: async ({ keys, onSettingValuesReceived, valueMode = API.SettingValueMode.CURRENT }) => {\r\n const settings: API.SettingValueMap = await SocketService.post(\r\n SettingConstants.ITEMS_GET_URL, { \r\n keys,\r\n value_mode: valueMode\r\n }\r\n );\r\n\r\n if (!!onSettingValuesReceived) {\r\n onSettingValuesReceived(settings);\r\n }\r\n\r\n return settings;\r\n },\r\n }\r\n }\r\n);","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { translateSettingSectionTitle } from './MenuItems';\r\nimport Icon from 'components/semantic/Icon';\r\n\r\n\r\ntype SideMenuProps = Pick<SettingSectionChildProps, 'menuItems' | 'advancedMenuItems' | 'settingsT'>;\r\n\r\nconst SideChildSectionMenu: React.FC<SideMenuProps> = ({ menuItems, advancedMenuItems, settingsT }) => {\r\n return (\r\n <div className=\"three wide column menu-column\">\r\n <div className=\"ui vertical secondary menu\">\r\n { menuItems }\r\n { !!advancedMenuItems && (\r\n <div>\r\n <div className=\"item header\">\r\n { settingsT.translate('Advanced') }\r\n </div>\r\n <div className=\"menu\">\r\n { advancedMenuItems }\r\n </div> \r\n </div>\r\n ) }\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\ntype TopMenuProps = Pick<SettingSectionChildProps, 'parentMenuItems'>;\r\n\r\nconst TopRootSectionMenu: React.FC<TopMenuProps> = ({ parentMenuItems }) => (\r\n <div className=\"ui secondary pointing menu settings top-menu\">\r\n { parentMenuItems }\r\n </div>\r\n);\r\n\r\n// eslint-disable-next-line max-len\r\ntype ContentProps = React.PropsWithChildren<Pick<SettingSectionChildProps, 'contentClassname' | 'currentMenuItem' | 'parent' | 'saveButton' | 'message' | 'settingsT'>>;\r\n\r\nconst Content: React.FC<ContentProps> = (\r\n { contentClassname, currentMenuItem, parent, saveButton, children, message, settingsT }\r\n) => (\r\n <div className={ classNames('thirteen wide column', contentClassname) }>\r\n <div className=\"ui segment\">\r\n <LayoutHeader\r\n title={ translateSettingSectionTitle(currentMenuItem.title, settingsT) }\r\n icon={ <Icon color=\"green\" icon={ parent!.icon }/> }\r\n rightComponent={ saveButton }\r\n />\r\n <div className=\"options\">\r\n { message }\r\n { children }\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nconst SideMenuLayout: React.FC<SettingSectionChildProps> = ({ children, ...other }) => (\r\n <div className=\"full\">\r\n <TopRootSectionMenu { ...other }/>\r\n <div \r\n id=\"setting-scroll-context\" \r\n className=\"ui segment grid main\"\r\n >\r\n <SideChildSectionMenu { ...other }/>\r\n <Content { ...other }>\r\n { children }\r\n </Content>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default SideMenuLayout;\r\n","import * as React from 'react';\r\n\r\nimport Dropdown from 'components/semantic/Dropdown';\r\nimport SectionedDropdown from 'components/semantic/SectionedDropdown';\r\nimport MenuSection from 'components/semantic/MenuSection';\r\nimport Icon from 'components/semantic/Icon';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { translateSettingSectionTitle } from './MenuItems';\r\n\r\n\r\n\r\n// eslint-disable-next-line max-len\r\ntype TopSectionSelectionMenuProps = Pick<SettingSectionChildProps, 'menuItems' | 'currentMenuItem' | 'parent' | 'advancedMenuItems' | 'parentMenuItems' | 'settingsT'>;\r\n\r\nconst TopSectionSelectionMenu: React.FC<TopSectionSelectionMenuProps> = (\r\n { menuItems, advancedMenuItems, currentMenuItem, parentMenuItems, parent, settingsT }\r\n) => (\r\n <div className=\"ui top-menu\">\r\n <Dropdown \r\n selection={ true }\r\n caption={ translateSettingSectionTitle(parent!.title, settingsT) }\r\n captionIcon={ `green ${parent!.icon}` }\r\n >\r\n { parentMenuItems }\r\n </Dropdown>\r\n\r\n <Icon \r\n icon=\"caret right\"\r\n size=\"large\"\r\n />\r\n\r\n <SectionedDropdown \r\n selection={ true }\r\n caption={ translateSettingSectionTitle(currentMenuItem.title, settingsT) }\r\n >\r\n <MenuSection>\r\n { menuItems }\r\n </MenuSection>\r\n <MenuSection caption={ settingsT.translate('Advanced') }>\r\n { advancedMenuItems }\r\n </MenuSection>\r\n </SectionedDropdown>\r\n </div>\r\n);\r\n\r\n\r\nconst TopMenuLayout: React.FC<SettingSectionChildProps> = (\r\n { saveButton, children, contentClassname, message, ...other }\r\n) => (\r\n <div className=\"mobile\">\r\n <TopSectionSelectionMenu { ...other }/>\r\n <div \r\n id=\"setting-scroll-context\" \r\n className={ contentClassname }\r\n >\r\n { !!saveButton && React.cloneElement(saveButton, { className: 'fluid' }) }\r\n <div className=\"options\">\r\n { message }\r\n { children }\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default TopMenuLayout;\r\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport SettingsMenuDecorator, { SettingsMenuDecoratorChildProps } from '../decorators/SettingsMenuDecorator';\r\nimport { useMobileLayout } from 'utils/BrowserUtils';\r\n\r\nimport SettingsSideMenuLayout from './SettingsSideMenuLayout';\r\nimport SettingsTopMenuLayout from './SettingsTopMenuLayout';\r\n\r\nimport SaveDecorator, { SaveDecoratorChildProps, SaveDecoratorProps } from '../decorators/SaveDecorator';\r\nimport { RouteComponentProps } from 'react-router';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { menuItemToLinkComponent } from './MenuItems';\r\n\r\n\r\nexport interface SettingSectionProps {\r\n\r\n}\r\n\r\ntype Props = SaveDecoratorChildProps & SettingsMenuDecoratorChildProps;\r\n\r\nexport type SettingSectionChildProps<RouteParams extends object = UI.EmptyObject> = \r\n SaveDecoratorChildProps & \r\n Pick<Props, 'parent' | 'currentMenuItem'> & \r\n RouteComponentProps<RouteParams> & \r\n React.PropsWithChildren<{\r\n contentClassname: string;\r\n parentMenuItems: React.ReactNode[];\r\n menuItems: React.ReactNode[];\r\n advancedMenuItems?: React.ReactNode[];\r\n settingsT: UI.ModuleTranslator;\r\n moduleT: UI.ModuleTranslator;\r\n }>;\r\n\r\n\r\n\r\nconst SettingSection: React.FC<Props> = (props) => {\r\n const Component = useMobileLayout() || window.innerWidth < 1000 ? SettingsTopMenuLayout : SettingsSideMenuLayout;\r\n\r\n const { moduleT, settingsT, parentMenuItems, menuItems, advancedMenuItems, location, ...childProps } = props;\r\n const { parent, currentMenuItem } = props;\r\n\r\n const contentClassname = classNames(\r\n 'section-content',\r\n `${parent!.url} ${currentMenuItem.url}`,\r\n );\r\n\r\n return (\r\n <Component \r\n { ...childProps }\r\n settingsT={ settingsT }\r\n moduleT={ moduleT! }\r\n location={ location }\r\n contentClassname={ contentClassname }\r\n parentMenuItems={ \r\n props.parentMenuItems!.map(item => menuItemToLinkComponent(item, undefined, settingsT, location)) \r\n }\r\n menuItems={ !props.menuItems ? [] : \r\n props.menuItems.map(item => menuItemToLinkComponent(item, parent, settingsT, location)) \r\n }\r\n advancedMenuItems={ !advancedMenuItems ? undefined : \r\n advancedMenuItems.map(item => menuItemToLinkComponent(item, parent, settingsT, location)) \r\n }\r\n />\r\n );\r\n};\r\n\r\nconst SettingSectionDecorated = SettingsMenuDecorator<SaveDecoratorProps>(\r\n SaveDecorator<SettingsMenuDecoratorChildProps>(SettingSection)\r\n);\r\n\r\nexport default SettingSectionDecorated;\r\n","import PropTypes from 'prop-types';\r\nimport { Component } from 'react';\r\nimport Button from 'components/semantic/Button';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport classNames from 'classnames';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nexport interface SaveButtonProps {\r\n saveHandler: () => Promise<void>;\r\n hasChanges: boolean;\r\n local?: boolean;\r\n className?: string;\r\n settingsT: UI.ModuleTranslator;\r\n}\r\n\r\nclass SaveButton extends Component<SaveButtonProps> {\r\n static propTypes = {\r\n /**\r\n * Message title\r\n */\r\n hasChanges: PropTypes.bool.isRequired,\r\n\r\n /**\r\n * Error details\r\n */\r\n saveHandler: PropTypes.func.isRequired,\r\n\r\n local: PropTypes.bool,\r\n };\r\n\r\n state = {\r\n saving: false\r\n };\r\n\r\n toggleSaveState = () => {\r\n this.setState({ saving: !this.state.saving });\r\n }\r\n\r\n onClick = () => {\r\n this.toggleSaveState();\r\n this.props.saveHandler()\r\n .then(this.toggleSaveState)\r\n .catch(this.toggleSaveState);\r\n }\r\n\r\n render() {\r\n const { local, hasChanges, className, settingsT } = this.props;\r\n\r\n const hasAccess: boolean = local || LoginStore.hasAccess(API.AccessEnum.SETTINGS_EDIT);\r\n\r\n let title;\r\n if (!hasAccess) {\r\n title = settingsT.translate('No save permission');\r\n } else {\r\n title = settingsT.translate(hasChanges ? 'Save changes' : 'No unsaved changes');\r\n }\r\n\r\n return (\r\n <Button \r\n className={ classNames('save', className) }\r\n caption={ title }\r\n icon={ (hasAccess && hasChanges ? 'green checkmark' : null) } \r\n loading={ this.state.saving } \r\n disabled={ !hasChanges || !hasAccess }\r\n onClick={ this.onClick }\r\n />\r\n );\r\n }\r\n}\r\n\r\nexport default SaveButton;","import * as React from 'react';\r\nimport { Prompt, RouteComponentProps } from 'react-router-dom';\r\nimport invariant from 'invariant';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport SaveButton, { SaveButtonProps } from '../components/SaveButton';\r\nimport NotificationActions from 'actions/NotificationActions';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport Form, { FormFieldChangeHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { ChildSectionType } from './SettingsMenuDecorator';\r\nimport { Location } from 'history';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nexport interface SaveDecoratorProps {\r\n currentMenuItem: ChildSectionType;\r\n settingsT: UI.ModuleTranslator;\r\n}\r\n\r\nexport interface SaveDecoratorChildProps {\r\n saveButton: React.ReactElement<SaveButtonProps> | false;\r\n message: React.ReactNode;\r\n}\r\n\r\ntype SaveableRef = Pick<Form, 'save'>;\r\n\r\n\r\nexport interface SaveDecoratorContext {\r\n onFieldChanged: FormFieldChangeHandler;\r\n addFormRef: (keys: string[], c: SaveableRef | null) => void;\r\n getFormRef: (keys: string[]) => SaveableRef;\r\n}\r\n\r\nexport const SaveDecoratorContext = React.createContext<SaveDecoratorContext | undefined>(undefined);\r\n\r\n\r\nexport interface SaveContextProps {\r\n saveContext: SaveDecoratorContext;\r\n}\r\n\r\nexport function withSaveContext<PropsT>(Component: React.ComponentType<PropsT & SaveContextProps>) {\r\n return function withSaveContext(props: PropsT) {\r\n return (\r\n <SaveDecoratorContext.Consumer>\r\n { context => <Component {...props} saveContext={ context! } /> }\r\n </SaveDecoratorContext.Consumer>\r\n );\r\n };\r\n}\r\n\r\nconst getFormId = (keys: string[]) => {\r\n return keys.join('_');\r\n}\r\n\r\nexport default function <PropsT extends object>(\r\n Component: React.ComponentType<SaveDecoratorChildProps & PropsT>\r\n) {\r\n type Props = SaveDecoratorProps & Pick<RouteComponentProps, 'location'> & PropsT;\r\n \r\n class SaveDecorator extends React.Component<React.PropsWithChildren<Props>> {\r\n static displayName = 'SaveDecorator';\r\n\r\n forms: { [key: string]: SaveableRef } = {};\r\n changedProperties = new Set<string>();\r\n\r\n componentDidUpdate(prevProps: SaveDecoratorProps) {\r\n if (prevProps.currentMenuItem.url !== this.props.currentMenuItem.url) {\r\n this.changedProperties.clear();\r\n }\r\n }\r\n\r\n onSettingsChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n if (hasChanges) {\r\n this.changedProperties.add(id);\r\n } else {\r\n this.changedProperties.delete(id);\r\n }\r\n\r\n this.forceUpdate();\r\n }\r\n\r\n onSettingsSaved = () => {\r\n const { translate } = this.props.settingsT;\r\n NotificationActions.success({ \r\n title: translate('Saving completed'),\r\n message: translate('Settings were saved successfully'),\r\n });\r\n\r\n this.forceUpdate();\r\n }\r\n\r\n handleSave = () => {\r\n invariant(Object.keys(this.forms).length > 0, 'No forms exist in SaveDecorator');\r\n const promises = Object.values(this.forms).map(c => c.save());\r\n this.changedProperties.clear();\r\n\r\n return Promise.all(promises)\r\n .then(this.onSettingsSaved);\r\n }\r\n\r\n hasChanges = () => {\r\n return this.changedProperties.size > 0;\r\n }\r\n\r\n promptSave = (nextLocation: Location) => {\r\n const { currentMenuItem, settingsT } = this.props;\r\n if (currentMenuItem.noSave) {\r\n return true;\r\n }\r\n\r\n // Closing/opening a modal?\r\n if (this.props.location.pathname.indexOf(nextLocation.pathname) !== -1 || \r\n nextLocation.pathname.indexOf(this.props.location.pathname) !== -1\r\n ) {\r\n return true;\r\n }\r\n\r\n const hasChanges = this.hasChanges() && LoginStore.hasAccess(API.AccessEnum.SETTINGS_EDIT);\r\n return !hasChanges ? true :\r\n settingsT.t('unsavedChangesPrompt', 'You have unsaved changes. Are you sure you want to leave?');\r\n }\r\n\r\n addFormRef = (keys: string[], c: SaveableRef | null) => {\r\n if (c) {\r\n invariant(\r\n c.hasOwnProperty('save'), \r\n 'Invalid setting form component supplied for SaveDecorator (save property missing)'\r\n );\r\n this.forms[getFormId(keys)] = c;\r\n } else {\r\n // Switching to another page \r\n // Single forms shouldn't be unmounted otherwise, but using identifiers would still be safer...\r\n this.forms = {};\r\n }\r\n }\r\n\r\n getFormRef = (keys: string[]) => {\r\n return this.forms[getFormId(keys)]\r\n }\r\n\r\n saveContext: SaveDecoratorContext = {\r\n onFieldChanged: this.onSettingsChanged,\r\n addFormRef: this.addFormRef,\r\n getFormRef: this.getFormRef,\r\n };\r\n\r\n render() {\r\n const { currentMenuItem, children, settingsT } = this.props;\r\n\r\n const message = currentMenuItem.local && (\r\n <Message \r\n description={ settingsT.t<string>(\r\n 'browserSpecificNote', \r\n 'Settings listed on this page are browser-specific'\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />\r\n );\r\n\r\n const saveButton = !currentMenuItem.noSave && (\r\n <SaveButton \r\n saveHandler={ this.handleSave } \r\n hasChanges={ this.hasChanges() }\r\n local={ currentMenuItem.local }\r\n settingsT={ settingsT }\r\n />\r\n );\r\n\r\n return (\r\n <Component \r\n { ...this.props }\r\n saveButton={ saveButton }\r\n message={ message }\r\n >\r\n <SaveDecoratorContext.Provider value={ this.saveContext }>\r\n <Prompt\r\n message={ this.promptSave }\r\n />\r\n { children }\r\n </SaveDecoratorContext.Provider>\r\n </Component>\r\n );\r\n }\r\n }\r\n\r\n return SaveDecorator;\r\n}\r\n","import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\nimport { \r\n Redirect,\r\n RouteComponentProps \r\n} from 'react-router-dom';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { \r\n menuItemsToRouteComponentArray, findMenuItem, sectionToUrl \r\n} from '../components/MenuItems';\r\n\r\n\r\nexport interface SectionType {\r\n url: string;\r\n access?: string;\r\n title: string;\r\n component: React.ComponentType<SettingsMenuDecoratorProps>;\r\n debugOnly?: boolean;\r\n icon?: string;\r\n menuItems?: ChildSectionType[] | RootSectionType[];\r\n advancedMenuItems?: ChildSectionType[];\r\n parentMenuItems?: RootSectionType[];\r\n noSave?: boolean;\r\n local?: boolean;\r\n}\r\n\r\nexport interface RootSectionType extends SectionType {\r\n\r\n}\r\n\r\nexport interface ChildSectionType extends SectionType {\r\n\r\n}\r\n\r\nexport interface SettingsMenuDecoratorProps \r\n extends RouteComponentProps<UI.EmptyObject>\r\n{\r\n parent?: RootSectionType;\r\n menuItems?: ChildSectionType[] | RootSectionType[];\r\n advancedMenuItems?: ChildSectionType[];\r\n parentMenuItems?: RootSectionType[];\r\n settingsT: UI.ModuleTranslator;\r\n moduleT?: UI.ModuleTranslator;\r\n}\r\n\r\nexport type SettingsMenuDecoratorChildProps = \r\n SettingsMenuDecoratorProps & \r\n React.PropsWithChildren<{\r\n currentMenuItem: SectionType;\r\n parent?: RootSectionType;\r\n }>;\r\n\r\nexport default function <PropsT>(Component: React.ComponentType<SettingsMenuDecoratorChildProps & PropsT>) {\r\n class SettingsMenuDecorator extends React.Component<SettingsMenuDecoratorProps & PropsT> {\r\n static propTypes = {\r\n parent: PropTypes.object,\r\n menuItems: PropTypes.array.isRequired,\r\n advancedMenuItems: PropTypes.array,\r\n location: PropTypes.object.isRequired,\r\n match: PropTypes.object.isRequired,\r\n };\r\n\r\n render() {\r\n const { location, match, parent, menuItems, advancedMenuItems, settingsT, moduleT } = this.props;\r\n if (location.pathname === match.url ||\r\n (parent && location.pathname === sectionToUrl(parent as SectionType))\r\n ) {\r\n if (!!menuItems && menuItems.length) {\r\n return <Redirect to={ sectionToUrl(menuItems[0], parent) }/>;\r\n }\r\n }\r\n\r\n const currentMenuItem = findMenuItem(menuItems, parent, location) || \r\n findMenuItem(advancedMenuItems, parent, location);\r\n\r\n if (!currentMenuItem) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Component \r\n { ...this.props } \r\n currentMenuItem={ currentMenuItem }\r\n >\r\n { menuItemsToRouteComponentArray(currentMenuItem, menuItems, settingsT, moduleT, parent) }\r\n { menuItemsToRouteComponentArray(currentMenuItem, advancedMenuItems, settingsT, moduleT, parent) }\r\n </Component>\r\n );\r\n }\r\n }\r\n\r\n return SettingsMenuDecorator;\r\n}\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","\r\nimport { Component } from 'react';\r\nimport { RouteComponentProps } from 'react-router';\r\nimport { withTranslation, WithTranslation } from 'react-i18next';\r\n\r\nimport SettingsMenuDecorator from '../decorators/SettingsMenuDecorator';\r\nimport { getModuleT } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport '../style.css';\r\n\r\n\r\nconst menu = [\r\n require('../routes/Profile'),\r\n require('../routes/Connectivity'),\r\n require('../routes/SpeedLimits'),\r\n require('../routes/Downloads'),\r\n require('../routes/Sharing'),\r\n require('../routes/View'),\r\n require('../routes/About'),\r\n require('../routes/Extensions'),\r\n require('../routes/System'),\r\n];\r\n\r\nconst MainLayout = SettingsMenuDecorator(({ children }) => {\r\n return (\r\n <div className=\"ui segment settings-layout\">\r\n { children }\r\n </div>\r\n );\r\n});\r\n\r\nexport interface SettingsProps extends RouteComponentProps, WithTranslation {\r\n\r\n}\r\n\r\n// Only to pass menu items to the decorated component\r\nclass Settings extends Component<SettingsProps> {\r\n settingsT = getModuleT(this.props.t, UI.Modules.SETTINGS);\r\n render() {\r\n return (\r\n <MainLayout \r\n { ...this.props } \r\n menuItems={ menu }\r\n settingsT={ this.settingsT }\r\n />\r\n );\r\n }\r\n}\r\n\r\nexport default withTranslation()(Settings);","\r\nimport * as React from 'react';\r\n\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\nimport SystemConstants from 'constants/SystemConstants';\r\nimport { formatDateTime, formatRelativeTime } from 'utils/ValueFormat';\r\nimport InstallPrompt from 'components/InstallPrompt';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport ExternalLink from 'components/ExternalLink';\r\n\r\n\r\ninterface ApplicationPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\nconst ApplicationPage: React.FC<ApplicationPageProps & StatisticsDecoratorChildProps<any>> = ({ stats, moduleT }) => {\r\n const { translate } = moduleT;\r\n const systemInfo = LoginStore.systemInfo;\r\n\r\n const buildDate = formatDateTime(UI_BUILD_DATE / 1000);\r\n return (\r\n <>\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row title={ translate('Application version') } text={ systemInfo.client_version }/>\r\n <Row title={ translate('Web UI version') } text={ UI_VERSION }/>\r\n <Row title={ translate('Web UI build date') } text={ buildDate }/>\r\n <Row title={ translate('API version') } text={ systemInfo.api_version }/>\r\n <Row title={ translate('API feature level') } text={ systemInfo.api_feature_level }/>\r\n <Row title={ translate('Started') } text={ formatRelativeTime(systemInfo.client_started) }/>\r\n <Row title={ translate('Active sessions') } text={ stats.active_sessions }/>\r\n <Row title={ translate('Server threads') } text={ stats.server_threads }/>\r\n\r\n <Header title={ translate('Resources') }/>\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.HOME_PAGE_URL }>\r\n { translate('Home page') }\r\n </ExternalLink>\r\n }\r\n noText={ true }\r\n />\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.HELP_URL }>\r\n { translate('Documentation') }\r\n </ExternalLink> \r\n }\r\n noText={ true }\r\n />\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.ISSUE_TRACKER_URL }>\r\n { translate('Feature request/bug tracker') }\r\n </ExternalLink> \r\n }\r\n noText={ true }\r\n />\r\n <Header title={ translate('Third-party credits') }/>\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.DBIP_URL }>\r\n IP Geolocation by DB-IP\r\n </ExternalLink> \r\n }\r\n noText={ true }\r\n />\r\n </Grid>\r\n <InstallPrompt alwaysShow={ true }/>\r\n </>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(ApplicationPage, SystemConstants.STATS_URL, null, 5);\r\n","\r\nimport * as React from 'react';\r\n\r\nimport { formatAverage, formatConnection, formatPercentage, formatSize } from 'utils/ValueFormat';\r\n\r\nimport HubConstants from 'constants/HubConstants';\r\n\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\n\r\nimport { Grid, Row, Header } from 'components/semantic/Grid';\r\n\r\n//import * as UI from 'types/ui';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface HubStatisticsPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\ninterface ClientInfo { \r\n name: string; \r\n count: number; \r\n}\r\n\r\nconst formatClientRow = (uniqueUsers: number, client: ClientInfo) => {\r\n return (\r\n <Row\r\n key={ client.name }\r\n title={ client.name }\r\n text={ `${client.count} (${formatPercentage(client.count, uniqueUsers)})` }\r\n />\r\n );\r\n};\r\n\r\nconst HubStatisticsPage: React.FC<HubStatisticsPageProps & StatisticsDecoratorChildProps<any>> = (\r\n { stats, moduleT }\r\n) => {\r\n const { translate } = moduleT;\r\n return (\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row \r\n title={ translate('Total users') } \r\n text={ stats.total_users }\r\n />\r\n <Row \r\n title={ translate('Unique users') } \r\n text={ `${stats.unique_users} (${formatPercentage(stats.unique_users, stats.total_users)})` }\r\n />\r\n <Row \r\n title={ translate('Active users') } \r\n text={ `${stats.active_users} (${formatPercentage(stats.active_users, stats.unique_users)})` }\r\n />\r\n <Row \r\n title={ translate('Total share') } \r\n text={ formatSize(stats.total_share, moduleT.plainT) }\r\n />\r\n <Row \r\n title={ translate('Average share per user') }\r\n text={ formatSize(\r\n (formatAverage(stats.total_share, stats.unique_users) as any as number),\r\n moduleT.plainT\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Average ADC download speed') } \r\n text={ formatConnection(stats.adc_down_per_user, moduleT.plainT) }\r\n />\r\n <Row \r\n title={ translate('Average ADC upload speed') } \r\n text={ formatConnection(stats.adc_up_per_user, moduleT.plainT) }\r\n />\r\n <Header title={ translate('Clients') }/>\r\n { stats.clients.map((c: ClientInfo) => formatClientRow(stats.unique_users, c)) }\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(\r\n HubStatisticsPage, \r\n HubConstants.STATS_URL, \r\n (t, props) => props.moduleT.translate('No hubs online'), \r\n 10\r\n);","\r\nimport * as React from 'react';\r\n\r\nimport { formatAverage, formatPercentage, formatSeconds, formatSize } from 'utils/ValueFormat';\r\n\r\nimport ShareConstants from 'constants/ShareConstants';\r\n\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\n\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\n//import * as UI from 'types/ui';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ntype ShareStatisticsPageProps = SettingSectionChildProps\r\n\r\nconst ShareStatisticsPage: React.FC<ShareStatisticsPageProps & StatisticsDecoratorChildProps<any>> = (\r\n { stats, moduleT }\r\n) => {\r\n const { translate, t } = moduleT;\r\n return (\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row \r\n title={ translate('Total share size') } \r\n text={ formatSize(stats.total_size, moduleT.plainT) }\r\n />\r\n <Row \r\n title={ translate('Total files') } \r\n // eslint-disable-next-line max-len\r\n text={ t(\r\n 'totalFilesValue',\r\n {\r\n defaultValue: '{{totalCount}} ({{uniqueCount}} unique)',\r\n replace: {\r\n totalCount: stats.total_file_count,\r\n uniqueCount: formatPercentage(stats.unique_file_count, stats.total_file_count)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Total directories') } \r\n text={ stats.total_directory_count }\r\n />\r\n <Row \r\n title={ translate('Average file age') } \r\n text={ formatSeconds(stats.average_file_age) }\r\n />\r\n <Row \r\n title={ translate('Average files per directory') } \r\n text={ formatAverage(stats.total_file_count, stats.total_directory_count) }\r\n />\r\n\r\n <Header title={ translate('Incoming searches') }/>\r\n <Row \r\n title={ translate('Total searches') } \r\n text={ t(\r\n 'searchesTotalValue',\r\n {\r\n defaultValue: '{{totalCount}} ({{perSecondCount}} per second)',\r\n replace: {\r\n totalCount: stats.total_searches,\r\n perSecondCount: stats.total_searches_per_second.toFixed(1)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('TTH searches') } \r\n text={ formatPercentage(stats.tth_searches, stats.total_searches) }\r\n />\r\n <Row \r\n title={ translate('Text searches') } \r\n // eslint-disable-next-line max-len\r\n text={ t(\r\n 'searchesPerSecondValue',\r\n {\r\n defaultValue: '{{totalCount}} ({{matchedCount}} matched per second)',\r\n replace: {\r\n totalCount: stats.recursive_searches,\r\n matchedCount: stats.unfiltered_recursive_searches_per_second.toFixed(2)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Filtered text searches') } \r\n text={ t(\r\n 'searchesFilteredValue',\r\n {\r\n defaultValue: '{{filteredPercentage}} ({{resultPercentage}} of the matched ones returned results)',\r\n replace: {\r\n filteredPercentage: formatPercentage(stats.filtered_searches, stats.recursive_searches),\r\n resultPercentage: formatPercentage(\r\n stats.recursive_searches_responded, \r\n stats.recursive_searches - stats.filtered_searches\r\n )\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Average text search tokens (non-filtered)') }\r\n // eslint-disable-next-line max-len\r\n text={ t(\r\n 'searchesAverageTokensValue',\r\n {\r\n defaultValue: '{{tokenCount}} ({{tokenLength}} bytes per token)',\r\n replace: {\r\n tokenCount: stats.average_search_token_count.toFixed(1),\r\n tokenLength: stats.average_search_token_length.toFixed(1)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Average matching time per text search') } \r\n text={ t(\r\n 'searchesAverageMatchTimeValue',\r\n {\r\n defaultValue: '{{matchTime}} ms',\r\n replace: {\r\n matchTime: stats.average_match_ms\r\n }\r\n }\r\n ) }\r\n />\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(\r\n ShareStatisticsPage, \r\n ShareConstants.STATS_URL, \r\n (t, props) => props.moduleT.translate('No files shared'), \r\n 60\r\n);","\r\nimport * as React from 'react';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\nimport TransferConstants from 'constants/TransferConstants';\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface TransferStatisticsPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\nconst TransferStatisticsPage: React.FC<TransferStatisticsPageProps & StatisticsDecoratorChildProps<any>> = (\r\n { stats, moduleT }\r\n) => {\r\n const { translate, plainT } = moduleT;\r\n\r\n const totalUp = stats.session_uploaded + stats.start_total_uploaded;\r\n const totalDown = stats.session_downloaded + stats.start_total_downloaded;\r\n\r\n return (\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row \r\n title={ translate('Total downloaded') } \r\n text={ formatSize(totalDown, plainT) }\r\n />\r\n <Row \r\n title={ translate('Total uploaded') } \r\n text={ formatSize(totalUp, plainT) }\r\n />\r\n <Header title={ translate('Session') }/>\r\n <Row \r\n title={ translate('Session downloaded') } \r\n text={ formatSize(stats.session_downloaded, plainT) }\r\n />\r\n <Row \r\n title={ translate('Session uploaded') } \r\n text={ formatSize(stats.session_uploaded, plainT) }\r\n />\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(TransferStatisticsPage, TransferConstants.TRANSFERRED_BYTES_URL, null, 5);\r\n","const AccessConstants = require('constants/AccessConstants').default;\r\n\r\nmodule.exports = {\r\n url: 'about',\r\n title: 'About',\r\n icon: 'info',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Application', \r\n noSave: true,\r\n url: 'application',\r\n component: require('./components/ApplicationPage').default, \r\n }, { \r\n title: 'Transfer statistics', \r\n noSave: true,\r\n url: 'transfers',\r\n access: AccessConstants.TRANSFERS,\r\n component: require('./components/TransferStatisticsPage').default, \r\n }, { \r\n title: 'Share statistics', \r\n noSave: true,\r\n url: 'share',\r\n component: require('./components/ShareStatisticsPage').default, \r\n }, { \r\n title: 'Hub statistics', \r\n noSave: true,\r\n url: 'hubs',\r\n access: AccessConstants.HUBS_VIEW,\r\n component: require('./components/HubStatisticsPage').default, \r\n },\r\n ],\r\n};","const MODULE_URL = 'connectivity';\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n DETECT_URL: MODULE_URL + '/detect',\r\n STATUS_URL: MODULE_URL + '/status',\r\n\r\n CONNECTIVITY_MESSAGE: 'connectivity_detection_message',\r\n CONNECTIVITY_STARTED: 'connectivity_detection_started',\r\n CONNECTIVITY_FINISHED: 'connectivity_detection_finished',\r\n}\r\n;\r\n","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport AccessConstants from 'constants/AccessConstants';\r\nimport ConnectivityConstants from 'constants/ConnectivityConstants';\r\n\r\nimport * as UI from 'types/ui';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst ConnectivityActions: UI.ActionListType<undefined> = {\r\n detect: {\r\n displayName: 'Detect now',\r\n access: AccessConstants.SETTINGS_EDIT,\r\n icon: IconConstants.CONFIGURE,\r\n handler: () => {\r\n return SocketService.post(ConnectivityConstants.DETECT_URL);\r\n }\r\n }\r\n};\r\n\r\nexport default {\r\n moduleId: UI.Modules.SETTINGS,\r\n actions: ConnectivityActions,\r\n};\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ConnectivityActions from 'actions/ui/ConnectivityActions';\r\nimport ConnectivityConstants from 'constants/ConnectivityConstants';\r\n\r\nimport { Row, Grid } from 'components/semantic/Grid';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst formatStatus = (\r\n protocolStatus: API.ConnectivityProtocolStatus, \r\n running: boolean,\r\n moduleT: UI.ModuleTranslator\r\n) => {\r\n const { translate, t } = moduleT;\r\n if (running) {\r\n return translate('Detecting...');\r\n }\r\n\r\n const auto = protocolStatus.auto_detect;\r\n const ret = t(auto ? 'autoDetected' : 'manualConfiguration', {\r\n defaultValue: auto ? '{{status}} (auto detected)' : '{{status}} (manual configuration)',\r\n replace: {\r\n status: protocolStatus.text\r\n }\r\n });\r\n\r\n return ret;\r\n};\r\n\r\n\r\ninterface DetectPanelProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DetectPanelDataProps extends DataProviderDecoratorChildProps {\r\n status: API.ConnectivityStatus;\r\n runningV4: boolean;\r\n runningV6: boolean;\r\n}\r\n\r\nconst DetectPanel: React.FC<DetectPanelProps & DetectPanelDataProps> = (\r\n { status, runningV4, runningV6, moduleT }\r\n) => (\r\n <div className=\"ui segment detect-panel\">\r\n <h3 className=\"header\">\r\n { moduleT.translate('Current auto detection status') }\r\n </h3>\r\n <Grid columns=\"two\">\r\n <Row \r\n title={ moduleT.translate('IPv4 connectivity') } \r\n text={ formatStatus(status.status_v4, runningV4, moduleT) }\r\n />\r\n <Row \r\n title={ moduleT.translate('IPv6 connectivity') } \r\n text={ formatStatus(status.status_v6, runningV6, moduleT) }\r\n />\r\n </Grid>\r\n <ActionButton \r\n className=\"detect-button\"\r\n actions={ ConnectivityActions }\r\n actionId=\"detect\"\r\n disabled={ !status.status_v4.auto_detect && !status.status_v6.auto_detect }\r\n loading={ runningV6 || runningV4 } \r\n />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<DetectPanelProps, DetectPanelDataProps>(DetectPanel, {\r\n urls: {\r\n status: ConnectivityConstants.STATUS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData, mergeData }) => {\r\n const setDetectState = (v6: boolean, running: boolean) => {\r\n const value = 'running' + (v6 ? 'V6' : 'V4');\r\n mergeData({ \r\n [value]: running,\r\n });\r\n };\r\n\r\n addSocketListener<API.ConnectivityDetectionStarted>(\r\n ConnectivityConstants.MODULE_URL, \r\n ConnectivityConstants.CONNECTIVITY_STARTED, \r\n data => {\r\n setDetectState(data.v6, true);\r\n }\r\n );\r\n\r\n addSocketListener<API.ConnectivityDetectionFinished>(\r\n ConnectivityConstants.MODULE_URL, \r\n ConnectivityConstants.CONNECTIVITY_FINISHED, \r\n data => {\r\n setDetectState(data.v6, false);\r\n refetchData();\r\n }\r\n );\r\n },\r\n});","import * as React from 'react';\r\n\r\nimport DetectPanel from 'routes/Settings/routes/Connectivity/components/DetectPanel';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport { Trans } from 'react-i18next';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst DetectionPage: React.FC<SettingSectionChildProps> = props => {\r\n const { toI18nKey } = props.moduleT;\r\n return (\r\n <div>\r\n <DetectPanel\r\n moduleT={ props.moduleT }\r\n />\r\n <Message \r\n description={\r\n <Trans i18nKey={ toI18nKey('connectivityDetectionNote') }>\r\n In case of file transfer connectivity issues, please confirm that your TCP ports are really open by \r\n using <ExternalLink url={ LinkConstants.PORTCHECK_URL }>an online port checker</ExternalLink>. Note that \r\n validity of the UDP port (search) can't be checked online.\r\n\r\n For more information about different connectivity modes, please visit \r\n { ' ' }\r\n <ExternalLink url={ LinkConstants.CONNECTIVITY_HELP_URL }>DC++'s connectivity FAQ</ExternalLink>.\r\n </Trans>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DetectionPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'always_ccpm',\r\n 'tls_mode',\r\n 'tls_allow_untrusted_clients',\r\n 'tls_allow_untrusted_hubs',\r\n];\r\n\r\nconst Encryption: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default Encryption;","import * as React from 'react';\r\nimport ProtocolPage from 'routes/Settings/routes/Connectivity/components/ProtocolPage';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'connection_auto_v4',\r\n 'connection_bind_v4',\r\n 'connection_mode_v4',\r\n 'connection_ip_v4',\r\n 'connection_update_ip_v4',\r\n 'connection_ip_override_v4',\r\n];\r\n\r\nconst IPv4: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <ProtocolPage\r\n { ...props }\r\n keys={ Entry }\r\n protocol=\"v4\"\r\n />\r\n </div>\r\n);\r\n\r\nexport default IPv4;","import * as React from 'react';\r\nimport ProtocolPage from 'routes/Settings/routes/Connectivity/components/ProtocolPage';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'connection_auto_v6',\r\n 'connection_bind_v6',\r\n 'connection_mode_v6',\r\n 'connection_ip_v6',\r\n 'connection_update_ip_v6',\r\n 'connection_ip_override_v6',\r\n];\r\n\r\nconst IPv6: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <ProtocolPage\r\n { ...props }\r\n keys={ Entry }\r\n protocol=\"v6\"\r\n />\r\n </div>\r\n);\r\n\r\nexport default IPv6;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst Entry = [\r\n 'tcp_port',\r\n 'udp_port',\r\n 'tls_port',\r\n 'preferred_port_mapper',\r\n];\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const translate = (text: string) => {\r\n return moduleT.t(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined),\r\n text\r\n );\r\n };\r\n\r\n if (id === 'tcp_port') {\r\n fieldOptions.help = translate('TCP port is used for unencrypted transfers');\r\n } else if (id === 'tls_port') {\r\n fieldOptions.help = translate('TLS port (TCP) is used for encrypted transfers');\r\n } else if (id === 'udp_port') {\r\n fieldOptions.help = translate('UDP port is used for searching');\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\nconst PortsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <Message \r\n description={ props.moduleT.t<string>(\r\n 'portsAutoValuesNote', \r\n 'Port numbers listed on this page can be overridden by port mappers (if enabled)'\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ FieldOptionGetter(props.moduleT) }\r\n valueMode={ API.SettingValueMode.FORCE_MANUAL }\r\n />\r\n </div>\r\n);\r\n\r\nexport default PortsPage;","import { Component } from 'react';\r\nimport RemoteSettingForm, { RemoteSettingFormProps } from 'routes/Settings/components/RemoteSettingForm';\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport { IncomingConnectionModeEnum } from 'constants/SettingConstants';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nimport * as API from 'types/api';\r\n\r\n\r\ninterface ProtocolPageProps extends SettingSectionChildProps, RemoteSettingFormProps {\r\n protocol: string;\r\n}\r\n\r\nclass ProtocolPage extends Component<ProtocolPageProps> {\r\n state = {\r\n autoDetectEnabled: false,\r\n };\r\n\r\n convertValue = (key: string) => {\r\n return `${key}_${this.props.protocol}`;\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const protocolEnabled = formValue[this.convertValue('connection_mode')] !== \r\n IncomingConnectionModeEnum.INCOMING_DISABLED;\r\n const autoDetect = formValue[this.convertValue('connection_auto')];\r\n\r\n if ((!protocolEnabled || autoDetect) && (\r\n id.indexOf('connection_ip') === 0 || id.indexOf('connection_bind') === 0 ||\r\n id.indexOf('connection_update_ip') === 0 || id.indexOf('connection_ip_override') === 0)\r\n ) {\r\n fieldOptions.disabled = true;\r\n }\r\n\r\n if (autoDetect && id.indexOf('connection_mode') === 0 && protocolEnabled) {\r\n fieldOptions.disabled = true;\r\n }\r\n\r\n if (!protocolEnabled && id.indexOf('connection_auto') === 0) {\r\n fieldOptions.disabled = true;\r\n }\r\n }\r\n\r\n onSettingValuesReceived = (settings: API.SettingValueMap) => {\r\n this.setState({\r\n autoDetectEnabled: settings[this.convertValue('connection_auto')]\r\n });\r\n }\r\n\r\n render() {\r\n return (\r\n <div>\r\n { this.state.autoDetectEnabled && (\r\n <Message\r\n description={ this.props.moduleT.t<string>(\r\n 'protocolAutoValuesNote', \r\n 'Connectivity auto detection is currently enabled; setting values listed on this page are not being used'\r\n ) }\r\n icon={ IconConstants.INFO }\r\n /> \r\n ) }\r\n <RemoteSettingForm\r\n { ...this.props }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSettingValuesReceived={ this.onSettingValuesReceived }\r\n valueMode={ API.SettingValueMode.FORCE_MANUAL }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default ProtocolPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport { OutgoingConnectionModeEnum } from 'constants/SettingConstants';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\n\r\n\r\nconst Entry = [\r\n 'outgoing_mode',\r\n 'socks_server',\r\n 'socks_port',\r\n 'socks_resolve',\r\n 'socks_user',\r\n 'socks_password',\r\n 'http_proxy',\r\n];\r\n\r\nconst onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const socksEnabled = formValue.outgoing_mode === OutgoingConnectionModeEnum.OUTGOING_SOCKS;\r\n\r\n if (!socksEnabled && id.indexOf('socks_') === 0) {\r\n fieldOptions.disabled = true;\r\n }\r\n};\r\n\r\nconst Encryption: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ onFieldSetting }\r\n />\r\n </div>\r\n);\r\n\r\nexport default Encryption;","module.exports = {\r\n url: 'connectivity',\r\n title: 'Connectivity',\r\n icon: 'signal',\r\n component: require('../../components/SettingSection').default,\r\n\r\n menuItems: [\r\n { \r\n title: 'Auto detection', \r\n url: 'detection', \r\n noSave: true,\r\n component: require('./components/DetectionPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'IPv4 connectivity (manual)', \r\n url: 'v4',\r\n component: require('./components/IPv4Page').default,\r\n }, {\r\n title: 'IPv6 connectivity (manual)', \r\n url: 'v6',\r\n component: require('./components/IPv6Page').default,\r\n }, { \r\n title: 'Ports (manual)', \r\n url: 'ports',\r\n component: require('./components/PortsPage').default,\r\n }, { \r\n title: 'Proxies', \r\n url: 'proxies',\r\n component: require('./components/ProxiesPage').default,\r\n }, { \r\n title: 'Encryption', \r\n url: 'encryption',\r\n component: require('./components/EncryptionPage').default,\r\n },\r\n ],\r\n};","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'allow_slow_overlap',\r\n 'finished_remove_exit',\r\n 'use_partial_sharing',\r\n];\r\n\r\n\r\nconst SegmentsEntry = [\r\n 'segmented_downloads',\r\n 'min_segment_size',\r\n];\r\n\r\nconst BufferEntry = [\r\n 'socket_read_buffer',\r\n 'socket_write_buffer',\r\n 'buffer_size',\r\n];\r\n\r\nconst CompressionEntry = [\r\n 'compress_transfers',\r\n 'max_compression',\r\n];\r\n\r\nconst DownloadOptionsPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ SegmentsEntry }\r\n title={ translate('Segments') }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ CompressionEntry }\r\n title={ translate('Compression') }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ BufferEntry }\r\n title={ translate('Buffers') }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DownloadOptionsPage;","\r\nimport SocketService from 'services/SocketService';\r\nimport History from 'utils/History';\r\n\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<undefined> = ({ location }) => {\r\n History.push(`${location.pathname}/directories`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.FavoriteDirectoryEntry> = ({ data: directory, location }) => {\r\n History.push(`${location.pathname}/directories/${directory.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.FavoriteDirectoryEntry> = (\r\n { data: directory }\r\n) => {\r\n return SocketService.delete(`${FavoriteDirectoryConstants.DIRECTORIES_URL}/${directory.id}`);\r\n};\r\n\r\nconst FavoriteDirectoryCreateActions: UI.ActionListType<undefined> = {\r\n create: { \r\n displayName: 'Add directory',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n },\r\n};\r\n\r\nconst FavoriteDirectoryEditActions: UI.ActionListType<API.FavoriteDirectoryEntry> = {\r\n edit: {\r\n displayName: 'Edit directory',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n },\r\n remove: {\r\n displayName: 'Remove directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the favorite directory {{item.name}}?',\r\n approveCaption: 'Remove directory',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove\r\n },\r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'favoriteDirectory',\r\n actions: FavoriteDirectoryCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'favoriteDirectory',\r\n actions: FavoriteDirectoryEditActions,\r\n }\r\n};\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport { getLastDirectory } from 'utils/FileUtils';\r\n\r\nimport Form, { FormFieldChangeHandler, FormSaveHandler, FormFieldSettingHandler } from 'components/form';\r\nimport { AutoSuggestField } from 'components/form/fields';\r\n\r\nimport FilesystemConstants from 'constants/FilesystemConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { translateForm } from 'utils/FormUtils';\r\n\r\n\r\nconst Entry: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'path',\r\n title: 'Path',\r\n type: API.SettingTypeEnum.DIRECTORY_PATH,\r\n },\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n];\r\n\r\nexport interface FavoriteDirectoryDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.FavoriteDirectoryEntryBase, UI.FormValueMap {\r\n\r\n}\r\n\r\nexport interface DataProps extends DataProviderDecoratorChildProps {\r\n virtualNames: string[];\r\n directoryEntry?: API.FavoriteDirectoryEntryBase;\r\n}\r\n\r\ninterface RouteProps {\r\n directoryId: string; \r\n}\r\n\r\ntype Props = FavoriteDirectoryDialogProps & DataProps & ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass FavoriteDirectoryDialog extends Component<Props> {\r\n static displayName = 'FavoriteDirectoryDialog';\r\n\r\n form: Form<Entry>;\r\n fieldDefinitions = translateForm(Entry, this.props.moduleT);\r\n\r\n isNew = () => {\r\n return !this.props.directoryEntry;\r\n }\r\n\r\n onFieldChanged: FormFieldChangeHandler<Entry> = (id, value, hasChanges) => {\r\n if (id.indexOf('path') !== -1) {\r\n return Promise.resolve({\r\n name: !!value.path ? getLastDirectory(value.path) : undefined \r\n });\r\n }\r\n\r\n return null;\r\n }\r\n\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (this.isNew()) {\r\n return SocketService.post(FavoriteDirectoryConstants.DIRECTORIES_URL, changedFields);\r\n }\r\n\r\n return SocketService.patch(\r\n `${FavoriteDirectoryConstants.DIRECTORIES_URL}/${this.props.directoryEntry!.id}`, \r\n changedFields\r\n );\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'path') {\r\n fieldOptions.disabled = !this.isNew();\r\n fieldOptions.config = Object.assign(fieldOptions.config || {}, {\r\n historyId: FilesystemConstants.LOCATION_DOWNLOAD,\r\n });\r\n } else if (id === 'name') {\r\n fieldOptions.factory = t.form.Textbox;\r\n fieldOptions.template = AutoSuggestField;\r\n fieldOptions.config = {\r\n suggestionGetter: () => this.props.virtualNames,\r\n };\r\n }\r\n }\r\n\r\n render() {\r\n const { moduleT, directoryEntry } = this.props;\r\n const title = moduleT.translate(this.isNew() ? 'Add favorite directory' : 'Edit favorite directory');\r\n return (\r\n <Modal \r\n className=\"favorite-directory\" \r\n title={ title } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.FOLDER } \r\n { ...this.props }\r\n >\r\n <Form<Entry>\r\n ref={ c => this.form = c! }\r\n fieldDefinitions={ this.fieldDefinitions }\r\n onFieldChanged={ this.onFieldChanged }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSave={ this.onSave }\r\n sourceValue={ directoryEntry as Entry }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<FavoriteDirectoryDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(FavoriteDirectoryDialog, {\r\n urls: {\r\n virtualNames: FavoriteDirectoryConstants.GROUPED_DIRECTORIES_URL,\r\n directoryEntry: ({ match }, socket) => {\r\n if (!match.params.directoryId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${FavoriteDirectoryConstants.DIRECTORIES_URL}/${match.params.directoryId}`);\r\n },\r\n },\r\n dataConverters: {\r\n virtualNames: (data: API.GroupedPath[]) => data.map(item => item.name, []),\r\n },\r\n }),\r\n 'directories/:directoryId([0-9A-Z]{39})?'\r\n);","import * as React from 'react';\r\n\r\nimport FavoriteDirectoryActions from 'actions/ui/FavoriteDirectoryActions';\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/menu';\r\nimport FavoriteDirectoryDialog from 'routes/Settings/routes/Downloads/components/FavoriteDirectoryDialog';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst Row: React.FC<{ directory: API.FavoriteDirectoryEntry; }> = ({ directory }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ directory.name }</strong> } \r\n actions={ FavoriteDirectoryActions.edit }\r\n itemData={ directory }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"path\">\r\n { directory.path }\r\n </td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (directory: API.FavoriteDirectoryEntry) => {\r\n return (\r\n <Row \r\n key={ directory.path } \r\n directory={ directory }\r\n />\r\n );\r\n};\r\n\r\ninterface FavoriteDirectoryPageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface FavoriteDirectoryPageDataProps extends DataProviderDecoratorChildProps {\r\n directories: API.FavoriteDirectoryEntry[];\r\n}\r\n\r\nconst FavoriteDirectoryPage: React.FC<FavoriteDirectoryPageProps & FavoriteDirectoryPageDataProps> = (\r\n { directories, moduleT }\r\n) => (\r\n <div id=\"directory-table\">\r\n <ActionButton\r\n actions={ FavoriteDirectoryActions.create }\r\n actionId=\"create\"\r\n />\r\n\r\n { directories.length === 0 ? null : (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ moduleT.translate('Name') }</th>\r\n <th>{ moduleT.translate('Path') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { directories.map(getRow) }\r\n </tbody>\r\n </table>\r\n ) }\r\n <FavoriteDirectoryDialog\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<FavoriteDirectoryPageProps, FavoriteDirectoryPageDataProps>(\r\n FavoriteDirectoryPage, {\r\n urls: {\r\n directories: FavoriteDirectoryConstants.DIRECTORIES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n FavoriteDirectoryConstants.MODULE_URL, \r\n FavoriteDirectoryConstants.DIRECTORIES_UPDATED, \r\n () => refetchData()\r\n );\r\n },\r\n }\r\n);","import * as React from 'react';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport FavoriteDirectoryTable from 'routes/Settings/routes/Downloads/components/FavoriteDirectoryTable';\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst Entry = [\r\n 'download_directory',\r\n];\r\n\r\nconst LocationsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n\r\n <Message \r\n description={ (\r\n <ExternalLink url={ LinkConstants.VARIABLE_HELP_URL }>\r\n { props.moduleT.translate('Available path variables') }\r\n </ExternalLink>\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />\r\n\r\n <div className=\"ui segment setting-form\">\r\n <LayoutHeader \r\n title={ props.moduleT.translate('Favorite download directories') }\r\n icon={ IconConstants.FOLDER }\r\n size=\"normal\"\r\n />\r\n <FavoriteDirectoryTable\r\n moduleT={ props.moduleT }\r\n />\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default LocationsPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'prio_highest_size',\r\n 'prio_high_size',\r\n 'prio_normal_size',\r\n 'prio_auto_default',\r\n];\r\n\r\nconst HighPrioEntry = [\r\n 'prio_high_files_to_highest',\r\n 'prio_high_files',\r\n 'prio_high_files_regex',\r\n];\r\n\r\nconst PrioritiesPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n title={ translate('File priorities') }\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n title={ translate('High priority files') }\r\n { ...props }\r\n keys={ HighPrioEntry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default PrioritiesPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'auto_add_sources',\r\n 'alt_search_auto',\r\n 'alt_search_max_sources',\r\n 'max_sources_match_queue',\r\n 'allow_match_full_list',\r\n];\r\n\r\nconst SearchMatchingPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default SearchMatchingPage;","\r\nimport SocketService from 'services/SocketService';\r\nimport History from 'utils/History';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport SearchConstants from 'constants/SearchConstants';\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<API.SearchType> = ({ location }) => {\r\n History.push(`${location.pathname}/types`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.SearchType> = ({ data: type, location }) => {\r\n History.push(`${location.pathname}/types/${type.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.SearchType> = (\r\n { data: type }\r\n) => {\r\n return SocketService.delete(`${SearchConstants.SEARCH_TYPES_URL}/${type.id}`);\r\n};\r\n\r\nconst SearchTypeCreateActions: UI.ActionListType<API.SearchType> = {\r\n create: { \r\n displayName: 'Add type',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n },\r\n};\r\n\r\nconst SearchTypeEditActions: UI.ActionListType<API.SearchType> = {\r\n edit: {\r\n displayName: 'Edit type',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n },\r\n remove: {\r\n displayName: 'Remove type',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the search type {{item.name}}?',\r\n approveCaption: 'Remove type',\r\n rejectCaption: `Don't remove`,\r\n },\r\n filter: type => !type.default_type,\r\n handler: handleRemove\r\n },\r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'searchType',\r\n actions: SearchTypeCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'searchType',\r\n actions: SearchTypeEditActions,\r\n }\r\n};\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport Form, { FormFieldSettingHandler, FormSaveHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translateForm } from 'utils/FormUtils';\r\nimport SearchConstants from 'constants/SearchConstants';\r\n\r\n\r\nconst Entry: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'extensions',\r\n title: 'File extensions',\r\n type: API.SettingTypeEnum.LIST,\r\n item_type: API.SettingTypeEnum.STRING\r\n },\r\n];\r\n\r\nexport interface SearchTypeDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.SearchType, UI.FormValueMap {\r\n\r\n}\r\n\r\nexport interface DataProps extends DataProviderDecoratorChildProps {\r\n searchTypeEntry?: API.SearchType;\r\n}\r\n\r\ninterface RouteProps {\r\n searchTypeId: string; \r\n}\r\n\r\ntype Props = SearchTypeDialogProps & DataProps & ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass SearchTypeDialog extends Component<Props> {\r\n static displayName = 'SearchTypeDialog';\r\n\r\n form: Form<Entry>;\r\n fieldDefinitions = translateForm(Entry, this.props.moduleT);\r\n\r\n isNew = () => {\r\n return !this.props.searchTypeEntry;\r\n }\r\n\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (this.isNew()) {\r\n return SocketService.post(SearchConstants.SEARCH_TYPES_URL, changedFields);\r\n }\r\n\r\n return SocketService.patch(\r\n `${SearchConstants.SEARCH_TYPES_URL}/${this.props.searchTypeEntry!.id}`, \r\n changedFields\r\n );\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'name') {\r\n const { searchTypeEntry } = this.props;\r\n fieldOptions.disabled = !!searchTypeEntry && searchTypeEntry.default_type;\r\n }\r\n }\r\n\r\n render() {\r\n const { moduleT, searchTypeEntry } = this.props;\r\n const title = moduleT.translate(this.isNew() ? 'Add search type' : 'Edit search type');\r\n return (\r\n <Modal \r\n className=\"search-type\" \r\n title={ title } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.FOLDER } \r\n { ...this.props }\r\n >\r\n <Form<Entry>\r\n ref={ c => this.form = c! }\r\n fieldDefinitions={ this.fieldDefinitions }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSave={ this.onSave }\r\n sourceValue={ searchTypeEntry as Entry }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<SearchTypeDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(SearchTypeDialog, {\r\n urls: {\r\n searchTypeEntry: ({ match }, socket) => {\r\n if (!match.params.searchTypeId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${SearchConstants.SEARCH_TYPES_URL}/${match.params.searchTypeId}`);\r\n },\r\n }\r\n }),\r\n 'types/:searchTypeId?'\r\n);","import * as React from 'react';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/menu';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport SearchTypeActions from 'actions/ui/SearchTypeActions';\r\nimport SearchConstants from 'constants/SearchConstants';\r\nimport SearchTypeDialog from './SearchTypeDialog';\r\nimport { formatBoolean } from 'utils/ValueFormat';\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst Row: React.FC<{ type: API.SearchType; moduleT: UI.ModuleTranslator; }> = ({ type, moduleT }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ type.str }</strong> } \r\n actions={ SearchTypeActions.edit }\r\n itemData={ type }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"extensions\">\r\n { type.extensions.join(', ') }\r\n </td>\r\n <td className=\"default\">\r\n { formatBoolean(type.default_type, moduleT.plainT) }\r\n </td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (type: API.SearchType, moduleT: UI.ModuleTranslator) => {\r\n return (\r\n <Row \r\n key={ type.id } \r\n type={ type }\r\n moduleT={ moduleT }\r\n />\r\n );\r\n};\r\n\r\ninterface SearchTypesPageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n searchTypes: API.SearchType[];\r\n}\r\n\r\ntype Props = SearchTypesPageProps & DataProps;\r\n\r\nconst SearchTypesPage: React.FC<Props> = (\r\n { searchTypes, moduleT }\r\n) => (\r\n <div id=\"directory-table\">\r\n <ActionButton\r\n actions={ SearchTypeActions.create }\r\n actionId=\"create\"\r\n />\r\n\r\n { searchTypes.length === 0 ? null : (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ moduleT.translate('Name') }</th>\r\n <th>{ moduleT.translate('File extensions') }</th>\r\n <th>{ moduleT.translate('Default') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { searchTypes.map(type => getRow(type, moduleT)) }\r\n </tbody>\r\n </table>\r\n ) }\r\n <Message\r\n icon={ IconConstants.NOTE }\r\n description={ \r\n moduleT.t(\r\n 'searchTypesNote', \r\n // eslint-disable-next-line max-len\r\n 'Note; Custom search types will only be applied to ADC hubs! On NMDC hubs, using a predefined search type will only search for a set of predefined, unconfigurable extensions; using a custom type will default to searching for any extension.'\r\n )\r\n }\r\n />\r\n <SearchTypeDialog\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<SearchTypesPageProps, DataProps>(\r\n SearchTypesPage, {\r\n urls: {\r\n searchTypes: SearchConstants.SEARCH_TYPES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n SearchConstants.MODULE_URL, \r\n SearchConstants.SEARCH_TYPES_UPDATED, \r\n () => refetchData()\r\n );\r\n },\r\n }\r\n);","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'dont_download_shared',\r\n 'dont_download_queued',\r\n 'download_dupe_min_size',\r\n];\r\n\r\nconst Skiplist = [\r\n 'download_skiplist',\r\n 'download_skiplist_regex',\r\n];\r\n\r\nconst SkippingOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n\r\n <RemoteSettingForm\r\n title={ props.moduleT.translate('Skiplist') }\r\n { ...props }\r\n keys={ Skiplist }\r\n />\r\n </div>\r\n);\r\n\r\nexport default SkippingOptionsPage;","module.exports = {\r\n url: 'downloads',\r\n title: 'Downloads',\r\n icon: 'download',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Locations', \r\n url: 'locations',\r\n component: require('./components/LocationsPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Skipping options', \r\n url: 'skipping-options',\r\n component: require('./components/SkippingOptionsPage').default,\r\n }, { \r\n title: 'Search matching', \r\n url: 'search-matching',\r\n component: require('./components/SearchMatchingPage').default,\r\n }, { \r\n title: 'Download options', \r\n url: 'download-options',\r\n component: require('./components/DownloadOptionsPage').default,\r\n }, { \r\n title: 'Priorities', \r\n url: 'priorities',\r\n component: require('./components/PrioritiesPage').default,\r\n }, { \r\n title: 'Search types', \r\n url: 'search-types',\r\n component: require('./components/SearchTypesPage').default,\r\n }\r\n ],\r\n};","import * as React from 'react';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface EngineStatusMessageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface EngineStatusMessageDataProps extends DataProviderDecoratorChildProps {\r\n enginesStatus: API.ExtensionEngineStatus;\r\n}\r\n\r\n// Show an info message if the default extension engine is not installed\r\nconst EngineStatusMessage: React.FC<EngineStatusMessageProps & EngineStatusMessageDataProps> = (\r\n { enginesStatus, moduleT }\r\n) => {\r\n if (enginesStatus[ExtensionConstants.DEFAULT_ENGINE]) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Message \r\n description={\r\n <Trans i18nKey={ moduleT.toI18nKey('defaultExtensionEngineMissing') }>\r\n The default extension engine <b>{ ExtensionConstants.DEFAULT_ENGINE }</b> is not installed on your system. \r\n Please visit <ExternalLink url={ LinkConstants.DEFAULT_ENGINE_URL }>engine's home page</ExternalLink> for \r\n installation instructions.\r\n </Trans>\r\n }\r\n icon={ IconConstants.WARNING }\r\n />\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<EngineStatusMessageProps, EngineStatusMessageDataProps>(EngineStatusMessage, {\r\n urls: {\r\n enginesStatus: ExtensionConstants.ENGINES_STATUS_URL,\r\n },\r\n loaderText: null\r\n});","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'extension_engines',\r\n];\r\n\r\nconst ExtensionEnginesPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default ExtensionEnginesPage;","import * as React from 'react';\r\n\r\nimport Extension from 'routes/Settings/routes/Extensions/components/extension/Extension';\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport 'fomantic-ui-css/components/item.min.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\n\r\ninterface NpmPackageLayoutProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface NpmCatalogItem {\r\n package: UI.NpmPackage;\r\n}\r\n\r\ninterface NpmPackageLayoutDataProps extends DataProviderDecoratorChildProps {\r\n installedPackages: API.Extension[];\r\n packageCatalog: NpmCatalogItem[];\r\n}\r\n\r\nconst getItem = (npmPackage: UI.NpmPackage, moduleT: UI.ModuleTranslator, installedPackages: API.Extension[]) => {\r\n const installedPackage = installedPackages.find(p => p.name === npmPackage.name);\r\n return (\r\n <Extension \r\n key={ npmPackage.name } \r\n npmPackage={ npmPackage } \r\n installedPackage={ installedPackage }\r\n moduleT={ moduleT }\r\n />\r\n );\r\n};\r\n\r\nconst NpmPackageLayout: React.FC<NpmPackageLayoutProps & NpmPackageLayoutDataProps> = ({\r\n packageCatalog, moduleT, installedPackages\r\n}) => (\r\n <div className=\"extension-layout\">\r\n <div className=\"ui divider\"/>\r\n { packageCatalog.length > 0 && (\r\n <div className=\"ui divided items\">\r\n { packageCatalog.map(data => getItem(data.package, moduleT, installedPackages)) }\r\n </div>\r\n ) }\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<NpmPackageLayoutProps, NpmPackageLayoutDataProps>(NpmPackageLayout, {\r\n urls: {\r\n installedPackages: ExtensionConstants.EXTENSIONS_URL,\r\n packageCatalog: () => fetchCorsSafeData(ExtensionConstants.NPM_PACKAGES_URL, true),\r\n },\r\n dataConverters: {\r\n packageCatalog: ({ objects }) => objects,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n const refetchInstalled = () => refetchData([ 'installedPackages' ]);\r\n\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.ADDED, refetchInstalled);\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.REMOVED, refetchInstalled);\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.UPDATED, refetchInstalled);\r\n },\r\n});\r\n","import * as React from 'react';\r\n\r\nimport ExtensionActions from 'actions/ui/ExtensionActions';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport EngineStatusMessage from 'routes/Settings/routes/Extensions/components/EngineStatusMessage';\r\nimport NpmPackageLayout from 'routes/Settings/routes/Extensions/components/NpmPackageLayout';\r\nimport ExtensionsConfigureDialog from 'routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\n\r\ninterface ExtensionBrowsePageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst ExtensionBrowsePage: React.FC<ExtensionBrowsePageProps> = ({ moduleT }) => {\r\n return (\r\n <>\r\n <EngineStatusMessage\r\n moduleT={ moduleT }\r\n />\r\n <div className=\"table-actions\">\r\n <ActionButton\r\n actions={ ExtensionActions.install }\r\n actionId=\"installUrl\"\r\n className=\"add\"\r\n />\r\n </div>\r\n <NpmPackageLayout\r\n moduleT={ moduleT }\r\n />\r\n <ExtensionsConfigureDialog/>\r\n </>\r\n );\r\n};\r\n\r\nexport default ExtensionBrowsePage;","import { Component } from 'react';\r\n\r\nimport Modal from 'components/semantic/Modal';\r\nimport Form, { FormSaveHandler } from 'components/form/Form';\r\n\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst getSettingsUrl = (extensionId: string) => {\r\n return `${ExtensionConstants.EXTENSIONS_URL}/${extensionId}/settings`;\r\n};\r\n\r\ninterface ExtensionsConfigureDialogProps {\r\n\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n fieldDefinitions: UI.FormFieldDefinition[];\r\n settings: UI.FormValueMap;\r\n extension: API.Extension;\r\n}\r\n\r\ninterface RouteProps { \r\n extensionId: string; \r\n}\r\n\r\ntype Props = ExtensionsConfigureDialogProps & DataProps & \r\n ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass ExtensionsConfigureDialog extends Component<Props> {\r\n static displayName = 'ExtensionsConfigureDialog';\r\n\r\n form: Form;\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<UI.FormValueMap> = (changedFields) => {\r\n return SocketService.patch(getSettingsUrl(this.props.extension.id), changedFields);\r\n }\r\n\r\n render() {\r\n const { extension, settings, fieldDefinitions, ...other } = this.props;\r\n return (\r\n <Modal \r\n { ...other }\r\n className=\"extensions configure\" \r\n title={ extension.name } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.EDIT }\r\n dynamicHeight={ true }\r\n >\r\n <Form\r\n ref={ (c: any) => this.form = c! }\r\n onSave={ this.onSave }\r\n fieldDefinitions={ fieldDefinitions }\r\n sourceValue={ settings }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<ExtensionsConfigureDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(\r\n ExtensionsConfigureDialog, {\r\n urls: {\r\n fieldDefinitions: ({ match }) => {\r\n return SocketService.get(`${getSettingsUrl(match.params.extensionId)}/definitions`);\r\n },\r\n settings: ({ match }) => SocketService.get(getSettingsUrl(match.params.extensionId)),\r\n extension: ({ match }, socket) => {\r\n return socket.get(`${ExtensionConstants.EXTENSIONS_URL}/${match.params.extensionId}`);\r\n },\r\n },\r\n }\r\n ),\r\n 'extensions/:extensionId'\r\n);","import DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport Extension from 'routes/Settings/routes/Extensions/components/extension/Extension';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\n\r\nexport interface NpmPackageData {\r\n name: string;\r\n description: string;\r\n version: string;\r\n _npmUser: {\r\n name: string;\r\n };\r\n}\r\n\r\n// The npm registry API returns different data/fieldnames for different calls\r\n// so we must do some conversions (the primary data format is the one used by the package search method)\r\nconst convertNpmPackage = ({ name, description, version, _npmUser }: NpmPackageData): UI.NpmPackage => {\r\n return {\r\n id: name,\r\n name,\r\n description,\r\n version,\r\n publisher: {\r\n username: _npmUser.name,\r\n },\r\n date: '',\r\n };\r\n};\r\n\r\n\r\ninterface LocalExtensionProps {\r\n installedPackage: API.Extension;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface LocalExtensionDataProps extends DataProviderDecoratorChildProps {\r\n npmPackage: NpmPackageData;\r\n}\r\n\r\nconst LocalExtension = DataProviderDecorator<LocalExtensionProps, LocalExtensionDataProps>(\r\n ({ installedPackage, npmPackage, dataError, moduleT }) => (\r\n <Extension \r\n key={ installedPackage.name } \r\n installedPackage={ installedPackage } \r\n npmPackage={ !!npmPackage ? convertNpmPackage(npmPackage) : undefined }\r\n npmError={ dataError }\r\n moduleT={ moduleT }\r\n />\r\n ), \r\n {\r\n urls: {\r\n npmPackage: ({ installedPackage }) => {\r\n if (installedPackage.private || !installedPackage.managed) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return fetchCorsSafeData(`${ExtensionConstants.NPM_PACKAGE_URL}${installedPackage.name}/latest`, true);\r\n },\r\n },\r\n renderOnError: true,\r\n }\r\n);\r\n\r\nexport default LocalExtension;\r\n","import * as React from 'react';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport EngineStatusMessage from 'routes/Settings/routes/Extensions/components/EngineStatusMessage';\r\nimport ExtensionsConfigureDialog from 'routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog';\r\n\r\nimport { Link } from 'react-router-dom';\r\nimport Message from 'components/semantic/Message';\r\nimport LocalExtension from 'routes/Settings/routes/Extensions/components/LocalExtension';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface ExtensionsManagePageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\ninterface ExtensionsManagePageDataProps extends DataProviderDecoratorChildProps {\r\n installedPackages: API.Extension[];\r\n}\r\n\r\nconst getItem = (extension: API.Extension, moduleT: UI.ModuleTranslator) => {\r\n return (\r\n <LocalExtension \r\n key={ extension.name } \r\n installedPackage={ extension } \r\n moduleT={ moduleT }\r\n />\r\n );\r\n};\r\n\r\nconst ExtensionsManagePage: React.FC<ExtensionsManagePageProps & ExtensionsManagePageDataProps> = ({ \r\n installedPackages, moduleT \r\n}) => {\r\n if (installedPackages.length === 0) {\r\n return (\r\n <Message \r\n description={\r\n <Trans i18nKey={ moduleT.toI18nKey('noInstalledExtensions') }>\r\n No installed extensions were found. New extensions \r\n can be installed from the <Link to=\"/settings/extensions/packages\">Extension catalog</Link> page.\r\n </Trans>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n );\r\n } \r\n\r\n return (\r\n <div className=\"extension-layout\">\r\n <EngineStatusMessage \r\n moduleT={ moduleT }\r\n />\r\n <div className=\"ui divider\"/>\r\n <div className=\"ui divided items\">\r\n { installedPackages.map(p => getItem(p, moduleT)) }\r\n </div>\r\n <ExtensionsConfigureDialog/>\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<ExtensionsManagePageProps, ExtensionsManagePageDataProps>(ExtensionsManagePage, {\r\n urls: {\r\n installedPackages: ExtensionConstants.EXTENSIONS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.ADDED, () => refetchData());\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.REMOVED, () => refetchData());\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.UPDATED, () => refetchData());\r\n },\r\n});\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'extensions_debug_mode',\r\n 'extensions_auto_update',\r\n 'extensions_init_timeout',\r\n];\r\n\r\nconst ExtensionOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default ExtensionOptionsPage;","import * as React from 'react';\r\n\r\nimport ExtensionActions from 'actions/ui/ExtensionActions';\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport ExternalLink from 'components/ExternalLink';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { ActionMenu } from 'components/menu';\r\nimport MenuConstants from 'constants/MenuConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport Icon from 'components/semantic/Icon';\r\n\r\n\r\nexport interface ExtensionActionButtonsProps {\r\n npmPackage?: UI.NpmPackage;\r\n installedPackage?: API.Extension;\r\n hasUpdate: boolean;\r\n installing: boolean;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\n\r\ntype InstallButtonProps = Omit<ExtensionActionButtonsProps, 'moduleT'>;\r\n\r\nconst InstallButton: React.FC<InstallButtonProps> = (\r\n { npmPackage, installedPackage, hasUpdate, installing }\r\n) => {\r\n if (installedPackage && !hasUpdate) {\r\n return null;\r\n }\r\n\r\n return (\r\n <ActionButton\r\n actions={ ExtensionActions.npm }\r\n actionId={ hasUpdate ? 'updateNpm' : 'installNpm' }\r\n className=\"right floated primary\"\r\n itemData={ npmPackage }\r\n loading={ installing }\r\n />\r\n );\r\n};\r\n\r\nconst ExtensionActionButtons: React.FC<ExtensionActionButtonsProps> = (\r\n { npmPackage, installedPackage, hasUpdate, installing, moduleT }\r\n) => (\r\n <div className=\"extra buttons\">\r\n { npmPackage && (\r\n <InstallButton\r\n npmPackage={ npmPackage }\r\n installedPackage={ installedPackage }\r\n hasUpdate={ hasUpdate }\r\n installing={ installing }\r\n />\r\n ) }\r\n { installedPackage && (\r\n <ActionMenu\r\n actions={ ExtensionActions.manage }\r\n ids={ [ 'configure', 'divider', 'remove' ] }\r\n remoteMenuId={ MenuConstants.EXTENSION }\r\n itemData={ installedPackage }\r\n className=\"right floated\"\r\n caption={ moduleT.translate('Manage...') }\r\n button={ true }\r\n contextElement=\"#setting-scroll-context\"\r\n menuElementClassName=\"left floated\"\r\n />\r\n ) }\r\n { npmPackage && (\r\n <ExternalLink \r\n className=\"ui right floated button\"\r\n url={ ExtensionConstants.NPM_HOMEPAGE_URL + npmPackage.name }\r\n >\r\n <Icon\r\n icon={ IconConstants.OPEN }\r\n />\r\n { moduleT.translate('Read more') }\r\n </ExternalLink> \r\n ) }\r\n { installedPackage && (\r\n <ActionButton\r\n actions={ ExtensionActions.manage }\r\n actionId={ installedPackage.running ? 'stop' : 'start' }\r\n className=\"right floated\"\r\n itemData={ installedPackage }\r\n />\r\n ) }\r\n </div>\r\n);\r\n\r\nexport default ExtensionActionButtons;","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\nimport Moment from 'moment';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport ExtensionIcon from 'routes/Settings/routes/Extensions/components/extension/ExtensionIcon';\r\nimport ExtensionActionButtons from 'routes/Settings/routes/Extensions/components/extension/ExtensionActionButtons';\r\n\r\nimport { compareVersions } from 'compare-versions';\r\n\r\nimport 'fomantic-ui-css/components/item.min.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { \r\n SocketSubscriptionDecoratorChildProps, SocketSubscriptionDecorator\r\n} from 'decorators/SocketSubscriptionDecorator';\r\nimport { errorResponseToString } from 'utils/TypeConvert';\r\nimport { DataFetchError } from 'decorators/DataProviderDecorator';\r\n\r\n\r\ninterface VersionProps {\r\n title: string;\r\n className?: string;\r\n packageInfo?: {\r\n date?: string;\r\n version: string;\r\n };\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst Version: React.FC<VersionProps> = ({ title, packageInfo, className, moduleT }) => {\r\n if (!packageInfo) {\r\n return null;\r\n }\r\n\r\n const versionDesc = !packageInfo.date ? packageInfo.version : moduleT.t(\r\n 'datePublished',\r\n {\r\n defaultValue: '{{version}} (published {{date}})',\r\n replace: {\r\n version: packageInfo.version,\r\n date: Moment(packageInfo.date).from(Moment())\r\n }\r\n }\r\n );\r\n\r\n return (\r\n <div className={ className }>\r\n { `${title}: ` }\r\n <span> \r\n { versionDesc }\r\n </span>\r\n </div>\r\n );\r\n};\r\n\r\nconst formatAuthor = (moduleT: UI.ModuleTranslator, npmPackage?: UI.NpmPackage, installedPackage?: API.Extension) => {\r\n let author: string | undefined;\r\n if (installedPackage && installedPackage.author) {\r\n author = installedPackage.author;\r\n }\r\n\r\n if (npmPackage) {\r\n author = npmPackage.publisher.username;\r\n }\r\n\r\n if (!author) {\r\n return null;\r\n }\r\n\r\n return moduleT.t('byAuthor', {\r\n defaultValue: 'by {{author}}',\r\n replace: {\r\n author\r\n }\r\n });\r\n};\r\n\r\nconst formatNote = (\r\n moduleT: UI.ModuleTranslator, \r\n installedPackage?: API.Extension, \r\n npmError?: DataFetchError | null\r\n) => {\r\n if (installedPackage && !installedPackage.managed) {\r\n return moduleT.translate('Unmanaged extension');\r\n }\r\n\r\n if (npmError) {\r\n return moduleT.t(\r\n 'extensionDirectoryFetchError',\r\n {\r\n defaultValue: 'Failed to fetch information from the extension directory: {{error}}',\r\n replace: {\r\n error: errorResponseToString(npmError)\r\n }\r\n }\r\n );\r\n }\r\n\r\n return moduleT.translate('Non-listed extension');\r\n};\r\n\r\n\r\nexport interface ExtensionProps {\r\n installedPackage?: API.Extension;\r\n npmPackage?: UI.NpmPackage;\r\n npmError?: DataFetchError | null;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\n\r\ninterface State {\r\n installing: boolean;\r\n}\r\nclass Extension extends React.PureComponent<ExtensionProps & SocketSubscriptionDecoratorChildProps, State> {\r\n //displayName: 'Extension',\r\n\r\n /*propTypes: {\r\n npmPackage: PropTypes.shape({\r\n name: PropTypes.string.isRequired,\r\n description: PropTypes.string.isRequired,\r\n version: PropTypes.string.isRequired,\r\n date: PropTypes.string,\r\n publisher: PropTypes.shape({\r\n username: PropTypes.string,\r\n }),\r\n }),\r\n installedPackage: PropTypes.shape({\r\n name: PropTypes.string.isRequired,\r\n description: PropTypes.string.isRequired,\r\n version: PropTypes.string.isRequired,\r\n author: PropTypes.string,\r\n }),\r\n },*/\r\n\r\n state: State = {\r\n installing: false,\r\n };\r\n\r\n onInstallationStarted = (data: API.ExtensionInstallEvent) => {\r\n if (data.install_id !== this.props.npmPackage!.name) {\r\n return;\r\n }\r\n\r\n this.setState({\r\n installing: true,\r\n });\r\n }\r\n\r\n onInstallationCompleted = (data: API.ExtensionInstallEvent) => {\r\n if (data.install_id !== this.props.npmPackage!.name) {\r\n return;\r\n }\r\n\r\n this.setState({\r\n installing: false,\r\n });\r\n }\r\n\r\n componentDidMount() {\r\n const { addSocketListener, npmPackage } = this.props;\r\n\r\n if (!!npmPackage) {\r\n // eslint-disable-next-line max-len\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.INSTALLATION_STARTED, this.onInstallationStarted);\r\n // eslint-disable-next-line max-len\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.INSTALLATION_SUCCEEDED, this.onInstallationCompleted);\r\n // eslint-disable-next-line max-len\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.INSTALLATION_FAILED, this.onInstallationCompleted);\r\n }\r\n }\r\n\r\n render() {\r\n const { npmPackage, installedPackage, npmError, moduleT } = this.props;\r\n const { installing } = this.state;\r\n const { translate } = moduleT;\r\n\r\n const hasUpdate = !!installedPackage && !!npmPackage && \r\n compareVersions(installedPackage.version, npmPackage.version) < 0;\r\n\r\n return (\r\n <div className=\"item extension\">\r\n <ExtensionIcon\r\n installedPackage={ installedPackage }\r\n hasUpdate={ hasUpdate }\r\n />\r\n <div className=\"content\">\r\n <a className=\"header\">\r\n { npmPackage ? npmPackage.name : installedPackage!.name }\r\n </a>\r\n <div className=\"meta author\">\r\n { formatAuthor(moduleT, npmPackage, installedPackage) }\r\n </div>\r\n <div className=\"description\">\r\n <span>{ npmPackage ? npmPackage.description : installedPackage!.description }</span>\r\n </div>\r\n <div className=\"extra version\">\r\n <Version \r\n className=\"npm\"\r\n title={ translate('Latest version') }\r\n packageInfo={ npmPackage }\r\n moduleT={ moduleT }\r\n />\r\n <div>\r\n { !npmPackage && formatNote(moduleT, installedPackage, npmError) }\r\n </div>\r\n <Version \r\n className={ npmPackage ? (!hasUpdate ? 'latest' : 'outdated') : undefined }\r\n title={ translate('Installed version') } \r\n packageInfo={ installedPackage }\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n <ExtensionActionButtons\r\n installedPackage={ installedPackage }\r\n npmPackage={ npmPackage }\r\n installing={ installing }\r\n hasUpdate={ hasUpdate }\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default SocketSubscriptionDecorator<ExtensionProps>(Extension);","import * as React from 'react';\r\n\r\nimport Icon from 'components/semantic/Icon';\r\n\r\nimport * as API from 'types/api';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst getCornerIcon = (installedPackage: API.Extension | undefined, hasUpdate: boolean) => {\r\n if (!installedPackage) {\r\n return null;\r\n }\r\n\r\n if (hasUpdate) {\r\n return 'yellow warning circle';\r\n }\r\n\r\n if (!installedPackage.managed) {\r\n return 'blue external square';\r\n }\r\n\r\n return 'green check circle';\r\n};\r\n\r\ninterface ExtensionIconProps {\r\n installedPackage?: API.Extension;\r\n hasUpdate: boolean;\r\n size?: string;\r\n}\r\n\r\nconst ExtensionIcon: React.FC<ExtensionIconProps> = ({ installedPackage, hasUpdate, size = 'huge' }) => (\r\n <div className=\"ui image\">\r\n <Icon \r\n icon={ IconConstants.EXTENSION }\r\n size={ size } \r\n cornerIcon={ getCornerIcon(installedPackage, hasUpdate) }\r\n />\r\n </div>\r\n);\r\n\r\nexport default ExtensionIcon;","module.exports = {\r\n url: 'extensions',\r\n title: 'Extensions',\r\n icon: 'puzzle',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'Manage installed', \r\n url: 'manage',\r\n noSave: true,\r\n component: require('./components/ExtensionsManagePage').default,\r\n }, { \r\n title: 'Extension catalog', \r\n url: 'packages', \r\n noSave: true,\r\n component: require('./components/ExtensionsBrowsePage').default,\r\n }\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Extension options', \r\n url: 'extension-options',\r\n component: require('./components/ExtensionsOptionsPage').default,\r\n }, { \r\n title: 'Extension engines', \r\n url: 'extension-engines',\r\n component: require('./components/ExtensionEnginesPage').default,\r\n },\r\n ],\r\n};","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'away_message',\r\n 'away_no_bots',\r\n 'away_idle_time',\r\n];\r\n\r\nconst AwayPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default AwayPage;","import * as React from 'react';\r\n\r\nimport UserConstants from 'constants/UserConstants';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport { UserMenu } from 'components/menu';\r\n\r\nimport * as API from 'types/api';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport MenuConstants from 'constants/MenuConstants';\r\n\r\n\r\nconst Row: React.FC<{ ignoreInfo: API.IgnoredUser; }> = ({ ignoreInfo }) => (\r\n <tr>\r\n <td className=\"user dropdown\">\r\n <UserMenu \r\n ids={ [ 'unignore' ] } \r\n userIcon=\"simple\"\r\n user={ ignoreInfo.user }\r\n contextElement=\"#setting-scroll-context\"\r\n remoteMenuId={ MenuConstants.USER }\r\n />\r\n </td>\r\n <td className=\"count\">\r\n { ignoreInfo.ignored_messages }\r\n </td>\r\n </tr>\r\n);\r\n\r\n\r\nconst getRow = (ignoreInfo: API.IgnoredUser) => {\r\n return (\r\n <Row \r\n key={ ignoreInfo.user.cid } \r\n ignoreInfo={ ignoreInfo } \r\n />\r\n );\r\n};\r\n\r\ntype IgnorePageProps = SettingSectionChildProps;\r\n\r\ninterface IgnorePageDataProps extends DataProviderDecoratorChildProps {\r\n ignores: API.IgnoredUser[];\r\n}\r\n\r\nconst IgnorePage: React.FC<IgnorePageProps & IgnorePageDataProps> = ({ ignores, moduleT }) => {\r\n const { translate } = moduleT;\r\n if (ignores.length === 0) {\r\n return (\r\n <Message\r\n title={ translate('No ignored users') }\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <div>\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('User') }</th>\r\n <th>{ translate('Messages ignored') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { ignores.map(getRow) }\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<IgnorePageProps, IgnorePageDataProps>(IgnorePage, {\r\n urls: {\r\n ignores: UserConstants.IGNORES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(UserConstants.MODULE_URL, UserConstants.IGNORE_ADDED, () => refetchData());\r\n addSocketListener(UserConstants.MODULE_URL, UserConstants.IGNORE_REMOVED, () => refetchData());\r\n },\r\n});","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport '../style.css';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { Trans } from 'react-i18next';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\n\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n //const { toI18nKey } = this.props.moduleT;\r\n if (id === 'nmdc_encoding') {\r\n fieldOptions.help = (\r\n <Trans \r\n i18nKey={ moduleT.toI18nKey(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined)\r\n ) }\r\n >\r\n <div>\r\n Encoding setting is only used in NMDC hubs. ADC hubs will always use UTF-8 encoding.\r\n <br/>\r\n <br/>\r\n <div>\r\n Commonly used values:\r\n <ul>\r\n <li>Central Europe: cp1250</li>\r\n <li>Cyrillic: cp1251</li>\r\n <li>Western Europe: cp1252</li>\r\n <li>Greek: cp1253</li>\r\n <li>Turkish: cp1254</li>\r\n <li>Hebrew: cp1256</li>\r\n </ul>\r\n </div>\r\n </div>\r\n </Trans>\r\n );\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\n\r\nconst Entry = [\r\n 'auto_follow_redirects',\r\n 'disconnect_offline_users',\r\n 'disconnect_hubs_noreg',\r\n 'min_search_interval',\r\n];\r\n\r\nconst MiscPage: React.FC<SettingSectionChildProps> = props => {\r\n // The locale-specific system encoding is used on Windows by default\r\n // while other system use UTF-8\r\n if (LoginStore.systemInfo.platform !== API.PlatformEnum.WINDOWS) {\r\n Entry.push('nmdc_encoding');\r\n }\r\n\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ FieldOptionGetter(props.moduleT) }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default MiscPage;","import * as React from 'react';\r\nimport { SettingProfileEnum } from 'constants/SettingConstants';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\nconst Entry = [\r\n 'nick',\r\n 'description',\r\n 'email',\r\n 'setting_profile',\r\n 'language_file'\r\n];\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n if (id === 'setting_profile') {\r\n let message;\r\n\r\n const profileId = formValue[id] as number;\r\n switch (profileId) {\r\n case SettingProfileEnum.NORMAL: {\r\n // eslint-disable-next-line max-len\r\n message = 'The client is used in normal private/public hubs for transferring files via internet. Use this profile if unsure.';\r\n break;\r\n }\r\n case SettingProfileEnum.RAR: {\r\n // eslint-disable-next-line max-len\r\n message = 'The client is used for transferring files that are split in RAR archives (or in other small-sized formats)';\r\n break;\r\n }\r\n case SettingProfileEnum.LAN: {\r\n // eslint-disable-next-line max-len\r\n message = 'The client is used for transferring files in local network (e.g. LAN parties) or in another closed network (e.g. university network)';\r\n break;\r\n }\r\n default:\r\n }\r\n\r\n if (message) {\r\n fieldOptions.help = moduleT.t(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, profileId.toString()),\r\n message\r\n );\r\n }\r\n } else if (id === 'language_file') {\r\n fieldOptions.help = (\r\n <Trans\r\n i18nKey={ moduleT.toI18nKey(toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined)) }\r\n >\r\n <p>\r\n The application must be restarted for the new language to take effect.\r\n </p>\r\n <p>\r\n If you want to help with improving the existing translations \r\n or translate the application into a new language, please see \r\n the <ExternalLink url={ LinkConstants.TRANSLATOR_HELP }>instructions for translators</ExternalLink>.\r\n </p>\r\n </Trans>\r\n );\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\nconst UserPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ FieldOptionGetter(props.moduleT) }\r\n />\r\n </div>\r\n);\r\n\r\nexport default UserPage;","module.exports = {\r\n url: 'profile',\r\n title: 'Profile',\r\n icon: 'user',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'User', \r\n url: 'user',\r\n component: require('./components/UserPage').default,\r\n }, { \r\n title: 'Away mode', \r\n url: 'away',\r\n component: require('./components/AwayPage').default,\r\n }, \r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Ignored users', \r\n url: 'ignored-users',\r\n noSave: true,\r\n component: require('./components/IgnorePage').default,\r\n }, { \r\n title: 'Miscellaneous', \r\n url: 'miscellaneous',\r\n component: require('./components/MiscPage').default,\r\n },\r\n ],\r\n};","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareConstants from 'constants/ShareConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport History from 'utils/History';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleAdd: UI.ActionHandler<void> = ({ location }) => {\r\n History.push(`${location.pathname}/browse`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<string> = ({ data: path }) => {\r\n return SocketService.post(ShareConstants.EXCLUDES_REMOVE_URL, { path });\r\n};\r\n\r\n\r\nconst ShareExcludeCreateActions: UI.ActionListType<undefined> = {\r\n add: {\r\n displayName: 'Add path',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n handler: handleAdd,\r\n },\r\n};\r\n\r\nconst ShareExcludeEditActions: UI.ActionListType<string> = {\r\n remove: { \r\n displayName: 'Remove path',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the excluded path {{item}}?',\r\n approveCaption: 'Remove path',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n }, \r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'shareExclude',\r\n actions: ShareExcludeCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'shareExclude',\r\n actions: ShareExcludeEditActions,\r\n }\r\n};\r\n","import * as React from 'react';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareActions from 'actions/ui/ShareActions';\r\nimport ShareExcludeActions from 'actions/ui/ShareExcludeActions';\r\nimport ShareConstants from 'constants/ShareConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport { ActionMenu } from 'components/menu';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport { FileBrowserRouteDialog } from 'components/filebrowser';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport FilesystemConstants from 'constants/FilesystemConstants';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\nconst Row: React.FC<{ path: string; }> = ({ path }) => (\r\n <tr>\r\n <td className=\"path dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ path }</strong> } \r\n actions={ ShareExcludeActions.edit } \r\n //ids={ [ 'remove' ] } \r\n itemData={ path }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (path: string) => {\r\n return (\r\n <Row \r\n key={ path } \r\n path={ path } \r\n />\r\n );\r\n};\r\n\r\n\r\ntype ExcludePageProps = SettingSectionChildProps;\r\n\r\ninterface ExcludePageDataProps extends DataProviderDecoratorChildProps {\r\n excludes: string[];\r\n}\r\n\r\nclass ExcludePage extends React.Component<ExcludePageProps & ExcludePageDataProps> {\r\n static displayName = 'ExcludePage';\r\n\r\n render() {\r\n const { excludes, moduleT } = this.props;\r\n const { translate, toI18nKey } = moduleT;\r\n return (\r\n <div>\r\n <Message\r\n title={\r\n <div>\r\n <div>\r\n <Trans i18nKey={ toI18nKey('shareRefreshNote') }>\r\n Share must be refreshed for the changes to take effect\r\n </Trans>\r\n </div>\r\n <br/>\r\n <ActionButton\r\n actions={ ShareActions }\r\n actionId=\"refresh\"\r\n />\r\n </div>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n\r\n <ActionButton\r\n actions={ ShareExcludeActions.create }\r\n actionId=\"add\"\r\n className=\"add\"\r\n />\r\n\r\n { excludes.length > 0 && (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('Path') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { excludes.map(getRow) }\r\n </tbody>\r\n </table>\r\n ) }\r\n\r\n <FileBrowserRouteDialog\r\n onConfirm={ path => runBackgroundSocketAction(\r\n () => SocketService.post(ShareConstants.EXCLUDES_ADD_URL, { path }), \r\n moduleT.plainT\r\n ) }\r\n initialPath=\"\"\r\n historyId={ FilesystemConstants.LOCATION_GENERIC }\r\n subHeader={ translate('Add excluded path') }\r\n selectMode={ UI.FileSelectModeEnum.DIRECTORY }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator(ExcludePage, {\r\n urls: {\r\n excludes: ShareConstants.EXCLUDES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ShareConstants.MODULE_URL, ShareConstants.EXCLUDE_ADDED, () => refetchData());\r\n addSocketListener(ShareConstants.MODULE_URL, ShareConstants.EXCLUDE_REMOVED, () => refetchData());\r\n },\r\n});","import * as React from 'react';\r\nimport SocketService from 'services/SocketService';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport Checkbox from 'components/semantic/Checkbox';\r\nimport Button from 'components/semantic/Button';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport HashConstants from 'constants/HashConstants';\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\nimport { Row, Grid } from 'components/semantic/Grid';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface OptimizeLayoutProps {\r\n running: boolean;\r\n startHandler: (verify: boolean) => void;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst OptimizeLayout: React.FC<OptimizeLayoutProps> = (\r\n { startHandler, running, moduleT }\r\n) => {\r\n const { toI18nKey, translate } = moduleT;\r\n const [ verify, setVerify ] = React.useState(false);\r\n return (\r\n <div className=\"optimize-layout\">\r\n <h4 className=\"header\" style={{ marginTop: '30px' }}>\r\n { translate('Maintenance') }\r\n </h4>\r\n <Message \r\n description={ (\r\n <Trans i18nKey={ toI18nKey('hashDBOptimizeNote') }>\r\n This operation will delete all hash information for files that aren't currently in share. \r\n If you are sharing files from network disks or from a removable storage, \r\n make sure that the files are currently shown in share (otherwise they have to be rehashed)\r\n </Trans>\r\n ) }\r\n icon={ IconConstants.NOTE }\r\n />\r\n\r\n <Checkbox \r\n caption={ translate('Verify integrity of hash data') } \r\n checked={ verify } \r\n disabled={ running }\r\n onChange={ setVerify }\r\n floating={ true }\r\n />\r\n <Button \r\n className=\"optimize-button\"\r\n caption={ translate('Optimize now') }\r\n icon={ IconConstants.CONFIGURE }\r\n loading={ running } \r\n onClick={ () => startHandler(verify) }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\ninterface HashDatabaseLayoutProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\ninterface HashDatabaseLayoutDataProps extends DataProviderDecoratorChildProps {\r\n status: API.HashDatabaseStatus;\r\n}\r\n\r\nclass HashDatabaseLayout extends React.Component<HashDatabaseLayoutProps & HashDatabaseLayoutDataProps> {\r\n handleOptimize = (verify: boolean) => {\r\n runBackgroundSocketAction(\r\n () => SocketService.post(HashConstants.OPTIMIZE_DATABASE_URL, { verify }),\r\n this.props.moduleT.plainT\r\n );\r\n }\r\n\r\n render() {\r\n const { status, moduleT } = this.props;\r\n const { translate, plainT } = moduleT;\r\n return (\r\n <div className=\"ui segment hash-database\">\r\n <h3 className=\"header\">\r\n { translate('Hash database') }\r\n </h3>\r\n <Grid columns=\"two\">\r\n <Row \r\n title={ translate('File index size') } \r\n text={ formatSize(status.file_index_size, plainT) }\r\n titleWidth=\"five\"\r\n />\r\n <Row \r\n title={ translate('Hash store size') }\r\n text={ formatSize(status.hash_store_size, plainT) }\r\n titleWidth=\"five\"\r\n />\r\n </Grid>\r\n { LoginStore.hasAccess(API.AccessEnum.SETTINGS_EDIT) && (\r\n <OptimizeLayout\r\n running={ status.maintenance_running }\r\n startHandler={ this.handleOptimize }\r\n moduleT={ moduleT }\r\n /> \r\n ) }\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator<HashDatabaseLayoutProps, HashDatabaseLayoutDataProps>(HashDatabaseLayout, {\r\n urls: {\r\n status: HashConstants.DATABASE_STATUS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(HashConstants.MODULE_URL, HashConstants.DATABASE_STATUS, () => refetchData());\r\n },\r\n});","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport HashDatabaseLayout from 'routes/Settings/routes/Sharing/components/HashDatabaseLayout';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'max_hash_speed',\r\n 'max_total_hashers',\r\n 'max_volume_hashers',\r\n];\r\n\r\nconst HashingPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n\r\n <HashDatabaseLayout\r\n moduleT={ props.moduleT }\r\n />\r\n </div>\r\n);\r\n\r\nexport default HashingPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'refresh_time',\r\n 'refresh_time_incoming',\r\n 'refresh_startup',\r\n 'refresh_threading',\r\n];\r\n\r\nconst RefreshOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default RefreshOptionsPage;","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport FilelistSessionActions from 'actions/reflux/FilelistSessionActions';\r\nimport FilelistSessionStore from 'stores/FilelistSessionStore';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst notDefault = (item: API.ShareProfile) => !item.default;\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<void> = (data, name: string) => {\r\n return SocketService.post(ShareProfileConstants.PROFILES_URL, { name: name });\r\n};\r\n\r\nconst handleDefault: UI.ActionHandler<API.ShareProfile> = ({ data: profile }) => {\r\n return SocketService.post(`${ShareProfileConstants.PROFILES_URL}/${profile.id}/default`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.ShareProfile> = (\r\n { data: profile },\r\n name: string\r\n) => {\r\n return SocketService.patch(`${ShareProfileConstants.PROFILES_URL}/${profile.id}`, { name: name });\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.ShareProfile> = (\r\n { data: profile }\r\n) => {\r\n return SocketService.delete(ShareProfileConstants.PROFILES_URL + '/' + profile.id);\r\n};\r\n\r\nconst handleBrowse: UI.ActionHandler<API.ShareProfile> = (\r\n { data: profile, location }\r\n) => {\r\n return FilelistSessionActions.ownList(location, profile.id, FilelistSessionStore);\r\n};\r\n\r\n\r\n\r\n\r\nconst ShareProfileCreateActions: UI.ActionListType<undefined> = {\r\n create: {\r\n displayName: 'Add profile',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n input: {\r\n approveCaption: 'Create',\r\n content: 'Enter name for the profile',\r\n inputProps: {\r\n placeholder: 'Enter name',\r\n required: true,\r\n }\r\n },\r\n handler: handleCreate,\r\n },\r\n};\r\n\r\nconst ShareProfileEditActions: UI.ActionListType<API.ShareProfile> = {\r\n browse: {\r\n displayName: 'Browse files',\r\n access: API.AccessEnum.FILELISTS_VIEW,\r\n icon: IconConstants.FILELIST,\r\n handler: handleBrowse,\r\n },\r\n divider: null,\r\n edit: { \r\n displayName: 'Rename profile',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.EDIT,\r\n input: profile => ({\r\n approveCaption: 'Rename',\r\n content: 'Enter new name for the profile {{item.name}}',\r\n inputProps: {\r\n placeholder: 'Enter name',\r\n defaultValue: profile.name,\r\n required: true,\r\n }\r\n }),\r\n handler: handleEdit,\r\n },\r\n default: {\r\n displayName: 'Set as default',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.DEFAULT,\r\n filter: notDefault,\r\n handler: handleDefault,\r\n },\r\n remove: {\r\n displayName: 'Remove profile',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n filter: notDefault,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the profile {{item.name}}?',\r\n approveCaption: 'Remove profile',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n },\r\n};\r\n\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'profile',\r\n actions: ShareProfileCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'profile',\r\n actions: ShareProfileEditActions,\r\n }\r\n};\r\n","import * as React from 'react';\r\n\r\nimport ShareProfileActions from 'actions/ui/ShareProfileActions';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport { ActionMenu } from 'components/menu';\r\n\r\nimport { Link } from 'react-router-dom';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport ShareProfileDecorator, { ShareProfileDecoratorChildProps } from 'decorators/ShareProfileDecorator';\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface ShareProfileRowProps { \r\n profile: API.ShareProfile;\r\n t: UI.TranslateF;\r\n}\r\n\r\nconst ShareProfileRow: React.FC<ShareProfileRowProps> = ({ profile, t }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ profile.str }</strong> } \r\n actions={ ShareProfileActions.edit } \r\n itemData={ profile }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"size\">\r\n { formatSize(profile.size, t) }\r\n </td>\r\n <td className=\"files\">\r\n { profile.files }\r\n </td>\r\n </tr>\r\n);\r\n\r\ntype ShareProfilesPageProps = SettingSectionChildProps\r\n\r\nconst ShareProfilesPage: React.FC<ShareProfilesPageProps & ShareProfileDecoratorChildProps> = (\r\n { moduleT, profiles }\r\n) => {\r\n const { translate, toI18nKey } = moduleT;\r\n return (\r\n <div>\r\n <Message \r\n description={\r\n <div>\r\n <Trans i18nKey={ toI18nKey('shareProfilesNote') }>\r\n <p>\r\n Queued files are shared via the partial file sharing feature in all hubs where the share \r\n has not been hidden, regardless of the configured share profiles.\r\n </p>\r\n <p>\r\n Share profiles are assigned for individual directories from the <Link to=\"/share\">Share</Link> page.\r\n </p>\r\n </Trans>\r\n </div>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n <ActionButton\r\n actions={ ShareProfileActions.create }\r\n actionId=\"create\"\r\n />\r\n\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('Name') }</th>\r\n <th>{ translate('Total size') }</th>\r\n <th>{ translate('Total files') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { profiles.map(profile => (\r\n <ShareProfileRow\r\n key={ profile.id }\r\n profile={ profile }\r\n t={ moduleT.plainT }\r\n />\r\n )) }\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator(ShareProfilesPage, false, undefined, false);","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'share_hidden',\r\n 'share_no_empty_dirs',\r\n 'share_no_zero_byte',\r\n 'share_follow_symlinks',\r\n 'share_max_size',\r\n];\r\n\r\nconst Skiplist = [\r\n 'share_skiplist',\r\n 'share_skiplist_regex',\r\n];\r\n\r\nconst SharingOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n title={ props.moduleT.translate('Skiplist') }\r\n { ...props }\r\n keys={ Skiplist }\r\n />\r\n </div>\r\n);\r\n\r\nexport default SharingOptionsPage;","module.exports = {\r\n url: 'sharing',\r\n title: 'Sharing',\r\n icon: 'tasks',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'Refresh options', \r\n url: 'refresh-options',\r\n component: require('./components/RefreshOptionsPage').default, \r\n }, { \r\n title: 'Share profiles', \r\n url: 'profiles', \r\n noSave: true,\r\n component: require('./components/ShareProfilesPage').default,\r\n }\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Sharing options', \r\n url: 'sharing-options',\r\n component: require('./components/SharingOptionsPage').default, \r\n }, { \r\n title: 'Hashing', \r\n url: 'hashing',\r\n component: require('./components/HashingPage').default, \r\n }, { \r\n title: 'Excluded paths', \r\n url: 'excludes',\r\n noSave: true,\r\n component: require('./components/ExcludePage').default,\r\n },\r\n ],\r\n};\r\n","import PropTypes from 'prop-types';\r\nimport { Component } from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport SocketService from 'services/SocketService';\r\nimport SettingConstants from 'constants/SettingConstants';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldChangeHandler, FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\n\r\n\r\ninterface AutoValuePanelProps extends SettingSectionChildProps {\r\n type: string;\r\n keys: string[];\r\n}\r\n\r\nclass AutoValuePanel extends Component<AutoValuePanelProps> {\r\n static propTypes = {\r\n // Form items to list\r\n keys: PropTypes.array.isRequired,\r\n\r\n // Type of the value section (from the setting key)\r\n type: PropTypes.string.isRequired,\r\n };\r\n\r\n getAutoKey = () => {\r\n return `${this.props.type}_auto_limits`;\r\n }\r\n\r\n // Fetch auto settings when enabling auto detection\r\n onFieldChanged: FormFieldChangeHandler = (changedKey, formValue, hasChanges) => {\r\n const autoSettingKey = this.getAutoKey();\r\n if (changedKey !== autoSettingKey || !formValue[autoSettingKey]) {\r\n return null;\r\n }\r\n\r\n return SocketService.post(SettingConstants.ITEMS_GET_URL, { \r\n keys: this.props.keys.filter(key => key !== autoSettingKey), \r\n value_mode: API.SettingValueMode.FORCE_AUTO,\r\n });\r\n }\r\n\r\n // Disable other fields when auto detection is enabled\r\n onFieldSetting: FormFieldSettingHandler<any> = (settingKey, fieldOptions, formValue) => {\r\n if (formValue[this.getAutoKey()] && settingKey !== this.getAutoKey()) {\r\n fieldOptions.disabled = true;\r\n }\r\n }\r\n\r\n render() {\r\n return (\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...this.props }\r\n onFieldChanged={ this.onFieldChanged }\r\n onFieldSetting={ this.onFieldSetting }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default AutoValuePanel;","import * as React from 'react';\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Auto = [\r\n 'download_auto_limits',\r\n 'download_slots',\r\n 'download_max_start_speed',\r\n];\r\n\r\nconst Manual = [\r\n 'download_highest_prio_slots',\r\n];\r\n\r\nconst DownloadLimitPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <AutoValuePanel\r\n { ...props }\r\n keys={ Auto }\r\n type=\"download\"\r\n />\r\n\r\n <RemoteSettingForm\r\n { ...props }\r\n title={ translate('Manually set') }\r\n keys={ Manual }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DownloadLimitPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'upload_limit_main',\r\n 'download_limit_main',\r\n //limit_use_with_auto_values: t.Bool,\r\n];\r\n\r\nconst LimiterPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default LimiterPage;","import * as React from 'react';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\nconst Entry = [\r\n 'download_speed',\r\n 'upload_speed',\r\n];\r\n\r\nconst SpeedPage: React.FC<SettingSectionChildProps> = props => {\r\n const { toI18nKey } = props.moduleT;\r\n return (\r\n <div>\r\n <div className=\"ui message\">\r\n <Trans i18nKey={ toI18nKey('connectionSpeedNote') }>\r\n Please be as accurate as possible and set the ACTUAL speed of your connection. You may use an online tester, \r\n such as <ExternalLink url={ LinkConstants.SPEEDTEST_URL }>Speedtest.net</ExternalLink>, to test your speed.\r\n </Trans>\r\n </div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default SpeedPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Auto = [\r\n 'upload_auto_limits',\r\n 'upload_slots',\r\n 'upload_auto_grant_speed',\r\n 'upload_max_granted',\r\n];\r\n\r\nconst Manual = [\r\n 'upload_minislot_size',\r\n 'upload_minislot_ext',\r\n];\r\n\r\nconst UploadLimitPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <AutoValuePanel\r\n { ...props }\r\n keys={ Auto }\r\n type=\"upload\"\r\n />\r\n\r\n <RemoteSettingForm\r\n { ...props }\r\n title={ translate('Manually set') }\r\n keys={ Manual }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default UploadLimitPage;","import * as React from 'react';\r\n\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Auto = [\r\n 'mcn_auto_limits',\r\n 'mcn_down',\r\n 'mcn_up',\r\n];\r\n\r\nconst UserLimitPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <AutoValuePanel\r\n { ...props }\r\n keys={ Auto }\r\n type=\"mcn\"\r\n />\r\n </div>\r\n);\r\n\r\nexport default UserLimitPage;","module.exports = {\r\n url: 'speed-limits',\r\n title: 'Speed and limits',\r\n icon: 'dashboard',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Connection speed', \r\n url: 'speed',\r\n component: require('./components/SpeedPage').default,\r\n }, { \r\n title: 'Bandwidth limiting', \r\n url: 'limiter',\r\n component: require('./components/LimiterPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Download limits', \r\n url: 'download-limits',\r\n component: require('./components/DownloadLimitPage').default,\r\n }, { \r\n title: 'Upload limits', \r\n url: 'upload-limits',\r\n component: require('./components/UploadLimitPage').default,\r\n }, { \r\n title: 'Per-user limits', \r\n url: 'user-limits',\r\n component: require('./components/UserLimitPage').default, \r\n },\r\n ],\r\n};","import * as React from 'react';\r\n\r\nimport SystemActions from 'actions/ui/SystemActions';\r\nimport ActionButton from 'components/ActionButton';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Generic = [\r\n 'web_server_threads',\r\n 'default_idle_timeout',\r\n 'ping_interval',\r\n 'ping_timeout',\r\n];\r\n\r\nconst Hooks = [\r\n 'share_file_validation_hook_timeout',\r\n 'share_directory_validation_hook_timeout',\r\n 'new_share_file_validation_hook_timeout',\r\n 'new_share_directory_validation_hook_timeout',\r\n \r\n 'outgoing_chat_message_hook_timeout',\r\n 'incoming_chat_message_hook_timeout',\r\n\r\n 'queue_add_bundle_hook_timeout',\r\n 'queue_add_bundle_file_hook_timeout',\r\n 'queue_add_source_hook_timeout',\r\n 'queue_bundle_finished_hook_timeout',\r\n 'queue_file_finished_hook_timeout',\r\n\r\n 'list_menuitems_hook_timeout',\r\n];\r\n\r\nconst ServerSettingsPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <ActionButton\r\n actions={ SystemActions }\r\n actionId=\"restartWeb\"\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Generic }\r\n />\r\n <div className=\"ui header\">\r\n { translate('Hook timeouts') }\r\n </div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Hooks }\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ServerSettingsPage;","import { Component } from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport '../style.css';\r\nimport { FormFieldChangeHandler, FormFieldSettingHandler } from 'components/form/Form';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nimport * as API from 'types/api';\r\n\r\nexport interface LogSectionProps extends SettingSectionChildProps {\r\n section: string;\r\n simple?: boolean;\r\n}\r\n\r\nclass LogSection extends Component<LogSectionProps> {\r\n state = {\r\n enabled: false,\r\n };\r\n\r\n convertKey = (suffix?: string) => {\r\n return `log_${this.props.section}${suffix ? `_${suffix}` : ''}`;\r\n }\r\n\r\n onSettingsReceived = (settings: API.SettingValueMap) => {\r\n this.setState({\r\n enabled: settings[this.convertKey()],\r\n });\r\n }\r\n\r\n onEnableStateChanged: FormFieldChangeHandler = (id, formValue, hasChanges) => {\r\n this.setState({ \r\n enabled: formValue[id]\r\n });\r\n }\r\n\r\n onContentSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n fieldOptions.disabled = !this.state.enabled;\r\n }\r\n\r\n getChildClass = (className: string) => {\r\n if (this.state.enabled) {\r\n return className + ' active';\r\n }\r\n\r\n return className;\r\n }\r\n\r\n render() {\r\n const Title = [\r\n this.convertKey(),\r\n ];\r\n\r\n const Content = [\r\n this.convertKey('file'),\r\n this.convertKey('format'),\r\n ];\r\n\r\n const { simple, ...other } = this.props;\r\n return (\r\n <div className={ this.getChildClass('log-section') }>\r\n <div className={ this.getChildClass('title') }>\r\n <RemoteSettingForm\r\n { ...other }\r\n keys={ Title }\r\n onFieldChanged={ this.onEnableStateChanged }\r\n onSettingValuesReceived={ this.onSettingsReceived }\r\n />\r\n </div>\r\n\r\n { !simple && (\r\n <div className={ this.getChildClass('content') }>\r\n <RemoteSettingForm\r\n { ...this.props }\r\n keys={ Content }\r\n onFieldSetting={ this.onContentSetting }\r\n />\r\n </div>\r\n ) }\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default LogSection;","import * as React from 'react';\r\n\r\nimport Accordion from 'components/semantic/Accordion';\r\n\r\nimport LogSection from 'routes/Settings/routes/System/components/LogSection';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface LogSectionGroupProps extends SettingSectionChildProps {\r\n sectionKeys: string[];\r\n title: string;\r\n simpleKeys?: string[];\r\n}\r\n\r\nconst LogSectionGroup: React.FC<LogSectionGroupProps> = props => {\r\n const { title, sectionKeys, simpleKeys, ...other } = props;\r\n return (\r\n <div>\r\n <div className=\"sections\">\r\n <div className=\"ui header\">\r\n { title }\r\n </div>\r\n <Accordion className=\"styled\" controlled={ true }>\r\n { sectionKeys.map(sectionKey => (\r\n <LogSection \r\n { ...other }\r\n key={ sectionKey } \r\n section={ sectionKey }\r\n simple={ !!simpleKeys && simpleKeys.indexOf(sectionKey) !== -1 }\r\n />\r\n )) }\r\n </Accordion>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default LogSectionGroup;","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport LogSectionGroup from './LogSectionGroup';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\n// Generic options\r\nconst Entry = [\r\n 'log_directory',\r\n];\r\n\r\n// Sections\r\nconst MessageSectionKeys = [\r\n 'main',\r\n 'pm',\r\n 'syslog',\r\n 'status',\r\n];\r\n\r\nconst TransferSectionKeys = [\r\n 'downloads',\r\n 'uploads',\r\n 'list_transfers',\r\n];\r\n\r\nconst SimpleSectionKeys = [\r\n 'list_transfers',\r\n];\r\n\r\nconst LoggingPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate, toI18nKey } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <div className=\"sections\">\r\n <Message\r\n icon={ IconConstants.INFO }\r\n description={\r\n <ExternalLink url={ LinkConstants.VARIABLE_HELP_URL }>\r\n <Trans i18nKey={ toI18nKey('variableHelp') }>\r\n Variable information for Filename and Format fields\r\n </Trans>\r\n </ExternalLink>\r\n }\r\n />\r\n <LogSectionGroup\r\n { ...props }\r\n sectionKeys={ MessageSectionKeys }\r\n title={ translate('Messages') }\r\n />\r\n <LogSectionGroup\r\n { ...props }\r\n sectionKeys={ TransferSectionKeys }\r\n title={ translate('Transfers') }\r\n simpleKeys={ SimpleSectionKeys }\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default LoggingPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport Message from 'components/semantic/Message';\r\nimport SystemActions from 'actions/ui/SystemActions';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst PlainEntry = [\r\n 'web_plain_port',\r\n 'web_plain_bind_address',\r\n];\r\n\r\nconst TlsEntry = [\r\n 'web_tls_port',\r\n 'web_tls_bind_address',\r\n\r\n 'web_tls_certificate_path',\r\n 'web_tls_certificate_key_path',\r\n];\r\n\r\nconst ServerSettingsPage: React.FC<SettingSectionChildProps> = props => {\r\n const { t } = props.moduleT;\r\n return (\r\n <div>\r\n {/*<Message \r\n description={ (\r\n <div>\r\n <div>\r\n New settings will take effect after restarting the management interface\r\n </div>\r\n <ActionButton \r\n action={ SystemActions.restartWeb }\r\n />\r\n </div>\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />*/}\r\n\r\n <ActionButton \r\n actions={ SystemActions }\r\n actionId=\"restartWeb\"\r\n />\r\n\r\n <div className=\"ui header\">\r\n HTTP\r\n </div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ PlainEntry }\r\n />\r\n </div>\r\n\r\n <div className=\"ui header\">\r\n HTTPS\r\n </div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ TlsEntry }\r\n />\r\n\r\n <Message \r\n description={ t<string>(\r\n 'defaultCertNote', \r\n 'The default client certificate is used if the certificate paths are empty') \r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ServerSettingsPage;","const MODULE_URL = 'web_users';\r\n\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n USERS_URL: MODULE_URL,\r\n\r\n ADDED: 'web_user_added',\r\n UPDATED: 'web_user_updated',\r\n REMOVED: 'web_user_removed',\r\n}\r\n;\r\n","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\n\r\nimport History from 'utils/History';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst isOther = (user: API.WebUser) => user.id !== LoginStore.user.id;\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<void> = ({ location }) => {\r\n History.push(`${location.pathname}/users`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.WebUser> = ({ data: user, location }) => {\r\n History.push(`${location.pathname}/users/${user.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.WebUser> = ({ data: user }) => {\r\n return SocketService.delete(`${WebUserConstants.USERS_URL}/${user.id}`);\r\n};\r\n\r\n\r\n\r\nconst WebUserCreateActions: UI.ActionListType<undefined> = {\r\n create: { \r\n displayName: 'Add user',\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate\r\n },\r\n};\r\n\r\nconst WebUserEditActions: UI.ActionListType<API.WebUser> = {\r\n edit: { \r\n displayName: 'Edit user',\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n },\r\n remove: {\r\n displayName: 'Remove user', \r\n filter: isOther,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the user {{item.username}}?',\r\n approveCaption: 'Remove user',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n },\r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'webUser',\r\n actions: WebUserCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'webUser',\r\n actions: WebUserEditActions\r\n }\r\n};\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\nimport AccessConstants from 'constants/AccessConstants';\r\nimport PermissionSelector from 'routes/Settings/routes/System/components/users/PermissionSelector';\r\n\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport Form, { FormSaveHandler, FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport '../../style.css';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { translateForm } from 'utils/FormUtils';\r\nimport { getSubModuleT } from 'utils/TranslationUtils';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst enum PermissionAction {\r\n EDIT = 'Edit',\r\n VIEW = 'View',\r\n SEND_MESSAGES = 'Send messages'\r\n}\r\n\r\ntype CaptionEntry = string | {\r\n title: string;\r\n action: PermissionAction;\r\n};\r\n\r\n\r\nconst AccessCaptions: { [key in string]: CaptionEntry } = {\r\n ADMIN: 'Administrator',\r\n\r\n SEARCH: 'Search',\r\n DOWNLOAD: 'Download',\r\n TRANSFERS: 'Transfers',\r\n\r\n EVENTS_VIEW: {\r\n title: 'Events',\r\n action: PermissionAction.VIEW,\r\n },\r\n EVENTS_EDIT: {\r\n title: 'Events',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n QUEUE_VIEW: {\r\n title: 'Queue',\r\n action: PermissionAction.VIEW,\r\n },\r\n QUEUE_EDIT: {\r\n title: 'Queue',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n FAVORITE_HUBS_VIEW: {\r\n title: 'Favorite hubs',\r\n action: PermissionAction.VIEW,\r\n },\r\n FAVORITE_HUBS_EDIT: {\r\n title: 'Favorite hubs',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n SETTINGS_VIEW: {\r\n title: 'Settings',\r\n action: PermissionAction.VIEW,\r\n },\r\n SETTINGS_EDIT: {\r\n title: 'Settings',\r\n action: PermissionAction.EDIT,\r\n },\r\n \r\n FILESYSTEM_VIEW: {\r\n title: 'Local filesystem',\r\n action: PermissionAction.VIEW,\r\n },\r\n FILESYSTEM_EDIT: {\r\n title: 'Local filesystem',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n HUBS_VIEW: {\r\n title: 'Hubs',\r\n action: PermissionAction.VIEW,\r\n },\r\n HUBS_EDIT: {\r\n title: 'Hubs',\r\n action: PermissionAction.EDIT,\r\n },\r\n HUBS_SEND: {\r\n title: 'Hubs',\r\n action: PermissionAction.SEND_MESSAGES,\r\n },\r\n\r\n PRIVATE_CHAT_VIEW: {\r\n title: 'Private chat',\r\n action: PermissionAction.VIEW,\r\n },\r\n PRIVATE_CHAT_EDIT: {\r\n title: 'Private chat',\r\n action: PermissionAction.EDIT,\r\n },\r\n PRIVATE_CHAT_SEND: {\r\n title: 'Private chat',\r\n action: PermissionAction.SEND_MESSAGES,\r\n },\r\n\r\n FILELISTS_VIEW: {\r\n title: 'Filelists',\r\n action: PermissionAction.VIEW,\r\n },\r\n FILELISTS_EDIT: {\r\n title: 'Filelists',\r\n action: PermissionAction.EDIT,\r\n },\r\n \r\n VIEW_FILE_VIEW: {\r\n title: 'Viewed files',\r\n action: PermissionAction.VIEW,\r\n },\r\n VIEW_FILE_EDIT: {\r\n title: 'Viewed files',\r\n action: PermissionAction.EDIT,\r\n },\r\n};\r\n\r\n\r\nconst reducePermissionToOption = (options: API.SettingEnumOption[], key: string, moduleT: UI.ModuleTranslator) => {\r\n const captionEntry = AccessCaptions[key];\r\n if (typeof captionEntry === 'string') {\r\n options.push({\r\n id: AccessConstants[key],\r\n name: moduleT.translate(captionEntry),\r\n });\r\n } else {\r\n options.push({\r\n id: AccessConstants[key],\r\n name: `${moduleT.translate(captionEntry.title)} (${moduleT.translate(captionEntry.action)})`,\r\n }); \r\n }\r\n\r\n return options;\r\n};\r\n\r\nconst getEntry = (isNew: boolean /*, moduleT: UI.ModuleTranslator*/): UI.FormFieldDefinition[] => {\r\n return [\r\n {\r\n key: 'username',\r\n title: 'User name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'password',\r\n type: API.SettingTypeEnum.STRING,\r\n title: isNew ? 'Password' : 'New password',\r\n optional: !isNew,\r\n },\r\n {\r\n key: 'permissions',\r\n title: 'Permissions',\r\n type: API.SettingTypeEnum.LIST,\r\n item_type: API.SettingTypeEnum.STRING,\r\n },\r\n ];\r\n};\r\n\r\ninterface WebUserDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.WebUserInput, UI.FormValueMap {\r\n\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n user: API.WebUserInput;\r\n}\r\n\r\ninterface RouteProps {\r\n userId: string;\r\n}\r\n\r\ntype Props = WebUserDialogProps & DataProps & \r\n ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass WebUserDialog extends Component<Props> {\r\n static displayName = 'WebUserDialog';\r\n\r\n\r\n entry: UI.FormFieldDefinition[];\r\n form: Form<Entry>;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n\r\n this.entry = translateForm(getEntry(this.isNew()), props.moduleT);\r\n \r\n const permissionT = getSubModuleT(props.moduleT, 'permissionSelector');\r\n const permissions = this.entry.find(def => def.key === 'permissions')!;\r\n Object.assign(permissions, {\r\n options: Object.keys(AccessConstants).reduce(\r\n (reduced, cur) => reducePermissionToOption(reduced, cur, permissionT), \r\n []\r\n )\r\n });\r\n }\r\n\r\n isNew = () => {\r\n return !this.props.user;\r\n }\r\n\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (this.isNew()) {\r\n return SocketService.post(WebUserConstants.USERS_URL, changedFields);\r\n }\r\n\r\n return SocketService.patch(`${WebUserConstants.USERS_URL}/${this.props.user.id}`, changedFields);\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'permissions') {\r\n const { user, moduleT } = this.props;\r\n fieldOptions.factory = t.form.Select;\r\n fieldOptions.template = PermissionSelector(moduleT);\r\n fieldOptions.disabled = !this.isNew() && user.username === LoginStore.user.username;\r\n } else if (id === 'password') {\r\n fieldOptions.type = 'password';\r\n } else if (id === 'username') {\r\n fieldOptions.disabled = !this.isNew();\r\n }\r\n }\r\n\r\n render() {\r\n const { user, moduleT, ...other } = this.props;\r\n const title = moduleT.translate(this.isNew() ? 'Add web user' : 'Edit user');\r\n\r\n return (\r\n <Modal \r\n className=\"web-user\" \r\n title={ title } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.USER }\r\n { ...other }\r\n >\r\n <Form<Entry>\r\n ref={ (c: any) => this.form = c! }\r\n fieldDefinitions={ this.entry }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSave={ this.onSave }\r\n sourceValue={ this.props.user as Entry }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<WebUserDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(WebUserDialog, {\r\n urls: {\r\n user: ({ match }, socket) => {\r\n if (!match.params.userId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${WebUserConstants.USERS_URL}/${match.params.userId}`);\r\n },\r\n },\r\n }),\r\n 'users/:userId?'\r\n);","import t from 'utils/tcomb-form';\r\n\r\nimport Checkbox from 'components/semantic/Checkbox';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { updateMultiselectValues } from 'utils/FormUtils';\r\n\r\n\r\ntype AccessOptionType = {\r\n value: API.AccessEnum;\r\n text: string;\r\n};\r\n\r\nconst PermissionSelector = (moduleT: UI.ModuleTranslator) => {\r\n return t.form.Form.templates.select.clone({\r\n renderSelect: (locals: UI.FormLocals<AccessOptionType, API.AccessEnum[]>) => {\r\n const onChange = (access: API.AccessEnum, checked: boolean) => {\r\n locals.onChange(\r\n updateMultiselectValues(locals.value, access, checked)\r\n );\r\n };\r\n\r\n const mapPermission = ({ value, text }: UI.FormOption<API.AccessEnum>) => (\r\n <Checkbox \r\n key={ value }\r\n className={ value }\r\n checked={ locals.value.indexOf(value) !== -1 } \r\n onChange={ checked => onChange(value, checked) }\r\n caption={ text }\r\n />\r\n );\r\n\r\n const filterPermission = ({ value }: UI.FormOption<API.AccessEnum>) => {\r\n if (locals.value.indexOf(API.AccessEnum.ADMIN) !== -1 && value !== API.AccessEnum.ADMIN) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const permissions = locals.options\r\n .filter(filterPermission)\r\n .map(mapPermission);\r\n\r\n return (\r\n <div className=\"permission-select\">\r\n <Message \r\n description={ moduleT.t<string>(\r\n 'adminPermissionNote',\r\n 'Administrator permission is required in order to access the System section in settings'\r\n ) }\r\n className=\"small\"\r\n />\r\n { permissions }\r\n </div>\r\n );\r\n }\r\n });\r\n};\r\n\r\n\r\nexport default PermissionSelector;\r\n","import * as React from 'react';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\nimport WebUserActions from 'actions/ui/WebUserActions';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport WebUserDialog from 'routes/Settings/routes/System/components/users/WebUserDialog';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/menu';\r\nimport { formatRelativeTime } from 'utils/ValueFormat';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface WebUserRowProps {\r\n user: API.WebUser;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst WebUserRow: React.FC<WebUserRowProps> = ({ user, moduleT }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ user.username }</strong> }\r\n actions={ WebUserActions.edit } \r\n itemData={ user }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"permissions\">\r\n { user.permissions.indexOf(API.AccessEnum.ADMIN) !== -1 ? \r\n moduleT.translate('Administrator') : \r\n user.permissions.length\r\n }\r\n </td>\r\n <td className=\"sessions\">\r\n { user.active_sessions }\r\n </td>\r\n <td className=\"last-login\">\r\n { formatRelativeTime(user.last_login) }\r\n </td>\r\n </tr>\r\n);\r\n\r\ninterface WebUsersPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\ninterface WebUsersPageDataProps extends DataProviderDecoratorChildProps {\r\n users: API.WebUser[];\r\n}\r\n\r\nclass WebUsersPage extends React.Component<WebUsersPageProps & WebUsersPageDataProps> {\r\n static displayName = 'WebUsersPage';\r\n\r\n render() {\r\n const { users, moduleT } = this.props;\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <ActionButton \r\n actions={ WebUserActions.create }\r\n actionId=\"create\"\r\n />\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('Username') }</th>\r\n <th>{ translate('Permissions') }</th>\r\n <th>{ translate('Active sessions') }</th>\r\n <th>{ translate('Last logged in') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { users.map(user => (\r\n <WebUserRow \r\n key={ user.username }\r\n user={ user }\r\n moduleT={ moduleT }\r\n />\r\n )) }\r\n </tbody>\r\n </table>\r\n <WebUserDialog\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator(WebUsersPage, {\r\n urls: {\r\n users: WebUserConstants.USERS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.ADDED, () => refetchData());\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.UPDATED, () => refetchData());\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.REMOVED, () => refetchData());\r\n },\r\n});","const AccessConstants = require('constants/AccessConstants').default;\r\n\r\nmodule.exports = {\r\n url: 'system',\r\n title: 'System',\r\n icon: 'settings',\r\n access: AccessConstants.ADMIN,\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'Users', \r\n url: 'users', \r\n noSave: true,\r\n component: require('./components/WebUsersPage').default,\r\n }, { \r\n title: 'Logging', \r\n url: 'logging',\r\n component: require('./components/LoggingPage').default,\r\n }, { \r\n title: 'Web server', \r\n url: 'server-settings',\r\n component: require('./components/ServerSettingsPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Advanced server settings', \r\n url: 'advanced-server-settings',\r\n component: require('./components/AdvancedServerSettingsPage').default, \r\n }\r\n ],\r\n};\r\n\r\n","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'use_main_chat_notify',\r\n 'show_joins',\r\n 'format_release_names'\r\n];\r\n\r\nconst GeneralPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default GeneralPage;","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'report_uploads',\r\n 'report_downloads',\r\n 'report_search_alternates',\r\n 'report_added_sources',\r\n 'report_blocked_share',\r\n 'report_hashed_files',\r\n 'report_scheduled_refreshes',\r\n 'report_filelist_dupes',\r\n];\r\n\r\nconst EventPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default EventPage;","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'history_search_max',\r\n 'history_download_max',\r\n 'history_chat_log_lines',\r\n];\r\n\r\nconst MessageEntry = [\r\n 'history_hub_messages',\r\n 'history_pm_messages',\r\n 'history_log_messages',\r\n];\r\n\r\nconst SessionEntry = [\r\n 'history_hub_sessions',\r\n 'history_pm_sessions',\r\n 'history_filelist_sessions',\r\n];\r\n\r\nconst HistoryPage: React.FC<SettingSectionChildProps> = props => {\r\n const { t } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n title={ t('maxMessageHistory', 'Maximum number of messages to cache') }\r\n { ...props }\r\n keys={ MessageEntry }\r\n />\r\n <RemoteSettingForm\r\n title={ t('maxSessionHistory', 'Maximum number of previously opened sessions') }\r\n { ...props }\r\n keys={ SessionEntry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default HistoryPage;","import * as React from 'react';\r\n\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport LocalSettingForm from 'routes/Settings/components/LocalSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n LocalSettings.UNREAD_LABEL_DELAY,\r\n LocalSettings.BACKGROUND_IMAGE_URL,\r\n LocalSettings.NO_INSTALL_PROMPT,\r\n];\r\n\r\nconst MiscellaneousPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <LocalSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default MiscellaneousPage;","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport LocalSettingForm from 'routes/Settings/components/LocalSettingForm';\r\n\r\nimport '../style.css';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst PopupEntry = [\r\n LocalSettings.NOTIFY_MENTION,\r\n LocalSettings.NOTIFY_PM_USER,\r\n LocalSettings.NOTIFY_PM_BOT,\r\n LocalSettings.NOTIFY_HUB_MESSAGE,\r\n\r\n LocalSettings.NOTIFY_BUNDLE_STATUS,\r\n\r\n LocalSettings.NOTIFY_EVENTS_INFO,\r\n LocalSettings.NOTIFY_EVENTS_WARNING,\r\n LocalSettings.NOTIFY_EVENTS_ERROR,\r\n];\r\n\r\nconst NotificationPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <LocalSettingForm\r\n title={ translate('Popup notifications') }\r\n { ...props }\r\n keys={ PopupEntry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default NotificationPage;","module.exports = {\r\n url: 'view',\r\n title: 'View',\r\n icon: 'browser',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Notifications', \r\n url: 'notifications',\r\n local: true,\r\n component: require('./components/NotificationPage').default, \r\n }, { \r\n title: 'Histories', \r\n url: 'histories',\r\n component: require('./components/HistoryPage').default, \r\n }, { \r\n title: 'Events', \r\n url: 'events',\r\n component: require('./components/EventPage').default, \r\n }, { \r\n title: 'Appearance', \r\n url: 'appearance',\r\n component: require('./components/AppearancePage').default, \r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Miscellaneous', \r\n url: 'miscellaneous',\r\n local: true,\r\n component: require('./components/MiscellaneousPage').default, \r\n },\r\n ],\r\n};","import LoginStore from 'stores/LoginStore';\r\nimport { fetchData } from 'utils/HttpUtils';\r\n\r\n\r\nexport const uploadTempFile = async (file: File): Promise<string> => {\r\n try {\r\n const res = await fetchData(`${getBasePath()}temp`, {\r\n method: 'POST',\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': LoginStore.authToken,\r\n \r\n 'Authorization': LoginStore.authToken,\r\n },\r\n body: file\r\n });\r\n\r\n return res.headers.get('Location')!;\r\n } catch (e) {\r\n throw e;\r\n }\r\n};\r\n\r\nconst toCorsSafeUrl = (url: string) => {\r\n const proxyUrl = `${window.location.origin}${getBasePath()}proxy?url=${encodeURIComponent(url)}`;\r\n return proxyUrl;\r\n};\r\n\r\nexport const fetchCorsSafeData = async (url: string, isJSON: boolean, options?: RequestInit) => {\r\n try {\r\n //console.log(`CORS HTTP request started (${url})`);\r\n\r\n const res = await fetchData(\r\n toCorsSafeUrl(url), \r\n {\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': LoginStore.authToken,\r\n\r\n // Temp workaround for people upgrading from versions < 2.7.0\r\n // If the new UI was loaded before restarting the app, a cache expiration time of \r\n // one year would have been set for \"Not found\" errors...\r\n 'Cache-Control': 'no-store, must-revalidate, max-age=0'\r\n },\r\n ...options,\r\n }\r\n );\r\n\r\n const data = await isJSON ? res.json() : res.text();\r\n return data;\r\n } catch (e) {\r\n console.error(`CORS HTTP request failed (${url})`, e);\r\n throw e;\r\n }\r\n};\r\n"],"names":["compareVersions","v1","v2","n1","validateAndParse","n2","p1","pop","p2","r","compareSegments","split","semver","version","TypeError","match","Error","shift","isWildcard","s","tryParse","v","n","parseInt","isNaN","compareStrings","a","b","ap","bp","String","forceType","i","Math","max","length","Object","keys","___CSS_LOADER_EXPORT___","push","module","id","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","isManaged","extension","managed","isRunning","running","downloadExtension","url","installId","shasum","install_id","handleNpmAction","data","npmPackage","name","tarball","dist","ExtensionInstallActions","installUrl","displayName","icon","access","input","approveCaption","content","inputProps","placeholder","type","required","handler","ExtensionNpmActions","installNpm","updateNpm","ExtensionManageActions","start","filter","ext","stop","configure","has_settings","location","pathname","divider","remove","confirmation","rejectCaption","install","moduleId","actions","npm","manage","ShareActions","refresh","SystemActions","restartWeb","shutdown","subId","alwaysShow","localSettings","prompt","useContext","t","title","description","className","caption","onClick","formatText","text","i18nKey","Row","titleWidth","noText","style","overflow","Header","Grid","children","columns","stackable","other","MODULE_URL","NPM_URL","EXTENSIONS_URL","DOWNLOAD_URL","ENGINES_URL","ENGINES_STATUS_URL","DEFAULT_ENGINE","STARTED","STOPPED","ADDED","REMOVED","UPDATED","INSTALLATION_STARTED","INSTALLATION_SUCCEEDED","INSTALLATION_FAILED","NPM_PACKAGES_URL","NPM_PACKAGE_URL","NPM_HOMEPAGE_URL","GROUPED_DIRECTORIES_URL","DIRECTORIES_URL","DIRECTORIES_UPDATED","PROFILES_URL","PROFILE_ADDED","PROFILE_UPDATED","PROFILE_REMOVED","HIDDEN_PROFILE_ID","profileToEnumValue","profile","str","Component","listHidden","dataProviderDecoratorSettings","addSize","merge","urls","profiles","dataConverters","p","map","size","convertProfile","onSocketConnected","addSocketListener","refetchData","fetchUrl","unavailableMessage","fetchIntervalSeconds","Decorator","state","stats","fetchStats","then","this","onStatsReceived","catch","error","console","message","fetchTimeout","window","setTimeout","setState","componentDidMount","componentWillUnmount","clearTimeout","render","props","assign","undefined","LocalSettingForm","constructor","super","onSave","changedSettingArray","allFields","settings","Promise","resolve","onFieldChanged","value","hasChanges","saveContext","definitions","moduleT","ref","f","addFormRef","fieldDefinitions","sourceValue","sectionToUrl","section","parent","translateSettingSectionTitle","settingsT","translate","menuItemToLinkComponent","menuItemInfo","debugOnly","menuItems","indexOf","menuItemsToRouteComponentArray","currentMenuItem","item","path","component","advancedMenuItems","parentMenuItems","camelCase","findMenuItem","find","isItemActive","RemoteSettingForm","changedValues","refetchValues","otherProps","onSettingValuesReceived","valueMode","value_mode","SideChildSectionMenu","TopRootSectionMenu","Content","contentClassname","saveButton","LayoutHeader","Icon","color","rightComponent","TopSectionSelectionMenu","Dropdown","selection","captionIcon","SectionedDropdown","MenuSection","SettingsMenuDecorator","SaveDecorator","innerWidth","SettingsTopMenuLayout","SettingsSideMenuLayout","childProps","SaveButton","saving","toggleSaveState","saveHandler","local","hasAccess","LoginStore","Button","loading","disabled","propTypes","SaveDecoratorContext","withSaveContext","Consumer","context","getFormId","join","forms","changedProperties","Set","onSettingsChanged","add","delete","forceUpdate","onSettingsSaved","NotificationActions","handleSave","promises","values","c","save","clear","all","promptSave","nextLocation","noSave","hasOwnProperty","getFormRef","componentDidUpdate","prevProps","Message","IconConstants","Provider","to","menu","MainLayout","Settings","withTranslation","systemInfo","buildDate","client_version","api_version","api_feature_level","client_started","active_sessions","server_threads","total_users","unique_users","active_users","total_share","plainT","adc_down_per_user","adc_up_per_user","clients","formatClientRow","uniqueUsers","client","count","total_size","defaultValue","replace","totalCount","total_file_count","uniqueCount","unique_file_count","total_directory_count","average_file_age","total_searches","perSecondCount","total_searches_per_second","toFixed","tth_searches","recursive_searches","matchedCount","unfiltered_recursive_searches_per_second","filteredPercentage","filtered_searches","resultPercentage","recursive_searches_responded","tokenCount","average_search_token_count","tokenLength","average_search_token_length","matchTime","average_match_ms","totalUp","session_uploaded","start_total_uploaded","totalDown","session_downloaded","start_total_downloaded","AccessConstants","exports","TRANSFERS","HUBS_VIEW","DETECT_URL","STATUS_URL","CONNECTIVITY_MESSAGE","CONNECTIVITY_STARTED","CONNECTIVITY_FINISHED","ConnectivityActions","detect","SocketService","ConnectivityConstants","formatStatus","protocolStatus","auto","auto_detect","status","DataProviderDecorator","runningV4","runningV6","status_v4","status_v6","ActionButton","actionId","mergeData","setDetectState","v6","toI18nKey","Trans","ExternalLink","LinkConstants","Entry","protocol","onFieldSetting","fieldOptions","formValue","help","ProtocolPage","autoDetectEnabled","convertValue","key","protocolEnabled","autoDetect","outgoing_mode","SegmentsEntry","BufferEntry","CompressionEntry","FavoriteDirectoryCreateActions","create","History","FavoriteDirectoryEditActions","edit","directory","FavoriteDirectoryConstants","FavoriteDirectoryDialog","isNew","directoryEntry","form","changedFields","config","historyId","FilesystemConstants","factory","template","suggestionGetter","virtualNames","Modal","onApprove","closable","Form","ModalRouteDecorator","socket","params","directoryId","get","FavoriteDirectoryActions","itemData","contextElement","getRow","directories","FavoriteDirectoryTable","HighPrioEntry","SearchTypeCreateActions","SearchTypeEditActions","default_type","SearchConstants","item_type","SearchTypeDialog","searchTypeEntry","searchTypeId","SearchTypeActions","extensions","searchTypes","Skiplist","enginesStatus","loaderText","packageCatalog","installedPackages","installedPackage","Extension","getItem","package","ExtensionConstants","objects","refetchInstalled","EngineStatusMessage","ExtensionActions","ExtensionsConfigureDialog","getSettingsUrl","extensionId","dynamicHeight","convertNpmPackage","_npmUser","publisher","username","date","dataError","npmError","private","renderOnError","InstallButton","hasUpdate","installing","ids","remoteMenuId","MenuConstants","button","menuElementClassName","Version","packageInfo","versionDesc","from","formatAuthor","author","formatNote","onInstallationStarted","onInstallationCompleted","ExtensionIcon","SocketSubscriptionDecorator","getCornerIcon","cornerIcon","ignoreInfo","userIcon","user","ignored_messages","cid","ignores","profileId","toString","ShareExcludeCreateActions","ShareExcludeEditActions","ShareConstants","ShareExcludeActions","ExcludePage","excludes","onConfirm","initialPath","subHeader","selectMode","OptimizeLayout","startHandler","verify","setVerify","marginTop","Checkbox","checked","onChange","floating","HashDatabaseLayout","handleOptimize","HashConstants","file_index_size","hash_store_size","maintenance_running","notDefault","default","ShareProfileCreateActions","ShareProfileConstants","ShareProfileEditActions","browse","FilelistSessionActions","FilelistSessionStore","ShareProfileRow","ShareProfileActions","files","ShareProfileDecorator","AutoValuePanel","getAutoKey","changedKey","autoSettingKey","settingKey","Auto","Manual","Generic","Hooks","LogSection","enabled","convertKey","suffix","onSettingsReceived","onEnableStateChanged","onContentSetting","getChildClass","Title","simple","sectionKeys","simpleKeys","Accordion","controlled","sectionKey","MessageSectionKeys","TransferSectionKeys","SimpleSectionKeys","PlainEntry","TlsEntry","WebUserCreateActions","WebUserEditActions","WebUserConstants","PermissionAction","AccessCaptions","ADMIN","SEARCH","DOWNLOAD","EVENTS_VIEW","action","VIEW","EVENTS_EDIT","EDIT","QUEUE_VIEW","QUEUE_EDIT","FAVORITE_HUBS_VIEW","FAVORITE_HUBS_EDIT","SETTINGS_VIEW","SETTINGS_EDIT","FILESYSTEM_VIEW","FILESYSTEM_EDIT","HUBS_EDIT","HUBS_SEND","SEND_MESSAGES","PRIVATE_CHAT_VIEW","PRIVATE_CHAT_EDIT","PRIVATE_CHAT_SEND","FILELISTS_VIEW","FILELISTS_EDIT","VIEW_FILE_VIEW","VIEW_FILE_EDIT","WebUserDialog","renderSelect","locals","permissions","entry","optional","permissionT","def","reduce","reduced","cur","captionEntry","reducePermissionToOption","userId","WebUserRow","WebUserActions","last_login","WebUsersPage","users","MessageEntry","SessionEntry","PopupEntry","uploadTempFile","file","getBasePath","method","headers","body","e","fetchCorsSafeData","isJSON","res","origin","encodeURIComponent","toCorsSafeUrl","json"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"js/settings.7aeffada3e24ba15d447.chunk.js","mappings":"gIAOO,MAAMA,EAAkB,CAACC,EAAIC,KAEhC,MAAMC,EAAKC,EAAiBH,GACtBI,EAAKD,EAAiBF,GAEtBI,EAAKH,EAAGI,MACRC,EAAKH,EAAGE,MAERE,EAAIC,EAAgBP,EAAIE,GAC9B,OAAU,IAANI,EACOA,EAEPH,GAAME,EACCE,EAAgBJ,EAAGK,MAAM,KAAMH,EAAGG,MAAM,MAE1CL,GAAME,EACJF,GAAM,EAAI,EAEd,CAAC,EAyENM,EAAS,6IACTR,EAAoBS,IACtB,GAAuB,iBAAZA,EACP,MAAM,IAAIC,UAAU,oCAExB,MAAMC,EAAQF,EAAQE,MAAMH,GAC5B,IAAKG,EACD,MAAM,IAAIC,MAAM,uCAAuCH,gBAG3D,OADAE,EAAME,QACCF,CAAK,EAEVG,EAAcC,GAAY,MAANA,GAAmB,MAANA,GAAmB,MAANA,EAC9CC,EAAYC,IACd,MAAMC,EAAIC,SAASF,EAAG,IACtB,OAAOG,MAAMF,GAAKD,EAAIC,CAAC,EAGrBG,EAAiB,CAACC,EAAGC,KACvB,GAAIT,EAAWQ,IAAMR,EAAWS,GAC5B,OAAO,EACX,MAAOC,EAAIC,GAJG,EAACH,EAAGC,WAAaD,UAAaC,EAAI,CAACG,OAAOJ,GAAII,OAAOH,IAAM,CAACD,EAAGC,GAI5DI,CAAUX,EAASM,GAAIN,EAASO,IACjD,OAAIC,EAAKC,EACE,EACPD,EAAKC,GACG,EACL,CAAC,EAENnB,EAAkB,CAACgB,EAAGC,KACxB,IAAK,IAAIK,EAAI,EAAGA,EAAIC,KAAKC,IAAIR,EAAES,OAAQR,EAAEQ,QAASH,IAAK,CACnD,MAAMvB,EAAIgB,EAAeC,EAAEM,IAAM,IAAKL,EAAEK,IAAM,KAC9C,GAAU,IAANvB,EACA,OAAOA,CACf,CACA,OAAO,CAAC,EASa2B,OAAOC,KAPT,CACnB,IAAK,CAAC,GACN,KAAM,CAAC,EAAG,GACV,IAAK,CAAC,GACN,KAAM,EAAE,EAAG,GACX,IAAK,EAAE,I,mFCxIPC,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,+qPAA8rP,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,oEAAoE,MAAQ,GAAG,SAAW,69FAA69F,eAAiB,CAAC,grPAA8rP,WAAa,MAEthlB,S,mFCJIH,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,sUAAuU,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,iEAAiE,MAAQ,GAAG,SAAW,8GAA8G,eAAiB,CAAC,uUAAuU,WAAa,MAEt7B,S,mFCJIH,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,kGAAmG,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,4DAA4D,MAAQ,GAAG,SAAW,yBAAyB,eAAiB,CAAC,mGAAmG,WAAa,MAEpZ,S,mFCJIH,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,kPAAmP,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,4DAA4D,MAAQ,GAAG,SAAW,yEAAyE,eAAiB,CAAC,mPAAmP,WAAa,MAEpuB,S,mFCJIH,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,kXAAmX,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,2DAA2D,MAAQ,GAAG,SAAW,sHAAsH,eAAiB,CAAC,mXAAmX,WAAa,MAEhhC,S,mFCJIH,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,+FAAgG,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,yDAAyD,MAAQ,GAAG,SAAW,yBAAyB,eAAiB,CAAC,gGAAgG,WAAa,MAE3Y,S,mFCJIH,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,m0DAAo0D,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,6CAA6C,MAAQ,GAAG,SAAW,qnBAAqnB,eAAiB,CAAC,o0DAAo0D,WAAa,MAEn6I,S,oKCIIC,EAAU,CAAC,EAEfA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,U,oKCf9CA,EAAU,CAAC,EAEfA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,U,oKCf9CA,EAAU,CAAC,EAEfA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,U,+HCblD,MAAMM,EAAaC,GAA6BA,EAAUC,QACpDC,EAAaF,GAA6BA,EAAUG,QAgBpDC,EAAoB,CAACC,EAAaC,EAAoBC,IACnD,SAAmB,iBAAiC,CACzDC,WAAYF,GAAwBD,EACpCA,MACAE,WAIEE,EACJ,IACG,O,OAAD,E,OAAA,E,EAAA,Y,IADAC,KAAMC,GAAU,G,iUAAU,GAA5B,UAEA,MAAMD,QAAa,OAAkB,oBAAqCC,EAAWC,KAAO,WAAW,IAEjG,QAAEC,EAAO,OAAEN,GAAWG,EAAKI,KAEjC,OAAOV,EAAkBS,EAASF,EAAWC,KAAML,EACrD,E,YANI,K,6QAMH,EAeKQ,EAAwD,CAC5DC,WAAY,CACVC,YAAa,mBACbC,KAAM,WACNC,OAAQ,WACRC,MAAO,CACLC,eAAgB,UAChBC,QAAS,qBACTC,WAAY,CACVC,YAAa,YACbC,KAAM,MACNC,UAAU,IAGdC,QA3BkD,EAClDjB,QAAQL,IAEHD,EAAkBC,KA6BrBuB,EAAwD,CAC5DC,WAAY,CACVZ,YAAa,UACbC,KAAM,WACNC,OAAQ,WACRQ,QAASlB,GAEXqB,UAAW,CACTb,YAAa,SACbC,KAAM,oBACNC,OAAQ,WACRQ,QAASlB,IAIPsB,EAA2D,CAC/DC,MAAO,CACLf,YAAa,QACbC,KAAM,SACNe,OAAQC,GAAOnC,EAAUmC,KAAShC,EAAUgC,GAC5Cf,OAAQ,WACRQ,QA/EiD,EAAGjB,KAAMV,KACrD,SAAmB,GAAG,sBAAqCA,EAAUY,eAgF5EuB,KAAM,CACJlB,YAAa,OACbC,KAAM,SACNe,OAAQC,GAAOnC,EAAUmC,IAAQhC,EAAUgC,GAC3Cf,OAAQ,WACRQ,QAlFgD,EAAGjB,KAAMV,KACpD,SAAmB,GAAG,sBAAqCA,EAAUY,cAmF5EwB,UAAW,CACTnB,YAAa,YACbC,KAAM,SACNe,OAlGiBjC,GAA6BA,EAAUqC,aAmGxDlB,OAAQ,mBACRQ,QAjGqD,EAAGjB,KAAMV,EAAWsC,eAC3E,SAAa,GAAGA,EAASC,uBAAuBvC,EAAUR,KAAK,GAkG/DgD,QAAS,KACTC,OAAQ,CACNxB,YAAa,YACbC,KAAM,WACNe,OAAQlC,EACRoB,OAAQ,WACRuB,aAAc,CAEZpB,QAAS,gIACTD,eAAgB,mBAChBsB,cAAe,gBAEjBhB,QA3EkD,EAClDjB,UAEK,WAAqB,mBAAoC,IAAMA,EAAKE,QA6E7E,GACEgC,QAAS,CACPC,SAAU,gBACVC,QAAS/B,GAEXgC,IAAK,CACHF,SAAU,gBACVC,QAASlB,GAEXoB,OAAQ,CACNH,SAAU,gBACVC,QAASf,G,wGCvIb,MAKMkB,EAA6C,CACjDC,QAAS,CACPjC,YAAa,cACbE,OAAQ,mBACRD,KAAM,oBACNS,QAVkB,IACb,SAAmB,mBAa5B,GACEkB,SAAU,WACVC,QAASG,E,yGCjBX,MAUME,EAA8C,CAClDC,WAAY,CACVnC,YAAa,qBACbE,OAAQ,WACRD,KAAM,oBACNwB,aAAc,CACZpB,QAAS,wdAKTD,eAAgB,uBAChBsB,cAAe,iBAEjBhB,QAxBqB,IAChB,SAAmB,eAA6B,iBAyBvD0B,SAAU,CACRpC,YAAa,wBACbE,OAAQ,WACRD,KAAM,UACNwB,aAAc,CACZpB,QAAS,2DACTD,eAAgB,yBAChBsB,cAAe,UAEjBhB,QA/BmB,IACd,SAAmB,eAA6B,eAmCzD,GACEkB,SAAU,YACVS,MAAO,SACPR,QAASK,E,uLC5BX,MAyCA,EAzCoD,EAAGI,iBACrD,MAAMC,GAAgB,OAA0B,KAC1CC,GAAS,IAAAC,YAAW,MACpB,EAAEC,IAAM,SACd,OAAKF,GAIAF,GAAgBC,EAAc,wBAC1B,MAIP,SAAC,IAAO,CACNI,OAAQ,QAAU,+BAAgCD,EAAG,aACrDE,aACE,+BAAKC,UAAU,kBAAgB,YAC7B,uBACIH,GACA,QAAU,iBAAkB,aAC5B,wFAGJ,SAAC,IAAM,CACLG,UAAU,UACVC,SAAU,QAAU,UAAWJ,EAAG,aAClCK,QAAU,IAAMP,IAChBvC,KAAO,cAENqC,IACD,SAAC,IAAM,CACLQ,SAAU,QAAU,gBAAiBJ,EAAG,aACxCK,QAAU,IAAM,aAA2B,wBAAiC,WA3B/E,IAiCR,C,iJC1CH,MAAMC,EAAcC,GACZA,IAKJ,SAAC,IAAK,eACJC,SAAU,QAAU,KAAM,cAAkB,mBAOrCC,EAA0B,EAAGR,QAAOM,OAAMJ,YAAWO,aAAa,OAAQC,aACrF,+BAAKR,UAAY,IAAW,SAAUA,IAAU,YAC9C,8BAAKA,UAAY,IAAWQ,EAAS,UAAYD,EAAY,sBAAoB,WAC/E,8BAAKP,UAAU,iBAAiBS,MAAO,CAAEC,SAAU,WAAU,UACzDZ,SAGHU,IACD,8BAAKR,UAAU,gBAAc,UACzBG,EAAWC,UAURO,EAAgC,EAAGb,YAC9C,8BAAKE,UAAU,UAAQ,WACrB,8BAAKA,UAAU,uBAAqB,WAClC,8BAAKA,UAAU,0BAAwB,UACnCF,WAWGc,EAA6B,I,IAAA,UAAEZ,EAAS,SAAEa,EAAQ,QAAEC,EAAO,UAAEC,GAAS,EAAKC,E,yUAAK,GAAnD,gDAA0D,OAClG,8BACEhB,UAAY,IACV,UAEA,CAAE,CAAC,GAAGc,cAAqBA,GAC3B,CAAEC,UAAWA,GACbf,IAEGgB,EAAK,UAERH,IAEL,C,gDCjFD,MAAMI,EAAa,aAEbC,EAAU,8BAEhB,GACED,WAAYA,EACZE,eAAgBF,EAChBG,aAAcH,EAAa,YAE3BI,YAAaJ,EAAa,WAC1BK,mBAAoBL,EAAa,kBAEjCM,eAAgB,OAEhBC,QAAS,oBACTC,QAAS,oBAETC,MAAO,kBACPC,QAAS,oBACTC,QAAS,oBAETC,qBAAsB,iCACtBC,uBAAwB,mCACxBC,oBAAqB,gCAErBC,iBAAkBd,EAAU,+DAC5Be,gBAAiBf,EACjBgB,iBAAkB,iC,+CC3BpB,MAAMjB,EAAa,uBACnB,GACEA,WAAYA,EAEZkB,wBAAyBlB,EAAa,iBACtCmB,gBAAiBnB,EAEjBoB,oBAAqB,+B,gDCPvB,MAAMpB,EAAa,iBACnB,GACEA,WAAYA,EACZqB,aAAcrB,EAEdsB,cAAe,sBACfC,gBAAiB,wBACjBC,gBAAiB,wBAEjBC,kBAAmB,E,uGCUd,MAAMC,EAAsBC,IAC1B,CACLlH,GAAIkH,EAAQlH,GACZoB,KAAM8F,EAAQC,MAkDlB,EA5C8B,SAC5BC,EACAC,EACAC,EACAC,GAAU,GAsBV,OAAO,OACLH,GACA,IAAAI,OAAMF,EAA+B,CACnCG,KAAM,CACJC,SAAU,kBAEZC,eAAgB,CACdD,SAfyC,CAACxG,GAA4BiD,QAC1E,MAAMuD,EAAWxG,EACduB,QAAOmF,GAAKP,GAAcO,EAAE5H,KAAO,wBACnC6H,KAAID,GAfc,EAACV,EAA2B/C,KACjD,IAAIgD,EAAMD,EAAQC,IAKlB,OAJII,GAAWL,EAAQlH,KAAO,wBAC5BmH,GAAO,MAAK,QAAWD,EAAQY,KAAM3D,OAGhC,OAAP,wBACK+C,GAAO,CACVC,OAAG,EAOOY,CAAeH,EAAGzD,KAE9B,OAAOuD,CAAQ,GAYbM,kBAAmB,CAACC,GAAqBC,kBACvCD,EAAkB,eAAkC,mBAAqC,IAAMC,MAC/FD,EAAkB,eAAkC,qBAAuC,IAAMC,MACjGD,EAAkB,eAAkC,qBAAuC,IAAMC,KAAc,IAIvH,C,8HCjDA,MAwEA,EAxE4B,SAC1Bd,EACAe,EACAC,EACAC,EAAuB,GAEvB,MAAMC,UAAkB,YAAxB,c,oBACE,KAAAC,MAAQ,CACNC,MAAO,MAaT,KAAAC,WAAa,KACX,QAAkBN,GACfO,KAAKC,KAAKC,iBACVC,OAAOC,GAAyBC,QAAQD,MAAM,wBAAyBA,EAAME,WAE5EX,EAAuB,IACzBM,KAAKM,aAAeC,OAAOC,WAAWR,KAAKF,WAAmC,IAAvBJ,G,EAI3D,KAAAO,gBAAmB1H,IACjByH,KAAKS,SAAS,CACZZ,MAAOtH,GACP,CAiCN,CAtDEmI,oBACEV,KAAKF,YACP,CAEAa,uBACEJ,OAAOK,aAAaZ,KAAKM,aAC3B,CAkBAO,SACE,MAAM,MAAEhB,GAAUG,KAAKJ,MACvB,OAAc,OAAVC,EACK,MAGLG,KAAKc,MAAMjB,OACb7I,OAAO+J,OAAOlB,EAAOG,KAAKc,MAAMjB,YAGpBmB,IAAVnB,GAEA,SAAC,IAAW,UACRrE,IACA,SAAC,IAAO,CACNC,OAAQ,QAAU,2BAA4BD,EAAG,aACjDE,YAAe+D,EAAiCA,EAAmBjE,EAAGwE,KAAKc,YAAvCE,OAQ5C,SAACvC,EAAS,iBACHuB,KAAKc,MAAK,CACfjB,MAAQA,KAGd,EAGF,OAAOF,CACT,C,sHCpEA,MAAMsB,UAAyB,EAAAxC,UAW7ByC,YAAYJ,GACVK,MAAML,GASR,KAAAM,OAA2C,CAACC,EAAqBC,KAC/D,cAA4BD,GAE5BrB,KAAKS,SAAS,CACZc,SAAU,kBAGLC,QAAQC,WAGjB,KAAAC,eAAyC,CAACrK,EAAIsK,EAAOC,KACnD,MAAM,YAAEC,EAAW,eAAEH,GAAmB1B,KAAKc,MAE7C,GADAe,EAAYH,eAAerK,EAAIsK,EAAOC,GAClCF,EACF,OAAOA,EAAerK,EAAIsK,EAAOC,E,EArBnC5B,KAAK8B,aAAc,QAAc,mBAAiChB,EAAM7J,MAAO6J,EAAMiB,SAErF/B,KAAKJ,MAAQ,CACX2B,SAAU,gBAEd,CAoBAV,SACE,MAAM,SAAEU,GAAavB,KAAKJ,MACpB,EAAkCI,KAAKc,OAAvC,YAAEe,EAAW,KAAE5K,GAAI,EAAK0F,E,yUAAK,GAA7B,wBACN,OACE,8BAAKhB,UAAU,sBAAoB,WACjC,SAAC,IAAI,iBACEgB,EAAK,CACVqF,IAAMC,GAAKJ,EAAYK,WAAWjL,EAAMgL,GACxCb,OAASpB,KAAKoB,OACde,iBAAmBnC,KAAK8B,YACxBM,YAAcb,EACdG,eAAiB1B,KAAK0B,oBAI9B,EAGF,SAAe,QAAgBT,E,oKCrExB,MAAMoB,EAAe,CAACC,EAAsBC,IAC3B,iBAAXA,EACF,aAAaA,EAAOrK,OAAOoK,EAAQpK,MAGrC,aAAaoK,EAAQpK,MAGjBsK,EAA+B,CAAC/G,EAAegH,IACnDA,EAAUC,UAAUjH,EAAO,CAAE,kBAGzBkH,EAA0B,CACrCC,EACAL,EACAE,EACAtI,KAEA,GAAIyI,EAAaC,UACf,OAAO,KAGT,GAAID,EAAa5J,SAAW,cAAqB4J,EAAa5J,QAC5D,OAAO,KAGT,IAAId,EAAMmK,EAAaO,EAAcL,GAQrC,OAJIK,EAAaE,WAAgD,IAAnC3I,EAASC,SAAS2I,QAAQ7K,KACtDA,EAAMmK,EAAaO,EAAaE,UAAU,GAAIF,KAI9C,SAAC,IAAkB,eAEjB1K,IAAMA,EACNa,KAAS6J,EAAa7J,KAAO,SAAS6J,EAAa7J,OAAS,MAAI,UAE9DyJ,EAA6BI,EAAanH,MAAOgH,KAJ7CvK,EAMT,EAGU8K,EAAiC,CAC5CC,EACAH,EACAL,EACAV,EACAQ,IAEKO,EAIEA,EAAU5D,KAAIgE,IACnB,SAAC,KAAK,CAEJC,KAAOd,EAAaa,EAAMX,GAC1B1B,OAAUC,IACR,SAACoC,EAAKE,UAAS,iBACRtC,EAAK,CACVgC,UAAYG,EAAgBH,UAC5BO,kBAAoBJ,EAAgBI,kBACpCd,OAASU,EACTK,gBAAkBR,EAClBL,UAAYA,EACZV,SAAU,QAAcA,GAAWU,GAAW,IAAAc,WAAUL,EAAKhL,UAV3DgL,EAAKhL,OALN,KA+BEsL,EAAe,CAC1BV,EACAP,EACApI,IAEK2I,EAIEA,EAAUW,MAAKP,GAjBI,EAC1BA,EACAX,EACApI,IAEiE,IAA1DA,EAASC,SAAS2I,QAAQV,EAAaa,EAAMX,IAYtBmB,CAAaR,EAAMX,EAAQpI,KAHhD,I,0ICzEX,MAAMwJ,UAA0B,EAAAlF,UAAhC,c,oBACE,KAAA2C,OAA4CwC,GACA,IAAtC5M,OAAOC,KAAK2M,GAAe7M,OACtByK,QAAQC,UAGV,SAAmB,mBAAgCmC,GACvD7D,KAAKC,KAAK6D,eAGf,KAAAA,cAAgB,KACd7D,KAAKc,MAAMvB,YAAY,CAAE,YAAa,EAGxC,KAAAmC,eAAyC,CAACrK,EAAIsK,EAAOC,KACnD,MAAM,YAAEC,EAAW,eAAEH,GAAmB1B,KAAKc,MAE7C,GADAe,EAAYH,eAAerK,EAAIsK,EAAOC,GAClCF,EACF,OAAOA,EAAerK,EAAIsK,EAAOC,E,CAmBvC,CAfEf,SACE,MAAM,EAAmEb,KAAKc,OAAxE,SAAES,EAAQ,iBAAEY,EAAgB,YAAEN,EAAW,KAAE5K,GAAI,EAAK6M,E,yUAAU,GAA9D,sDACN,OACE,8BAAKnI,UAAU,uBAAqB,WAClC,SAAC,IAAI,iBACEmI,EAAU,CACf9B,IAAMC,GAAKJ,EAAYK,WAAWjL,EAAMgL,GACxCb,OAASpB,KAAKoB,OACde,iBAAmBA,EACnBC,YAAcb,EACdG,eAAiB1B,KAAK0B,oBAI9B,EAGF,SAAe,QACb,QAAgBiC,GAChB,CACE7E,KAAM,CACJqD,iBAAkB,EAAGlL,UAAW,SAAmB,2BAAwC,CAAEA,SAC7FsK,SAAU,EAAStK,OAAM8M,0BAAyBC,YAAY,iBAAmC,O,OAAD,E,OAAA,E,EAAA,YAC9F,MAAMzC,QAAsC,SAC1C,mBAAgC,CAC9BtK,OACAgN,WAAYD,IAQhB,OAJMD,GACJA,EAAwBxC,GAGnBA,CACT,E,YAbgG,K,6QAa/F,I,qJC1EP,MAAM2C,EAAgD,EAAGpB,YAAWO,oBAAmBZ,gBAEnF,8BAAK9G,UAAU,iCAA+B,WAC5C,+BAAKA,UAAU,8BAA4B,WACvCmH,IACEO,IACF,4BACE,8BAAK1H,UAAU,eAAa,UACxB8G,EAAUC,UAAU,gBAExB,8BAAK/G,UAAU,QAAM,UACjB0H,eAWVc,EAA6C,EAAGb,sBACpD,8BAAK3H,UAAU,gDAA8C,UACzD2H,KAOAc,EAAkC,EACpCC,mBAAkBpB,kBAAiBV,SAAQ+B,aAAY9H,WAAU6D,UAASoC,gBAE5E,8BAAK9G,UAAY,IAAW,uBAAwB0I,IAAiB,WACnE,+BAAK1I,UAAU,cAAY,YACzB,SAAC4I,EAAA,EAAY,CACX9I,OAAQ,QAA6BwH,EAAgBxH,MAAOgH,GAC5D1J,MAAO,SAACyL,EAAA,EAAI,CAACC,MAAM,QAAQ1L,KAAOwJ,EAAQxJ,OAC1C2L,eAAiBJ,KAEnB,+BAAK3I,UAAU,WAAS,WACpB0E,EACA7D,aAqBV,EAf4D,I,IAAA,SAAEA,GAAQ,EAAKG,E,yUAAK,GAApB,cAA2B,OACrF,+BAAKhB,UAAU,QAAM,YACnB,SAACwI,EAAkB,iBAAMxH,KACzB,+BACEtF,GAAG,yBACHsE,UAAU,wBAAsB,YAEhC,SAACuI,EAAoB,iBAAMvH,KAC3B,SAACyH,EAAO,iBAAMzH,EAAK,UACfH,YAIT,E,oCC3DD,MAAMmI,EAAkE,EACpE7B,YAAWO,oBAAmBJ,kBAAiBK,kBAAiBf,SAAQE,gBAE1E,+BAAK9G,UAAU,eAAa,YAC1B,SAACiJ,EAAA,EAAQ,eACPC,WAAY,EACZjJ,SAAU,QAA6B2G,EAAQ9G,MAAOgH,GACtDqC,YAAc,SAASvC,EAAQxJ,QAAM,UAEnCuK,MAGJ,SAACkB,EAAA,EAAI,CACHzL,KAAK,cACLoG,KAAK,WAGP,UAAC4F,EAAA,EAAiB,eAChBF,WAAY,EACZjJ,SAAU,QAA6BqH,EAAgBxH,MAAOgH,IAAU,YAExE,SAACuC,EAAA,EAAW,UACRlC,KAEJ,SAACkC,EAAA,EAAW,eAACpJ,QAAU6G,EAAUC,UAAU,aAAW,UAClDW,aAyBV,EAjBE,I,IAAA,WAAEiB,EAAU,SAAE9H,EAAQ,iBAAE6H,EAAgB,QAAEhE,GAAO,EAAK1D,E,yUAAK,GAA3D,wDACG,OACH,+BAAKhB,UAAU,UAAQ,YACrB,SAACgJ,EAAuB,iBAAMhI,KAC9B,+BACEtF,GAAG,yBACHsE,UAAY0I,GAAgB,aAExBC,GAAc,eAAmBA,EAAY,CAAE3I,UAAW,WAC9D,+BAAKA,UAAU,WAAS,WACpB0E,EACA7D,aAIT,E,eCzBD,MAmCA,GAJgC,EAAAyI,EAAA,IAC9B,EAAAC,EAAA,KAhCuCpE,IACvC,MAAMrC,GAAY,WAAqB8B,OAAO4E,WAAa,IAAOC,EAAwBC,GAEpF,QAAEtD,EAAO,UAAEU,EAAS,gBAAEa,EAAe,UAAER,EAAS,kBAAEO,EAAiB,SAAElJ,GAA4B2G,EAAfwE,E,yUAAU,CAAKxE,EAAjG,uFACA,OAAEyB,EAAM,gBAAEU,GAAoBnC,EAE9BuD,EAAmB,IACvB,kBACA,GAAG9B,EAAQrK,OAAO+K,EAAgB/K,OAGpC,OACE,SAACuG,EAAS,iBACH6G,EAAU,CACf7C,UAAYA,EACZV,QAAUA,EACV5H,SAAWA,EACXkK,iBAAmBA,EACnBf,gBACExC,EAAMwC,gBAAiBpE,KAAIgE,IAAQ,QAAwBA,OAAMlC,EAAWyB,EAAWtI,KAEzF2I,UAAahC,EAAMgC,UACjBhC,EAAMgC,UAAU5D,KAAIgE,IAAQ,QAAwBA,EAAMX,EAAQE,EAAWtI,KADhD,GAG/BkJ,kBAAqBA,EACnBA,EAAkBnE,KAAIgE,IAAQ,QAAwBA,EAAMX,EAAQE,EAAWtI,UADxC6G,IAI5C,I,uMC9CH,MAAMuE,UAAmB,EAAA9G,UAAzB,c,oBAeE,KAAAmB,MAAQ,CACN4F,QAAQ,GAGV,KAAAC,gBAAkB,KAChBzF,KAAKS,SAAS,CAAE+E,QAASxF,KAAKJ,MAAM4F,QAAS,EAG/C,KAAA3J,QAAU,KACRmE,KAAKyF,kBACLzF,KAAKc,MAAM4E,cACR3F,KAAKC,KAAKyF,iBACVvF,MAAMF,KAAKyF,gBAAgB,CA0BlC,CAvBE5E,SACE,MAAM,MAAE8E,EAAK,WAAE/D,EAAU,UAAEjG,EAAS,UAAE8G,GAAczC,KAAKc,MAEnD8E,EAAqBD,GAASE,EAAA,YAAqB,oBAEzD,IAAIpK,EAOJ,OAHEA,EAHGmK,EAGKnD,EAAUC,UAAUd,EAAa,eAAiB,sBAFlDa,EAAUC,UAAU,uBAM5B,SAACoD,EAAA,EAAM,CACLnK,UAAY,IAAW,OAAQA,GAC/BC,QAAUH,EACV1C,KAAQ6M,GAAahE,EAAa,kBAAoB,KACtDmE,QAAU/F,KAAKJ,MAAM4F,OACrBQ,UAAYpE,IAAegE,EAC3B/J,QAAUmE,KAAKnE,SAGrB,EAnDO,EAAAoK,UAAY,CAIjBrE,WAAY,oBAKZ8D,YAAa,oBAEbC,MAAO,UA2CX,U,0BCpCO,MAAMO,EAAuB,qBAAsDlF,GAOnF,SAASmF,EAAwB1H,GACtC,OAAO,SAAyBqC,GAC9B,OACE,SAACoF,EAAqBE,SAAQ,UAC1BC,IAAW,SAAC5H,EAAS,iBAAKqC,EAAK,CAAEe,YAAcwE,MAGvD,CACF,CAEA,MAAMC,EAAarP,GACVA,EAAKsP,KAAK,KAGJ,SAAS,EACtB9H,GAIA,MAAMyG,UAAsB,YAA5B,c,oBAGE,KAAAsB,MAAyC,CAAC,EAC1C,KAAAC,kBAAoB,IAAIC,IAQxB,KAAAC,kBAA4C,CAACtP,EAAIsK,EAAOC,KAClDA,EACF5B,KAAKyG,kBAAkBG,IAAIvP,GAE3B2I,KAAKyG,kBAAkBI,OAAOxP,GAGhC2I,KAAK8G,aAAa,EAGpB,KAAAC,gBAAkB,KAChB,MAAM,UAAErE,GAAc1C,KAAKc,MAAM2B,UACjCuE,EAAA,UAA4B,CAC1BvL,MAAOiH,EAAU,oBACjBrC,QAASqC,EAAU,sCAGrB1C,KAAK8G,aAAa,EAGpB,KAAAG,WAAa,KACX,IAAUjQ,OAAOC,KAAK+I,KAAKwG,OAAOzP,OAAS,EAAG,mCAC9C,MAAMmQ,EAAWlQ,OAAOmQ,OAAOnH,KAAKwG,OAAOtH,KAAIkI,GAAKA,EAAEC,SAGtD,OAFArH,KAAKyG,kBAAkBa,QAEhB9F,QAAQ+F,IAAIL,GAChBnH,KAAKC,KAAK+G,gBAAgB,EAG/B,KAAAnF,WAAa,IACJ5B,KAAKyG,kBAAkBtH,KAAO,EAGvC,KAAAqI,WAAcC,IACZ,MAAM,gBAAExE,EAAe,UAAER,GAAczC,KAAKc,MAC5C,QAAImC,EAAgByE,UAKiD,IAAjE1H,KAAKc,MAAM3G,SAASC,SAAS2I,QAAQ0E,EAAarN,YACe,IAAjEqN,EAAarN,SAAS2I,QAAQ/C,KAAKc,MAAM3G,SAASC,cAKnC4F,KAAK4B,cAAgBiE,EAAA,YAAqB,sBAE3DpD,EAAUjH,EAAE,uBAAwB,8DAA4D,EAGpG,KAAA0G,WAAa,CAACjL,EAAgBmQ,KACxBA,GACF,IACEA,EAAEO,eAAe,QACjB,qFAEF3H,KAAKwG,MAAMF,EAAUrP,IAASmQ,GAI9BpH,KAAKwG,MAAQ,CAAC,C,EAIlB,KAAAoB,WAAc3Q,GACL+I,KAAKwG,MAAMF,EAAUrP,IAG9B,KAAA4K,YAAoC,CAClCH,eAAgB1B,KAAK2G,kBACrBzE,WAAYlC,KAAKkC,WACjB0F,WAAY5H,KAAK4H,WAwCrB,CAtHEC,mBAAmBC,GACbA,EAAU7E,gBAAgB/K,MAAQ8H,KAAKc,MAAMmC,gBAAgB/K,KAC/D8H,KAAKyG,kBAAkBa,OAE3B,CA6EAzG,SACE,MAAM,gBAAEoC,EAAe,SAAEzG,EAAQ,UAAEiG,GAAczC,KAAKc,MAEhDT,EAAU4C,EAAgB0C,QAC9B,SAACoC,EAAA,EAAO,CACNrM,YAAc+G,EAAUjH,EACtB,sBACA,qDAEFzC,KAAOiP,EAAA,SAIL1D,GAAcrB,EAAgByE,SAClC,SAAC,EAAU,CACThC,YAAc1F,KAAKiH,WACnBrF,WAAa5B,KAAK4B,aAClB+D,MAAQ1C,EAAgB0C,MACxBlD,UAAYA,IAIhB,OACE,SAAChE,EAAS,iBACHuB,KAAKc,MAAK,CACfwD,WAAaA,EACbjE,QAAUA,GAAO,WAEjB,UAAC6F,EAAqB+B,SAAQ,eAACtG,MAAQ3B,KAAK6B,aAAW,YACrD,SAAC,KAAM,CACLxB,QAAUL,KAAKwH,aAEfhL,QAIV,EAGF,OA7HS,EAAA1D,YAAc,gBA6HhBoM,CACT,C,oHC1Ie,SAAS,EAASzG,GAC/B,MAAMwG,UAA8B,YASlCpE,SACE,MAAM,SAAE1G,EAAQ,MAAExE,EAAK,OAAE4M,EAAM,UAAEO,EAAS,kBAAEO,EAAiB,UAAEZ,EAAS,QAAEV,GAAY/B,KAAKc,MAC3F,IAAI3G,EAASC,WAAazE,EAAMuC,KAC7BqK,GAAUpI,EAASC,YAAa,QAAamI,KAExCO,GAAaA,EAAU/L,OAC3B,OAAO,SAAC,KAAQ,CAACmR,IAAK,QAAapF,EAAU,GAAIP,KAIrD,MAAMU,GAAkB,QAAaH,EAAWP,EAAQpI,KACtD,QAAakJ,EAAmBd,EAAQpI,GAE1C,OAAK8I,GAKH,UAACxE,EAAS,iBACHuB,KAAKc,MAAK,CACfmC,gBAAkBA,GAAe,YAE/B,QAA+BA,EAAiBH,EAAWL,EAAWV,EAASQ,IAC/E,QAA+BU,EAAiBI,EAAmBZ,EAAWV,EAASQ,OATpF,IAYX,EAGF,OArCS,EAAA0D,UAAY,CACjB1D,OAAQ,WACRO,UAAW,qBACXO,kBAAmB,UACnBlJ,SAAU,sBACVxE,MAAO,uBAgCJsP,CACT,C,kQClFI3N,EAAU,CAAC,EAEfA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,WAA3C,MCbD6Q,EAAO,CACX,EAAQ,OACR,EAAQ,OACR,EAAQ,OACR,EAAQ,OACR,EAAQ,OACR,EAAQ,OACR,EAAQ,OACR,EAAQ,OACR,EAAQ,QAGJC,GAAa,EAAAnD,EAAA,IAAsB,EAAGzI,eAExC,8BAAKb,UAAU,8BAA4B,UACvCa,OAUR,MAAM6L,UAAiB,EAAA5J,UAAvB,c,oBACE,KAAAgE,WAAY,QAAWzC,KAAKc,MAAMtF,EAAG,cAUvC,CATEqF,SACE,OACE,SAACuH,EAAU,iBACJpI,KAAKc,MAAK,CACfgC,UAAYqF,EACZ1F,UAAYzC,KAAKyC,YAGvB,EAGF,SAAe,EAAA6F,EAAA,IAAf,CAAiCD,E,iKChCjC,MAyDA,GAAe,QAzD8E,EAAGxI,QAAOkC,cACrG,MAAM,UAAEW,GAAcX,EAChBwG,EAAa,eAEbC,GAAY,QAAe,gBACjC,OACE,iCACE,UAAC,KAAI,eAAC/L,QAAQ,MAAMC,WAAY,GAAI,YAClC,SAAC,KAAG,CAACjB,MAAQiH,EAAU,uBAAyB3G,KAAOwM,EAAWE,kBAClE,SAAC,KAAG,CAAChN,MAAQiH,EAAU,kBAAoB3G,KAAO,YAClD,SAAC,KAAG,CAACN,MAAQiH,EAAU,qBAAuB3G,KAAOyM,KACrD,SAAC,KAAG,CAAC/M,MAAQiH,EAAU,eAAiB3G,KAAOwM,EAAWG,eAC1D,SAAC,KAAG,CAACjN,MAAQiH,EAAU,qBAAuB3G,KAAOwM,EAAWI,qBAChE,SAAC,KAAG,CAAClN,MAAQiH,EAAU,WAAa3G,MAAO,QAAmBwM,EAAWK,mBACzE,SAAC,KAAG,CAACnN,MAAQiH,EAAU,mBAAqB3G,KAAO8D,EAAMgJ,mBACzD,SAAC,KAAG,CAACpN,MAAQiH,EAAU,kBAAoB3G,KAAO8D,EAAMiJ,kBAExD,SAAC,KAAM,CAACrN,MAAQiH,EAAU,gBAC1B,SAAC,KAAG,CACFjH,OACE,SAAC,IAAY,eAACvD,IAAM,mBAA2B,UAC3CwK,EAAU,gBAGhBvG,QAAS,KAEX,SAAC,KAAG,CACFV,OACE,SAAC,IAAY,eAACvD,IAAM,cAAsB,UACtCwK,EAAU,oBAGhBvG,QAAS,KAEX,SAAC,KAAG,CACFV,OACE,SAAC,IAAY,eAACvD,IAAM,uBAA+B,UAC/CwK,EAAU,kCAGhBvG,QAAS,KAEX,SAAC,KAAM,CAACV,MAAQiH,EAAU,0BAC1B,SAAC,KAAG,CACFjH,OACE,SAAC,IAAY,eAACvD,IAAM,cAAsB,uCAI5CiE,QAAS,SAGb,SAAC,IAAa,CAACf,YAAa,MAE/B,GAGiD,cAA2B,KAAM,E,qHCpDrF,MAqDA,GAAe,QA3CkF,EAC7FyE,QAAOkC,cAET,MAAM,UAAEW,GAAcX,EACtB,OACE,UAAC,KAAI,eAACtF,QAAQ,MAAMC,WAAY,GAAI,YAClC,SAAC,KAAG,CACFjB,MAAQiH,EAAU,eAClB3G,KAAO8D,EAAMkJ,eAEf,SAAC,KAAG,CACFtN,MAAQiH,EAAU,gBAClB3G,KAAO,GAAG8D,EAAMmJ,kBAAiB,QAAiBnJ,EAAMmJ,aAAcnJ,EAAMkJ,mBAE9E,SAAC,KAAG,CACFtN,MAAQiH,EAAU,gBAClB3G,KAAO,GAAG8D,EAAMoJ,kBAAiB,QAAiBpJ,EAAMoJ,aAAcpJ,EAAMmJ,oBAE9E,SAAC,KAAG,CACFvN,MAAQiH,EAAU,eAClB3G,MAAO,QAAW8D,EAAMqJ,YAAanH,EAAQoH,WAE/C,SAAC,KAAG,CACF1N,MAAQiH,EAAU,0BAClB3G,MAAO,SACJ,QAAc8D,EAAMqJ,YAAarJ,EAAMmJ,cACxCjH,EAAQoH,WAGZ,SAAC,KAAG,CACF1N,MAAQiH,EAAU,8BAClB3G,MAAO,QAAiB8D,EAAMuJ,kBAAmBrH,EAAQoH,WAE3D,SAAC,KAAG,CACF1N,MAAQiH,EAAU,4BAClB3G,MAAO,QAAiB8D,EAAMwJ,gBAAiBtH,EAAQoH,WAEzD,SAAC,KAAM,CAAC1N,MAAQiH,EAAU,aACxB7C,EAAMyJ,QAAQpK,KAAKkI,IAAkBmC,OAhDpBC,EAgDoC3J,EAAMmJ,aAhDrBS,EAgDmCrC,GA9C7E,SAAC,KAAG,CAEF3L,MAAQgO,EAAOhR,KACfsD,KAAO,GAAG0N,EAAOC,WAAU,QAAiBD,EAAOC,MAAOF,OAFpDC,EAAOhR,MAHK,IAAC+Q,EAAqBC,CAgDqC,OAEhF,GAKD,eACA,CAACjO,EAAGsF,IAAUA,EAAMiB,QAAQW,UAAU,mBACtC,G,oHChEF,MAmHA,GAAe,QAnHsF,EACjG7C,QAAOkC,cAET,MAAM,UAAEW,EAAS,EAAElH,GAAMuG,EACzB,OACE,UAAC,KAAI,eAACtF,QAAQ,MAAMC,WAAY,GAAI,YAClC,SAAC,KAAG,CACFjB,MAAQiH,EAAU,oBAClB3G,MAAO,QAAW8D,EAAM8J,WAAY5H,EAAQoH,WAE9C,SAAC,KAAG,CACF1N,MAAQiH,EAAU,eAElB3G,KAAOP,EACL,kBACA,CACEoO,aAAc,0CACdC,QAAS,CACPC,WAAYjK,EAAMkK,iBAClBC,aAAa,QAAiBnK,EAAMoK,kBAAmBpK,EAAMkK,wBAKrE,SAAC,KAAG,CACFtO,MAAQiH,EAAU,qBAClB3G,KAAO8D,EAAMqK,yBAEf,SAAC,KAAG,CACFzO,MAAQiH,EAAU,oBAClB3G,MAAO,QAAc8D,EAAMsK,qBAE7B,SAAC,KAAG,CACF1O,MAAQiH,EAAU,+BAClB3G,MAAO,QAAc8D,EAAMkK,iBAAkBlK,EAAMqK,0BAGrD,SAAC,KAAM,CAACzO,MAAQiH,EAAU,wBAC1B,SAAC,KAAG,CACFjH,MAAQiH,EAAU,kBAClB3G,KAAOP,EACL,qBACA,CACEoO,aAAc,iDACdC,QAAS,CACPC,WAAYjK,EAAMuK,eAClBC,eAAgBxK,EAAMyK,0BAA0BC,QAAQ,SAKhE,SAAC,KAAG,CACF9O,MAAQiH,EAAU,gBAClB3G,MAAO,QAAiB8D,EAAM2K,aAAc3K,EAAMuK,mBAEpD,SAAC,KAAG,CACF3O,MAAQiH,EAAU,iBAElB3G,KAAOP,EACL,yBACA,CACEoO,aAAc,uDACdC,QAAS,CACPC,WAAYjK,EAAM4K,mBAClBC,aAAc7K,EAAM8K,yCAAyCJ,QAAQ,SAK7E,SAAC,KAAG,CACF9O,MAAQiH,EAAU,0BAClB3G,KAAOP,EACL,wBACA,CACEoO,aAAc,qFACdC,QAAS,CACPe,oBAAoB,QAAiB/K,EAAMgL,kBAAmBhL,EAAM4K,oBACpEK,kBAAkB,QAChBjL,EAAMkL,6BACNlL,EAAM4K,mBAAqB5K,EAAMgL,yBAM3C,SAAC,KAAG,CACFpP,MAAQiH,EAAU,6CAElB3G,KAAOP,EACL,6BACA,CACEoO,aAAc,mDACdC,QAAS,CACPmB,WAAYnL,EAAMoL,2BAA2BV,QAAQ,GACrDW,YAAarL,EAAMsL,4BAA4BZ,QAAQ,SAK/D,SAAC,KAAG,CACF9O,MAAQiH,EAAU,yCAClB3G,KAAOP,EACL,gCACA,CACEoO,aAAc,mBACdC,QAAS,CACPuB,UAAWvL,EAAMwL,yBAM5B,GAKD,eACA,CAAC7P,EAAGsF,IAAUA,EAAMiB,QAAQW,UAAU,oBACtC,G,0GCzHF,MA+BA,GAAe,E,SAAA,IA/B4F,EACvG7C,QAAOkC,cAET,MAAM,UAAEW,EAAS,OAAEyG,GAAWpH,EAExBuJ,EAAUzL,EAAM0L,iBAAmB1L,EAAM2L,qBACzCC,EAAY5L,EAAM6L,mBAAqB7L,EAAM8L,uBAEnD,OACE,UAAC,KAAI,eAAClP,QAAQ,MAAMC,WAAY,GAAI,YAClC,SAAC,KAAG,CACFjB,MAAQiH,EAAU,oBAClB3G,MAAO,QAAW0P,EAAWtC,MAE/B,SAAC,KAAG,CACF1N,MAAQiH,EAAU,kBAClB3G,MAAO,QAAWuP,EAASnC,MAE7B,SAAC,KAAM,CAAC1N,MAAQiH,EAAU,cAC1B,SAAC,KAAG,CACFjH,MAAQiH,EAAU,sBAClB3G,MAAO,QAAW8D,EAAM6L,mBAAoBvC,MAE9C,SAAC,KAAG,CACF1N,MAAQiH,EAAU,oBAClB3G,MAAO,QAAW8D,EAAM0L,iBAAkBpC,QAG/C,GAGwD,0BAAyC,KAAM,E,kBC9C1G,MAAMyC,EAAkB,WAExBxU,EAAOyU,QAAU,CACf3T,IAAK,QACLuD,MAAO,QACP1C,KAAM,OACNqK,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,cACPiM,QAAQ,EACRxP,IAAK,cACLkL,UAAW,YACV,CACD3H,MAAO,sBACPiM,QAAQ,EACRxP,IAAK,YACLc,OAAQ4S,EAAgBE,UACxB1I,UAAW,YACV,CACD3H,MAAO,mBACPiM,QAAQ,EACRxP,IAAK,QACLkL,UAAW,YACV,CACD3H,MAAO,iBACPiM,QAAQ,EACRxP,IAAK,OACLc,OAAQ4S,EAAgBG,UACxB3I,UAAW,a,oHC7BjB,MAAMxG,EAAa,eACnB,GACEA,WAAYA,EACZoP,WAAYpP,EAAa,UACzBqP,WAAYrP,EAAa,UAEzBsP,qBAAsB,iCACtBC,qBAAsB,iCACtBC,sBAAuB,mC,0BCEzB,MAAMC,EAAoD,CACxDC,OAAQ,CACNxT,YAAa,aACbE,OAAQ4S,EAAA,gBACR7S,KAAMiP,EAAA,YACNxO,QAAS,IACA+S,EAAA,OAAmBC,EAAsBR,cAKtD,GACEtR,SAAU,cACVC,QAAS0R,G,gJCZP/U,EAAU,CAAC,EAEfA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,WAA3C,MCVDmV,EAAe,CACnBC,EACA1U,EACA+J,KAEA,MAAM,UAAEW,EAAS,EAAElH,GAAMuG,EACzB,GAAI/J,EACF,OAAO0K,EAAU,gBAGnB,MAAMiK,EAAOD,EAAeE,YAQ5B,OAPYpR,EAAEmR,EAAO,eAAiB,sBAAuB,CAC3D/C,aAAc+C,EAAO,6BAA+B,oCACpD9C,QAAS,CACPgD,OAAQH,EAAe3Q,OAIjB,EAyCZ,GAAe,EAAA+Q,EAAA,IA3BwD,EACnED,SAAQE,YAAWC,YAAWjL,cAEhC,+BAAKpG,UAAU,2BAAyB,YACtC,6BAAIA,UAAU,UAAQ,UAClBoG,EAAQW,UAAU,qCAEtB,UAACnG,EAAA,GAAI,eAACE,QAAQ,OAAK,YACjB,SAAC,KAAG,CACFhB,MAAQsG,EAAQW,UAAU,qBAC1B3G,KAAO0Q,EAAaI,EAAOI,UAAWF,EAAWhL,MAEnD,SAAC,KAAG,CACFtG,MAAQsG,EAAQW,UAAU,qBAC1B3G,KAAO0Q,EAAaI,EAAOK,UAAWF,EAAWjL,UAGrD,SAACoL,EAAA,EAAY,CACXxR,UAAU,gBACVhB,QAAU,EACVyS,SAAS,SACTpH,UAAY6G,EAAOI,UAAUL,cAAgBC,EAAOK,UAAUN,YAC9D7G,QAAUiH,GAAaD,SAK6D,CACxFjO,KAAM,CACJ+N,OAAQL,EAAsBP,YAEhC5M,kBAAmB,CAACC,GAAqBC,cAAa8N,gBACpD,MAAMC,EAAiB,CAACC,EAAavV,KAEnCqV,EAAU,CACR,CAFY,WAAaE,EAAK,KAAO,OAE5BvV,GACT,EAGJsH,EACEkN,EAAsB5P,WACtB4P,EAAsBL,sBACtB5T,IACE+U,EAAe/U,EAAKgV,IAAI,EAAK,IAIjCjO,EACEkN,EAAsB5P,WACtB4P,EAAsBJ,uBACtB7T,IACE+U,EAAe/U,EAAKgV,IAAI,GACxBhO,GAAa,GAEhB,I,gDC1FL,MAyBA,EAzB0DuB,IACxD,MAAM,UAAE0M,GAAc1M,EAAMiB,QAC5B,OACE,4BACE,SAAC,EAAW,CACVA,QAAUjB,EAAMiB,WAElB,SAACgG,EAAA,EAAO,CACNrM,aACE,UAAC+R,EAAA,EAAK,eAACzR,QAAUwR,EAAU,8BAA4B,yHAE/C,SAACE,EAAA,EAAY,eAACxV,IAAMyV,EAAA,iBAA2B,sCAAwC,+IAI3F,KACF,SAACD,EAAA,EAAY,eAACxV,IAAMyV,EAAA,yBAAmC,uCAAyC,QAGpG5U,KAAOiP,EAAA,WAGZ,C,qFC7BH,MAAM4F,EAAQ,CACZ,cACA,WACA,8BACA,4BAYF,EATuD9M,IACrD,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,qFCXb,MAAMA,EAAQ,CACZ,qBACA,qBACA,qBACA,mBACA,0BACA,6BAaF,EAViD9M,IAC/C,0BACE,SAAC,IAAY,iBACNA,EAAK,CACV7J,KAAO2W,EACPC,SAAS,S,oFCbf,MAAMD,EAAQ,CACZ,qBACA,qBACA,qBACA,mBACA,0BACA,6BAaF,EAViD9M,IAC/C,0BACE,SAAC,IAAY,iBACNA,EAAK,CACV7J,KAAO2W,EACPC,SAAS,S,4ICPf,MAAMD,EAAQ,CACZ,WACA,WACA,WACA,yBA0CF,EAlBsD9M,IAAS,OAC7D,4BACE,SAAC,IAAO,CACNpF,YAAcoF,EAAMiB,QAAQvG,EAC1B,sBACA,mFAEFzC,KAAO,YAET,SAAC,IAAiB,iBACX+H,EAAK,CACV7J,KAAO2W,EACPE,gBAjCqB/L,EAiCcjB,EAAMiB,QAhCG,CAAC1K,EAAI0W,EAAcC,KACjE,MAAMtL,EAAa3G,GACVgG,EAAQvG,GACb,QAAc,UAA8CnE,OAAI2J,GAChEjF,GAIO,aAAP1E,EACF0W,EAAaE,KAAOvL,EAAU,8CACd,aAAPrL,EACT0W,EAAaE,KAAOvL,EAAU,kDACd,aAAPrL,IACT0W,EAAaE,KAAOvL,EAAU,kC,GAoB9BsB,UAAY,wBAlCQ,IAACjC,CAqC1B,C,iICzCD,MAAMmM,UAAqB,EAAAzP,UAA3B,c,oBACE,KAAAmB,MAAQ,CACNuO,mBAAmB,GAGrB,KAAAC,aAAgBC,GACP,GAAGA,KAAOrO,KAAKc,MAAM+M,WAG9B,KAAAC,eAA0C,CAACzW,EAAI0W,EAAcC,KAC3D,MAAMM,EAAkBN,EAAUhO,KAAKoO,aAAa,sBAClD,uBACIG,EAAaP,EAAUhO,KAAKoO,aAAa,oBAEzCE,IAAmBC,GACS,IAAhClX,EAAG0L,QAAQ,kBAA4D,IAAlC1L,EAAG0L,QAAQ,oBACT,IAAvC1L,EAAG0L,QAAQ,yBAA0E,IAAzC1L,EAAG0L,QAAQ,4BAEvDgL,EAAa/H,UAAW,GAGtBuI,GAAgD,IAAlClX,EAAG0L,QAAQ,oBAA4BuL,IACvDP,EAAa/H,UAAW,GAGrBsI,GAAqD,IAAlCjX,EAAG0L,QAAQ,qBACjCgL,EAAa/H,UAAW,E,EAI5B,KAAAjC,wBAA2BxC,IACzBvB,KAAKS,SAAS,CACZ0N,kBAAmB5M,EAASvB,KAAKoO,aAAa,qBAC9C,CAwBN,CArBEvN,SACE,OACE,2BACIb,KAAKJ,MAAMuO,oBACX,SAAC,IAAO,CACNzS,YAAcsE,KAAKc,MAAMiB,QAAQvG,EAC/B,yBACA,2GAEFzC,KAAO,YAGX,SAAC,IAAiB,iBACXiH,KAAKc,MAAK,CACfgN,eAAiB9N,KAAK8N,eACtB/J,wBAA0B/D,KAAK+D,wBAC/BC,UAAY,uBAIpB,EAGF,S,gGCnEA,MAAM4J,EAAQ,CACZ,gBACA,eACA,aACA,gBACA,aACA,iBACA,cAGIE,EAA0C,CAACzW,EAAI0W,EAAcC,KAC5CA,EAAUQ,gBAAkB,qBAEH,IAAzBnX,EAAG0L,QAAQ,YAC9BgL,EAAa/H,UAAW,E,EAc5B,EAVuDlF,IACrD,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,EACPE,eAAiBA,M,kBC/BvB1W,EAAOyU,QAAU,CACf3T,IAAK,eACLuD,MAAO,eACP1C,KAAM,SACNqK,UAAW,WAEXN,UAAW,CACT,CACErH,MAAO,iBACPvD,IAAK,YACLwP,QAAQ,EACRtE,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,6BACPvD,IAAK,KACLkL,UAAW,YACV,CACD3H,MAAO,6BACPvD,IAAK,KACLkL,UAAW,WACV,CACD3H,MAAO,iBACPvD,IAAK,QACLkL,UAAW,YACV,CACD3H,MAAO,UACPvD,IAAK,UACLkL,UAAW,YACV,CACD3H,MAAO,aACPvD,IAAK,aACLkL,UAAW,a,qFC9BjB,MAAMwK,EAAQ,CACZ,qBACA,uBACA,uBAIIa,EAAgB,CACpB,sBACA,oBAGIC,EAAc,CAClB,qBACA,sBACA,eAGIC,EAAmB,CACvB,qBACA,mBA8BF,EA3BgE7N,IAC9D,MAAM,UAAE4B,GAAc5B,EAAMiB,QAC5B,OACE,4BACE,SAAC,IAAiB,iBACXjB,EAAK,CACV7J,KAAO2W,MAET,SAAC,IAAiB,iBACX9M,EAAK,CACV7J,KAAOwX,EACPhT,MAAQiH,EAAU,gBAEpB,SAAC,IAAiB,iBACX5B,EAAK,CACV7J,KAAO0X,EACPlT,MAAQiH,EAAU,mBAEpB,SAAC,IAAiB,iBACX5B,EAAK,CACV7J,KAAOyX,EACPjT,MAAQiH,EAAU,gBAGvB,C,qLCxCH,MAcMkM,EAA+D,CACnEC,OAAQ,CACN/V,YAAa,gBACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACNxO,QAnB8C,EAAGW,eACnD2U,EAAA,OAAa,GAAG3U,EAASC,uBAAuB,IAsB5C2U,EAA8E,CAClFC,KAAM,CACJlW,YAAa,iBACbE,OAAQ,mBACRD,KAAMiP,EAAA,OACNxO,QAxB6D,EAAGjB,KAAM0W,EAAW9U,eACnF2U,EAAA,OAAa,GAAG3U,EAASC,wBAAwB6U,EAAU5X,KAAK,GAyBhEiD,OAAQ,CACNxB,YAAa,mBACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACNzN,aAAc,CACZpB,QAAS,6EACTD,eAAgB,mBAChBsB,cAAe,gBAEjBhB,QA/B+D,EAC/DjB,KAAM0W,KAED1C,EAAA,SAAqB,GAAG2C,EAAA,qBAA8CD,EAAU5X,QAgCzF,GACEwX,OAAQ,CACNnU,SAAU,cACVS,MAAO,oBACPR,QAASiU,GAEXI,KAAM,CACJtU,SAAU,cACVS,MAAO,oBACPR,QAASoU,I,4HCrCb,MAAMnB,EAAkC,CACtC,CACES,IAAK,OACL5S,MAAO,OACPnC,KAAM,qBAER,CACE+U,IAAK,OACL5S,MAAO,OACPnC,KAAM,cAuBV,MAAM6V,UAAgC,EAAA1Q,UAAtC,c,oBAIE,KAAA0D,kBAAmB,QAAcyL,EAAO5N,KAAKc,MAAMiB,SAEnD,KAAAqN,MAAQ,KACEpP,KAAKc,MAAMuO,eAGrB,KAAA3N,eAAgD,CAACrK,EAAIsK,EAAOC,KAC9B,IAAxBvK,EAAG0L,QAAQ,QACNvB,QAAQC,QAAQ,CACrBhJ,KAAQkJ,EAAMwB,MAAO,QAAiBxB,EAAMwB,WAAQnC,IAIjD,KAGT,KAAAqG,KAAO,IACErH,KAAKsP,KAAKjI,OAGnB,KAAAjG,OAAkCmO,GAC5BvP,KAAKoP,QACA7C,EAAA,OAAmB2C,EAAA,kBAA4CK,GAGjEhD,EAAA,QACL,GAAG2C,EAAA,qBAA8ClP,KAAKc,MAAMuO,eAAgBhY,KAC5EkY,GAIJ,KAAAzB,eAAiD,CAACzW,EAAI0W,EAAcC,KACvD,SAAP3W,GACF0W,EAAa/H,UAAYhG,KAAKoP,QAC9BrB,EAAayB,OAASxY,OAAO+J,OAAOgN,EAAayB,QAAU,CAAC,EAAG,CAC7DC,UAAWC,EAAA,uBAEG,SAAPrY,IACT0W,EAAa4B,QAAU,kBACvB5B,EAAa6B,SAAW,KACxB7B,EAAayB,OAAS,CACpBK,iBAAkB,IAAM7P,KAAKc,MAAMgP,c,CA6B3C,CAxBEjP,SACE,MAAM,QAAEkB,EAAO,eAAEsN,GAAmBrP,KAAKc,MACnCrF,EAASsG,EAAQW,UAAU1C,KAAKoP,QAAU,yBAA2B,2BAC3E,OACE,SAACW,EAAA,EAAK,eACJpU,UAAU,qBACVF,MAAQA,EACRuU,UAAYhQ,KAAKqH,KACjB4I,UAAW,EACXlX,KAAOiP,EAAA,UACFhI,KAAKc,MAAK,WAEf,SAACoP,EAAA,EAAI,CACHlO,IAAMoF,GAAKpH,KAAKsP,KAAOlI,EACvBjF,iBAAmBnC,KAAKmC,iBACxBT,eAAiB1B,KAAK0B,eACtBoM,eAAiB9N,KAAK8N,eACtB1M,OAASpB,KAAKoB,OACdgB,YAAciN,EACdlV,SAAW6F,KAAKc,MAAM3G,aAI9B,EAxEO,EAAArB,YAAc,0BA2EvB,SAAe,EAAAqX,EAAA,KACb,EAAArD,EAAA,GAA+DqC,EAAyB,CACtFrQ,KAAM,CACJgR,aAAcZ,EAAA,0BACdG,eAAgB,EAAG1Z,SAASya,IACrBza,EAAM0a,OAAOC,YAIXF,EAAOG,IAAI,GAAGrB,EAAA,qBAA8CvZ,EAAM0a,OAAOC,eAHvE9O,QAAQC,aAAQT,IAM7BhC,eAAgB,CACd8Q,aAAevX,GAA4BA,EAAK2G,KAAIgE,GAAQA,EAAKzK,MAAM,OAG3E,2CCtIIwD,EAA4D,EAAGgT,gBACnE,2BACE,6BAAItT,UAAU,iBAAe,WAC3B,SAAC,KAAU,CACTC,SAAU,4BAAUqT,EAAUxW,OAC9BkC,QAAU6V,EAAyBxB,KACnCyB,SAAWxB,EACXyB,eAAe,gCAGnB,6BAAI/U,UAAU,QAAM,UAChBsT,EAAU9L,WAKZwN,EAAU1B,IAEZ,SAAChT,EAAG,CAEFgT,UAAYA,GADNA,EAAU9L,MA0CtB,GAAe,EAAA2J,EAAA,IA5BsF,EACjG8D,cAAa7O,cAEf,+BAAK1K,GAAG,mBAAiB,YACvB,SAAC8V,EAAA,EAAY,CACXxS,QAAU6V,EAAyB3B,OACnCzB,SAAS,WAGc,IAAvBwD,EAAY7Z,OAAe,MAC3B,iCAAO4E,UAAU,oBAAkB,YACjC,4BACE,2BACE,wBAAMoG,EAAQW,UAAU,WACxB,wBAAMX,EAAQW,UAAU,gBAG5B,2BACIkO,EAAY1R,IAAIyR,UAIxB,SAAC,EAAuB,CACtB5O,QAAUA,SAMS,CACrBjD,KAAM,CACJ8R,YAAa1B,EAAA,mBAEf7P,kBAAmB,CAACC,GAAqBC,kBACvCD,EACE4P,EAAA,aACAA,EAAA,uBACA,IAAM3P,KACP,I,eCzEP,MAAM,EAAQ,CACZ,sBAgCF,EA7B0DuB,IACxD,4BACE,SAAC6C,EAAA,EAAiB,iBACX7C,EAAK,CACV7J,KAAO,MAGT,SAAC8Q,EAAA,EAAO,CACNrM,aACE,SAACgS,EAAA,EAAY,eAACxV,IAAMyV,EAAA,qBAA+B,UAC/C7M,EAAMiB,QAAQW,UAAU,+BAG9B3J,KAAOiP,EAAA,UAGT,+BAAKrM,UAAU,2BAAyB,YACtC,SAAC4I,EAAA,EAAY,CACX9I,MAAQqF,EAAMiB,QAAQW,UAAU,iCAChC3J,KAAOiP,EAAA,SACP7I,KAAK,YAEP,SAAC0R,EAAsB,CACrB9O,QAAUjB,EAAMiB,gB,qFCrCxB,MAAM6L,EAAQ,CACZ,oBACA,iBACA,mBACA,qBAGIkD,EAAgB,CACpB,6BACA,kBACA,yBAqBF,EAlB2DhQ,IACzD,MAAM,UAAE4B,GAAc5B,EAAMiB,QAC5B,OACE,4BACE,SAAC,IAAiB,eAChBtG,MAAQiH,EAAU,oBACb5B,EAAK,CACV7J,KAAO2W,MAET,SAAC,IAAiB,eAChBnS,MAAQiH,EAAU,wBACb5B,EAAK,CACV7J,KAAO6Z,OAGZ,C,qFC5BH,MAAMlD,EAAQ,CACZ,mBACA,kBACA,yBACA,0BACA,yBAYF,EAT+D9M,IAC7D,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,2KCLb,MAcMmD,EAA6D,CACjElC,OAAQ,CACN/V,YAAa,WACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACNxO,QAnBmD,EAAGW,eACxD2U,EAAA,OAAa,GAAG3U,EAASC,iBAAiB,IAsBtC4W,EAA2D,CAC/DhC,KAAM,CACJlW,YAAa,YACbE,OAAQ,mBACRD,KAAMiP,EAAA,OACNxO,QAxBiD,EAAGjB,KAAMe,EAAMa,eAClE2U,EAAA,OAAa,GAAG3U,EAASC,kBAAkBd,EAAKjC,KAAK,GAyBrDiD,OAAQ,CACNxB,YAAa,cACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACNzN,aAAc,CACZpB,QAAS,sEACTD,eAAgB,cAChBsB,cAAe,gBAEjBV,OAAQR,IAASA,EAAK2X,aACtBzX,QAhCmD,EACnDjB,KAAMe,KAEDiT,EAAA,SAAqB,GAAG2E,EAAA,sBAAoC5X,EAAKjC,QAiC1E,GACEwX,OAAQ,CACNnU,SAAU,cACVS,MAAO,aACPR,QAASoW,GAEX/B,KAAM,CACJtU,SAAU,cACVS,MAAO,aACPR,QAASqW,I,gDC9Cb,MAAMpD,EAAkC,CACtC,CACES,IAAK,OACL5S,MAAO,OACPnC,KAAM,aAER,CACE+U,IAAK,aACL5S,MAAO,kBACPnC,KAAM,UACN6X,UAAW,cAsBf,MAAMC,UAAyB,EAAA3S,UAA/B,c,oBAIE,KAAA0D,kBAAmB,QAAcyL,EAAO5N,KAAKc,MAAMiB,SAEnD,KAAAqN,MAAQ,KACEpP,KAAKc,MAAMuQ,gBAGrB,KAAAhK,KAAO,IACErH,KAAKsP,KAAKjI,OAGnB,KAAAjG,OAAkCmO,GAC5BvP,KAAKoP,QACA7C,EAAA,OAAmB2E,EAAA,mBAAkC3B,GAGvDhD,EAAA,QACL,GAAG2E,EAAA,sBAAoClR,KAAKc,MAAMuQ,gBAAiBha,KACnEkY,GAIJ,KAAAzB,eAAiD,CAACzW,EAAI0W,EAAcC,KAClE,GAAW,SAAP3W,EAAe,CACjB,MAAM,gBAAEga,GAAoBrR,KAAKc,MACjCiN,EAAa/H,WAAaqL,GAAmBA,EAAgBJ,Y,EA2BnE,CAvBEpQ,SACE,MAAM,QAAEkB,EAAO,gBAAEsP,GAAoBrR,KAAKc,MACpCrF,EAASsG,EAAQW,UAAU1C,KAAKoP,QAAU,kBAAoB,oBACpE,OACE,SAACW,EAAA,EAAK,eACJpU,UAAU,cACVF,MAAQA,EACRuU,UAAYhQ,KAAKqH,KACjB4I,UAAW,EACXlX,KAAOiP,EAAA,UACFhI,KAAKc,MAAK,WAEf,SAACoP,EAAA,EAAI,CACHlO,IAAMoF,GAAKpH,KAAKsP,KAAOlI,EACvBjF,iBAAmBnC,KAAKmC,iBACxB2L,eAAiB9N,KAAK8N,eACtB1M,OAASpB,KAAKoB,OACdgB,YAAciP,EACdlX,SAAW6F,KAAKc,MAAM3G,aAI9B,EArDO,EAAArB,YAAc,mBAwDvB,SAAe,EAAAqX,EAAA,KACb,EAAArD,EAAA,GAA+DsE,EAAkB,CAC/EtS,KAAM,CACJuS,gBAAiB,EAAG1b,SAASya,IACtBza,EAAM0a,OAAOiB,aAIXlB,EAAOG,IAAI,GAAGW,EAAA,sBAAoCvb,EAAM0a,OAAOiB,gBAH7D9P,QAAQC,aAAQT,MAO/B,wB,yBCpGF,MAAM/E,EAAyE,EAAG3C,OAAMyI,cACtF,2BACE,6BAAIpG,UAAU,iBAAe,WAC3B,SAAC,KAAU,CACTC,SAAU,4BAAUtC,EAAKkF,MACzB7D,QAAU4W,EAAkBvC,KAC5ByB,SAAWnX,EACXoX,eAAe,gCAGnB,6BAAI/U,UAAU,cAAY,UACtBrC,EAAKkY,WAAWjL,KAAK,UAEzB,6BAAI5K,UAAU,WAAS,WACnB,QAAcrC,EAAK2X,aAAclP,EAAQoH,cAgEjD,GAAe,EAAA2D,EAAA,IAvC0B,EACrC2E,cAAa1P,cAEf,+BAAK1K,GAAG,mBAAiB,YACvB,SAAC8V,EAAA,EAAY,CACXxS,QAAU4W,EAAkB1C,OAC5BzB,SAAS,WAGc,IAAvBqE,EAAY1a,OAAe,MAC3B,iCAAO4E,UAAU,oBAAkB,YACjC,4BACE,2BACE,wBAAMoG,EAAQW,UAAU,WACxB,wBAAMX,EAAQW,UAAU,sBACxB,wBAAMX,EAAQW,UAAU,mBAG5B,2BACI+O,EAAYvS,KAAI5F,GAvCb,EAACA,EAAsByI,KAElC,SAAC9F,EAAG,CAEF3C,KAAOA,EACPyI,QAAUA,GAFJzI,EAAKjC,IAoCmBsZ,CAAOrX,EAAMyI,YAI7C,SAACgG,EAAA,EAAO,CACNhP,KAAOiP,EAAA,OACPtM,YACEqG,EAAQvG,EACN,kBAEA,qPAIN,SAAC,EAAgB,CACfuG,QAAUA,SAMG,CACfjD,KAAM,CACJ2S,YAAaP,EAAA,oBAEf7R,kBAAmB,CAACC,GAAqBC,kBACvCD,EACE4R,EAAA,aACAA,EAAA,wBACA,IAAM3R,KACP,G,qFCvGP,MAAMqO,EAAQ,CACZ,uBACA,uBACA,0BAGI8D,EAAW,CACf,oBACA,2BAkBF,EAfgE5Q,IAC9D,4BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,MAGT,SAAC,IAAiB,eAChBnS,MAAQqF,EAAMiB,QAAQW,UAAU,aAC3B5B,EAAK,CACV7J,KAAOya,O,kBCzBbta,EAAOyU,QAAU,CACf3T,IAAK,YACLuD,MAAO,YACP1C,KAAM,WACNqK,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,YACPvD,IAAK,YACLkL,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,mBACPvD,IAAK,mBACLkL,UAAW,YACV,CACD3H,MAAO,kBACPvD,IAAK,kBACLkL,UAAW,YACV,CACD3H,MAAO,mBACPvD,IAAK,mBACLkL,UAAW,YACV,CACD3H,MAAO,aACPvD,IAAK,aACLkL,UAAW,YACV,CACD3H,MAAO,eACPvD,IAAK,eACLkL,UAAW,a,uJCPjB,MAqBA,GAAe,QArBgF,EAC3FuO,gBAAe5P,aAEb4P,EAAc,oBACT,MAIP,SAAC,IAAO,CACNjW,aACE,UAAC,IAAK,eAACM,QAAU+F,EAAQyL,UAAU,kCAAgC,4CACpC,uBAAK,qBAAuC,mDAC5D,SAAC,IAAY,eAACtV,IAAM,wBAAgC,kCAAoC,sCAIzGa,KAAO,eAKqG,CAChH+F,KAAM,CACJ6S,cAAe,wBAEjBC,WAAY,M,qFC9Cd,MAAMhE,EAAQ,CACZ,qBAYF,EATiE9M,IAC/D,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,kKCeb,MAyBA,GAAe,EAAAd,EAAA,IAbuE,EACpF+E,iBAAgB9P,UAAS+P,wBAEzB,+BAAKnW,UAAU,oBAAkB,YAC/B,gBAAKA,UAAU,eACbkW,EAAe9a,OAAS,IACxB,8BAAK4E,UAAU,oBAAkB,UAC7BkW,EAAe3S,KAAI3G,GAnBb,EAACC,EAA2BuJ,EAA8B+P,KACxE,MAAMC,EAAmBD,EAAkBrO,MAAKxE,GAAKA,EAAExG,OAASD,EAAWC,OAC3E,OACE,SAACuZ,EAAA,EAAS,CAERxZ,WAAaA,EACbuZ,iBAAmBA,EACnBhQ,QAAUA,GAHJvJ,EAAWC,KAKpB,EAUkCwZ,CAAQ1Z,EAAK2Z,QAASnQ,EAAS+P,aAMqC,CACvGhT,KAAM,CACJgT,kBAAmBK,EAAA,iBACnBN,eAAgB,KAAM,OAAkBM,EAAA,oBAAqC,IAE/EnT,eAAgB,CACd6S,eAAgB,EAAGO,aAAcA,GAEnC/S,kBAAmB,CAACC,GAAqBC,kBACvC,MAAM8S,EAAmB,IAAM9S,EAAY,CAAE,sBAE7CD,EAAkB6S,EAAA,aAA+BA,EAAA,QAA0BE,GAC3E/S,EAAkB6S,EAAA,aAA+BA,EAAA,UAA4BE,GAC7E/S,EAAkB6S,EAAA,aAA+BA,EAAA,UAA4BE,EAAiB,I,eChDlG,MAqBA,EArBgE,EAAGtQ,cAE/D,iCACE,SAACuQ,EAAA,EAAmB,CAClBvQ,QAAUA,KAEZ,8BAAKpG,UAAU,iBAAe,WAC5B,SAACwR,EAAA,EAAY,CACXxS,QAAU4X,EAAA,UACVnF,SAAS,aACTzR,UAAU,YAGd,SAAC,EAAgB,CACfoG,QAAUA,KAEZ,SAACyQ,EAAA,EAAyB,M,qJChBhC,MAAMC,EAAkBC,GACf,GAAG,sBAAqCA,aAoBjD,MAAMF,UAAkC,EAAA/T,UAAxC,c,oBAIE,KAAA4I,KAAO,IACErH,KAAKsP,KAAKjI,OAGnB,KAAAjG,OAA4CmO,GACnC,UAAoBkD,EAAezS,KAAKc,MAAMjJ,UAAUR,IAAKkY,EAyBxE,CAtBE1O,SACE,MAAM,EAAsDb,KAAKc,OAA3D,UAAEjJ,EAAS,SAAE0J,EAAQ,iBAAEY,GAAgB,EAAKxF,E,yUAAK,GAAjD,6CACN,OACE,SAAC,IAAK,iBACCA,EAAK,CACVhB,UAAU,uBACVF,MAAQ5D,EAAUY,KAClBuX,UAAYhQ,KAAKqH,KACjB4I,UAAW,EACXlX,KAAO,SACP4Z,eAAgB,GAAI,WAEpB,SAAC,IAAI,CACH3Q,IAAOoF,GAAWpH,KAAKsP,KAAOlI,EAC9BhG,OAASpB,KAAKoB,OACde,iBAAmBA,EACnBC,YAAcb,EACdpH,SAAW6F,KAAKc,MAAM3G,aAI9B,EAhCO,EAAArB,YAAc,4BAmCvB,SAAe,SACb,OACE0Z,EAA2B,CACzB1T,KAAM,CACJqD,iBAAkB,EAAGxM,WACZ,QAAkB,GAAG8c,EAAe9c,EAAM0a,OAAOqC,4BAE1DnR,SAAU,EAAG5L,WAAY,QAAkB8c,EAAe9c,EAAM0a,OAAOqC,cACvE7a,UAAW,EAAGlC,SAASya,IACdA,EAAOG,IAAI,GAAG,sBAAqC5a,EAAM0a,OAAOqC,kBAK/E,0B,kKClEF,MAAME,EAAoB,EAAGna,OAAMiD,cAAajG,UAASod,eAChD,CACLxb,GAAIoB,EACJA,OACAiD,cACAjG,UACAqd,UAAW,CACTC,SAAUF,EAASpa,MAErBua,KAAM,KAsCV,GAxBuB,EAAAlG,EAAA,IACrB,EAAGiF,mBAAkBvZ,aAAYya,YAAWlR,cAC1C,SAACiQ,EAAA,EAAS,CAERD,iBAAmBA,EACnBvZ,WAAeA,EAAaoa,EAAkBpa,QAAcwI,EAC5DkS,SAAWD,EACXlR,QAAUA,GAJJgQ,EAAiBtZ,OAO3B,CACEqG,KAAM,CACJtG,WAAY,EAAGuZ,sBACTA,EAAiBoB,UAAYpB,EAAiBja,QACzC0J,QAAQC,aAAQT,IAGlB,OAAkB,GAAGmR,EAAA,oBAAqCJ,EAAiBtZ,eAAe,IAGrG2a,eAAe,I,0BCpCnB,MAyCA,GAAe,EAAAtG,EAAA,IA/BmF,EAChGgF,oBAAmB/P,aAEc,IAA7B+P,EAAkB/a,QAElB,SAACgR,EAAA,EAAO,CACNrM,aACE,UAAC+R,EAAA,EAAK,eAACzR,QAAU+F,EAAQyL,UAAU,0BAAwB,4FAE/B,SAAC,KAAI,eAACtF,GAAG,iCAA+B,iCAAyB,aAG/FnP,KAAOiP,EAAA,UAMX,+BAAKrM,UAAU,oBAAkB,YAC/B,SAAC2W,EAAA,EAAmB,CAClBvQ,QAAUA,KAEZ,gBAAKpG,UAAU,gBACf,8BAAKA,UAAU,oBAAkB,UAC7BmW,EAAkB5S,KAAID,GAlChB,EAACpH,EAA0BkK,KAEvC,SAAC,EAAc,CAEbgQ,iBAAmBla,EACnBkK,QAAUA,GAFJlK,EAAUY,MA+BewZ,CAAQhT,EAAG8C,SAE1C,SAACyQ,EAAA,EAAyB,SAKqF,CACnH1T,KAAM,CACJgT,kBAAmBK,EAAA,kBAErB9S,kBAAmB,CAACC,GAAqBC,kBACvCD,EAAkB6S,EAAA,aAA+BA,EAAA,SAA0B,IAAM5S,MACjFD,EAAkB6S,EAAA,aAA+BA,EAAA,WAA4B,IAAM5S,MACnFD,EAAkB6S,EAAA,aAA+BA,EAAA,WAA4B,IAAM5S,KAAc,G,qFCzErG,MAAMqO,EAAQ,CACZ,wBACA,yBACA,2BAYF,EATiE9M,IAC/D,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,gMCab,MAAMyF,EAA8C,EAChD7a,aAAYuZ,mBAAkBuB,YAAWC,gBAEvCxB,IAAqBuB,EAChB,MAIP,SAACnG,EAAA,EAAY,CACXxS,QAAU4X,EAAA,MACVnF,SAAWkG,EAAY,YAAc,aACrC3X,UAAU,wBACV8U,SAAWjY,EACXuN,QAAUwN,IAoDhB,EA/CsE,EAClE/a,aAAYuZ,mBAAkBuB,YAAWC,aAAYxR,cAEvD,+BAAKpG,UAAU,iBAAe,WAC1BnD,IACA,SAAC6a,EAAa,CACZ7a,WAAaA,EACbuZ,iBAAmBA,EACnBuB,UAAYA,EACZC,WAAaA,IAGfxB,IACA,SAAC,KAAU,CACTpX,QAAU4X,EAAA,SACViB,IAAM,CAAE,YAAa,UAAW,UAChCC,aAAeC,EAAA,YACfjD,SAAWsB,EACXpW,UAAU,gBACVC,QAAUmG,EAAQW,UAAU,aAC5BiR,QAAS,EACTjD,eAAe,0BACfkD,qBAAqB,iBAGvBpb,IACA,UAACkV,EAAA,EAAY,eACX/R,UAAU,0BACVzD,IAAMia,EAAA,mBAAsC3Z,EAAWC,MAAI,YAE3D,SAAC+L,EAAA,EAAI,CACHzL,KAAOiP,EAAA,SAEPjG,EAAQW,UAAU,iBAGtBqP,IACA,SAAC5E,EAAA,EAAY,CACXxS,QAAU4X,EAAA,SACVnF,SAAW2E,EAAiB/Z,QAAU,OAAS,QAC/C2D,UAAU,gBACV8U,SAAWsB,Q,gDCrDnB,MAAM8B,EAAkC,EAAGpY,QAAOqY,cAAanY,YAAWoG,cACxE,IAAK+R,EACH,OAAO,KAGT,MAAMC,EAAeD,EAAYd,KAA6BjR,EAAQvG,EACpE,gBACA,CACEoO,aAAc,mCACdC,QAAS,CACPpU,QAASqe,EAAYre,QACrBud,KAAM,IAAOc,EAAYd,MAAMgB,KAAK,UANFF,EAAYre,QAWpD,OACE,+BAAKkG,UAAYA,GAAS,WACtB,GAAGF,OACL,0BACIsY,OAGP,EAGGE,EAAe,CAAClS,EAA8BvJ,EAA4BuZ,KAC9E,IAAImC,EASJ,OARInC,GAAoBA,EAAiBmC,SACvCA,EAASnC,EAAiBmC,QAGxB1b,IACF0b,EAAS1b,EAAWsa,UAAUC,UAG3BmB,EAIEnS,EAAQvG,EAAE,WAAY,CAC3BoO,aAAc,gBACdC,QAAS,CACPqK,YANK,IAQP,EAGEC,EAAa,CACjBpS,EACAgQ,EACAmB,IAEInB,IAAqBA,EAAiBja,QACjCiK,EAAQW,UAAU,uBAGvBwQ,EACKnR,EAAQvG,EACb,+BACA,CACEoO,aAAc,sEACdC,QAAS,CACP1J,OAAO,QAAsB+S,MAM9BnR,EAAQW,UAAU,wBAe3B,MAAMsP,UAAkB,gBAAxB,c,oBAqBE,KAAApS,MAAe,CACb2T,YAAY,GAGd,KAAAa,sBAAyB7b,IACnBA,EAAKF,aAAe2H,KAAKc,MAAMtI,WAAYC,MAI/CuH,KAAKS,SAAS,CACZ8S,YAAY,GACZ,EAGJ,KAAAc,wBAA2B9b,IACrBA,EAAKF,aAAe2H,KAAKc,MAAMtI,WAAYC,MAI/CuH,KAAKS,SAAS,CACZ8S,YAAY,GACZ,CAoEN,CAjEE7S,oBACE,MAAM,kBAAEpB,EAAiB,WAAE9G,GAAewH,KAAKc,MAEzCtI,IAEJ8G,EAAkB6S,EAAA,aAA+BA,EAAA,uBAAyCnS,KAAKoU,uBAE/F9U,EAAkB6S,EAAA,aAA+BA,EAAA,yBAA2CnS,KAAKqU,yBAEjG/U,EAAkB6S,EAAA,aAA+BA,EAAA,sBAAwCnS,KAAKqU,yBAElG,CAEAxT,SACE,MAAM,WAAErI,EAAU,iBAAEuZ,EAAgB,SAAEmB,EAAQ,QAAEnR,GAAY/B,KAAKc,OAC3D,WAAEyS,GAAevT,KAAKJ,OACtB,UAAE8C,GAAcX,EAEhBuR,IAAcvB,KAAsBvZ,IACxC,QAAgBuZ,EAAiBtc,QAAS+C,EAAW/C,SAAW,EAElE,OACE,+BAAKkG,UAAU,kBAAgB,YAC7B,SAAC2Y,EAAA,EAAa,CACZvC,iBAAmBA,EACnBuB,UAAYA,KAEd,+BAAK3X,UAAU,WAAS,YACtB,4BAAGA,UAAU,UAAQ,UACjBnD,EAAaA,EAAWC,KAAOsZ,EAAkBtZ,SAErD,8BAAKkD,UAAU,eAAa,UACxBsY,EAAalS,EAASvJ,EAAYuZ,OAEtC,8BAAKpW,UAAU,eAAa,WAC1B,0BAAQnD,EAAaA,EAAWkD,YAAcqW,EAAkBrW,kBAElE,+BAAKC,UAAU,iBAAe,YAC5B,SAACkY,EAAO,CACNlY,UAAU,MACVF,MAAQiH,EAAU,kBAClBoR,YAActb,EACduJ,QAAUA,KAEZ,0BACKvJ,GAAc2b,EAAWpS,EAASgQ,EAAkBmB,MAEzD,SAACW,EAAO,CACNlY,UAAYnD,EAAe8a,EAAuB,WAAX,cAAyBtS,EAChEvF,MAAQiH,EAAU,qBAClBoR,YAAc/B,EACdhQ,QAAUA,SAGd,SAAC,EAAsB,CACrBgQ,iBAAmBA,EACnBvZ,WAAaA,EACb+a,WAAaA,EACbD,UAAYA,EACZvR,QAAUA,WAKpB,EAGF,SAAe,EAAAwS,EAAA,GAA4CvC,E,gGC7N3D,MAAMwC,EAAgB,CAACzC,EAA6CuB,IAC7DvB,EAIDuB,EACK,wBAGJvB,EAAiBja,QAIf,qBAHE,uBARA,KA8BX,EAVoD,EAAGia,mBAAkBuB,YAAWnU,OAAO,WACzF,8BAAKxD,UAAU,YAAU,WACvB,SAAC,IAAI,CACH5C,KAAO,cACPoG,KAAOA,EACPsV,WAAaD,EAAczC,EAAkBuB,O,kBCnCnDlc,EAAOyU,QAAU,CACf3T,IAAK,aACLuD,MAAO,aACP1C,KAAM,SACNqK,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,mBACPvD,IAAK,SACLwP,QAAQ,EACRtE,UAAW,YACV,CACD3H,MAAO,oBACPvD,IAAK,WACLwP,QAAQ,EACRtE,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,oBACPvD,IAAK,oBACLkL,UAAW,YACV,CACD3H,MAAO,oBACPvD,IAAK,oBACLkL,UAAW,a,qFCtBjB,MAAMwK,EAAQ,CACZ,eACA,eACA,kBAYF,EATqD9M,IACnD,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,gICAb,MAAM3R,EAAkD,EAAGyY,iBACzD,2BACE,6BAAI/Y,UAAU,iBAAe,WAC3B,SAAC,KAAQ,CACP6X,IAAM,CAAE,YACRmB,SAAS,SACTC,KAAOF,EAAWE,KAClBlE,eAAe,0BACf+C,aAAe,eAGnB,6BAAI9X,UAAU,SAAO,UACjB+Y,EAAWG,uBAMblE,EAAU+D,IAEZ,SAACzY,EAAG,CAEFyY,WAAaA,GADPA,EAAWE,KAAKE,KAuC5B,GAAe,QA3BqD,EAAGC,UAAShT,cAC9E,MAAM,UAAEW,GAAcX,EACtB,OAAuB,IAAnBgT,EAAQhe,QAER,SAAC,IAAO,CACN0E,MAAQiH,EAAU,uBAMtB,0BACE,iCAAO/G,UAAU,oBAAkB,YACjC,4BACE,2BACE,wBAAM+G,EAAU,WAChB,wBAAMA,EAAU,4BAGpB,2BACIqS,EAAQ7V,IAAIyR,UAIrB,GAGoF,CACrF7R,KAAM,CACJiW,QAAS,iBAEX1V,kBAAmB,CAACC,GAAqBC,kBACvCD,EAAkB,eAA0B,kBAA4B,IAAMC,MAC9ED,EAAkB,eAA0B,oBAA8B,IAAMC,KAAc,G,uPCrE9FjI,EAAU,CAAC,EAEfA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,W,0BCXlD,MAmCMsW,EAAQ,CACZ,wBACA,2BACA,wBACA,uBAqBF,EAlBqD9M,IAOnD,OAJI+E,EAAA,wBAAmC,cACrC+H,EAAMzW,KAAK,kBAIX,0BACE,SAACwM,EAAA,EAAiB,iBACX7C,EAAK,CACV7J,KAAO2W,EACPE,gBAtDmB/L,EAsDgBjB,EAAMiB,QArDC,CAAC1K,EAAI0W,EAAcC,KAEtD,kBAAP3W,IACF0W,EAAaE,MACX,SAACR,EAAA,EAAK,eACJzR,QAAU+F,EAAQyL,WAChB,QAAc,UAA8CnW,OAAI2J,KACjE,WAED,mHAEE,mBACA,mBACA,oDAEE,2BACE,oDACA,8CACA,oDACA,2CACA,6CACA,uD,QAtBU,IAACe,CAyDxB,C,uJC3DH,MAAM6L,EAAQ,CACZ,OACA,cACA,QACA,kBACA,iBAiEF,EAVqD9M,IAAS,OAC5D,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,EACPE,gBAzDqB/L,EAyDcjB,EAAMiB,QAxDG,CAAC1K,EAAI0W,EAAcC,KACjE,GAAW,oBAAP3W,EAA0B,CAC5B,IAAIgJ,EAEJ,MAAM2U,EAAYhH,EAAU3W,GAC5B,OAAQ2d,GACN,KAAK,YAEH3U,EAAU,oHACV,MAEF,KAAK,SAEHA,EAAU,6GACV,MAEF,KAAK,SAEHA,EAAU,uIAMVA,IACF0N,EAAaE,KAAOlM,EAAQvG,GAC1B,QAAc,UAA8CnE,EAAI2d,EAAUC,YAC1E5U,G,KAGY,kBAAPhJ,IACT0W,EAAaE,MACX,UAAC,IAAK,eACJjS,QAAU+F,EAAQyL,WAAU,QAAc,UAA8CnW,OAAI2J,KAAW,YAEvG,mGAGA,2JAGM,SAAC,IAAY,eAAC9I,IAAM,qBAA6B,4CAA8C,W,QA1CrF,IAAC6J,CA4D1B,C,kBCjFD3K,EAAOyU,QAAU,CACf3T,IAAK,UACLuD,MAAO,UACP1C,KAAM,OACNqK,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,OACPvD,IAAK,OACLkL,UAAW,YACV,CACD3H,MAAO,YACPvD,IAAK,OACLkL,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,gBACPvD,IAAK,gBACLwP,QAAQ,EACRtE,UAAW,YACV,CACD3H,MAAO,gBACPvD,IAAK,gBACLkL,UAAW,a,oJCbjB,MASM8R,EAA0D,CAC9DtO,IAAK,CACH9N,YAAa,WACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACNxO,QAdsC,EAAGW,eAC3C2U,EAAA,OAAa,GAAG3U,EAASC,kBAAkB,IAiBvC+a,EAAqD,CACzD7a,OAAQ,CACNxB,YAAa,cACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACNzN,aAAc,CACZpB,QAAS,mEACTD,eAAgB,cAChBsB,cAAe,gBAEjBhB,QAxB2C,EAAGjB,KAAM4K,KAC/CoJ,EAAA,OAAmB6I,EAAA,sBAAoC,CAAEjS,WA2BlE,GACE0L,OAAQ,CACNnU,SAAU,cACVS,MAAO,eACPR,QAASua,GAEXlG,KAAM,CACJtU,SAAU,cACVS,MAAO,eACPR,QAASwa,I,4FC9Bb,MAAMlZ,EAAmC,EAAGkH,WAC1C,yBACE,6BAAIxH,UAAU,iBAAe,WAC3B,SAAC,KAAU,CACTC,SAAU,4BAAUuH,IACpBxI,QAAU0a,EAAoBrG,KAE9ByB,SAAWtN,EACXuN,eAAe,iCAMjBC,EAAUxN,IAEZ,SAAClH,EAAG,CAEFkH,KAAOA,GADDA,GAaZ,MAAMmS,UAAoB,YAGxBzU,SACE,MAAM,SAAE0U,EAAQ,QAAExT,GAAY/B,KAAKc,OAC7B,UAAE4B,EAAS,UAAE8K,GAAczL,EACjC,OACE,4BACE,SAACgG,EAAA,EAAO,CACNtM,OACE,4BACE,0BACE,SAACgS,EAAA,EAAK,eAACzR,QAAUwR,EAAU,qBAAmB,yEAIhD,mBACA,SAACL,EAAA,EAAY,CACXxS,QAAUG,EAAA,EACVsS,SAAS,eAIfrU,KAAOiP,EAAA,UAGT,SAACmF,EAAA,EAAY,CACXxS,QAAU0a,EAAoBxG,OAC9BzB,SAAS,MACTzR,UAAU,QAGV4Z,EAASxe,OAAS,IAClB,iCAAO4E,UAAU,oBAAkB,YACjC,4BACE,yBACE,wBAAM+G,EAAU,eAGpB,2BACI6S,EAASrW,IAAIyR,UAKrB,SAAC,IAAsB,CACrB6E,UAAYrS,IAAQ,SAClB,IAAMoJ,EAAA,OAAmB6I,EAAA,mBAAiC,CAAEjS,UAC5DpB,EAAQoH,QAEVsM,YAAY,GACZhG,UAAYC,EAAA,mBACZgG,UAAYhT,EAAU,qBACtBiT,WAAa,mBAIrB,EAxDO,EAAA7c,YAAc,cA2DvB,SAAe,EAAAgU,EAAA,GAAsBwI,EAAa,CAChDxW,KAAM,CACJyW,SAAUH,EAAA,gBAEZ/V,kBAAmB,CAACC,GAAqBC,kBACvCD,EAAkB8V,EAAA,aAA2BA,EAAA,iBAA8B,IAAM7V,MACjFD,EAAkB8V,EAAA,aAA2BA,EAAA,mBAAgC,IAAM7V,KAAc,G,4OCzFrG,MAAMqW,EAAgD,EAClDC,eAAc7d,UAAS+J,cAEzB,MAAM,UAAEyL,EAAS,UAAE9K,GAAcX,GACzB+T,EAAQC,GAAc,YAAe,GAC7C,OACE,+BAAKpa,UAAU,mBAAiB,YAC9B,6BAAIA,UAAU,SAASS,MAAO,CAAE4Z,UAAW,SAAQ,UAC/CtT,EAAU,mBAEd,SAACqF,EAAA,EAAO,CACNrM,aACE,SAAC+R,EAAA,EAAK,eAACzR,QAAUwR,EAAU,uBAAqB,6QAMlDzU,KAAOiP,EAAA,UAGT,SAACiO,EAAA,EAAQ,CACPra,QAAU8G,EAAU,iCACpBwT,QAAUJ,EACV9P,SAAWhO,EACXme,SAAWJ,EACXK,UAAW,KAEb,SAACtQ,EAAA,EAAM,CACLnK,UAAU,kBACVC,QAAU8G,EAAU,gBACpB3J,KAAOiP,EAAA,YACPjC,QAAU/N,EACV6D,QAAU,IAAMga,EAAaC,QAGlC,EAUH,MAAMO,UAA2B,YAAjC,c,oBACE,KAAAC,eAAkBR,KAChB,SACE,IAAMvJ,EAAA,OAAmBgK,EAAA,wBAAqC,CAAET,YAChE9V,KAAKc,MAAMiB,QAAQoH,OACpB,CAiCL,CA9BEtI,SACE,MAAM,OAAEgM,EAAM,QAAE9K,GAAY/B,KAAKc,OAC3B,UAAE4B,EAAS,OAAEyG,GAAWpH,EAC9B,OACE,+BAAKpG,UAAU,4BAA0B,YACvC,6BAAIA,UAAU,UAAQ,UAClB+G,EAAU,qBAEd,UAACnG,EAAA,GAAI,eAACE,QAAQ,OAAK,YACjB,SAAC,KAAG,CACFhB,MAAQiH,EAAU,mBAClB3G,MAAO,QAAW8Q,EAAO2J,gBAAiBrN,GAC1CjN,WAAW,UAEb,SAAC,KAAG,CACFT,MAAQiH,EAAU,mBAClB3G,MAAO,QAAW8Q,EAAO4J,gBAAiBtN,GAC1CjN,WAAW,aAGb2J,EAAA,YAAqB,sBACrB,SAAC+P,EAAc,CACb5d,QAAU6U,EAAO6J,oBACjBb,aAAe7V,KAAKsW,eACpBvU,QAAUA,OAKpB,EAGF,SAAe,EAAA+K,EAAA,GAA4EuJ,EAAoB,CAC7GvX,KAAM,CACJ+N,OAAQ0J,EAAA,uBAEVlX,kBAAmB,CAACC,GAAqBC,kBACvCD,EAAkBiX,EAAA,aAA0BA,EAAA,mBAA+B,IAAMhX,KAAc,ICnH7FqO,EAAQ,CACZ,iBACA,oBACA,sBAgBF,EAbwD9M,IACtD,4BACE,SAAC6C,EAAA,EAAiB,iBACX7C,EAAK,CACV7J,KAAO2W,MAGT,SAAC,EAAkB,CACjB7L,QAAUjB,EAAMiB,Y,qFCftB,MAAM6L,EAAQ,CACZ,eACA,wBACA,kBACA,qBAYF,EAT+D9M,IAC7D,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,qJCHb,MAAM+I,EAAczT,IAA4BA,EAAK0T,QAiC/CC,EAA0D,CAC9DhI,OAAQ,CACN/V,YAAa,cACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACN/O,MAAO,CACLC,eAAgB,SAChBC,QAAS,6BACTC,WAAY,CACVC,YAAa,aACbE,UAAU,IAGdC,QA3CyC,CAACjB,EAAME,IAC3C8T,EAAA,OAAmBuK,EAAA,eAAoC,CAAEre,KAAMA,MA8ClEse,EAA+D,CACnEC,OAAQ,CACNle,YAAa,eACbE,OAAQ,oBACRD,KAAMiP,EAAA,WACNxO,QA/BqD,EACrDjB,KAAMgG,EAASpE,cAEV8c,EAAA,UAA+B9c,EAAUoE,EAAQlH,GAAI6f,EAAA,IA8B5D7c,QAAS,KACT2U,KAAM,CACJlW,YAAa,iBACbE,OAAQ,mBACRD,KAAMiP,EAAA,OACN/O,MAAOsF,IAAW,CAChBrF,eAAgB,SAChBC,QAAS,+CACTC,WAAY,CACVC,YAAa,aACbuQ,aAAcrL,EAAQ9F,KACtBc,UAAU,KAGdC,QA5DmD,EACnDjB,KAAMgG,GACR9F,IAEO8T,EAAA,QAAoB,GAAGuK,EAAA,kBAAsCvY,EAAQlH,KAAM,CAAEoB,KAAMA,KA0D1Fme,QAAS,CACP9d,YAAa,iBACbE,OAAQ,mBACRD,KAAMiP,EAAA,UACNlO,OAAQ6c,EACRnd,QAvEsD,EAAGjB,KAAMgG,KAC1DgO,EAAA,OAAmB,GAAGuK,EAAA,kBAAsCvY,EAAQlH,eAwE3EiD,OAAQ,CACNxB,YAAa,iBACbE,OAAQ,mBACRD,KAAMiP,EAAA,SACNlO,OAAQ6c,EACRpc,aAAc,CACZpB,QAAS,kEACTD,eAAgB,iBAChBsB,cAAe,gBAEjBhB,QAxEqD,EACrDjB,KAAMgG,KAEDgO,EAAA,SAAqBuK,EAAA,eAAqC,IAAMvY,EAAQlH,MA0EjF,GACEwX,OAAQ,CACNnU,SAAU,cACVS,MAAO,UACPR,QAASkc,GAEX7H,KAAM,CACJtU,SAAU,cACVS,MAAO,UACPR,QAASoc,I,2FCzFb,MAAMI,EAAkD,EAAG5Y,UAAS/C,MAClE,2BACE,6BAAIG,UAAU,iBAAe,WAC3B,SAAC,KAAU,CACTC,SAAU,4BAAU2C,EAAQC,MAC5B7D,QAAUyc,EAAoBpI,KAC9ByB,SAAWlS,EACXmS,eAAe,gCAGnB,6BAAI/U,UAAU,QAAM,WAChB,QAAW4C,EAAQY,KAAM3D,OAE7B,6BAAIG,UAAU,SAAO,UACjB4C,EAAQ8Y,YAwDhB,GAAe,EAAAC,EAAA,IAjD+E,EAC1FvV,UAAShD,eAEX,MAAM,UAAE2D,EAAS,UAAE8K,GAAczL,EACjC,OACE,4BACE,SAACgG,EAAA,EAAO,CACNrM,aACE,0BACE,UAAC+R,EAAA,EAAK,eAACzR,QAAUwR,EAAU,sBAAoB,YAC7C,uLAIA,6FACkE,SAAC,KAAI,eAACtF,GAAG,UAAQ,qBAAa,kBAKtGnP,KAAOiP,EAAA,UAET,SAACmF,EAAA,EAAY,CACXxS,QAAUyc,EAAoBvI,OAC9BzB,SAAS,YAGX,iCAAOzR,UAAU,oBAAkB,YACjC,4BACE,2BACE,wBAAM+G,EAAU,WAChB,wBAAMA,EAAU,iBAChB,wBAAMA,EAAU,uBAGpB,2BACI3D,EAASG,KAAIX,IACb,SAAC4Y,EAAe,CAEd5Y,QAAUA,EACV/C,EAAIuG,EAAQoH,QAFN5K,EAAQlH,cAQzB,IAGqD,OAAO2J,GAAW,E,qFC9F1E,MAAM4M,EAAQ,CACZ,eACA,sBACA,qBACA,wBACA,kBAGI8D,EAAW,CACf,iBACA,wBAiBF,EAd+D5Q,IAC7D,4BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,MAET,SAAC,IAAiB,eAChBnS,MAAQqF,EAAMiB,QAAQW,UAAU,aAC3B5B,EAAK,CACV7J,KAAOya,O,kBC1Bbta,EAAOyU,QAAU,CACf3T,IAAK,UACLuD,MAAO,UACP1C,KAAM,QACNqK,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,kBACPvD,IAAK,kBACLkL,UAAW,YACV,CACD3H,MAAO,iBACPvD,IAAK,WACLwP,QAAQ,EACRtE,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,kBACPvD,IAAK,kBACLkL,UAAW,YACV,CACD3H,MAAO,UACPvD,IAAK,UACLkL,UAAW,YACV,CACD3H,MAAO,iBACPvD,IAAK,WACLwP,QAAQ,EACRtE,UAAW,a,wICbjB,MAAMmU,UAAuB,EAAA9Y,UAA7B,c,oBASE,KAAA+Y,WAAa,IACJ,GAAGxX,KAAKc,MAAMxH,mBAIvB,KAAAoI,eAAyC,CAAC+V,EAAYzJ,EAAWpM,KAC/D,MAAM8V,EAAiB1X,KAAKwX,aAC5B,OAAIC,IAAeC,GAAmB1J,EAAU0J,GAIzC,SAAmB,mBAAgC,CACxDzgB,KAAM+I,KAAKc,MAAM7J,KAAK6C,QAAOuU,GAAOA,IAAQqJ,IAC5CzT,WAAY,kBALL,IAMP,EAIJ,KAAA6J,eAA+C,CAAC6J,EAAY5J,EAAcC,KACpEA,EAAUhO,KAAKwX,eAAiBG,IAAe3X,KAAKwX,eACtDzJ,EAAa/H,UAAW,E,CAe9B,CAXEnF,SACE,OACE,8BAAKlF,UAAU,cAAY,WACzB,SAAC,IAAiB,iBACXqE,KAAKc,MAAK,CACfY,eAAiB1B,KAAK0B,eACtBoM,eAAiB9N,KAAK8N,oBAI9B,EA1CO,EAAA7H,UAAY,CAEjBhP,KAAM,qBAGNqC,KAAM,uBAwCV,S,gGCzDA,MAAMse,EAAO,CACX,uBACA,iBACA,4BAGIC,EAAS,CACb,+BAsBF,EAnB8D/W,IAC5D,MAAM,UAAE4B,GAAc5B,EAAMiB,QAC5B,OACE,4BACE,SAAC,IAAc,iBACRjB,EAAK,CACV7J,KAAO2gB,EACPte,KAAK,eAGP,SAAC,IAAiB,iBACXwH,EAAK,CACVrF,MAAQiH,EAAU,gBAClBzL,KAAO4gB,OAGZ,C,qFC5BH,MAAMjK,EAAQ,CACZ,oBACA,uBAaF,EATwD9M,IACtD,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,qHCJb,MAAMA,EAAQ,CACZ,iBACA,gBAqBF,EAlBsD9M,IACpD,MAAM,UAAE0M,GAAc1M,EAAMiB,QAC5B,OACE,4BACE,8BAAKpG,UAAU,cAAY,WACzB,UAAC,IAAK,eAACK,QAAUwR,EAAU,wBAAsB,oIAEvC,SAAC,IAAY,eAACtV,IAAM,mBAA2B,6BAAiC,gCAG5F,SAAC,IAAiB,iBACX4I,EAAK,CACV7J,KAAO2W,OAGZ,C,gGCxBH,MAAMgK,EAAO,CACX,qBACA,eACA,0BACA,sBAGIC,EAAS,CACb,uBACA,uBAsBF,EAnB4D/W,IAC1D,MAAM,UAAE4B,GAAc5B,EAAMiB,QAC5B,OACE,4BACE,SAAC,IAAc,iBACRjB,EAAK,CACV7J,KAAO2gB,EACPte,KAAK,aAGP,SAAC,IAAiB,iBACXwH,EAAK,CACVrF,MAAQiH,EAAU,gBAClBzL,KAAO4gB,OAGZ,C,qFC5BH,MAAMD,EAAO,CACX,kBACA,WACA,UAaF,EAV0D9W,IACxD,0BACE,SAAC,IAAc,iBACRA,EAAK,CACV7J,KAAO2gB,EACPte,KAAK,U,kBCjBXlC,EAAOyU,QAAU,CACf3T,IAAK,eACLuD,MAAO,mBACP1C,KAAM,YACNqK,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,mBACPvD,IAAK,QACLkL,UAAW,WACV,CACD3H,MAAO,qBACPvD,IAAK,UACLkL,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,kBACPvD,IAAK,kBACLkL,UAAW,YACV,CACD3H,MAAO,gBACPvD,IAAK,gBACLkL,UAAW,YACV,CACD3H,MAAO,kBACPvD,IAAK,cACLkL,UAAW,a,2GCnBjB,MAAM0U,EAAU,CACd,qBACA,uBACA,gBACA,gBAGIC,EAAQ,CACZ,qCACA,0CACA,yCACA,8CAEA,qCACA,qCAEA,gCACA,qCACA,gCACA,qCACA,mCAEA,+BA4BF,EAzB+DjX,IAC7D,MAAM,UAAE4B,GAAc5B,EAAMiB,QAC5B,OACE,4BACE,SAAC,IAAY,CACXpH,QAAU,IACVyS,SAAS,gBAEX,SAAC,IAAiB,iBACXtM,EAAK,CACV7J,KAAO6gB,MAET,8BAAKnc,UAAU,aAAW,UACtB+G,EAAU,qBAEd,8BAAK/G,UAAU,cAAY,WACzB,SAAC,IAAiB,iBACXmF,EAAK,CACV7J,KAAO8gB,UAId,C,meC1CH,MAAMC,UAAmB,EAAAvZ,UAAzB,c,oBACE,KAAAmB,MAAQ,CACNqY,SAAS,GAGX,KAAAC,WAAcC,GACL,OAAOnY,KAAKc,MAAMwB,UAAU6V,EAAS,IAAIA,IAAW,KAG7D,KAAAC,mBAAsB7W,IACpBvB,KAAKS,SAAS,CACZwX,QAAS1W,EAASvB,KAAKkY,eACvB,EAGJ,KAAAG,qBAA+C,CAAChhB,EAAI2W,EAAWpM,KAC7D5B,KAAKS,SAAS,CACZwX,QAASjK,EAAU3W,IACnB,EAGJ,KAAAihB,iBAA4C,CAACjhB,EAAI0W,EAAcC,KAC7DD,EAAa/H,UAAYhG,KAAKJ,MAAMqY,OAAO,EAG7C,KAAAM,cAAiB5c,GACXqE,KAAKJ,MAAMqY,QACNtc,EAAY,UAGdA,CAqCX,CAlCEkF,SACE,MAAM2X,EAAQ,CACZxY,KAAKkY,cAGD9T,EAAU,CACdpE,KAAKkY,WAAW,QAChBlY,KAAKkY,WAAW,WAGZ,EAAuBlY,KAAKc,OAA5B,OAAE2X,GAAM,EAAK9b,EAAK,IAAlB,YACN,OACE,+BAAKhB,UAAYqE,KAAKuY,cAAc,gBAAc,YAChD,8BAAK5c,UAAYqE,KAAKuY,cAAc,UAAQ,WAC1C,SAAC5U,EAAA,EAAiB,iBACXhH,EAAK,CACV1F,KAAOuhB,EACP9W,eAAiB1B,KAAKqY,qBACtBtU,wBAA0B/D,KAAKoY,0BAIhCK,IACD,8BAAK9c,UAAYqE,KAAKuY,cAAc,YAAU,WAC5C,SAAC5U,EAAA,EAAiB,iBACX3D,KAAKc,MAAK,CACf7J,KAAOmN,EACP0J,eAAiB9N,KAAKsY,0BAMlC,EAGF,UCrEA,MAuBA,EAvBwDxX,IACtD,MAAM,MAAErF,EAAK,YAAEid,EAAW,WAAEC,GAAyB7X,EAAVnE,E,yUAAK,CAAKmE,EAA/C,sCACN,OACE,0BACE,+BAAKnF,UAAU,YAAU,YACvB,8BAAKA,UAAU,aAAW,UACtBF,MAEJ,SAACmd,EAAA,GAAS,eAACjd,UAAU,SAASkd,YAAa,GAAI,UAC3CH,EAAYxZ,KAAI4Z,IAChB,mBAAC,EAAU,iBACJnc,EAAK,CACV0R,IAAMyK,EACNxW,QAAUwW,EACVL,SAAWE,IAAkD,IAApCA,EAAW5V,QAAQ+V,gBAMvD,E,eCnBH,MAAMlL,EAAQ,CACZ,iBAIImL,EAAqB,CACzB,OACA,KACA,SACA,UAGIC,EAAsB,CAC1B,YACA,UACA,kBAGIC,EAAoB,CACxB,kBAsCF,EAnCwDnY,IACtD,MAAM,UAAE4B,EAAS,UAAE8K,GAAc1M,EAAMiB,QACvC,OACE,4BACE,SAAC4B,EAAA,EAAiB,iBACX7C,EAAK,CACV7J,KAAO2W,MAET,+BAAKjS,UAAU,YAAU,YACvB,SAACoM,EAAA,EAAO,CACNhP,KAAOiP,EAAA,OACPtM,aACE,SAACgS,EAAA,EAAY,eAACxV,IAAMyV,EAAA,qBAA+B,WACjD,SAACF,EAAA,EAAK,eAACzR,QAAUwR,EAAU,iBAAe,yEAMhD,SAAC,EAAe,iBACT1M,EAAK,CACV4X,YAAcK,EACdtd,MAAQiH,EAAU,gBAEpB,SAAC,EAAe,iBACT5B,EAAK,CACV4X,YAAcM,EACdvd,MAAQiH,EAAU,aAClBiW,WAAaM,WAIpB,C,iIC3DH,MAAMC,EAAa,CACjB,iBACA,0BAGIC,EAAW,CACf,eACA,uBAEA,2BACA,gCAyDF,EAtD+DrY,IAC7D,MAAM,GAAQA,EAAMiB,QACpB,OACE,4BAeE,SAAC,IAAY,CACXpH,QAAU,IACVyS,SAAS,gBAGX,8BAAKzR,UAAU,aAAW,qBAG1B,8BAAKA,UAAU,cAAY,WACzB,SAAC,IAAiB,iBACXmF,EAAK,CACV7J,KAAOiiB,SAIX,8BAAKvd,UAAU,aAAW,sBAG1B,+BAAKA,UAAU,cAAY,YACzB,SAAC,IAAiB,iBACXmF,EAAK,CACV7J,KAAOkiB,MAGT,SAAC,IAAO,CACNzd,YAAcF,EACZ,kBACA,6EAEFzC,KAAO,iBAId,C,0EC1EH,MAAM6D,EAAa,YAEnB,EACcA,EADd,EAEaA,E,yDCUb,MAiBMwc,EAAqD,CACzDvK,OAAQ,CACN/V,YAAa,WACbC,KAAMiP,EAAA,SACNxO,QAlByC,EAAGW,eAC9C2U,EAAA,OAAa,GAAG3U,EAASC,iBAAiB,IAqBtCif,EAAqD,CACzDrK,KAAM,CACJlW,YAAa,YACbC,KAAMiP,EAAA,OACNxO,QAtB8C,EAAGjB,KAAMqc,EAAMza,eAC/D2U,EAAA,OAAa,GAAG3U,EAASC,kBAAkBwa,EAAKvd,KAAK,GAuBrDiD,OAAQ,CACNxB,YAAa,cACbgB,OAjCa8a,GAAsBA,EAAKvd,KAAOwO,EAAA,UAkC/C9M,KAAMiP,EAAA,SACNzN,aAAc,CACZpB,QAAS,mEACTD,eAAgB,cAChBsB,cAAe,gBAEjBhB,QA7BgD,EAAGjB,KAAMqc,KACpDrI,EAAA,SAAqB,GAAG+M,KAA8B1E,EAAKvd,QAgCpE,GACEwX,OAAQ,CACNnU,SAAU,cACVS,MAAO,UACPR,QAASye,GAEXpK,KAAM,CACJtU,SAAU,cACVS,MAAO,UACPR,QAAS0e,I,2GCxCFE,E,4CAAX,SAAWA,GACT,cACA,cACA,+BACD,CAJD,CAAWA,IAAAA,EAAgB,KAY3B,MAAMC,EAAoD,CACxDC,MAAO,gBAEPC,OAAQ,SACRC,SAAU,WACV7N,UAAW,YAEX8N,YAAa,CACXne,MAAO,SACPoe,OAAQN,EAAiBO,MAE3BC,YAAa,CACXte,MAAO,SACPoe,OAAQN,EAAiBS,MAG3BC,WAAY,CACVxe,MAAO,QACPoe,OAAQN,EAAiBO,MAE3BI,WAAY,CACVze,MAAO,QACPoe,OAAQN,EAAiBS,MAG3BG,mBAAoB,CAClB1e,MAAO,gBACPoe,OAAQN,EAAiBO,MAE3BM,mBAAoB,CAClB3e,MAAO,gBACPoe,OAAQN,EAAiBS,MAG3BK,cAAe,CACb5e,MAAO,WACPoe,OAAQN,EAAiBO,MAE3BQ,cAAe,CACb7e,MAAO,WACPoe,OAAQN,EAAiBS,MAG3BO,gBAAiB,CACf9e,MAAO,mBACPoe,OAAQN,EAAiBO,MAE3BU,gBAAiB,CACf/e,MAAO,mBACPoe,OAAQN,EAAiBS,MAG3BjO,UAAW,CACTtQ,MAAO,OACPoe,OAAQN,EAAiBO,MAE3BW,UAAW,CACThf,MAAO,OACPoe,OAAQN,EAAiBS,MAE3BU,UAAW,CACTjf,MAAO,OACPoe,OAAQN,EAAiBoB,eAG3BC,kBAAmB,CACjBnf,MAAO,eACPoe,OAAQN,EAAiBO,MAE3Be,kBAAmB,CACjBpf,MAAO,eACPoe,OAAQN,EAAiBS,MAE3Bc,kBAAmB,CACjBrf,MAAO,eACPoe,OAAQN,EAAiBoB,eAG3BI,eAAgB,CACdtf,MAAO,YACPoe,OAAQN,EAAiBO,MAE3BkB,eAAgB,CACdvf,MAAO,YACPoe,OAAQN,EAAiBS,MAG3BiB,eAAgB,CACdxf,MAAO,eACPoe,OAAQN,EAAiBO,MAE3BoB,eAAgB,CACdzf,MAAO,eACPoe,OAAQN,EAAiBS,OA+D7B,MAAMmB,UAAsB,EAAA1c,UAO1ByC,YAAYJ,GAhDG,IAACsO,EAiDdjO,MAAML,GAcR,KAAAsO,MAAQ,KACEpP,KAAKc,MAAM8T,KAGrB,KAAAvN,KAAO,IACErH,KAAKsP,KAAKjI,OAGnB,KAAAjG,OAAkCmO,GAC5BvP,KAAKoP,QACA7C,EAAA,OAAmB+M,EAA4B/J,GAGjDhD,EAAA,QAAoB,GAAG+M,KAA8BtZ,KAAKc,MAAM8T,KAAKvd,KAAMkY,GAGpF,KAAAzB,eAAiD,CAACzW,EAAI0W,EAAcC,KAClE,GAAW,gBAAP3W,EAAsB,CACxB,MAAM,KAAEud,EAAI,QAAE7S,GAAY/B,KAAKc,MAC/BiN,EAAa4B,QAAU,iBACvB5B,EAAa6B,SC9NQ,CAAC7N,GACnB,sCAAmC,CACxCqZ,aAAeC,IACb,MAwBMC,EAAcD,EAAO/jB,QACxBwC,QATsB,EAAG6H,YAC0B,IAAhD0Z,EAAO1Z,MAAMoB,QAAQ,aAAgCpB,IAAU,aASlEzC,KApBmB,EAAGyC,QAAO5F,WAC9B,SAACka,EAAA,EAAQ,CAEPta,UAAYgG,EACZuU,SAA2C,IAAjCmF,EAAO1Z,MAAMoB,QAAQpB,GAC/BwU,SAAWD,GAXE,EAACld,EAAwBkd,KACxCmF,EAAOlF,UACL,QAAwBkF,EAAO1Z,MAAO3I,EAAQkd,GAC/C,EAQuBC,CAASxU,EAAOuU,GACtCta,QAAUG,GAJJ4F,KAoBV,OACE,+BAAKhG,UAAU,qBAAmB,YAChC,SAACoM,EAAA,EAAO,CACNrM,YAAcqG,EAAQvG,EACpB,sBACA,0FAEFG,UAAU,UAEV2f,KAEL,IDoLuB,CAAmBvZ,GAC3CgM,EAAa/H,UAAYhG,KAAKoP,SAAWwF,EAAK7B,WAAalN,EAAA,e,KAC3C,aAAPxO,EACT0W,EAAazU,KAAO,WACJ,aAAPjC,IACT0W,EAAa/H,UAAYhG,KAAKoP,Q,EArChCpP,KAAKub,OAAQ,SAnDCnM,EAmDsBpP,KAAKoP,QAlDpC,CACL,CACEf,IAAK,WACL5S,MAAO,YACPnC,KAAM,aAER,CACE+U,IAAK,WACL/U,KAAM,YACNmC,MAAO2T,EAAQ,WAAa,eAC5BoM,UAAWpM,GAEb,CACEf,IAAK,cACL5S,MAAO,cACPnC,KAAM,UACN6X,UAAW,eAkCsCrQ,EAAMiB,SAEzD,MAAM0Z,GAAc,QAAc3a,EAAMiB,QAAS,sBAC3CuZ,EAActb,KAAKub,MAAM9X,MAAKiY,GAAmB,gBAAZA,EAAIrN,MAC/CrX,OAAO+J,OAAOua,EAAa,CACzBhkB,QAASN,OAAOC,KAAK2U,EAAA,GAAiB+P,QACpC,CAACC,EAASC,IA1Ee,EAACvkB,EAAkC+W,EAAatM,KAC/E,MAAM+Z,EAAetC,EAAenL,GAapC,MAZ4B,iBAAjByN,EACTxkB,EAAQH,KAAK,CACXE,GAAIuU,EAAA,EAAgByC,GACpB5V,KAAMsJ,EAAQW,UAAUoZ,KAG1BxkB,EAAQH,KAAK,CACXE,GAAIuU,EAAA,EAAgByC,GACpB5V,KAAM,GAAGsJ,EAAQW,UAAUoZ,EAAargB,WAAWsG,EAAQW,UAAUoZ,EAAajC,aAI/EviB,CAAO,EA4DUykB,CAAyBH,EAASC,EAAKJ,IACzD,KAGN,CA+BA5a,SACE,MAAM,EAA8Bb,KAAKc,OAAnC,KAAE8T,EAAI,QAAE7S,GAAO,EAAKpF,E,yUAAK,GAAzB,oBACAlB,EAAQsG,EAAQW,UAAU1C,KAAKoP,QAAU,eAAiB,aAEhE,OACE,SAACW,EAAA,EAAK,eACJpU,UAAU,WACVF,MAAQA,EACRuU,UAAYhQ,KAAKqH,KACjB4I,UAAW,EACXlX,KAAOiP,EAAA,QACFrL,EAAK,WAEV,SAACuT,EAAA,EAAI,CACHlO,IAAOoF,GAAWpH,KAAKsP,KAAOlI,EAC9BjF,iBAAmBnC,KAAKub,MACxBzN,eAAiB9N,KAAK8N,eACtB1M,OAASpB,KAAKoB,OACdgB,YAAcpC,KAAKc,MAAM8T,KACzBza,SAAW6F,KAAKc,MAAM3G,aAI9B,EAzEO,EAAArB,YAAc,gBA4EvB,SAAe,EAAAqX,EAAA,KACb,EAAArD,EAAA,GAA+DqO,EAAe,CAC5Erc,KAAM,CACJ8V,KAAM,EAAGjf,SAASya,IACXza,EAAM0a,OAAO2L,OAIX5L,EAAOG,IAAI,GAAG+I,KAA8B3jB,EAAM0a,OAAO2L,UAHvDxa,QAAQC,aAAQT,MAO/B,kB,yBEpQF,MAAMib,EAAwC,EAAGrH,OAAM7S,cACrD,2BACE,6BAAIpG,UAAU,iBAAe,WAC3B,SAAC,KAAU,CACTC,SAAU,4BAAUgZ,EAAK7B,WACzBpY,QAAUuhB,EAAelN,KACzByB,SAAWmE,EACXlE,eAAe,gCAGnB,6BAAI/U,UAAU,eAAa,WAC6B,IAApDiZ,EAAK0G,YAAYvY,QAAQ,YACvBhB,EAAQW,UAAU,iBAClBkS,EAAK0G,YAAYvkB,WAGvB,6BAAI4E,UAAU,YAAU,UACpBiZ,EAAK/L,oBAET,6BAAIlN,UAAU,cAAY,WACtB,QAAmBiZ,EAAKuH,kBAahC,MAAMC,UAAqB,YAGzBvb,SACE,MAAM,MAAEwb,EAAK,QAAEta,GAAY/B,KAAKc,OAC1B,UAAE4B,GAAcX,EACtB,OACE,4BACE,SAACoL,EAAA,EAAY,CACXxS,QAAUuhB,EAAerN,OACzBzB,SAAS,YAEX,iCAAOzR,UAAU,oBAAkB,YACjC,4BACE,2BACE,wBAAM+G,EAAU,eAChB,wBAAMA,EAAU,kBAChB,wBAAMA,EAAU,sBAChB,wBAAMA,EAAU,0BAGpB,2BACI2Z,EAAMnd,KAAI0V,IACV,SAACqH,EAAU,CAETrH,KAAOA,EACP7S,QAAUA,GAFJ6S,EAAK7B,mBAOnB,SAAC,EAAa,CACZhR,QAAUA,MAIlB,EAnCO,EAAAjJ,YAAc,eAsCvB,SAAe,EAAAgU,EAAA,GAAsBsP,EAAc,CACjDtd,KAAM,CACJud,MAAO/C,GAETja,kBAAmB,CAACC,GAAqBC,kBACvCD,EAAkBga,EJ/Fb,kBI+FkE,IAAM/Z,MAC7ED,EAAkBga,EJ/FX,oBI+FkE,IAAM/Z,MAC/ED,EAAkBga,EJ/FX,oBI+FkE,IAAM/Z,KAAc,G,kBCvGjG,MAAMqM,EAAkB,WAExBxU,EAAOyU,QAAU,CACf3T,IAAK,SACLuD,MAAO,SACP1C,KAAM,WACNC,OAAQ4S,EAAgB6N,MACxBrW,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,QACPvD,IAAK,QACLwP,QAAQ,EACRtE,UAAW,YACV,CACD3H,MAAO,UACPvD,IAAK,UACLkL,UAAW,YACV,CACD3H,MAAO,aACPvD,IAAK,kBACLkL,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,2BACPvD,IAAK,2BACLkL,UAAW,a,qFCtBjB,MAAMwK,EAAQ,CACZ,uBACA,aACA,wBAYF,EATwD9M,IACtD,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,qFCVb,MAAMA,EAAQ,CACZ,iBACA,mBACA,2BACA,uBACA,uBACA,sBACA,6BACA,yBAYF,EATsD9M,IACpD,0BACE,SAAC,IAAiB,iBACXA,EAAK,CACV7J,KAAO2W,M,qFCfb,MAAMA,EAAQ,CACZ,qBACA,uBACA,0BAGI0O,EAAe,CACnB,uBACA,sBACA,wBAGIC,EAAe,CACnB,uBACA,sBACA,6BAyBF,EAtBwDzb,IACtD,MAAM,GAAQA,EAAMiB,QACpB,OACE,4BACE,SAAC,IAAiB,iBACXjB,EAAK,CACV7J,KAAO2W,MAET,SAAC,IAAiB,eAChBnS,MAAQD,EAAE,oBAAqB,wCAC1BsF,EAAK,CACV7J,KAAOqlB,MAET,SAAC,IAAiB,eAChB7gB,MAAQD,EAAE,oBAAqB,iDAC1BsF,EAAK,CACV7J,KAAOslB,OAGZ,C,gGCpCH,MAAM3O,EAAQ,CACZ,wBACA,0BACA,wBAYF,EAT8D9M,IAC5D,0BACE,SAAC,IAAgB,iBACVA,EAAK,CACV7J,KAAO2W,M,iOCNTtW,EAAU,CAAC,EAEfA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,WAA3C,MCjBDklB,EAAa,CACjB,oBACA,oBACA,mBACA,wBAEA,0BAEA,wBACA,2BACA,0BAgBF,EAb6D1b,IAC3D,MAAM,UAAE4B,GAAc5B,EAAMiB,QAC5B,OACE,0BACE,SAACd,EAAA,EAAgB,eACfxF,MAAQiH,EAAU,wBACb5B,EAAK,CACV7J,KAAOulB,MAGZ,C,kBChCHplB,EAAOyU,QAAU,CACf3T,IAAK,OACLuD,MAAO,OACP1C,KAAM,UACNqK,UAAW,WACXN,UAAW,CACT,CACErH,MAAO,gBACPvD,IAAK,gBACLyN,OAAO,EACPvC,UAAW,YACV,CACD3H,MAAO,YACPvD,IAAK,YACLkL,UAAW,YACV,CACD3H,MAAO,SACPvD,IAAK,SACLkL,UAAW,YACV,CACD3H,MAAO,aACPvD,IAAK,aACLkL,UAAW,aAGfC,kBAAmB,CACjB,CACE5H,MAAO,gBACPvD,IAAK,gBACLyN,OAAO,EACPvC,UAAW,a,wXC1BV,MAAMqZ,EAAwBC,GAAgC,OAAD,6BAClE,IAYE,aAXkB,OAAU,GAAGC,oBAAqB,CAClDC,OAAQ,OACRC,QAAS,CAEP,kBAAmB,cAEnB,cAAiB,eAEnBC,KAAMJ,KAGGG,QAAQtM,IAAI,W,CACvB,MAAOwM,GACP,MAAMA,C,CAEV,IAOaC,EAAoB,CAAO9kB,EAAa+kB,EAAiB3lB,IAA0B,OAAD,6BAC7F,IAGE,MAAM4lB,QAAY,OATA,CAAChlB,GACJ,GAAGqI,OAAOpG,SAASgjB,SAASR,0BAA0BS,mBAAmBllB,KAStFmlB,CAAcnlB,GAAM,OAAF,QAEhB2kB,QAAS,CAEP,kBAAmB,cAKnB,gBAAiB,yCAEhBvlB,IAKP,aADmB2lB,GAASC,EAAII,OAASJ,EAAInhB,M,CAE7C,MAAOghB,GAEP,MADA3c,QAAQD,MAAM,6BAA6BjI,KAAQ6kB,GAC7CA,C,CAEV,G","sources":["webpack://airdcpp-webui/./node_modules/compare-versions/lib/esm/index.js","webpack://airdcpp-webui/./node_modules/fomantic-ui-css/components/item.min.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/System/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/View/style.css","webpack://airdcpp-webui/./src/routes/Settings/style.css","webpack://airdcpp-webui/./node_modules/fomantic-ui-css/components/item.min.css?538d","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/style.css?1643","webpack://airdcpp-webui/./src/routes/Settings/routes/System/style.css?7e6a","webpack://airdcpp-webui/./src/actions/ui/ExtensionActions.ts","webpack://airdcpp-webui/./src/actions/ui/ShareActions.ts","webpack://airdcpp-webui/./src/actions/ui/SystemActions.ts","webpack://airdcpp-webui/./src/components/InstallPrompt.tsx","webpack://airdcpp-webui/./src/components/semantic/Grid.tsx","webpack://airdcpp-webui/./src/constants/ExtensionConstants.ts","webpack://airdcpp-webui/./src/constants/FavoriteDirectoryConstants.ts","webpack://airdcpp-webui/./src/constants/ShareProfileConstants.ts","webpack://airdcpp-webui/./src/decorators/ShareProfileDecorator.tsx","webpack://airdcpp-webui/./src/decorators/StatisticsDecorator.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/LocalSettingForm.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/MenuItems.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/RemoteSettingForm.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingsSideMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingsTopMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingSection.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SaveButton.tsx","webpack://airdcpp-webui/./src/routes/Settings/decorators/SaveDecorator.tsx","webpack://airdcpp-webui/./src/routes/Settings/decorators/SettingsMenuDecorator.tsx","webpack://airdcpp-webui/./src/routes/Settings/style.css?ebc5","webpack://airdcpp-webui/./src/routes/Settings/components/Settings.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/ApplicationPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/HubStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/ShareStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/TransferStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/index.js","webpack://airdcpp-webui/./src/constants/ConnectivityConstants.ts","webpack://airdcpp-webui/./src/actions/ui/ConnectivityActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/style.css?efda","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/DetectPanel.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/DetectionPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/EncryptionPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/IPv4Page.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/IPv6Page.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/PortsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/ProtocolPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/ProxiesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/DownloadOptionsPage.tsx","webpack://airdcpp-webui/./src/actions/ui/FavoriteDirectoryActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/FavoriteDirectoryDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/FavoriteDirectoryTable.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/LocationsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/PrioritiesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchMatchingPage.tsx","webpack://airdcpp-webui/./src/actions/ui/SearchTypeActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchTypeDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchTypesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SkippingOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/EngineStatusMessage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionEnginesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/NpmPackageLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsBrowsePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/LocalExtension.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsManagePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/ExtensionActionButtons.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/Extension.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/ExtensionIcon.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/AwayPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/IgnorePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/style.css?1785","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/MiscPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/UserPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/index.js","webpack://airdcpp-webui/./src/actions/ui/ShareExcludeActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/ExcludePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/HashDatabaseLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/HashingPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/RefreshOptionsPage.tsx","webpack://airdcpp-webui/./src/actions/ui/ShareProfileActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/ShareProfilesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/SharingOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/AutoValuePanel.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/DownloadLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/LimiterPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/SpeedPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/UploadLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/UserLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/AdvancedServerSettingsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LogSection.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LogSectionGroup.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LoggingPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/ServerSettingsPage.tsx","webpack://airdcpp-webui/./src/constants/WebUserConstants.ts","webpack://airdcpp-webui/./src/actions/ui/WebUserActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/users/WebUserDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/users/PermissionSelector.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/WebUsersPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/index.js","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/AppearancePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/EventPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/HistoryPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/MiscellaneousPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/style.css?0d4b","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/NotificationPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/index.js","webpack://airdcpp-webui/./src/services/HttpService.ts"],"sourcesContent":["/**\n * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.\n * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`.\n * @param v1 - First version to compare\n * @param v2 - Second version to compare\n * @returns Numeric value compatible with the [Array.sort(fn) interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters).\n */\nexport const compareVersions = (v1, v2) => {\n // validate input and split into segments\n const n1 = validateAndParse(v1);\n const n2 = validateAndParse(v2);\n // pop off the patch\n const p1 = n1.pop();\n const p2 = n2.pop();\n // validate numbers\n const r = compareSegments(n1, n2);\n if (r !== 0)\n return r;\n // validate pre-release\n if (p1 && p2) {\n return compareSegments(p1.split('.'), p2.split('.'));\n }\n else if (p1 || p2) {\n return p1 ? -1 : 1;\n }\n return 0;\n};\n/**\n * Validate [semver](https://semver.org/) version strings.\n *\n * @param version Version number to validate\n * @returns `true` if the version number is a valid semver version number, `false` otherwise.\n *\n * @example\n * ```\n * validate('1.0.0-rc.1'); // return true\n * validate('1.0-rc.1'); // return false\n * validate('foo'); // return false\n * ```\n */\nexport const validate = (version) => typeof version === 'string' && /^[v\\d]/.test(version) && semver.test(version);\n/**\n * Compare [semver](https://semver.org/) version strings using the specified operator.\n *\n * @param v1 First version to compare\n * @param v2 Second version to compare\n * @param operator Allowed arithmetic operator to use\n * @returns `true` if the comparison between the firstVersion and the secondVersion satisfies the operator, `false` otherwise.\n *\n * @example\n * ```\n * compare('10.1.8', '10.0.4', '>'); // return true\n * compare('10.0.1', '10.0.1', '='); // return true\n * compare('10.1.1', '10.2.2', '<'); // return true\n * compare('10.1.1', '10.2.2', '<='); // return true\n * compare('10.1.1', '10.2.2', '>='); // return false\n * ```\n */\nexport const compare = (v1, v2, operator) => {\n // validate input operator\n assertValidOperator(operator);\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n const res = compareVersions(v1, v2);\n return operatorResMap[operator].includes(res);\n};\n/**\n * Match [npm semver](https://docs.npmjs.com/cli/v6/using-npm/semver) version range.\n *\n * @param version Version number to match\n * @param range Range pattern for version\n * @returns `true` if the version number is within the range, `false` otherwise.\n *\n * @example\n * ```\n * satisfies('1.1.0', '^1.0.0'); // return true\n * satisfies('1.1.0', '~1.0.0'); // return false\n * ```\n */\nexport const satisfies = (version, range) => {\n // if no range operator then \"=\"\n const m = range.match(/^([<>=~^]+)/);\n const op = m ? m[1] : '=';\n // if gt/lt/eq then operator compare\n if (op !== '^' && op !== '~')\n return compare(version, range, op);\n // else range of either \"~\" or \"^\" is assumed\n const [v1, v2, v3] = validateAndParse(version);\n const [r1, r2, r3] = validateAndParse(range);\n if (compareStrings(v1, r1) !== 0)\n return false;\n if (op === '^') {\n return compareSegments([v2, v3], [r2, r3]) >= 0;\n }\n if (compareStrings(v2, r2) !== 0)\n return false;\n return compareStrings(v3, r3) >= 0;\n};\nconst semver = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\nconst validateAndParse = (version) => {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n const match = version.match(semver);\n if (!match) {\n throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n }\n match.shift();\n return match;\n};\nconst isWildcard = (s) => s === '*' || s === 'x' || s === 'X';\nconst tryParse = (v) => {\n const n = parseInt(v, 10);\n return isNaN(n) ? v : n;\n};\nconst forceType = (a, b) => typeof a !== typeof b ? [String(a), String(b)] : [a, b];\nconst compareStrings = (a, b) => {\n if (isWildcard(a) || isWildcard(b))\n return 0;\n const [ap, bp] = forceType(tryParse(a), tryParse(b));\n if (ap > bp)\n return 1;\n if (ap < bp)\n return -1;\n return 0;\n};\nconst compareSegments = (a, b) => {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const r = compareStrings(a[i] || '0', b[i] || '0');\n if (r !== 0)\n return r;\n }\n return 0;\n};\nconst operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1],\n};\nconst allowedOperators = Object.keys(operatorResMap);\nconst assertValidOperator = (op) => {\n if (typeof op !== 'string') {\n throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new Error(`Invalid operator, expected one of ${allowedOperators.join('|')}`);\n }\n};\n//# sourceMappingURL=index.js.map","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/*!\\n * # Fomantic-UI 2.9.0 - Item\\n * http://github.com/fomantic/Fomantic-UI/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.items>.item{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease,-webkit-box-shadow .1s ease;z-index:''}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:'';-ms-flex-item-align:start;align-self:start}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;background:0 0;color:rgba(0,0,0,.87);margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;-ms-flex-item-align:start;align-self:start;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,system-ui,-apple-system,\\\"Segoe UI\\\",Roboto,Oxygen,Ubuntu,Cantarell,\\\"Helvetica Neue\\\",Arial,\\\"Noto Sans\\\",\\\"Liberation Sans\\\",sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\\\"left floated\\\"]{float:left}.ui.items>.item [class*=\\\"right floated\\\"]{float:right}.ui.items>.item .content img{-ms-flex-item-align:center;align-self:center;width:''}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:'';height:'';border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:auto;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:''}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0 0 0;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\\\"right floated\\\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767.98px){.ui.items:not(.unstackable)>.item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\\\"top aligned\\\"].content{-ms-flex-item-align:start;align-self:flex-start}.ui.items>.item>.image+[class*=\\\"middle aligned\\\"].content{-ms-flex-item-align:center;align-self:center}.ui.items>.item>.image+[class*=\\\"bottom aligned\\\"].content{-ms-flex-item-align:end;align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\\\"very relaxed\\\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\\\"very relaxed\\\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}.ui.mini.items>.item{font-size:.78571429em}.ui.tiny.items>.item{font-size:.85714286em}.ui.small.items>.item{font-size:.92857143em}.ui.large.items>.item{font-size:1.14285714em}.ui.big.items>.item{font-size:1.28571429em}.ui.huge.items>.item{font-size:1.42857143em}.ui.massive.items>.item{font-size:1.71428571em}@media only screen and (max-width:767.98px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}.ui.inverted.items>.item{background:0 0}.ui.inverted.items>.item>.content{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.items>.item .extra{background:0 0}.ui.inverted.items>.item>.content>.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>.description{color:rgba(255,255,255,.9)}.ui.inverted.items>.item .meta{color:rgba(255,255,255,.8)}.ui.inverted.items>.item>.content a:not(.ui){color:#57a4ef}.ui.inverted.items>.item>.content a:not(.ui):hover{color:#4183c4}.ui.inverted.items>.item>.content>a.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>a.header:hover{color:#fff}.ui.inverted.items>.item .meta>a:not(.ui){color:rgba(255,255,255,.7)}.ui.inverted.items>.item .meta>a:not(.ui):hover{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content .favorite.icon:hover{color:#ffc63d}.ui.inverted.items>.item>.content .active.favorite.icon{color:#ffec56}.ui.inverted.items>.item>.content .like.icon:hover{color:#ff5a63}.ui.inverted.items>.item>.content .active.like.icon{color:#ff5a63}.ui.inverted.items>.item .extra{color:rgba(255,255,255,.7)}.ui.inverted.items a.item:hover .content .header,.ui.inverted.link.items>.item:hover .content .header{color:#fff}.ui.inverted.divided.items>.item{border-top:1px solid rgba(255,255,255,.1)}.ui.inverted.divided.items>.item:first-child{border-top:none}\", \"\",{\"version\":3,\"sources\":[\"webpack://./node_modules/fomantic-ui-css/components/item.min.css\"],\"names\":[],\"mappings\":\"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\",\"sourcesContent\":[\"/*!\\n * # Fomantic-UI 2.9.0 - Item\\n * http://github.com/fomantic/Fomantic-UI/\\n *\\n *\\n * Released under the MIT license\\n * http://opensource.org/licenses/MIT\\n *\\n */.ui.items>.item{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease,-webkit-box-shadow .1s ease;z-index:''}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:'';-ms-flex-item-align:start;align-self:start}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;background:0 0;color:rgba(0,0,0,.87);margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;-ms-flex-item-align:start;align-self:start;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,system-ui,-apple-system,\\\"Segoe UI\\\",Roboto,Oxygen,Ubuntu,Cantarell,\\\"Helvetica Neue\\\",Arial,\\\"Noto Sans\\\",\\\"Liberation Sans\\\",sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\\\"left floated\\\"]{float:left}.ui.items>.item [class*=\\\"right floated\\\"]{float:right}.ui.items>.item .content img{-ms-flex-item-align:center;align-self:center;width:''}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:'';height:'';border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:auto;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:''}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0 0 0;top:0;left:0;color:rgba(0,0,0,.4);-webkit-box-shadow:none;box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\\\"right floated\\\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra::after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767.98px){.ui.items:not(.unstackable)>.item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\\\"top aligned\\\"].content{-ms-flex-item-align:start;align-self:flex-start}.ui.items>.item>.image+[class*=\\\"middle aligned\\\"].content{-ms-flex-item-align:center;align-self:center}.ui.items>.item>.image+[class*=\\\"bottom aligned\\\"].content{-ms-flex-item-align:end;align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\\\"very relaxed\\\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\\\"very relaxed\\\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}.ui.mini.items>.item{font-size:.78571429em}.ui.tiny.items>.item{font-size:.85714286em}.ui.small.items>.item{font-size:.92857143em}.ui.large.items>.item{font-size:1.14285714em}.ui.big.items>.item{font-size:1.28571429em}.ui.huge.items>.item{font-size:1.42857143em}.ui.massive.items>.item{font-size:1.71428571em}@media only screen and (max-width:767.98px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}.ui.inverted.items>.item{background:0 0}.ui.inverted.items>.item>.content{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.items>.item .extra{background:0 0}.ui.inverted.items>.item>.content>.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>.description{color:rgba(255,255,255,.9)}.ui.inverted.items>.item .meta{color:rgba(255,255,255,.8)}.ui.inverted.items>.item>.content a:not(.ui){color:#57a4ef}.ui.inverted.items>.item>.content a:not(.ui):hover{color:#4183c4}.ui.inverted.items>.item>.content>a.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>a.header:hover{color:#fff}.ui.inverted.items>.item .meta>a:not(.ui){color:rgba(255,255,255,.7)}.ui.inverted.items>.item .meta>a:not(.ui):hover{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content .favorite.icon:hover{color:#ffc63d}.ui.inverted.items>.item>.content .active.favorite.icon{color:#ffec56}.ui.inverted.items>.item>.content .like.icon:hover{color:#ff5a63}.ui.inverted.items>.item>.content .active.like.icon{color:#ff5a63}.ui.inverted.items>.item .extra{color:rgba(255,255,255,.7)}.ui.inverted.items a.item:hover .content .header,.ui.inverted.link.items>.item:hover .content .header{color:#fff}.ui.inverted.divided.items>.item{border-top:1px solid rgba(255,255,255,.1)}.ui.inverted.divided.items>.item:first-child{border-top:none}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .detect-panel {\\n margin-top: 30px;\\n}\\n\\n.settings-layout .detect-panel .header.column > div {\\n overflow: hidden;\\n line-height: inherit !important;\\n}\\n\\n.settings-layout .detect-panel .header.column {\\n max-width: 200px;\\n}\\n\\n.settings-layout .detect-panel .detect-button {\\n margin-top: 20px;\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Connectivity/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;EAChB,+BAA+B;AACjC;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .detect-panel {\\n margin-top: 30px;\\n}\\n\\n.settings-layout .detect-panel .header.column > div {\\n overflow: hidden;\\n line-height: inherit !important;\\n}\\n\\n.settings-layout .detect-panel .header.column {\\n max-width: 200px;\\n}\\n\\n.settings-layout .detect-panel .detect-button {\\n margin-top: 20px;\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .profile.miscellaneous .field-nmdc_encoding li {\\r\\n margin-bottom: 5px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Profile/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,kBAAkB;AACpB\",\"sourcesContent\":[\".settings-layout .profile.miscellaneous .field-nmdc_encoding li {\\r\\n margin-bottom: 5px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .hash-database.grid {\\r\\n padding: 10px 0px 15px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .hash-database.grid .row {\\r\\n padding: 5px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .sharing.excludes .add.button {\\r\\n margin-top: 20px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Sharing/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,0BAA0B;AAC5B;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .hash-database.grid {\\r\\n padding: 10px 0px 15px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .hash-database.grid .row {\\r\\n padding: 5px 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .sharing.excludes .add.button {\\r\\n margin-top: 20px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".web-user.modal .ui.checkbox {\\r\\n width: 100%;\\r\\n margin-top: 5px;\\r\\n}\\r\\n\\r\\n.web-user.modal .ui.checkbox.admin {\\r\\n margin-bottom: 10px;\\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .log-section.active {\\r\\n background-color: whitesmoke;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .sections {\\r\\n margin-top: 25px !important;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/System/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,WAAW;EACX,eAAe;AACjB;;AAEA;EACE,mBAAmB;EACnB,iBAAiB;AACnB;;AAEA;EACE,4BAA4B;AAC9B;;AAEA;EACE,2BAA2B;AAC7B\",\"sourcesContent\":[\".web-user.modal .ui.checkbox {\\r\\n width: 100%;\\r\\n margin-top: 5px;\\r\\n}\\r\\n\\r\\n.web-user.modal .ui.checkbox.admin {\\r\\n margin-bottom: 10px;\\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .log-section.active {\\r\\n background-color: whitesmoke;\\r\\n}\\r\\n\\r\\n.settings-layout .system.logging .sections {\\r\\n margin-top: 25px !important;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout .view.notifications .field-notify_events_info {\\r\\n margin-top: 25px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/View/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .view.notifications .field-notify_events_info {\\r\\n margin-top: 25px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".settings-layout {\\r\\n padding-bottom: 30px;\\r\\n max-height: 100% !important;\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n}\\r\\n\\r\\n.settings-layout .menu-column .menu {\\r\\n max-width: 100%;\\r\\n}\\r\\n\\r\\n.settings-layout .layout.header {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form {\\r\\n margin-top: 30px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form:first-child {\\r\\n margin-top: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout h3 {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout h4 {\\r\\n margin-top: 15px;\\r\\n}\\r\\n\\r\\n.settings-layout > div,\\r\\n.settings-layout .mobile .section-content {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n overflow-y: auto;\\r\\n margin-bottom: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .main.grid {\\r\\n overflow-y: auto;\\r\\n padding: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content {\\r\\n padding-bottom: 5px;\\r\\n /* For possible scrollbar */\\r\\n padding-right: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about {\\r\\n margin-top: 10px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about .options {\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .full .section-content {\\r\\n height: 100%;\\r\\n padding-bottom: 2px;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > .ui.dropdown,\\r\\n.settings-layout .top-menu > .ui.dropdown > .caption {\\r\\n display: flex;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > i {\\r\\n margin: 0px 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .full .top-menu i {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .save.button {\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .options {\\r\\n min-height: 80px;\\r\\n}\\r\\n\\r\\n.settings-layout .options > .ui.grid {\\r\\n margin: 0px;\\r\\n}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,oBAAoB;EACpB,2BAA2B;EAC3B,aAAa;EACb,sBAAsB;AACxB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;;EAEE,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,YAAY;AACd;;AAEA;EACE,mBAAmB;EACnB,2BAA2B;EAC3B,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,cAAc;AAChB;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,cAAc;AAChB;;AAEA;;EAEE,aAAa;AACf;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,mBAAmB;EACnB,cAAc;AAChB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,WAAW;AACb\",\"sourcesContent\":[\".settings-layout {\\r\\n padding-bottom: 30px;\\r\\n max-height: 100% !important;\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n}\\r\\n\\r\\n.settings-layout .menu-column .menu {\\r\\n max-width: 100%;\\r\\n}\\r\\n\\r\\n.settings-layout .layout.header {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form {\\r\\n margin-top: 30px;\\r\\n}\\r\\n\\r\\n.settings-layout .setting-form:first-child {\\r\\n margin-top: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout h3 {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.settings-layout h4 {\\r\\n margin-top: 15px;\\r\\n}\\r\\n\\r\\n.settings-layout > div,\\r\\n.settings-layout .mobile .section-content {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n overflow-y: auto;\\r\\n margin-bottom: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .main.grid {\\r\\n overflow-y: auto;\\r\\n padding: 0px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content {\\r\\n padding-bottom: 5px;\\r\\n /* For possible scrollbar */\\r\\n padding-right: 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about {\\r\\n margin-top: 10px;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .section-content.about .options {\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .full .section-content {\\r\\n height: 100%;\\r\\n padding-bottom: 2px;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > .ui.dropdown,\\r\\n.settings-layout .top-menu > .ui.dropdown > .caption {\\r\\n display: flex;\\r\\n}\\r\\n\\r\\n.settings-layout .top-menu > i {\\r\\n margin: 0px 5px;\\r\\n}\\r\\n\\r\\n.settings-layout .full .top-menu i {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.settings-layout .mobile .save.button {\\r\\n margin-bottom: 10px;\\r\\n flex-shrink: 0;\\r\\n}\\r\\n\\r\\n.settings-layout .options {\\r\\n min-height: 80px;\\r\\n}\\r\\n\\r\\n.settings-layout .options > .ui.grid {\\r\\n margin: 0px;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\n import API from \"!../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../css-loader/dist/cjs.js!./item.min.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../css-loader/dist/cjs.js!./item.min.css\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","\r\nimport SocketService from 'services/SocketService';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport History from 'utils/History';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst isManaged = (extension: API.Extension) => extension.managed;\r\nconst isRunning = (extension: API.Extension) => extension.running;\r\nconst hasSettings = (extension: API.Extension) => extension.has_settings;\r\n\r\n\r\nconst handleConfigure: UI.ActionHandler<API.Extension> = ({ data: extension, location }) => {\r\n History.push(`${location.pathname}/extensions/${extension.id}`);\r\n};\r\n\r\nconst handleStart: UI.ActionHandler<API.Extension> = ({ data: extension }) => {\r\n return SocketService.post(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}/start`);\r\n};\r\n\r\nconst handleStop: UI.ActionHandler<API.Extension> = ({ data: extension }) => {\r\n return SocketService.post(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}/stop`);\r\n};\r\n\r\nconst downloadExtension = (url: string, installId?: string, shasum?: string) => {\r\n return SocketService.post(ExtensionConstants.DOWNLOAD_URL, {\r\n install_id: installId ? installId : url,\r\n url,\r\n shasum\r\n });\r\n};\r\n\r\nconst handleNpmAction: UI.ActionHandler<UI.NpmPackage> = async (\r\n { data: npmPackage, ...other }\r\n) => {\r\n const data = await fetchCorsSafeData(ExtensionConstants.NPM_PACKAGE_URL + npmPackage.name + '/latest', true);\r\n\r\n const { tarball, shasum } = data.dist;\r\n\r\n return downloadExtension(tarball, npmPackage.name, shasum);\r\n};\r\n\r\nconst handleInstallUrl: UI.ActionHandler<undefined> = (\r\n { data }, url: string\r\n) => {\r\n return downloadExtension(url);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.Extension> = (\r\n { data }\r\n) => {\r\n return SocketService.delete(ExtensionConstants.EXTENSIONS_URL + '/' + data.name);\r\n};\r\n\r\n\r\nconst ExtensionInstallActions: UI.ActionListType<undefined> = {\r\n installUrl: {\r\n displayName: 'Install from URL',\r\n icon: IconConstants.CREATE,\r\n access: API.AccessEnum.ADMIN,\r\n input: {\r\n approveCaption: 'Install',\r\n content: 'Enter download URL',\r\n inputProps: {\r\n placeholder: 'Enter URL',\r\n type: 'url',\r\n required: true,\r\n }\r\n },\r\n handler: handleInstallUrl\r\n },\r\n};\r\n\r\n\r\nconst ExtensionNpmActions: UI.ActionListType<UI.NpmPackage> = {\r\n installNpm: {\r\n displayName: 'Install',\r\n icon: IconConstants.CREATE,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleNpmAction,\r\n },\r\n updateNpm: {\r\n displayName: 'Update',\r\n icon: IconConstants.REFRESH_COLORED,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleNpmAction,\r\n },\r\n};\r\n\r\nconst ExtensionManageActions: UI.ActionListType<API.Extension> = {\r\n start: {\r\n displayName: 'Start',\r\n icon: IconConstants.PLAY,\r\n filter: ext => isManaged(ext) && !isRunning(ext),\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleStart,\r\n },\r\n stop: {\r\n displayName: 'Stop',\r\n icon: IconConstants.STOP,\r\n filter: ext => isManaged(ext) && isRunning(ext),\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleStop,\r\n },\r\n configure: {\r\n displayName: 'Configure',\r\n icon: IconConstants.EDIT,\r\n filter: hasSettings,\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n handler: handleConfigure,\r\n },\r\n divider: null,\r\n remove: {\r\n displayName: 'Uninstall',\r\n icon: IconConstants.REMOVE,\r\n filter: isManaged,\r\n access: API.AccessEnum.ADMIN,\r\n confirmation: {\r\n // eslint-disable-next-line max-len\r\n content: 'Are you sure that you want to remove the extension {{item.name}}? This will also remove possible extension-specific settings.',\r\n approveCaption: 'Remove extension',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n },\r\n};\r\n\r\n\r\nexport default {\r\n install: {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n actions: ExtensionInstallActions,\r\n },\r\n npm: {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n actions: ExtensionNpmActions,\r\n },\r\n manage: {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n actions: ExtensionManageActions,\r\n }\r\n};\r\n","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareConstants from 'constants/ShareConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleRefresh = () => {\r\n return SocketService.post(ShareConstants.REFRESH_URL);\r\n};\r\n\r\n\r\nconst ShareActions: UI.ActionListType<undefined> = {\r\n refresh: {\r\n displayName: 'Refresh all',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REFRESH_COLORED,\r\n handler: handleRefresh,\r\n },\r\n};\r\n\r\nexport default {\r\n moduleId: UI.Modules.SHARE,\r\n actions: ShareActions,\r\n};\r\n\r\n","import SystemConstants from 'constants/SystemConstants';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleRestartWeb = () => {\r\n return SocketService.post(SystemConstants.MODULE_URL + '/restart_web');\r\n};\r\n\r\nconst handleShutdown = () => {\r\n return SocketService.post(SystemConstants.MODULE_URL + '/shutdown');\r\n};\r\n\r\n\r\n\r\nconst SystemActions: UI.ActionListType<undefined> = {\r\n restartWeb: {\r\n displayName: 'Restart web server',\r\n access: API.AccessEnum.ADMIN,\r\n icon: IconConstants.REFRESH_COLORED,\r\n confirmation: {\r\n content: `When changing the binding options, it's recommended to restart the web server only \r\n when you are able to access the server for troubleshooting. If \\\r\n the web server won't come back online, you should start the application \r\n manually to see if there are any error messages. The configuration file is located in your \\\r\n user directory by default (inside .airdc++ directory) in case you need to edit it manually.`,\r\n approveCaption: 'Continue and restart',\r\n rejectCaption: `Don't restart`,\r\n },\r\n handler: handleRestartWeb\r\n },\r\n shutdown: {\r\n displayName: 'Shut down application',\r\n access: API.AccessEnum.ADMIN,\r\n icon: IconConstants.POWER,\r\n confirmation: {\r\n content: 'Are you sure that you wish to shut down the application?',\r\n approveCaption: 'Continue and shut down',\r\n rejectCaption: 'Cancel',\r\n },\r\n handler: handleShutdown\r\n },\r\n};\r\n\r\n\r\nexport default {\r\n moduleId: UI.Modules.COMMON,\r\n subId: 'system',\r\n actions: SystemActions,\r\n};\r\n","import { useContext } from 'react';\r\nimport * as React from 'react';\r\n\r\n//import ExternalLink from 'components/ExternalLink';\r\n//import LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport Button from 'components/semantic/Button';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport { useStore } from 'effects/StoreListenerEffect';\r\nimport LocalSettingStore from 'stores/LocalSettingStore';\r\nimport { InstallPromptContext } from 'context/InstallPromptContext';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate, toI18nKey } from 'utils/TranslationUtils';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\n\r\ninterface InstallPromptProps {\r\n alwaysShow?: boolean;\r\n}\r\n\r\nconst InstallPrompt: React.FC<InstallPromptProps> = ({ alwaysShow }) => {\r\n const localSettings = useStore<UI.FormValueMap>(LocalSettingStore);\r\n const prompt = useContext(InstallPromptContext);\r\n const { t } = useTranslation();\r\n if (!prompt) {\r\n return null;\r\n }\r\n\r\n if (!alwaysShow && !!localSettings[LocalSettings.NO_INSTALL_PROMPT]) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Message \r\n title={ translate('Install as local application', t, UI.Modules.COMMON) }\r\n description={ (\r\n <div className=\"install-prompt\">\r\n <p>\r\n { t(\r\n toI18nKey('pwaInstallDesc', UI.Modules.COMMON), \r\n 'This web application can be installed locally, providing a better user experience'\r\n ) }\r\n </p>\r\n <Button\r\n className=\"primary\"\r\n caption={ translate('Install', t, UI.Modules.COMMON) }\r\n onClick={ () => prompt!() }\r\n icon={ IconConstants.CREATE }\r\n />\r\n { !alwaysShow && (\r\n <Button\r\n caption={ translate(`Don't install`, t, UI.Modules.COMMON) }\r\n onClick={ () => LocalSettingStore.setValue(LocalSettings.NO_INSTALL_PROMPT, true) }\r\n />\r\n ) }\r\n </div>\r\n ) }\r\n />\r\n );\r\n};\r\n\r\nexport default InstallPrompt;","\r\nimport * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { toI18nKey } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nexport interface RowProps {\r\n title: React.ReactNode;\r\n text?: React.ReactNode;\r\n titleWidth?: string;\r\n className?: string;\r\n noText?: boolean;\r\n}\r\n\r\n\r\n\r\nconst formatText = (text: React.ReactNode) => {\r\n if (!!text) {\r\n return text;\r\n }\r\n \r\n return (\r\n <Trans \r\n i18nKey={ toI18nKey('na', UI.Modules.COMMON) }\r\n >\r\n N/A\r\n </Trans>\r\n );\r\n};\r\n\r\nexport const Row: React.FC<RowProps> = ({ title, text, className, titleWidth = 'four', noText }) => (\r\n <div className={ classNames('ui row', className) }>\r\n <div className={ classNames(noText ? 'sixteen' : titleWidth, 'wide column title') }>\r\n <div className=\"ui tiny header\" style={{ overflow: 'hidden' }}>\r\n { title }\r\n </div>\r\n </div>\r\n { !noText && (\r\n <div className=\"column value\">\r\n { formatText(text) }\r\n </div> \r\n ) }\r\n </div>\r\n);\r\n\r\nexport interface HeaderProps {\r\n title: React.ReactNode;\r\n}\r\n\r\nexport const Header: React.FC<HeaderProps> = ({ title }) => (\r\n <div className=\"ui row\">\r\n <div className=\"sixteen wide column\">\r\n <div className=\"ui blue section header\">\r\n { title }\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\r\n columns?: string;\r\n stackable?: boolean;\r\n}\r\n\r\nexport const Grid: React.FC<GridProps> = ({ className, children, columns, stackable, ...other }) => (\r\n <div \r\n className={ classNames(\r\n 'ui grid', \r\n //`${columns} column`, \r\n { [`${columns} column`]: !!columns },\r\n { stackable: stackable },\r\n className\r\n ) }\r\n { ...other }\r\n >\r\n { children }\r\n </div>\r\n);\r\n","const MODULE_URL = 'extensions';\r\n\r\nconst NPM_URL = 'https://registry.npmjs.org/';\r\n\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n EXTENSIONS_URL: MODULE_URL,\r\n DOWNLOAD_URL: MODULE_URL + '/download',\r\n\r\n ENGINES_URL: MODULE_URL + '/engines',\r\n ENGINES_STATUS_URL: MODULE_URL + '/engines/status',\r\n\r\n DEFAULT_ENGINE: 'node',\r\n\r\n STARTED: 'extension_started',\r\n STOPPED: 'extension_stopped',\r\n\r\n ADDED: 'extension_added',\r\n REMOVED: 'extension_removed',\r\n UPDATED: 'extension_updated',\r\n\r\n INSTALLATION_STARTED: 'extension_installation_started',\r\n INSTALLATION_SUCCEEDED: 'extension_installation_succeeded',\r\n INSTALLATION_FAILED: 'extension_installation_failed',\r\n\r\n NPM_PACKAGES_URL: NPM_URL + '-/v1/search?text=keywords:airdcpp-extensions-public&size=100',\r\n NPM_PACKAGE_URL: NPM_URL,\r\n NPM_HOMEPAGE_URL: 'https://www.npmjs.com/package/',\r\n}\r\n;\r\n","const MODULE_URL = 'favorite_directories';\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n\r\n GROUPED_DIRECTORIES_URL: MODULE_URL + '/grouped_paths',\r\n DIRECTORIES_URL: MODULE_URL,\r\n\r\n DIRECTORIES_UPDATED: 'favorite_directories_updated',\r\n}\r\n;\r\n","const MODULE_URL = 'share_profiles';\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n PROFILES_URL: MODULE_URL,\r\n\r\n PROFILE_ADDED: 'share_profile_added',\r\n PROFILE_UPDATED: 'share_profile_updated',\r\n PROFILE_REMOVED: 'share_profile_removed',\r\n\r\n HIDDEN_PROFILE_ID: 1\r\n}\r\n;\r\n","import * as React from 'react';\r\nimport { merge } from 'lodash';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\n\r\nimport DataProviderDecorator, { \r\n DataProviderDecoratorChildProps, DataProviderDecoratorSettings, DataConverter \r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\ninterface ShareProfileDecoratorDataProps {\r\n profiles: API.ShareProfile[];\r\n}\r\n\r\nexport const profileToEnumValue = (profile: API.ShareProfile) => {\r\n return {\r\n id: profile.id,\r\n name: profile.str,\r\n };\r\n};\r\n\r\nexport type ShareProfileDecoratorChildProps = DataProviderDecoratorChildProps & ShareProfileDecoratorDataProps;\r\n\r\nconst ShareProfileDecorator = function <PropsT extends object>(\r\n Component: React.ComponentType<PropsT & ShareProfileDecoratorChildProps>, \r\n listHidden: boolean, \r\n dataProviderDecoratorSettings?: DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>,\r\n addSize = true\r\n) {\r\n const convertProfile = (profile: API.ShareProfile, t: UI.TranslateF): API.ShareProfile => {\r\n let str = profile.str;\r\n if (addSize && profile.id !== ShareProfileConstants.HIDDEN_PROFILE_ID) {\r\n str += ` (${formatSize(profile.size, t)})`;\r\n }\r\n\r\n return {\r\n ...profile,\r\n str,\r\n };\r\n };\r\n\r\n const convertProfiles: DataConverter<PropsT> = (data: API.ShareProfile[], { t }) => {\r\n const profiles = data\r\n .filter(p => listHidden || p.id !== ShareProfileConstants.HIDDEN_PROFILE_ID)\r\n .map(p => convertProfile(p, t));\r\n\r\n return profiles;\r\n };\r\n\r\n return DataProviderDecorator<PropsT, ShareProfileDecoratorDataProps>(\r\n Component, \r\n merge(dataProviderDecoratorSettings, {\r\n urls: {\r\n profiles: ShareProfileConstants.PROFILES_URL,\r\n },\r\n dataConverters: {\r\n profiles: convertProfiles,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ShareProfileConstants.MODULE_URL, ShareProfileConstants.PROFILE_ADDED, () => refetchData());\r\n addSocketListener(ShareProfileConstants.MODULE_URL, ShareProfileConstants.PROFILE_UPDATED, () => refetchData());\r\n addSocketListener(ShareProfileConstants.MODULE_URL, ShareProfileConstants.PROFILE_REMOVED, () => refetchData());\r\n },\r\n } as DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>)\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator;\r\n","import * as React from 'react';\r\n\r\nimport SocketService from 'services/SocketService';\r\nimport Message from 'components/semantic/Message';\r\nimport { ErrorResponse } from 'airdcpp-apisocket';\r\n\r\nimport { Translation } from 'react-i18next';\r\nimport { translate } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nexport interface StatisticsDecoratorProps<DataT> {\r\n stats?: DataT;\r\n}\r\n\r\nexport interface StatisticsDecoratorChildProps<DataT> {\r\n stats: DataT;\r\n}\r\n\r\n// Decorator for statistics pages that fetch the content from API\r\nconst StatisticsDecorator = function <DataT, PropsT>(\r\n Component: React.ComponentType<StatisticsDecoratorChildProps<DataT> & PropsT>, \r\n fetchUrl: string, \r\n unavailableMessage: ((t: UI.TranslateF, props: PropsT) => string) | null, \r\n fetchIntervalSeconds = 0\r\n) {\r\n class Decorator extends React.Component<StatisticsDecoratorProps<DataT> & PropsT> {\r\n state = {\r\n stats: null\r\n };\r\n\r\n fetchTimeout: number | undefined;\r\n\r\n componentDidMount() {\r\n this.fetchStats();\r\n }\r\n\r\n componentWillUnmount() {\r\n window.clearTimeout(this.fetchTimeout);\r\n }\r\n\r\n fetchStats = () => {\r\n SocketService.get(fetchUrl)\r\n .then(this.onStatsReceived)\r\n .catch((error: ErrorResponse) => console.error('Failed to fetch stats', error.message));\r\n\r\n if (fetchIntervalSeconds > 0) {\r\n this.fetchTimeout = window.setTimeout(this.fetchStats, fetchIntervalSeconds * 1000);\r\n }\r\n }\r\n\r\n onStatsReceived = (data: object) => {\r\n this.setState({ \r\n stats: data \r\n });\r\n }\r\n\r\n render() {\r\n const { stats } = this.state;\r\n if (stats === null) {\r\n return null;\r\n }\r\n\r\n if (this.props.stats) {\r\n Object.assign(stats, this.props.stats);\r\n }\r\n\r\n if (stats === undefined) {\r\n return (\r\n <Translation>\r\n { t => (\r\n <Message\r\n title={ translate('Statistics not available', t, UI.Modules.COMMON) }\r\n description={ !unavailableMessage ? undefined : unavailableMessage(t, this.props) }\r\n />\r\n ) }\r\n </Translation>\r\n );\r\n }\r\n\r\n return (\r\n <Component \r\n { ...this.props } \r\n stats={ stats }\r\n />\r\n );\r\n }\r\n }\r\n\r\n return Decorator;\r\n};\r\n\r\nexport default StatisticsDecorator;\r\n","//import PropTypes from 'prop-types';\r\nimport { Component } from 'react';\r\n\r\nimport LocalSettingStore from 'stores/LocalSettingStore';\r\n\r\nimport Form, { FormProps, FormSaveHandler, FormFieldChangeHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { withSaveContext, SaveContextProps } from '../decorators/SaveDecorator';\r\nimport { RouteComponentProps } from 'react-router';\r\nimport { translateForm } from 'utils/FormUtils';\r\n\r\n\r\nexport interface LocalSettingFormProps extends Omit<FormProps, 'onSave' | 'fieldDefinitions' | 'value'> {\r\n keys: string[];\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\n\r\ntype Props = LocalSettingFormProps & SaveContextProps & RouteComponentProps<UI.EmptyObject>;\r\n\r\nclass LocalSettingForm extends Component<Props> {\r\n /*static propTypes = {\r\n // Form items to list\r\n keys: PropTypes.array.isRequired,\r\n };*/\r\n\r\n definitions: UI.FormFieldDefinition[];\r\n state: {\r\n settings: API.SettingValueMap,\r\n };\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n\r\n this.definitions = translateForm(LocalSettingStore.getDefinitions(props.keys), props.moduleT);\r\n\r\n this.state = {\r\n settings: LocalSettingStore.getValues(),\r\n };\r\n }\r\n\r\n onSave: FormSaveHandler<UI.FormValueMap> = (changedSettingArray, allFields) => {\r\n LocalSettingStore.setValues(changedSettingArray);\r\n\r\n this.setState({\r\n settings: LocalSettingStore.getValues(),\r\n });\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n onFieldChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n const { saveContext, onFieldChanged } = this.props;\r\n saveContext.onFieldChanged(id, value, hasChanges);\r\n if (onFieldChanged) {\r\n return onFieldChanged(id, value, hasChanges);\r\n }\r\n }\r\n\r\n render() {\r\n const { settings } = this.state;\r\n const { saveContext, keys, ...other } = this.props;\r\n return (\r\n <div className=\"local setting-form\">\r\n <Form\r\n { ...other }\r\n ref={ f => saveContext.addFormRef(keys, f) }\r\n onSave={ this.onSave }\r\n fieldDefinitions={ this.definitions }\r\n sourceValue={ settings }\r\n onFieldChanged={ this.onFieldChanged }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default withSaveContext(LocalSettingForm);","import RouterMenuItemLink from 'components/semantic/RouterMenuItemLink';\r\nimport { Location } from 'history';\r\nimport LoginStore from 'stores/LoginStore';\r\nimport { Route, RouteComponentProps } from 'react-router-dom';\r\nimport { SectionType, RootSectionType } from '../decorators/SettingsMenuDecorator';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { getSubModuleT } from 'utils/TranslationUtils';\r\nimport { camelCase } from 'lodash';\r\n\r\n\r\nexport const sectionToUrl = (section: SectionType, parent?: SectionType) => {\r\n if (typeof parent === 'object') {\r\n return `/settings/${parent.url}/${section.url}`;\r\n }\r\n\r\n return `/settings/${section.url}`;\r\n};\r\n\r\nexport const translateSettingSectionTitle = (title: string, settingsT: UI.ModuleTranslator) => {\r\n return settingsT.translate(title, [ UI.SubNamespaces.NAVIGATION ]);\r\n};\r\n\r\nexport const menuItemToLinkComponent = (\r\n menuItemInfo: SectionType, \r\n parent: RootSectionType | undefined, \r\n settingsT: UI.ModuleTranslator,\r\n location: Location\r\n) => {\r\n if (menuItemInfo.debugOnly && process.env.NODE_ENV === 'production') {\r\n return null;\r\n }\r\n\r\n if (menuItemInfo.access && !LoginStore.hasAccess(menuItemInfo.access)) {\r\n return null;\r\n }\r\n\r\n let url = sectionToUrl(menuItemInfo, parent);\r\n\r\n // Browsing is smoother when the child page is loaded directly\r\n // Don't use the child URL for currently active parent so that the route is detected as active correctly\r\n if (menuItemInfo.menuItems && location.pathname.indexOf(url) !== 0) {\r\n url = sectionToUrl(menuItemInfo.menuItems[0], menuItemInfo);\r\n }\r\n\r\n return (\r\n <RouterMenuItemLink \r\n key={ url } \r\n url={ url } \r\n icon={ !!menuItemInfo.icon ? `green ${menuItemInfo.icon}` : null }\r\n >\r\n { translateSettingSectionTitle(menuItemInfo.title, settingsT) }\r\n </RouterMenuItemLink>\r\n );\r\n};\r\n\r\nexport const menuItemsToRouteComponentArray = (\r\n currentMenuItem: SectionType, \r\n menuItems: SectionType[] | undefined,\r\n settingsT: UI.ModuleTranslator,\r\n moduleT: UI.ModuleTranslator | undefined,\r\n parent: SectionType | undefined\r\n) => {\r\n if (!menuItems) {\r\n return null;\r\n }\r\n\r\n return menuItems.map(item => (\r\n <Route\r\n key={ item.url }\r\n path={ sectionToUrl(item, parent) }\r\n render={ (props: RouteComponentProps<UI.EmptyObject>) => (\r\n <item.component\r\n { ...props }\r\n menuItems={ currentMenuItem.menuItems }\r\n advancedMenuItems={ currentMenuItem.advancedMenuItems }\r\n parent={ currentMenuItem }\r\n parentMenuItems={ menuItems }\r\n settingsT={ settingsT }\r\n moduleT={ getSubModuleT(moduleT || settingsT, camelCase(item.url)) }\r\n />\r\n ) }\r\n />\r\n ));\r\n};\r\n\r\n\r\nexport const isItemActive = (\r\n item: SectionType, \r\n parent: RootSectionType | undefined, \r\n location: Location\r\n) => {\r\n return location.pathname.indexOf(sectionToUrl(item, parent)) === 0;\r\n};\r\n\r\nexport const findMenuItem = (\r\n menuItems: SectionType[] | undefined, \r\n parent: RootSectionType | undefined, \r\n location: Location\r\n) => {\r\n if (!menuItems) {\r\n return null;\r\n }\r\n\r\n return menuItems.find(item => isItemActive(item, parent, location));\r\n};\r\n","import { Component } from 'react';\r\nimport SettingConstants from 'constants/SettingConstants';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport Form, { FormProps, FormSaveHandler, FormFieldChangeHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { withSaveContext, SaveContextProps } from '../decorators/SaveDecorator';\r\nimport { RouteComponentProps } from 'react-router';\r\n\r\n\r\nexport interface RemoteSettingFormProps extends Omit<FormProps, 'onSave' | 'value' | 'fieldDefinitions'> {\r\n keys: string[];\r\n onSettingValuesReceived?: (settings: API.SettingValueMap) => void;\r\n valueMode?: API.SettingValueMode;\r\n}\r\n\r\ninterface RemoteSettingFormDataProps extends DataProviderDecoratorChildProps {\r\n settings: API.SettingValueMap;\r\n fieldDefinitions: UI.FormFieldDefinition[];\r\n}\r\n\r\n\r\ntype Props = RemoteSettingFormProps & RemoteSettingFormDataProps & SaveContextProps & RouteComponentProps;\r\n\r\nclass RemoteSettingForm extends Component<Props> {\r\n onSave: FormSaveHandler<UI.FormValueMap> = (changedValues) => {\r\n if (Object.keys(changedValues).length === 0) {\r\n return Promise.resolve();\r\n }\r\n\r\n return SocketService.post(SettingConstants.ITEMS_SET_URL, changedValues)\r\n .then(this.refetchValues);\r\n }\r\n\r\n refetchValues = () => {\r\n this.props.refetchData([ 'settings' ]);\r\n }\r\n\r\n onFieldChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n const { saveContext, onFieldChanged } = this.props;\r\n saveContext.onFieldChanged(id, value, hasChanges);\r\n if (onFieldChanged) {\r\n return onFieldChanged(id, value, hasChanges);\r\n }\r\n }\r\n\r\n render() {\r\n const { settings, fieldDefinitions, saveContext, keys, ...otherProps } = this.props;\r\n return (\r\n <div className=\"remote setting-form\">\r\n <Form\r\n { ...otherProps }\r\n ref={ f => saveContext.addFormRef(keys, f) }\r\n onSave={ this.onSave }\r\n fieldDefinitions={ fieldDefinitions }\r\n sourceValue={ settings }\r\n onFieldChanged={ this.onFieldChanged }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator<RemoteSettingFormProps, RemoteSettingFormDataProps>(\r\n withSaveContext(RemoteSettingForm), \r\n {\r\n urls: {\r\n fieldDefinitions: ({ keys }) => SocketService.post(SettingConstants.ITEMS_DEFINITIONS_URL, { keys }),\r\n settings: async ({ keys, onSettingValuesReceived, valueMode = API.SettingValueMode.CURRENT }) => {\r\n const settings: API.SettingValueMap = await SocketService.post(\r\n SettingConstants.ITEMS_GET_URL, { \r\n keys,\r\n value_mode: valueMode\r\n }\r\n );\r\n\r\n if (!!onSettingValuesReceived) {\r\n onSettingValuesReceived(settings);\r\n }\r\n\r\n return settings;\r\n },\r\n }\r\n }\r\n);","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { translateSettingSectionTitle } from './MenuItems';\r\nimport Icon from 'components/semantic/Icon';\r\n\r\n\r\ntype SideMenuProps = Pick<SettingSectionChildProps, 'menuItems' | 'advancedMenuItems' | 'settingsT'>;\r\n\r\nconst SideChildSectionMenu: React.FC<SideMenuProps> = ({ menuItems, advancedMenuItems, settingsT }) => {\r\n return (\r\n <div className=\"three wide column menu-column\">\r\n <div className=\"ui vertical secondary menu\">\r\n { menuItems }\r\n { !!advancedMenuItems && (\r\n <div>\r\n <div className=\"item header\">\r\n { settingsT.translate('Advanced') }\r\n </div>\r\n <div className=\"menu\">\r\n { advancedMenuItems }\r\n </div> \r\n </div>\r\n ) }\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\ntype TopMenuProps = Pick<SettingSectionChildProps, 'parentMenuItems'>;\r\n\r\nconst TopRootSectionMenu: React.FC<TopMenuProps> = ({ parentMenuItems }) => (\r\n <div className=\"ui secondary pointing menu settings top-menu\">\r\n { parentMenuItems }\r\n </div>\r\n);\r\n\r\n// eslint-disable-next-line max-len\r\ntype ContentProps = React.PropsWithChildren<Pick<SettingSectionChildProps, 'contentClassname' | 'currentMenuItem' | 'parent' | 'saveButton' | 'message' | 'settingsT'>>;\r\n\r\nconst Content: React.FC<ContentProps> = (\r\n { contentClassname, currentMenuItem, parent, saveButton, children, message, settingsT }\r\n) => (\r\n <div className={ classNames('thirteen wide column', contentClassname) }>\r\n <div className=\"ui segment\">\r\n <LayoutHeader\r\n title={ translateSettingSectionTitle(currentMenuItem.title, settingsT) }\r\n icon={ <Icon color=\"green\" icon={ parent!.icon }/> }\r\n rightComponent={ saveButton }\r\n />\r\n <div className=\"options\">\r\n { message }\r\n { children }\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nconst SideMenuLayout: React.FC<SettingSectionChildProps> = ({ children, ...other }) => (\r\n <div className=\"full\">\r\n <TopRootSectionMenu { ...other }/>\r\n <div \r\n id=\"setting-scroll-context\" \r\n className=\"ui segment grid main\"\r\n >\r\n <SideChildSectionMenu { ...other }/>\r\n <Content { ...other }>\r\n { children }\r\n </Content>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default SideMenuLayout;\r\n","import * as React from 'react';\r\n\r\nimport Dropdown from 'components/semantic/Dropdown';\r\nimport SectionedDropdown from 'components/semantic/SectionedDropdown';\r\nimport MenuSection from 'components/semantic/MenuSection';\r\nimport Icon from 'components/semantic/Icon';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { translateSettingSectionTitle } from './MenuItems';\r\n\r\n\r\n\r\n// eslint-disable-next-line max-len\r\ntype TopSectionSelectionMenuProps = Pick<SettingSectionChildProps, 'menuItems' | 'currentMenuItem' | 'parent' | 'advancedMenuItems' | 'parentMenuItems' | 'settingsT'>;\r\n\r\nconst TopSectionSelectionMenu: React.FC<TopSectionSelectionMenuProps> = (\r\n { menuItems, advancedMenuItems, currentMenuItem, parentMenuItems, parent, settingsT }\r\n) => (\r\n <div className=\"ui top-menu\">\r\n <Dropdown \r\n selection={ true }\r\n caption={ translateSettingSectionTitle(parent!.title, settingsT) }\r\n captionIcon={ `green ${parent!.icon}` }\r\n >\r\n { parentMenuItems }\r\n </Dropdown>\r\n\r\n <Icon \r\n icon=\"caret right\"\r\n size=\"large\"\r\n />\r\n\r\n <SectionedDropdown \r\n selection={ true }\r\n caption={ translateSettingSectionTitle(currentMenuItem.title, settingsT) }\r\n >\r\n <MenuSection>\r\n { menuItems }\r\n </MenuSection>\r\n <MenuSection caption={ settingsT.translate('Advanced') }>\r\n { advancedMenuItems }\r\n </MenuSection>\r\n </SectionedDropdown>\r\n </div>\r\n);\r\n\r\n\r\nconst TopMenuLayout: React.FC<SettingSectionChildProps> = (\r\n { saveButton, children, contentClassname, message, ...other }\r\n) => (\r\n <div className=\"mobile\">\r\n <TopSectionSelectionMenu { ...other }/>\r\n <div \r\n id=\"setting-scroll-context\" \r\n className={ contentClassname }\r\n >\r\n { !!saveButton && React.cloneElement(saveButton, { className: 'fluid' }) }\r\n <div className=\"options\">\r\n { message }\r\n { children }\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default TopMenuLayout;\r\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport SettingsMenuDecorator, { SettingsMenuDecoratorChildProps } from '../decorators/SettingsMenuDecorator';\r\nimport { useMobileLayout } from 'utils/BrowserUtils';\r\n\r\nimport SettingsSideMenuLayout from './SettingsSideMenuLayout';\r\nimport SettingsTopMenuLayout from './SettingsTopMenuLayout';\r\n\r\nimport SaveDecorator, { SaveDecoratorChildProps, SaveDecoratorProps } from '../decorators/SaveDecorator';\r\nimport { RouteComponentProps } from 'react-router';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { menuItemToLinkComponent } from './MenuItems';\r\n\r\n\r\nexport interface SettingSectionProps {\r\n\r\n}\r\n\r\ntype Props = SaveDecoratorChildProps & SettingsMenuDecoratorChildProps;\r\n\r\nexport type SettingSectionChildProps<RouteParams extends object = UI.EmptyObject> = \r\n SaveDecoratorChildProps & \r\n Pick<Props, 'parent' | 'currentMenuItem'> & \r\n RouteComponentProps<RouteParams> & \r\n React.PropsWithChildren<{\r\n contentClassname: string;\r\n parentMenuItems: React.ReactNode[];\r\n menuItems: React.ReactNode[];\r\n advancedMenuItems?: React.ReactNode[];\r\n settingsT: UI.ModuleTranslator;\r\n moduleT: UI.ModuleTranslator;\r\n }>;\r\n\r\n\r\n\r\nconst SettingSection: React.FC<Props> = (props) => {\r\n const Component = useMobileLayout() || window.innerWidth < 1000 ? SettingsTopMenuLayout : SettingsSideMenuLayout;\r\n\r\n const { moduleT, settingsT, parentMenuItems, menuItems, advancedMenuItems, location, ...childProps } = props;\r\n const { parent, currentMenuItem } = props;\r\n\r\n const contentClassname = classNames(\r\n 'section-content',\r\n `${parent!.url} ${currentMenuItem.url}`,\r\n );\r\n\r\n return (\r\n <Component \r\n { ...childProps }\r\n settingsT={ settingsT }\r\n moduleT={ moduleT! }\r\n location={ location }\r\n contentClassname={ contentClassname }\r\n parentMenuItems={ \r\n props.parentMenuItems!.map(item => menuItemToLinkComponent(item, undefined, settingsT, location)) \r\n }\r\n menuItems={ !props.menuItems ? [] : \r\n props.menuItems.map(item => menuItemToLinkComponent(item, parent, settingsT, location)) \r\n }\r\n advancedMenuItems={ !advancedMenuItems ? undefined : \r\n advancedMenuItems.map(item => menuItemToLinkComponent(item, parent, settingsT, location)) \r\n }\r\n />\r\n );\r\n};\r\n\r\nconst SettingSectionDecorated = SettingsMenuDecorator<SaveDecoratorProps>(\r\n SaveDecorator<SettingsMenuDecoratorChildProps>(SettingSection)\r\n);\r\n\r\nexport default SettingSectionDecorated;\r\n","import PropTypes from 'prop-types';\r\nimport { Component } from 'react';\r\nimport Button from 'components/semantic/Button';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport classNames from 'classnames';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nexport interface SaveButtonProps {\r\n saveHandler: () => Promise<void>;\r\n hasChanges: boolean;\r\n local?: boolean;\r\n className?: string;\r\n settingsT: UI.ModuleTranslator;\r\n}\r\n\r\nclass SaveButton extends Component<SaveButtonProps> {\r\n static propTypes = {\r\n /**\r\n * Message title\r\n */\r\n hasChanges: PropTypes.bool.isRequired,\r\n\r\n /**\r\n * Error details\r\n */\r\n saveHandler: PropTypes.func.isRequired,\r\n\r\n local: PropTypes.bool,\r\n };\r\n\r\n state = {\r\n saving: false\r\n };\r\n\r\n toggleSaveState = () => {\r\n this.setState({ saving: !this.state.saving });\r\n }\r\n\r\n onClick = () => {\r\n this.toggleSaveState();\r\n this.props.saveHandler()\r\n .then(this.toggleSaveState)\r\n .catch(this.toggleSaveState);\r\n }\r\n\r\n render() {\r\n const { local, hasChanges, className, settingsT } = this.props;\r\n\r\n const hasAccess: boolean = local || LoginStore.hasAccess(API.AccessEnum.SETTINGS_EDIT);\r\n\r\n let title;\r\n if (!hasAccess) {\r\n title = settingsT.translate('No save permission');\r\n } else {\r\n title = settingsT.translate(hasChanges ? 'Save changes' : 'No unsaved changes');\r\n }\r\n\r\n return (\r\n <Button \r\n className={ classNames('save', className) }\r\n caption={ title }\r\n icon={ (hasAccess && hasChanges ? 'green checkmark' : null) } \r\n loading={ this.state.saving } \r\n disabled={ !hasChanges || !hasAccess }\r\n onClick={ this.onClick }\r\n />\r\n );\r\n }\r\n}\r\n\r\nexport default SaveButton;","import * as React from 'react';\r\nimport { Prompt, RouteComponentProps } from 'react-router-dom';\r\nimport invariant from 'invariant';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport SaveButton, { SaveButtonProps } from '../components/SaveButton';\r\nimport NotificationActions from 'actions/NotificationActions';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport Form, { FormFieldChangeHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { ChildSectionType } from './SettingsMenuDecorator';\r\nimport { Location } from 'history';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nexport interface SaveDecoratorProps {\r\n currentMenuItem: ChildSectionType;\r\n settingsT: UI.ModuleTranslator;\r\n}\r\n\r\nexport interface SaveDecoratorChildProps {\r\n saveButton: React.ReactElement<SaveButtonProps> | false;\r\n message: React.ReactNode;\r\n}\r\n\r\ntype SaveableRef = Pick<Form, 'save'>;\r\n\r\n\r\nexport interface SaveDecoratorContext {\r\n onFieldChanged: FormFieldChangeHandler;\r\n addFormRef: (keys: string[], c: SaveableRef | null) => void;\r\n getFormRef: (keys: string[]) => SaveableRef;\r\n}\r\n\r\nexport const SaveDecoratorContext = React.createContext<SaveDecoratorContext | undefined>(undefined);\r\n\r\n\r\nexport interface SaveContextProps {\r\n saveContext: SaveDecoratorContext;\r\n}\r\n\r\nexport function withSaveContext<PropsT>(Component: React.ComponentType<PropsT & SaveContextProps>) {\r\n return function withSaveContext(props: PropsT) {\r\n return (\r\n <SaveDecoratorContext.Consumer>\r\n { context => <Component {...props} saveContext={ context! } /> }\r\n </SaveDecoratorContext.Consumer>\r\n );\r\n };\r\n}\r\n\r\nconst getFormId = (keys: string[]) => {\r\n return keys.join('_');\r\n}\r\n\r\nexport default function <PropsT extends object>(\r\n Component: React.ComponentType<SaveDecoratorChildProps & PropsT>\r\n) {\r\n type Props = SaveDecoratorProps & Pick<RouteComponentProps, 'location'> & PropsT;\r\n \r\n class SaveDecorator extends React.Component<React.PropsWithChildren<Props>> {\r\n static displayName = 'SaveDecorator';\r\n\r\n forms: { [key: string]: SaveableRef } = {};\r\n changedProperties = new Set<string>();\r\n\r\n componentDidUpdate(prevProps: SaveDecoratorProps) {\r\n if (prevProps.currentMenuItem.url !== this.props.currentMenuItem.url) {\r\n this.changedProperties.clear();\r\n }\r\n }\r\n\r\n onSettingsChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n if (hasChanges) {\r\n this.changedProperties.add(id);\r\n } else {\r\n this.changedProperties.delete(id);\r\n }\r\n\r\n this.forceUpdate();\r\n }\r\n\r\n onSettingsSaved = () => {\r\n const { translate } = this.props.settingsT;\r\n NotificationActions.success({ \r\n title: translate('Saving completed'),\r\n message: translate('Settings were saved successfully'),\r\n });\r\n\r\n this.forceUpdate();\r\n }\r\n\r\n handleSave = () => {\r\n invariant(Object.keys(this.forms).length > 0, 'No forms exist in SaveDecorator');\r\n const promises = Object.values(this.forms).map(c => c.save());\r\n this.changedProperties.clear();\r\n\r\n return Promise.all(promises)\r\n .then(this.onSettingsSaved);\r\n }\r\n\r\n hasChanges = () => {\r\n return this.changedProperties.size > 0;\r\n }\r\n\r\n promptSave = (nextLocation: Location) => {\r\n const { currentMenuItem, settingsT } = this.props;\r\n if (currentMenuItem.noSave) {\r\n return true;\r\n }\r\n\r\n // Closing/opening a modal?\r\n if (this.props.location.pathname.indexOf(nextLocation.pathname) !== -1 || \r\n nextLocation.pathname.indexOf(this.props.location.pathname) !== -1\r\n ) {\r\n return true;\r\n }\r\n\r\n const hasChanges = this.hasChanges() && LoginStore.hasAccess(API.AccessEnum.SETTINGS_EDIT);\r\n return !hasChanges ? true :\r\n settingsT.t('unsavedChangesPrompt', 'You have unsaved changes. Are you sure you want to leave?');\r\n }\r\n\r\n addFormRef = (keys: string[], c: SaveableRef | null) => {\r\n if (c) {\r\n invariant(\r\n c.hasOwnProperty('save'), \r\n 'Invalid setting form component supplied for SaveDecorator (save property missing)'\r\n );\r\n this.forms[getFormId(keys)] = c;\r\n } else {\r\n // Switching to another page \r\n // Single forms shouldn't be unmounted otherwise, but using identifiers would still be safer...\r\n this.forms = {};\r\n }\r\n }\r\n\r\n getFormRef = (keys: string[]) => {\r\n return this.forms[getFormId(keys)]\r\n }\r\n\r\n saveContext: SaveDecoratorContext = {\r\n onFieldChanged: this.onSettingsChanged,\r\n addFormRef: this.addFormRef,\r\n getFormRef: this.getFormRef,\r\n };\r\n\r\n render() {\r\n const { currentMenuItem, children, settingsT } = this.props;\r\n\r\n const message = currentMenuItem.local && (\r\n <Message \r\n description={ settingsT.t<string>(\r\n 'browserSpecificNote', \r\n 'Settings listed on this page are browser-specific'\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />\r\n );\r\n\r\n const saveButton = !currentMenuItem.noSave && (\r\n <SaveButton \r\n saveHandler={ this.handleSave } \r\n hasChanges={ this.hasChanges() }\r\n local={ currentMenuItem.local }\r\n settingsT={ settingsT }\r\n />\r\n );\r\n\r\n return (\r\n <Component \r\n { ...this.props }\r\n saveButton={ saveButton }\r\n message={ message }\r\n >\r\n <SaveDecoratorContext.Provider value={ this.saveContext }>\r\n <Prompt\r\n message={ this.promptSave }\r\n />\r\n { children }\r\n </SaveDecoratorContext.Provider>\r\n </Component>\r\n );\r\n }\r\n }\r\n\r\n return SaveDecorator;\r\n}\r\n","import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\nimport { \r\n Redirect,\r\n RouteComponentProps \r\n} from 'react-router-dom';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { \r\n menuItemsToRouteComponentArray, findMenuItem, sectionToUrl \r\n} from '../components/MenuItems';\r\n\r\n\r\nexport interface SectionType {\r\n url: string;\r\n access?: string;\r\n title: string;\r\n component: React.ComponentType<SettingsMenuDecoratorProps>;\r\n debugOnly?: boolean;\r\n icon?: string;\r\n menuItems?: ChildSectionType[] | RootSectionType[];\r\n advancedMenuItems?: ChildSectionType[];\r\n parentMenuItems?: RootSectionType[];\r\n noSave?: boolean;\r\n local?: boolean;\r\n}\r\n\r\nexport interface RootSectionType extends SectionType {\r\n\r\n}\r\n\r\nexport interface ChildSectionType extends SectionType {\r\n\r\n}\r\n\r\nexport interface SettingsMenuDecoratorProps \r\n extends RouteComponentProps<UI.EmptyObject>\r\n{\r\n parent?: RootSectionType;\r\n menuItems?: ChildSectionType[] | RootSectionType[];\r\n advancedMenuItems?: ChildSectionType[];\r\n parentMenuItems?: RootSectionType[];\r\n settingsT: UI.ModuleTranslator;\r\n moduleT?: UI.ModuleTranslator;\r\n}\r\n\r\nexport type SettingsMenuDecoratorChildProps = \r\n SettingsMenuDecoratorProps & \r\n React.PropsWithChildren<{\r\n currentMenuItem: SectionType;\r\n parent?: RootSectionType;\r\n }>;\r\n\r\nexport default function <PropsT>(Component: React.ComponentType<SettingsMenuDecoratorChildProps & PropsT>) {\r\n class SettingsMenuDecorator extends React.Component<SettingsMenuDecoratorProps & PropsT> {\r\n static propTypes = {\r\n parent: PropTypes.object,\r\n menuItems: PropTypes.array.isRequired,\r\n advancedMenuItems: PropTypes.array,\r\n location: PropTypes.object.isRequired,\r\n match: PropTypes.object.isRequired,\r\n };\r\n\r\n render() {\r\n const { location, match, parent, menuItems, advancedMenuItems, settingsT, moduleT } = this.props;\r\n if (location.pathname === match.url ||\r\n (parent && location.pathname === sectionToUrl(parent as SectionType))\r\n ) {\r\n if (!!menuItems && menuItems.length) {\r\n return <Redirect to={ sectionToUrl(menuItems[0], parent) }/>;\r\n }\r\n }\r\n\r\n const currentMenuItem = findMenuItem(menuItems, parent, location) || \r\n findMenuItem(advancedMenuItems, parent, location);\r\n\r\n if (!currentMenuItem) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Component \r\n { ...this.props } \r\n currentMenuItem={ currentMenuItem }\r\n >\r\n { menuItemsToRouteComponentArray(currentMenuItem, menuItems, settingsT, moduleT, parent) }\r\n { menuItemsToRouteComponentArray(currentMenuItem, advancedMenuItems, settingsT, moduleT, parent) }\r\n </Component>\r\n );\r\n }\r\n }\r\n\r\n return SettingsMenuDecorator;\r\n}\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","\r\nimport { Component } from 'react';\r\nimport { RouteComponentProps } from 'react-router';\r\nimport { withTranslation, WithTranslation } from 'react-i18next';\r\n\r\nimport SettingsMenuDecorator from '../decorators/SettingsMenuDecorator';\r\nimport { getModuleT } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport '../style.css';\r\n\r\n\r\nconst menu = [\r\n require('../routes/Profile'),\r\n require('../routes/Connectivity'),\r\n require('../routes/SpeedLimits'),\r\n require('../routes/Downloads'),\r\n require('../routes/Sharing'),\r\n require('../routes/View'),\r\n require('../routes/About'),\r\n require('../routes/Extensions'),\r\n require('../routes/System'),\r\n];\r\n\r\nconst MainLayout = SettingsMenuDecorator(({ children }) => {\r\n return (\r\n <div className=\"ui segment settings-layout\">\r\n { children }\r\n </div>\r\n );\r\n});\r\n\r\nexport interface SettingsProps extends RouteComponentProps, WithTranslation {\r\n\r\n}\r\n\r\n// Only to pass menu items to the decorated component\r\nclass Settings extends Component<SettingsProps> {\r\n settingsT = getModuleT(this.props.t, UI.Modules.SETTINGS);\r\n render() {\r\n return (\r\n <MainLayout \r\n { ...this.props } \r\n menuItems={ menu }\r\n settingsT={ this.settingsT }\r\n />\r\n );\r\n }\r\n}\r\n\r\nexport default withTranslation()(Settings);","\r\nimport * as React from 'react';\r\n\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\nimport SystemConstants from 'constants/SystemConstants';\r\nimport { formatDateTime, formatRelativeTime } from 'utils/ValueFormat';\r\nimport InstallPrompt from 'components/InstallPrompt';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport ExternalLink from 'components/ExternalLink';\r\n\r\n\r\ninterface ApplicationPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\nconst ApplicationPage: React.FC<ApplicationPageProps & StatisticsDecoratorChildProps<any>> = ({ stats, moduleT }) => {\r\n const { translate } = moduleT;\r\n const systemInfo = LoginStore.systemInfo;\r\n\r\n const buildDate = formatDateTime(UI_BUILD_DATE / 1000);\r\n return (\r\n <>\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row title={ translate('Application version') } text={ systemInfo.client_version }/>\r\n <Row title={ translate('Web UI version') } text={ UI_VERSION }/>\r\n <Row title={ translate('Web UI build date') } text={ buildDate }/>\r\n <Row title={ translate('API version') } text={ systemInfo.api_version }/>\r\n <Row title={ translate('API feature level') } text={ systemInfo.api_feature_level }/>\r\n <Row title={ translate('Started') } text={ formatRelativeTime(systemInfo.client_started) }/>\r\n <Row title={ translate('Active sessions') } text={ stats.active_sessions }/>\r\n <Row title={ translate('Server threads') } text={ stats.server_threads }/>\r\n\r\n <Header title={ translate('Resources') }/>\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.HOME_PAGE_URL }>\r\n { translate('Home page') }\r\n </ExternalLink>\r\n }\r\n noText={ true }\r\n />\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.HELP_URL }>\r\n { translate('Documentation') }\r\n </ExternalLink> \r\n }\r\n noText={ true }\r\n />\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.ISSUE_TRACKER_URL }>\r\n { translate('Feature request/bug tracker') }\r\n </ExternalLink> \r\n }\r\n noText={ true }\r\n />\r\n <Header title={ translate('Third-party credits') }/>\r\n <Row\r\n title={ \r\n <ExternalLink url={ LinkConstants.DBIP_URL }>\r\n IP Geolocation by DB-IP\r\n </ExternalLink> \r\n }\r\n noText={ true }\r\n />\r\n </Grid>\r\n <InstallPrompt alwaysShow={ true }/>\r\n </>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(ApplicationPage, SystemConstants.STATS_URL, null, 5);\r\n","\r\nimport * as React from 'react';\r\n\r\nimport { formatAverage, formatConnection, formatPercentage, formatSize } from 'utils/ValueFormat';\r\n\r\nimport HubConstants from 'constants/HubConstants';\r\n\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\n\r\nimport { Grid, Row, Header } from 'components/semantic/Grid';\r\n\r\n//import * as UI from 'types/ui';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface HubStatisticsPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\ninterface ClientInfo { \r\n name: string; \r\n count: number; \r\n}\r\n\r\nconst formatClientRow = (uniqueUsers: number, client: ClientInfo) => {\r\n return (\r\n <Row\r\n key={ client.name }\r\n title={ client.name }\r\n text={ `${client.count} (${formatPercentage(client.count, uniqueUsers)})` }\r\n />\r\n );\r\n};\r\n\r\nconst HubStatisticsPage: React.FC<HubStatisticsPageProps & StatisticsDecoratorChildProps<any>> = (\r\n { stats, moduleT }\r\n) => {\r\n const { translate } = moduleT;\r\n return (\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row \r\n title={ translate('Total users') } \r\n text={ stats.total_users }\r\n />\r\n <Row \r\n title={ translate('Unique users') } \r\n text={ `${stats.unique_users} (${formatPercentage(stats.unique_users, stats.total_users)})` }\r\n />\r\n <Row \r\n title={ translate('Active users') } \r\n text={ `${stats.active_users} (${formatPercentage(stats.active_users, stats.unique_users)})` }\r\n />\r\n <Row \r\n title={ translate('Total share') } \r\n text={ formatSize(stats.total_share, moduleT.plainT) }\r\n />\r\n <Row \r\n title={ translate('Average share per user') }\r\n text={ formatSize(\r\n (formatAverage(stats.total_share, stats.unique_users) as any as number),\r\n moduleT.plainT\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Average ADC download speed') } \r\n text={ formatConnection(stats.adc_down_per_user, moduleT.plainT) }\r\n />\r\n <Row \r\n title={ translate('Average ADC upload speed') } \r\n text={ formatConnection(stats.adc_up_per_user, moduleT.plainT) }\r\n />\r\n <Header title={ translate('Clients') }/>\r\n { stats.clients.map((c: ClientInfo) => formatClientRow(stats.unique_users, c)) }\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(\r\n HubStatisticsPage, \r\n HubConstants.STATS_URL, \r\n (t, props) => props.moduleT.translate('No hubs online'), \r\n 10\r\n);","\r\nimport * as React from 'react';\r\n\r\nimport { formatAverage, formatPercentage, formatSeconds, formatSize } from 'utils/ValueFormat';\r\n\r\nimport ShareConstants from 'constants/ShareConstants';\r\n\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\n\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\n//import * as UI from 'types/ui';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ntype ShareStatisticsPageProps = SettingSectionChildProps\r\n\r\nconst ShareStatisticsPage: React.FC<ShareStatisticsPageProps & StatisticsDecoratorChildProps<any>> = (\r\n { stats, moduleT }\r\n) => {\r\n const { translate, t } = moduleT;\r\n return (\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row \r\n title={ translate('Total share size') } \r\n text={ formatSize(stats.total_size, moduleT.plainT) }\r\n />\r\n <Row \r\n title={ translate('Total files') } \r\n // eslint-disable-next-line max-len\r\n text={ t(\r\n 'totalFilesValue',\r\n {\r\n defaultValue: '{{totalCount}} ({{uniqueCount}} unique)',\r\n replace: {\r\n totalCount: stats.total_file_count,\r\n uniqueCount: formatPercentage(stats.unique_file_count, stats.total_file_count)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Total directories') } \r\n text={ stats.total_directory_count }\r\n />\r\n <Row \r\n title={ translate('Average file age') } \r\n text={ formatSeconds(stats.average_file_age) }\r\n />\r\n <Row \r\n title={ translate('Average files per directory') } \r\n text={ formatAverage(stats.total_file_count, stats.total_directory_count) }\r\n />\r\n\r\n <Header title={ translate('Incoming searches') }/>\r\n <Row \r\n title={ translate('Total searches') } \r\n text={ t(\r\n 'searchesTotalValue',\r\n {\r\n defaultValue: '{{totalCount}} ({{perSecondCount}} per second)',\r\n replace: {\r\n totalCount: stats.total_searches,\r\n perSecondCount: stats.total_searches_per_second.toFixed(1)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('TTH searches') } \r\n text={ formatPercentage(stats.tth_searches, stats.total_searches) }\r\n />\r\n <Row \r\n title={ translate('Text searches') } \r\n // eslint-disable-next-line max-len\r\n text={ t(\r\n 'searchesPerSecondValue',\r\n {\r\n defaultValue: '{{totalCount}} ({{matchedCount}} matched per second)',\r\n replace: {\r\n totalCount: stats.recursive_searches,\r\n matchedCount: stats.unfiltered_recursive_searches_per_second.toFixed(2)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Filtered text searches') } \r\n text={ t(\r\n 'searchesFilteredValue',\r\n {\r\n defaultValue: '{{filteredPercentage}} ({{resultPercentage}} of the matched ones returned results)',\r\n replace: {\r\n filteredPercentage: formatPercentage(stats.filtered_searches, stats.recursive_searches),\r\n resultPercentage: formatPercentage(\r\n stats.recursive_searches_responded, \r\n stats.recursive_searches - stats.filtered_searches\r\n )\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Average text search tokens (non-filtered)') }\r\n // eslint-disable-next-line max-len\r\n text={ t(\r\n 'searchesAverageTokensValue',\r\n {\r\n defaultValue: '{{tokenCount}} ({{tokenLength}} bytes per token)',\r\n replace: {\r\n tokenCount: stats.average_search_token_count.toFixed(1),\r\n tokenLength: stats.average_search_token_length.toFixed(1)\r\n }\r\n }\r\n ) }\r\n />\r\n <Row \r\n title={ translate('Average matching time per text search') } \r\n text={ t(\r\n 'searchesAverageMatchTimeValue',\r\n {\r\n defaultValue: '{{matchTime}} ms',\r\n replace: {\r\n matchTime: stats.average_match_ms\r\n }\r\n }\r\n ) }\r\n />\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(\r\n ShareStatisticsPage, \r\n ShareConstants.STATS_URL, \r\n (t, props) => props.moduleT.translate('No files shared'), \r\n 60\r\n);","\r\nimport * as React from 'react';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\nimport TransferConstants from 'constants/TransferConstants';\r\nimport StatisticsDecorator, { StatisticsDecoratorChildProps } from 'decorators/StatisticsDecorator';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface TransferStatisticsPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\nconst TransferStatisticsPage: React.FC<TransferStatisticsPageProps & StatisticsDecoratorChildProps<any>> = (\r\n { stats, moduleT }\r\n) => {\r\n const { translate, plainT } = moduleT;\r\n\r\n const totalUp = stats.session_uploaded + stats.start_total_uploaded;\r\n const totalDown = stats.session_downloaded + stats.start_total_downloaded;\r\n\r\n return (\r\n <Grid columns=\"two\" stackable={ true }>\r\n <Row \r\n title={ translate('Total downloaded') } \r\n text={ formatSize(totalDown, plainT) }\r\n />\r\n <Row \r\n title={ translate('Total uploaded') } \r\n text={ formatSize(totalUp, plainT) }\r\n />\r\n <Header title={ translate('Session') }/>\r\n <Row \r\n title={ translate('Session downloaded') } \r\n text={ formatSize(stats.session_downloaded, plainT) }\r\n />\r\n <Row \r\n title={ translate('Session uploaded') } \r\n text={ formatSize(stats.session_uploaded, plainT) }\r\n />\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(TransferStatisticsPage, TransferConstants.TRANSFERRED_BYTES_URL, null, 5);\r\n","const AccessConstants = require('constants/AccessConstants').default;\r\n\r\nmodule.exports = {\r\n url: 'about',\r\n title: 'About',\r\n icon: 'info',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Application', \r\n noSave: true,\r\n url: 'application',\r\n component: require('./components/ApplicationPage').default, \r\n }, { \r\n title: 'Transfer statistics', \r\n noSave: true,\r\n url: 'transfers',\r\n access: AccessConstants.TRANSFERS,\r\n component: require('./components/TransferStatisticsPage').default, \r\n }, { \r\n title: 'Share statistics', \r\n noSave: true,\r\n url: 'share',\r\n component: require('./components/ShareStatisticsPage').default, \r\n }, { \r\n title: 'Hub statistics', \r\n noSave: true,\r\n url: 'hubs',\r\n access: AccessConstants.HUBS_VIEW,\r\n component: require('./components/HubStatisticsPage').default, \r\n },\r\n ],\r\n};","const MODULE_URL = 'connectivity';\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n DETECT_URL: MODULE_URL + '/detect',\r\n STATUS_URL: MODULE_URL + '/status',\r\n\r\n CONNECTIVITY_MESSAGE: 'connectivity_detection_message',\r\n CONNECTIVITY_STARTED: 'connectivity_detection_started',\r\n CONNECTIVITY_FINISHED: 'connectivity_detection_finished',\r\n}\r\n;\r\n","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport AccessConstants from 'constants/AccessConstants';\r\nimport ConnectivityConstants from 'constants/ConnectivityConstants';\r\n\r\nimport * as UI from 'types/ui';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst ConnectivityActions: UI.ActionListType<undefined> = {\r\n detect: {\r\n displayName: 'Detect now',\r\n access: AccessConstants.SETTINGS_EDIT,\r\n icon: IconConstants.CONFIGURE,\r\n handler: () => {\r\n return SocketService.post(ConnectivityConstants.DETECT_URL);\r\n }\r\n }\r\n};\r\n\r\nexport default {\r\n moduleId: UI.Modules.SETTINGS,\r\n actions: ConnectivityActions,\r\n};\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ConnectivityActions from 'actions/ui/ConnectivityActions';\r\nimport ConnectivityConstants from 'constants/ConnectivityConstants';\r\n\r\nimport { Row, Grid } from 'components/semantic/Grid';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst formatStatus = (\r\n protocolStatus: API.ConnectivityProtocolStatus, \r\n running: boolean,\r\n moduleT: UI.ModuleTranslator\r\n) => {\r\n const { translate, t } = moduleT;\r\n if (running) {\r\n return translate('Detecting...');\r\n }\r\n\r\n const auto = protocolStatus.auto_detect;\r\n const ret = t(auto ? 'autoDetected' : 'manualConfiguration', {\r\n defaultValue: auto ? '{{status}} (auto detected)' : '{{status}} (manual configuration)',\r\n replace: {\r\n status: protocolStatus.text\r\n }\r\n });\r\n\r\n return ret;\r\n};\r\n\r\n\r\ninterface DetectPanelProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DetectPanelDataProps extends DataProviderDecoratorChildProps {\r\n status: API.ConnectivityStatus;\r\n runningV4: boolean;\r\n runningV6: boolean;\r\n}\r\n\r\nconst DetectPanel: React.FC<DetectPanelProps & DetectPanelDataProps> = (\r\n { status, runningV4, runningV6, moduleT }\r\n) => (\r\n <div className=\"ui segment detect-panel\">\r\n <h3 className=\"header\">\r\n { moduleT.translate('Current auto detection status') }\r\n </h3>\r\n <Grid columns=\"two\">\r\n <Row \r\n title={ moduleT.translate('IPv4 connectivity') } \r\n text={ formatStatus(status.status_v4, runningV4, moduleT) }\r\n />\r\n <Row \r\n title={ moduleT.translate('IPv6 connectivity') } \r\n text={ formatStatus(status.status_v6, runningV6, moduleT) }\r\n />\r\n </Grid>\r\n <ActionButton \r\n className=\"detect-button\"\r\n actions={ ConnectivityActions }\r\n actionId=\"detect\"\r\n disabled={ !status.status_v4.auto_detect && !status.status_v6.auto_detect }\r\n loading={ runningV6 || runningV4 } \r\n />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<DetectPanelProps, DetectPanelDataProps>(DetectPanel, {\r\n urls: {\r\n status: ConnectivityConstants.STATUS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData, mergeData }) => {\r\n const setDetectState = (v6: boolean, running: boolean) => {\r\n const value = 'running' + (v6 ? 'V6' : 'V4');\r\n mergeData({ \r\n [value]: running,\r\n });\r\n };\r\n\r\n addSocketListener<API.ConnectivityDetectionStarted>(\r\n ConnectivityConstants.MODULE_URL, \r\n ConnectivityConstants.CONNECTIVITY_STARTED, \r\n data => {\r\n setDetectState(data.v6, true);\r\n }\r\n );\r\n\r\n addSocketListener<API.ConnectivityDetectionFinished>(\r\n ConnectivityConstants.MODULE_URL, \r\n ConnectivityConstants.CONNECTIVITY_FINISHED, \r\n data => {\r\n setDetectState(data.v6, false);\r\n refetchData();\r\n }\r\n );\r\n },\r\n});","import * as React from 'react';\r\n\r\nimport DetectPanel from 'routes/Settings/routes/Connectivity/components/DetectPanel';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport { Trans } from 'react-i18next';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst DetectionPage: React.FC<SettingSectionChildProps> = props => {\r\n const { toI18nKey } = props.moduleT;\r\n return (\r\n <div>\r\n <DetectPanel\r\n moduleT={ props.moduleT }\r\n />\r\n <Message \r\n description={\r\n <Trans i18nKey={ toI18nKey('connectivityDetectionNote') }>\r\n In case of file transfer connectivity issues, please confirm that your TCP ports are really open by \r\n using <ExternalLink url={ LinkConstants.PORTCHECK_URL }>an online port checker</ExternalLink>. Note that \r\n validity of the UDP port (search) can't be checked online.\r\n\r\n For more information about different connectivity modes, please visit \r\n { ' ' }\r\n <ExternalLink url={ LinkConstants.CONNECTIVITY_HELP_URL }>DC++'s connectivity FAQ</ExternalLink>.\r\n </Trans>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DetectionPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'always_ccpm',\r\n 'tls_mode',\r\n 'tls_allow_untrusted_clients',\r\n 'tls_allow_untrusted_hubs',\r\n];\r\n\r\nconst Encryption: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default Encryption;","import * as React from 'react';\r\nimport ProtocolPage from 'routes/Settings/routes/Connectivity/components/ProtocolPage';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'connection_auto_v4',\r\n 'connection_bind_v4',\r\n 'connection_mode_v4',\r\n 'connection_ip_v4',\r\n 'connection_update_ip_v4',\r\n 'connection_ip_override_v4',\r\n];\r\n\r\nconst IPv4: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <ProtocolPage\r\n { ...props }\r\n keys={ Entry }\r\n protocol=\"v4\"\r\n />\r\n </div>\r\n);\r\n\r\nexport default IPv4;","import * as React from 'react';\r\nimport ProtocolPage from 'routes/Settings/routes/Connectivity/components/ProtocolPage';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'connection_auto_v6',\r\n 'connection_bind_v6',\r\n 'connection_mode_v6',\r\n 'connection_ip_v6',\r\n 'connection_update_ip_v6',\r\n 'connection_ip_override_v6',\r\n];\r\n\r\nconst IPv6: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <ProtocolPage\r\n { ...props }\r\n keys={ Entry }\r\n protocol=\"v6\"\r\n />\r\n </div>\r\n);\r\n\r\nexport default IPv6;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst Entry = [\r\n 'tcp_port',\r\n 'udp_port',\r\n 'tls_port',\r\n 'preferred_port_mapper',\r\n];\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const translate = (text: string) => {\r\n return moduleT.t(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined),\r\n text\r\n );\r\n };\r\n\r\n if (id === 'tcp_port') {\r\n fieldOptions.help = translate('TCP port is used for unencrypted transfers');\r\n } else if (id === 'tls_port') {\r\n fieldOptions.help = translate('TLS port (TCP) is used for encrypted transfers');\r\n } else if (id === 'udp_port') {\r\n fieldOptions.help = translate('UDP port is used for searching');\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\nconst PortsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <Message \r\n description={ props.moduleT.t<string>(\r\n 'portsAutoValuesNote', \r\n 'Port numbers listed on this page can be overridden by port mappers (if enabled)'\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ FieldOptionGetter(props.moduleT) }\r\n valueMode={ API.SettingValueMode.FORCE_MANUAL }\r\n />\r\n </div>\r\n);\r\n\r\nexport default PortsPage;","import { Component } from 'react';\r\nimport RemoteSettingForm, { RemoteSettingFormProps } from 'routes/Settings/components/RemoteSettingForm';\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport { IncomingConnectionModeEnum } from 'constants/SettingConstants';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nimport * as API from 'types/api';\r\n\r\n\r\ninterface ProtocolPageProps extends SettingSectionChildProps, RemoteSettingFormProps {\r\n protocol: string;\r\n}\r\n\r\nclass ProtocolPage extends Component<ProtocolPageProps> {\r\n state = {\r\n autoDetectEnabled: false,\r\n };\r\n\r\n convertValue = (key: string) => {\r\n return `${key}_${this.props.protocol}`;\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const protocolEnabled = formValue[this.convertValue('connection_mode')] !== \r\n IncomingConnectionModeEnum.INCOMING_DISABLED;\r\n const autoDetect = formValue[this.convertValue('connection_auto')];\r\n\r\n if ((!protocolEnabled || autoDetect) && (\r\n id.indexOf('connection_ip') === 0 || id.indexOf('connection_bind') === 0 ||\r\n id.indexOf('connection_update_ip') === 0 || id.indexOf('connection_ip_override') === 0)\r\n ) {\r\n fieldOptions.disabled = true;\r\n }\r\n\r\n if (autoDetect && id.indexOf('connection_mode') === 0 && protocolEnabled) {\r\n fieldOptions.disabled = true;\r\n }\r\n\r\n if (!protocolEnabled && id.indexOf('connection_auto') === 0) {\r\n fieldOptions.disabled = true;\r\n }\r\n }\r\n\r\n onSettingValuesReceived = (settings: API.SettingValueMap) => {\r\n this.setState({\r\n autoDetectEnabled: settings[this.convertValue('connection_auto')]\r\n });\r\n }\r\n\r\n render() {\r\n return (\r\n <div>\r\n { this.state.autoDetectEnabled && (\r\n <Message\r\n description={ this.props.moduleT.t<string>(\r\n 'protocolAutoValuesNote', \r\n 'Connectivity auto detection is currently enabled; setting values listed on this page are not being used'\r\n ) }\r\n icon={ IconConstants.INFO }\r\n /> \r\n ) }\r\n <RemoteSettingForm\r\n { ...this.props }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSettingValuesReceived={ this.onSettingValuesReceived }\r\n valueMode={ API.SettingValueMode.FORCE_MANUAL }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default ProtocolPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport { OutgoingConnectionModeEnum } from 'constants/SettingConstants';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\n\r\n\r\nconst Entry = [\r\n 'outgoing_mode',\r\n 'socks_server',\r\n 'socks_port',\r\n 'socks_resolve',\r\n 'socks_user',\r\n 'socks_password',\r\n 'http_proxy',\r\n];\r\n\r\nconst onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const socksEnabled = formValue.outgoing_mode === OutgoingConnectionModeEnum.OUTGOING_SOCKS;\r\n\r\n if (!socksEnabled && id.indexOf('socks_') === 0) {\r\n fieldOptions.disabled = true;\r\n }\r\n};\r\n\r\nconst Encryption: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ onFieldSetting }\r\n />\r\n </div>\r\n);\r\n\r\nexport default Encryption;","module.exports = {\r\n url: 'connectivity',\r\n title: 'Connectivity',\r\n icon: 'signal',\r\n component: require('../../components/SettingSection').default,\r\n\r\n menuItems: [\r\n { \r\n title: 'Auto detection', \r\n url: 'detection', \r\n noSave: true,\r\n component: require('./components/DetectionPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'IPv4 connectivity (manual)', \r\n url: 'v4',\r\n component: require('./components/IPv4Page').default,\r\n }, {\r\n title: 'IPv6 connectivity (manual)', \r\n url: 'v6',\r\n component: require('./components/IPv6Page').default,\r\n }, { \r\n title: 'Ports (manual)', \r\n url: 'ports',\r\n component: require('./components/PortsPage').default,\r\n }, { \r\n title: 'Proxies', \r\n url: 'proxies',\r\n component: require('./components/ProxiesPage').default,\r\n }, { \r\n title: 'Encryption', \r\n url: 'encryption',\r\n component: require('./components/EncryptionPage').default,\r\n },\r\n ],\r\n};","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'allow_slow_overlap',\r\n 'finished_remove_exit',\r\n 'use_partial_sharing',\r\n];\r\n\r\n\r\nconst SegmentsEntry = [\r\n 'segmented_downloads',\r\n 'min_segment_size',\r\n];\r\n\r\nconst BufferEntry = [\r\n 'socket_read_buffer',\r\n 'socket_write_buffer',\r\n 'buffer_size',\r\n];\r\n\r\nconst CompressionEntry = [\r\n 'compress_transfers',\r\n 'max_compression',\r\n];\r\n\r\nconst DownloadOptionsPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ SegmentsEntry }\r\n title={ translate('Segments') }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ CompressionEntry }\r\n title={ translate('Compression') }\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ BufferEntry }\r\n title={ translate('Buffers') }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DownloadOptionsPage;","\r\nimport SocketService from 'services/SocketService';\r\nimport History from 'utils/History';\r\n\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<undefined> = ({ location }) => {\r\n History.push(`${location.pathname}/directories`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.FavoriteDirectoryEntry> = ({ data: directory, location }) => {\r\n History.push(`${location.pathname}/directories/${directory.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.FavoriteDirectoryEntry> = (\r\n { data: directory }\r\n) => {\r\n return SocketService.delete(`${FavoriteDirectoryConstants.DIRECTORIES_URL}/${directory.id}`);\r\n};\r\n\r\nconst FavoriteDirectoryCreateActions: UI.ActionListType<undefined> = {\r\n create: { \r\n displayName: 'Add directory',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n },\r\n};\r\n\r\nconst FavoriteDirectoryEditActions: UI.ActionListType<API.FavoriteDirectoryEntry> = {\r\n edit: {\r\n displayName: 'Edit directory',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n },\r\n remove: {\r\n displayName: 'Remove directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the favorite directory {{item.name}}?',\r\n approveCaption: 'Remove directory',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove\r\n },\r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'favoriteDirectory',\r\n actions: FavoriteDirectoryCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'favoriteDirectory',\r\n actions: FavoriteDirectoryEditActions,\r\n }\r\n};\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport { getLastDirectory } from 'utils/FileUtils';\r\n\r\nimport Form, { FormFieldChangeHandler, FormSaveHandler, FormFieldSettingHandler } from 'components/form';\r\nimport { AutoSuggestField } from 'components/form/fields';\r\n\r\nimport FilesystemConstants from 'constants/FilesystemConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { translateForm } from 'utils/FormUtils';\r\n\r\n\r\nconst Entry: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'path',\r\n title: 'Path',\r\n type: API.SettingTypeEnum.DIRECTORY_PATH,\r\n },\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n];\r\n\r\nexport interface FavoriteDirectoryDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.FavoriteDirectoryEntryBase, UI.FormValueMap {\r\n\r\n}\r\n\r\nexport interface DataProps extends DataProviderDecoratorChildProps {\r\n virtualNames: string[];\r\n directoryEntry?: API.FavoriteDirectoryEntryBase;\r\n}\r\n\r\ninterface RouteProps {\r\n directoryId: string; \r\n}\r\n\r\ntype Props = FavoriteDirectoryDialogProps & DataProps & ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass FavoriteDirectoryDialog extends Component<Props> {\r\n static displayName = 'FavoriteDirectoryDialog';\r\n\r\n form: Form<Entry>;\r\n fieldDefinitions = translateForm(Entry, this.props.moduleT);\r\n\r\n isNew = () => {\r\n return !this.props.directoryEntry;\r\n }\r\n\r\n onFieldChanged: FormFieldChangeHandler<Entry> = (id, value, hasChanges) => {\r\n if (id.indexOf('path') !== -1) {\r\n return Promise.resolve({\r\n name: !!value.path ? getLastDirectory(value.path) : undefined \r\n });\r\n }\r\n\r\n return null;\r\n }\r\n\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (this.isNew()) {\r\n return SocketService.post(FavoriteDirectoryConstants.DIRECTORIES_URL, changedFields);\r\n }\r\n\r\n return SocketService.patch(\r\n `${FavoriteDirectoryConstants.DIRECTORIES_URL}/${this.props.directoryEntry!.id}`, \r\n changedFields\r\n );\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'path') {\r\n fieldOptions.disabled = !this.isNew();\r\n fieldOptions.config = Object.assign(fieldOptions.config || {}, {\r\n historyId: FilesystemConstants.LOCATION_DOWNLOAD,\r\n });\r\n } else if (id === 'name') {\r\n fieldOptions.factory = t.form.Textbox;\r\n fieldOptions.template = AutoSuggestField;\r\n fieldOptions.config = {\r\n suggestionGetter: () => this.props.virtualNames,\r\n };\r\n }\r\n }\r\n\r\n render() {\r\n const { moduleT, directoryEntry } = this.props;\r\n const title = moduleT.translate(this.isNew() ? 'Add favorite directory' : 'Edit favorite directory');\r\n return (\r\n <Modal \r\n className=\"favorite-directory\" \r\n title={ title } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.FOLDER } \r\n { ...this.props }\r\n >\r\n <Form<Entry>\r\n ref={ c => this.form = c! }\r\n fieldDefinitions={ this.fieldDefinitions }\r\n onFieldChanged={ this.onFieldChanged }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSave={ this.onSave }\r\n sourceValue={ directoryEntry as Entry }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<FavoriteDirectoryDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(FavoriteDirectoryDialog, {\r\n urls: {\r\n virtualNames: FavoriteDirectoryConstants.GROUPED_DIRECTORIES_URL,\r\n directoryEntry: ({ match }, socket) => {\r\n if (!match.params.directoryId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${FavoriteDirectoryConstants.DIRECTORIES_URL}/${match.params.directoryId}`);\r\n },\r\n },\r\n dataConverters: {\r\n virtualNames: (data: API.GroupedPath[]) => data.map(item => item.name, []),\r\n },\r\n }),\r\n 'directories/:directoryId([0-9A-Z]{39})?'\r\n);","import * as React from 'react';\r\n\r\nimport FavoriteDirectoryActions from 'actions/ui/FavoriteDirectoryActions';\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/menu';\r\nimport FavoriteDirectoryDialog from 'routes/Settings/routes/Downloads/components/FavoriteDirectoryDialog';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst Row: React.FC<{ directory: API.FavoriteDirectoryEntry; }> = ({ directory }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ directory.name }</strong> } \r\n actions={ FavoriteDirectoryActions.edit }\r\n itemData={ directory }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"path\">\r\n { directory.path }\r\n </td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (directory: API.FavoriteDirectoryEntry) => {\r\n return (\r\n <Row \r\n key={ directory.path } \r\n directory={ directory }\r\n />\r\n );\r\n};\r\n\r\ninterface FavoriteDirectoryPageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface FavoriteDirectoryPageDataProps extends DataProviderDecoratorChildProps {\r\n directories: API.FavoriteDirectoryEntry[];\r\n}\r\n\r\nconst FavoriteDirectoryPage: React.FC<FavoriteDirectoryPageProps & FavoriteDirectoryPageDataProps> = (\r\n { directories, moduleT }\r\n) => (\r\n <div id=\"directory-table\">\r\n <ActionButton\r\n actions={ FavoriteDirectoryActions.create }\r\n actionId=\"create\"\r\n />\r\n\r\n { directories.length === 0 ? null : (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ moduleT.translate('Name') }</th>\r\n <th>{ moduleT.translate('Path') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { directories.map(getRow) }\r\n </tbody>\r\n </table>\r\n ) }\r\n <FavoriteDirectoryDialog\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<FavoriteDirectoryPageProps, FavoriteDirectoryPageDataProps>(\r\n FavoriteDirectoryPage, {\r\n urls: {\r\n directories: FavoriteDirectoryConstants.DIRECTORIES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n FavoriteDirectoryConstants.MODULE_URL, \r\n FavoriteDirectoryConstants.DIRECTORIES_UPDATED, \r\n () => refetchData()\r\n );\r\n },\r\n }\r\n);","import * as React from 'react';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport FavoriteDirectoryTable from 'routes/Settings/routes/Downloads/components/FavoriteDirectoryTable';\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst Entry = [\r\n 'download_directory',\r\n];\r\n\r\nconst LocationsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n\r\n <Message \r\n description={ (\r\n <ExternalLink url={ LinkConstants.VARIABLE_HELP_URL }>\r\n { props.moduleT.translate('Available path variables') }\r\n </ExternalLink>\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />\r\n\r\n <div className=\"ui segment setting-form\">\r\n <LayoutHeader \r\n title={ props.moduleT.translate('Favorite download directories') }\r\n icon={ IconConstants.FOLDER }\r\n size=\"normal\"\r\n />\r\n <FavoriteDirectoryTable\r\n moduleT={ props.moduleT }\r\n />\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default LocationsPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'prio_highest_size',\r\n 'prio_high_size',\r\n 'prio_normal_size',\r\n 'prio_auto_default',\r\n];\r\n\r\nconst HighPrioEntry = [\r\n 'prio_high_files_to_highest',\r\n 'prio_high_files',\r\n 'prio_high_files_regex',\r\n];\r\n\r\nconst PrioritiesPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n title={ translate('File priorities') }\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n title={ translate('High priority files') }\r\n { ...props }\r\n keys={ HighPrioEntry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default PrioritiesPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'auto_add_sources',\r\n 'alt_search_auto',\r\n 'alt_search_max_sources',\r\n 'max_sources_match_queue',\r\n 'allow_match_full_list',\r\n];\r\n\r\nconst SearchMatchingPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default SearchMatchingPage;","\r\nimport SocketService from 'services/SocketService';\r\nimport History from 'utils/History';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport SearchConstants from 'constants/SearchConstants';\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<API.SearchType> = ({ location }) => {\r\n History.push(`${location.pathname}/types`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.SearchType> = ({ data: type, location }) => {\r\n History.push(`${location.pathname}/types/${type.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.SearchType> = (\r\n { data: type }\r\n) => {\r\n return SocketService.delete(`${SearchConstants.SEARCH_TYPES_URL}/${type.id}`);\r\n};\r\n\r\nconst SearchTypeCreateActions: UI.ActionListType<API.SearchType> = {\r\n create: { \r\n displayName: 'Add type',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n },\r\n};\r\n\r\nconst SearchTypeEditActions: UI.ActionListType<API.SearchType> = {\r\n edit: {\r\n displayName: 'Edit type',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n },\r\n remove: {\r\n displayName: 'Remove type',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the search type {{item.name}}?',\r\n approveCaption: 'Remove type',\r\n rejectCaption: `Don't remove`,\r\n },\r\n filter: type => !type.default_type,\r\n handler: handleRemove\r\n },\r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'searchType',\r\n actions: SearchTypeCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'searchType',\r\n actions: SearchTypeEditActions,\r\n }\r\n};\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport Form, { FormFieldSettingHandler, FormSaveHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translateForm } from 'utils/FormUtils';\r\nimport SearchConstants from 'constants/SearchConstants';\r\n\r\n\r\nconst Entry: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'extensions',\r\n title: 'File extensions',\r\n type: API.SettingTypeEnum.LIST,\r\n item_type: API.SettingTypeEnum.STRING\r\n },\r\n];\r\n\r\nexport interface SearchTypeDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.SearchType, UI.FormValueMap {\r\n\r\n}\r\n\r\nexport interface DataProps extends DataProviderDecoratorChildProps {\r\n searchTypeEntry?: API.SearchType;\r\n}\r\n\r\ninterface RouteProps {\r\n searchTypeId: string; \r\n}\r\n\r\ntype Props = SearchTypeDialogProps & DataProps & ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass SearchTypeDialog extends Component<Props> {\r\n static displayName = 'SearchTypeDialog';\r\n\r\n form: Form<Entry>;\r\n fieldDefinitions = translateForm(Entry, this.props.moduleT);\r\n\r\n isNew = () => {\r\n return !this.props.searchTypeEntry;\r\n }\r\n\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (this.isNew()) {\r\n return SocketService.post(SearchConstants.SEARCH_TYPES_URL, changedFields);\r\n }\r\n\r\n return SocketService.patch(\r\n `${SearchConstants.SEARCH_TYPES_URL}/${this.props.searchTypeEntry!.id}`, \r\n changedFields\r\n );\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'name') {\r\n const { searchTypeEntry } = this.props;\r\n fieldOptions.disabled = !!searchTypeEntry && searchTypeEntry.default_type;\r\n }\r\n }\r\n\r\n render() {\r\n const { moduleT, searchTypeEntry } = this.props;\r\n const title = moduleT.translate(this.isNew() ? 'Add search type' : 'Edit search type');\r\n return (\r\n <Modal \r\n className=\"search-type\" \r\n title={ title } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.FOLDER } \r\n { ...this.props }\r\n >\r\n <Form<Entry>\r\n ref={ c => this.form = c! }\r\n fieldDefinitions={ this.fieldDefinitions }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSave={ this.onSave }\r\n sourceValue={ searchTypeEntry as Entry }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<SearchTypeDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(SearchTypeDialog, {\r\n urls: {\r\n searchTypeEntry: ({ match }, socket) => {\r\n if (!match.params.searchTypeId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${SearchConstants.SEARCH_TYPES_URL}/${match.params.searchTypeId}`);\r\n },\r\n }\r\n }),\r\n 'types/:searchTypeId?'\r\n);","import * as React from 'react';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/menu';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport SearchTypeActions from 'actions/ui/SearchTypeActions';\r\nimport SearchConstants from 'constants/SearchConstants';\r\nimport SearchTypeDialog from './SearchTypeDialog';\r\nimport { formatBoolean } from 'utils/ValueFormat';\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst Row: React.FC<{ type: API.SearchType; moduleT: UI.ModuleTranslator; }> = ({ type, moduleT }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ type.str }</strong> } \r\n actions={ SearchTypeActions.edit }\r\n itemData={ type }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"extensions\">\r\n { type.extensions.join(', ') }\r\n </td>\r\n <td className=\"default\">\r\n { formatBoolean(type.default_type, moduleT.plainT) }\r\n </td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (type: API.SearchType, moduleT: UI.ModuleTranslator) => {\r\n return (\r\n <Row \r\n key={ type.id } \r\n type={ type }\r\n moduleT={ moduleT }\r\n />\r\n );\r\n};\r\n\r\ninterface SearchTypesPageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n searchTypes: API.SearchType[];\r\n}\r\n\r\ntype Props = SearchTypesPageProps & DataProps;\r\n\r\nconst SearchTypesPage: React.FC<Props> = (\r\n { searchTypes, moduleT }\r\n) => (\r\n <div id=\"directory-table\">\r\n <ActionButton\r\n actions={ SearchTypeActions.create }\r\n actionId=\"create\"\r\n />\r\n\r\n { searchTypes.length === 0 ? null : (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ moduleT.translate('Name') }</th>\r\n <th>{ moduleT.translate('File extensions') }</th>\r\n <th>{ moduleT.translate('Default') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { searchTypes.map(type => getRow(type, moduleT)) }\r\n </tbody>\r\n </table>\r\n ) }\r\n <Message\r\n icon={ IconConstants.NOTE }\r\n description={ \r\n moduleT.t(\r\n 'searchTypesNote', \r\n // eslint-disable-next-line max-len\r\n 'Note; Custom search types will only be applied to ADC hubs! On NMDC hubs, using a predefined search type will only search for a set of predefined, unconfigurable extensions; using a custom type will default to searching for any extension.'\r\n )\r\n }\r\n />\r\n <SearchTypeDialog\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<SearchTypesPageProps, DataProps>(\r\n SearchTypesPage, {\r\n urls: {\r\n searchTypes: SearchConstants.SEARCH_TYPES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n SearchConstants.MODULE_URL, \r\n SearchConstants.SEARCH_TYPES_UPDATED, \r\n () => refetchData()\r\n );\r\n },\r\n }\r\n);","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'dont_download_shared',\r\n 'dont_download_queued',\r\n 'download_dupe_min_size',\r\n];\r\n\r\nconst Skiplist = [\r\n 'download_skiplist',\r\n 'download_skiplist_regex',\r\n];\r\n\r\nconst SkippingOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n\r\n <RemoteSettingForm\r\n title={ props.moduleT.translate('Skiplist') }\r\n { ...props }\r\n keys={ Skiplist }\r\n />\r\n </div>\r\n);\r\n\r\nexport default SkippingOptionsPage;","module.exports = {\r\n url: 'downloads',\r\n title: 'Downloads',\r\n icon: 'download',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Locations', \r\n url: 'locations',\r\n component: require('./components/LocationsPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Skipping options', \r\n url: 'skipping-options',\r\n component: require('./components/SkippingOptionsPage').default,\r\n }, { \r\n title: 'Search matching', \r\n url: 'search-matching',\r\n component: require('./components/SearchMatchingPage').default,\r\n }, { \r\n title: 'Download options', \r\n url: 'download-options',\r\n component: require('./components/DownloadOptionsPage').default,\r\n }, { \r\n title: 'Priorities', \r\n url: 'priorities',\r\n component: require('./components/PrioritiesPage').default,\r\n }, { \r\n title: 'Search types', \r\n url: 'search-types',\r\n component: require('./components/SearchTypesPage').default,\r\n }\r\n ],\r\n};","import * as React from 'react';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface EngineStatusMessageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface EngineStatusMessageDataProps extends DataProviderDecoratorChildProps {\r\n enginesStatus: API.ExtensionEngineStatus;\r\n}\r\n\r\n// Show an info message if the default extension engine is not installed\r\nconst EngineStatusMessage: React.FC<EngineStatusMessageProps & EngineStatusMessageDataProps> = (\r\n { enginesStatus, moduleT }\r\n) => {\r\n if (enginesStatus[ExtensionConstants.DEFAULT_ENGINE]) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Message \r\n description={\r\n <Trans i18nKey={ moduleT.toI18nKey('defaultExtensionEngineMissing') }>\r\n The default extension engine <b>{ ExtensionConstants.DEFAULT_ENGINE }</b> is not installed on your system. \r\n Please visit <ExternalLink url={ LinkConstants.DEFAULT_ENGINE_URL }>engine's home page</ExternalLink> for \r\n installation instructions.\r\n </Trans>\r\n }\r\n icon={ IconConstants.WARNING }\r\n />\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<EngineStatusMessageProps, EngineStatusMessageDataProps>(EngineStatusMessage, {\r\n urls: {\r\n enginesStatus: ExtensionConstants.ENGINES_STATUS_URL,\r\n },\r\n loaderText: null\r\n});","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'extension_engines',\r\n];\r\n\r\nconst ExtensionEnginesPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default ExtensionEnginesPage;","import * as React from 'react';\r\n\r\nimport Extension from 'routes/Settings/routes/Extensions/components/extension/Extension';\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport 'fomantic-ui-css/components/item.min.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\n\r\ninterface NpmPackageLayoutProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface NpmCatalogItem {\r\n package: UI.NpmPackage;\r\n}\r\n\r\ninterface NpmPackageLayoutDataProps extends DataProviderDecoratorChildProps {\r\n installedPackages: API.Extension[];\r\n packageCatalog: NpmCatalogItem[];\r\n}\r\n\r\nconst getItem = (npmPackage: UI.NpmPackage, moduleT: UI.ModuleTranslator, installedPackages: API.Extension[]) => {\r\n const installedPackage = installedPackages.find(p => p.name === npmPackage.name);\r\n return (\r\n <Extension \r\n key={ npmPackage.name } \r\n npmPackage={ npmPackage } \r\n installedPackage={ installedPackage }\r\n moduleT={ moduleT }\r\n />\r\n );\r\n};\r\n\r\nconst NpmPackageLayout: React.FC<NpmPackageLayoutProps & NpmPackageLayoutDataProps> = ({\r\n packageCatalog, moduleT, installedPackages\r\n}) => (\r\n <div className=\"extension-layout\">\r\n <div className=\"ui divider\"/>\r\n { packageCatalog.length > 0 && (\r\n <div className=\"ui divided items\">\r\n { packageCatalog.map(data => getItem(data.package, moduleT, installedPackages)) }\r\n </div>\r\n ) }\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<NpmPackageLayoutProps, NpmPackageLayoutDataProps>(NpmPackageLayout, {\r\n urls: {\r\n installedPackages: ExtensionConstants.EXTENSIONS_URL,\r\n packageCatalog: () => fetchCorsSafeData(ExtensionConstants.NPM_PACKAGES_URL, true),\r\n },\r\n dataConverters: {\r\n packageCatalog: ({ objects }) => objects,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n const refetchInstalled = () => refetchData([ 'installedPackages' ]);\r\n\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.ADDED, refetchInstalled);\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.REMOVED, refetchInstalled);\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.UPDATED, refetchInstalled);\r\n },\r\n});\r\n","import * as React from 'react';\r\n\r\nimport ExtensionActions from 'actions/ui/ExtensionActions';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport EngineStatusMessage from 'routes/Settings/routes/Extensions/components/EngineStatusMessage';\r\nimport NpmPackageLayout from 'routes/Settings/routes/Extensions/components/NpmPackageLayout';\r\nimport ExtensionsConfigureDialog from 'routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\n\r\ninterface ExtensionBrowsePageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst ExtensionBrowsePage: React.FC<ExtensionBrowsePageProps> = ({ moduleT }) => {\r\n return (\r\n <>\r\n <EngineStatusMessage\r\n moduleT={ moduleT }\r\n />\r\n <div className=\"table-actions\">\r\n <ActionButton\r\n actions={ ExtensionActions.install }\r\n actionId=\"installUrl\"\r\n className=\"add\"\r\n />\r\n </div>\r\n <NpmPackageLayout\r\n moduleT={ moduleT }\r\n />\r\n <ExtensionsConfigureDialog/>\r\n </>\r\n );\r\n};\r\n\r\nexport default ExtensionBrowsePage;","import { Component } from 'react';\r\n\r\nimport Modal from 'components/semantic/Modal';\r\nimport Form, { FormSaveHandler } from 'components/form/Form';\r\n\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst getSettingsUrl = (extensionId: string) => {\r\n return `${ExtensionConstants.EXTENSIONS_URL}/${extensionId}/settings`;\r\n};\r\n\r\ninterface ExtensionsConfigureDialogProps {\r\n\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n fieldDefinitions: UI.FormFieldDefinition[];\r\n settings: UI.FormValueMap;\r\n extension: API.Extension;\r\n}\r\n\r\ninterface RouteProps { \r\n extensionId: string; \r\n}\r\n\r\ntype Props = ExtensionsConfigureDialogProps & DataProps & \r\n ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass ExtensionsConfigureDialog extends Component<Props> {\r\n static displayName = 'ExtensionsConfigureDialog';\r\n\r\n form: Form;\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<UI.FormValueMap> = (changedFields) => {\r\n return SocketService.patch(getSettingsUrl(this.props.extension.id), changedFields);\r\n }\r\n\r\n render() {\r\n const { extension, settings, fieldDefinitions, ...other } = this.props;\r\n return (\r\n <Modal \r\n { ...other }\r\n className=\"extensions configure\" \r\n title={ extension.name } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.EDIT }\r\n dynamicHeight={ true }\r\n >\r\n <Form\r\n ref={ (c: any) => this.form = c! }\r\n onSave={ this.onSave }\r\n fieldDefinitions={ fieldDefinitions }\r\n sourceValue={ settings }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<ExtensionsConfigureDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(\r\n ExtensionsConfigureDialog, {\r\n urls: {\r\n fieldDefinitions: ({ match }) => {\r\n return SocketService.get(`${getSettingsUrl(match.params.extensionId)}/definitions`);\r\n },\r\n settings: ({ match }) => SocketService.get(getSettingsUrl(match.params.extensionId)),\r\n extension: ({ match }, socket) => {\r\n return socket.get(`${ExtensionConstants.EXTENSIONS_URL}/${match.params.extensionId}`);\r\n },\r\n },\r\n }\r\n ),\r\n 'extensions/:extensionId'\r\n);","import DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport Extension from 'routes/Settings/routes/Extensions/components/extension/Extension';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\n\r\nexport interface NpmPackageData {\r\n name: string;\r\n description: string;\r\n version: string;\r\n _npmUser: {\r\n name: string;\r\n };\r\n}\r\n\r\n// The npm registry API returns different data/fieldnames for different calls\r\n// so we must do some conversions (the primary data format is the one used by the package search method)\r\nconst convertNpmPackage = ({ name, description, version, _npmUser }: NpmPackageData): UI.NpmPackage => {\r\n return {\r\n id: name,\r\n name,\r\n description,\r\n version,\r\n publisher: {\r\n username: _npmUser.name,\r\n },\r\n date: '',\r\n };\r\n};\r\n\r\n\r\ninterface LocalExtensionProps {\r\n installedPackage: API.Extension;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface LocalExtensionDataProps extends DataProviderDecoratorChildProps {\r\n npmPackage: NpmPackageData;\r\n}\r\n\r\nconst LocalExtension = DataProviderDecorator<LocalExtensionProps, LocalExtensionDataProps>(\r\n ({ installedPackage, npmPackage, dataError, moduleT }) => (\r\n <Extension \r\n key={ installedPackage.name } \r\n installedPackage={ installedPackage } \r\n npmPackage={ !!npmPackage ? convertNpmPackage(npmPackage) : undefined }\r\n npmError={ dataError }\r\n moduleT={ moduleT }\r\n />\r\n ), \r\n {\r\n urls: {\r\n npmPackage: ({ installedPackage }) => {\r\n if (installedPackage.private || !installedPackage.managed) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return fetchCorsSafeData(`${ExtensionConstants.NPM_PACKAGE_URL}${installedPackage.name}/latest`, true);\r\n },\r\n },\r\n renderOnError: true,\r\n }\r\n);\r\n\r\nexport default LocalExtension;\r\n","import * as React from 'react';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport EngineStatusMessage from 'routes/Settings/routes/Extensions/components/EngineStatusMessage';\r\nimport ExtensionsConfigureDialog from 'routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog';\r\n\r\nimport { Link } from 'react-router-dom';\r\nimport Message from 'components/semantic/Message';\r\nimport LocalExtension from 'routes/Settings/routes/Extensions/components/LocalExtension';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface ExtensionsManagePageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\ninterface ExtensionsManagePageDataProps extends DataProviderDecoratorChildProps {\r\n installedPackages: API.Extension[];\r\n}\r\n\r\nconst getItem = (extension: API.Extension, moduleT: UI.ModuleTranslator) => {\r\n return (\r\n <LocalExtension \r\n key={ extension.name } \r\n installedPackage={ extension } \r\n moduleT={ moduleT }\r\n />\r\n );\r\n};\r\n\r\nconst ExtensionsManagePage: React.FC<ExtensionsManagePageProps & ExtensionsManagePageDataProps> = ({ \r\n installedPackages, moduleT \r\n}) => {\r\n if (installedPackages.length === 0) {\r\n return (\r\n <Message \r\n description={\r\n <Trans i18nKey={ moduleT.toI18nKey('noInstalledExtensions') }>\r\n No installed extensions were found. New extensions \r\n can be installed from the <Link to=\"/settings/extensions/packages\">Extension catalog</Link> page.\r\n </Trans>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n );\r\n } \r\n\r\n return (\r\n <div className=\"extension-layout\">\r\n <EngineStatusMessage \r\n moduleT={ moduleT }\r\n />\r\n <div className=\"ui divider\"/>\r\n <div className=\"ui divided items\">\r\n { installedPackages.map(p => getItem(p, moduleT)) }\r\n </div>\r\n <ExtensionsConfigureDialog/>\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<ExtensionsManagePageProps, ExtensionsManagePageDataProps>(ExtensionsManagePage, {\r\n urls: {\r\n installedPackages: ExtensionConstants.EXTENSIONS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.ADDED, () => refetchData());\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.REMOVED, () => refetchData());\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.UPDATED, () => refetchData());\r\n },\r\n});\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'extensions_debug_mode',\r\n 'extensions_auto_update',\r\n 'extensions_init_timeout',\r\n];\r\n\r\nconst ExtensionOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default ExtensionOptionsPage;","import * as React from 'react';\r\n\r\nimport ExtensionActions from 'actions/ui/ExtensionActions';\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport ExternalLink from 'components/ExternalLink';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { ActionMenu } from 'components/menu';\r\nimport MenuConstants from 'constants/MenuConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport Icon from 'components/semantic/Icon';\r\n\r\n\r\nexport interface ExtensionActionButtonsProps {\r\n npmPackage?: UI.NpmPackage;\r\n installedPackage?: API.Extension;\r\n hasUpdate: boolean;\r\n installing: boolean;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\n\r\ntype InstallButtonProps = Omit<ExtensionActionButtonsProps, 'moduleT'>;\r\n\r\nconst InstallButton: React.FC<InstallButtonProps> = (\r\n { npmPackage, installedPackage, hasUpdate, installing }\r\n) => {\r\n if (installedPackage && !hasUpdate) {\r\n return null;\r\n }\r\n\r\n return (\r\n <ActionButton\r\n actions={ ExtensionActions.npm }\r\n actionId={ hasUpdate ? 'updateNpm' : 'installNpm' }\r\n className=\"right floated primary\"\r\n itemData={ npmPackage }\r\n loading={ installing }\r\n />\r\n );\r\n};\r\n\r\nconst ExtensionActionButtons: React.FC<ExtensionActionButtonsProps> = (\r\n { npmPackage, installedPackage, hasUpdate, installing, moduleT }\r\n) => (\r\n <div className=\"extra buttons\">\r\n { npmPackage && (\r\n <InstallButton\r\n npmPackage={ npmPackage }\r\n installedPackage={ installedPackage }\r\n hasUpdate={ hasUpdate }\r\n installing={ installing }\r\n />\r\n ) }\r\n { installedPackage && (\r\n <ActionMenu\r\n actions={ ExtensionActions.manage }\r\n ids={ [ 'configure', 'divider', 'remove' ] }\r\n remoteMenuId={ MenuConstants.EXTENSION }\r\n itemData={ installedPackage }\r\n className=\"right floated\"\r\n caption={ moduleT.translate('Manage...') }\r\n button={ true }\r\n contextElement=\"#setting-scroll-context\"\r\n menuElementClassName=\"left floated\"\r\n />\r\n ) }\r\n { npmPackage && (\r\n <ExternalLink \r\n className=\"ui right floated button\"\r\n url={ ExtensionConstants.NPM_HOMEPAGE_URL + npmPackage.name }\r\n >\r\n <Icon\r\n icon={ IconConstants.OPEN }\r\n />\r\n { moduleT.translate('Read more') }\r\n </ExternalLink> \r\n ) }\r\n { installedPackage && (\r\n <ActionButton\r\n actions={ ExtensionActions.manage }\r\n actionId={ installedPackage.running ? 'stop' : 'start' }\r\n className=\"right floated\"\r\n itemData={ installedPackage }\r\n />\r\n ) }\r\n </div>\r\n);\r\n\r\nexport default ExtensionActionButtons;","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\nimport Moment from 'moment';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport ExtensionIcon from 'routes/Settings/routes/Extensions/components/extension/ExtensionIcon';\r\nimport ExtensionActionButtons from 'routes/Settings/routes/Extensions/components/extension/ExtensionActionButtons';\r\n\r\nimport { compareVersions } from 'compare-versions';\r\n\r\nimport 'fomantic-ui-css/components/item.min.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { \r\n SocketSubscriptionDecoratorChildProps, SocketSubscriptionDecorator\r\n} from 'decorators/SocketSubscriptionDecorator';\r\nimport { errorResponseToString } from 'utils/TypeConvert';\r\nimport { DataFetchError } from 'decorators/DataProviderDecorator';\r\n\r\n\r\ninterface VersionProps {\r\n title: string;\r\n className?: string;\r\n packageInfo?: {\r\n date?: string;\r\n version: string;\r\n };\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst Version: React.FC<VersionProps> = ({ title, packageInfo, className, moduleT }) => {\r\n if (!packageInfo) {\r\n return null;\r\n }\r\n\r\n const versionDesc = !packageInfo.date ? packageInfo.version : moduleT.t(\r\n 'datePublished',\r\n {\r\n defaultValue: '{{version}} (published {{date}})',\r\n replace: {\r\n version: packageInfo.version,\r\n date: Moment(packageInfo.date).from(Moment())\r\n }\r\n }\r\n );\r\n\r\n return (\r\n <div className={ className }>\r\n { `${title}: ` }\r\n <span> \r\n { versionDesc }\r\n </span>\r\n </div>\r\n );\r\n};\r\n\r\nconst formatAuthor = (moduleT: UI.ModuleTranslator, npmPackage?: UI.NpmPackage, installedPackage?: API.Extension) => {\r\n let author: string | undefined;\r\n if (installedPackage && installedPackage.author) {\r\n author = installedPackage.author;\r\n }\r\n\r\n if (npmPackage) {\r\n author = npmPackage.publisher.username;\r\n }\r\n\r\n if (!author) {\r\n return null;\r\n }\r\n\r\n return moduleT.t('byAuthor', {\r\n defaultValue: 'by {{author}}',\r\n replace: {\r\n author\r\n }\r\n });\r\n};\r\n\r\nconst formatNote = (\r\n moduleT: UI.ModuleTranslator, \r\n installedPackage?: API.Extension, \r\n npmError?: DataFetchError | null\r\n) => {\r\n if (installedPackage && !installedPackage.managed) {\r\n return moduleT.translate('Unmanaged extension');\r\n }\r\n\r\n if (npmError) {\r\n return moduleT.t(\r\n 'extensionDirectoryFetchError',\r\n {\r\n defaultValue: 'Failed to fetch information from the extension directory: {{error}}',\r\n replace: {\r\n error: errorResponseToString(npmError)\r\n }\r\n }\r\n );\r\n }\r\n\r\n return moduleT.translate('Non-listed extension');\r\n};\r\n\r\n\r\nexport interface ExtensionProps {\r\n installedPackage?: API.Extension;\r\n npmPackage?: UI.NpmPackage;\r\n npmError?: DataFetchError | null;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\n\r\ninterface State {\r\n installing: boolean;\r\n}\r\nclass Extension extends React.PureComponent<ExtensionProps & SocketSubscriptionDecoratorChildProps, State> {\r\n //displayName: 'Extension',\r\n\r\n /*propTypes: {\r\n npmPackage: PropTypes.shape({\r\n name: PropTypes.string.isRequired,\r\n description: PropTypes.string.isRequired,\r\n version: PropTypes.string.isRequired,\r\n date: PropTypes.string,\r\n publisher: PropTypes.shape({\r\n username: PropTypes.string,\r\n }),\r\n }),\r\n installedPackage: PropTypes.shape({\r\n name: PropTypes.string.isRequired,\r\n description: PropTypes.string.isRequired,\r\n version: PropTypes.string.isRequired,\r\n author: PropTypes.string,\r\n }),\r\n },*/\r\n\r\n state: State = {\r\n installing: false,\r\n };\r\n\r\n onInstallationStarted = (data: API.ExtensionInstallEvent) => {\r\n if (data.install_id !== this.props.npmPackage!.name) {\r\n return;\r\n }\r\n\r\n this.setState({\r\n installing: true,\r\n });\r\n }\r\n\r\n onInstallationCompleted = (data: API.ExtensionInstallEvent) => {\r\n if (data.install_id !== this.props.npmPackage!.name) {\r\n return;\r\n }\r\n\r\n this.setState({\r\n installing: false,\r\n });\r\n }\r\n\r\n componentDidMount() {\r\n const { addSocketListener, npmPackage } = this.props;\r\n\r\n if (!!npmPackage) {\r\n // eslint-disable-next-line max-len\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.INSTALLATION_STARTED, this.onInstallationStarted);\r\n // eslint-disable-next-line max-len\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.INSTALLATION_SUCCEEDED, this.onInstallationCompleted);\r\n // eslint-disable-next-line max-len\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.INSTALLATION_FAILED, this.onInstallationCompleted);\r\n }\r\n }\r\n\r\n render() {\r\n const { npmPackage, installedPackage, npmError, moduleT } = this.props;\r\n const { installing } = this.state;\r\n const { translate } = moduleT;\r\n\r\n const hasUpdate = !!installedPackage && !!npmPackage && \r\n compareVersions(installedPackage.version, npmPackage.version) < 0;\r\n\r\n return (\r\n <div className=\"item extension\">\r\n <ExtensionIcon\r\n installedPackage={ installedPackage }\r\n hasUpdate={ hasUpdate }\r\n />\r\n <div className=\"content\">\r\n <a className=\"header\">\r\n { npmPackage ? npmPackage.name : installedPackage!.name }\r\n </a>\r\n <div className=\"meta author\">\r\n { formatAuthor(moduleT, npmPackage, installedPackage) }\r\n </div>\r\n <div className=\"description\">\r\n <span>{ npmPackage ? npmPackage.description : installedPackage!.description }</span>\r\n </div>\r\n <div className=\"extra version\">\r\n <Version \r\n className=\"npm\"\r\n title={ translate('Latest version') }\r\n packageInfo={ npmPackage }\r\n moduleT={ moduleT }\r\n />\r\n <div>\r\n { !npmPackage && formatNote(moduleT, installedPackage, npmError) }\r\n </div>\r\n <Version \r\n className={ npmPackage ? (!hasUpdate ? 'latest' : 'outdated') : undefined }\r\n title={ translate('Installed version') } \r\n packageInfo={ installedPackage }\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n <ExtensionActionButtons\r\n installedPackage={ installedPackage }\r\n npmPackage={ npmPackage }\r\n installing={ installing }\r\n hasUpdate={ hasUpdate }\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default SocketSubscriptionDecorator<ExtensionProps>(Extension);","import * as React from 'react';\r\n\r\nimport Icon from 'components/semantic/Icon';\r\n\r\nimport * as API from 'types/api';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst getCornerIcon = (installedPackage: API.Extension | undefined, hasUpdate: boolean) => {\r\n if (!installedPackage) {\r\n return null;\r\n }\r\n\r\n if (hasUpdate) {\r\n return 'yellow warning circle';\r\n }\r\n\r\n if (!installedPackage.managed) {\r\n return 'blue external square';\r\n }\r\n\r\n return 'green check circle';\r\n};\r\n\r\ninterface ExtensionIconProps {\r\n installedPackage?: API.Extension;\r\n hasUpdate: boolean;\r\n size?: string;\r\n}\r\n\r\nconst ExtensionIcon: React.FC<ExtensionIconProps> = ({ installedPackage, hasUpdate, size = 'huge' }) => (\r\n <div className=\"ui image\">\r\n <Icon \r\n icon={ IconConstants.EXTENSION }\r\n size={ size } \r\n cornerIcon={ getCornerIcon(installedPackage, hasUpdate) }\r\n />\r\n </div>\r\n);\r\n\r\nexport default ExtensionIcon;","module.exports = {\r\n url: 'extensions',\r\n title: 'Extensions',\r\n icon: 'puzzle',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'Manage installed', \r\n url: 'manage',\r\n noSave: true,\r\n component: require('./components/ExtensionsManagePage').default,\r\n }, { \r\n title: 'Extension catalog', \r\n url: 'packages', \r\n noSave: true,\r\n component: require('./components/ExtensionsBrowsePage').default,\r\n }\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Extension options', \r\n url: 'extension-options',\r\n component: require('./components/ExtensionsOptionsPage').default,\r\n }, { \r\n title: 'Extension engines', \r\n url: 'extension-engines',\r\n component: require('./components/ExtensionEnginesPage').default,\r\n },\r\n ],\r\n};","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'away_message',\r\n 'away_no_bots',\r\n 'away_idle_time',\r\n];\r\n\r\nconst AwayPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default AwayPage;","import * as React from 'react';\r\n\r\nimport UserConstants from 'constants/UserConstants';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport { UserMenu } from 'components/menu';\r\n\r\nimport * as API from 'types/api';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport MenuConstants from 'constants/MenuConstants';\r\n\r\n\r\nconst Row: React.FC<{ ignoreInfo: API.IgnoredUser; }> = ({ ignoreInfo }) => (\r\n <tr>\r\n <td className=\"user dropdown\">\r\n <UserMenu \r\n ids={ [ 'unignore' ] } \r\n userIcon=\"simple\"\r\n user={ ignoreInfo.user }\r\n contextElement=\"#setting-scroll-context\"\r\n remoteMenuId={ MenuConstants.USER }\r\n />\r\n </td>\r\n <td className=\"count\">\r\n { ignoreInfo.ignored_messages }\r\n </td>\r\n </tr>\r\n);\r\n\r\n\r\nconst getRow = (ignoreInfo: API.IgnoredUser) => {\r\n return (\r\n <Row \r\n key={ ignoreInfo.user.cid } \r\n ignoreInfo={ ignoreInfo } \r\n />\r\n );\r\n};\r\n\r\ntype IgnorePageProps = SettingSectionChildProps;\r\n\r\ninterface IgnorePageDataProps extends DataProviderDecoratorChildProps {\r\n ignores: API.IgnoredUser[];\r\n}\r\n\r\nconst IgnorePage: React.FC<IgnorePageProps & IgnorePageDataProps> = ({ ignores, moduleT }) => {\r\n const { translate } = moduleT;\r\n if (ignores.length === 0) {\r\n return (\r\n <Message\r\n title={ translate('No ignored users') }\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <div>\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('User') }</th>\r\n <th>{ translate('Messages ignored') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { ignores.map(getRow) }\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<IgnorePageProps, IgnorePageDataProps>(IgnorePage, {\r\n urls: {\r\n ignores: UserConstants.IGNORES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(UserConstants.MODULE_URL, UserConstants.IGNORE_ADDED, () => refetchData());\r\n addSocketListener(UserConstants.MODULE_URL, UserConstants.IGNORE_REMOVED, () => refetchData());\r\n },\r\n});","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport '../style.css';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { Trans } from 'react-i18next';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\n\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n //const { toI18nKey } = this.props.moduleT;\r\n if (id === 'nmdc_encoding') {\r\n fieldOptions.help = (\r\n <Trans \r\n i18nKey={ moduleT.toI18nKey(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined)\r\n ) }\r\n >\r\n <div>\r\n Encoding setting is only used in NMDC hubs. ADC hubs will always use UTF-8 encoding.\r\n <br/>\r\n <br/>\r\n <div>\r\n Commonly used values:\r\n <ul>\r\n <li>Central Europe: cp1250</li>\r\n <li>Cyrillic: cp1251</li>\r\n <li>Western Europe: cp1252</li>\r\n <li>Greek: cp1253</li>\r\n <li>Turkish: cp1254</li>\r\n <li>Hebrew: cp1256</li>\r\n </ul>\r\n </div>\r\n </div>\r\n </Trans>\r\n );\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\n\r\nconst Entry = [\r\n 'auto_follow_redirects',\r\n 'disconnect_offline_users',\r\n 'disconnect_hubs_noreg',\r\n 'min_search_interval',\r\n];\r\n\r\nconst MiscPage: React.FC<SettingSectionChildProps> = props => {\r\n // The locale-specific system encoding is used on Windows by default\r\n // while other system use UTF-8\r\n if (LoginStore.systemInfo.platform !== API.PlatformEnum.WINDOWS) {\r\n Entry.push('nmdc_encoding');\r\n }\r\n\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ FieldOptionGetter(props.moduleT) }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default MiscPage;","import * as React from 'react';\r\nimport { SettingProfileEnum } from 'constants/SettingConstants';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\nconst Entry = [\r\n 'nick',\r\n 'description',\r\n 'email',\r\n 'setting_profile',\r\n 'language_file'\r\n];\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n if (id === 'setting_profile') {\r\n let message;\r\n\r\n const profileId = formValue[id] as number;\r\n switch (profileId) {\r\n case SettingProfileEnum.NORMAL: {\r\n // eslint-disable-next-line max-len\r\n message = 'The client is used in normal private/public hubs for transferring files via internet. Use this profile if unsure.';\r\n break;\r\n }\r\n case SettingProfileEnum.RAR: {\r\n // eslint-disable-next-line max-len\r\n message = 'The client is used for transferring files that are split in RAR archives (or in other small-sized formats)';\r\n break;\r\n }\r\n case SettingProfileEnum.LAN: {\r\n // eslint-disable-next-line max-len\r\n message = 'The client is used for transferring files in local network (e.g. LAN parties) or in another closed network (e.g. university network)';\r\n break;\r\n }\r\n default:\r\n }\r\n\r\n if (message) {\r\n fieldOptions.help = moduleT.t(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, profileId.toString()),\r\n message\r\n );\r\n }\r\n } else if (id === 'language_file') {\r\n fieldOptions.help = (\r\n <Trans\r\n i18nKey={ moduleT.toI18nKey(toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined)) }\r\n >\r\n <p>\r\n The application must be restarted for the new language to take effect.\r\n </p>\r\n <p>\r\n If you want to help with improving the existing translations \r\n or translate the application into a new language, please see \r\n the <ExternalLink url={ LinkConstants.TRANSLATOR_HELP }>instructions for translators</ExternalLink>.\r\n </p>\r\n </Trans>\r\n );\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\nconst UserPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n onFieldSetting={ FieldOptionGetter(props.moduleT) }\r\n />\r\n </div>\r\n);\r\n\r\nexport default UserPage;","module.exports = {\r\n url: 'profile',\r\n title: 'Profile',\r\n icon: 'user',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'User', \r\n url: 'user',\r\n component: require('./components/UserPage').default,\r\n }, { \r\n title: 'Away mode', \r\n url: 'away',\r\n component: require('./components/AwayPage').default,\r\n }, \r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Ignored users', \r\n url: 'ignored-users',\r\n noSave: true,\r\n component: require('./components/IgnorePage').default,\r\n }, { \r\n title: 'Miscellaneous', \r\n url: 'miscellaneous',\r\n component: require('./components/MiscPage').default,\r\n },\r\n ],\r\n};","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareConstants from 'constants/ShareConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport History from 'utils/History';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst handleAdd: UI.ActionHandler<void> = ({ location }) => {\r\n History.push(`${location.pathname}/browse`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<string> = ({ data: path }) => {\r\n return SocketService.post(ShareConstants.EXCLUDES_REMOVE_URL, { path });\r\n};\r\n\r\n\r\nconst ShareExcludeCreateActions: UI.ActionListType<undefined> = {\r\n add: {\r\n displayName: 'Add path',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n handler: handleAdd,\r\n },\r\n};\r\n\r\nconst ShareExcludeEditActions: UI.ActionListType<string> = {\r\n remove: { \r\n displayName: 'Remove path',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the excluded path {{item}}?',\r\n approveCaption: 'Remove path',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n }, \r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'shareExclude',\r\n actions: ShareExcludeCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'shareExclude',\r\n actions: ShareExcludeEditActions,\r\n }\r\n};\r\n","import * as React from 'react';\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareActions from 'actions/ui/ShareActions';\r\nimport ShareExcludeActions from 'actions/ui/ShareExcludeActions';\r\nimport ShareConstants from 'constants/ShareConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport { ActionMenu } from 'components/menu';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\nimport { FileBrowserRouteDialog } from 'components/filebrowser';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport FilesystemConstants from 'constants/FilesystemConstants';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\nconst Row: React.FC<{ path: string; }> = ({ path }) => (\r\n <tr>\r\n <td className=\"path dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ path }</strong> } \r\n actions={ ShareExcludeActions.edit } \r\n //ids={ [ 'remove' ] } \r\n itemData={ path }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (path: string) => {\r\n return (\r\n <Row \r\n key={ path } \r\n path={ path } \r\n />\r\n );\r\n};\r\n\r\n\r\ntype ExcludePageProps = SettingSectionChildProps;\r\n\r\ninterface ExcludePageDataProps extends DataProviderDecoratorChildProps {\r\n excludes: string[];\r\n}\r\n\r\nclass ExcludePage extends React.Component<ExcludePageProps & ExcludePageDataProps> {\r\n static displayName = 'ExcludePage';\r\n\r\n render() {\r\n const { excludes, moduleT } = this.props;\r\n const { translate, toI18nKey } = moduleT;\r\n return (\r\n <div>\r\n <Message\r\n title={\r\n <div>\r\n <div>\r\n <Trans i18nKey={ toI18nKey('shareRefreshNote') }>\r\n Share must be refreshed for the changes to take effect\r\n </Trans>\r\n </div>\r\n <br/>\r\n <ActionButton\r\n actions={ ShareActions }\r\n actionId=\"refresh\"\r\n />\r\n </div>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n\r\n <ActionButton\r\n actions={ ShareExcludeActions.create }\r\n actionId=\"add\"\r\n className=\"add\"\r\n />\r\n\r\n { excludes.length > 0 && (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('Path') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { excludes.map(getRow) }\r\n </tbody>\r\n </table>\r\n ) }\r\n\r\n <FileBrowserRouteDialog\r\n onConfirm={ path => runBackgroundSocketAction(\r\n () => SocketService.post(ShareConstants.EXCLUDES_ADD_URL, { path }), \r\n moduleT.plainT\r\n ) }\r\n initialPath=\"\"\r\n historyId={ FilesystemConstants.LOCATION_GENERIC }\r\n subHeader={ translate('Add excluded path') }\r\n selectMode={ UI.FileSelectModeEnum.DIRECTORY }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator(ExcludePage, {\r\n urls: {\r\n excludes: ShareConstants.EXCLUDES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ShareConstants.MODULE_URL, ShareConstants.EXCLUDE_ADDED, () => refetchData());\r\n addSocketListener(ShareConstants.MODULE_URL, ShareConstants.EXCLUDE_REMOVED, () => refetchData());\r\n },\r\n});","import * as React from 'react';\r\nimport SocketService from 'services/SocketService';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport Checkbox from 'components/semantic/Checkbox';\r\nimport Button from 'components/semantic/Button';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport HashConstants from 'constants/HashConstants';\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\nimport { Row, Grid } from 'components/semantic/Grid';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface OptimizeLayoutProps {\r\n running: boolean;\r\n startHandler: (verify: boolean) => void;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst OptimizeLayout: React.FC<OptimizeLayoutProps> = (\r\n { startHandler, running, moduleT }\r\n) => {\r\n const { toI18nKey, translate } = moduleT;\r\n const [ verify, setVerify ] = React.useState(false);\r\n return (\r\n <div className=\"optimize-layout\">\r\n <h4 className=\"header\" style={{ marginTop: '30px' }}>\r\n { translate('Maintenance') }\r\n </h4>\r\n <Message \r\n description={ (\r\n <Trans i18nKey={ toI18nKey('hashDBOptimizeNote') }>\r\n This operation will delete all hash information for files that aren't currently in share. \r\n If you are sharing files from network disks or from a removable storage, \r\n make sure that the files are currently shown in share (otherwise they have to be rehashed)\r\n </Trans>\r\n ) }\r\n icon={ IconConstants.NOTE }\r\n />\r\n\r\n <Checkbox \r\n caption={ translate('Verify integrity of hash data') } \r\n checked={ verify } \r\n disabled={ running }\r\n onChange={ setVerify }\r\n floating={ true }\r\n />\r\n <Button \r\n className=\"optimize-button\"\r\n caption={ translate('Optimize now') }\r\n icon={ IconConstants.CONFIGURE }\r\n loading={ running } \r\n onClick={ () => startHandler(verify) }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\ninterface HashDatabaseLayoutProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\ninterface HashDatabaseLayoutDataProps extends DataProviderDecoratorChildProps {\r\n status: API.HashDatabaseStatus;\r\n}\r\n\r\nclass HashDatabaseLayout extends React.Component<HashDatabaseLayoutProps & HashDatabaseLayoutDataProps> {\r\n handleOptimize = (verify: boolean) => {\r\n runBackgroundSocketAction(\r\n () => SocketService.post(HashConstants.OPTIMIZE_DATABASE_URL, { verify }),\r\n this.props.moduleT.plainT\r\n );\r\n }\r\n\r\n render() {\r\n const { status, moduleT } = this.props;\r\n const { translate, plainT } = moduleT;\r\n return (\r\n <div className=\"ui segment hash-database\">\r\n <h3 className=\"header\">\r\n { translate('Hash database') }\r\n </h3>\r\n <Grid columns=\"two\">\r\n <Row \r\n title={ translate('File index size') } \r\n text={ formatSize(status.file_index_size, plainT) }\r\n titleWidth=\"five\"\r\n />\r\n <Row \r\n title={ translate('Hash store size') }\r\n text={ formatSize(status.hash_store_size, plainT) }\r\n titleWidth=\"five\"\r\n />\r\n </Grid>\r\n { LoginStore.hasAccess(API.AccessEnum.SETTINGS_EDIT) && (\r\n <OptimizeLayout\r\n running={ status.maintenance_running }\r\n startHandler={ this.handleOptimize }\r\n moduleT={ moduleT }\r\n /> \r\n ) }\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator<HashDatabaseLayoutProps, HashDatabaseLayoutDataProps>(HashDatabaseLayout, {\r\n urls: {\r\n status: HashConstants.DATABASE_STATUS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(HashConstants.MODULE_URL, HashConstants.DATABASE_STATUS, () => refetchData());\r\n },\r\n});","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport HashDatabaseLayout from 'routes/Settings/routes/Sharing/components/HashDatabaseLayout';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'max_hash_speed',\r\n 'max_total_hashers',\r\n 'max_volume_hashers',\r\n];\r\n\r\nconst HashingPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n\r\n <HashDatabaseLayout\r\n moduleT={ props.moduleT }\r\n />\r\n </div>\r\n);\r\n\r\nexport default HashingPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'refresh_time',\r\n 'refresh_time_incoming',\r\n 'refresh_startup',\r\n 'refresh_threading',\r\n];\r\n\r\nconst RefreshOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default RefreshOptionsPage;","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport FilelistSessionActions from 'actions/reflux/FilelistSessionActions';\r\nimport FilelistSessionStore from 'stores/FilelistSessionStore';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst notDefault = (item: API.ShareProfile) => !item.default;\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<void> = (data, name: string) => {\r\n return SocketService.post(ShareProfileConstants.PROFILES_URL, { name: name });\r\n};\r\n\r\nconst handleDefault: UI.ActionHandler<API.ShareProfile> = ({ data: profile }) => {\r\n return SocketService.post(`${ShareProfileConstants.PROFILES_URL}/${profile.id}/default`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.ShareProfile> = (\r\n { data: profile },\r\n name: string\r\n) => {\r\n return SocketService.patch(`${ShareProfileConstants.PROFILES_URL}/${profile.id}`, { name: name });\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.ShareProfile> = (\r\n { data: profile }\r\n) => {\r\n return SocketService.delete(ShareProfileConstants.PROFILES_URL + '/' + profile.id);\r\n};\r\n\r\nconst handleBrowse: UI.ActionHandler<API.ShareProfile> = (\r\n { data: profile, location }\r\n) => {\r\n return FilelistSessionActions.ownList(location, profile.id, FilelistSessionStore);\r\n};\r\n\r\n\r\n\r\n\r\nconst ShareProfileCreateActions: UI.ActionListType<undefined> = {\r\n create: {\r\n displayName: 'Add profile',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.CREATE,\r\n input: {\r\n approveCaption: 'Create',\r\n content: 'Enter name for the profile',\r\n inputProps: {\r\n placeholder: 'Enter name',\r\n required: true,\r\n }\r\n },\r\n handler: handleCreate,\r\n },\r\n};\r\n\r\nconst ShareProfileEditActions: UI.ActionListType<API.ShareProfile> = {\r\n browse: {\r\n displayName: 'Browse files',\r\n access: API.AccessEnum.FILELISTS_VIEW,\r\n icon: IconConstants.FILELIST,\r\n handler: handleBrowse,\r\n },\r\n divider: null,\r\n edit: { \r\n displayName: 'Rename profile',\r\n access: API.AccessEnum.SETTINGS_EDIT, \r\n icon: IconConstants.EDIT,\r\n input: profile => ({\r\n approveCaption: 'Rename',\r\n content: 'Enter new name for the profile {{item.name}}',\r\n inputProps: {\r\n placeholder: 'Enter name',\r\n defaultValue: profile.name,\r\n required: true,\r\n }\r\n }),\r\n handler: handleEdit,\r\n },\r\n default: {\r\n displayName: 'Set as default',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.DEFAULT,\r\n filter: notDefault,\r\n handler: handleDefault,\r\n },\r\n remove: {\r\n displayName: 'Remove profile',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n filter: notDefault,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the profile {{item.name}}?',\r\n approveCaption: 'Remove profile',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n },\r\n};\r\n\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'profile',\r\n actions: ShareProfileCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'profile',\r\n actions: ShareProfileEditActions,\r\n }\r\n};\r\n","import * as React from 'react';\r\n\r\nimport ShareProfileActions from 'actions/ui/ShareProfileActions';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport { ActionMenu } from 'components/menu';\r\n\r\nimport { Link } from 'react-router-dom';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport ShareProfileDecorator, { ShareProfileDecoratorChildProps } from 'decorators/ShareProfileDecorator';\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\ninterface ShareProfileRowProps { \r\n profile: API.ShareProfile;\r\n t: UI.TranslateF;\r\n}\r\n\r\nconst ShareProfileRow: React.FC<ShareProfileRowProps> = ({ profile, t }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ profile.str }</strong> } \r\n actions={ ShareProfileActions.edit } \r\n itemData={ profile }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"size\">\r\n { formatSize(profile.size, t) }\r\n </td>\r\n <td className=\"files\">\r\n { profile.files }\r\n </td>\r\n </tr>\r\n);\r\n\r\ntype ShareProfilesPageProps = SettingSectionChildProps\r\n\r\nconst ShareProfilesPage: React.FC<ShareProfilesPageProps & ShareProfileDecoratorChildProps> = (\r\n { moduleT, profiles }\r\n) => {\r\n const { translate, toI18nKey } = moduleT;\r\n return (\r\n <div>\r\n <Message \r\n description={\r\n <div>\r\n <Trans i18nKey={ toI18nKey('shareProfilesNote') }>\r\n <p>\r\n Queued files are shared via the partial file sharing feature in all hubs where the share \r\n has not been hidden, regardless of the configured share profiles.\r\n </p>\r\n <p>\r\n Share profiles are assigned for individual directories from the <Link to=\"/share\">Share</Link> page.\r\n </p>\r\n </Trans>\r\n </div>\r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n <ActionButton\r\n actions={ ShareProfileActions.create }\r\n actionId=\"create\"\r\n />\r\n\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('Name') }</th>\r\n <th>{ translate('Total size') }</th>\r\n <th>{ translate('Total files') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { profiles.map(profile => (\r\n <ShareProfileRow\r\n key={ profile.id }\r\n profile={ profile }\r\n t={ moduleT.plainT }\r\n />\r\n )) }\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator(ShareProfilesPage, false, undefined, false);","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'share_hidden',\r\n 'share_no_empty_dirs',\r\n 'share_no_zero_byte',\r\n 'share_follow_symlinks',\r\n 'share_max_size',\r\n];\r\n\r\nconst Skiplist = [\r\n 'share_skiplist',\r\n 'share_skiplist_regex',\r\n];\r\n\r\nconst SharingOptionsPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n title={ props.moduleT.translate('Skiplist') }\r\n { ...props }\r\n keys={ Skiplist }\r\n />\r\n </div>\r\n);\r\n\r\nexport default SharingOptionsPage;","module.exports = {\r\n url: 'sharing',\r\n title: 'Sharing',\r\n icon: 'tasks',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'Refresh options', \r\n url: 'refresh-options',\r\n component: require('./components/RefreshOptionsPage').default, \r\n }, { \r\n title: 'Share profiles', \r\n url: 'profiles', \r\n noSave: true,\r\n component: require('./components/ShareProfilesPage').default,\r\n }\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Sharing options', \r\n url: 'sharing-options',\r\n component: require('./components/SharingOptionsPage').default, \r\n }, { \r\n title: 'Hashing', \r\n url: 'hashing',\r\n component: require('./components/HashingPage').default, \r\n }, { \r\n title: 'Excluded paths', \r\n url: 'excludes',\r\n noSave: true,\r\n component: require('./components/ExcludePage').default,\r\n },\r\n ],\r\n};\r\n","import PropTypes from 'prop-types';\r\nimport { Component } from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport SocketService from 'services/SocketService';\r\nimport SettingConstants from 'constants/SettingConstants';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { FormFieldChangeHandler, FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\n\r\n\r\ninterface AutoValuePanelProps extends SettingSectionChildProps {\r\n type: string;\r\n keys: string[];\r\n}\r\n\r\nclass AutoValuePanel extends Component<AutoValuePanelProps> {\r\n static propTypes = {\r\n // Form items to list\r\n keys: PropTypes.array.isRequired,\r\n\r\n // Type of the value section (from the setting key)\r\n type: PropTypes.string.isRequired,\r\n };\r\n\r\n getAutoKey = () => {\r\n return `${this.props.type}_auto_limits`;\r\n }\r\n\r\n // Fetch auto settings when enabling auto detection\r\n onFieldChanged: FormFieldChangeHandler = (changedKey, formValue, hasChanges) => {\r\n const autoSettingKey = this.getAutoKey();\r\n if (changedKey !== autoSettingKey || !formValue[autoSettingKey]) {\r\n return null;\r\n }\r\n\r\n return SocketService.post(SettingConstants.ITEMS_GET_URL, { \r\n keys: this.props.keys.filter(key => key !== autoSettingKey), \r\n value_mode: API.SettingValueMode.FORCE_AUTO,\r\n });\r\n }\r\n\r\n // Disable other fields when auto detection is enabled\r\n onFieldSetting: FormFieldSettingHandler<any> = (settingKey, fieldOptions, formValue) => {\r\n if (formValue[this.getAutoKey()] && settingKey !== this.getAutoKey()) {\r\n fieldOptions.disabled = true;\r\n }\r\n }\r\n\r\n render() {\r\n return (\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...this.props }\r\n onFieldChanged={ this.onFieldChanged }\r\n onFieldSetting={ this.onFieldSetting }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default AutoValuePanel;","import * as React from 'react';\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Auto = [\r\n 'download_auto_limits',\r\n 'download_slots',\r\n 'download_max_start_speed',\r\n];\r\n\r\nconst Manual = [\r\n 'download_highest_prio_slots',\r\n];\r\n\r\nconst DownloadLimitPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <AutoValuePanel\r\n { ...props }\r\n keys={ Auto }\r\n type=\"download\"\r\n />\r\n\r\n <RemoteSettingForm\r\n { ...props }\r\n title={ translate('Manually set') }\r\n keys={ Manual }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DownloadLimitPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Entry = [\r\n 'upload_limit_main',\r\n 'download_limit_main',\r\n //limit_use_with_auto_values: t.Bool,\r\n];\r\n\r\nconst LimiterPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default LimiterPage;","import * as React from 'react';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\nconst Entry = [\r\n 'download_speed',\r\n 'upload_speed',\r\n];\r\n\r\nconst SpeedPage: React.FC<SettingSectionChildProps> = props => {\r\n const { toI18nKey } = props.moduleT;\r\n return (\r\n <div>\r\n <div className=\"ui message\">\r\n <Trans i18nKey={ toI18nKey('connectionSpeedNote') }>\r\n Please be as accurate as possible and set the ACTUAL speed of your connection. You may use an online tester, \r\n such as <ExternalLink url={ LinkConstants.SPEEDTEST_URL }>Speedtest.net</ExternalLink>, to test your speed.\r\n </Trans>\r\n </div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default SpeedPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nconst Auto = [\r\n 'upload_auto_limits',\r\n 'upload_slots',\r\n 'upload_auto_grant_speed',\r\n 'upload_max_granted',\r\n];\r\n\r\nconst Manual = [\r\n 'upload_minislot_size',\r\n 'upload_minislot_ext',\r\n];\r\n\r\nconst UploadLimitPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <AutoValuePanel\r\n { ...props }\r\n keys={ Auto }\r\n type=\"upload\"\r\n />\r\n\r\n <RemoteSettingForm\r\n { ...props }\r\n title={ translate('Manually set') }\r\n keys={ Manual }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default UploadLimitPage;","import * as React from 'react';\r\n\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Auto = [\r\n 'mcn_auto_limits',\r\n 'mcn_down',\r\n 'mcn_up',\r\n];\r\n\r\nconst UserLimitPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <AutoValuePanel\r\n { ...props }\r\n keys={ Auto }\r\n type=\"mcn\"\r\n />\r\n </div>\r\n);\r\n\r\nexport default UserLimitPage;","module.exports = {\r\n url: 'speed-limits',\r\n title: 'Speed and limits',\r\n icon: 'dashboard',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Connection speed', \r\n url: 'speed',\r\n component: require('./components/SpeedPage').default,\r\n }, { \r\n title: 'Bandwidth limiting', \r\n url: 'limiter',\r\n component: require('./components/LimiterPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Download limits', \r\n url: 'download-limits',\r\n component: require('./components/DownloadLimitPage').default,\r\n }, { \r\n title: 'Upload limits', \r\n url: 'upload-limits',\r\n component: require('./components/UploadLimitPage').default,\r\n }, { \r\n title: 'Per-user limits', \r\n url: 'user-limits',\r\n component: require('./components/UserLimitPage').default, \r\n },\r\n ],\r\n};","import * as React from 'react';\r\n\r\nimport SystemActions from 'actions/ui/SystemActions';\r\nimport ActionButton from 'components/ActionButton';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Generic = [\r\n 'web_server_threads',\r\n 'default_idle_timeout',\r\n 'ping_interval',\r\n 'ping_timeout',\r\n];\r\n\r\nconst Hooks = [\r\n 'share_file_validation_hook_timeout',\r\n 'share_directory_validation_hook_timeout',\r\n 'new_share_file_validation_hook_timeout',\r\n 'new_share_directory_validation_hook_timeout',\r\n \r\n 'outgoing_chat_message_hook_timeout',\r\n 'incoming_chat_message_hook_timeout',\r\n\r\n 'queue_add_bundle_hook_timeout',\r\n 'queue_add_bundle_file_hook_timeout',\r\n 'queue_add_source_hook_timeout',\r\n 'queue_bundle_finished_hook_timeout',\r\n 'queue_file_finished_hook_timeout',\r\n\r\n 'list_menuitems_hook_timeout',\r\n];\r\n\r\nconst ServerSettingsPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <ActionButton\r\n actions={ SystemActions }\r\n actionId=\"restartWeb\"\r\n />\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Generic }\r\n />\r\n <div className=\"ui header\">\r\n { translate('Hook timeouts') }\r\n </div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Hooks }\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ServerSettingsPage;","import { Component } from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport '../style.css';\r\nimport { FormFieldChangeHandler, FormFieldSettingHandler } from 'components/form/Form';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\nimport * as API from 'types/api';\r\n\r\nexport interface LogSectionProps extends SettingSectionChildProps {\r\n section: string;\r\n simple?: boolean;\r\n}\r\n\r\nclass LogSection extends Component<LogSectionProps> {\r\n state = {\r\n enabled: false,\r\n };\r\n\r\n convertKey = (suffix?: string) => {\r\n return `log_${this.props.section}${suffix ? `_${suffix}` : ''}`;\r\n }\r\n\r\n onSettingsReceived = (settings: API.SettingValueMap) => {\r\n this.setState({\r\n enabled: settings[this.convertKey()],\r\n });\r\n }\r\n\r\n onEnableStateChanged: FormFieldChangeHandler = (id, formValue, hasChanges) => {\r\n this.setState({ \r\n enabled: formValue[id]\r\n });\r\n }\r\n\r\n onContentSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n fieldOptions.disabled = !this.state.enabled;\r\n }\r\n\r\n getChildClass = (className: string) => {\r\n if (this.state.enabled) {\r\n return className + ' active';\r\n }\r\n\r\n return className;\r\n }\r\n\r\n render() {\r\n const Title = [\r\n this.convertKey(),\r\n ];\r\n\r\n const Content = [\r\n this.convertKey('file'),\r\n this.convertKey('format'),\r\n ];\r\n\r\n const { simple, ...other } = this.props;\r\n return (\r\n <div className={ this.getChildClass('log-section') }>\r\n <div className={ this.getChildClass('title') }>\r\n <RemoteSettingForm\r\n { ...other }\r\n keys={ Title }\r\n onFieldChanged={ this.onEnableStateChanged }\r\n onSettingValuesReceived={ this.onSettingsReceived }\r\n />\r\n </div>\r\n\r\n { !simple && (\r\n <div className={ this.getChildClass('content') }>\r\n <RemoteSettingForm\r\n { ...this.props }\r\n keys={ Content }\r\n onFieldSetting={ this.onContentSetting }\r\n />\r\n </div>\r\n ) }\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default LogSection;","import * as React from 'react';\r\n\r\nimport Accordion from 'components/semantic/Accordion';\r\n\r\nimport LogSection from 'routes/Settings/routes/System/components/LogSection';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface LogSectionGroupProps extends SettingSectionChildProps {\r\n sectionKeys: string[];\r\n title: string;\r\n simpleKeys?: string[];\r\n}\r\n\r\nconst LogSectionGroup: React.FC<LogSectionGroupProps> = props => {\r\n const { title, sectionKeys, simpleKeys, ...other } = props;\r\n return (\r\n <div>\r\n <div className=\"sections\">\r\n <div className=\"ui header\">\r\n { title }\r\n </div>\r\n <Accordion className=\"styled\" controlled={ true }>\r\n { sectionKeys.map(sectionKey => (\r\n <LogSection \r\n { ...other }\r\n key={ sectionKey } \r\n section={ sectionKey }\r\n simple={ !!simpleKeys && simpleKeys.indexOf(sectionKey) !== -1 }\r\n />\r\n )) }\r\n </Accordion>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default LogSectionGroup;","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport LogSectionGroup from './LogSectionGroup';\r\nimport { Trans } from 'react-i18next';\r\n\r\n\r\n// Generic options\r\nconst Entry = [\r\n 'log_directory',\r\n];\r\n\r\n// Sections\r\nconst MessageSectionKeys = [\r\n 'main',\r\n 'pm',\r\n 'syslog',\r\n 'status',\r\n];\r\n\r\nconst TransferSectionKeys = [\r\n 'downloads',\r\n 'uploads',\r\n 'list_transfers',\r\n];\r\n\r\nconst SimpleSectionKeys = [\r\n 'list_transfers',\r\n];\r\n\r\nconst LoggingPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate, toI18nKey } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <div className=\"sections\">\r\n <Message\r\n icon={ IconConstants.INFO }\r\n description={\r\n <ExternalLink url={ LinkConstants.VARIABLE_HELP_URL }>\r\n <Trans i18nKey={ toI18nKey('variableHelp') }>\r\n Variable information for Filename and Format fields\r\n </Trans>\r\n </ExternalLink>\r\n }\r\n />\r\n <LogSectionGroup\r\n { ...props }\r\n sectionKeys={ MessageSectionKeys }\r\n title={ translate('Messages') }\r\n />\r\n <LogSectionGroup\r\n { ...props }\r\n sectionKeys={ TransferSectionKeys }\r\n title={ translate('Transfers') }\r\n simpleKeys={ SimpleSectionKeys }\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default LoggingPage;","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport Message from 'components/semantic/Message';\r\nimport SystemActions from 'actions/ui/SystemActions';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst PlainEntry = [\r\n 'web_plain_port',\r\n 'web_plain_bind_address',\r\n];\r\n\r\nconst TlsEntry = [\r\n 'web_tls_port',\r\n 'web_tls_bind_address',\r\n\r\n 'web_tls_certificate_path',\r\n 'web_tls_certificate_key_path',\r\n];\r\n\r\nconst ServerSettingsPage: React.FC<SettingSectionChildProps> = props => {\r\n const { t } = props.moduleT;\r\n return (\r\n <div>\r\n {/*<Message \r\n description={ (\r\n <div>\r\n <div>\r\n New settings will take effect after restarting the management interface\r\n </div>\r\n <ActionButton \r\n action={ SystemActions.restartWeb }\r\n />\r\n </div>\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />*/}\r\n\r\n <ActionButton \r\n actions={ SystemActions }\r\n actionId=\"restartWeb\"\r\n />\r\n\r\n <div className=\"ui header\">\r\n HTTP\r\n </div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ PlainEntry }\r\n />\r\n </div>\r\n\r\n <div className=\"ui header\">\r\n HTTPS\r\n </div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ TlsEntry }\r\n />\r\n\r\n <Message \r\n description={ t<string>(\r\n 'defaultCertNote', \r\n 'The default client certificate is used if the certificate paths are empty') \r\n }\r\n icon={ IconConstants.INFO }\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ServerSettingsPage;","const MODULE_URL = 'web_users';\r\n\r\nexport default {\r\n MODULE_URL: MODULE_URL,\r\n USERS_URL: MODULE_URL,\r\n\r\n ADDED: 'web_user_added',\r\n UPDATED: 'web_user_updated',\r\n REMOVED: 'web_user_removed',\r\n}\r\n;\r\n","\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\n\r\nimport History from 'utils/History';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\n\r\nconst isOther = (user: API.WebUser) => user.id !== LoginStore.user.id;\r\n\r\n\r\nconst handleCreate: UI.ActionHandler<void> = ({ location }) => {\r\n History.push(`${location.pathname}/users`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.WebUser> = ({ data: user, location }) => {\r\n History.push(`${location.pathname}/users/${user.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.WebUser> = ({ data: user }) => {\r\n return SocketService.delete(`${WebUserConstants.USERS_URL}/${user.id}`);\r\n};\r\n\r\n\r\n\r\nconst WebUserCreateActions: UI.ActionListType<undefined> = {\r\n create: { \r\n displayName: 'Add user',\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate\r\n },\r\n};\r\n\r\nconst WebUserEditActions: UI.ActionListType<API.WebUser> = {\r\n edit: { \r\n displayName: 'Edit user',\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n },\r\n remove: {\r\n displayName: 'Remove user', \r\n filter: isOther,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the user {{item.username}}?',\r\n approveCaption: 'Remove user',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n },\r\n};\r\n\r\nexport default {\r\n create: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'webUser',\r\n actions: WebUserCreateActions,\r\n },\r\n edit: {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'webUser',\r\n actions: WebUserEditActions\r\n }\r\n};\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport ModalRouteDecorator, { ModalRouteDecoratorChildProps } from 'decorators/ModalRouteDecorator';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\nimport AccessConstants from 'constants/AccessConstants';\r\nimport PermissionSelector from 'routes/Settings/routes/System/components/users/PermissionSelector';\r\n\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport Form, { FormSaveHandler, FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport '../../style.css';\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { translateForm } from 'utils/FormUtils';\r\nimport { getSubModuleT } from 'utils/TranslationUtils';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\n\r\nconst enum PermissionAction {\r\n EDIT = 'Edit',\r\n VIEW = 'View',\r\n SEND_MESSAGES = 'Send messages'\r\n}\r\n\r\ntype CaptionEntry = string | {\r\n title: string;\r\n action: PermissionAction;\r\n};\r\n\r\n\r\nconst AccessCaptions: { [key in string]: CaptionEntry } = {\r\n ADMIN: 'Administrator',\r\n\r\n SEARCH: 'Search',\r\n DOWNLOAD: 'Download',\r\n TRANSFERS: 'Transfers',\r\n\r\n EVENTS_VIEW: {\r\n title: 'Events',\r\n action: PermissionAction.VIEW,\r\n },\r\n EVENTS_EDIT: {\r\n title: 'Events',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n QUEUE_VIEW: {\r\n title: 'Queue',\r\n action: PermissionAction.VIEW,\r\n },\r\n QUEUE_EDIT: {\r\n title: 'Queue',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n FAVORITE_HUBS_VIEW: {\r\n title: 'Favorite hubs',\r\n action: PermissionAction.VIEW,\r\n },\r\n FAVORITE_HUBS_EDIT: {\r\n title: 'Favorite hubs',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n SETTINGS_VIEW: {\r\n title: 'Settings',\r\n action: PermissionAction.VIEW,\r\n },\r\n SETTINGS_EDIT: {\r\n title: 'Settings',\r\n action: PermissionAction.EDIT,\r\n },\r\n \r\n FILESYSTEM_VIEW: {\r\n title: 'Local filesystem',\r\n action: PermissionAction.VIEW,\r\n },\r\n FILESYSTEM_EDIT: {\r\n title: 'Local filesystem',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n HUBS_VIEW: {\r\n title: 'Hubs',\r\n action: PermissionAction.VIEW,\r\n },\r\n HUBS_EDIT: {\r\n title: 'Hubs',\r\n action: PermissionAction.EDIT,\r\n },\r\n HUBS_SEND: {\r\n title: 'Hubs',\r\n action: PermissionAction.SEND_MESSAGES,\r\n },\r\n\r\n PRIVATE_CHAT_VIEW: {\r\n title: 'Private chat',\r\n action: PermissionAction.VIEW,\r\n },\r\n PRIVATE_CHAT_EDIT: {\r\n title: 'Private chat',\r\n action: PermissionAction.EDIT,\r\n },\r\n PRIVATE_CHAT_SEND: {\r\n title: 'Private chat',\r\n action: PermissionAction.SEND_MESSAGES,\r\n },\r\n\r\n FILELISTS_VIEW: {\r\n title: 'Filelists',\r\n action: PermissionAction.VIEW,\r\n },\r\n FILELISTS_EDIT: {\r\n title: 'Filelists',\r\n action: PermissionAction.EDIT,\r\n },\r\n \r\n VIEW_FILE_VIEW: {\r\n title: 'Viewed files',\r\n action: PermissionAction.VIEW,\r\n },\r\n VIEW_FILE_EDIT: {\r\n title: 'Viewed files',\r\n action: PermissionAction.EDIT,\r\n },\r\n};\r\n\r\n\r\nconst reducePermissionToOption = (options: API.SettingEnumOption[], key: string, moduleT: UI.ModuleTranslator) => {\r\n const captionEntry = AccessCaptions[key];\r\n if (typeof captionEntry === 'string') {\r\n options.push({\r\n id: AccessConstants[key],\r\n name: moduleT.translate(captionEntry),\r\n });\r\n } else {\r\n options.push({\r\n id: AccessConstants[key],\r\n name: `${moduleT.translate(captionEntry.title)} (${moduleT.translate(captionEntry.action)})`,\r\n }); \r\n }\r\n\r\n return options;\r\n};\r\n\r\nconst getEntry = (isNew: boolean /*, moduleT: UI.ModuleTranslator*/): UI.FormFieldDefinition[] => {\r\n return [\r\n {\r\n key: 'username',\r\n title: 'User name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'password',\r\n type: API.SettingTypeEnum.STRING,\r\n title: isNew ? 'Password' : 'New password',\r\n optional: !isNew,\r\n },\r\n {\r\n key: 'permissions',\r\n title: 'Permissions',\r\n type: API.SettingTypeEnum.LIST,\r\n item_type: API.SettingTypeEnum.STRING,\r\n },\r\n ];\r\n};\r\n\r\ninterface WebUserDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.WebUserInput, UI.FormValueMap {\r\n\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n user: API.WebUserInput;\r\n}\r\n\r\ninterface RouteProps {\r\n userId: string;\r\n}\r\n\r\ntype Props = WebUserDialogProps & DataProps & \r\n ModalRouteDecoratorChildProps<RouteProps>;\r\n\r\nclass WebUserDialog extends Component<Props> {\r\n static displayName = 'WebUserDialog';\r\n\r\n\r\n entry: UI.FormFieldDefinition[];\r\n form: Form<Entry>;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n\r\n this.entry = translateForm(getEntry(this.isNew()), props.moduleT);\r\n \r\n const permissionT = getSubModuleT(props.moduleT, 'permissionSelector');\r\n const permissions = this.entry.find(def => def.key === 'permissions')!;\r\n Object.assign(permissions, {\r\n options: Object.keys(AccessConstants).reduce(\r\n (reduced, cur) => reducePermissionToOption(reduced, cur, permissionT), \r\n []\r\n )\r\n });\r\n }\r\n\r\n isNew = () => {\r\n return !this.props.user;\r\n }\r\n\r\n save = () => {\r\n return this.form.save();\r\n }\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (this.isNew()) {\r\n return SocketService.post(WebUserConstants.USERS_URL, changedFields);\r\n }\r\n\r\n return SocketService.patch(`${WebUserConstants.USERS_URL}/${this.props.user.id}`, changedFields);\r\n }\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'permissions') {\r\n const { user, moduleT } = this.props;\r\n fieldOptions.factory = t.form.Select;\r\n fieldOptions.template = PermissionSelector(moduleT);\r\n fieldOptions.disabled = !this.isNew() && user.username === LoginStore.user.username;\r\n } else if (id === 'password') {\r\n fieldOptions.type = 'password';\r\n } else if (id === 'username') {\r\n fieldOptions.disabled = !this.isNew();\r\n }\r\n }\r\n\r\n render() {\r\n const { user, moduleT, ...other } = this.props;\r\n const title = moduleT.translate(this.isNew() ? 'Add web user' : 'Edit user');\r\n\r\n return (\r\n <Modal \r\n className=\"web-user\" \r\n title={ title } \r\n onApprove={ this.save } \r\n closable={ false } \r\n icon={ IconConstants.USER }\r\n { ...other }\r\n >\r\n <Form<Entry>\r\n ref={ (c: any) => this.form = c! }\r\n fieldDefinitions={ this.entry }\r\n onFieldSetting={ this.onFieldSetting }\r\n onSave={ this.onSave }\r\n sourceValue={ this.props.user as Entry }\r\n location={ this.props.location }\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<WebUserDialogProps, RouteProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(WebUserDialog, {\r\n urls: {\r\n user: ({ match }, socket) => {\r\n if (!match.params.userId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${WebUserConstants.USERS_URL}/${match.params.userId}`);\r\n },\r\n },\r\n }),\r\n 'users/:userId?'\r\n);","import t from 'utils/tcomb-form';\r\n\r\nimport Checkbox from 'components/semantic/Checkbox';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { updateMultiselectValues } from 'utils/FormUtils';\r\n\r\n\r\ntype AccessOptionType = {\r\n value: API.AccessEnum;\r\n text: string;\r\n};\r\n\r\nconst PermissionSelector = (moduleT: UI.ModuleTranslator) => {\r\n return t.form.Form.templates.select.clone({\r\n renderSelect: (locals: UI.FormLocals<AccessOptionType, API.AccessEnum[]>) => {\r\n const onChange = (access: API.AccessEnum, checked: boolean) => {\r\n locals.onChange(\r\n updateMultiselectValues(locals.value, access, checked)\r\n );\r\n };\r\n\r\n const mapPermission = ({ value, text }: UI.FormOption<API.AccessEnum>) => (\r\n <Checkbox \r\n key={ value }\r\n className={ value }\r\n checked={ locals.value.indexOf(value) !== -1 } \r\n onChange={ checked => onChange(value, checked) }\r\n caption={ text }\r\n />\r\n );\r\n\r\n const filterPermission = ({ value }: UI.FormOption<API.AccessEnum>) => {\r\n if (locals.value.indexOf(API.AccessEnum.ADMIN) !== -1 && value !== API.AccessEnum.ADMIN) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const permissions = locals.options\r\n .filter(filterPermission)\r\n .map(mapPermission);\r\n\r\n return (\r\n <div className=\"permission-select\">\r\n <Message \r\n description={ moduleT.t<string>(\r\n 'adminPermissionNote',\r\n 'Administrator permission is required in order to access the System section in settings'\r\n ) }\r\n className=\"small\"\r\n />\r\n { permissions }\r\n </div>\r\n );\r\n }\r\n });\r\n};\r\n\r\n\r\nexport default PermissionSelector;\r\n","import * as React from 'react';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\nimport WebUserActions from 'actions/ui/WebUserActions';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport WebUserDialog from 'routes/Settings/routes/System/components/users/WebUserDialog';\r\n\r\nimport DataProviderDecorator, { DataProviderDecoratorChildProps } from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/menu';\r\nimport { formatRelativeTime } from 'utils/ValueFormat';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\ninterface WebUserRowProps {\r\n user: API.WebUser;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst WebUserRow: React.FC<WebUserRowProps> = ({ user, moduleT }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu \r\n caption={ <strong>{ user.username }</strong> }\r\n actions={ WebUserActions.edit } \r\n itemData={ user }\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"permissions\">\r\n { user.permissions.indexOf(API.AccessEnum.ADMIN) !== -1 ? \r\n moduleT.translate('Administrator') : \r\n user.permissions.length\r\n }\r\n </td>\r\n <td className=\"sessions\">\r\n { user.active_sessions }\r\n </td>\r\n <td className=\"last-login\">\r\n { formatRelativeTime(user.last_login) }\r\n </td>\r\n </tr>\r\n);\r\n\r\ninterface WebUsersPageProps extends SettingSectionChildProps {\r\n\r\n}\r\n\r\ninterface WebUsersPageDataProps extends DataProviderDecoratorChildProps {\r\n users: API.WebUser[];\r\n}\r\n\r\nclass WebUsersPage extends React.Component<WebUsersPageProps & WebUsersPageDataProps> {\r\n static displayName = 'WebUsersPage';\r\n\r\n render() {\r\n const { users, moduleT } = this.props;\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <ActionButton \r\n actions={ WebUserActions.create }\r\n actionId=\"create\"\r\n />\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{ translate('Username') }</th>\r\n <th>{ translate('Permissions') }</th>\r\n <th>{ translate('Active sessions') }</th>\r\n <th>{ translate('Last logged in') }</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n { users.map(user => (\r\n <WebUserRow \r\n key={ user.username }\r\n user={ user }\r\n moduleT={ moduleT }\r\n />\r\n )) }\r\n </tbody>\r\n </table>\r\n <WebUserDialog\r\n moduleT={ moduleT }\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator(WebUsersPage, {\r\n urls: {\r\n users: WebUserConstants.USERS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.ADDED, () => refetchData());\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.UPDATED, () => refetchData());\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.REMOVED, () => refetchData());\r\n },\r\n});","const AccessConstants = require('constants/AccessConstants').default;\r\n\r\nmodule.exports = {\r\n url: 'system',\r\n title: 'System',\r\n icon: 'settings',\r\n access: AccessConstants.ADMIN,\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n { \r\n title: 'Users', \r\n url: 'users', \r\n noSave: true,\r\n component: require('./components/WebUsersPage').default,\r\n }, { \r\n title: 'Logging', \r\n url: 'logging',\r\n component: require('./components/LoggingPage').default,\r\n }, { \r\n title: 'Web server', \r\n url: 'server-settings',\r\n component: require('./components/ServerSettingsPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Advanced server settings', \r\n url: 'advanced-server-settings',\r\n component: require('./components/AdvancedServerSettingsPage').default, \r\n }\r\n ],\r\n};\r\n\r\n","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'use_main_chat_notify',\r\n 'show_joins',\r\n 'format_release_names'\r\n];\r\n\r\nconst GeneralPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default GeneralPage;","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'report_uploads',\r\n 'report_downloads',\r\n 'report_search_alternates',\r\n 'report_added_sources',\r\n 'report_blocked_share',\r\n 'report_hashed_files',\r\n 'report_scheduled_refreshes',\r\n 'report_filelist_dupes',\r\n];\r\n\r\nconst EventPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default EventPage;","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n 'history_search_max',\r\n 'history_download_max',\r\n 'history_chat_log_lines',\r\n];\r\n\r\nconst MessageEntry = [\r\n 'history_hub_messages',\r\n 'history_pm_messages',\r\n 'history_log_messages',\r\n];\r\n\r\nconst SessionEntry = [\r\n 'history_hub_sessions',\r\n 'history_pm_sessions',\r\n 'history_filelist_sessions',\r\n];\r\n\r\nconst HistoryPage: React.FC<SettingSectionChildProps> = props => {\r\n const { t } = props.moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n <RemoteSettingForm\r\n title={ t('maxMessageHistory', 'Maximum number of messages to cache') }\r\n { ...props }\r\n keys={ MessageEntry }\r\n />\r\n <RemoteSettingForm\r\n title={ t('maxSessionHistory', 'Maximum number of previously opened sessions') }\r\n { ...props }\r\n keys={ SessionEntry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default HistoryPage;","import * as React from 'react';\r\n\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport LocalSettingForm from 'routes/Settings/components/LocalSettingForm';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst Entry = [\r\n LocalSettings.UNREAD_LABEL_DELAY,\r\n LocalSettings.BACKGROUND_IMAGE_URL,\r\n LocalSettings.NO_INSTALL_PROMPT,\r\n];\r\n\r\nconst MiscellaneousPage: React.FC<SettingSectionChildProps> = props => (\r\n <div>\r\n <LocalSettingForm\r\n { ...props }\r\n keys={ Entry }\r\n />\r\n </div>\r\n);\r\n\r\nexport default MiscellaneousPage;","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport LocalSettingForm from 'routes/Settings/components/LocalSettingForm';\r\n\r\nimport '../style.css';\r\nimport { SettingSectionChildProps } from 'routes/Settings/components/SettingSection';\r\n\r\n\r\nconst PopupEntry = [\r\n LocalSettings.NOTIFY_MENTION,\r\n LocalSettings.NOTIFY_PM_USER,\r\n LocalSettings.NOTIFY_PM_BOT,\r\n LocalSettings.NOTIFY_HUB_MESSAGE,\r\n\r\n LocalSettings.NOTIFY_BUNDLE_STATUS,\r\n\r\n LocalSettings.NOTIFY_EVENTS_INFO,\r\n LocalSettings.NOTIFY_EVENTS_WARNING,\r\n LocalSettings.NOTIFY_EVENTS_ERROR,\r\n];\r\n\r\nconst NotificationPage: React.FC<SettingSectionChildProps> = props => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <LocalSettingForm\r\n title={ translate('Popup notifications') }\r\n { ...props }\r\n keys={ PopupEntry }\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default NotificationPage;","module.exports = {\r\n url: 'view',\r\n title: 'View',\r\n icon: 'browser',\r\n component: require('../../components/SettingSection').default, \r\n menuItems: [\r\n { \r\n title: 'Notifications', \r\n url: 'notifications',\r\n local: true,\r\n component: require('./components/NotificationPage').default, \r\n }, { \r\n title: 'Histories', \r\n url: 'histories',\r\n component: require('./components/HistoryPage').default, \r\n }, { \r\n title: 'Events', \r\n url: 'events',\r\n component: require('./components/EventPage').default, \r\n }, { \r\n title: 'Appearance', \r\n url: 'appearance',\r\n component: require('./components/AppearancePage').default, \r\n },\r\n ],\r\n advancedMenuItems: [\r\n { \r\n title: 'Miscellaneous', \r\n url: 'miscellaneous',\r\n local: true,\r\n component: require('./components/MiscellaneousPage').default, \r\n },\r\n ],\r\n};","import LoginStore from 'stores/LoginStore';\r\nimport { fetchData } from 'utils/HttpUtils';\r\n\r\n\r\nexport const uploadTempFile = async (file: File): Promise<string> => {\r\n try {\r\n const res = await fetchData(`${getBasePath()}temp`, {\r\n method: 'POST',\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': LoginStore.authToken,\r\n \r\n 'Authorization': LoginStore.authToken,\r\n },\r\n body: file\r\n });\r\n\r\n return res.headers.get('Location')!;\r\n } catch (e) {\r\n throw e;\r\n }\r\n};\r\n\r\nconst toCorsSafeUrl = (url: string) => {\r\n const proxyUrl = `${window.location.origin}${getBasePath()}proxy?url=${encodeURIComponent(url)}`;\r\n return proxyUrl;\r\n};\r\n\r\nexport const fetchCorsSafeData = async (url: string, isJSON: boolean, options?: RequestInit) => {\r\n try {\r\n //console.log(`CORS HTTP request started (${url})`);\r\n\r\n const res = await fetchData(\r\n toCorsSafeUrl(url), \r\n {\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': LoginStore.authToken,\r\n\r\n // Temp workaround for people upgrading from versions < 2.7.0\r\n // If the new UI was loaded before restarting the app, a cache expiration time of \r\n // one year would have been set for \"Not found\" errors...\r\n 'Cache-Control': 'no-store, must-revalidate, max-age=0'\r\n },\r\n ...options,\r\n }\r\n );\r\n\r\n const data = await isJSON ? res.json() : res.text();\r\n return data;\r\n } catch (e) {\r\n console.error(`CORS HTTP request failed (${url})`, e);\r\n throw e;\r\n }\r\n};\r\n"],"names":["compareVersions","v1","v2","n1","validateAndParse","n2","p1","pop","p2","r","compareSegments","split","semver","version","TypeError","match","Error","shift","isWildcard","s","tryParse","v","n","parseInt","isNaN","compareStrings","a","b","ap","bp","String","forceType","i","Math","max","length","Object","keys","___CSS_LOADER_EXPORT___","push","module","id","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","isManaged","extension","managed","isRunning","running","downloadExtension","url","installId","shasum","install_id","handleNpmAction","data","npmPackage","name","tarball","dist","ExtensionInstallActions","installUrl","displayName","icon","access","input","approveCaption","content","inputProps","placeholder","type","required","handler","ExtensionNpmActions","installNpm","updateNpm","ExtensionManageActions","start","filter","ext","stop","configure","has_settings","location","pathname","divider","remove","confirmation","rejectCaption","install","moduleId","actions","npm","manage","ShareActions","refresh","SystemActions","restartWeb","shutdown","subId","alwaysShow","localSettings","prompt","useContext","t","title","description","className","caption","onClick","formatText","text","i18nKey","Row","titleWidth","noText","style","overflow","Header","Grid","children","columns","stackable","other","MODULE_URL","NPM_URL","EXTENSIONS_URL","DOWNLOAD_URL","ENGINES_URL","ENGINES_STATUS_URL","DEFAULT_ENGINE","STARTED","STOPPED","ADDED","REMOVED","UPDATED","INSTALLATION_STARTED","INSTALLATION_SUCCEEDED","INSTALLATION_FAILED","NPM_PACKAGES_URL","NPM_PACKAGE_URL","NPM_HOMEPAGE_URL","GROUPED_DIRECTORIES_URL","DIRECTORIES_URL","DIRECTORIES_UPDATED","PROFILES_URL","PROFILE_ADDED","PROFILE_UPDATED","PROFILE_REMOVED","HIDDEN_PROFILE_ID","profileToEnumValue","profile","str","Component","listHidden","dataProviderDecoratorSettings","addSize","merge","urls","profiles","dataConverters","p","map","size","convertProfile","onSocketConnected","addSocketListener","refetchData","fetchUrl","unavailableMessage","fetchIntervalSeconds","Decorator","state","stats","fetchStats","then","this","onStatsReceived","catch","error","console","message","fetchTimeout","window","setTimeout","setState","componentDidMount","componentWillUnmount","clearTimeout","render","props","assign","undefined","LocalSettingForm","constructor","super","onSave","changedSettingArray","allFields","settings","Promise","resolve","onFieldChanged","value","hasChanges","saveContext","definitions","moduleT","ref","f","addFormRef","fieldDefinitions","sourceValue","sectionToUrl","section","parent","translateSettingSectionTitle","settingsT","translate","menuItemToLinkComponent","menuItemInfo","debugOnly","menuItems","indexOf","menuItemsToRouteComponentArray","currentMenuItem","item","path","component","advancedMenuItems","parentMenuItems","camelCase","findMenuItem","find","isItemActive","RemoteSettingForm","changedValues","refetchValues","otherProps","onSettingValuesReceived","valueMode","value_mode","SideChildSectionMenu","TopRootSectionMenu","Content","contentClassname","saveButton","LayoutHeader","Icon","color","rightComponent","TopSectionSelectionMenu","Dropdown","selection","captionIcon","SectionedDropdown","MenuSection","SettingsMenuDecorator","SaveDecorator","innerWidth","SettingsTopMenuLayout","SettingsSideMenuLayout","childProps","SaveButton","saving","toggleSaveState","saveHandler","local","hasAccess","LoginStore","Button","loading","disabled","propTypes","SaveDecoratorContext","withSaveContext","Consumer","context","getFormId","join","forms","changedProperties","Set","onSettingsChanged","add","delete","forceUpdate","onSettingsSaved","NotificationActions","handleSave","promises","values","c","save","clear","all","promptSave","nextLocation","noSave","hasOwnProperty","getFormRef","componentDidUpdate","prevProps","Message","IconConstants","Provider","to","menu","MainLayout","Settings","withTranslation","systemInfo","buildDate","client_version","api_version","api_feature_level","client_started","active_sessions","server_threads","total_users","unique_users","active_users","total_share","plainT","adc_down_per_user","adc_up_per_user","clients","formatClientRow","uniqueUsers","client","count","total_size","defaultValue","replace","totalCount","total_file_count","uniqueCount","unique_file_count","total_directory_count","average_file_age","total_searches","perSecondCount","total_searches_per_second","toFixed","tth_searches","recursive_searches","matchedCount","unfiltered_recursive_searches_per_second","filteredPercentage","filtered_searches","resultPercentage","recursive_searches_responded","tokenCount","average_search_token_count","tokenLength","average_search_token_length","matchTime","average_match_ms","totalUp","session_uploaded","start_total_uploaded","totalDown","session_downloaded","start_total_downloaded","AccessConstants","exports","TRANSFERS","HUBS_VIEW","DETECT_URL","STATUS_URL","CONNECTIVITY_MESSAGE","CONNECTIVITY_STARTED","CONNECTIVITY_FINISHED","ConnectivityActions","detect","SocketService","ConnectivityConstants","formatStatus","protocolStatus","auto","auto_detect","status","DataProviderDecorator","runningV4","runningV6","status_v4","status_v6","ActionButton","actionId","mergeData","setDetectState","v6","toI18nKey","Trans","ExternalLink","LinkConstants","Entry","protocol","onFieldSetting","fieldOptions","formValue","help","ProtocolPage","autoDetectEnabled","convertValue","key","protocolEnabled","autoDetect","outgoing_mode","SegmentsEntry","BufferEntry","CompressionEntry","FavoriteDirectoryCreateActions","create","History","FavoriteDirectoryEditActions","edit","directory","FavoriteDirectoryConstants","FavoriteDirectoryDialog","isNew","directoryEntry","form","changedFields","config","historyId","FilesystemConstants","factory","template","suggestionGetter","virtualNames","Modal","onApprove","closable","Form","ModalRouteDecorator","socket","params","directoryId","get","FavoriteDirectoryActions","itemData","contextElement","getRow","directories","FavoriteDirectoryTable","HighPrioEntry","SearchTypeCreateActions","SearchTypeEditActions","default_type","SearchConstants","item_type","SearchTypeDialog","searchTypeEntry","searchTypeId","SearchTypeActions","extensions","searchTypes","Skiplist","enginesStatus","loaderText","packageCatalog","installedPackages","installedPackage","Extension","getItem","package","ExtensionConstants","objects","refetchInstalled","EngineStatusMessage","ExtensionActions","ExtensionsConfigureDialog","getSettingsUrl","extensionId","dynamicHeight","convertNpmPackage","_npmUser","publisher","username","date","dataError","npmError","private","renderOnError","InstallButton","hasUpdate","installing","ids","remoteMenuId","MenuConstants","button","menuElementClassName","Version","packageInfo","versionDesc","from","formatAuthor","author","formatNote","onInstallationStarted","onInstallationCompleted","ExtensionIcon","SocketSubscriptionDecorator","getCornerIcon","cornerIcon","ignoreInfo","userIcon","user","ignored_messages","cid","ignores","profileId","toString","ShareExcludeCreateActions","ShareExcludeEditActions","ShareConstants","ShareExcludeActions","ExcludePage","excludes","onConfirm","initialPath","subHeader","selectMode","OptimizeLayout","startHandler","verify","setVerify","marginTop","Checkbox","checked","onChange","floating","HashDatabaseLayout","handleOptimize","HashConstants","file_index_size","hash_store_size","maintenance_running","notDefault","default","ShareProfileCreateActions","ShareProfileConstants","ShareProfileEditActions","browse","FilelistSessionActions","FilelistSessionStore","ShareProfileRow","ShareProfileActions","files","ShareProfileDecorator","AutoValuePanel","getAutoKey","changedKey","autoSettingKey","settingKey","Auto","Manual","Generic","Hooks","LogSection","enabled","convertKey","suffix","onSettingsReceived","onEnableStateChanged","onContentSetting","getChildClass","Title","simple","sectionKeys","simpleKeys","Accordion","controlled","sectionKey","MessageSectionKeys","TransferSectionKeys","SimpleSectionKeys","PlainEntry","TlsEntry","WebUserCreateActions","WebUserEditActions","WebUserConstants","PermissionAction","AccessCaptions","ADMIN","SEARCH","DOWNLOAD","EVENTS_VIEW","action","VIEW","EVENTS_EDIT","EDIT","QUEUE_VIEW","QUEUE_EDIT","FAVORITE_HUBS_VIEW","FAVORITE_HUBS_EDIT","SETTINGS_VIEW","SETTINGS_EDIT","FILESYSTEM_VIEW","FILESYSTEM_EDIT","HUBS_EDIT","HUBS_SEND","SEND_MESSAGES","PRIVATE_CHAT_VIEW","PRIVATE_CHAT_EDIT","PRIVATE_CHAT_SEND","FILELISTS_VIEW","FILELISTS_EDIT","VIEW_FILE_VIEW","VIEW_FILE_EDIT","WebUserDialog","renderSelect","locals","permissions","entry","optional","permissionT","def","reduce","reduced","cur","captionEntry","reducePermissionToOption","userId","WebUserRow","WebUserActions","last_login","WebUsersPage","users","MessageEntry","SessionEntry","PopupEntry","uploadTempFile","file","getBasePath","method","headers","body","e","fetchCorsSafeData","isJSON","res","origin","encodeURIComponent","toCorsSafeUrl","json"],"sourceRoot":""}
|