From 4426eb2424b6200489d78301ca1a5ac6b89cd41f Mon Sep 17 00:00:00 2001 From: crschnick Date: Sat, 15 Jun 2024 10:40:03 +0000 Subject: [PATCH] Merge branch release-10.0 into master --- app/build.gradle | 23 +- .../io/xpipe/app/beacon/AppBeaconServer.java | 174 +++ .../app/beacon/BeaconRequestHandler.java | 124 ++ .../io/xpipe/app/beacon/BeaconSession.java | 11 + .../xpipe/app/beacon/BeaconShellSession.java | 12 + .../app/beacon/impl/AskpassExchangeImpl.java | 34 + .../impl/ConnectionQueryExchangeImpl.java | 148 ++ .../beacon/impl/DaemonFocusExchangeImpl.java | 20 + .../beacon/impl/DaemonModeExchangeImpl.java | 36 + .../beacon/impl/DaemonOpenExchangeImpl.java | 25 + .../beacon/impl/DaemonStatusExchangeImpl.java | 25 + .../beacon/impl/DaemonStopExchangeImpl.java | 22 + .../impl/DaemonVersionExchangeImpl.java} | 15 +- .../beacon/impl/HandshakeExchangeImpl.java | 42 + .../beacon/impl/ShellExecExchangeImpl.java | 35 + .../beacon/impl/ShellStartExchangeImpl.java | 34 + .../beacon/impl/ShellStopExchangeImpl.java | 26 + .../impl/TerminalLaunchExchangeImpl.java | 17 + .../beacon/impl/TerminalWaitExchangeImpl.java | 17 + .../app/browser/BrowserTransferComp.java | 9 +- .../xpipe/app/browser/file/BrowserEntry.java | 7 +- .../app/browser/file/LocalFileSystem.java | 5 +- .../browser/session/BrowserSessionTab.java | 2 +- .../xpipe/app/comp/base/ListBoxViewComp.java | 15 +- .../io/xpipe/app/comp/base/MarkdownComp.java | 6 +- .../xpipe/app/comp/base/SideMenuBarComp.java | 15 +- .../xpipe/app/comp/base/StoreToggleComp.java | 69 +- .../xpipe/app/comp/base/ToggleSwitchComp.java | 24 +- .../app/comp/store/DenseStoreEntryComp.java | 2 +- .../comp/store/StandardStoreEntryComp.java | 2 +- .../app/comp/store/StoreCreationComp.java | 4 + .../app/comp/store/StoreCreationMenu.java | 6 +- .../xpipe/app/comp/store/StoreEntryComp.java | 294 ++-- .../comp/store/StoreEntryListStatusComp.java | 4 +- .../app/comp/store/StoreEntryWrapper.java | 110 +- .../xpipe/app/comp/store/StoreIntroComp.java | 66 +- .../io/xpipe/app/comp/store/StoreSection.java | 60 +- .../xpipe/app/comp/store/StoreViewState.java | 35 +- .../xpipe/app/core/AppDesktopIntegration.java | 5 + .../xpipe/app/core/AppExtensionManager.java | 2 +- .../java/io/xpipe/app/core/AppProperties.java | 7 +- .../io/xpipe/app/core/AppSocketServer.java | 358 ----- .../main/java/io/xpipe/app/core/AppTheme.java | 8 +- .../java/io/xpipe/app/core/mode/BaseMode.java | 14 +- .../io/xpipe/app/core/mode/OperationMode.java | 4 + .../app/exchange/AskpassExchangeImpl.java | 25 - .../app/exchange/DialogExchangeImpl.java | 76 - .../xpipe/app/exchange/FocusExchangeImpl.java | 15 - .../app/exchange/LaunchExchangeImpl.java | 34 - .../app/exchange/MessageExchangeImpl.java | 47 - .../app/exchange/MessageExchangeImpls.java | 61 - .../xpipe/app/exchange/OpenExchangeImpl.java | 30 - .../app/exchange/QueryStoreExchangeImpl.java | 23 - .../exchange/TerminalLaunchExchangeImpl.java | 16 - .../exchange/TerminalWaitExchangeImpl.java | 17 - .../app/exchange/cli/DrainExchangeImpl.java | 30 - .../exchange/cli/EditStoreExchangeImpl.java | 21 - .../exchange/cli/ListStoresExchangeImpl.java | 32 - .../app/exchange/cli/ModeExchangeImpl.java | 36 - .../exchange/cli/ReadDrainExchangeImpl.java | 14 - .../exchange/cli/RemoveStoreExchangeImpl.java | 23 - .../exchange/cli/RenameStoreExchangeImpl.java | 18 - .../app/exchange/cli/SinkExchangeImpl.java | 29 - .../app/exchange/cli/StatusExchangeImpl.java | 22 - .../app/exchange/cli/StopExchangeImpl.java | 22 - .../exchange/cli/StoreAddExchangeImpl.java | 141 -- .../cli/StoreProviderListExchangeImpl.java | 37 - .../java/io/xpipe/app/ext/ActionProvider.java | 61 +- .../app/ext/DataStorageExtensionProvider.java | 31 + .../io/xpipe/app/ext/DataStoreProvider.java | 11 +- .../app/ext/EnabledParentStoreProvider.java | 40 + .../xpipe/app/ext/EnabledStoreProvider.java | 25 + .../io/xpipe/app/ext/ExtensionException.java | 2 +- .../ext/SingletonSessionStoreProvider.java | 7 +- .../app/fxcomps/impl/IconButtonComp.java | 8 +- .../app/fxcomps/impl/StoreCategoryComp.java | 2 +- .../fxcomps/util/DerivedObservableList.java | 10 +- .../xpipe/app/fxcomps/util/LabelGraphic.java | 42 + .../xpipe/app/launcher/LauncherCommand.java | 32 +- .../app/launcher/LauncherConnection.java | 18 - .../io/xpipe/app/launcher/LauncherInput.java | 20 +- .../java/io/xpipe/app/prefs/AppPrefs.java | 29 +- .../app/prefs/ExternalApplicationType.java | 7 +- .../xpipe/app/prefs/ExternalEditorType.java | 49 +- .../io/xpipe/app/prefs/HttpApiCategory.java | 30 + .../java/io/xpipe/app/prefs/SyncCategory.java | 5 +- .../io/xpipe/app/storage/DataStorage.java | 136 +- .../io/xpipe/app/storage/DataStoreEntry.java | 76 +- .../app/storage/ImpersistentStorage.java | 26 +- .../io/xpipe/app/storage/StandardStorage.java | 17 +- .../app/terminal/ExternalTerminalType.java | 76 +- .../xpipe/app/terminal/WezTerminalType.java | 101 +- .../java/io/xpipe/app/util/AskpassAlert.java | 4 + .../java/io/xpipe/app/util/CommandView.java | 18 +- .../io/xpipe/app/util/CommandViewBase.java | 18 + .../java/io/xpipe/app/util/FileOpener.java | 11 +- .../java/io/xpipe/app/util/HostHelper.java | 8 + .../app/util/LicenseConnectionLimit.java | 32 + .../app/util/LicenseRequiredException.java | 7 +- .../java/io/xpipe/app/util/LocalShell.java | 1 + .../io/xpipe/app/util/MarkdownHelper.java | 13 +- .../io/xpipe/app/util/OptionsBuilder.java | 8 +- .../app/util/TerminalLauncherManager.java | 17 +- app/src/main/java/module-info.java | 46 +- .../io/xpipe/app/resources/misc/api.md | 1249 +++++++++++++++ .../app/resources/misc/github-dark.min.css | 10 + .../{web => misc}/github-markdown-dark.css | 8 +- .../{web => misc}/github-markdown-light.css | 8 +- .../xpipe/app/resources/misc/highlight.min.js | 1381 +++++++++++++++++ .../app/resources/style/store-entry-comp.css | 4 +- .../io/xpipe/app/resources/style/style.css | 8 + .../io/xpipe/app/resources/theme/custom.css | 2 +- .../io/xpipe/app/resources/theme/mocha.css | 115 ++ beacon/README.md | 19 +- .../io/xpipe/beacon/BeaconAuthMethod.java | 34 + .../java/io/xpipe/beacon/BeaconClient.java | 329 +--- ...ge.java => BeaconClientErrorResponse.java} | 10 +- .../xpipe/beacon/BeaconClientException.java | 23 + .../xpipe/beacon/BeaconClientInformation.java | 59 + .../java/io/xpipe/beacon/BeaconConfig.java | 12 - .../io/xpipe/beacon/BeaconConnection.java | 189 --- .../beacon/BeaconConnectorException.java | 25 + .../java/io/xpipe/beacon/BeaconException.java | 25 - .../java/io/xpipe/beacon/BeaconFormat.java | 112 -- .../java/io/xpipe/beacon/BeaconHandler.java | 34 - .../java/io/xpipe/beacon/BeaconInterface.java | 74 + .../io/xpipe/beacon/BeaconJacksonModule.java | 9 +- .../java/io/xpipe/beacon/BeaconServer.java | 9 +- .../beacon/BeaconServerErrorResponse.java | 20 + .../xpipe/beacon/BeaconServerException.java | 23 + .../java/io/xpipe/beacon/ClientException.java | 25 - .../io/xpipe/beacon/ConnectorException.java | 25 - .../java/io/xpipe/beacon/RequestMessage.java | 3 - .../java/io/xpipe/beacon/ResponseMessage.java | 3 - .../java/io/xpipe/beacon/ServerException.java | 25 - .../io/xpipe/beacon/api/AskpassExchange.java | 35 + .../beacon/api/ConnectionQueryExchange.java | 53 + .../xpipe/beacon/api/DaemonFocusExchange.java | 29 + .../xpipe/beacon/api/DaemonModeExchange.java | 32 + .../xpipe/beacon/api/DaemonOpenExchange.java | 30 + .../beacon/api/DaemonStatusExchange.java | 27 + .../xpipe/beacon/api/DaemonStopExchange.java | 30 + .../beacon/api/DaemonVersionExchange.java | 30 + .../xpipe/beacon/api/HandshakeExchange.java | 40 + .../xpipe/beacon/api/ShellExecExchange.java | 38 + .../xpipe/beacon/api/ShellStartExchange.java | 30 + .../xpipe/beacon/api/ShellStopExchange.java | 30 + .../TerminalLaunchExchange.java | 16 +- .../beacon/api/TerminalWaitExchange.java | 30 + .../beacon/exchange/AskpassExchange.java | 39 - .../xpipe/beacon/exchange/DrainExchange.java | 34 - .../xpipe/beacon/exchange/FocusExchange.java | 31 - .../xpipe/beacon/exchange/LaunchExchange.java | 36 - .../beacon/exchange/MessageExchange.java | 34 - .../beacon/exchange/MessageExchanges.java | 48 - .../xpipe/beacon/exchange/OpenExchange.java | 32 - .../beacon/exchange/QueryStoreExchange.java | 51 - .../xpipe/beacon/exchange/SinkExchange.java | 34 - .../xpipe/beacon/exchange/StopExchange.java | 31 - .../beacon/exchange/TerminalWaitExchange.java | 32 - .../beacon/exchange/cli/DialogExchange.java | 50 - .../exchange/cli/EditStoreExchange.java | 35 - .../exchange/cli/ListCollectionsExchange.java | 32 - .../exchange/cli/ListEntriesExchange.java | 34 - .../exchange/cli/ListStoresExchange.java | 32 - .../beacon/exchange/cli/ModeExchange.java | 35 - .../exchange/cli/ReadDrainExchange.java | 31 - .../cli/RemoveCollectionExchange.java | 31 - .../exchange/cli/RemoveStoreExchange.java | 31 - .../cli/RenameCollectionExchange.java | 34 - .../exchange/cli/RenameStoreExchange.java | 34 - .../beacon/exchange/cli/StatusExchange.java | 29 - .../beacon/exchange/cli/StoreAddExchange.java | 36 - .../cli/StoreProviderListExchange.java | 35 - .../beacon/exchange/cli/VersionExchange.java | 32 - .../exchange/data/CollectionListEntry.java | 17 - .../beacon/exchange/data/EntryListEntry.java | 17 - .../beacon/exchange/data/ProviderEntry.java | 14 - .../exchange/data/ServerErrorMessage.java | 25 - .../beacon/exchange/data/StoreListEntry.java | 17 - .../beacon/test/BeaconDaemonController.java | 20 +- .../test/BeaconDaemonExtensionTest.java | 5 +- .../xpipe/beacon/util/QuietDialogHandler.java | 74 - beacon/src/main/java/module-info.java | 49 +- .../io.xpipe.core.util.ModuleLayerLoader | 1 + build.gradle | 10 +- core/build.gradle | 2 - .../process/CommandFeedbackPredicate.java | 6 + .../java/io/xpipe/core/process/OsType.java | 14 +- .../io/xpipe/core/process/ShellDialects.java | 7 +- .../java/io/xpipe/core/store/DataStoreId.java | 2 - .../xpipe/core/store/EnabledStoreState.java | 24 + .../java/io/xpipe/core/store/FilePath.java | 1 - .../java/io/xpipe/core/store/LocalStore.java | 7 +- .../core/store/NetworkTunnelSession.java | 16 + .../xpipe/core/store/NetworkTunnelStore.java | 149 ++ .../io/xpipe/core/store/ServiceStore.java | 23 + .../java/io/xpipe/core/store/Session.java | 21 +- .../io/xpipe/core/store/SessionChain.java | 51 + .../io/xpipe/core/store/SessionListener.java | 6 + .../core/store/SingletonSessionStore.java | 16 +- .../java/io/xpipe/core/store/StorePath.java | 84 + .../io/xpipe/core/util/JacksonMapper.java | 14 +- .../io/xpipe/core/util/ModuleLayerLoader.java | 3 +- .../io/xpipe/core/util/XPipeInstallation.java | 12 +- core/src/main/java/module-info.java | 9 +- .../io.xpipe.core.util.ModuleLayerLoader | 2 + dist/build.gradle | 4 +- dist/changelogs/10.0.md | 72 + dist/changelogs/9.4.1.md | 59 + dist/changelogs/9.4.1_incremental.md | 3 + dist/changelogs/9.4_incremental.md | 20 +- dist/jpackage.gradle | 2 +- dist/licenses/prettytime.license | 177 --- dist/licenses/prettytime.properties | 4 - dist/logo/hicolor/1024x1024/apps/xpipe.png | Bin 0 -> 109894 bytes dist/logo/hicolor/128x128/apps/xpipe.png | Bin 0 -> 10988 bytes dist/logo/hicolor/16x16/apps/xpipe.png | Bin 0 -> 647 bytes dist/logo/hicolor/256x256/apps/xpipe.png | Bin 0 -> 25614 bytes dist/logo/hicolor/32x32/apps/xpipe.png | Bin 0 -> 1811 bytes dist/logo/hicolor/48x48/apps/xpipe.png | Bin 0 -> 2999 bytes dist/logo/hicolor/512x512/apps/xpipe.png | Bin 0 -> 47253 bytes dist/logo/hicolor/64x64/apps/xpipe.png | Bin 0 -> 4344 bytes .../ext/base/action/BrowseStoreAction.java | 9 +- .../ext/base/action/CloneStoreAction.java | 9 +- ...on.java => DeleteChildrenStoreAction.java} | 11 +- .../ext/base/action/EditStoreAction.java | 13 +- ...unchAction.java => LaunchStoreAction.java} | 11 +- ...n.java => RefreshChildrenStoreAction.java} | 13 +- ...mpleAction.java => SampleStoreAction.java} | 12 +- .../{ScanAction.java => ScanStoreAction.java} | 11 +- .../ext/base/action/ShareStoreAction.java | 9 +- .../xpipe/ext/base/action/XPipeUrlAction.java | 16 +- .../DesktopApplicationStoreProvider.java | 4 - .../desktop/DesktopCommandStoreProvider.java | 4 - .../DesktopEnvironmentStoreProvider.java | 8 - .../base/script/PredefinedScriptGroup.java | 4 +- .../base/script/PredefinedScriptStore.java | 19 + .../ext/base/script/RunScriptAction.java | 95 ++ .../script/ScriptDataStorageProvider.java | 50 + .../base/script/ScriptGroupStoreProvider.java | 37 +- .../io/xpipe/ext/base/script/ScriptStore.java | 43 +- .../ext/base/script/ScriptTargetType.java | 13 + .../ext/base/script/SimpleScriptStore.java | 10 +- .../script/SimpleScriptStoreProvider.java | 135 +- .../service/AbstractServiceGroupStore.java | 24 + .../AbstractServiceGroupStoreProvider.java | 70 + .../base/service/AbstractServiceStore.java | 42 + .../service/AbstractServiceStoreProvider.java | 100 ++ .../ext/base/service/CustomServiceStore.java | 17 + .../service/CustomServiceStoreProvider.java | 70 + .../service/FixedServiceCreatorStore.java | 11 + .../base/service/FixedServiceGroupStore.java | 29 + .../FixedServiceGroupStoreProvider.java | 30 + .../ext/base/service/FixedServiceStore.java | 32 + .../service/FixedServiceStoreProvider.java | 35 + .../ext/base/service/MappedServiceStore.java | 15 + .../service/MappedServiceStoreProvider.java | 26 + .../base/service/ServiceCopyUrlAction.java | 60 + .../ext/base/service/ServiceGroupStore.java | 28 + .../service/ServiceGroupStoreProvider.java | 30 + .../ext/base/service/ServiceLicenseCheck.java | 34 + .../ext/base/service/ServiceOpenAction.java | 60 + .../ext/base/store/StorePauseAction.java | 14 +- .../ext/base/store/StoreStartAction.java | 14 +- .../xpipe/ext/base/store/StoreStopAction.java | 14 +- ext/base/src/main/java/module-info.java | 34 +- .../img/serviceGroup_icon-16-dark.png | Bin 0 -> 728 bytes .../resources/img/serviceGroup_icon-16.png | Bin 0 -> 729 bytes .../img/serviceGroup_icon-24-dark.png | Bin 0 -> 1237 bytes .../resources/img/serviceGroup_icon-24.png | Bin 0 -> 1250 bytes .../img/serviceGroup_icon-40-dark.png | Bin 0 -> 2216 bytes .../resources/img/serviceGroup_icon-40.png | Bin 0 -> 2242 bytes .../resources/img/serviceGroup_icon-dark.svg | 127 ++ .../base/resources/img/serviceGroup_icon.svg | 130 ++ .../resources/img/service_icon-16-dark.png | Bin 0 -> 861 bytes .../base/resources/img/service_icon-16.png | Bin 0 -> 861 bytes .../resources/img/service_icon-24-dark.png | Bin 0 -> 1359 bytes .../base/resources/img/service_icon-24.png | Bin 0 -> 1359 bytes .../resources/img/service_icon-40-dark.png | Bin 0 -> 2454 bytes .../base/resources/img/service_icon-40.png | Bin 0 -> 2454 bytes .../base/resources/img/service_icon-dark.svg | 100 ++ .../ext/base/resources/img/service_icon.svg | 100 ++ .../ext/base/resources/scripts/apt_update.sh | 1 + .../ext/base/resources/scripts/crlf_to_lf.sh | 8 + .../gradle_scripts/atlantafx-base-2.0.2.jar | Bin 0 -> 710112 bytes gradle/gradle_scripts/dev_default.properties | 3 + gradle/gradle_scripts/java.gradle | 2 +- .../gradle_scripts/local_junit_suite.gradle | 2 +- gradle/gradle_scripts/modules.gradle | 8 +- .../gradle_scripts/remote_junit_suite.gradle | 4 +- gradle/gradle_scripts/vernacular-1.16.jar | Bin 101276 -> 101280 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- lang/app/strings/translations_da.properties | 18 + lang/app/strings/translations_de.properties | 18 + lang/app/strings/translations_en.properties | 23 +- lang/app/strings/translations_es.properties | 18 + lang/app/strings/translations_fr.properties | 18 + lang/app/strings/translations_it.properties | 18 + lang/app/strings/translations_ja.properties | 18 + lang/app/strings/translations_nl.properties | 18 + lang/app/strings/translations_pt.properties | 18 + lang/app/strings/translations_ru.properties | 18 + lang/app/strings/translations_tr.properties | 18 + lang/app/strings/translations_zh.properties | 18 + lang/base/strings/translations_da.properties | 22 +- lang/base/strings/translations_de.properties | 22 +- lang/base/strings/translations_en.properties | 22 +- lang/base/strings/translations_es.properties | 22 +- lang/base/strings/translations_fr.properties | 22 +- lang/base/strings/translations_it.properties | 22 +- lang/base/strings/translations_ja.properties | 22 +- lang/base/strings/translations_nl.properties | 22 +- lang/base/strings/translations_pt.properties | 22 +- lang/base/strings/translations_ru.properties | 22 +- lang/base/strings/translations_tr.properties | 22 +- lang/base/strings/translations_zh.properties | 22 +- lang/base/texts/executionType_da.md | 51 +- lang/base/texts/executionType_de.md | 51 +- lang/base/texts/executionType_en.md | 51 +- lang/base/texts/executionType_es.md | 51 +- lang/base/texts/executionType_fr.md | 51 +- lang/base/texts/executionType_it.md | 51 +- lang/base/texts/executionType_ja.md | 51 +- lang/base/texts/executionType_nl.md | 51 +- lang/base/texts/executionType_pt.md | 51 +- lang/base/texts/executionType_ru.md | 51 +- lang/base/texts/executionType_tr.md | 51 +- lang/base/texts/executionType_zh.md | 51 +- lang/proc/strings/translations_da.properties | 10 + lang/proc/strings/translations_de.properties | 10 + lang/proc/strings/translations_en.properties | 12 +- lang/proc/strings/translations_es.properties | 10 + lang/proc/strings/translations_fr.properties | 10 + lang/proc/strings/translations_it.properties | 10 + lang/proc/strings/translations_ja.properties | 10 + lang/proc/strings/translations_nl.properties | 10 + lang/proc/strings/translations_pt.properties | 10 + lang/proc/strings/translations_ru.properties | 10 + lang/proc/strings/translations_tr.properties | 10 + lang/proc/strings/translations_zh.properties | 10 + openapi.yaml | 417 +++++ version | 2 +- 343 files changed, 9172 insertions(+), 4358 deletions(-) create mode 100644 app/src/main/java/io/xpipe/app/beacon/AppBeaconServer.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/BeaconRequestHandler.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/BeaconSession.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/BeaconShellSession.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/AskpassExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/ConnectionQueryExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/DaemonFocusExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/DaemonModeExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/DaemonOpenExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/DaemonStatusExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/DaemonStopExchangeImpl.java rename app/src/main/java/io/xpipe/app/{exchange/VersionExchangeImpl.java => beacon/impl/DaemonVersionExchangeImpl.java} (53%) create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/HandshakeExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/ShellExecExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/ShellStartExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/ShellStopExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/TerminalLaunchExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/beacon/impl/TerminalWaitExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/core/AppSocketServer.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/AskpassExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/FocusExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/LaunchExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpls.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/OpenExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/QueryStoreExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/TerminalLaunchExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/TerminalWaitExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/DrainExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/EditStoreExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/ListStoresExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/ModeExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/RemoveStoreExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/RenameStoreExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/SinkExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/StatusExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java delete mode 100644 app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java create mode 100644 app/src/main/java/io/xpipe/app/ext/DataStorageExtensionProvider.java create mode 100644 app/src/main/java/io/xpipe/app/ext/EnabledParentStoreProvider.java create mode 100644 app/src/main/java/io/xpipe/app/ext/EnabledStoreProvider.java create mode 100644 app/src/main/java/io/xpipe/app/fxcomps/util/LabelGraphic.java delete mode 100644 app/src/main/java/io/xpipe/app/launcher/LauncherConnection.java create mode 100644 app/src/main/java/io/xpipe/app/prefs/HttpApiCategory.java create mode 100644 app/src/main/java/io/xpipe/app/util/CommandViewBase.java create mode 100644 app/src/main/java/io/xpipe/app/util/LicenseConnectionLimit.java create mode 100644 app/src/main/resources/io/xpipe/app/resources/misc/api.md create mode 100644 app/src/main/resources/io/xpipe/app/resources/misc/github-dark.min.css rename app/src/main/resources/io/xpipe/app/resources/{web => misc}/github-markdown-dark.css (99%) rename app/src/main/resources/io/xpipe/app/resources/{web => misc}/github-markdown-light.css (99%) create mode 100644 app/src/main/resources/io/xpipe/app/resources/misc/highlight.min.js create mode 100644 app/src/main/resources/io/xpipe/app/resources/theme/mocha.css create mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconAuthMethod.java rename beacon/src/main/java/io/xpipe/beacon/{exchange/data/ClientErrorMessage.java => BeaconClientErrorResponse.java} (53%) create mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconClientException.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconClientInformation.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconConnection.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconConnectorException.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconException.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconFormat.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconInterface.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconServerErrorResponse.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/BeaconServerException.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/ClientException.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/ConnectorException.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/RequestMessage.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/ResponseMessage.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/ServerException.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/AskpassExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/ConnectionQueryExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/DaemonFocusExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/DaemonModeExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/DaemonOpenExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/DaemonStatusExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/DaemonStopExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/DaemonVersionExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/HandshakeExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/ShellExecExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/ShellStartExchange.java create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/ShellStopExchange.java rename beacon/src/main/java/io/xpipe/beacon/{exchange => api}/TerminalLaunchExchange.java (50%) create mode 100644 beacon/src/main/java/io/xpipe/beacon/api/TerminalWaitExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/AskpassExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/DrainExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/LaunchExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchanges.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/OpenExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/SinkExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/StopExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/TerminalWaitExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/DialogExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/EditStoreExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListCollectionsExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListEntriesExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListStoresExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/ReadDrainExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveCollectionExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveStoreExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameCollectionExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameStoreExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/StatusExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreAddExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreProviderListExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/cli/VersionExchange.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/CollectionListEntry.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/EntryListEntry.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/ProviderEntry.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/ServerErrorMessage.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/data/StoreListEntry.java delete mode 100644 beacon/src/main/java/io/xpipe/beacon/util/QuietDialogHandler.java create mode 100644 beacon/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader create mode 100644 core/src/main/java/io/xpipe/core/process/CommandFeedbackPredicate.java create mode 100644 core/src/main/java/io/xpipe/core/store/EnabledStoreState.java create mode 100644 core/src/main/java/io/xpipe/core/store/NetworkTunnelSession.java create mode 100644 core/src/main/java/io/xpipe/core/store/NetworkTunnelStore.java create mode 100644 core/src/main/java/io/xpipe/core/store/ServiceStore.java create mode 100644 core/src/main/java/io/xpipe/core/store/SessionChain.java create mode 100644 core/src/main/java/io/xpipe/core/store/SessionListener.java create mode 100644 core/src/main/java/io/xpipe/core/store/StorePath.java create mode 100644 core/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader create mode 100644 dist/changelogs/10.0.md create mode 100644 dist/changelogs/9.4.1.md create mode 100644 dist/changelogs/9.4.1_incremental.md delete mode 100644 dist/licenses/prettytime.license delete mode 100644 dist/licenses/prettytime.properties create mode 100644 dist/logo/hicolor/1024x1024/apps/xpipe.png create mode 100644 dist/logo/hicolor/128x128/apps/xpipe.png create mode 100644 dist/logo/hicolor/16x16/apps/xpipe.png create mode 100644 dist/logo/hicolor/256x256/apps/xpipe.png create mode 100644 dist/logo/hicolor/32x32/apps/xpipe.png create mode 100644 dist/logo/hicolor/48x48/apps/xpipe.png create mode 100644 dist/logo/hicolor/512x512/apps/xpipe.png create mode 100644 dist/logo/hicolor/64x64/apps/xpipe.png rename ext/base/src/main/java/io/xpipe/ext/base/action/{DeleteStoreChildrenAction.java => DeleteChildrenStoreAction.java} (86%) rename ext/base/src/main/java/io/xpipe/ext/base/action/{LaunchAction.java => LaunchStoreAction.java} (92%) rename ext/base/src/main/java/io/xpipe/ext/base/action/{RefreshStoreChildrenAction.java => RefreshChildrenStoreAction.java} (87%) rename ext/base/src/main/java/io/xpipe/ext/base/action/{SampleAction.java => SampleStoreAction.java} (94%) rename ext/base/src/main/java/io/xpipe/ext/base/action/{ScanAction.java => ScanStoreAction.java} (88%) create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptAction.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/script/ScriptDataStorageProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTargetType.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceCreatorStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStoreProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/ServiceCopyUrlAction.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStoreProvider.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/ServiceLicenseCheck.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-16-dark.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-16.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-24-dark.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-24.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-40-dark.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-40.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-dark.svg create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon.svg create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-16-dark.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-16.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-24-dark.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-24.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-40-dark.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-40.png create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-dark.svg create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon.svg create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/apt_update.sh create mode 100644 ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/crlf_to_lf.sh create mode 100644 gradle/gradle_scripts/atlantafx-base-2.0.2.jar create mode 100644 openapi.yaml diff --git a/app/build.gradle b/app/build.gradle index d2a337a18..b7788035e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,20 +45,20 @@ dependencies { api 'com.vladsch.flexmark:flexmark-ext-footnotes:0.64.8' api 'com.vladsch.flexmark:flexmark-ext-definition:0.64.8' api 'com.vladsch.flexmark:flexmark-ext-anchorlink:0.64.8' + api 'com.vladsch.flexmark:flexmark-ext-yaml-front-matter:0.64.8' + api 'com.vladsch.flexmark:flexmark-ext-toc:0.64.8' api files("$rootDir/gradle/gradle_scripts/markdowngenerator-1.3.1.1.jar") api files("$rootDir/gradle/gradle_scripts/vernacular-1.16.jar") - api 'info.picocli:picocli:4.7.5' + api 'info.picocli:picocli:4.7.6' api ('org.kohsuke:github-api:1.321') { exclude group: 'org.apache.commons', module: 'commons-lang3' } api 'org.apache.commons:commons-lang3:3.14.0' - api 'io.sentry:sentry:7.8.0' + api 'io.sentry:sentry:7.10.0' api 'commons-io:commons-io:2.16.1' api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.17.1" - api group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: "2.17.1" api group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: "2.17.1" - api group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: "2.17.1" api group: 'org.kordamp.ikonli', name: 'ikonli-material2-pack', version: "12.2.0" api group: 'org.kordamp.ikonli', name: 'ikonli-materialdesign2-pack', version: "12.2.0" api group: 'org.kordamp.ikonli', name: 'ikonli-javafx', version: "12.2.0" @@ -68,10 +68,7 @@ dependencies { api group: 'org.slf4j', name: 'slf4j-jdk-platform-logging', version: '2.0.13' api 'io.xpipe:modulefs:0.1.5' api 'net.synedra:validatorfx:0.4.2' - api ('io.github.mkpaz:atlantafx-base:2.0.1') { - exclude group: 'org.openjfx', module: 'javafx-base' - exclude group: 'org.openjfx', module: 'javafx-controls' - } + api files("$rootDir/gradle/gradle_scripts/atlantafx-base-2.0.2.jar") } apply from: "$rootDir/gradle/gradle_scripts/local_junit_suite.gradle" @@ -96,9 +93,6 @@ run { systemProperty 'io.xpipe.app.logLevel', "trace" systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion systemProperty 'io.xpipe.app.staging', isStage - // systemProperty "io.xpipe.beacon.port", "21724" - // systemProperty "io.xpipe.beacon.printMessages", "true" - // systemProperty 'io.xpipe.app.debugPlatform', "true" // Apply passed xpipe properties for (final def e in System.getProperties().entrySet()) { @@ -153,6 +147,13 @@ processResources { into resourcesDir } } + + doLast { + copy { + from file("$rootDir/openapi.yaml") + into file("${sourceSets.main.output.resourcesDir}/io/xpipe/app/resources/misc"); + } + } } distTar { diff --git a/app/src/main/java/io/xpipe/app/beacon/AppBeaconServer.java b/app/src/main/java/io/xpipe/app/beacon/AppBeaconServer.java new file mode 100644 index 000000000..68fcc7fd6 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/AppBeaconServer.java @@ -0,0 +1,174 @@ +package io.xpipe.app.beacon; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; +import io.xpipe.app.core.AppResources; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.util.MarkdownHelper; +import io.xpipe.beacon.BeaconConfig; +import io.xpipe.beacon.BeaconInterface; +import io.xpipe.core.util.XPipeInstallation; +import lombok.Getter; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.*; +import java.util.concurrent.Executors; + +public class AppBeaconServer { + + private static AppBeaconServer INSTANCE; + @Getter + private final int port; + @Getter + private final boolean propertyPort; + private boolean running; + private HttpServer server; + @Getter + private final Set sessions = new HashSet<>(); + @Getter + private final Set shellSessions = new HashSet<>(); + @Getter + private String localAuthSecret; + + private String notFoundHtml; + private final Map resources = new HashMap<>(); + + static { + int port; + boolean propertyPort; + if (System.getProperty(BeaconConfig.BEACON_PORT_PROP) != null) { + port = BeaconConfig.getUsedPort(); + propertyPort = true; + } else { + port = AppPrefs.get().httpServerPort().getValue(); + propertyPort = false; + } + INSTANCE = new AppBeaconServer(port, propertyPort); + } + + private AppBeaconServer(int port, boolean propertyPort) { + this.port = port; + this.propertyPort = propertyPort; + } + + public static void init() { + try { + INSTANCE.initAuthSecret(); + INSTANCE.start(); + TrackEvent.withInfo("Started http server") + .tag("port", INSTANCE.getPort()) + .build() + .handle(); + } catch (Exception ex) { + // Not terminal! + // We can still continue without the running server + ErrorEvent.fromThrowable("Unable to start local http server on port " + INSTANCE.getPort(), ex) + .build() + .handle(); + } + } + + public static void reset() { + if (INSTANCE != null) { + INSTANCE.stop(); + INSTANCE = null; + } + } + + public void addSession(BeaconSession session) { + this.sessions.add(session); + } + + public static AppBeaconServer get() { + return INSTANCE; + } + + private void stop() { + if (!running) { + return; + } + + running = false; + server.stop(1); + } + + private void initAuthSecret() throws IOException { + var file = XPipeInstallation.getLocalBeaconAuthFile(); + var id = UUID.randomUUID().toString(); + Files.writeString(file, id); + localAuthSecret = id; + } + + private void start() throws IOException { + server = HttpServer.create(new InetSocketAddress("localhost", port), 10); + BeaconInterface.getAll().forEach(beaconInterface -> { + server.createContext(beaconInterface.getPath(), new BeaconRequestHandler<>(beaconInterface)); + }); + server.setExecutor(Executors.newSingleThreadExecutor(r -> { + Thread t = Executors.defaultThreadFactory().newThread(r); + t.setName("http handler"); + t.setUncaughtExceptionHandler((t1, e) -> { + ErrorEvent.fromThrowable(e).handle(); + }); + return t; + })); + + var resourceMap = Map.of( + "openapi.yaml", "misc/openapi.yaml", + "markdown.css", "misc/github-markdown-dark.css", + "highlight.min.js", "misc/highlight.min.js", + "github-dark.min.css", "misc/github-dark.min.css" + ); + resourceMap.forEach((s, s2) -> { + server.createContext("/" + s, exchange -> { + handleResource(exchange, s2); + }); + }); + + server.createContext("/", exchange -> { + handleCatchAll(exchange); + }); + + server.start(); + running = true; + } + + private void handleResource(HttpExchange exchange, String resource) throws IOException { + if (!resources.containsKey(resource)) { + AppResources.with(AppResources.XPIPE_MODULE, resource, file -> { + resources.put(resource, Files.readString(file)); + }); + } + var body = resources.get(resource).getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(200,body.length); + try (var out = exchange.getResponseBody()) { + out.write(body); + } + } + + private void handleCatchAll(HttpExchange exchange) throws IOException { + if (notFoundHtml == null) { + AppResources.with(AppResources.XPIPE_MODULE, "misc/api.md", file -> { + notFoundHtml = MarkdownHelper.toHtml(Files.readString(file), head -> { + return head + "\n" + + "" + "\n" + + "" + "\n" + + "" + "\n" + + ""; + }, s -> { + return "
" + s + "
"; + }); + }); + } + var body = notFoundHtml.getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(200,body.length); + try (var out = exchange.getResponseBody()) { + out.write(body); + } + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/BeaconRequestHandler.java b/app/src/main/java/io/xpipe/app/beacon/BeaconRequestHandler.java new file mode 100644 index 000000000..ce713fe73 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/BeaconRequestHandler.java @@ -0,0 +1,124 @@ +package io.xpipe.app.beacon; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.issue.TrackEvent; +import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.beacon.*; +import io.xpipe.core.util.JacksonMapper; +import lombok.SneakyThrows; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +public class BeaconRequestHandler implements HttpHandler { + + private final BeaconInterface beaconInterface; + + public BeaconRequestHandler(BeaconInterface beaconInterface) {this.beaconInterface = beaconInterface;} + + @Override + public void handle(HttpExchange exchange) throws IOException { + if (!AppPrefs.get().disableApiAuthentication().get() && beaconInterface.requiresAuthentication()) { + var auth = exchange.getRequestHeaders().getFirst("Authorization"); + if (auth == null) { + writeError(exchange, new BeaconClientErrorResponse("Missing Authorization header"), 401); + return; + } + + var token = auth.replace("Bearer ", ""); + var session = AppBeaconServer.get().getSessions().stream().filter(s -> s.getToken().equals(token)).findFirst().orElse(null); + if (session == null) { + writeError(exchange, new BeaconClientErrorResponse("Unknown token"), 403); + return; + } + } + + handleAuthenticatedRequest(exchange); + } + + private void handleAuthenticatedRequest(HttpExchange exchange) { + T object; + Object response; + try { + try (InputStream is = exchange.getRequestBody()) { + var tree = JacksonMapper.getDefault().readTree(is); + TrackEvent.trace("Parsed raw request:\n" + tree.toPrettyString()); + var emptyRequestClass = tree.isEmpty() && beaconInterface.getRequestClass().getDeclaredFields().length == 0; + object = emptyRequestClass ? createDefaultRequest(beaconInterface) : JacksonMapper.getDefault().treeToValue(tree, beaconInterface.getRequestClass()); + TrackEvent.trace("Parsed request object:\n" + object); + } + response = beaconInterface.handle(exchange, object); + } catch (BeaconClientException clientException) { + ErrorEvent.fromThrowable(clientException).omit().expected().handle(); + writeError(exchange, new BeaconClientErrorResponse(clientException.getMessage()), 400); + return; + } catch (BeaconServerException serverException) { + var cause = serverException.getCause() != null ? serverException.getCause() : serverException; + ErrorEvent.fromThrowable(cause).handle(); + writeError(exchange, new BeaconServerErrorResponse(cause), 500); + return; + } catch (IOException ex) { + // Handle serialization errors as normal exceptions and other IO exceptions as assuming that the connection is broken + if (!ex.getClass().getName().contains("jackson")) { + ErrorEvent.fromThrowable(ex).omit().expected().handle(); + } else { + ErrorEvent.fromThrowable(ex).omit().expected().handle(); + writeError(exchange, new BeaconClientErrorResponse(ex.getMessage()), 400); + } + return; + } catch (Throwable other) { + ErrorEvent.fromThrowable(other).handle(); + writeError(exchange, new BeaconServerErrorResponse(other), 500); + return; + } + + try { + var emptyResponseClass = beaconInterface.getResponseClass().getDeclaredFields().length == 0; + if (!emptyResponseClass && response != null) { + TrackEvent.trace("Sending response:\n" + object); + var tree = JacksonMapper.getDefault().valueToTree(response); + TrackEvent.trace("Sending raw response:\n" + tree.toPrettyString()); + var bytes = tree.toPrettyString().getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(200, bytes.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(bytes); + } + } else { + exchange.sendResponseHeaders(200, -1); + } + } catch (IOException ioException) { + ErrorEvent.fromThrowable(ioException).omit().expected().handle(); + } catch (Throwable other) { + ErrorEvent.fromThrowable(other).handle(); + writeError(exchange, new BeaconServerErrorResponse(other), 500); + return; + } + } + + private void writeError(HttpExchange exchange, Object errorMessage, int code) { + try { + var bytes = JacksonMapper.getDefault().writeValueAsString(errorMessage).getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(code, bytes.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(bytes); + } + } catch (IOException ex) { + ErrorEvent.fromThrowable(ex).omit().expected().handle(); + } + } + + @SneakyThrows + @SuppressWarnings("unchecked") + private REQ createDefaultRequest(BeaconInterface beaconInterface) { + var c = beaconInterface.getRequestClass().getDeclaredMethod("builder"); + c.setAccessible(true); + var b = c.invoke(null); + var m = b.getClass().getDeclaredMethod("build"); + m.setAccessible(true); + return (REQ) beaconInterface.getRequestClass().cast(m.invoke(b)); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/BeaconSession.java b/app/src/main/java/io/xpipe/app/beacon/BeaconSession.java new file mode 100644 index 000000000..38cec0f23 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/BeaconSession.java @@ -0,0 +1,11 @@ +package io.xpipe.app.beacon; + +import io.xpipe.beacon.BeaconClientInformation; +import lombok.Value; + +@Value +public class BeaconSession { + + BeaconClientInformation clientInformation; + String token; +} diff --git a/app/src/main/java/io/xpipe/app/beacon/BeaconShellSession.java b/app/src/main/java/io/xpipe/app/beacon/BeaconShellSession.java new file mode 100644 index 000000000..a92415a7a --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/BeaconShellSession.java @@ -0,0 +1,12 @@ +package io.xpipe.app.beacon; + +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.core.process.ShellControl; +import lombok.Value; + +@Value +public class BeaconShellSession { + + DataStoreEntry entry; + ShellControl control; +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/AskpassExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/AskpassExchangeImpl.java new file mode 100644 index 000000000..e3fa224b5 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/AskpassExchangeImpl.java @@ -0,0 +1,34 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.util.AskpassAlert; +import io.xpipe.app.util.SecretManager; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.AskpassExchange; + +import java.io.IOException; + +public class AskpassExchangeImpl extends AskpassExchange { + + @Override + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + if (msg.getRequest() == null) { + var r = AskpassAlert.queryRaw(msg.getPrompt(), null); + return Response.builder().value(r.getSecret()).build(); + } + + var found = msg.getSecretId() != null + ? SecretManager.getProgress(msg.getRequest(), msg.getSecretId()) + : SecretManager.getProgress(msg.getRequest()); + if (found.isEmpty()) { + return Response.builder().build(); + } + + var p = found.get(); + var secret = p.process(msg.getPrompt()); + return Response.builder() + .value(secret != null ? secret.inPlace() : null) + .build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionQueryExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionQueryExchangeImpl.java new file mode 100644 index 000000000..2fca86f76 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionQueryExchangeImpl.java @@ -0,0 +1,148 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.ConnectionQueryExchange; +import io.xpipe.core.store.StorePath; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class ConnectionQueryExchangeImpl extends ConnectionQueryExchange { + + @Override + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + var catMatcher = Pattern.compile(toRegex("all connections/" + msg.getCategoryFilter())); + var conMatcher = Pattern.compile(toRegex(msg.getConnectionFilter())); + + List found = new ArrayList<>(); + for (DataStoreEntry storeEntry : DataStorage.get().getStoreEntries()) { + if (!storeEntry.getValidity().isUsable()) { + continue; + } + + var name = DataStorage.get().getStorePath(storeEntry).toString(); + if (!conMatcher.matcher(name).matches()) { + continue; + } + + var cat = DataStorage.get().getStoreCategoryIfPresent(storeEntry.getCategoryUuid()).orElse(null); + if (cat == null) { + continue; + } + + var c = DataStorage.get().getStorePath(cat).toString(); + if (!catMatcher.matcher(c).matches()) { + continue; + } + + found.add(storeEntry); + } + + var mapped = new ArrayList(); + for (DataStoreEntry e : found) { + var names = DataStorage.get().getStorePath(DataStorage.get().getStoreCategoryIfPresent(e.getCategoryUuid()).orElseThrow()).getNames(); + var cat = new StorePath(names.subList(1, names.size())); + var obj = ConnectionQueryExchange.QueryResponse.builder() + .uuid(e.getUuid()).category(cat).connection(DataStorage.get() + .getStorePath(e)).type(e.getProvider().getId()).build(); + mapped.add(obj); + } + return Response.builder().found(mapped).build(); + } + + private String toRegex(String pattern) { + // https://stackoverflow.com/a/17369948/6477761 + StringBuilder sb = new StringBuilder(pattern.length()); + int inGroup = 0; + int inClass = 0; + int firstIndexInClass = -1; + char[] arr = pattern.toCharArray(); + for (int i = 0; i < arr.length; i++) { + char ch = arr[i]; + switch (ch) { + case '\\': + if (++i >= arr.length) { + sb.append('\\'); + } else { + char next = arr[i]; + switch (next) { + case ',': + // escape not needed + break; + case 'Q': + case 'E': + // extra escape needed + sb.append('\\'); + default: + sb.append('\\'); + } + sb.append(next); + } + break; + case '*': + if (inClass == 0) + sb.append(".*"); + else + sb.append('*'); + break; + case '?': + if (inClass == 0) + sb.append('.'); + else + sb.append('?'); + break; + case '[': + inClass++; + firstIndexInClass = i+1; + sb.append('['); + break; + case ']': + inClass--; + sb.append(']'); + break; + case '.': + case '(': + case ')': + case '+': + case '|': + case '^': + case '$': + case '@': + case '%': + if (inClass == 0 || (firstIndexInClass == i && ch == '^')) + sb.append('\\'); + sb.append(ch); + break; + case '!': + if (firstIndexInClass == i) + sb.append('^'); + else + sb.append('!'); + break; + case '{': + inGroup++; + sb.append('('); + break; + case '}': + inGroup--; + sb.append(')'); + break; + case ',': + if (inGroup > 0) + sb.append('|'); + else + sb.append(','); + break; + default: + sb.append(ch); + } + } + return sb.toString(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/DaemonFocusExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonFocusExchangeImpl.java new file mode 100644 index 000000000..1a25af89e --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonFocusExchangeImpl.java @@ -0,0 +1,20 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.DaemonFocusExchange; + +import java.io.IOException; + +public class DaemonFocusExchangeImpl extends DaemonFocusExchange { + + +@Override +public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + + OperationMode.switchUp(OperationMode.map(msg.getMode())); + return Response.builder().build(); +} +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/DaemonModeExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonModeExchangeImpl.java new file mode 100644 index 000000000..ab7de9958 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonModeExchangeImpl.java @@ -0,0 +1,36 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.app.util.ThreadHelper; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.DaemonModeExchange; + +import java.io.IOException; + +public class DaemonModeExchangeImpl extends DaemonModeExchange { + @Override + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + // Wait for startup + while (OperationMode.get() == null) { + ThreadHelper.sleep(100); + } + + var mode = OperationMode.map(msg.getMode()); + if (!mode.isSupported()) { + throw new BeaconClientException("Unsupported mode: " + msg.getMode().getDisplayName() + ". Supported: " + + String.join( + ", ", + OperationMode.getAll().stream() + .filter(OperationMode::isSupported) + .map(OperationMode::getId) + .toList())); + } + + OperationMode.switchToSyncIfPossible(mode); + return DaemonModeExchange.Response.builder() + .usedMode(OperationMode.map(OperationMode.get())) + .build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/DaemonOpenExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonOpenExchangeImpl.java new file mode 100644 index 000000000..8a89878ec --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonOpenExchangeImpl.java @@ -0,0 +1,25 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.app.launcher.LauncherInput; +import io.xpipe.app.util.PlatformState; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.DaemonOpenExchange; + +import java.io.IOException; + +public class DaemonOpenExchangeImpl extends DaemonOpenExchange { + @Override + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + if (msg.getArguments().isEmpty()) { + if (!OperationMode.switchToSyncIfPossible(OperationMode.GUI)) { + throw new BeaconServerException(PlatformState.getLastError()); + } + } + + LauncherInput.handle(msg.getArguments()); + return Response.builder().build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/DaemonStatusExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonStatusExchangeImpl.java new file mode 100644 index 000000000..77eadf156 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonStatusExchangeImpl.java @@ -0,0 +1,25 @@ +package io.xpipe.app.beacon.impl; + + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.DaemonStatusExchange; + +import java.io.IOException; + +public class DaemonStatusExchangeImpl extends DaemonStatusExchange { + + @Override + public Object handle(HttpExchange exchange, Request body) throws IOException, BeaconClientException, BeaconServerException { + String mode; + if (OperationMode.get() == null) { + mode = "none"; + } else { + mode = OperationMode.get().getId(); + } + + return Response.builder().mode(mode).build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/DaemonStopExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonStopExchangeImpl.java new file mode 100644 index 000000000..0189350c2 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonStopExchangeImpl.java @@ -0,0 +1,22 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.core.mode.OperationMode; +import io.xpipe.app.util.ThreadHelper; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.DaemonStopExchange; + +import java.io.IOException; + +public class DaemonStopExchangeImpl extends DaemonStopExchange { + + @Override + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + ThreadHelper.runAsync(() -> { + ThreadHelper.sleep(1000); + OperationMode.close(); + }); + return Response.builder().success(true).build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/exchange/VersionExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonVersionExchangeImpl.java similarity index 53% rename from app/src/main/java/io/xpipe/app/exchange/VersionExchangeImpl.java rename to app/src/main/java/io/xpipe/app/beacon/impl/DaemonVersionExchangeImpl.java index 9115b06f8..f6ba986c4 100644 --- a/app/src/main/java/io/xpipe/app/exchange/VersionExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/beacon/impl/DaemonVersionExchangeImpl.java @@ -1,14 +1,17 @@ -package io.xpipe.app.exchange; +package io.xpipe.app.beacon.impl; +import com.sun.net.httpserver.HttpExchange; import io.xpipe.app.core.AppProperties; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.cli.VersionExchange; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.DaemonVersionExchange; -public class VersionExchangeImpl extends VersionExchange - implements MessageExchangeImpl { +import java.io.IOException; + +public class DaemonVersionExchangeImpl extends DaemonVersionExchange { @Override - public Response handleRequest(BeaconHandler handler, Request msg) { + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { var jvmVersion = System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.version") + ")"; diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/HandshakeExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/HandshakeExchangeImpl.java new file mode 100644 index 000000000..2e10a773c --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/HandshakeExchangeImpl.java @@ -0,0 +1,42 @@ +package io.xpipe.app.beacon.impl; + + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.beacon.AppBeaconServer; +import io.xpipe.app.beacon.BeaconSession; +import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.beacon.BeaconAuthMethod; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.HandshakeExchange; + +import java.io.IOException; +import java.util.UUID; + +public class HandshakeExchangeImpl extends HandshakeExchange { + + @Override + public Object handle(HttpExchange exchange, Request body) throws IOException, BeaconClientException, BeaconServerException { + if (!checkAuth(body.getAuth())) { + throw new BeaconClientException("Authentication failed"); + } + + var session = new BeaconSession(body.getClient(), UUID.randomUUID().toString()); + AppBeaconServer.get().addSession(session); + return Response.builder().sessionToken(session.getToken()).build(); + } + + private boolean checkAuth(BeaconAuthMethod authMethod) { + if (authMethod instanceof BeaconAuthMethod.Local local) { + var c = local.getAuthFileContent().trim(); + return AppBeaconServer.get().getLocalAuthSecret().equals(c); + } + + if (authMethod instanceof BeaconAuthMethod.ApiKey key) { + var c = key.getKey().trim(); + return AppPrefs.get().apiKey().get().equals(c); + } + + return false; + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/ShellExecExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/ShellExecExchangeImpl.java new file mode 100644 index 000000000..ad72fed64 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/ShellExecExchangeImpl.java @@ -0,0 +1,35 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.beacon.AppBeaconServer; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.ShellExecExchange; +import lombok.SneakyThrows; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicReference; + +public class ShellExecExchangeImpl extends ShellExecExchange { + + @Override + @SneakyThrows + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + var e = DataStorage.get().getStoreEntryIfPresent(msg.getConnection()).orElseThrow(() -> new IllegalArgumentException("Unknown connection")); + var existing = AppBeaconServer.get().getShellSessions().stream().filter(beaconShellSession -> beaconShellSession.getEntry().equals(e)).findFirst(); + if (existing.isEmpty()) { + throw new BeaconClientException("No shell session active for connection"); + } + + AtomicReference out = new AtomicReference<>(); + AtomicReference err = new AtomicReference<>(); + long exitCode; + try (var command = existing.get().getControl().command(msg.getCommand()).start()) { + command.accumulateStdout(s -> out.set(s)); + command.accumulateStderr(s -> err.set(s)); + exitCode = command.getExitCode(); + } + return Response.builder().stdout(out.get()).stderr(err.get()).exitCode(exitCode).build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/ShellStartExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/ShellStartExchangeImpl.java new file mode 100644 index 000000000..085b8e714 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/ShellStartExchangeImpl.java @@ -0,0 +1,34 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.beacon.AppBeaconServer; +import io.xpipe.app.beacon.BeaconShellSession; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.ShellStartExchange; +import io.xpipe.core.store.ShellStore; +import lombok.SneakyThrows; + +import java.io.IOException; + +public class ShellStartExchangeImpl extends ShellStartExchange { + + @Override + @SneakyThrows + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + var e = DataStorage.get().getStoreEntryIfPresent(msg.getConnection()).orElseThrow(() -> new IllegalArgumentException("Unknown connection")); + if (!(e.getStore() instanceof ShellStore s)) { + throw new BeaconClientException("Not a shell connection"); + } + + var existing = AppBeaconServer.get().getShellSessions().stream().filter(beaconShellSession -> beaconShellSession.getEntry().equals(e)).findFirst(); + if (existing.isPresent()) { + return Response.builder().build(); + } + + var control = s.control().start(); + AppBeaconServer.get().getShellSessions().add(new BeaconShellSession(e, control)); + return Response.builder().build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/ShellStopExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/ShellStopExchangeImpl.java new file mode 100644 index 000000000..07f07eb8d --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/ShellStopExchangeImpl.java @@ -0,0 +1,26 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.beacon.AppBeaconServer; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.ShellStopExchange; +import lombok.SneakyThrows; + +import java.io.IOException; + +public class ShellStopExchangeImpl extends ShellStopExchange { + + @Override + @SneakyThrows + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + var e = DataStorage.get().getStoreEntryIfPresent(msg.getConnection()).orElseThrow(() -> new IllegalArgumentException("Unknown connection")); + var existing = AppBeaconServer.get().getShellSessions().stream().filter(beaconShellSession -> beaconShellSession.getEntry().equals(e)).findFirst(); + if (existing.isPresent()) { + existing.get().getControl().close(); + AppBeaconServer.get().getShellSessions().remove(existing.get()); + } + return Response.builder().build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/TerminalLaunchExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/TerminalLaunchExchangeImpl.java new file mode 100644 index 000000000..097486bcc --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/TerminalLaunchExchangeImpl.java @@ -0,0 +1,17 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.util.TerminalLauncherManager; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.TerminalLaunchExchange; + +import java.io.IOException; + +public class TerminalLaunchExchangeImpl extends TerminalLaunchExchange { + @Override + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + var r = TerminalLauncherManager.performLaunch(msg.getRequest()); + return Response.builder().targetFile(r).build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/TerminalWaitExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/TerminalWaitExchangeImpl.java new file mode 100644 index 000000000..2114dacbd --- /dev/null +++ b/app/src/main/java/io/xpipe/app/beacon/impl/TerminalWaitExchangeImpl.java @@ -0,0 +1,17 @@ +package io.xpipe.app.beacon.impl; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.app.util.TerminalLauncherManager; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; +import io.xpipe.beacon.api.TerminalWaitExchange; + +import java.io.IOException; + +public class TerminalWaitExchangeImpl extends TerminalWaitExchange { + @Override + public Object handle(HttpExchange exchange, Request msg) throws IOException, BeaconClientException, BeaconServerException { + TerminalLauncherManager.waitForCompletion(msg.getRequest()); + return Response.builder().build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java index 988b8e557..553aae3d0 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserTransferComp.java @@ -10,7 +10,6 @@ import io.xpipe.app.fxcomps.augment.DragOverPseudoClassAugment; import io.xpipe.app.fxcomps.impl.*; import io.xpipe.app.fxcomps.util.DerivedObservableList; import io.xpipe.app.fxcomps.util.PlatformThread; -import io.xpipe.core.process.OsType; import javafx.beans.binding.Bindings; import javafx.collections.FXCollections; import javafx.geometry.Insets; @@ -183,13 +182,7 @@ public class BrowserTransferComp extends SimpleComp { event.consume(); }); struc.get().setOnDragDone(event -> { - // macOS does always report false here, which is unfortunate - if (!event.isAccepted() && !OsType.getLocal().equals(OsType.MACOS)) { - return; - } - - // Don't clear, it might be more convenient to keep the contents - // model.clear(); + model.clear(); event.consume(); }); }), diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserEntry.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserEntry.java index bcc4e9404..d8e617992 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserEntry.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserEntry.java @@ -27,8 +27,9 @@ public class BrowserEntry { if (rawFileEntry == null) { return null; } + rawFileEntry = rawFileEntry.resolved(); - if (rawFileEntry.getKind() == FileKind.DIRECTORY) { + if (rawFileEntry.getKind() != FileKind.FILE) { return null; } @@ -45,6 +46,7 @@ public class BrowserEntry { if (rawFileEntry == null) { return null; } + rawFileEntry = rawFileEntry.resolved(); if (rawFileEntry.getKind() != FileKind.DIRECTORY) { return null; @@ -58,13 +60,14 @@ public class BrowserEntry { return null; } + public String getIcon() { if (fileType != null) { return fileType.getIcon(); } else if (directoryType != null) { return directoryType.getIcon(rawFileEntry, false); } else { - return rawFileEntry.getKind() == FileKind.DIRECTORY + return rawFileEntry != null && rawFileEntry.resolved().getKind() == FileKind.DIRECTORY ? "default_folder.svg" : "default_file.svg"; } diff --git a/app/src/main/java/io/xpipe/app/browser/file/LocalFileSystem.java b/app/src/main/java/io/xpipe/app/browser/file/LocalFileSystem.java index 2fe56c18e..50650aadd 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/LocalFileSystem.java +++ b/app/src/main/java/io/xpipe/app/browser/file/LocalFileSystem.java @@ -4,7 +4,6 @@ import io.xpipe.core.store.FileKind; import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.LocalStore; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -19,13 +18,13 @@ public class LocalFileSystem { } } - public static FileSystem.FileEntry getLocalFileEntry(Path file) throws IOException { + public static FileSystem.FileEntry getLocalFileEntry(Path file) throws Exception { if (localFileSystem == null) { throw new IllegalStateException(); } return new FileSystem.FileEntry( - localFileSystem, + localFileSystem.open(), file.toString(), Files.getLastModifiedTime(file).toInstant(), Files.isHidden(file), diff --git a/app/src/main/java/io/xpipe/app/browser/session/BrowserSessionTab.java b/app/src/main/java/io/xpipe/app/browser/session/BrowserSessionTab.java index f6c07d05b..64414f537 100644 --- a/app/src/main/java/io/xpipe/app/browser/session/BrowserSessionTab.java +++ b/app/src/main/java/io/xpipe/app/browser/session/BrowserSessionTab.java @@ -23,7 +23,7 @@ public abstract class BrowserSessionTab { this.browserModel = browserModel; this.entry = entry; this.name = DataStorage.get().getStoreDisplayName(entry.get()); - this.tooltip = DataStorage.get().getId(entry.getEntry()).toString(); + this.tooltip = DataStorage.get().getStorePath(entry.getEntry()).toString(); } public abstract Comp comp(); diff --git a/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java b/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java index 997869629..b64fcac05 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ListBoxViewComp.java @@ -13,6 +13,7 @@ import javafx.scene.control.ScrollPane; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; +import java.util.ArrayList; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -67,7 +68,9 @@ public class ListBoxViewComp extends Comp> { // Clear cache of unused values cache.keySet().removeIf(t -> !all.contains(t)); - var newShown = shown.stream() + // Create copy to reduce chances of concurrent modification + var shownCopy = new ArrayList<>(shown); + var newShown = shownCopy.stream() .map(v -> { if (!cache.containsKey(v)) { var comp = compFunction.apply(v); @@ -80,6 +83,10 @@ public class ListBoxViewComp extends Comp> { .limit(limit) .toList(); + if (listView.getChildren().equals(newShown)) { + return; + } + for (int i = 0; i < newShown.size(); i++) { var r = newShown.get(i); r.pseudoClassStateChanged(ODD, false); @@ -87,10 +94,8 @@ public class ListBoxViewComp extends Comp> { r.pseudoClassStateChanged(i % 2 == 0 ? EVEN : ODD, true); } - if (!listView.getChildren().equals(newShown)) { - var d = new DerivedObservableList<>(listView.getChildren(), true); - d.setContent(newShown); - } + var d = new DerivedObservableList<>(listView.getChildren(), true); + d.setContent(newShown); }; if (asynchronous) { diff --git a/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java b/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java index f8469ba8f..83e6ac940 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/MarkdownComp.java @@ -42,7 +42,7 @@ public class MarkdownComp extends Comp> { } private String getHtml() { - return MarkdownHelper.toHtml(markdown.getValue(), htmlTransformation); + return MarkdownHelper.toHtml(markdown.getValue(), s -> s, htmlTransformation); } @SneakyThrows @@ -55,8 +55,8 @@ public class MarkdownComp extends Comp> { AppProperties.get().getDataDir().resolve("webview").toFile()); wv.setPageFill(Color.TRANSPARENT); var theme = AppPrefs.get() != null && AppPrefs.get().theme.getValue().isDark() - ? "web/github-markdown-dark.css" - : "web/github-markdown-light.css"; + ? "misc/github-markdown-dark.css" + : "misc/github-markdown-light.css"; var url = AppResources.getResourceURL(AppResources.XPIPE_MODULE, theme).orElseThrow(); wv.getEngine().setUserStyleSheetLocation(url.toString()); diff --git a/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java b/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java index d7090c609..abc5f00fd 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java @@ -9,6 +9,7 @@ import io.xpipe.app.fxcomps.augment.Augment; import io.xpipe.app.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.impl.TooltipAugment; import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.update.UpdateAvailableAlert; import io.xpipe.app.update.XPipeDistributionType; import io.xpipe.app.util.Hyperlinks; @@ -147,9 +148,8 @@ public class SideMenuBarComp extends Comp> { } { - var shortcut = new KeyCodeCombination(KeyCode.values()[KeyCode.DIGIT1.ordinal() + entries.size() + 2]); var b = new IconButtonComp("mdi2t-translate", () -> Hyperlinks.open(Hyperlinks.TRANSLATE)) - .tooltipKey("translate", shortcut) + .tooltipKey("translate") .apply(simpleBorders) .accessibleTextKey("translate"); b.apply(struc -> { @@ -158,6 +158,17 @@ public class SideMenuBarComp extends Comp> { vbox.getChildren().add(b.createRegion()); } + { + var b = new IconButtonComp("mdi2c-code-json", () -> Hyperlinks.open("http://localhost:" + AppPrefs.get().httpServerPort().getValue())) + .tooltipKey("api") + .apply(simpleBorders) + .accessibleTextKey("api"); + b.apply(struc -> { + AppFont.setSize(struc.get(), 2); + }); + vbox.getChildren().add(b.createRegion()); + } + { var b = new IconButtonComp("mdi2u-update", () -> UpdateAvailableAlert.showIfNeeded()) .tooltipKey("updateAvailableTooltip") diff --git a/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java b/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java index e765e784a..210920b8c 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java @@ -1,18 +1,19 @@ package io.xpipe.app.comp.base; import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.store.DataStore; - +import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.value.ObservableBooleanValue; +import javafx.beans.value.ObservableValue; import javafx.scene.layout.Region; - import lombok.AllArgsConstructor; import lombok.Setter; @@ -24,17 +25,19 @@ import java.util.function.Function; public class StoreToggleComp extends SimpleComp { private final String nameKey; + private final ObservableValue graphic; private final StoreSection section; private final BooleanProperty value; private final Consumer onChange; @Setter - private ObservableBooleanValue customVisibility = new SimpleBooleanProperty(true); + private ObservableValue customVisibility = new SimpleBooleanProperty(true); public static StoreToggleComp simpleToggle( - String nameKey, StoreSection section, Function initial, BiConsumer setter) { + String nameKey, ObservableValue graphic, StoreSection section, Function initial, BiConsumer setter) { return new StoreToggleComp( nameKey, + graphic, section, new SimpleBooleanProperty( initial.apply(section.getWrapper().getEntry().getStore().asNeeded())), @@ -43,27 +46,57 @@ public class StoreToggleComp extends SimpleComp { }); } + public static StoreToggleComp enableToggle( + String nameKey, StoreSection section, Function initial, BiConsumer setter) { + var val = new SimpleBooleanProperty(); + ObservableValue g = val.map(aBoolean -> aBoolean ? + new LabelGraphic.IconGraphic("mdi2c-circle-slice-8") : new LabelGraphic.IconGraphic("mdi2p-power")); + var t = new StoreToggleComp( + nameKey, + g, + section, + new SimpleBooleanProperty( + initial.apply(section.getWrapper().getEntry().getStore().asNeeded())), + v -> { + setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v); + }); + t.tooltipKey("enabled"); + t.value.subscribe((newValue) -> { + val.set(newValue); + }); + return t; + } + public static StoreToggleComp childrenToggle( - String nameKey, StoreSection section, Function initial, BiConsumer setter) { - return new StoreToggleComp( - nameKey, - section, - new SimpleBooleanProperty( - initial.apply(section.getWrapper().getEntry().getStore().asNeeded())), - v -> { - setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v); - }); + String nameKey, boolean graphic, StoreSection section, Function initial, BiConsumer setter) { + var val = new SimpleBooleanProperty(); + ObservableValue g = graphic ? val.map(aBoolean -> aBoolean ? + new LabelGraphic.IconGraphic("mdi2c-circle-slice-8") : new LabelGraphic.IconGraphic("mdi2c-circle-half-full")) : null; + var t = new StoreToggleComp(nameKey, g, section, + new SimpleBooleanProperty(initial.apply(section.getWrapper().getEntry().getStore().asNeeded())), v -> { + Platform.runLater(() -> { + setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v); + StoreViewState.get().toggleStoreListUpdate(); + }); + }); + t.tooltipKey("showAllChildren"); + t.value.subscribe((newValue) -> { + val.set(newValue); + }); + return t; } - public StoreToggleComp(String nameKey, StoreSection section, boolean initial, Consumer onChange) { + public StoreToggleComp(String nameKey, ObservableValue graphic, StoreSection section, boolean initial, Consumer onChange) { this.nameKey = nameKey; + this.graphic = graphic; this.section = section; this.value = new SimpleBooleanProperty(initial); this.onChange = onChange; } - public StoreToggleComp(String nameKey, StoreSection section, BooleanProperty initial, Consumer onChange) { + public StoreToggleComp(String nameKey, ObservableValue graphic, StoreSection section, BooleanProperty initial, Consumer onChange) { this.nameKey = nameKey; + this.graphic = graphic; this.section = section; this.value = initial; this.onChange = onChange; @@ -74,7 +107,7 @@ public class StoreToggleComp extends SimpleComp { var disable = section.getWrapper().getValidity().map(state -> state != DataStoreEntry.Validity.COMPLETE); var visible = Bindings.createBooleanBinding( () -> { - if (!this.customVisibility.get()) { + if (!this.customVisibility.getValue()) { return false; } @@ -83,7 +116,7 @@ public class StoreToggleComp extends SimpleComp { section.getWrapper().getValidity(), section.getShowDetails(), this.customVisibility); - var t = new ToggleSwitchComp(value, AppI18n.observable(nameKey)) + var t = new ToggleSwitchComp(value, AppI18n.observable(nameKey), graphic) .visible(visible) .disable(disable); value.addListener((observable, oldValue, newValue) -> { diff --git a/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java b/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java index 05bd5bea6..94960c975 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java @@ -1,25 +1,25 @@ package io.xpipe.app.comp.base; +import atlantafx.base.controls.ToggleSwitch; import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.fxcomps.util.PlatformThread; - import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; +import javafx.css.PseudoClass; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Region; +import lombok.EqualsAndHashCode; +import lombok.Value; -import atlantafx.base.controls.ToggleSwitch; - +@Value +@EqualsAndHashCode(callSuper = true) public class ToggleSwitchComp extends SimpleComp { - private final Property selected; - private final ObservableValue name; - - public ToggleSwitchComp(Property selected, ObservableValue name) { - this.selected = selected; - this.name = name; - } + Property selected; + ObservableValue name; + ObservableValue graphic; @Override protected Region createSimple() { @@ -43,6 +43,10 @@ public class ToggleSwitchComp extends SimpleComp { if (name != null) { s.textProperty().bind(PlatformThread.sync(name)); } + if (graphic != null) { + s.graphicProperty().bind(PlatformThread.sync(graphic.map(labelGraphic -> labelGraphic.createGraphicNode()))); + s.pseudoClassStateChanged(PseudoClass.getPseudoClass("has-graphic"),true); + } return s; } } diff --git a/app/src/main/java/io/xpipe/app/comp/store/DenseStoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/DenseStoreEntryComp.java index b5953cc85..29a52a0ac 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/DenseStoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/DenseStoreEntryComp.java @@ -103,7 +103,7 @@ public class DenseStoreEntryComp extends StoreEntryComp { grid.getColumnConstraints().addAll(infoCC, custom); var cr = content != null ? content.createRegion() : new Region(); - var bb = createButtonBar().createRegion(); + var bb = createButtonBar(); var controls = new HBox(cr, bb); controls.setFillHeight(true); controls.setAlignment(Pos.CENTER_RIGHT); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StandardStoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StandardStoreEntryComp.java index a95a95dbf..595e7bc56 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StandardStoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StandardStoreEntryComp.java @@ -51,7 +51,7 @@ public class StandardStoreEntryComp extends StoreEntryComp { var custom = new ColumnConstraints(0, customSize, customSize); custom.setHalignment(HPos.RIGHT); var cr = content != null ? content.createRegion() : new Region(); - var bb = createButtonBar().createRegion(); + var bb = createButtonBar(); var controls = new HBox(cr, bb); controls.setFillHeight(true); HBox.setHgrow(cr, Priority.ALWAYS); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java index 7220f5e82..a9588494a 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java @@ -286,6 +286,10 @@ public class StoreCreationComp extends DialogComp { if (ex instanceof ValidationException) { ErrorEvent.expected(ex); skippable.set(false); + } else if (ex instanceof StackOverflowError) { + // Cycles in connection graphs can fail hard but are expected + ErrorEvent.expected(ex); + skippable.set(false); } else { skippable.set(true); } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java index cdcb3dc25..cbb597a5d 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java @@ -40,12 +40,16 @@ public class StoreCreationMenu { menu.getItems() .add(category( - "addCommand", "mdi2c-code-greater-than", DataStoreProvider.CreationCategory.COMMAND, "cmd")); + "addService", "mdi2c-cloud-braces", DataStoreProvider.CreationCategory.SERVICE, null)); menu.getItems() .add(category( "addTunnel", "mdi2v-vector-polyline-plus", DataStoreProvider.CreationCategory.TUNNEL, null)); + menu.getItems() + .add(category( + "addCommand", "mdi2c-code-greater-than", DataStoreProvider.CreationCategory.COMMAND, "cmd")); + menu.getItems() .add(category("addDatabase", "mdi2d-database-plus", DataStoreProvider.CreationCategory.DATABASE, null)); } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java index da3ab6bed..6cd55eba6 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java @@ -1,5 +1,6 @@ package io.xpipe.app.comp.store; +import atlantafx.base.layout.InputGroup; import atlantafx.base.theme.Styles; import io.xpipe.app.comp.base.LoadingOverlayComp; import io.xpipe.app.core.*; @@ -9,8 +10,12 @@ import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.augment.ContextMenuAugment; import io.xpipe.app.fxcomps.augment.GrowAugment; -import io.xpipe.app.fxcomps.impl.*; +import io.xpipe.app.fxcomps.impl.IconButtonComp; +import io.xpipe.app.fxcomps.impl.LabelComp; +import io.xpipe.app.fxcomps.impl.PrettyImageHelper; +import io.xpipe.app.fxcomps.impl.TooltipAugment; import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.DerivedObservableList; import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; @@ -199,63 +204,65 @@ public abstract class StoreEntryComp extends SimpleComp { return stack; } - protected Comp createButtonBar() { - var list = new ArrayList>(); - for (var p : wrapper.getActionProviders().entrySet()) { - var actionProvider = p.getKey().getDataStoreCallSite(); - if (!actionProvider.isMajor(wrapper.getEntry().ref())) { - continue; - } + protected Region createButtonBar() { + var list = new DerivedObservableList<>(wrapper.getActionProviders(), false); + var buttons = list.mapped(actionProvider -> { + var button = buildButton(actionProvider); + return button != null ? button.createRegion() : null; + }).filtered(region -> region != null).getList(); - var def = p.getKey().getDefaultDataStoreCallSite(); - if (def != null && def.equals(wrapper.getDefaultActionProvider().getValue())) { - continue; - } + var ig = new InputGroup(); + Runnable update = () -> { + var l = new ArrayList(buttons); + var settingsButton = createSettingsButton().createRegion(); + l.add(settingsButton); + l.forEach(o -> o.getStyleClass().remove(Styles.FLAT)); + ig.getChildren().setAll(l); + }; + buttons.subscribe(update); + update.run(); + ig.setAlignment(Pos.CENTER_RIGHT); + ig.setPadding(new Insets(5)); + ig.getStyleClass().add("button-bar"); + return ig; + } - var button = - new IconButtonComp(actionProvider.getIcon(wrapper.getEntry().ref()), () -> { - ThreadHelper.runFailableAsync(() -> { - var action = actionProvider.createAction( - wrapper.getEntry().ref()); - action.execute(); - }); + private Comp buildButton(ActionProvider p) { + var leaf = p.getLeafDataStoreCallSite(); + var branch = p.getBranchDataStoreCallSite(); + var cs = leaf != null ? leaf : branch; + + if (cs == null || !cs.isMajor(wrapper.getEntry().ref())) { + return null; + } + + var button = + new IconButtonComp(cs.getIcon(wrapper.getEntry().ref()), leaf != null ? () -> { + ThreadHelper.runFailableAsync(() -> { + wrapper.runAction(leaf.createAction(wrapper.getEntry().ref()), leaf.showBusy()); }); - button.accessibleText( - actionProvider.getName(wrapper.getEntry().ref()).getValue()); - button.apply(new TooltipAugment<>( - actionProvider.getName(wrapper.getEntry().ref()), null)); - if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ONLY_SHOW_IF_ENABLED) { - button.hide(Bindings.not(p.getValue())); - } else if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ALWAYS_SHOW) { - button.disable(Bindings.not(p.getValue())); - } - list.add(button); + } : null); + if (branch != null) { + button.apply(new ContextMenuAugment<>(mouseEvent -> mouseEvent.getButton() == MouseButton.PRIMARY,keyEvent -> false,() -> { + var cm = ContextMenuHelper.create(); + branch.getChildren().forEach(childProvider -> { + var menu = buildMenuItemForAction(childProvider); + if (menu != null) { + cm.getItems().add(menu); + } + }); + return cm; + })); } - - var settingsButton = createSettingsButton(); - list.add(settingsButton); - if (list.size() > 1) { - list.getFirst().styleClass(Styles.LEFT_PILL); - for (int i = 1; i < list.size() - 1; i++) { - list.get(i).styleClass(Styles.CENTER_PILL); - } - list.getLast().styleClass(Styles.RIGHT_PILL); - } - list.forEach(comp -> { - comp.apply(struc -> { - struc.get().getStyleClass().remove(Styles.FLAT); - }); - }); - return new HorizontalComp(list) - .apply(struc -> { - struc.get().setAlignment(Pos.CENTER_RIGHT); - struc.get().setPadding(new Insets(5)); - }) - .styleClass("button-bar"); + button.accessibleText( + cs.getName(wrapper.getEntry().ref()).getValue()); + button.apply(new TooltipAugment<>( + cs.getName(wrapper.getEntry().ref()), null)); + return button; } protected Comp createSettingsButton() { - var settingsButton = new IconButtonComp("mdi2d-dots-horizontal-circle-outline", () -> {}); + var settingsButton = new IconButtonComp("mdi2d-dots-horizontal-circle-outline", null); settingsButton.styleClass("settings"); settingsButton.accessibleText("More"); settingsButton.apply(new ContextMenuAugment<>( @@ -271,103 +278,21 @@ public abstract class StoreEntryComp extends SimpleComp { AppFont.normal(contextMenu.getStyleableNode()); var hasSep = false; - for (var p : wrapper.getActionProviders().entrySet()) { - var actionProvider = p.getKey().getDataStoreCallSite(); - if (actionProvider.isMajor(wrapper.getEntry().ref())) { + for (var p : wrapper.getActionProviders()) { + var item = buildMenuItemForAction(p); + if (item == null) { continue; } - if (actionProvider.isSystemAction() && !hasSep) { + if (p.getLeafDataStoreCallSite() != null && p.getLeafDataStoreCallSite().isSystemAction() && !hasSep) { if (contextMenu.getItems().size() > 0) { contextMenu.getItems().add(new SeparatorMenuItem()); } hasSep = true; } - var name = actionProvider.getName(wrapper.getEntry().ref()); - var icon = actionProvider.getIcon(wrapper.getEntry().ref()); - var item = actionProvider.canLinkTo() - ? new Menu(null, new FontIcon(icon)) - : new MenuItem(null, new FontIcon(icon)); - - var proRequired = p.getKey().getProFeatureId() != null - && !LicenseProvider.get() - .getFeature(p.getKey().getProFeatureId()) - .isSupported(); - if (proRequired) { - item.setDisable(true); - item.textProperty().bind(Bindings.createStringBinding(() -> name.getValue() + " (Pro)", name)); - } else { - item.textProperty().bind(name); - } - - Menu menu = actionProvider.canLinkTo() ? (Menu) item : null; - item.setOnAction(event -> { - if (menu != null && !event.getTarget().equals(menu)) { - return; - } - - if (menu != null && menu.isDisable()) { - return; - } - - contextMenu.hide(); - ThreadHelper.runFailableAsync(() -> { - var action = actionProvider.createAction(wrapper.getEntry().ref()); - action.execute(); - }); - }); - if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ONLY_SHOW_IF_ENABLED) { - item.visibleProperty().bind(p.getValue()); - } else if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ALWAYS_SHOW) { - item.disableProperty().bind(Bindings.not(p.getValue())); - } contextMenu.getItems().add(item); - - if (menu != null) { - var run = new MenuItem(null, new FontIcon("mdi2c-code-greater-than")); - run.textProperty().bind(AppI18n.observable("base.execute")); - run.setOnAction(event -> { - ThreadHelper.runFailableAsync(() -> { - p.getKey() - .getDataStoreCallSite() - .createAction(wrapper.getEntry().ref()) - .execute(); - }); - }); - menu.getItems().add(run); - - var sc = new MenuItem(null, new FontIcon("mdi2c-code-greater-than")); - var url = "xpipe://action/" + p.getKey().getId() + "/" - + wrapper.getEntry().getUuid(); - sc.textProperty().bind(AppI18n.observable("base.createShortcut")); - sc.setOnAction(event -> { - ThreadHelper.runFailableAsync(() -> { - DesktopShortcuts.create( - url, - wrapper.nameProperty().getValue() + " (" - + p.getKey() - .getDataStoreCallSite() - .getName(wrapper.getEntry().ref()) - .getValue() + ")"); - }); - }); - menu.getItems().add(sc); - - if (XPipeDistributionType.get().isSupportsUrls()) { - var l = new MenuItem(null, new FontIcon("mdi2c-clipboard-list-outline")); - l.textProperty().bind(AppI18n.observable("base.copyShareLink")); - l.setOnAction(event -> { - ThreadHelper.runFailableAsync(() -> { - AppActionLinkDetector.setLastDetectedAction(url); - ClipboardHelper.copyUrl(url); - }); - }); - menu.getItems().add(l); - } - } } - if (contextMenu.getItems().size() > 0 && !hasSep) { contextMenu.getItems().add(new SeparatorMenuItem()); } @@ -385,6 +310,11 @@ public abstract class StoreEntryComp extends SimpleComp { browse.setOnAction( event -> DesktopHelper.browsePathLocal(wrapper.getEntry().getDirectory())); contextMenu.getItems().add(browse); + + var copyId = new MenuItem(AppI18n.get("copyId"), new FontIcon("mdi2c-content-copy")); + copyId.setOnAction( + event -> ClipboardHelper.copyText(wrapper.getEntry().getUuid().toString())); + contextMenu.getItems().add(copyId); } if (DataStorage.get().isRootEntry(wrapper.getEntry())) { @@ -418,7 +348,7 @@ public abstract class StoreEntryComp extends SimpleComp { wrapper.moveTo(storeCategoryWrapper.getCategory()); event.consume(); }); - if (storeCategoryWrapper.getParent() == null) { + if (storeCategoryWrapper.getParent() == null || storeCategoryWrapper.equals(wrapper.getCategory().getValue())) { m.setDisable(true); } @@ -490,6 +420,94 @@ public abstract class StoreEntryComp extends SimpleComp { return contextMenu; } + private MenuItem buildMenuItemForAction(ActionProvider p) { + var leaf = p.getLeafDataStoreCallSite(); + var branch = p.getBranchDataStoreCallSite(); + var cs = leaf != null ? leaf : branch; + + if (cs == null || cs.isMajor(wrapper.getEntry().ref())) { + return null; + } + + var name = cs.getName(wrapper.getEntry().ref()); + var icon = cs.getIcon(wrapper.getEntry().ref()); + var item = (leaf != null && leaf.canLinkTo()) || branch != null + ? new Menu(null, new FontIcon(icon)) + : new MenuItem(null, new FontIcon(icon)); + + var proRequired = p.getProFeatureId() != null + && !LicenseProvider.get() + .getFeature(p.getProFeatureId()) + .isSupported(); + if (proRequired) { + item.setDisable(true); + item.textProperty().bind(Bindings.createStringBinding(() -> name.getValue() + " (Pro)", name)); + } else { + item.textProperty().bind(name); + } + Menu menu = item instanceof Menu m ? m : null; + + if (branch != null) { + var items = branch.getChildren().stream().map(c -> buildMenuItemForAction(c)).toList(); + menu.getItems().addAll(items); + return menu; + } else if (leaf.canLinkTo()) { + var run = new MenuItem(null, new FontIcon("mdi2c-code-greater-than")); + run.textProperty().bind(AppI18n.observable("base.execute")); + run.setOnAction(event -> { + ThreadHelper.runFailableAsync(() -> { + wrapper.runAction(leaf.createAction(wrapper.getEntry().ref()), leaf.showBusy()); + }); + }); + menu.getItems().add(run); + + var sc = new MenuItem(null, new FontIcon("mdi2c-code-greater-than")); + var url = "xpipe://action/" + p.getId() + "/" + + wrapper.getEntry().getUuid(); + sc.textProperty().bind(AppI18n.observable("base.createShortcut")); + sc.setOnAction(event -> { + ThreadHelper.runFailableAsync(() -> { + DesktopShortcuts.create( + url, + wrapper.nameProperty().getValue() + " (" + + p + .getLeafDataStoreCallSite() + .getName(wrapper.getEntry().ref()) + .getValue() + ")"); + }); + }); + menu.getItems().add(sc); + + if (XPipeDistributionType.get().isSupportsUrls()) { + var l = new MenuItem(null, new FontIcon("mdi2c-clipboard-list-outline")); + l.textProperty().bind(AppI18n.observable("base.copyShareLink")); + l.setOnAction(event -> { + ThreadHelper.runFailableAsync(() -> { + AppActionLinkDetector.setLastDetectedAction(url); + ClipboardHelper.copyUrl(url); + }); + }); + menu.getItems().add(l); + } + } + + item.setOnAction(event -> { + if (menu != null && !event.getTarget().equals(menu)) { + return; + } + + if (menu != null && menu.isDisable()) { + return; + } + + event.consume(); + ThreadHelper.runFailableAsync(() -> { + wrapper.runAction(leaf.createAction(wrapper.getEntry().ref()), leaf.showBusy()); + }); + }); + + return item; + } private static String DEFAULT_NOTES = null; diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java index f657af52c..a1111478e 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java @@ -61,14 +61,14 @@ public class StoreEntryListStatusComp extends SimpleComp { var inRootCategory = StoreViewState.get().getActiveCategory().getValue().getRoot().equals(rootCategory); // Sadly the all binding does not update when the individual visibility of entries changes // But it is good enough. - var showProvider = storeEntryWrapper.getEntry().getProvider() == null || + var showProvider = !storeEntryWrapper.getEntry().getValidity().isUsable() || storeEntryWrapper.getEntry().getProvider().shouldShow(storeEntryWrapper); return inRootCategory && showProvider; }, StoreViewState.get().getActiveCategory()); var shownList = all.filtered( storeEntryWrapper -> { - return storeEntryWrapper.shouldShow( + return storeEntryWrapper.matchesFilter( StoreViewState.get().getFilterString().getValue()); }, StoreViewState.get().getFilterString()); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java index 5d96ed2dc..c548f5fdc 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java @@ -9,8 +9,8 @@ import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreColor; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.ThreadHelper; -import javafx.beans.Observable; import javafx.beans.property.*; +import javafx.collections.FXCollections; import lombok.Getter; import java.time.Duration; @@ -26,8 +26,8 @@ public class StoreEntryWrapper { private final BooleanProperty disabled = new SimpleBooleanProperty(); private final BooleanProperty busy = new SimpleBooleanProperty(); private final Property validity = new SimpleObjectProperty<>(); - private final Map actionProviders; - private final Property> defaultActionProvider; + private final ListProperty actionProviders = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final Property defaultActionProvider = new SimpleObjectProperty<>(); private final BooleanProperty deletable = new SimpleBooleanProperty(); private final BooleanProperty expanded = new SimpleBooleanProperty(); private final Property persistentState = new SimpleObjectProperty<>(); @@ -41,30 +41,24 @@ public class StoreEntryWrapper { this.entry = entry; this.name = new SimpleStringProperty(entry.getName()); this.lastAccess = new SimpleObjectProperty<>(entry.getLastAccess().minus(Duration.ofMillis(500))); - this.actionProviders = new LinkedHashMap<>(); ActionProvider.ALL.stream() .filter(dataStoreActionProvider -> { return !entry.isDisabled() - && dataStoreActionProvider.getDataStoreCallSite() != null + && dataStoreActionProvider.getLeafDataStoreCallSite() != null && dataStoreActionProvider - .getDataStoreCallSite() + .getLeafDataStoreCallSite() .getApplicableClass() .isAssignableFrom(entry.getStore().getClass()); }) .sorted(Comparator.comparing( - actionProvider -> actionProvider.getDataStoreCallSite().isSystemAction())) + actionProvider -> actionProvider.getLeafDataStoreCallSite().isSystemAction())) .forEach(dataStoreActionProvider -> { - actionProviders.put(dataStoreActionProvider, new SimpleBooleanProperty(true)); + actionProviders.add(dataStoreActionProvider); }); - this.defaultActionProvider = new SimpleObjectProperty<>(); this.notes = new SimpleObjectProperty<>(new StoreNotes(entry.getNotes(), entry.getNotes())); setupListeners(); } - public List getUpdateObservables() { - return List.of(category); - } - public void moveTo(DataStoreCategory category) { ThreadHelper.runAsync(() -> { DataStorage.get().updateCategory(entry, category); @@ -136,7 +130,7 @@ public class StoreEntryWrapper { color.setValue(entry.getColor()); notes.setValue(new StoreNotes(entry.getNotes(), entry.getNotes())); - busy.setValue(entry.isInRefresh()); + busy.setValue(entry.getBusyCounter().get() != 0); deletable.setValue(entry.getConfiguration().isDeletable() || AppPrefs.get().developerDisableGuiRestrictions().getValue()); @@ -156,48 +150,56 @@ public class StoreEntryWrapper { } } - actionProviders.keySet().forEach(dataStoreActionProvider -> { - if (!isInStorage()) { - actionProviders.get(dataStoreActionProvider).set(false); - defaultActionProvider.setValue(null); - return; - } - - if (!entry.getValidity().isUsable() - && !dataStoreActionProvider - .getDataStoreCallSite() - .activeType() - .equals(ActionProvider.DataStoreCallSite.ActiveType.ALWAYS_ENABLE)) { - actionProviders.get(dataStoreActionProvider).set(false); - return; - } - + if (!isInStorage()) { + actionProviders.clear(); + defaultActionProvider.setValue(null); + } else { var defaultProvider = ActionProvider.ALL.stream() - .filter(e -> e.getDefaultDataStoreCallSite() != null + .filter(e -> entry.getStore() != null && e.getDefaultDataStoreCallSite() != null && e.getDefaultDataStoreCallSite() - .getApplicableClass() - .isAssignableFrom(entry.getStore().getClass()) + .getApplicableClass() + .isAssignableFrom(entry.getStore().getClass()) && e.getDefaultDataStoreCallSite().isApplicable(entry.ref())) .findFirst() - .map(ActionProvider::getDefaultDataStoreCallSite) .orElse(null); this.defaultActionProvider.setValue(defaultProvider); try { - actionProviders - .get(dataStoreActionProvider) - .set(dataStoreActionProvider - .getDataStoreCallSite() - .getApplicableClass() - .isAssignableFrom(entry.getStore().getClass()) - && dataStoreActionProvider - .getDataStoreCallSite() - .isApplicable(entry.ref())); + var newProviders = ActionProvider.ALL.stream() + .filter(dataStoreActionProvider -> { + return showActionProvider(dataStoreActionProvider); + }) + .sorted(Comparator.comparing( + actionProvider -> actionProvider.getLeafDataStoreCallSite() != null && + actionProvider.getLeafDataStoreCallSite().isSystemAction())) + .toList(); + if (!actionProviders.equals(newProviders)) { + actionProviders.setAll(newProviders); + } } catch (Exception ex) { ErrorEvent.fromThrowable(ex).handle(); - actionProviders.get(dataStoreActionProvider).set(false); } - }); + } + } + + private boolean showActionProvider(ActionProvider p) { + var leaf = p.getLeafDataStoreCallSite(); + if (leaf != null) { + return (entry.getValidity().isUsable() || (!leaf.requiresValidStore() && entry.getProvider() != null)) + && leaf.getApplicableClass().isAssignableFrom(entry.getStore().getClass()) + && leaf + .isApplicable(entry.ref()); + } + + + var branch = p.getBranchDataStoreCallSite(); + if (branch != null && entry.getStore() != null && branch.getApplicableClass().isAssignableFrom(entry.getStore().getClass())) { + return branch.getChildren().stream().anyMatch(child -> { + return showActionProvider(child); + }); + } + + return false; } public void refreshChildren() { @@ -220,17 +222,31 @@ public class StoreEntryWrapper { var found = getDefaultActionProvider().getValue(); entry.notifyUpdate(true, false); if (found != null) { - found.createAction(entry.ref()).execute(); + var act = found.getDefaultDataStoreCallSite().createAction(entry.ref()); + runAction(act,found.getDefaultDataStoreCallSite().showBusy()); } else { entry.setExpanded(!entry.isExpanded()); } } + public void runAction(ActionProvider.Action action, boolean showBusy) throws Exception { + try { + if (showBusy) { + getEntry().incrementBusyCounter(); + } + action.execute(); + } finally { + if (showBusy) { + getEntry().decrementBusyCounter(); + } + } + } + public void toggleExpanded() { this.expanded.set(!expanded.getValue()); } - public boolean shouldShow(String filter) { + public boolean matchesFilter(String filter) { if (filter == null || nameProperty().getValue().toLowerCase().contains(filter.toLowerCase())) { return true; } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreIntroComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreIntroComp.java index 7b3602c23..63ba318fb 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreIntroComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreIntroComp.java @@ -1,13 +1,15 @@ package io.xpipe.app.comp.store; +import atlantafx.base.theme.Styles; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.PrettySvgComp; +import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.util.ScanAlert; - import javafx.beans.property.SimpleStringProperty; +import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -15,14 +17,11 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; - -import atlantafx.base.theme.Styles; import org.kordamp.ikonli.javafx.FontIcon; public class StoreIntroComp extends SimpleComp { - @Override - public Region createSimple() { + private Region createIntro() { var title = new Label(); title.textProperty().bind(AppI18n.observable("storeIntroTitle")); title.getStyleClass().add(Styles.TEXT_BOLD); @@ -45,7 +44,7 @@ public class StoreIntroComp extends SimpleComp { text.setSpacing(5); text.setAlignment(Pos.CENTER_LEFT); var hbox = new HBox(img, text); - hbox.setSpacing(35); + hbox.setSpacing(55); hbox.setAlignment(Pos.CENTER); var v = new VBox(hbox, scanPane); @@ -56,8 +55,63 @@ public class StoreIntroComp extends SimpleComp { v.setSpacing(10); v.getStyleClass().add("intro"); + return v; + } + + + private Region createImportIntro() { + var title = new Label(); + title.textProperty().bind(AppI18n.observable("importConnectionsTitle")); + title.getStyleClass().add(Styles.TEXT_BOLD); + AppFont.setSize(title, 7); + + var importDesc = new Label(); + importDesc.textProperty().bind(AppI18n.observable("storeIntroImportDescription")); + importDesc.setWrapText(true); + importDesc.setMaxWidth(470); + + var importButton = new Button(null, new FontIcon("mdi2g-git")); + importButton.textProperty().bind(AppI18n.observable("importConnections")); + importButton.setOnAction(event -> AppPrefs.get().selectCategory("sync")); + var importPane = new StackPane(importButton); + importPane.setAlignment(Pos.CENTER); + + var fi = new FontIcon("mdi2g-git"); + fi.setIconSize(80); + var img = new StackPane(fi); + img.setPrefWidth(100); + img.setPrefHeight(150); + var text = new VBox(title, importDesc); + text.setSpacing(5); + text.setAlignment(Pos.CENTER_LEFT); + var hbox = new HBox(img, text); + hbox.setSpacing(35); + hbox.setAlignment(Pos.CENTER); + + var v = new VBox(hbox, importPane); + v.setMinWidth(Region.USE_PREF_SIZE); + v.setMaxWidth(Region.USE_PREF_SIZE); + v.setMinHeight(Region.USE_PREF_SIZE); + v.setMaxHeight(Region.USE_PREF_SIZE); + + v.setSpacing(10); + v.getStyleClass().add("intro"); + return v; + } + + @Override + public Region createSimple() { + var intro = createIntro(); + var introImport = createImportIntro(); + var v = new VBox(intro, introImport); + v.setSpacing(80); + v.setMinWidth(Region.USE_PREF_SIZE); + v.setMaxWidth(Region.USE_PREF_SIZE); + v.setMinHeight(Region.USE_PREF_SIZE); + v.setMaxHeight(Region.USE_PREF_SIZE); var sp = new StackPane(v); + sp.setPadding(new Insets(40, 0, 0, 0)); sp.setAlignment(Pos.CENTER); sp.setPickOnBounds(false); return sp; diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java index 67bb0cda9..fe7e19ae4 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java @@ -14,9 +14,7 @@ import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import lombok.Value; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Set; +import java.util.*; import java.util.function.Predicate; import java.util.function.ToIntFunction; @@ -87,7 +85,7 @@ public class StoreSection { } seen.add(wrapper); - var found = list.getList().stream().filter(section -> wrapper.getEntry().getOrderBefore().equals(section.getWrapper().getEntry().getUuid())).findFirst(); + var found = list.getList().stream().filter(section -> section.getWrapper().getEntry().getUuid().equals(wrapper.getEntry().getOrderBefore())).findFirst(); if (found.isPresent()) { return count(found.get().getWrapper(), seen); } else { @@ -125,16 +123,16 @@ public class StoreSection { category, StoreViewState.get().getEntriesListChangeObservable()); var cached = topLevel.mapped( - storeEntryWrapper -> create(storeEntryWrapper, 1, all, entryFilter, filterString, category)); + storeEntryWrapper -> create(List.of(), storeEntryWrapper, 1, all, entryFilter, filterString, category)); var ordered = sorted(cached, category); var shown = ordered.filtered( section -> { - var showFilter = filterString == null || section.matchesFilter(filterString.get()); - var matchesSelector = section.anyMatches(entryFilter); - var sameCategory = category == null - || category.getValue() == null - || showInCategory(category.getValue(), section.getWrapper()); - return showFilter && matchesSelector && sameCategory; + // matches filter + return (filterString == null || section.matchesFilter(filterString.get())) && + // matches selector + (section.anyMatches(entryFilter)) && + // same category + (category == null || category.getValue() == null || showInCategory(category.getValue(), section.getWrapper())); }, category, filterString); @@ -142,6 +140,7 @@ public class StoreSection { } private static StoreSection create( + List parents, StoreEntryWrapper e, int depth, DerivedObservableList all, @@ -161,31 +160,28 @@ public class StoreSection { // .map(found -> found.equals(e.getEntry())) // .orElse(false); - // This check is fast as the children are cached in the storage - var isChildren = DataStorage.get().getStoreChildren(e.getEntry()).contains(other.getEntry()); - var showProvider = other.getEntry().getProvider() == null || - other.getEntry().getProvider().shouldShow(other); - return isChildren && showProvider; + // is children. This check is fast as the children are cached in the storage + return DataStorage.get().getStoreChildren(e.getEntry()).contains(other.getEntry()) && + // show provider + (!other.getEntry().getValidity().isUsable() || other.getEntry().getProvider().shouldShow(other)); }, e.getPersistentState(), e.getCache(), StoreViewState.get().getEntriesListChangeObservable()); - var cached = allChildren.mapped( - entry1 -> create(entry1, depth + 1, all, entryFilter, filterString, category)); + var l = new ArrayList<>(parents); + l.add(e); + var cached = allChildren.mapped(c -> create(l, c, depth + 1, all, entryFilter, filterString, category)); var ordered = sorted(cached, category); var filtered = ordered.filtered( section -> { - var showFilter = filterString == null || section.matchesFilter(filterString.get()); - var matchesSelector = section.anyMatches(entryFilter); - // Prevent updates for children on category switching by checking depth - var showCategory = category == null - || category.getValue() == null - || showInCategory(category.getValue(), section.getWrapper()) - || depth > 0; - // If this entry is already shown as root due to a different category than parent, don't show it - // again here - var notRoot = + // matches filter + return (filterString == null || section.matchesFilter(filterString.get()) || l.stream().anyMatch(p -> p.matchesFilter(filterString.get()))) && + // matches selector + section.anyMatches(entryFilter) && + // matches category + // Prevent updates for children on category switching by checking depth + (category == null || category.getValue() == null || showInCategory(category.getValue(), section.getWrapper()) || depth > 0) && + // not root + // If this entry is already shown as root due to a different category than parent, don't show it + // again here !DataStorage.get().isRootEntry(section.getWrapper().getEntry()); - var showProvider = section.getWrapper().getEntry().getProvider() == null || - section.getWrapper().getEntry().getProvider().shouldShow(section.getWrapper()); - return showFilter && matchesSelector && showCategory && notRoot && showProvider; }, category, filterString, @@ -214,7 +210,7 @@ public class StoreSection { } public boolean matchesFilter(String filter) { - return anyMatches(storeEntryWrapper -> storeEntryWrapper.shouldShow(filter)); + return anyMatches(storeEntryWrapper -> storeEntryWrapper.matchesFilter(filter)); } public boolean anyMatches(Predicate c) { diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java index 238cfe0dc..b1792dcf6 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java @@ -2,6 +2,7 @@ package io.xpipe.app.comp.store; import io.xpipe.app.core.AppCache; import io.xpipe.app.fxcomps.util.DerivedObservableList; +import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; @@ -117,6 +118,18 @@ public class StoreViewState { .orElseThrow())); } + public void toggleStoreOrderUpdate() { + PlatformThread.runLaterIfNeeded(() -> { + entriesOrderChangeObservable.set(entriesOrderChangeObservable.get() + 1); + }); + } + + public void toggleStoreListUpdate() { + PlatformThread.runLaterIfNeeded(() -> { + entriesListChangeObservable.set(entriesListChangeObservable.get() + 1); + }); + } + private void addListeners() { if (AppPrefs.get() != null) { AppPrefs.get().condenseConnectionDisplay().addListener((observable, oldValue, newValue) -> { @@ -136,14 +149,14 @@ public class StoreViewState { @Override public void onStoreOrderUpdate() { Platform.runLater(() -> { - entriesOrderChangeObservable.set(entriesOrderChangeObservable.get() + 1); + toggleStoreOrderUpdate(); }); } @Override public void onStoreListUpdate() { Platform.runLater(() -> { - entriesListChangeObservable.set(entriesListChangeObservable.get() + 1); + toggleStoreListUpdate(); }); } @@ -281,11 +294,9 @@ public class StoreViewState { public int compare(StoreCategoryWrapper o1, StoreCategoryWrapper o2) { var o1Root = o1.getRoot(); var o2Root = o2.getRoot(); - if (o1Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) { return -1; } - if (o2Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) { return 1; } @@ -302,6 +313,22 @@ public class StoreViewState { return 1; } + if (o1.getDepth() > o2.getDepth()) { + if (o1.getParent() == o2) { + return 1; + } + + return compare(o1.getParent(), o2); + } + + if (o1.getDepth() < o2.getDepth()) { + if (o2.getParent() == o1) { + return -1; + } + + return compare(o1, o2.getParent()); + } + var parent = compare(o1.getParent(), o2.getParent()); if (parent != 0) { return parent; diff --git a/app/src/main/java/io/xpipe/app/core/AppDesktopIntegration.java b/app/src/main/java/io/xpipe/app/core/AppDesktopIntegration.java index c6900b53e..5ad9b00ee 100644 --- a/app/src/main/java/io/xpipe/app/core/AppDesktopIntegration.java +++ b/app/src/main/java/io/xpipe/app/core/AppDesktopIntegration.java @@ -5,6 +5,7 @@ import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.launcher.LauncherInput; import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.util.PlatformState; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.process.OsType; @@ -16,6 +17,10 @@ import java.util.List; public class AppDesktopIntegration { public static void setupDesktopIntegrations() { + if (PlatformState.getCurrent() != PlatformState.RUNNING) { + return; + } + try { if (Desktop.isDesktopSupported()) { Desktop.getDesktop().addAppEventListener(new SystemSleepListener() { diff --git a/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java b/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java index 9f7de75d8..b32386789 100644 --- a/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java +++ b/app/src/main/java/io/xpipe/app/core/AppExtensionManager.java @@ -72,7 +72,7 @@ public class AppExtensionManager { private void loadBaseExtension() { var baseModule = findAndParseExtension("base", ModuleLayer.boot()); if (baseModule.isEmpty()) { - throw new ExtensionException("Missing base module. Is the installation corrupt?"); + throw new ExtensionException("Missing base module. Is the installation data corrupt?"); } baseLayer = baseModule.get().getModule().getLayer(); diff --git a/app/src/main/java/io/xpipe/app/core/AppProperties.java b/app/src/main/java/io/xpipe/app/core/AppProperties.java index bb1735903..700c71dd5 100644 --- a/app/src/main/java/io/xpipe/app/core/AppProperties.java +++ b/app/src/main/java/io/xpipe/app/core/AppProperties.java @@ -50,11 +50,10 @@ public class AppProperties { Properties props = new Properties(); props.load(Files.newInputStream(propsFile)); props.forEach((key, value) -> { - if (System.getProperty(key.toString()) != null) { - return; + // Don't overwrite existing properties + if (System.getProperty(key.toString()) == null) { + System.setProperty(key.toString(), value.toString()); } - - System.setProperty(key.toString(), value.toString()); }); } catch (IOException e) { ErrorEvent.fromThrowable(e).handle(); diff --git a/app/src/main/java/io/xpipe/app/core/AppSocketServer.java b/app/src/main/java/io/xpipe/app/core/AppSocketServer.java deleted file mode 100644 index eb2ac1695..000000000 --- a/app/src/main/java/io/xpipe/app/core/AppSocketServer.java +++ /dev/null @@ -1,358 +0,0 @@ -package io.xpipe.app.core; - -import io.xpipe.app.exchange.MessageExchangeImpls; -import io.xpipe.app.issue.ErrorEvent; -import io.xpipe.app.issue.TrackEvent; -import io.xpipe.beacon.*; -import io.xpipe.beacon.exchange.MessageExchanges; -import io.xpipe.beacon.exchange.data.ClientErrorMessage; -import io.xpipe.beacon.exchange.data.ServerErrorMessage; -import io.xpipe.core.util.Deobfuscator; -import io.xpipe.core.util.FailableRunnable; -import io.xpipe.core.util.JacksonMapper; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.node.TextNode; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringWriter; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.HexFormat; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; - -public class AppSocketServer { - - private static AppSocketServer INSTANCE; - private final int port; - private ServerSocket socket; - private boolean running; - private int connectionCounter; - private Thread listenerThread; - - private AppSocketServer(int port) { - this.port = port; - } - - public static void init() { - int port = -1; - try { - port = BeaconConfig.getUsedPort(); - INSTANCE = new AppSocketServer(port); - INSTANCE.createSocketListener(); - - TrackEvent.withInfo("Initialized socket server") - .tag("port", port) - .build() - .handle(); - } catch (Exception ex) { - // Not terminal! - ErrorEvent.fromThrowable(ex) - .description("Unable to start local socket server on port " + port) - .build() - .handle(); - } - } - - public static void reset() { - if (INSTANCE != null) { - INSTANCE.stop(); - INSTANCE = null; - } - } - - private void stop() { - if (!running) { - return; - } - - running = false; - try { - socket.close(); - } catch (IOException e) { - ErrorEvent.fromThrowable(e).handle(); - } - try { - listenerThread.join(); - } catch (InterruptedException ignored) { - } - } - - private void createSocketListener() throws IOException { - socket = new ServerSocket(port, 10000, InetAddress.getLoopbackAddress()); - running = true; - listenerThread = new Thread( - () -> { - while (running) { - Socket clientSocket; - try { - clientSocket = socket.accept(); - } catch (Exception ex) { - continue; - } - - try { - performExchangesAsync(clientSocket); - } catch (Exception ex) { - ErrorEvent.fromThrowable(ex).build().handle(); - } - connectionCounter++; - } - }, - "socket server"); - listenerThread.start(); - } - - private boolean performExchange(Socket clientSocket, int id) throws Exception { - if (clientSocket.isClosed()) { - TrackEvent.trace("Socket closed"); - return false; - } - - JsonNode node; - try (InputStream blockIn = BeaconFormat.readBlocks(clientSocket.getInputStream())) { - node = JacksonMapper.getDefault().readTree(blockIn); - } - if (node.isMissingNode()) { - TrackEvent.trace("Received EOF"); - return false; - } - - TrackEvent.trace("Received raw request: \n" + node.toPrettyString()); - - var req = parseRequest(node); - TrackEvent.trace("Parsed request: \n" + req.toString()); - - var prov = MessageExchangeImpls.byRequest(req); - if (prov.isEmpty()) { - throw new IllegalArgumentException("Unknown request id: " + req.getClass()); - } - AtomicReference> post = new AtomicReference<>(); - var res = prov.get() - .handleRequest( - new BeaconHandler() { - @Override - public void postResponse(FailableRunnable r) { - post.set(r); - } - - @Override - public OutputStream sendBody() throws IOException { - TrackEvent.trace("Starting writing body for #" + id); - return AppSocketServer.this.sendBody(clientSocket); - } - - @Override - public InputStream receiveBody() throws IOException { - TrackEvent.trace("Starting to read body for #" + id); - return AppSocketServer.this.receiveBody(clientSocket); - } - }, - req); - - TrackEvent.trace("Sending response to #" + id + ": \n" + res.toString()); - AppSocketServer.this.sendResponse(clientSocket, res); - - try { - // If this fails, we sadly can't send an error response. Therefore just report it on the server side - if (post.get() != null) { - post.get().run(); - } - } catch (Exception ex) { - ErrorEvent.fromThrowable(ex).handle(); - } - - TrackEvent.builder() - .type("trace") - .message("Socket connection #" + id + " performed exchange " - + req.getClass().getSimpleName()) - .build() - .handle(); - - return true; - } - - private void performExchanges(Socket clientSocket, int id) { - try { - JsonNode informationNode; - try (InputStream blockIn = BeaconFormat.readBlocks(clientSocket.getInputStream())) { - informationNode = JacksonMapper.getDefault().readTree(blockIn); - } - if (informationNode.isMissingNode()) { - TrackEvent.trace("Received EOF"); - return; - } - var information = - JacksonMapper.getDefault().treeToValue(informationNode, BeaconClient.ClientInformation.class); - try (var blockOut = BeaconFormat.writeBlocks(clientSocket.getOutputStream())) { - blockOut.write("\"ACK\"".getBytes(StandardCharsets.UTF_8)); - } - - TrackEvent.builder() - .type("trace") - .message("Created new socket connection #" + id) - .tag("client", information != null ? information.toDisplayString() : "Unknown") - .build() - .handle(); - - try { - while (true) { - if (!performExchange(clientSocket, id)) { - break; - } - } - TrackEvent.builder() - .type("trace") - .message("Socket connection #" + id + " finished successfully") - .build() - .handle(); - - } catch (ClientException ce) { - TrackEvent.trace("Sending client error to #" + id + ": " + ce.getMessage()); - sendClientErrorResponse(clientSocket, ce.getMessage()); - } catch (ServerException se) { - TrackEvent.trace("Sending server error to #" + id + ": " + se.getMessage()); - Deobfuscator.deobfuscate(se); - sendServerErrorResponse(clientSocket, se); - var toReport = se.getCause() != null ? se.getCause() : se; - ErrorEvent.fromThrowable(toReport).build().handle(); - } catch (SocketException ex) { - // Do not send error and omit it, as this might happen often - // This is expected if you kill a running xpipe CLI process - // We do not send the error to the client as the socket connection might be broken - ErrorEvent.fromThrowable(ex).omitted(true).expected().build().handle(); - } catch (Throwable ex) { - TrackEvent.trace("Sending internal server error to #" + id + ": " + ex.getMessage()); - Deobfuscator.deobfuscate(ex); - sendServerErrorResponse(clientSocket, ex); - ErrorEvent.fromThrowable(ex).build().handle(); - } - } catch (SocketException ex) { - // Omit it, as this might happen often - // This is expected if you kill a running xpipe CLI process - ErrorEvent.fromThrowable(ex).expected().omit().build().handle(); - } catch (Throwable ex) { - ErrorEvent.fromThrowable(ex).build().handle(); - } finally { - try { - clientSocket.close(); - TrackEvent.trace("Closed socket #" + id); - } catch (IOException e) { - ErrorEvent.fromThrowable(e).build().handle(); - } - } - - TrackEvent.builder().type("trace").message("Socket connection #" + id + " finished unsuccessfully"); - } - - private void performExchangesAsync(Socket clientSocket) { - var id = connectionCounter; - var t = new Thread( - () -> { - performExchanges(clientSocket, id); - }, - "socket connection #" + id); - t.start(); - } - - public OutputStream sendBody(Socket outSocket) throws IOException { - outSocket.getOutputStream().write(BeaconConfig.BODY_SEPARATOR); - return BeaconFormat.writeBlocks(outSocket.getOutputStream()); - } - - public InputStream receiveBody(Socket outSocket) throws IOException { - var read = outSocket.getInputStream().readNBytes(BeaconConfig.BODY_SEPARATOR.length); - if (!Arrays.equals(read, BeaconConfig.BODY_SEPARATOR)) { - throw new IOException("Expected body start (" + HexFormat.of().formatHex(BeaconConfig.BODY_SEPARATOR) - + ") but got " + HexFormat.of().formatHex(read)); - } - return BeaconFormat.readBlocks(outSocket.getInputStream()); - } - - public void sendResponse(Socket outSocket, T obj) throws Exception { - ObjectNode json = JacksonMapper.getDefault().valueToTree(obj); - var prov = MessageExchanges.byResponse(obj).get(); - json.set("messageType", new TextNode(prov.getId())); - json.set("messagePhase", new TextNode("response")); - var msg = JsonNodeFactory.instance.objectNode(); - msg.set("xPipeMessage", json); - - var writer = new StringWriter(); - var mapper = JacksonMapper.getDefault(); - try (JsonGenerator g = mapper.createGenerator(writer).setPrettyPrinter(new DefaultPrettyPrinter())) { - g.writeTree(msg); - } catch (IOException ex) { - throw new ConnectorException("Couldn't serialize request", ex); - } - - var content = writer.toString(); - TrackEvent.trace("Sending raw response:\n" + content); - try (OutputStream blockOut = BeaconFormat.writeBlocks(outSocket.getOutputStream())) { - blockOut.write(content.getBytes(StandardCharsets.UTF_8)); - } - } - - public void sendClientErrorResponse(Socket outSocket, String message) throws Exception { - var err = new ClientErrorMessage(message); - ObjectNode json = JacksonMapper.getDefault().valueToTree(err); - var msg = JsonNodeFactory.instance.objectNode(); - msg.set("xPipeClientError", json); - - // Don't log this as it clutters the output - // TrackEvent.trace("beacon", "Sending raw client error:\n" + json.toPrettyString()); - - var mapper = JacksonMapper.getDefault(); - try (OutputStream blockOut = BeaconFormat.writeBlocks(outSocket.getOutputStream())) { - var gen = mapper.createGenerator(blockOut); - gen.writeTree(msg); - } - } - - public void sendServerErrorResponse(Socket outSocket, Throwable ex) throws Exception { - var err = new ServerErrorMessage(UUID.randomUUID(), ex); - ObjectNode json = JacksonMapper.getDefault().valueToTree(err); - var msg = JsonNodeFactory.instance.objectNode(); - msg.set("xPipeServerError", json); - - // Don't log this as it clutters the output - // TrackEvent.trace("beacon", "Sending raw server error:\n" + json.toPrettyString()); - - var mapper = JacksonMapper.getDefault(); - try (OutputStream blockOut = BeaconFormat.writeBlocks(outSocket.getOutputStream())) { - var gen = mapper.createGenerator(blockOut); - gen.writeTree(msg); - } - } - - private T parseRequest(JsonNode header) throws Exception { - ObjectNode content = (ObjectNode) header.required("xPipeMessage"); - TrackEvent.trace("Parsed raw request:\n" + content.toPrettyString()); - - var type = content.required("messageType").textValue(); - var phase = content.required("messagePhase").textValue(); - if (!phase.equals("request")) { - throw new IllegalArgumentException("Not a request"); - } - content.remove("messageType"); - content.remove("messagePhase"); - - var prov = MessageExchangeImpls.byId(type); - if (prov.isEmpty()) { - throw new IllegalArgumentException("Unknown request id: " + type); - } - - var reader = JacksonMapper.getDefault().readerFor(prov.get().getRequestClass()); - return reader.readValue(content); - } -} diff --git a/app/src/main/java/io/xpipe/app/core/AppTheme.java b/app/src/main/java/io/xpipe/app/core/AppTheme.java index c126f0e03..380a4f05e 100644 --- a/app/src/main/java/io/xpipe/app/core/AppTheme.java +++ b/app/src/main/java/io/xpipe/app/core/AppTheme.java @@ -235,10 +235,7 @@ public class AppTheme { .collect(Collectors.joining("\n"))); }); - var out = Files.createTempFile(id, ".css"); - Files.writeString(out, builder.toString()); - - Application.setUserAgentStylesheet(out.toUri().toString()); + Application.setUserAgentStylesheet(Styles.toDataURI(builder.toString())); } @Override @@ -257,13 +254,14 @@ public class AppTheme { public static final Theme CUPERTINO_LIGHT = new Theme("cupertinoLight", "cupertino", new CupertinoLight()); public static final Theme CUPERTINO_DARK = new Theme("cupertinoDark", "cupertino", new CupertinoDark()); public static final Theme DRACULA = new Theme("dracula", "dracula", new Dracula()); + public static final Theme MOCHA = new DerivedTheme("mocha", "primer", "Mocha", new PrimerDark()); // Adjust this to create your own theme public static final Theme CUSTOM = new DerivedTheme("custom", "primer", "Custom", new PrimerDark()); // Also include your custom theme here public static final List ALL = - List.of(PRIMER_LIGHT, PRIMER_DARK, NORD_LIGHT, NORD_DARK, CUPERTINO_LIGHT, CUPERTINO_DARK, DRACULA); + List.of(PRIMER_LIGHT, PRIMER_DARK, NORD_LIGHT, NORD_DARK, CUPERTINO_LIGHT, CUPERTINO_DARK, DRACULA, MOCHA); protected final String id; @Getter diff --git a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java index d3b8582d7..63f840d94 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java @@ -1,5 +1,6 @@ package io.xpipe.app.core.mode; +import io.xpipe.app.beacon.AppBeaconServer; import io.xpipe.app.browser.session.BrowserSessionModel; import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.*; @@ -17,7 +18,6 @@ import io.xpipe.app.util.FileBridge; import io.xpipe.app.util.LicenseProvider; import io.xpipe.app.util.LocalShell; import io.xpipe.app.util.UnlockAlert; -import io.xpipe.core.util.JacksonMapper; public class BaseMode extends OperationMode { @@ -43,12 +43,8 @@ public class BaseMode extends OperationMode { // if (true) throw new IllegalStateException(); TrackEvent.info("Initializing base mode components ..."); - AppExtensionManager.init(true); - JacksonMapper.initModularized(AppExtensionManager.getInstance().getExtendedLayer()); AppI18n.init(); LicenseProvider.get().init(); - AppPrefs.initLocal(); - AppI18n.init(); AppCertutilCheck.check(); AppAvCheck.check(); AppSid.init(); @@ -56,8 +52,8 @@ public class BaseMode extends OperationMode { AppShellCheck.check(); XPipeDistributionType.init(); AppPrefs.setDefaults(); - // Initialize socket server as we should be prepared for git askpass commands - AppSocketServer.init(); + // Initialize beacon server as we should be prepared for git askpass commands + AppBeaconServer.init(); GitStorageHandler.getInstance().init(); GitStorageHandler.getInstance().setupRepositoryAndPull(); AppPrefs.initSharedRemote(); @@ -85,8 +81,8 @@ public class BaseMode extends OperationMode { AppResources.reset(); AppExtensionManager.reset(); AppDataLock.unlock(); - // Shut down socket server last to keep a non-daemon thread running - AppSocketServer.reset(); + // Shut down server last to keep a non-daemon thread running + AppBeaconServer.reset(); TrackEvent.info("Background mode shutdown finished"); } } diff --git a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java index ad3633e62..44edc6064 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java @@ -6,6 +6,7 @@ import io.xpipe.app.core.check.AppTempCheck; import io.xpipe.app.core.check.AppUserDirectoryCheck; import io.xpipe.app.issue.*; import io.xpipe.app.launcher.LauncherCommand; +import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.util.LocalShell; import io.xpipe.app.util.PlatformState; import io.xpipe.app.util.ThreadHelper; @@ -109,6 +110,9 @@ public abstract class OperationMode { AppProperties.logArguments(args); AppProperties.logSystemProperties(); AppProperties.logPassedProperties(); + AppExtensionManager.init(true); + AppI18n.init(); + AppPrefs.initLocal(); TrackEvent.info("Finished initial setup"); } catch (Throwable ex) { ErrorEvent.fromThrowable(ex).term().handle(); diff --git a/app/src/main/java/io/xpipe/app/exchange/AskpassExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/AskpassExchangeImpl.java deleted file mode 100644 index 810d2c71b..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/AskpassExchangeImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.app.util.SecretManager; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.AskpassExchange; - -public class AskpassExchangeImpl extends AskpassExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) { - var found = msg.getSecretId() != null - ? SecretManager.getProgress(msg.getRequest(), msg.getSecretId()) - : SecretManager.getProgress(msg.getRequest()); - if (found.isEmpty()) { - return Response.builder().build(); - } - - var p = found.get(); - var secret = p.process(msg.getPrompt()); - return Response.builder() - .value(secret != null ? secret.inPlace() : null) - .build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java deleted file mode 100644 index b6d46c203..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/DialogExchangeImpl.java +++ /dev/null @@ -1,76 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.app.issue.TrackEvent; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.cli.DialogExchange; -import io.xpipe.core.dialog.Dialog; -import io.xpipe.core.dialog.DialogReference; -import io.xpipe.core.util.FailableConsumer; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class DialogExchangeImpl extends DialogExchange - implements MessageExchangeImpl { - - private static final Map openDialogs = new HashMap<>(); - private static final Map> openDialogConsumers = new HashMap<>(); - - public static DialogReference add(Dialog d, FailableConsumer onCompletion) throws Exception { - return add(d, UUID.randomUUID(), onCompletion); - } - - public static DialogReference add(Dialog d, UUID uuid, FailableConsumer onCompletion) - throws Exception { - openDialogs.put(uuid, d); - openDialogConsumers.put(uuid, onCompletion); - return new DialogReference(uuid, d.start()); - } - - @Override - public DialogExchange.Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - if (msg.isCancel()) { - TrackEvent.withTrace("Received cancel dialog request") - .tag("key", msg.getDialogKey()) - .handle(); - openDialogs.remove(msg.getDialogKey()); - openDialogConsumers.remove(msg.getDialogKey()); - return DialogExchange.Response.builder().element(null).build(); - } - - var dialog = openDialogs.get(msg.getDialogKey()); - var e = dialog.receive(msg.getValue()); - - TrackEvent.withTrace("Received normal dialog request") - .tag("key", msg.getDialogKey()) - .tag("value", msg.getValue()) - .tag("newElement", e) - .handle(); - - if (e == null) { - openDialogs.remove(msg.getDialogKey()); - var con = openDialogConsumers.remove(msg.getDialogKey()); - con.accept(dialog.getResult()); - } - - return DialogExchange.Response.builder().element(e).build(); - // - // - // var provider = getProvider(msg.getInstance().getProvider()); - // var completeConfig = toCompleteConfig(provider); - // - // var option = completeConfig.keySet().stream() - // .filter(o -> o.getKey().equals(msg.getKey())).findAny() - // .orElseThrow(() -> new ClientException("Invalid config key: " + msg.getKey())); - // - // String errorMsg = null; - // try { - // option.getConverter().convertFromString(msg.getValue()); - // } catch (Exception ex) { - // errorMsg = ex.getMessage(); - // } - // - // return DialogExchange.Response.builder().errorMsg(errorMsg).build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/FocusExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/FocusExchangeImpl.java deleted file mode 100644 index 2b5181d5d..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/FocusExchangeImpl.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.FocusExchange; - -public class FocusExchangeImpl extends FocusExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) { - OperationMode.switchUp(OperationMode.map(msg.getMode())); - return Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/LaunchExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/LaunchExchangeImpl.java deleted file mode 100644 index a7dfb5a7c..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/LaunchExchangeImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.LaunchExchange; -import io.xpipe.core.store.LaunchableStore; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public class LaunchExchangeImpl extends LaunchExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - var store = getStoreEntryById(msg.getId(), false); - if (store.getStore() instanceof LaunchableStore s) { - // var command = s.prepareLaunchCommand() - // .prepareTerminalOpen(TerminalInitScriptConfig.ofName(store.getName()), sc -> null); - // return Response.builder().command(split(command)).build(); - } - - throw new IllegalArgumentException(store.getName() + " is not launchable"); - } - - private List split(String command) { - var split = Arrays.stream(command.split(" ", 3)).collect(Collectors.toList()); - var s = split.get(2); - if ((s.startsWith("\"") && s.endsWith("\"")) || (s.startsWith("'") && s.endsWith("'"))) { - split.set(2, s.substring(1, s.length() - 1)); - } - return split; - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java deleted file mode 100644 index f73b7583a..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpl.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.app.storage.DataStorage; -import io.xpipe.app.storage.DataStoreEntry; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.core.store.DataStoreId; - -import lombok.NonNull; - -public interface MessageExchangeImpl extends MessageExchange { - - default DataStoreEntry getStoreEntryByName(@NonNull String name, boolean acceptDisabled) throws ClientException { - var store = DataStorage.get().getStoreEntryIfPresent(name); - if (store.isEmpty()) { - throw new ClientException("No store with name " + name + " was found"); - } - if (store.get().isDisabled() && !acceptDisabled) { - throw new ClientException( - String.format("Store %s is disabled", store.get().getName())); - } - return store.get(); - } - - default DataStoreEntry getStoreEntryById(@NonNull DataStoreId id, boolean acceptUnusable) throws ClientException { - var store = DataStorage.get().getStoreEntryIfPresent(id); - if (store.isEmpty()) { - throw new ClientException("No store with id " + id + " was found"); - } - if (store.get().isDisabled() && !acceptUnusable) { - throw new ClientException( - String.format("Store %s is disabled", store.get().getName())); - } - if (!store.get().getValidity().isUsable() && !acceptUnusable) { - throw new ClientException(String.format( - "Store %s is not completely configured", store.get().getName())); - } - return store.get(); - } - - String getId(); - - RS handleRequest(BeaconHandler handler, RQ msg) throws Exception; -} diff --git a/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpls.java b/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpls.java deleted file mode 100644 index 94a18b15b..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/MessageExchangeImpls.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchanges; -import io.xpipe.core.util.ModuleLayerLoader; - -import java.util.List; -import java.util.Optional; -import java.util.ServiceLoader; -import java.util.stream.Collectors; - -public class MessageExchangeImpls { - - private static List> ALL; - - @SuppressWarnings("unchecked") - public static Optional> byId( - String name) { - var r = ALL.stream().filter(d -> d.getId().equals(name)).findAny(); - return Optional.ofNullable((MessageExchangeImpl) r.orElse(null)); - } - - @SuppressWarnings("unchecked") - public static - Optional> byRequest(RQ req) { - var r = ALL.stream() - .filter(d -> d.getRequestClass().equals(req.getClass())) - .findAny(); - return Optional.ofNullable((MessageExchangeImpl) r.orElse(null)); - } - - public static List> getAll() { - return ALL; - } - - public static class Loader implements ModuleLayerLoader { - - @Override - public void init(ModuleLayer layer) { - ALL = ServiceLoader.load(layer, MessageExchangeImpl.class).stream() - .map(s -> { - // TrackEvent.trace("init", "Loaded exchange implementation " + ex.getId()); - return (MessageExchangeImpl) s.get(); - }) - .collect(Collectors.toList()); - - ALL.forEach(messageExchange -> { - if (MessageExchanges.byId(messageExchange.getId()).isEmpty()) { - throw new AssertionError("Missing base exchange: " + messageExchange.getId()); - } - }); - - MessageExchanges.getAll().forEach(messageExchange -> { - if (MessageExchangeImpls.byId(messageExchange.getId()).isEmpty()) { - throw new AssertionError("Missing exchange implementation: " + messageExchange.getId()); - } - }); - } - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/OpenExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/OpenExchangeImpl.java deleted file mode 100644 index 9a5601772..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/OpenExchangeImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.app.launcher.LauncherInput; -import io.xpipe.app.util.PlatformState; -import io.xpipe.app.util.ThreadHelper; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ServerException; -import io.xpipe.beacon.exchange.OpenExchange; - -public class OpenExchangeImpl extends OpenExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws ServerException { - if (msg.getArguments().isEmpty()) { - if (!OperationMode.switchToSyncIfPossible(OperationMode.GUI)) { - throw new ServerException(PlatformState.getLastError()); - } - } - - // Wait for startup - while (OperationMode.get() == null) { - ThreadHelper.sleep(100); - } - - LauncherInput.handle(msg.getArguments()); - return Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/QueryStoreExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/QueryStoreExchangeImpl.java deleted file mode 100644 index 39f546597..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/QueryStoreExchangeImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.QueryStoreExchange; -import io.xpipe.core.dialog.DialogMapper; - -public class QueryStoreExchangeImpl extends QueryStoreExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - var store = getStoreEntryByName(msg.getName(), true); - var summary = ""; - var dialog = store.getProvider().dialogForStore(store.getStore().asNeeded()); - var config = new DialogMapper(dialog).handle(); - return Response.builder() - .summary(summary) - .internalStore(store.getStore()) - .provider(store.getProvider().getId()) - .config(config) - .build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/TerminalLaunchExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/TerminalLaunchExchangeImpl.java deleted file mode 100644 index 5540de7f3..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/TerminalLaunchExchangeImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.app.util.TerminalLauncherManager; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.exchange.TerminalLaunchExchange; - -public class TerminalLaunchExchangeImpl extends TerminalLaunchExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws ClientException { - var r = TerminalLauncherManager.performLaunch(msg.getRequest()); - return Response.builder().targetFile(r).build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/TerminalWaitExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/TerminalWaitExchangeImpl.java deleted file mode 100644 index bac98a9e2..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/TerminalWaitExchangeImpl.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.xpipe.app.exchange; - -import io.xpipe.app.util.TerminalLauncherManager; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.ServerException; -import io.xpipe.beacon.exchange.TerminalWaitExchange; - -public class TerminalWaitExchangeImpl extends TerminalWaitExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws ServerException, ClientException { - TerminalLauncherManager.waitForCompletion(msg.getRequest()); - return Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/DrainExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/DrainExchangeImpl.java deleted file mode 100644 index 5cdd9b159..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/DrainExchangeImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.exchange.DrainExchange; -import io.xpipe.core.store.ShellStore; - -public class DrainExchangeImpl extends DrainExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - var ds = getStoreEntryById(msg.getSource(), false); - - if (!(ds.getStore() instanceof ShellStore)) { - throw new ClientException("Can't open file system for connection"); - } - - handler.postResponse(() -> { - ShellStore store = ds.getStore().asNeeded(); - try (var fs = store.createFileSystem(); - var output = handler.sendBody(); - var inputStream = fs.openInput(msg.getPath())) { - inputStream.transferTo(output); - } - }); - return Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/EditStoreExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/EditStoreExchangeImpl.java deleted file mode 100644 index b13c3045c..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/EditStoreExchangeImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.DialogExchangeImpl; -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.cli.EditStoreExchange; -import io.xpipe.core.store.DataStore; - -public class EditStoreExchangeImpl extends EditStoreExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - var s = getStoreEntryByName(msg.getName(), false); - var dialog = s.getProvider().dialogForStore(s.getStore()); - var reference = DialogExchangeImpl.add(dialog, (DataStore newStore) -> { - // s.setStore(newStore); - }); - return Response.builder().dialog(reference).build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/ListStoresExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/ListStoresExchangeImpl.java deleted file mode 100644 index 09a449776..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/ListStoresExchangeImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.app.storage.DataStorage; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.cli.ListStoresExchange; -import io.xpipe.beacon.exchange.data.StoreListEntry; - -import java.util.Comparator; -import java.util.List; - -public class ListStoresExchangeImpl extends ListStoresExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) { - DataStorage s = DataStorage.get(); - if (s == null) { - return Response.builder().entries(List.of()).build(); - } - - var e = s.getStoreEntries().stream() - .filter(entry -> !entry.isDisabled()) - .map(col -> StoreListEntry.builder() - .id(DataStorage.get().getId(col)) - .type(col.getProvider().getId()) - .build()) - .sorted(Comparator.comparing(en -> en.getId().toString())) - .toList(); - return Response.builder().entries(e).build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/ModeExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/ModeExchangeImpl.java deleted file mode 100644 index d08a88c6e..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/ModeExchangeImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.app.util.ThreadHelper; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.exchange.cli.ModeExchange; - -public class ModeExchangeImpl extends ModeExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - // Wait for startup - while (OperationMode.get() == null) { - ThreadHelper.sleep(100); - } - - var mode = OperationMode.map(msg.getMode()); - if (!mode.isSupported()) { - throw new ClientException("Unsupported mode: " + msg.getMode().getDisplayName() + ". Supported: " - + String.join( - ", ", - OperationMode.getAll().stream() - .filter(OperationMode::isSupported) - .map(OperationMode::getId) - .toList())); - } - - OperationMode.switchToSyncIfPossible(mode); - return ModeExchange.Response.builder() - .usedMode(OperationMode.map(OperationMode.get())) - .build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java deleted file mode 100644 index 2cc03a8f4..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/ReadDrainExchangeImpl.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.cli.ReadDrainExchange; - -public class ReadDrainExchangeImpl extends ReadDrainExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) { - return ReadDrainExchange.Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/RemoveStoreExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/RemoveStoreExchangeImpl.java deleted file mode 100644 index 25ee3208c..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/RemoveStoreExchangeImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.app.storage.DataStorage; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.exchange.cli.RemoveStoreExchange; -import io.xpipe.core.store.DataStoreId; - -public class RemoveStoreExchangeImpl extends RemoveStoreExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - var s = getStoreEntryById(DataStoreId.fromString(msg.getStoreName()), true); - if (!s.getConfiguration().isDeletable()) { - throw new ClientException("Store is not deletable"); - } - - DataStorage.get().deleteStoreEntry(s); - return Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/RenameStoreExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/RenameStoreExchangeImpl.java deleted file mode 100644 index eccd5546e..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/RenameStoreExchangeImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.exchange.cli.RenameStoreExchange; -import io.xpipe.core.store.DataStoreId; - -public class RenameStoreExchangeImpl extends RenameStoreExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws ClientException { - var s = getStoreEntryById(DataStoreId.fromString(msg.getStoreName()), true); - s.setName(msg.getNewName()); - return Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/SinkExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/SinkExchangeImpl.java deleted file mode 100644 index 79ddef7f0..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/SinkExchangeImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.exchange.SinkExchange; -import io.xpipe.core.store.ShellStore; - -public class SinkExchangeImpl extends SinkExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) throws Exception { - var ds = getStoreEntryById(msg.getSource(), false); - - if (!(ds.getStore() instanceof ShellStore)) { - throw new ClientException("Can't open file system for connection"); - } - - ShellStore store = ds.getStore().asNeeded(); - try (var fs = store.createFileSystem(); - var inputStream = handler.receiveBody(); - var output = fs.openOutput(msg.getPath(), -1)) { - inputStream.transferTo(output); - } - - return Response.builder().build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/StatusExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/StatusExchangeImpl.java deleted file mode 100644 index 520a2e913..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/StatusExchangeImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.cli.StatusExchange; - -public class StatusExchangeImpl extends StatusExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) { - String mode; - if (OperationMode.get() == null) { - mode = "none"; - } else { - mode = OperationMode.get().getId(); - } - - return Response.builder().mode(mode).build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java deleted file mode 100644 index df02c0b6d..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/StopExchangeImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.core.mode.OperationMode; -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.app.util.ThreadHelper; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.StopExchange; - -public class StopExchangeImpl extends StopExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) { - handler.postResponse(() -> { - ThreadHelper.runAsync(() -> { - ThreadHelper.sleep(1000); - OperationMode.close(); - }); - }); - return Response.builder().success(true).build(); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java deleted file mode 100644 index ee47a65a9..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/StoreAddExchangeImpl.java +++ /dev/null @@ -1,141 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.DialogExchangeImpl; -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.app.ext.DataStoreProvider; -import io.xpipe.app.ext.DataStoreProviders; -import io.xpipe.app.storage.DataStorage; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.exchange.cli.StoreAddExchange; -import io.xpipe.core.dialog.Choice; -import io.xpipe.core.dialog.Dialog; -import io.xpipe.core.dialog.QueryConverter; -import io.xpipe.core.store.DataStore; - -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; - -import lombok.SneakyThrows; - -import java.util.List; - -public class StoreAddExchangeImpl extends StoreAddExchange - implements MessageExchangeImpl { - - @Override - @SneakyThrows - public StoreAddExchange.Response handleRequest(BeaconHandler handler, Request msg) { - Dialog creatorDialog; - DataStoreProvider provider; - if (msg.getStoreInput() != null) { - creatorDialog = Dialog.empty().evaluateTo(msg::getStoreInput); - provider = null; - } else { - if (msg.getType() == null) { - throw new ClientException("Missing data store tight"); - } - - provider = DataStoreProviders.byName(msg.getType()).orElseThrow(() -> { - return new ClientException("Unrecognized data store type: " + msg.getType()); - }); - - creatorDialog = provider.dialogForStore(provider.defaultStore()); - } - - var name = new SimpleStringProperty(msg.getName()); - var completeDialog = createCompleteDialog(provider, creatorDialog, name); - var config = DialogExchangeImpl.add(completeDialog, (DataStore store) -> { - if (store == null) { - return; - } - - DataStorage.get().addStoreIfNotPresent(name.getValue(), store); - }); - - return StoreAddExchange.Response.builder().config(config).build(); - } - - private Dialog createCompleteDialog(DataStoreProvider provider, Dialog creator, StringProperty name) { - var validator = Dialog.header(() -> { - DataStore store = creator.getResult(); - if (store == null) { - return "Store is null"; - } - - return null; - }) - .map((String msg) -> { - return msg == null ? creator.getResult() : null; - }); - - var creatorAndValidator = Dialog.chain(creator, Dialog.busy(), validator); - - var nameQ = Dialog.retryIf( - Dialog.query("Store name", true, true, false, name.getValue(), QueryConverter.STRING), - (String r) -> { - return DataStorage.get().getStoreEntryIfPresent(r).isPresent() - ? "Store with name " + r + " already exists" - : null; - }) - .onCompletion((String n) -> name.setValue(n)); - - var display = Dialog.header(() -> { - if (provider == null) { - return "Successfully created data store " + name.get(); - } - - DataStore s = creator.getResult(); - String d = ""; - d = d.indent(2); - return "Successfully created data store " + name.get() + ":\n" + d; - }); - - if (provider == null) { - return Dialog.chain( - creatorAndValidator, Dialog.skipIf(display, () -> creatorAndValidator.getResult() == null)) - .evaluateTo(creatorAndValidator); - } - - var aborted = new SimpleBooleanProperty(); - var addStore = - Dialog.skipIf(Dialog.chain(nameQ, display), () -> aborted.get() || validator.getResult() == null); - - var prop = new SimpleObjectProperty(); - var fork = Dialog.skipIf( - Dialog.fork( - "Choose how to continue", - List.of( - new Choice('r', "Retry"), - new Choice('i', "Ignore and continue"), - new Choice('e', "Edit configuration"), - new Choice('a', "Abort")), - true, - 0, - (Integer choice) -> { - if (choice == 0) { - return Dialog.chain(Dialog.busy(), validator, prop.get()); - } - if (choice == 1) { - return null; - } - if (choice == 2) { - return Dialog.chain(creatorAndValidator, prop.get()); - } - if (choice == 3) { - aborted.set(true); - return null; - } - - throw new AssertionError(); - }) - .evaluateTo(() -> null), - () -> validator.getResult() != null); - prop.set(fork); - - return Dialog.chain(creatorAndValidator, fork, addStore) - .evaluateTo(() -> aborted.get() ? null : creator.getResult()); - } -} diff --git a/app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java b/app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java deleted file mode 100644 index b89861049..000000000 --- a/app/src/main/java/io/xpipe/app/exchange/cli/StoreProviderListExchangeImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.xpipe.app.exchange.cli; - -import io.xpipe.app.exchange.MessageExchangeImpl; -import io.xpipe.app.ext.DataStoreProvider; -import io.xpipe.app.ext.DataStoreProviders; -import io.xpipe.beacon.BeaconHandler; -import io.xpipe.beacon.exchange.cli.StoreProviderListExchange; -import io.xpipe.beacon.exchange.data.ProviderEntry; - -import java.util.Arrays; -import java.util.stream.Collectors; - -public class StoreProviderListExchangeImpl extends StoreProviderListExchange - implements MessageExchangeImpl { - - @Override - public Response handleRequest(BeaconHandler handler, Request msg) { - var categories = DataStoreProvider.CreationCategory.values(); - var all = DataStoreProviders.getAll(); - var map = Arrays.stream(categories) - .collect(Collectors.toMap(category -> getName(category), category -> all.stream() - .filter(dataStoreProvider -> category.equals(dataStoreProvider.getCreationCategory())) - .map(p -> ProviderEntry.builder() - .id(p.getId()) - .description(p.displayDescription().getValue()) - .hidden(p.getCreationCategory() == null) - .build()) - .toList())); - - return Response.builder().entries(map).build(); - } - - private String getName(DataStoreProvider.CreationCategory category) { - return category.name().substring(0, 1).toUpperCase() - + category.name().substring(1).toLowerCase(); - } -} diff --git a/app/src/main/java/io/xpipe/app/ext/ActionProvider.java b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java index 2d1ddad43..76d8f67b8 100644 --- a/app/src/main/java/io/xpipe/app/ext/ActionProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java @@ -33,10 +33,6 @@ public interface ActionProvider { return null; } - default boolean isActive() { - return true; - } - default String getProFeatureId() { return null; } @@ -45,7 +41,12 @@ public interface ActionProvider { return null; } - default DataStoreCallSite getDataStoreCallSite() { + default LeafDataStoreCallSite getLeafDataStoreCallSite() { + return null; + } + + + default BranchDataStoreCallSite getBranchDataStoreCallSite() { return null; } @@ -55,8 +56,6 @@ public interface ActionProvider { interface Action { - boolean requiresJavaFXPlatform(); - void execute() throws Exception; } @@ -89,6 +88,10 @@ public interface ActionProvider { default boolean isApplicable(DataStoreEntryRef o) { return true; } + + default boolean showBusy() { + return true; + } } interface DataStoreCallSite { @@ -97,14 +100,6 @@ public interface ActionProvider { return false; } - default boolean canLinkTo() { - return false; - } - - Action createAction(DataStoreEntryRef store); - - Class getApplicableClass(); - default boolean isMajor(DataStoreEntryRef o) { return false; } @@ -117,14 +112,30 @@ public interface ActionProvider { String getIcon(DataStoreEntryRef store); - default ActiveType activeType() { - return ActiveType.ONLY_SHOW_IF_ENABLED; + Class getApplicableClass(); + + default boolean showBusy() { + return true; + } + } + + interface BranchDataStoreCallSite extends DataStoreCallSite { + + default List getChildren() { + return List.of(); + } + } + + interface LeafDataStoreCallSite extends DataStoreCallSite { + + default boolean canLinkTo() { + return false; } - enum ActiveType { - ONLY_SHOW_IF_ENABLED, - ALWAYS_SHOW, - ALWAYS_ENABLE + Action createAction(DataStoreEntryRef store); + + default boolean requiresValidStore() { + return true; } } @@ -134,14 +145,6 @@ public interface ActionProvider { public void init(ModuleLayer layer) { ALL.addAll(ServiceLoader.load(layer, ActionProvider.class).stream() .map(actionProviderProvider -> actionProviderProvider.get()) - .filter(provider -> { - try { - return provider.isActive(); - } catch (Throwable e) { - ErrorEvent.fromThrowable(e).handle(); - return false; - } - }) .toList()); } } diff --git a/app/src/main/java/io/xpipe/app/ext/DataStorageExtensionProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStorageExtensionProvider.java new file mode 100644 index 000000000..946726769 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/ext/DataStorageExtensionProvider.java @@ -0,0 +1,31 @@ +package io.xpipe.app.ext; + +import io.xpipe.core.util.ModuleLayerLoader; + +import java.util.Comparator; +import java.util.List; +import java.util.ServiceLoader; +import java.util.stream.Collectors; + +public abstract class DataStorageExtensionProvider { + + private static List ALL; + + public static List getAll() { + return ALL; + } + + public void storageInit() throws Exception {} + + public static class Loader implements ModuleLayerLoader { + + @Override + public void init(ModuleLayer layer) { + ALL = ServiceLoader.load(layer, DataStorageExtensionProvider.class).stream() + .map(ServiceLoader.Provider::get) + .sorted(Comparator.comparing( + scanProvider -> scanProvider.getClass().getName())) + .collect(Collectors.toList()); + } + } +} diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java index b05302b02..b3cbaf3e1 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -12,10 +12,8 @@ import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; -import io.xpipe.core.dialog.Dialog; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.JacksonizedValue; - import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.Property; @@ -31,7 +29,9 @@ public interface DataStoreProvider { default boolean shouldShow(StoreEntryWrapper w) { return true; } - + + default void onChildrenRefresh(DataStoreEntry entry) {} + default ObservableBooleanValue busy(StoreEntryWrapper wrapper) { return new SimpleBooleanProperty(false); } @@ -196,10 +196,6 @@ public interface DataStoreProvider { return getModuleName() + ":" + getId() + "_icon.svg"; } - default Dialog dialogForStore(DataStore store) { - return null; - } - default DataStore defaultStore() { return null; } @@ -216,6 +212,7 @@ public interface DataStoreProvider { HOST, DATABASE, SHELL, + SERVICE, COMMAND, TUNNEL, SCRIPT, diff --git a/app/src/main/java/io/xpipe/app/ext/EnabledParentStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/EnabledParentStoreProvider.java new file mode 100644 index 000000000..24935e30d --- /dev/null +++ b/app/src/main/java/io/xpipe/app/ext/EnabledParentStoreProvider.java @@ -0,0 +1,40 @@ +package io.xpipe.app.ext; + +import io.xpipe.app.comp.base.StoreToggleComp; +import io.xpipe.app.comp.store.StoreEntryComp; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.comp.store.StoreViewState; +import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.core.store.EnabledStoreState; +import io.xpipe.core.store.StatefulDataStore; + +public interface EnabledParentStoreProvider extends DataStoreProvider { + + @Override + public default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { + if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { + return StoreEntryComp.create(sec.getWrapper(), null, preferLarge); + } + + var enabled = StoreToggleComp.>enableToggle( + null, sec, s -> s.getState().isEnabled(), (s, aBoolean) -> { + var state = s.getState().toBuilder().enabled(aBoolean).build(); + s.setState(state); + }); + + var e = sec.getWrapper().getEntry(); + var parent = DataStorage.get().getDefaultDisplayParent(e); + if (parent.isPresent()) { + var parentWrapper = StoreViewState.get().getEntryWrapper(parent.get()); + // Disable selection if parent is already made enabled + enabled.setCustomVisibility(BindingsHelper.map(parentWrapper.getPersistentState(), o -> { + EnabledStoreState state = (EnabledStoreState) o; + return !state.isEnabled(); + })); + } + + return StoreEntryComp.create(sec.getWrapper(), enabled, preferLarge); + } +} diff --git a/app/src/main/java/io/xpipe/app/ext/EnabledStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/EnabledStoreProvider.java new file mode 100644 index 000000000..d67a9b20c --- /dev/null +++ b/app/src/main/java/io/xpipe/app/ext/EnabledStoreProvider.java @@ -0,0 +1,25 @@ +package io.xpipe.app.ext; + +import io.xpipe.app.comp.base.StoreToggleComp; +import io.xpipe.app.comp.store.StoreEntryComp; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.core.store.EnabledStoreState; +import io.xpipe.core.store.StatefulDataStore; + +public interface EnabledStoreProvider extends DataStoreProvider { + + @Override + public default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { + if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { + return StoreEntryComp.create(sec.getWrapper(), null, preferLarge); + } + + var enabled = StoreToggleComp.>enableToggle( + null, sec, s -> s.getState().isEnabled(), (s, aBoolean) -> { + var state = s.getState().toBuilder().enabled(aBoolean).build(); + s.setState(state); + }); + return StoreEntryComp.create(sec.getWrapper(), enabled, preferLarge); + } +} diff --git a/app/src/main/java/io/xpipe/app/ext/ExtensionException.java b/app/src/main/java/io/xpipe/app/ext/ExtensionException.java index bd7b0c238..e26db7670 100644 --- a/app/src/main/java/io/xpipe/app/ext/ExtensionException.java +++ b/app/src/main/java/io/xpipe/app/ext/ExtensionException.java @@ -21,6 +21,6 @@ public class ExtensionException extends RuntimeException { } public static ExtensionException corrupt(String message) { - return new ExtensionException(message + ". Is the installation corrupt?"); + return new ExtensionException(message + ". Is the installation data corrupt?"); } } diff --git a/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java index 1a0e42442..720da1111 100644 --- a/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java @@ -6,12 +6,14 @@ import io.xpipe.app.comp.store.StoreEntryComp; import io.xpipe.app.comp.store.StoreEntryWrapper; import io.xpipe.app.comp.store.StoreSection; import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.store.SingletonSessionStore; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableBooleanValue; +import javafx.beans.value.ObservableValue; public interface SingletonSessionStoreProvider extends DataStoreProvider { @@ -38,7 +40,9 @@ public interface SingletonSessionStoreProvider extends DataStoreProvider { enabled.set(s.isSessionEnabled()); }); - var t = new StoreToggleComp(null, sec, enabled, aBoolean -> { + ObservableValue g = enabled.map(aBoolean -> aBoolean ? + new LabelGraphic.IconGraphic("mdi2c-circle-slice-8") : new LabelGraphic.IconGraphic("mdi2p-power")); + var t = new StoreToggleComp(null, g, sec, enabled, aBoolean -> { SingletonSessionStore s = sec.getWrapper().getEntry().getStore().asNeeded(); if (s.isSessionEnabled() != aBoolean) { ThreadHelper.runFailableAsync(() -> { @@ -50,6 +54,7 @@ public interface SingletonSessionStoreProvider extends DataStoreProvider { }); } }); + t.tooltipKey("enabled"); return t; } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java index 94c05144e..438247b0e 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java @@ -53,12 +53,12 @@ public class IconButtonComp extends Comp> { }); // fi.iconColorProperty().bind(button.textFillProperty()); button.setGraphic(fi); - button.setOnAction(e -> { - if (listener != null) { + if (listener != null) { + button.setOnAction(e -> { listener.run(); e.consume(); - } - }); + }); + } button.getStyleClass().add("icon-button-comp"); return new SimpleCompStructure<>(button); } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java index c461917c7..f85aeda68 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java @@ -79,7 +79,7 @@ public class StoreCategoryComp extends SimpleComp { })); var shownList = new DerivedObservableList<>(category.getContainedEntries(), true).filtered( storeEntryWrapper -> { - return storeEntryWrapper.shouldShow( + return storeEntryWrapper.matchesFilter( StoreViewState.get().getFilterString().getValue()); }, StoreViewState.get().getFilterString()).getList(); diff --git a/app/src/main/java/io/xpipe/app/fxcomps/util/DerivedObservableList.java b/app/src/main/java/io/xpipe/app/fxcomps/util/DerivedObservableList.java index 166bf3ef7..cd8102588 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/util/DerivedObservableList.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/util/DerivedObservableList.java @@ -129,9 +129,17 @@ public class DerivedObservableList { } public DerivedObservableList mapped(Function map) { + var cache = new HashMap(); var l1 = this.createNewDerived(); Runnable runnable = () -> { - l1.setContent(list.stream().map(map).toList()); + cache.keySet().removeIf(t -> !getList().contains(t)); + l1.setContent(list.stream().map(v -> { + if (!cache.containsKey(v)) { + cache.put(v, map.apply(v)); + } + + return cache.get(v); + }).toList()); }; runnable.run(); list.addListener((ListChangeListener) c -> { diff --git a/app/src/main/java/io/xpipe/app/fxcomps/util/LabelGraphic.java b/app/src/main/java/io/xpipe/app/fxcomps/util/LabelGraphic.java new file mode 100644 index 000000000..475300f19 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/fxcomps/util/LabelGraphic.java @@ -0,0 +1,42 @@ +package io.xpipe.app.fxcomps.util; + +import io.xpipe.app.fxcomps.Comp; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; +import javafx.scene.Node; +import lombok.EqualsAndHashCode; +import lombok.Value; +import org.kordamp.ikonli.javafx.FontIcon; + +public abstract class LabelGraphic { + + public static ObservableValue fixedIcon(String icon) { + return new SimpleObjectProperty<>(new IconGraphic(icon)); + } + + public abstract Node createGraphicNode(); + + @Value + @EqualsAndHashCode(callSuper = true) + public static class IconGraphic extends LabelGraphic { + + String icon; + + @Override + public Node createGraphicNode() { + return new FontIcon(icon); + } + } + + @Value + @EqualsAndHashCode(callSuper = true) + public static class CompGraphic extends LabelGraphic { + + Comp comp; + + @Override + public Node createGraphicNode() { + return comp.createRegion(); + } + } +} diff --git a/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java b/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java index b47f84e64..5ac652703 100644 --- a/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java +++ b/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java @@ -1,5 +1,6 @@ package io.xpipe.app.launcher; +import io.xpipe.app.beacon.AppBeaconServer; import io.xpipe.app.core.AppDataLock; import io.xpipe.app.core.AppLogs; import io.xpipe.app.core.AppProperties; @@ -9,13 +10,13 @@ import io.xpipe.app.issue.LogErrorHandler; import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.util.ThreadHelper; -import io.xpipe.beacon.BeaconServer; -import io.xpipe.beacon.exchange.FocusExchange; -import io.xpipe.beacon.exchange.OpenExchange; +import io.xpipe.beacon.BeaconClient; +import io.xpipe.beacon.BeaconClientInformation; +import io.xpipe.beacon.api.DaemonFocusExchange; +import io.xpipe.beacon.api.DaemonOpenExchange; import io.xpipe.core.process.OsType; import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeInstallation; - import lombok.SneakyThrows; import picocli.CommandLine; @@ -81,26 +82,25 @@ public class LauncherCommand implements Callable { private void checkStart() { try { - if (BeaconServer.isReachable()) { - try (var con = new LauncherConnection()) { - con.constructSocket(); - con.performSimpleExchange(FocusExchange.Request.builder() - .mode(getEffectiveMode()) - .build()); + var port = AppBeaconServer.get().getPort(); + var client = BeaconClient.tryEstablishConnection(port, BeaconClientInformation.Daemon.builder().build()); + if (client.isPresent()) { + client.get().performRequest(DaemonFocusExchange.Request.builder().mode(getEffectiveMode()).build()); if (!inputs.isEmpty()) { - con.performSimpleExchange( - OpenExchange.Request.builder().arguments(inputs).build()); + client.get().performRequest( + DaemonOpenExchange.Request.builder().arguments(inputs).build()); } if (OsType.getLocal().equals(OsType.MACOS)) { Desktop.getDesktop().setOpenURIHandler(e -> { - con.performSimpleExchange(OpenExchange.Request.builder() - .arguments(List.of(e.getURI().toString())) - .build()); + try { + client.get().performRequest(DaemonOpenExchange.Request.builder().arguments(List.of(e.getURI().toString())).build()); + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).expected().omit().handle(); + } }); ThreadHelper.sleep(1000); } - } TrackEvent.info("Another instance is already running on this port. Quitting ..."); OperationMode.halt(1); } diff --git a/app/src/main/java/io/xpipe/app/launcher/LauncherConnection.java b/app/src/main/java/io/xpipe/app/launcher/LauncherConnection.java deleted file mode 100644 index fdbe0a25c..000000000 --- a/app/src/main/java/io/xpipe/app/launcher/LauncherConnection.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.xpipe.app.launcher; - -import io.xpipe.beacon.BeaconClient; -import io.xpipe.beacon.BeaconConnection; -import io.xpipe.beacon.BeaconException; - -public class LauncherConnection extends BeaconConnection { - - @Override - protected void constructSocket() { - try { - beaconClient = BeaconClient.establishConnection( - BeaconClient.DaemonInformation.builder().build()); - } catch (Exception ex) { - throw new BeaconException("Unable to connect to running xpipe daemon", ex); - } - } -} diff --git a/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java b/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java index adf5d47a3..070cdc212 100644 --- a/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java +++ b/app/src/main/java/io/xpipe/app/launcher/LauncherInput.java @@ -2,7 +2,6 @@ package io.xpipe.app.launcher; import io.xpipe.app.browser.session.BrowserSessionModel; import io.xpipe.app.core.AppLayoutModel; -import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.TrackEvent; @@ -34,17 +33,13 @@ public abstract class LauncherInput { } }); - var requiresPlatform = all.stream().anyMatch(launcherInput -> launcherInput.requiresJavaFXPlatform()); - if (requiresPlatform) { - OperationMode.switchToSyncIfPossible(OperationMode.GUI); - } - var hasGui = OperationMode.get() == OperationMode.GUI; +// var requiresPlatform = all.stream().anyMatch(launcherInput -> launcherInput.requiresJavaFXPlatform()); +// if (requiresPlatform) { +// OperationMode.switchToSyncIfPossible(OperationMode.GUI); +// } +// var hasGui = OperationMode.get() == OperationMode.GUI; all.forEach(launcherInput -> { - if (!hasGui && launcherInput.requiresJavaFXPlatform()) { - return; - } - try { launcherInput.execute(); } catch (Exception e) { @@ -102,11 +97,6 @@ public abstract class LauncherInput { Path file; - @Override - public boolean requiresJavaFXPlatform() { - return true; - } - @Override public void execute() { if (!Files.exists(file)) { diff --git a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java index 2765b7b10..a2e7e3582 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java @@ -14,14 +14,13 @@ import io.xpipe.app.terminal.ExternalTerminalType; import io.xpipe.app.util.PasswordLockSecretValue; import io.xpipe.core.util.InPlaceSecretValue; import io.xpipe.core.util.ModuleHelper; - +import io.xpipe.core.util.XPipeInstallation; import javafx.beans.binding.Bindings; import javafx.beans.property.*; import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableDoubleValue; import javafx.beans.value.ObservableStringValue; import javafx.beans.value.ObservableValue; - import lombok.Getter; import lombok.Value; @@ -121,6 +120,25 @@ public class AppPrefs { private final StringProperty lockCrypt = mapVaultSpecific(new SimpleStringProperty(), "workspaceLock", String.class); + final Property httpServerPort = + mapVaultSpecific(new SimpleObjectProperty<>(XPipeInstallation.getDefaultBeaconPort()), "httpServerPort", Integer.class); + final StringProperty apiKey = + mapVaultSpecific(new SimpleStringProperty(UUID.randomUUID().toString()), "apiKey", String.class); + final BooleanProperty disableApiAuthentication = + mapVaultSpecific(new SimpleBooleanProperty(false), "disableApiAuthentication", Boolean.class); + + public ObservableValue httpServerPort() { + return httpServerPort; + } + + public ObservableStringValue apiKey() { + return apiKey; + } + + public ObservableBooleanValue disableApiAuthentication() { + return disableApiAuthentication; + } + private final IntegerProperty editorReloadTimeout = map(new SimpleIntegerProperty(1000), "editorReloadTimeout", Integer.class); private final BooleanProperty confirmDeletions = @@ -153,6 +171,7 @@ public class AppPrefs { new SshCategory(), new LocalShellCategory(), new SecurityCategory(), + new HttpApiCategory(), new TroubleshootCategory(), new DeveloperCategory()) .filter(appPrefsCategory -> appPrefsCategory.show()) @@ -435,12 +454,8 @@ public class AppPrefs { } public void initDefaultValues() { - if (externalEditor.get() == null) { - ExternalEditorType.detectDefault(); - } - + externalEditor.setValue(ExternalEditorType.detectDefault(externalEditor.get())); terminalType.set(ExternalTerminalType.determineDefault(terminalType.get())); - if (rdpClientType.get() == null) { rdpClientType.setValue(ExternalRdpClientType.determineDefault()); } diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java index 58ebf9b10..e992eebb3 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java @@ -45,16 +45,17 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue { @Override public boolean isAvailable() { try (ShellControl pc = LocalShell.getShell().start()) { - return pc.command(String.format( + var out = pc.command(String.format( "mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications", applicationName)) - .executeAndCheck(); + .readStdoutIfPossible(); + return out.isPresent() && !out.get().isBlank(); } catch (Exception e) { ErrorEvent.fromThrowable(e).handle(); return false; } } - + @Override public boolean isSelectable() { return OsType.getLocal().equals(OsType.MACOS); diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java index dce1a5635..750980263 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java @@ -145,43 +145,34 @@ public interface ExternalEditorType extends PrefsChoiceValue { }) .get(); - static void detectDefault() { - var typeProperty = AppPrefs.get().externalEditor; - var customProperty = AppPrefs.get().customEditorCommand; + static ExternalEditorType detectDefault(ExternalEditorType existing) { + // Verify that our selection is still valid + if (existing != null && existing.isAvailable()) { + return existing; + } + if (OsType.getLocal().equals(OsType.WINDOWS)) { - typeProperty.set(WINDOWS_EDITORS.stream() + return WINDOWS_EDITORS.stream() .filter(PrefsChoiceValue::isAvailable) .findFirst() - .orElse(null)); + .orElse(null); } if (OsType.getLocal().equals(OsType.LINUX)) { - var env = System.getenv("VISUAL"); - if (env != null) { - var found = LINUX_EDITORS.stream() - .filter(externalEditorType -> externalEditorType.executable.equalsIgnoreCase(env)) - .findFirst() - .orElse(null); - if (found == null) { - typeProperty.set(CUSTOM); - customProperty.set(env); - } else { - typeProperty.set(found); - } - } else { - typeProperty.set(LINUX_EDITORS.stream() - .filter(ExternalApplicationType.PathApplication::isAvailable) - .findFirst() - .orElse(null)); - } + return LINUX_EDITORS.stream() + .filter(ExternalApplicationType.PathApplication::isAvailable) + .findFirst() + .orElse(null); } if (OsType.getLocal().equals(OsType.MACOS)) { - typeProperty.set(MACOS_EDITORS.stream() + return MACOS_EDITORS.stream() .filter(PrefsChoiceValue::isAvailable) .findFirst() - .orElse(null)); + .orElse(null); } + + return null; } void launch(Path file) throws Exception; @@ -194,10 +185,10 @@ public interface ExternalEditorType extends PrefsChoiceValue { @Override public void launch(Path file) throws Exception { - ExternalApplicationHelper.startAsync(CommandBuilder.of() - .add("open", "-a") - .addQuoted(applicationName) - .addFile(file.toString())); + try (var sc = LocalShell.getShell().start()) { + sc.executeSimpleCommand(CommandBuilder.of() + .add("open", "-a").addQuoted(applicationName).addFile(file.toString())); + } } } diff --git a/app/src/main/java/io/xpipe/app/prefs/HttpApiCategory.java b/app/src/main/java/io/xpipe/app/prefs/HttpApiCategory.java new file mode 100644 index 000000000..94bcf2ba3 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/prefs/HttpApiCategory.java @@ -0,0 +1,30 @@ +package io.xpipe.app.prefs; + +import io.xpipe.app.beacon.AppBeaconServer; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.util.OptionsBuilder; + +public class HttpApiCategory extends AppPrefsCategory { + + @Override + protected String getId() { + return "httpApi"; + } + + @Override + protected Comp create() { + var prefs = AppPrefs.get(); + return new OptionsBuilder() + .addTitle("httpServerConfiguration") + .sub(new OptionsBuilder() + .nameAndDescription("httpServerPort") + .addInteger(prefs.httpServerPort) + .disable(AppBeaconServer.get().isPropertyPort()) + .nameAndDescription("apiKey") + .addString(prefs.apiKey) + .nameAndDescription("disableApiAuthentication") + .addToggle(prefs.disableApiAuthentication) + ) + .buildComp(); + } +} diff --git a/app/src/main/java/io/xpipe/app/prefs/SyncCategory.java b/app/src/main/java/io/xpipe/app/prefs/SyncCategory.java index 62431effe..f88ef002b 100644 --- a/app/src/main/java/io/xpipe/app/prefs/SyncCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/SyncCategory.java @@ -2,6 +2,7 @@ package io.xpipe.app.prefs; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.core.AppI18n; +import io.xpipe.app.core.AppProperties; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.util.DesktopHelper; @@ -19,8 +20,10 @@ public class SyncCategory extends AppPrefsCategory { var builder = new OptionsBuilder(); builder.addTitle("sync") .sub(new OptionsBuilder() - .nameAndDescription("enableGitStorage") + .name("enableGitStorage") + .description(AppProperties.get().isStaging() ? "enableGitStoragePtbDisabled" : "enableGitStorage") .addToggle(prefs.enableGitStorage) + .disable(AppProperties.get().isStaging()) .nameAndDescription("storageGitRemote") .addString(prefs.storageGitRemote, true) .disable(prefs.enableGitStorage.not()) diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index dbdac50ce..c1712a540 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -5,11 +5,12 @@ import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.util.FixedHierarchyStore; import io.xpipe.app.util.ThreadHelper; -import io.xpipe.core.store.*; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FixedChildStore; +import io.xpipe.core.store.LocalStore; +import io.xpipe.core.store.StorePath; import io.xpipe.core.util.UuidHelper; - import javafx.util.Pair; - import lombok.Getter; import lombok.NonNull; import lombok.Setter; @@ -20,7 +21,6 @@ import java.time.Instant; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -61,6 +61,8 @@ public abstract class DataStorage { @Setter protected DataStoreCategory selectedCategory; + private final Map storeEntryMapCache = Collections.synchronizedMap(new IdentityHashMap<>()); + public DataStorage() { var prefsDir = AppPrefs.get().storageDirectory().getValue(); this.dir = !Files.exists(prefsDir) || !Files.isDirectory(prefsDir) ? AppPrefs.DEFAULT_STORAGE_DIR : prefsDir; @@ -260,16 +262,10 @@ public abstract class DataStorage { return true; } - protected void refreshValidities(boolean makeValid) { - var changed = new AtomicBoolean(false); - do { - changed.set(false); - storeEntries.keySet().forEach(dataStoreEntry -> { - if (makeValid ? dataStoreEntry.tryMakeValid() : dataStoreEntry.tryMakeInvalid()) { - changed.set(true); - } - }); - } while (changed.get()); + protected void refreshEntries() { + storeEntries.keySet().forEach(dataStoreEntry -> { + dataStoreEntry.refreshStore(); + }); } public void updateEntry(DataStoreEntry entry, DataStoreEntry newEntry) { @@ -299,8 +295,7 @@ public abstract class DataStorage { var toAdd = Stream.concat(Stream.of(entry), children.stream()).toArray(DataStoreEntry[]::new); listeners.forEach(storageListener -> storageListener.onStoreAdd(toAdd)); } - refreshValidities(true); - + refreshEntries(); saveAsync(); } @@ -345,21 +340,21 @@ public abstract class DataStorage { return false; } - e.setInRefresh(true); + e.incrementBusyCounter(); List> newChildren; try { newChildren = ((FixedHierarchyStore) (e.getStore())).listChildren(e); - e.setInRefresh(false); } catch (Exception ex) { - e.setInRefresh(false); ErrorEvent.fromThrowable(ex).handle(); return false; + } finally { + e.decrementBusyCounter(); } - var oldChildren = getStoreEntries().stream() - .filter(other -> e.equals(getDefaultDisplayParent(other).orElse(null))) - .toList(); + + var oldChildren = getStoreChildren(e); var toRemove = oldChildren.stream() + .filter(oc -> oc.getStore() instanceof FixedChildStore) .filter(oc -> { var oid = ((FixedChildStore) oc.getStore()).getFixedId(); if (oid.isEmpty()) { @@ -375,6 +370,10 @@ public abstract class DataStorage { .toList(); var toAdd = newChildren.stream() .filter(nc -> { + if (nc.getStore() == null) { + return false; + } + var nid = nc.getStore().getFixedId(); // These can't be automatically generated if (nid.isEmpty()) { @@ -382,6 +381,7 @@ public abstract class DataStorage { } return oldChildren.stream() + .filter(oc -> oc.getStore() instanceof FixedChildStore) .filter(oc -> ((FixedChildStore) oc.getStore()) .getFixedId() .isPresent()) @@ -394,6 +394,7 @@ public abstract class DataStorage { }) .toList(); var toUpdate = oldChildren.stream() + .filter(oc -> oc.getStore() instanceof FixedChildStore) .map(oc -> { var oid = ((FixedChildStore) oc.getStore()).getFixedId(); if (oid.isEmpty()) { @@ -445,7 +446,10 @@ public abstract class DataStorage { } } }); + refreshEntries(); saveAsync(); + toAdd.forEach(dataStoreEntryRef -> dataStoreEntryRef.get().getProvider().onChildrenRefresh(dataStoreEntryRef.getEntry())); + toUpdate.forEach(dataStoreEntryRef -> dataStoreEntryRef.getKey().getProvider().onChildrenRefresh(dataStoreEntryRef.getKey())); return !newChildren.isEmpty(); } @@ -458,7 +462,7 @@ public abstract class DataStorage { c.forEach(entry -> entry.finalizeEntry()); this.storeEntriesSet.removeAll(c); this.listeners.forEach(l -> l.onStoreRemove(c.toArray(DataStoreEntry[]::new))); - refreshValidities(false); + refreshEntries(); saveAsync(); } @@ -477,7 +481,7 @@ public abstract class DataStorage { toDelete.forEach(entry -> entry.finalizeEntry()); toDelete.forEach(this.storeEntriesSet::remove); this.listeners.forEach(l -> l.onStoreRemove(toDelete.toArray(DataStoreEntry[]::new))); - refreshValidities(false); + refreshEntries(); saveAsync(); } @@ -532,7 +536,7 @@ public abstract class DataStorage { this.listeners.forEach(l -> l.onStoreAdd(e)); e.initializeEntry(); - refreshValidities(true); + e.refreshStore(); return e; } @@ -566,11 +570,13 @@ public abstract class DataStorage { p.setChildrenCache(null); }); } + for (DataStoreEntry e : toAdd) { + e.refreshStore(); + } this.listeners.forEach(l -> l.onStoreAdd(toAdd.toArray(DataStoreEntry[]::new))); for (DataStoreEntry e : toAdd) { e.initializeEntry(); } - refreshValidities(true); saveAsync(); } @@ -598,7 +604,7 @@ public abstract class DataStorage { this.storeEntries.remove(store); getDefaultDisplayParent(store).ifPresent(p -> p.setChildrenCache(null)); this.listeners.forEach(l -> l.onStoreRemove(store)); - refreshValidities(false); + refreshEntries(); saveAsync(); } @@ -734,6 +740,22 @@ public abstract class DataStorage { return children; } + public List getCategoryParentHierarchy(DataStoreCategory cat) { + var es = new ArrayList(); + es.add(cat); + + DataStoreCategory current = cat; + while ((current = getStoreCategoryIfPresent(current.getParentCategory()).orElse(null)) != null) { + if (es.contains(current)) { + break; + } + + es.addFirst(current); + } + + return es; + } + public List getStoreParentHierarchy(DataStoreEntry entry) { var es = new ArrayList(); es.add(entry); @@ -750,34 +772,17 @@ public abstract class DataStorage { return es; } - public DataStoreId getId(DataStoreEntry entry) { - return DataStoreId.create(getStoreParentHierarchy(entry).stream() + public StorePath getStorePath(DataStoreEntry entry) { + return StorePath.create(getStoreParentHierarchy(entry).stream() .filter(e -> !(e.getStore() instanceof LocalStore)) - .map(e -> e.getName().replaceAll(":", "_")) + .map(e -> e.getName().toLowerCase().replaceAll("/", "_")) .toArray(String[]::new)); } - public Optional getStoreEntryIfPresent(@NonNull DataStoreId id) { - var current = getStoreEntryIfPresent(id.getNames().getFirst()); - if (current.isPresent()) { - for (int i = 1; i < id.getNames().size(); i++) { - var children = getStoreChildren(current.get()); - int finalI = i; - current = children.stream() - .filter(dataStoreEntry -> dataStoreEntry - .getName() - .equalsIgnoreCase(id.getNames().get(finalI))) - .findFirst(); - if (current.isEmpty()) { - break; - } - } - - if (current.isPresent()) { - return current; - } - } - return Optional.empty(); + public StorePath getStorePath(DataStoreCategory entry) { + return StorePath.create(getCategoryParentHierarchy(entry).stream() + .map(e -> e.getName().toLowerCase().replaceAll("/", "_")) + .toArray(String[]::new)); } public Optional getStoreEntryInProgressIfPresent(@NonNull DataStore store) { @@ -787,12 +792,29 @@ public abstract class DataStorage { } public Optional getStoreEntryIfPresent(@NonNull DataStore store, boolean identityOnly) { - return storeEntriesSet.stream() + if (identityOnly) { + synchronized (storeEntryMapCache) { + var found = storeEntryMapCache.get(store); + if (found != null) { + return Optional.of(found); + } + } + } + + var found = storeEntriesSet.stream() .filter(n -> n.getStore() == store || (!identityOnly && (n.getStore() != null && Objects.equals( store.getClass(), n.getStore().getClass()) && store.equals(n.getStore())))) .findFirst(); + if (found.isPresent()) { + if (identityOnly) { + synchronized (storeEntryMapCache) { + storeEntryMapCache.put(store, found.get()); + } + } + } + return found; } public DataStoreCategory getRootCategory(DataStoreCategory category) { @@ -854,12 +876,22 @@ public abstract class DataStorage { } public DataStoreEntry getOrCreateNewSyntheticEntry(DataStoreEntry parent, String name, DataStore store) { + var forStoreIdentity = getStoreEntryIfPresent(store, true); + if (forStoreIdentity.isPresent()) { + return forStoreIdentity.get(); + } + var uuid = UuidHelper.generateFromObject(parent.getUuid(), name); var found = getStoreEntryIfPresent(uuid); if (found.isPresent()) { return found.get(); } + var forStore = getStoreEntryIfPresent(store, false); + if (forStore.isPresent()) { + return forStore.get(); + } + return DataStoreEntry.createNew(uuid, parent.getCategoryUuid(), name, store); } diff --git a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java index 0b705df86..f4455869e 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -21,6 +21,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.Instant; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -46,8 +47,7 @@ public class DataStoreEntry extends StorageElement { @NonFinal boolean expanded; - @NonFinal - boolean inRefresh; + AtomicInteger busyCounter = new AtomicInteger(); @Getter @NonFinal @@ -323,14 +323,21 @@ public class DataStoreEntry extends StorageElement { return getName(); } - public void setInRefresh(boolean newRefresh) { - var changed = inRefresh != newRefresh; - if (changed) { - this.inRefresh = newRefresh; + public void incrementBusyCounter() { + var r = busyCounter.incrementAndGet() == 1; + if (r) { notifyUpdate(false, false); } } + public boolean decrementBusyCounter() { + var r = busyCounter.decrementAndGet() == 0; + if (r) { + notifyUpdate(false, false); + } + return r; + } + public DataStoreEntryRef ref() { return new DataStoreEntryRef<>(this); } @@ -503,7 +510,7 @@ public class DataStoreEntry extends StorageElement { try { store.checkComplete(); - setInRefresh(true); + incrementBusyCounter(); if (store instanceof ValidatableStore l) { l.validate(); } else if (store instanceof FixedHierarchyStore h) { @@ -512,32 +519,27 @@ public class DataStoreEntry extends StorageElement { .collect(Collectors.toSet()); } } finally { - setInRefresh(false); + decrementBusyCounter(); } } - public boolean tryMakeValid() { + public void refreshStore() { if (validity == Validity.LOAD_FAILED) { - return false; - } - - var complete = validity == Validity.COMPLETE; - if (complete) { - return false; + return; } var newStore = DataStorageParser.storeFromNode(storeNode); if (newStore == null) { store = null; validity = Validity.LOAD_FAILED; - return true; + return; } var newComplete = newStore.isComplete(); if (!newComplete) { validity = Validity.INCOMPLETE; store = newStore; - return false; + return; } if (!newStore.equals(store)) { @@ -546,52 +548,19 @@ public class DataStoreEntry extends StorageElement { validity = Validity.COMPLETE; // Don't count this as modification as this is done always notifyUpdate(false, false); - return true; - } - - public boolean tryMakeInvalid() { - if (validity == Validity.LOAD_FAILED) { - return false; - } - - if (validity == Validity.INCOMPLETE) { - return false; - } - - var newStore = DataStorageParser.storeFromNode(storeNode); - if (newStore == null) { - store = null; - validity = Validity.LOAD_FAILED; - return true; - } - - var newComplete = newStore.isComplete(); - if (newComplete) { - validity = Validity.COMPLETE; - store = newStore; - return false; - } - - if (!newStore.equals(store)) { - store = newStore; - } - validity = Validity.INCOMPLETE; - notifyUpdate(false, false); - return true; } @SneakyThrows public void initializeEntry() { if (store instanceof ExpandedLifecycleStore lifecycleStore) { try { - inRefresh = true; + incrementBusyCounter(); notifyUpdate(false, false); lifecycleStore.initializeValidate(); - inRefresh = false; } catch (Exception e) { - inRefresh = false; ErrorEvent.fromThrowable(e).handle(); } finally { + decrementBusyCounter(); notifyUpdate(false, false); } } @@ -601,12 +570,13 @@ public class DataStoreEntry extends StorageElement { public void finalizeEntry() { if (store instanceof ExpandedLifecycleStore lifecycleStore) { try { - inRefresh = true; + incrementBusyCounter(); notifyUpdate(false, false); lifecycleStore.finalizeValidate(); } catch (Exception e) { ErrorEvent.fromThrowable(e).handle(); } finally { + decrementBusyCounter(); notifyUpdate(false, false); } } diff --git a/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java b/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java index e352def66..8d11a11d0 100644 --- a/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/ImpersistentStorage.java @@ -1,13 +1,8 @@ package io.xpipe.app.storage; import io.xpipe.app.comp.store.StoreSortMode; -import io.xpipe.app.issue.ErrorEvent; -import io.xpipe.app.issue.TrackEvent; import io.xpipe.core.store.LocalStore; -import org.apache.commons.io.FileUtils; - -import java.nio.file.Files; import java.time.Instant; import java.util.UUID; @@ -20,22 +15,17 @@ public class ImpersistentStorage extends DataStorage { @Override public void load() { - var storesDir = getStoresDir(); - var categoriesDir = getCategoriesDir(); - { var cat = DataStoreCategory.createNew(null, ALL_CONNECTIONS_CATEGORY_UUID, "All connections"); - cat.setDirectory(categoriesDir.resolve(ALL_CONNECTIONS_CATEGORY_UUID.toString())); storeCategories.add(cat); } { var cat = DataStoreCategory.createNew(null, ALL_SCRIPTS_CATEGORY_UUID, "All scripts"); - cat.setDirectory(categoriesDir.resolve(ALL_SCRIPTS_CATEGORY_UUID.toString())); storeCategories.add(cat); } { var cat = new DataStoreCategory( - categoriesDir.resolve(DEFAULT_CATEGORY_UUID.toString()), + null, DEFAULT_CATEGORY_UUID, "Default", Instant.now(), @@ -50,7 +40,6 @@ public class ImpersistentStorage extends DataStorage { var e = DataStoreEntry.createNew( LOCAL_ID, DataStorage.DEFAULT_CATEGORY_UUID, "Local Machine", new LocalStore()); - e.setDirectory(getStoresDir().resolve(LOCAL_ID.toString())); e.setConfiguration( StorageElement.Configuration.builder().deletable(false).build()); storeEntries.put(e, e); @@ -58,18 +47,7 @@ public class ImpersistentStorage extends DataStorage { } @Override - public synchronized void save(boolean dispose) { - var storesDir = getStoresDir(); - - TrackEvent.info("Storage persistence is disabled. Deleting storage contents ..."); - try { - if (Files.exists(storesDir)) { - FileUtils.cleanDirectory(storesDir.toFile()); - } - } catch (Exception ex) { - ErrorEvent.fromThrowable(ex).build().handle(); - } - } + public synchronized void save(boolean dispose) {} @Override public boolean supportsSharing() { diff --git a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java index 34958fbaa..1a64ee96a 100644 --- a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java @@ -1,11 +1,11 @@ package io.xpipe.app.storage; +import io.xpipe.app.ext.DataStorageExtensionProvider; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.core.process.OsType; import io.xpipe.core.store.LocalStore; - import lombok.Getter; import org.apache.commons.io.FileUtils; @@ -197,14 +197,15 @@ public class StandardStorage extends DataStorage { local.setColor(DataStoreColor.BLUE); } - refreshValidities(true); + callProviders(); + refreshEntries(); storeEntriesSet.forEach(entry -> { var syntheticParent = getSyntheticParent(entry); syntheticParent.ifPresent(entry1 -> { addStoreEntryIfNotPresent(entry1); }); }); - refreshValidities(true); + refreshEntries(); // Save to apply changes if (!hasFixedLocal) { @@ -226,6 +227,16 @@ public class StandardStorage extends DataStorage { this.gitStorageHandler.afterStorageLoad(); } + private void callProviders() { + DataStorageExtensionProvider.getAll().forEach(p -> { + try { + p.storageInit(); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + } + }); + } + public void save(boolean dispose) { try { // If another save operation is in progress, we have to wait on dispose diff --git a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java index 5fa676473..e281f21a2 100644 --- a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java +++ b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java @@ -238,6 +238,35 @@ public interface ExternalTerminalType extends PrefsChoiceValue { .addFile(configuration.getScriptFile()); } }; + ExternalTerminalType FOOT = new SimplePathType("app.foot", "foot", true) { + @Override + public String getWebsite() { + return "https://codeberg.org/dnkl/foot"; + } + + @Override + public boolean supportsTabs() { + return false; + } + + @Override + public boolean isRecommended() { + return false; + } + + @Override + public boolean supportsColoredTitle() { + return true; + } + + @Override + protected CommandBuilder toCommand(LaunchConfiguration configuration) { + return CommandBuilder.of() + .add("--title") + .addQuoted(configuration.getColoredTitle()) + .addFile(configuration.getScriptFile()); + } + }; ExternalTerminalType ELEMENTARY = new SimplePathType("app.elementaryTerminal", "io.elementary.terminal", true) { @Override @@ -262,7 +291,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue { @Override protected CommandBuilder toCommand(LaunchConfiguration configuration) { - return CommandBuilder.of().add("--new-tab").add("-e").addFile(configuration.getColoredTitle()); + return CommandBuilder.of().add("--new-tab").add("-e").addFile(configuration.getScriptFile()); } }; ExternalTerminalType TILIX = new SimplePathType("app.tilix", "tilix", true) { @@ -514,17 +543,11 @@ public interface ExternalTerminalType extends PrefsChoiceValue { @Override public void launch(LaunchConfiguration configuration) throws Exception { - try (ShellControl pc = LocalShell.getShell()) { - var suffix = "\"" + configuration.getScriptFile().toString().replaceAll("\"", "\\\\\"") + "\""; - pc.osascriptCommand(String.format( - """ - activate application "Terminal" - delay 1 - tell app "Terminal" to do script %s - """, - suffix)) - .execute(); - } + LocalShell.getShell() + .executeSimpleCommand(CommandBuilder.of() + .add("open", "-a") + .addQuoted("Terminal.app") + .addFile(configuration.getScriptFile())); } }; ExternalTerminalType ITERM2 = new MacOsType("app.iterm2", "iTerm") { @@ -550,26 +573,11 @@ public interface ExternalTerminalType extends PrefsChoiceValue { @Override public void launch(LaunchConfiguration configuration) throws Exception { - try (ShellControl pc = LocalShell.getShell()) { - pc.osascriptCommand(String.format( - """ - if application "iTerm" is not running then - launch application "iTerm" - delay 1 - tell application "iTerm" - tell current tab of current window - close - end tell - end tell - end if - tell application "iTerm" - activate - create window with default profile command "%s" - end tell - """, - configuration.getScriptFile().toString().replaceAll("\"", "\\\\\""))) - .execute(); - } + LocalShell.getShell() + .executeSimpleCommand(CommandBuilder.of() + .add("open", "-a") + .addQuoted("iTerm.app") + .addFile(configuration.getScriptFile())); } }; ExternalTerminalType WARP = new MacOsType("app.warp", "Warp") { @@ -662,6 +670,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue { TILDA, XTERM, DEEPIN_TERMINAL, + FOOT, Q_TERMINAL); List MACOS_TERMINALS = List.of( KittyTerminalType.KITTY_MACOS, @@ -705,7 +714,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue { return ExternalTerminalType.POWERSHELL; } - if (existing != null) { + // Verify that our selection is still valid + if (existing != null && existing.isAvailable()) { return existing; } diff --git a/app/src/main/java/io/xpipe/app/terminal/WezTerminalType.java b/app/src/main/java/io/xpipe/app/terminal/WezTerminalType.java index 8bf48d1a4..f63d33be6 100644 --- a/app/src/main/java/io/xpipe/app/terminal/WezTerminalType.java +++ b/app/src/main/java/io/xpipe/app/terminal/WezTerminalType.java @@ -1,9 +1,14 @@ package io.xpipe.app.terminal; +import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.prefs.ExternalApplicationHelper; +import io.xpipe.app.prefs.ExternalApplicationType; import io.xpipe.app.util.LocalShell; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.WindowsRegistry; import io.xpipe.core.process.CommandBuilder; +import io.xpipe.core.process.OsType; +import io.xpipe.core.process.ShellControl; import java.nio.file.Path; import java.util.Optional; @@ -26,7 +31,7 @@ public interface WezTerminalType extends ExternalTerminalType { @Override default boolean isRecommended() { - return false; + return OsType.getLocal() != OsType.WINDOWS; } @Override @@ -51,25 +56,62 @@ public interface WezTerminalType extends ExternalTerminalType { @Override protected Optional determineInstallation() { - Optional launcherDir; - launcherDir = WindowsRegistry.local().readValue( - WindowsRegistry.HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{BCF6F0DA-5B9A-408D-8562-F680AE6E1EAF}_is1", - "InstallLocation") - .map(p -> p + "\\wezterm-gui.exe"); - return launcherDir.map(Path::of); + try { + var foundKey = WindowsRegistry.local().findKeyForEqualValueMatchRecursive(WindowsRegistry.HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "http://wezfurlong.org/wezterm"); + if (foundKey.isPresent()) { + var installKey = WindowsRegistry.local().readValue( + foundKey.get().getHkey(), + foundKey.get().getKey(), + "InstallLocation"); + if (installKey.isPresent()) { + return installKey.map(p -> p + "\\wezterm-gui.exe").map(Path::of); + } + } + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).omit().handle(); + } + + try (ShellControl pc = LocalShell.getShell()) { + if (pc.executeSimpleBooleanCommand(pc.getShellDialect().getWhichCommand("wezterm-gui"))) { + return Optional.of(Path.of("wezterm-gui")); + } + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + } + + return Optional.empty(); } } - class Linux extends SimplePathType implements WezTerminalType { + class Linux extends ExternalApplicationType implements WezTerminalType { public Linux() { - super("app.wezterm", "wezterm-gui", true); + super("app.wezterm"); + } + + public boolean isAvailable() { + try (ShellControl pc = LocalShell.getShell()) { + return pc.executeSimpleBooleanCommand(pc.getShellDialect().getWhichCommand("wezterm")) && + pc.executeSimpleBooleanCommand(pc.getShellDialect().getWhichCommand("wezterm-gui")); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + return false; + } } @Override - protected CommandBuilder toCommand(LaunchConfiguration configuration) { - return CommandBuilder.of().add("start").addFile(configuration.getScriptFile()); + public void launch(LaunchConfiguration configuration) throws Exception { + var spawn = LocalShell.getShell().command(CommandBuilder.of().addFile("wezterm") + .add("cli", "spawn") + .addFile(configuration.getScriptFile())) + .executeAndCheck(); + if (!spawn) { + ExternalApplicationHelper.startAsync(CommandBuilder.of() + .addFile("wezterm-gui") + .add("start") + .addFile(configuration.getScriptFile())); + } } } @@ -81,20 +123,27 @@ public interface WezTerminalType extends ExternalTerminalType { @Override public void launch(LaunchConfiguration configuration) throws Exception { - var path = LocalShell.getShell() - .command(String.format( - "mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null", - applicationName)) - .readStdoutOrThrow(); - var c = CommandBuilder.of() - .addFile(Path.of(path) - .resolve("Contents") - .resolve("MacOS") - .resolve("wezterm-gui") - .toString()) - .add("start") - .add(configuration.getDialectLaunchCommand()); - ExternalApplicationHelper.startAsync(c); + try (var sc = LocalShell.getShell()) { + var path = sc.command( + String.format("mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null", + applicationName)).readStdoutOrThrow(); + var spawn = sc.command(CommandBuilder.of().addFile(Path.of(path) + .resolve("Contents") + .resolve("MacOS") + .resolve("wezterm").toString()) + .add("cli", "spawn", "--pane-id", "0") + .addFile(configuration.getScriptFile())) + .executeAndCheck(); + if (!spawn) { + ExternalApplicationHelper.startAsync(CommandBuilder.of() + .addFile(Path.of(path) + .resolve("Contents") + .resolve("MacOS") + .resolve("wezterm-gui").toString()) + .add("start") + .addFile(configuration.getScriptFile())); + } + } } } } diff --git a/app/src/main/java/io/xpipe/app/util/AskpassAlert.java b/app/src/main/java/io/xpipe/app/util/AskpassAlert.java index fee05d49d..18243a547 100644 --- a/app/src/main/java/io/xpipe/app/util/AskpassAlert.java +++ b/app/src/main/java/io/xpipe/app/util/AskpassAlert.java @@ -56,6 +56,10 @@ public class AskpassAlert { @Override public void handle(long now) { + if (!stage.isShowing()) { + return; + } + if (regainedFocusCount >= 2) { return; } diff --git a/app/src/main/java/io/xpipe/app/util/CommandView.java b/app/src/main/java/io/xpipe/app/util/CommandView.java index ffcf685ad..dce5ee6d6 100644 --- a/app/src/main/java/io/xpipe/app/util/CommandView.java +++ b/app/src/main/java/io/xpipe/app/util/CommandView.java @@ -1,13 +1,21 @@ package io.xpipe.app.util; import io.xpipe.core.process.CommandBuilder; +import io.xpipe.core.process.CommandControl; import io.xpipe.core.process.ShellControl; -import lombok.experimental.SuperBuilder; -@SuperBuilder -public abstract class CommandView { +import java.util.function.Consumer; - protected final ShellControl shellControl; +public abstract class CommandView implements AutoCloseable { - protected abstract CommandBuilder base(); + protected abstract CommandControl build(Consumer builder); + + protected abstract ShellControl getShellControl(); + + public abstract CommandView start() throws Exception; + + @Override + public void close() throws Exception { + getShellControl().close(); + } } diff --git a/app/src/main/java/io/xpipe/app/util/CommandViewBase.java b/app/src/main/java/io/xpipe/app/util/CommandViewBase.java new file mode 100644 index 000000000..5a80834f1 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/util/CommandViewBase.java @@ -0,0 +1,18 @@ +package io.xpipe.app.util; + +import io.xpipe.core.process.CommandBuilder; +import io.xpipe.core.process.CommandControl; +import io.xpipe.core.process.ShellControl; +import lombok.Getter; + +import java.util.function.Consumer; + +public abstract class CommandViewBase extends CommandView { + + @Getter + protected final ShellControl shellControl; + + public CommandViewBase(ShellControl shellControl) {this.shellControl = shellControl;} + + protected abstract CommandControl build(Consumer builder); +} diff --git a/app/src/main/java/io/xpipe/app/util/FileOpener.java b/app/src/main/java/io/xpipe/app/util/FileOpener.java index 62390236d..bd742a624 100644 --- a/app/src/main/java/io/xpipe/app/util/FileOpener.java +++ b/app/src/main/java/io/xpipe/app/util/FileOpener.java @@ -28,10 +28,9 @@ public class FileOpener { try { editor.launch(Path.of(localFile).toRealPath()); } catch (Exception e) { - ErrorEvent.fromThrowable(e) - .description("Unable to launch editor " + ErrorEvent.fromThrowable("Unable to launch editor " + editor.toTranslatedString().getValue() - + ".\nMaybe try to use a different editor in the settings.") + + ".\nMaybe try to use a different editor in the settings.", e) .expected() .handle(); } @@ -52,8 +51,7 @@ public class FileOpener { } } } catch (Exception e) { - ErrorEvent.fromThrowable(e) - .description("Unable to open file " + localFile) + ErrorEvent.fromThrowable("Unable to open file " + localFile, e) .handle(); } } @@ -68,8 +66,7 @@ public class FileOpener { pc.executeSimpleCommand("open \"" + localFile + "\""); } } catch (Exception e) { - ErrorEvent.fromThrowable(e) - .description("Unable to open file " + localFile) + ErrorEvent.fromThrowable("Unable to open file " + localFile, e) .handle(); } } diff --git a/app/src/main/java/io/xpipe/app/util/HostHelper.java b/app/src/main/java/io/xpipe/app/util/HostHelper.java index c73857f68..9e337ff01 100644 --- a/app/src/main/java/io/xpipe/app/util/HostHelper.java +++ b/app/src/main/java/io/xpipe/app/util/HostHelper.java @@ -6,6 +6,14 @@ import java.util.Locale; public class HostHelper { + private static int portCounter = 0; + + public static int randomPort() { + var p = 40000 + portCounter; + portCounter = portCounter + 1 % 1000; + return p; + } + public static int findRandomOpenPortOnAllLocalInterfaces() throws IOException { try (ServerSocket socket = new ServerSocket(0)) { return socket.getLocalPort(); diff --git a/app/src/main/java/io/xpipe/app/util/LicenseConnectionLimit.java b/app/src/main/java/io/xpipe/app/util/LicenseConnectionLimit.java new file mode 100644 index 000000000..7210023a8 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/util/LicenseConnectionLimit.java @@ -0,0 +1,32 @@ +package io.xpipe.app.util; + +import io.xpipe.app.storage.DataStorage; +import io.xpipe.core.store.DataStore; + +public abstract class LicenseConnectionLimit { + + private final int limit; + private final LicensedFeature feature; + + public LicenseConnectionLimit(int limit, LicensedFeature feature) { + this.limit = limit; + this.feature = feature; + } + + protected abstract boolean matches(DataStore store); + + public void checkLimit() { + if (feature.isSupported()) { + return; + } + + var found = DataStorage.get() + .getStoreEntries() + .stream() + .filter(entry -> entry.getValidity().isUsable() && matches(entry.getStore())) + .toList(); + if (found.size() > limit) { + throw new LicenseRequiredException(feature, limit); + } + } +} diff --git a/app/src/main/java/io/xpipe/app/util/LicenseRequiredException.java b/app/src/main/java/io/xpipe/app/util/LicenseRequiredException.java index 53bae9864..2e1173098 100644 --- a/app/src/main/java/io/xpipe/app/util/LicenseRequiredException.java +++ b/app/src/main/java/io/xpipe/app/util/LicenseRequiredException.java @@ -1,7 +1,6 @@ package io.xpipe.app.util; import io.xpipe.app.core.AppI18n; - import lombok.Getter; @Getter @@ -15,6 +14,12 @@ public class LicenseRequiredException extends RuntimeException { this.feature = feature; } + public LicenseRequiredException(LicensedFeature feature, int limit) { + super(feature.getDisplayName() + " " + + (feature.isPlural() ? AppI18n.get("areOnlySupportedLimit", limit) : AppI18n.get("isOnlySupportedLimit", limit))); + this.feature = feature; + } + public LicenseRequiredException(String featureName, boolean plural, LicensedFeature feature) { super(featureName + " " + (plural ? AppI18n.get("areOnlySupported") : AppI18n.get("isOnlySupported"))); this.feature = feature; diff --git a/app/src/main/java/io/xpipe/app/util/LocalShell.java b/app/src/main/java/io/xpipe/app/util/LocalShell.java index 18f8f49e8..939ceaaa7 100644 --- a/app/src/main/java/io/xpipe/app/util/LocalShell.java +++ b/app/src/main/java/io/xpipe/app/util/LocalShell.java @@ -41,6 +41,7 @@ public class LocalShell { localPowershell = ProcessControlProvider.get() .createLocalProcessControl(false) .subShell(ShellDialects.POWERSHELL) + .withoutLicenseCheck() .start(); } return localPowershell.start(); diff --git a/app/src/main/java/io/xpipe/app/util/MarkdownHelper.java b/app/src/main/java/io/xpipe/app/util/MarkdownHelper.java index 639167017..296bb830d 100644 --- a/app/src/main/java/io/xpipe/app/util/MarkdownHelper.java +++ b/app/src/main/java/io/xpipe/app/util/MarkdownHelper.java @@ -6,6 +6,8 @@ import com.vladsch.flexmark.ext.footnotes.FootnoteExtension; import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension; import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension; import com.vladsch.flexmark.ext.tables.TablesExtension; +import com.vladsch.flexmark.ext.toc.TocExtension; +import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension; import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.ast.Document; @@ -16,14 +18,16 @@ import java.util.function.UnaryOperator; public class MarkdownHelper { - public static String toHtml(String value, UnaryOperator htmlTransformation) { + public static String toHtml(String value, UnaryOperator headTransformation, UnaryOperator bodyTransformation) { MutableDataSet options = new MutableDataSet().set(Parser.EXTENSIONS, Arrays.asList( StrikethroughExtension.create(), TaskListExtension.create(), TablesExtension.create(), FootnoteExtension.create(), DefinitionExtension.create(), - AnchorLinkExtension.create() + AnchorLinkExtension.create(), + YamlFrontMatterExtension.create(), + TocExtension.create() )) .set(FootnoteExtension.FOOTNOTE_BACK_LINK_REF_CLASS,"footnotes") .set(TablesExtension.WITH_CAPTION, false) @@ -38,7 +42,8 @@ public class MarkdownHelper { HtmlRenderer renderer = HtmlRenderer.builder(options).build(); Document document = parser.parse(value); var html = renderer.render(document); - var result = htmlTransformation.apply(html); - return "
" + result + "
"; + var result = bodyTransformation.apply(html); + var headContent = headTransformation.apply(""); + return "" + headContent + "
" + result + "
"; } } diff --git a/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java b/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java index ad032cae4..5725b5a54 100644 --- a/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java +++ b/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java @@ -23,6 +23,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Supplier; public class OptionsBuilder { @@ -146,6 +147,11 @@ public class OptionsBuilder { return this; } + public OptionsBuilder check(Function c) { + lastCompHeadReference.apply(s -> c.apply(ownValidator).decorates(s.get())); + return this; + } + public OptionsBuilder check(Check c) { lastCompHeadReference.apply(s -> c.decorates(s.get())); return this; @@ -221,7 +227,7 @@ public class OptionsBuilder { } public OptionsBuilder addToggle(Property prop) { - var comp = new ToggleSwitchComp(prop, null); + var comp = new ToggleSwitchComp(prop, null, null); pushComp(comp); props.add(prop); return this; diff --git a/app/src/main/java/io/xpipe/app/util/TerminalLauncherManager.java b/app/src/main/java/io/xpipe/app/util/TerminalLauncherManager.java index 936e34e4f..152c02bf6 100644 --- a/app/src/main/java/io/xpipe/app/util/TerminalLauncherManager.java +++ b/app/src/main/java/io/xpipe/app/util/TerminalLauncherManager.java @@ -1,13 +1,12 @@ package io.xpipe.app.util; -import io.xpipe.beacon.ClientException; -import io.xpipe.beacon.ServerException; +import io.xpipe.beacon.BeaconClientException; +import io.xpipe.beacon.BeaconServerException; import io.xpipe.core.process.ProcessControl; import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.TerminalInitScriptConfig; import io.xpipe.core.process.WorkingDirectoryFunction; import io.xpipe.core.store.FilePath; - import lombok.Setter; import lombok.Value; import lombok.experimental.NonFinal; @@ -73,10 +72,10 @@ public class TerminalLauncherManager { return latch; } - public static Path waitForCompletion(UUID request) throws ClientException, ServerException { + public static Path waitForCompletion(UUID request) throws BeaconClientException, BeaconServerException { var e = entries.get(request); if (e == null) { - throw new ClientException("Unknown launch request " + request); + throw new BeaconClientException("Unknown launch request " + request); } while (true) { @@ -89,21 +88,21 @@ public class TerminalLauncherManager { if (r instanceof ResultFailure failure) { entries.remove(request); var t = failure.getThrowable(); - throw new ServerException(t); + throw new BeaconServerException(t); } return ((ResultSuccess) r).getTargetScript(); } } - public static Path performLaunch(UUID request) throws ClientException { + public static Path performLaunch(UUID request) throws BeaconClientException { var e = entries.remove(request); if (e == null) { - throw new ClientException("Unknown launch request " + request); + throw new BeaconClientException("Unknown launch request " + request); } if (!(e.result instanceof ResultSuccess)) { - throw new ClientException("Invalid launch request state " + request); + throw new BeaconClientException("Invalid launch request state " + request); } return ((ResultSuccess) e.getResult()).getTargetScript(); diff --git a/app/src/main/java/module-info.java b/app/src/main/java/module-info.java index a0d3e8280..01b8e79cd 100644 --- a/app/src/main/java/module-info.java +++ b/app/src/main/java/module-info.java @@ -1,7 +1,7 @@ +import com.fasterxml.jackson.databind.Module; +import io.xpipe.app.beacon.impl.*; import io.xpipe.app.browser.action.BrowserAction; import io.xpipe.app.core.AppLogs; -import io.xpipe.app.exchange.*; -import io.xpipe.app.exchange.cli.*; import io.xpipe.app.ext.*; import io.xpipe.app.issue.EventHandler; import io.xpipe.app.issue.EventHandlerImpl; @@ -10,15 +10,15 @@ import io.xpipe.app.util.AppJacksonModule; import io.xpipe.app.util.LicenseProvider; import io.xpipe.app.util.ProxyManagerProviderImpl; import io.xpipe.app.util.TerminalLauncher; +import io.xpipe.beacon.BeaconInterface; import io.xpipe.core.util.DataStateProvider; import io.xpipe.core.util.ModuleLayerLoader; import io.xpipe.core.util.ProxyFunction; import io.xpipe.core.util.ProxyManagerProvider; - -import com.fasterxml.jackson.databind.Module; import org.slf4j.spi.SLF4JServiceProvider; open module io.xpipe.app { + exports io.xpipe.app.beacon; exports io.xpipe.app.core; exports io.xpipe.app.util; exports io.xpipe.app; @@ -52,6 +52,7 @@ open module io.xpipe.app { requires com.vladsch.flexmark; requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.annotation; requires net.synedra.validatorfx; requires org.kordamp.ikonli.feather; requires io.xpipe.modulefs; @@ -79,14 +80,6 @@ open module io.xpipe.app { requires net.steppschuh.markdowngenerator; requires com.shinyhut.vernacular; - // Required by extensions - requires java.security.jgss; - requires java.security.sasl; - requires java.xml; - requires java.xml.crypto; - requires java.sql; - requires java.sql.rowset; - // Required runtime modules requires jdk.charsets; requires jdk.crypto.cryptoki; @@ -100,8 +93,8 @@ open module io.xpipe.app { // For debugging requires jdk.jdwp.agent; requires org.kordamp.ikonli.core; + requires jdk.httpserver; - uses MessageExchangeImpl; uses TerminalLauncher; uses io.xpipe.app.ext.ActionProvider; uses EventHandler; @@ -113,11 +106,13 @@ open module io.xpipe.app { uses BrowserAction; uses LicenseProvider; uses io.xpipe.app.util.LicensedFeature; + uses io.xpipe.beacon.BeaconInterface; + uses DataStorageExtensionProvider; provides Module with AppJacksonModule; provides ModuleLayerLoader with - MessageExchangeImpls.Loader, + DataStorageExtensionProvider.Loader, DataStoreProviders.Loader, ActionProvider.Loader, PrefsProvider.Loader, @@ -132,26 +127,9 @@ open module io.xpipe.app { AppLogs.Slf4jProvider; provides EventHandler with EventHandlerImpl; - provides MessageExchangeImpl with - ReadDrainExchangeImpl, - EditStoreExchangeImpl, - StoreProviderListExchangeImpl, - OpenExchangeImpl, - LaunchExchangeImpl, - FocusExchangeImpl, - StatusExchangeImpl, - DrainExchangeImpl, - SinkExchangeImpl, - StopExchangeImpl, - ModeExchangeImpl, - DialogExchangeImpl, - RemoveStoreExchangeImpl, - RenameStoreExchangeImpl, - ListStoresExchangeImpl, - StoreAddExchangeImpl, + provides BeaconInterface with ShellStartExchangeImpl, ShellStopExchangeImpl, ShellExecExchangeImpl, ConnectionQueryExchangeImpl, DaemonOpenExchangeImpl, DaemonFocusExchangeImpl, DaemonStatusExchangeImpl, DaemonStopExchangeImpl, + HandshakeExchangeImpl, DaemonModeExchangeImpl, AskpassExchangeImpl, TerminalWaitExchangeImpl, - TerminalLaunchExchangeImpl, - QueryStoreExchangeImpl, - VersionExchangeImpl; + TerminalLaunchExchangeImpl, DaemonVersionExchangeImpl; } diff --git a/app/src/main/resources/io/xpipe/app/resources/misc/api.md b/app/src/main/resources/io/xpipe/app/resources/misc/api.md new file mode 100644 index 000000000..8a4b6301a --- /dev/null +++ b/app/src/main/resources/io/xpipe/app/resources/misc/api.md @@ -0,0 +1,1249 @@ +--- +title: XPipe API Documentation v10.0 +language_tabs: + - javascript: JavaScript + - python: Python + - java: Java + - go: Go + - shell: Shell +language_clients: + - javascript: "" + - python: "" + - java: "" + - go: "" + - shell: "" +toc_footers: + - XPipe - Plans and pricing +includes: [] +search: true +highlight_theme: darkula +headingLevel: 2 + +--- + +

XPipe API Documentation v10.0

+ +The XPipe API provides programmatic access to XPipe’s features. + +The XPipe application will start up an HTTP server that can be used to send requests. +You can change the port of it in the settings menu. +Note that this server is HTTP-only for now as it runs only on localhost. HTTPS requests are not accepted. + +This allows you to programmatically manage remote systems. +To start off, you can query connections based on various filters. +With the matched connections, you can start remote shell sessions for each one and run arbitrary commands in them. +You get the command exit code and output as a response, allowing you to adapt your control flow based on command outputs. +Any kind of passwords and other secrets are automatically provided by XPipe when establishing a shell connection. +If a required password is not stored and is set to be dynamically prompted, the running XPipe application will ask you to enter any required passwords. + +You can quickly get started by either using this page as an API reference or alternatively import the [OpenAPI definition file](/openapi.yaml) into your API client of choice. +See the authentication handshake below on how to authenticate prior to sending requests. + +Base URLs: + +* http://localhost:21721 + +Table of contents: +[TOC] + +# Authentication + +- HTTP Authentication, scheme: bearer The bearer token used is the session token that you receive from the handshake exchange. + +

Default

+ +## Establish a new API session + + + +`POST /handshake` + +Prior to sending requests to the API, you first have to establish a new API session via the handshake endpoint. +In the response you will receive a session token that you can use to authenticate during this session. + +This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients. + +Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests. + +> Body parameter + +```json +{ + "auth": { + "type": "ApiKey", + "key": "" + }, + "client": { + "type": "Api", + "name": "My client name" + } +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|body|body|[HandshakeRequest](#schemahandshakerequest)|true|none| + +> Example responses + +> 200 Response + +```json +{ + "sessionToken": "string" +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The handshake was successful. The returned token can be used for authentication in this session. The token is valid as long as XPipe is running.|[HandshakeResponse](#schemahandshakeresponse)| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|None| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|None| + + + +
+ +Code samples + +```javascript +const inputBody = '{ + "auth": { + "type": "ApiKey", + "key": "" + }, + "client": { + "type": "Api", + "name": "My client name" + } +}'; +const headers = { + 'Content-Type':'application/json', + 'Accept':'application/json' +}; + +fetch('http://localhost:21721/handshake', +{ + method: 'POST', + body: inputBody, + headers: headers +}) +.then(function(res) { + return res.json(); +}).then(function(body) { + console.log(body); +}); + +``` + +```python +import requests +headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json' +} + +data = """ +{ + "auth": { + "type": "ApiKey", + "key": "" + }, + "client": { + "type": "Api", + "name": "My client name" + } +} +""" +r = requests.post('http://localhost:21721/handshake', headers = headers, data = data) + +print(r.json()) + +``` + +```java +var uri = URI.create("http://localhost:21721/handshake"); +var client = HttpClient.newHttpClient(); +var request = HttpRequest + .newBuilder() + .uri(uri) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(""" +{ + "auth": { + "type": "ApiKey", + "key": "" + }, + "client": { + "type": "Api", + "name": "My client name" + } +} + """)) + .build(); +var response = client.send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.statusCode()); +System.out.println(response.body()); + +``` + +```go +package main + +import ( + "bytes" + "net/http" +) + +func main() { + + headers := map[string][]string{ + "Content-Type": []string{"application/json"}, + "Accept": []string{"application/json"}, + } + + data := bytes.NewBuffer([]byte{jsonReq}) + req, err := http.NewRequest("POST", "http://localhost:21721/handshake", data) + req.Header = headers + + client := &http.Client{} + resp, err := client.Do(req) + // ... +} + +``` + +```shell +# You can also use wget +curl -X POST http://localhost:21721/handshake \ + -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ + --data ' +{ + "auth": { + "type": "ApiKey", + "key": "" + }, + "client": { + "type": "Api", + "name": "My client name" + } +} +' + +``` + +
+ +## Query connections + + + +`POST /connection/query` + +Queries all connections using various filters. + +The filters support globs and can match the category names and connection names. +All matching is case insensitive. + +> Body parameter + +```json +{ + "categoryFilter": "*", + "connectionFilter": "*", + "typeFilter": "*" +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|body|body|[ConnectionQueryRequest](#schemaconnectionqueryrequest)|true|none| + +> Example responses + +> The query was successful. The body contains all matched connections. + +```json +{ + "found": [ + { + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", + "category": [ + "default" + ], + "connection": [ + "local machine" + ], + "type": "local" + }, + { + "uuid": "e1462ddc-9beb-484c-bd91-bb666027e300", + "category": [ + "default", + "category 1" + ], + "connection": [ + "ssh system", + "shell environments", + "bash" + ], + "type": "shellEnvironment" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The query was successful. The body contains all matched connections.|[ConnectionQueryResponse](#schemaconnectionqueryresponse)| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|None| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None| +|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|None| + + + +
+ +Code samples + +```javascript +const inputBody = '{ + "categoryFilter": "*", + "connectionFilter": "*", + "typeFilter": "*" +}'; +const headers = { + 'Content-Type':'application/json', + 'Accept':'application/json', + 'Authorization':'Bearer {access-token}' +}; + +fetch('http://localhost:21721/connection/query', +{ + method: 'POST', + body: inputBody, + headers: headers +}) +.then(function(res) { + return res.json(); +}).then(function(body) { + console.log(body); +}); + +``` + +```python +import requests +headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': 'Bearer {access-token}' +} + +data = """ +{ + "categoryFilter": "*", + "connectionFilter": "*", + "typeFilter": "*" +} +""" +r = requests.post('http://localhost:21721/connection/query', headers = headers, data = data) + +print(r.json()) + +``` + +```java +var uri = URI.create("http://localhost:21721/connection/query"); +var client = HttpClient.newHttpClient(); +var request = HttpRequest + .newBuilder() + .uri(uri) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("Authorization", "Bearer {access-token}") + .POST(HttpRequest.BodyPublishers.ofString(""" +{ + "categoryFilter": "*", + "connectionFilter": "*", + "typeFilter": "*" +} + """)) + .build(); +var response = client.send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.statusCode()); +System.out.println(response.body()); + +``` + +```go +package main + +import ( + "bytes" + "net/http" +) + +func main() { + + headers := map[string][]string{ + "Content-Type": []string{"application/json"}, + "Accept": []string{"application/json"}, + "Authorization": []string{"Bearer {access-token}"}, + } + + data := bytes.NewBuffer([]byte{jsonReq}) + req, err := http.NewRequest("POST", "http://localhost:21721/connection/query", data) + req.Header = headers + + client := &http.Client{} + resp, err := client.Do(req) + // ... +} + +``` + +```shell +# You can also use wget +curl -X POST http://localhost:21721/connection/query \ + -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer {access-token}' \ + --data ' +{ + "categoryFilter": "*", + "connectionFilter": "*", + "typeFilter": "*" +} +' + +``` + +
+ +## Start shell connection + + + +`POST /shell/start` + +Starts a new shell session for a connection. If an existing shell session is already running for that connection, this operation will do nothing. + +Note that there are a variety of possible errors that can occur here when establishing the shell connection. +These errors will be returned with the HTTP return code 500. + +> Body parameter + +```json +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|body|body|[ShellStartRequest](#schemashellstartrequest)|true|none| + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The operation was successful. The shell session was started.|None| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|None| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None| +|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|None| + + + +
+ +Code samples + +```javascript +const inputBody = '{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +}'; +const headers = { + 'Content-Type':'application/json', + 'Authorization':'Bearer {access-token}' +}; + +fetch('http://localhost:21721/shell/start', +{ + method: 'POST', + body: inputBody, + headers: headers +}) +.then(function(res) { + return res.json(); +}).then(function(body) { + console.log(body); +}); + +``` + +```python +import requests +headers = { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer {access-token}' +} + +data = """ +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} +""" +r = requests.post('http://localhost:21721/shell/start', headers = headers, data = data) + +print(r.json()) + +``` + +```java +var uri = URI.create("http://localhost:21721/shell/start"); +var client = HttpClient.newHttpClient(); +var request = HttpRequest + .newBuilder() + .uri(uri) + .header("Content-Type", "application/json") + .header("Authorization", "Bearer {access-token}") + .POST(HttpRequest.BodyPublishers.ofString(""" +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} + """)) + .build(); +var response = client.send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.statusCode()); +System.out.println(response.body()); + +``` + +```go +package main + +import ( + "bytes" + "net/http" +) + +func main() { + + headers := map[string][]string{ + "Content-Type": []string{"application/json"}, + "Authorization": []string{"Bearer {access-token}"}, + } + + data := bytes.NewBuffer([]byte{jsonReq}) + req, err := http.NewRequest("POST", "http://localhost:21721/shell/start", data) + req.Header = headers + + client := &http.Client{} + resp, err := client.Do(req) + // ... +} + +``` + +```shell +# You can also use wget +curl -X POST http://localhost:21721/shell/start \ + -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {access-token}' \ + --data ' +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} +' + +``` + +
+ +## Stop shell connection + + + +`POST /shell/stop` + +Stops an existing shell session for a connection. + +This operation will return once the shell has exited. +If the shell is busy or stuck, you might have to work with timeouts to account for these cases. + +> Body parameter + +```json +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|body|body|[ShellStopRequest](#schemashellstoprequest)|true|none| + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The operation was successful. The shell session was stopped.|None| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|None| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None| +|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|None| + + + +
+ +Code samples + +```javascript +const inputBody = '{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +}'; +const headers = { + 'Content-Type':'application/json', + 'Authorization':'Bearer {access-token}' +}; + +fetch('http://localhost:21721/shell/stop', +{ + method: 'POST', + body: inputBody, + headers: headers +}) +.then(function(res) { + return res.json(); +}).then(function(body) { + console.log(body); +}); + +``` + +```python +import requests +headers = { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer {access-token}' +} + +data = """ +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} +""" +r = requests.post('http://localhost:21721/shell/stop', headers = headers, data = data) + +print(r.json()) + +``` + +```java +var uri = URI.create("http://localhost:21721/shell/stop"); +var client = HttpClient.newHttpClient(); +var request = HttpRequest + .newBuilder() + .uri(uri) + .header("Content-Type", "application/json") + .header("Authorization", "Bearer {access-token}") + .POST(HttpRequest.BodyPublishers.ofString(""" +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} + """)) + .build(); +var response = client.send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.statusCode()); +System.out.println(response.body()); + +``` + +```go +package main + +import ( + "bytes" + "net/http" +) + +func main() { + + headers := map[string][]string{ + "Content-Type": []string{"application/json"}, + "Authorization": []string{"Bearer {access-token}"}, + } + + data := bytes.NewBuffer([]byte{jsonReq}) + req, err := http.NewRequest("POST", "http://localhost:21721/shell/stop", data) + req.Header = headers + + client := &http.Client{} + resp, err := client.Do(req) + // ... +} + +``` + +```shell +# You can also use wget +curl -X POST http://localhost:21721/shell/stop \ + -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {access-token}' \ + --data ' +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" +} +' + +``` + +
+ +## Execute command in a shell session + + + +`POST /shell/exec` + +Runs a command in an active shell session and waits for it to finish. The exit code and output will be returned in the response. + +Note that a variety of different errors can occur when executing the command. +If the command finishes, even with an error code, a normal HTTP 200 response will be returned. +However, if any other error occurs like the shell not responding or exiting unexpectedly, an HTTP 500 response will be returned. + +> Body parameter + +```json +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", + "command": "echo $USER" +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|body|body|[ShellExecRequest](#schemashellexecrequest)|true|none| + +> Example responses + +> The operation was successful. The shell command finished. + +```json +{ + "exitCode": 0, + "stdout": "root", + "stderr": "" +} +``` + +```json +{ + "exitCode": 127, + "stdout": "", + "stderr": "invalid: command not found" +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The operation was successful. The shell command finished.|[ShellExecResponse](#schemashellexecresponse)| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad request. Please check error message and your parameters.|None| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|Authorization failed. Please supply a `Bearer` token via the `Authorization` header.|None| +|403|[Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)|Authorization failed. Please supply a valid `Bearer` token via the `Authorization` header.|None| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|The requested resource could not be found.|None| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal error.|None| + + + +
+ +Code samples + +```javascript +const inputBody = '{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", + "command": "echo $USER" +}'; +const headers = { + 'Content-Type':'application/json', + 'Accept':'application/json', + 'Authorization':'Bearer {access-token}' +}; + +fetch('http://localhost:21721/shell/exec', +{ + method: 'POST', + body: inputBody, + headers: headers +}) +.then(function(res) { + return res.json(); +}).then(function(body) { + console.log(body); +}); + +``` + +```python +import requests +headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': 'Bearer {access-token}' +} + +data = """ +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", + "command": "echo $USER" +} +""" +r = requests.post('http://localhost:21721/shell/exec', headers = headers, data = data) + +print(r.json()) + +``` + +```java +var uri = URI.create("http://localhost:21721/shell/exec"); +var client = HttpClient.newHttpClient(); +var request = HttpRequest + .newBuilder() + .uri(uri) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("Authorization", "Bearer {access-token}") + .POST(HttpRequest.BodyPublishers.ofString(""" +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", + "command": "echo $USER" +} + """)) + .build(); +var response = client.send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.statusCode()); +System.out.println(response.body()); + +``` + +```go +package main + +import ( + "bytes" + "net/http" +) + +func main() { + + headers := map[string][]string{ + "Content-Type": []string{"application/json"}, + "Accept": []string{"application/json"}, + "Authorization": []string{"Bearer {access-token}"}, + } + + data := bytes.NewBuffer([]byte{jsonReq}) + req, err := http.NewRequest("POST", "http://localhost:21721/shell/exec", data) + req.Header = headers + + client := &http.Client{} + resp, err := client.Do(req) + // ... +} + +``` + +```shell +# You can also use wget +curl -X POST http://localhost:21721/shell/exec \ + -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer {access-token}' \ + --data ' +{ + "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", + "command": "echo $USER" +} +' + +``` + +
+ +# Schemas + +

ShellStartRequest

+ + + + + + +```json +{ + "connection": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|connection|string|true|none|The connection uuid| + +

ShellStopRequest

+ + + + + + +```json +{ + "connection": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|connection|string|true|none|The connection uuid| + +

ShellExecRequest

+ + + + + + +```json +{ + "connection": "string", + "command": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|connection|string|true|none|The connection uuid| +|command|string|true|none|The command to execute| + +

ShellExecResponse

+ + + + + + +```json +{ + "exitCode": 0, + "stdout": "string", + "stderr": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|exitCode|integer|true|none|The exit code of the command| +|stdout|string|true|none|The stdout output of the command| +|stderr|string|true|none|The stderr output of the command| + +

ConnectionQueryRequest

+ + + + + + +```json +{ + "categoryFilter": "string", + "connectionFilter": "string", + "typeFilter": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|categoryFilter|string|true|none|The filter string to match categories. Categories are delimited by / if they are hierarchical. The filter supports globs.| +|connectionFilter|string|true|none|The filter string to match connection names. Connection names are delimited by / if they are hierarchical. The filter supports globs.| +|typeFilter|string|true|none|The filter string to connection types. Every unique type of connection like SSH or docker has its own type identifier that you can match. The filter supports globs.| + +

ConnectionQueryResponse

+ + + + + + +```json +{ + "found": [ + { + "uuid": "string", + "category": [ + "string" + ], + "connection": [ + "string" + ], + "type": "string" + } + ] +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|found|[object]|true|none|The found connections| +|» uuid|string|true|none|The unique id of the connection| +|» category|[string]|true|none|The full category path as an array| +|» connection|[string]|true|none|The full connection name path as an array| +|» type|string|true|none|The type identifier of the connection| + +

HandshakeRequest

+ + + + + + +```json +{ + "auth": { + "type": "string", + "key": "string" + }, + "client": { + "type": "string" + } +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|auth|[AuthMethod](#schemaauthmethod)|true|none|none| +|client|[ClientInformation](#schemaclientinformation)|true|none|none| + +

HandshakeResponse

+ + + + + + +```json +{ + "sessionToken": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|sessionToken|string|true|none|The generated bearer token that can be used for authentication in this session| + +

AuthMethod

+ + + + + + +```json +{ + "type": "string", + "key": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|type|string|true|none|none| + +oneOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[ApiKey](#schemaapikey)|false|none|API key authentication| + +xor + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[Local](#schemalocal)|false|none|Authentication method for local applications. Uses file system access as proof of authentication.| + +

ApiKey

+ + + + + + +```json +{ + "type": "string", + "key": "string" +} + +``` + +API key authentication + +

Properties

+ +allOf - discriminator: AuthMethod.type + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[AuthMethod](#schemaauthmethod)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|object|false|none|none| +|» key|string|true|none|The API key| + +

Local

+ + + + + + +```json +{ + "type": "string", + "key": "string", + "authFileContent": "string" +} + +``` + +Authentication method for local applications. Uses file system access as proof of authentication. + +

Properties

+ +allOf - discriminator: AuthMethod.type + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[AuthMethod](#schemaauthmethod)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|object|false|none|none| +|» authFileContent|string|true|none|The contents of the local file $TEMP/xpipe_auth. This file is automatically generated when XPipe starts.| + +

ClientInformation

+ + + + + + +```json +{ + "type": "string" +} + +``` + +

Properties

+ +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|type|string|true|none|none| + +

ApiClientInformation

+ + + + + + +```json +{ + "type": "string", + "name": "string" +} + +``` + +Provides information about the client that connected to the XPipe API. + +

Properties

+ +allOf - discriminator: ClientInformation.type + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[ClientInformation](#schemaclientinformation)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|object|false|none|none| +|» name|string|true|none|The name of the client.| + diff --git a/app/src/main/resources/io/xpipe/app/resources/misc/github-dark.min.css b/app/src/main/resources/io/xpipe/app/resources/misc/github-dark.min.css new file mode 100644 index 000000000..03b6da8bf --- /dev/null +++ b/app/src/main/resources/io/xpipe/app/resources/misc/github-dark.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub Dark + Description: Dark theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-dark + Current colors taken from GitHub's CSS +*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c} \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/web/github-markdown-dark.css b/app/src/main/resources/io/xpipe/app/resources/misc/github-markdown-dark.css similarity index 99% rename from app/src/main/resources/io/xpipe/app/resources/web/github-markdown-dark.css rename to app/src/main/resources/io/xpipe/app/resources/misc/github-markdown-dark.css index b818a8b7f..4fe441894 100644 --- a/app/src/main/resources/io/xpipe/app/resources/web/github-markdown-dark.css +++ b/app/src/main/resources/io/xpipe/app/resources/misc/github-markdown-dark.css @@ -70,6 +70,12 @@ html { font-style: italic; } +.markdown-body summary { + font-weight: 600; + padding-bottom: .3em; + font-size: 1.4em; +} + .markdown-body h1 { margin: .67em 0; font-weight: 600; @@ -416,7 +422,7 @@ html { .markdown-body table, .markdown-body pre, .markdown-body details { - margin-top: 0; + margin-top: 16px; margin-bottom: 16px; } diff --git a/app/src/main/resources/io/xpipe/app/resources/web/github-markdown-light.css b/app/src/main/resources/io/xpipe/app/resources/misc/github-markdown-light.css similarity index 99% rename from app/src/main/resources/io/xpipe/app/resources/web/github-markdown-light.css rename to app/src/main/resources/io/xpipe/app/resources/misc/github-markdown-light.css index 1c792edbe..c69cdde9c 100644 --- a/app/src/main/resources/io/xpipe/app/resources/web/github-markdown-light.css +++ b/app/src/main/resources/io/xpipe/app/resources/misc/github-markdown-light.css @@ -542,10 +542,16 @@ html { .markdown-body table, .markdown-body pre, .markdown-body details { - margin-top: 0; + margin-top: 16px; margin-bottom: 16px; } +.markdown-body summary { + font-weight: 600; + padding-bottom: .3em; + font-size: 1.4em; +} + .markdown-body blockquote > :first-child { margin-top: 0; } diff --git a/app/src/main/resources/io/xpipe/app/resources/misc/highlight.min.js b/app/src/main/resources/io/xpipe/app/resources/misc/highlight.min.js new file mode 100644 index 000000000..c5c1ca504 --- /dev/null +++ b/app/src/main/resources/io/xpipe/app/resources/misc/highlight.min.js @@ -0,0 +1,1381 @@ +/*! + Highlight.js v11.9.0 (git: b7ec4bfafc) + (c) 2006-2024 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";function e(t){ +return t instanceof Map?t.clear=t.delete=t.set=()=>{ +throw Error("map is read-only")}:t instanceof Set&&(t.add=t.clear=t.delete=()=>{ +throw Error("set is read-only") +}),Object.freeze(t),Object.getOwnPropertyNames(t).forEach((n=>{ +const i=t[n],s=typeof i;"object"!==s&&"function"!==s||Object.isFrozen(i)||e(i) +})),t}class t{constructor(e){ +void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} +ignoreMatch(){this.isMatchIgnored=!0}}function n(e){ +return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") +}function i(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t] +;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n}const s=e=>!!e.scope +;class o{constructor(e,t){ +this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){ +this.buffer+=n(e)}openNode(e){if(!s(e))return;const t=((e,{prefix:t})=>{ +if(e.startsWith("language:"))return e.replace("language:","language-") +;if(e.includes(".")){const n=e.split(".") +;return[`${t}${n.shift()}`,...n.map(((e,t)=>`${e}${"_".repeat(t+1)}`))].join(" ") +}return`${t}${e}`})(e.scope,{prefix:this.classPrefix});this.span(t)} +closeNode(e){s(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ +this.buffer+=``}}const r=(e={})=>{const t={children:[]} +;return Object.assign(t,e),t};class a{constructor(){ +this.rootNode=r(),this.stack=[this.rootNode]}get top(){ +return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ +this.top.children.push(e)}openNode(e){const t=r({scope:e}) +;this.add(t),this.stack.push(t)}closeNode(){ +if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ +for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} +walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){ +return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t), +t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){ +"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ +a._collapse(e)})))}}class c extends a{constructor(e){super(),this.options=e} +addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){ +this.closeNode()}__addSublanguage(e,t){const n=e.root +;t&&(n.scope="language:"+t),this.add(n)}toHTML(){ +return new o(this,this.options).value()}finalize(){ +return this.closeAllNodes(),!0}}function l(e){ +return e?"string"==typeof e?e:e.source:null}function g(e){return h("(?=",e,")")} +function u(e){return h("(?:",e,")*")}function d(e){return h("(?:",e,")?")} +function h(...e){return e.map((e=>l(e))).join("")}function f(...e){const t=(e=>{ +const t=e[e.length-1] +;return"object"==typeof t&&t.constructor===Object?(e.splice(e.length-1,1),t):{} +})(e);return"("+(t.capture?"":"?:")+e.map((e=>l(e))).join("|")+")"} +function p(e){return RegExp(e.toString()+"|").exec("").length-1} +const b=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ +;function m(e,{joinWith:t}){let n=0;return e.map((e=>{n+=1;const t=n +;let i=l(e),s="";for(;i.length>0;){const e=b.exec(i);if(!e){s+=i;break} +s+=i.substring(0,e.index), +i=i.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?s+="\\"+(Number(e[1])+t):(s+=e[0], +"("===e[0]&&n++)}return s})).map((e=>`(${e})`)).join(t)} +const E="[a-zA-Z]\\w*",x="[a-zA-Z_]\\w*",w="\\b\\d+(\\.\\d+)?",y="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",_="\\b(0b[01]+)",O={ +begin:"\\\\[\\s\\S]",relevance:0},v={scope:"string",begin:"'",end:"'", +illegal:"\\n",contains:[O]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", +contains:[O]},N=(e,t,n={})=>{const s=i({scope:"comment",begin:e,end:t, +contains:[]},n);s.contains.push({scope:"doctag", +begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", +end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) +;const o=f("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) +;return s.contains.push({begin:h(/[ ]+/,"(",o,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),s +},S=N("//","$"),M=N("/\\*","\\*/"),R=N("#","$");var j=Object.freeze({ +__proto__:null,APOS_STRING_MODE:v,BACKSLASH_ESCAPE:O,BINARY_NUMBER_MODE:{ +scope:"number",begin:_,relevance:0},BINARY_NUMBER_RE:_,COMMENT:N, +C_BLOCK_COMMENT_MODE:M,C_LINE_COMMENT_MODE:S,C_NUMBER_MODE:{scope:"number", +begin:y,relevance:0},C_NUMBER_RE:y,END_SAME_AS_BEGIN:e=>Object.assign(e,{ +"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{ +t.data._beginMatch!==e[1]&&t.ignoreMatch()}}),HASH_COMMENT_MODE:R,IDENT_RE:E, +MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+x,relevance:0}, +NUMBER_MODE:{scope:"number",begin:w,relevance:0},NUMBER_RE:w, +PHRASAL_WORDS_MODE:{ +begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ +},QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/, +end:/\/[gimuy]*/,contains:[O,{begin:/\[/,end:/\]/,relevance:0,contains:[O]}]}, +RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", +SHEBANG:(e={})=>{const t=/^#![ ]*\// +;return e.binary&&(e.begin=h(t,/.*\b/,e.binary,/\b.*/)),i({scope:"meta",begin:t, +end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)}, +TITLE_MODE:{scope:"title",begin:E,relevance:0},UNDERSCORE_IDENT_RE:x, +UNDERSCORE_TITLE_MODE:{scope:"title",begin:x,relevance:0}});function A(e,t){ +"."===e.input[e.index-1]&&t.ignoreMatch()}function I(e,t){ +void 0!==e.className&&(e.scope=e.className,delete e.className)}function T(e,t){ +t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", +e.__beforeBegin=A,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, +void 0===e.relevance&&(e.relevance=0))}function L(e,t){ +Array.isArray(e.illegal)&&(e.illegal=f(...e.illegal))}function B(e,t){ +if(e.match){ +if(e.begin||e.end)throw Error("begin & end are not supported with match") +;e.begin=e.match,delete e.match}}function P(e,t){ +void 0===e.relevance&&(e.relevance=1)}const D=(e,t)=>{if(!e.beforeMatch)return +;if(e.starts)throw Error("beforeMatch cannot be used with starts") +;const n=Object.assign({},e);Object.keys(e).forEach((t=>{delete e[t] +})),e.keywords=n.keywords,e.begin=h(n.beforeMatch,g(n.begin)),e.starts={ +relevance:0,contains:[Object.assign(n,{endsParent:!0})] +},e.relevance=0,delete n.beforeMatch +},H=["of","and","for","in","not","or","if","then","parent","list","value"],C="keyword" +;function $(e,t,n=C){const i=Object.create(null) +;return"string"==typeof e?s(n,e.split(" ")):Array.isArray(e)?s(n,e):Object.keys(e).forEach((n=>{ +Object.assign(i,$(e[n],t,n))})),i;function s(e,n){ +t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split("|") +;i[n[0]]=[e,U(n[0],n[1])]}))}}function U(e,t){ +return t?Number(t):(e=>H.includes(e.toLowerCase()))(e)?0:1}const z={},W=e=>{ +console.error(e)},X=(e,...t)=>{console.log("WARN: "+e,...t)},G=(e,t)=>{ +z[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),z[`${e}/${t}`]=!0) +},K=Error();function F(e,t,{key:n}){let i=0;const s=e[n],o={},r={} +;for(let e=1;e<=t.length;e++)r[e+i]=s[e],o[e+i]=!0,i+=p(t[e-1]) +;e[n]=r,e[n]._emit=o,e[n]._multi=!0}function Z(e){(e=>{ +e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, +delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ +_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope +}),(e=>{if(Array.isArray(e.begin)){ +if(e.skip||e.excludeBegin||e.returnBegin)throw W("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), +K +;if("object"!=typeof e.beginScope||null===e.beginScope)throw W("beginScope must be object"), +K;F(e,e.begin,{key:"beginScope"}),e.begin=m(e.begin,{joinWith:""})}})(e),(e=>{ +if(Array.isArray(e.end)){ +if(e.skip||e.excludeEnd||e.returnEnd)throw W("skip, excludeEnd, returnEnd not compatible with endScope: {}"), +K +;if("object"!=typeof e.endScope||null===e.endScope)throw W("endScope must be object"), +K;F(e,e.end,{key:"endScope"}),e.end=m(e.end,{joinWith:""})}})(e)}function V(e){ +function t(t,n){ +return RegExp(l(t),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(n?"g":"")) +}class n{constructor(){ +this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} +addRule(e,t){ +t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]), +this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) +;const e=this.regexes.map((e=>e[1]));this.matcherRe=t(m(e,{joinWith:"|" +}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex +;const t=this.matcherRe.exec(e);if(!t)return null +;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n] +;return t.splice(0,n),Object.assign(t,i)}}class s{constructor(){ +this.rules=[],this.multiRegexes=[], +this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ +if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n +;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))), +t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){ +return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){ +this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){ +const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex +;let n=t.exec(e) +;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{ +const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)} +return n&&(this.regexIndex+=n.position+1, +this.regexIndex===this.count&&this.considerAll()),n}} +if(e.compilerExtensions||(e.compilerExtensions=[]), +e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") +;return e.classNameAliases=i(e.classNameAliases||{}),function n(o,r){const a=o +;if(o.isCompiled)return a +;[I,B,Z,D].forEach((e=>e(o,r))),e.compilerExtensions.forEach((e=>e(o,r))), +o.__beforeBegin=null,[T,L,P].forEach((e=>e(o,r))),o.isCompiled=!0;let c=null +;return"object"==typeof o.keywords&&o.keywords.$pattern&&(o.keywords=Object.assign({},o.keywords), +c=o.keywords.$pattern, +delete o.keywords.$pattern),c=c||/\w+/,o.keywords&&(o.keywords=$(o.keywords,e.case_insensitive)), +a.keywordPatternRe=t(c,!0), +r&&(o.begin||(o.begin=/\B|\b/),a.beginRe=t(a.begin),o.end||o.endsWithParent||(o.end=/\B|\b/), +o.end&&(a.endRe=t(a.end)), +a.terminatorEnd=l(a.end)||"",o.endsWithParent&&r.terminatorEnd&&(a.terminatorEnd+=(o.end?"|":"")+r.terminatorEnd)), +o.illegal&&(a.illegalRe=t(o.illegal)), +o.contains||(o.contains=[]),o.contains=[].concat(...o.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>i(e,{ +variants:null},t)))),e.cachedVariants?e.cachedVariants:q(e)?i(e,{ +starts:e.starts?i(e.starts):null +}):Object.isFrozen(e)?i(e):e))("self"===e?o:e)))),o.contains.forEach((e=>{n(e,a) +})),o.starts&&n(o.starts,r),a.matcher=(e=>{const t=new s +;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin" +}))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end" +}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t})(a),a}(e)}function q(e){ +return!!e&&(e.endsWithParent||q(e.starts))}class J extends Error{ +constructor(e,t){super(e),this.name="HTMLInjectionError",this.html=t}} +const Y=n,Q=i,ee=Symbol("nomatch"),te=n=>{ +const i=Object.create(null),s=Object.create(null),o=[];let r=!0 +;const a="Could not find the language '{}', did you forget to load/include a language module?",l={ +disableAutodetect:!0,name:"Plain text",contains:[]};let p={ +ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, +languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", +cssSelector:"pre code",languages:null,__emitter:c};function b(e){ +return p.noHighlightRe.test(e)}function m(e,t,n){let i="",s="" +;"object"==typeof t?(i=e, +n=t.ignoreIllegals,s=t.language):(G("10.7.0","highlight(lang, code, ...args) has been deprecated."), +G("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), +s=e,i=t),void 0===n&&(n=!0);const o={code:i,language:s};N("before:highlight",o) +;const r=o.result?o.result:E(o.language,o.code,n) +;return r.code=o.code,N("after:highlight",r),r}function E(e,n,s,o){ +const c=Object.create(null);function l(){if(!N.keywords)return void M.addText(R) +;let e=0;N.keywordPatternRe.lastIndex=0;let t=N.keywordPatternRe.exec(R),n="" +;for(;t;){n+=R.substring(e,t.index) +;const s=_.case_insensitive?t[0].toLowerCase():t[0],o=(i=s,N.keywords[i]);if(o){ +const[e,i]=o +;if(M.addText(n),n="",c[s]=(c[s]||0)+1,c[s]<=7&&(j+=i),e.startsWith("_"))n+=t[0];else{ +const n=_.classNameAliases[e]||e;u(t[0],n)}}else n+=t[0] +;e=N.keywordPatternRe.lastIndex,t=N.keywordPatternRe.exec(R)}var i +;n+=R.substring(e),M.addText(n)}function g(){null!=N.subLanguage?(()=>{ +if(""===R)return;let e=null;if("string"==typeof N.subLanguage){ +if(!i[N.subLanguage])return void M.addText(R) +;e=E(N.subLanguage,R,!0,S[N.subLanguage]),S[N.subLanguage]=e._top +}else e=x(R,N.subLanguage.length?N.subLanguage:null) +;N.relevance>0&&(j+=e.relevance),M.__addSublanguage(e._emitter,e.language) +})():l(),R=""}function u(e,t){ +""!==e&&(M.startScope(t),M.addText(e),M.endScope())}function d(e,t){let n=1 +;const i=t.length-1;for(;n<=i;){if(!e._emit[n]){n++;continue} +const i=_.classNameAliases[e[n]]||e[n],s=t[n];i?u(s,i):(R=s,l(),R=""),n++}} +function h(e,t){ +return e.scope&&"string"==typeof e.scope&&M.openNode(_.classNameAliases[e.scope]||e.scope), +e.beginScope&&(e.beginScope._wrap?(u(R,_.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), +R=""):e.beginScope._multi&&(d(e.beginScope,t),R="")),N=Object.create(e,{parent:{ +value:N}}),N}function f(e,n,i){let s=((e,t)=>{const n=e&&e.exec(t) +;return n&&0===n.index})(e.endRe,i);if(s){if(e["on:end"]){const i=new t(e) +;e["on:end"](n,i),i.isMatchIgnored&&(s=!1)}if(s){ +for(;e.endsParent&&e.parent;)e=e.parent;return e}} +if(e.endsWithParent)return f(e.parent,n,i)}function b(e){ +return 0===N.matcher.regexIndex?(R+=e[0],1):(T=!0,0)}function m(e){ +const t=e[0],i=n.substring(e.index),s=f(N,e,i);if(!s)return ee;const o=N +;N.endScope&&N.endScope._wrap?(g(), +u(t,N.endScope._wrap)):N.endScope&&N.endScope._multi?(g(), +d(N.endScope,e)):o.skip?R+=t:(o.returnEnd||o.excludeEnd||(R+=t), +g(),o.excludeEnd&&(R=t));do{ +N.scope&&M.closeNode(),N.skip||N.subLanguage||(j+=N.relevance),N=N.parent +}while(N!==s.parent);return s.starts&&h(s.starts,e),o.returnEnd?0:t.length} +let w={};function y(i,o){const a=o&&o[0];if(R+=i,null==a)return g(),0 +;if("begin"===w.type&&"end"===o.type&&w.index===o.index&&""===a){ +if(R+=n.slice(o.index,o.index+1),!r){const t=Error(`0 width match regex (${e})`) +;throw t.languageName=e,t.badRule=w.rule,t}return 1} +if(w=o,"begin"===o.type)return(e=>{ +const n=e[0],i=e.rule,s=new t(i),o=[i.__beforeBegin,i["on:begin"]] +;for(const t of o)if(t&&(t(e,s),s.isMatchIgnored))return b(n) +;return i.skip?R+=n:(i.excludeBegin&&(R+=n), +g(),i.returnBegin||i.excludeBegin||(R=n)),h(i,e),i.returnBegin?0:n.length})(o) +;if("illegal"===o.type&&!s){ +const e=Error('Illegal lexeme "'+a+'" for mode "'+(N.scope||"")+'"') +;throw e.mode=N,e}if("end"===o.type){const e=m(o);if(e!==ee)return e} +if("illegal"===o.type&&""===a)return 1 +;if(I>1e5&&I>3*o.index)throw Error("potential infinite loop, way more iterations than matches") +;return R+=a,a.length}const _=O(e) +;if(!_)throw W(a.replace("{}",e)),Error('Unknown language: "'+e+'"') +;const v=V(_);let k="",N=o||v;const S={},M=new p.__emitter(p);(()=>{const e=[] +;for(let t=N;t!==_;t=t.parent)t.scope&&e.unshift(t.scope) +;e.forEach((e=>M.openNode(e)))})();let R="",j=0,A=0,I=0,T=!1;try{ +if(_.__emitTokens)_.__emitTokens(n,M);else{for(N.matcher.considerAll();;){ +I++,T?T=!1:N.matcher.considerAll(),N.matcher.lastIndex=A +;const e=N.matcher.exec(n);if(!e)break;const t=y(n.substring(A,e.index),e) +;A=e.index+t}y(n.substring(A))}return M.finalize(),k=M.toHTML(),{language:e, +value:k,relevance:j,illegal:!1,_emitter:M,_top:N}}catch(t){ +if(t.message&&t.message.includes("Illegal"))return{language:e,value:Y(n), +illegal:!0,relevance:0,_illegalBy:{message:t.message,index:A, +context:n.slice(A-100,A+100),mode:t.mode,resultSoFar:k},_emitter:M};if(r)return{ +language:e,value:Y(n),illegal:!1,relevance:0,errorRaised:t,_emitter:M,_top:N} +;throw t}}function x(e,t){t=t||p.languages||Object.keys(i);const n=(e=>{ +const t={value:Y(e),illegal:!1,relevance:0,_top:l,_emitter:new p.__emitter(p)} +;return t._emitter.addText(e),t})(e),s=t.filter(O).filter(k).map((t=>E(t,e,!1))) +;s.unshift(n);const o=s.sort(((e,t)=>{ +if(e.relevance!==t.relevance)return t.relevance-e.relevance +;if(e.language&&t.language){if(O(e.language).supersetOf===t.language)return 1 +;if(O(t.language).supersetOf===e.language)return-1}return 0})),[r,a]=o,c=r +;return c.secondBest=a,c}function w(e){let t=null;const n=(e=>{ +let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"" +;const n=p.languageDetectRe.exec(t);if(n){const t=O(n[1]) +;return t||(X(a.replace("{}",n[1])), +X("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"} +return t.split(/\s+/).find((e=>b(e)||O(e)))})(e);if(b(n))return +;if(N("before:highlightElement",{el:e,language:n +}),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e) +;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), +console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), +console.warn("The element with unescaped HTML:"), +console.warn(e)),p.throwUnescapedHTML))throw new J("One of your code blocks includes unescaped HTML.",e.innerHTML) +;t=e;const i=t.textContent,o=n?m(i,{language:n,ignoreIllegals:!0}):x(i) +;e.innerHTML=o.value,e.dataset.highlighted="yes",((e,t,n)=>{const i=t&&s[t]||n +;e.classList.add("hljs"),e.classList.add("language-"+i) +})(e,n,o.language),e.result={language:o.language,re:o.relevance, +relevance:o.relevance},o.secondBest&&(e.secondBest={ +language:o.secondBest.language,relevance:o.secondBest.relevance +}),N("after:highlightElement",{el:e,result:o,text:i})}let y=!1;function _(){ +"loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(w):y=!0 +}function O(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]} +function v(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ +s[e.toLowerCase()]=t}))}function k(e){const t=O(e) +;return t&&!t.disableAutodetect}function N(e,t){const n=e;o.forEach((e=>{ +e[n]&&e[n](t)}))} +"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ +y&&_()}),!1),Object.assign(n,{highlight:m,highlightAuto:x,highlightAll:_, +highlightElement:w, +highlightBlock:e=>(G("10.7.0","highlightBlock will be removed entirely in v12.0"), +G("10.7.0","Please use highlightElement now."),w(e)),configure:e=>{p=Q(p,e)}, +initHighlighting:()=>{ +_(),G("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, +initHighlightingOnLoad:()=>{ +_(),G("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") +},registerLanguage:(e,t)=>{let s=null;try{s=t(n)}catch(t){ +if(W("Language definition for '{}' could not be registered.".replace("{}",e)), +!r)throw t;W(t),s=l} +s.name||(s.name=e),i[e]=s,s.rawDefinition=t.bind(null,n),s.aliases&&v(s.aliases,{ +languageName:e})},unregisterLanguage:e=>{delete i[e] +;for(const t of Object.keys(s))s[t]===e&&delete s[t]}, +listLanguages:()=>Object.keys(i),getLanguage:O,registerAliases:v, +autoDetection:k,inherit:Q,addPlugin:e=>{(e=>{ +e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{ +e["before:highlightBlock"](Object.assign({block:t.el},t)) +}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{ +e["after:highlightBlock"](Object.assign({block:t.el},t))})})(e),o.push(e)}, +removePlugin:e=>{const t=o.indexOf(e);-1!==t&&o.splice(t,1)}}),n.debugMode=()=>{ +r=!1},n.safeMode=()=>{r=!0},n.versionString="11.9.0",n.regex={concat:h, +lookahead:g,either:f,optional:d,anyNumberOfTimes:u} +;for(const t in j)"object"==typeof j[t]&&e(j[t]);return Object.assign(n,j),n +},ne=te({});return ne.newInstance=()=>te({}),ne}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);/*! `bash` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const s=e.regex,t={},n={begin:/\$\{/, +end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{ +className:"variable",variants:[{ +begin:s.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},n]});const a={ +className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE] +},i=e.inherit(e.COMMENT(),{match:[/(^|\s)/,/#.*$/],scope:{2:"comment"}}),c={ +begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, +end:/(\w+)/,className:"string"})]}},o={className:"string",begin:/"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,t,a]};a.contains.push(o);const r={begin:/\$?\(\(/, +end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] +},l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 +}),m={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, +contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ +name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, +keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], +literal:["true","false"], +built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] +},contains:[l,e.SHEBANG(),m,r,i,c,{match:/(\/[a-z._-]+)+/},o,{match:/\\"/},{ +className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}})() +;hljs.registerLanguage("bash",e)})();/*! `c` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n=e.regex,t=e.COMMENT("//","$",{ +contains:[{begin:/\\\n/}] +}),s="decltype\\(auto\\)",a="[a-zA-Z_]\\w*::",r="("+s+"|"+n.optional(a)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",i={ +className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ +match:/\batomic_[a-z]{3,6}\b/}]},l={className:"string",variants:[{ +begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ +begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", +end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ +begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},o={ +className:"number",variants:[{begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" +},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ +keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(l,{className:"string"}),{ +className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ +className:"title",begin:n.optional(a)+e.IDENT_RE,relevance:0 +},g=n.optional(a)+e.IDENT_RE+"\\s*\\(",u={ +keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], +type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], +literal:"true false NULL", +built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" +},m=[c,i,t,e.C_BLOCK_COMMENT_MODE,o,l],_={variants:[{begin:/=/,end:/;/},{ +begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], +keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u, +contains:m.concat(["self"]),relevance:0}]),relevance:0},p={ +begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, +keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:s,keywords:u,relevance:0},{ +begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})], +relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/, +keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,l,o,i,{begin:/\(/, +end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,l,o,i] +}]},i,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u, +disableAutodetect:!0,illegal:"=]/,contains:[{ +beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c, +strings:l,keywords:u}}}})();hljs.registerLanguage("c",e)})();/*! `cpp` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const t=e.regex,a=e.COMMENT("//","$",{ +contains:[{begin:/\\\n/}] +}),n="decltype\\(auto\\)",r="[a-zA-Z_]\\w*::",i="(?!struct)("+n+"|"+t.optional(r)+"[a-zA-Z_]\\w*"+t.optional("<[^<>]+>")+")",s={ +className:"type",begin:"\\b[a-z\\d_]*_t\\b"},c={className:"string",variants:[{ +begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ +begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", +end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ +begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},o={ +className:"number",variants:[{ +begin:"[+-]?(?:(?:[0-9](?:'?[0-9])*\\.(?:[0-9](?:'?[0-9])*)?|\\.[0-9](?:'?[0-9])*)(?:[Ee][+-]?[0-9](?:'?[0-9])*)?|[0-9](?:'?[0-9])*[Ee][+-]?[0-9](?:'?[0-9])*|0[Xx](?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*(?:\\.(?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)?)?|\\.[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)[Pp][+-]?[0-9](?:'?[0-9])*)(?:[Ff](?:16|32|64|128)?|(BF|bf)16|[Ll]|)" +},{ +begin:"[+-]?\\b(?:0[Bb][01](?:'?[01])*|0[Xx][0-9A-Fa-f](?:'?[0-9A-Fa-f])*|0(?:'?[0-7])*|[1-9](?:'?[0-9])*)(?:[Uu](?:LL?|ll?)|[Uu][Zz]?|(?:LL?|ll?)[Uu]?|[Zz][Uu]|)" +}],relevance:0},l={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ +keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(c,{className:"string"}),{ +className:"string",begin:/<.*?>/},a,e.C_BLOCK_COMMENT_MODE]},u={ +className:"title",begin:t.optional(r)+e.IDENT_RE,relevance:0 +},d=t.optional(r)+e.IDENT_RE+"\\s*\\(",p={ +type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"], +keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"], +literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"], +_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"] +},_={className:"function.dispatch",relevance:0,keywords:{ +_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"] +}, +begin:t.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,t.lookahead(/(<[^<>]+>|)\s*\(/)) +},m=[_,l,s,a,e.C_BLOCK_COMMENT_MODE,o,c],f={variants:[{begin:/=/,end:/;/},{ +begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], +keywords:p,contains:m.concat([{begin:/\(/,end:/\)/,keywords:p, +contains:m.concat(["self"]),relevance:0}]),relevance:0},g={className:"function", +begin:"("+i+"[\\*&\\s]+)+"+d,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, +keywords:p,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:n,keywords:p,relevance:0},{ +begin:d,returnBegin:!0,contains:[u],relevance:0},{begin:/::/,relevance:0},{ +begin:/:/,endsWithParent:!0,contains:[c,o]},{relevance:0,match:/,/},{ +className:"params",begin:/\(/,end:/\)/,keywords:p,relevance:0, +contains:[a,e.C_BLOCK_COMMENT_MODE,c,o,s,{begin:/\(/,end:/\)/,keywords:p, +relevance:0,contains:["self",a,e.C_BLOCK_COMMENT_MODE,c,o,s]}] +},s,a,e.C_BLOCK_COMMENT_MODE,l]};return{name:"C++", +aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:p,illegal:"",keywords:p,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:p},{ +match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/], +className:{1:"keyword",3:"title.class"}}])}}})();hljs.registerLanguage("cpp",e) +})();/*! `csharp` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n={ +keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]), +built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"], +literal:["default","false","null","true"]},a=e.inherit(e.TITLE_MODE,{ +begin:"[a-zA-Z](\\.?\\w)*"}),i={className:"number",variants:[{ +begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},s={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}] +},t=e.inherit(s,{illegal:/\n/}),r={className:"subst",begin:/\{/,end:/\}/, +keywords:n},l=e.inherit(r,{illegal:/\n/}),c={className:"string",begin:/\$"/, +end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/ +},e.BACKSLASH_ESCAPE,l]},o={className:"string",begin:/\$@"/,end:'"',contains:[{ +begin:/\{\{/},{begin:/\}\}/},{begin:'""'},r]},d=e.inherit(o,{illegal:/\n/, +contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},l]}) +;r.contains=[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,i,e.C_BLOCK_COMMENT_MODE], +l.contains=[d,c,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,i,e.inherit(e.C_BLOCK_COMMENT_MODE,{ +illegal:/\n/})];const g={variants:[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] +},E={begin:"<",end:">",contains:[{beginKeywords:"in out"},a] +},_=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",b={ +begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"], +keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0, +contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{ +begin:"\x3c!--|--\x3e"},{begin:""}]}] +}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#", +end:"$",keywords:{ +keyword:"if else elif endif define undef warning error line region endregion pragma checksum" +}},g,i,{beginKeywords:"class interface",relevance:0,end:/[{;=]/, +illegal:/[^\s:,]/,contains:[{beginKeywords:"where class" +},a,E,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace", +relevance:0,end:/[{;=]/,illegal:/[^\s:]/, +contains:[a,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ +beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/, +contains:[a,E,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta", +begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{ +className:"string",begin:/"/,end:/"/}]},{ +beginKeywords:"new return throw await else",relevance:0},{className:"function", +begin:"("+_+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, +end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{ +beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial", +relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, +contains:[e.TITLE_MODE,E],relevance:0},{match:/\(\)/},{className:"params", +begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0, +contains:[g,i,e.C_BLOCK_COMMENT_MODE] +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},b]}}})() +;hljs.registerLanguage("csharp",e)})();/*! `css` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;const e=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video","defs","g","marker","mask","pattern","svg","switch","symbol","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feFlood","feGaussianBlur","feImage","feMerge","feMorphology","feOffset","feSpecularLighting","feTile","feTurbulence","linearGradient","radialGradient","stop","circle","ellipse","image","line","path","polygon","polyline","rect","text","use","textPath","tspan","foreignObject","clipPath"],r=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"].sort().reverse(),o=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"].sort().reverse(),t=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"].sort().reverse(),i=["align-content","align-items","align-self","alignment-baseline","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","cx","cy","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","empty-cells","enable-background","fill","fill-opacity","fill-rule","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","flood-color","flood-opacity","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-horizontal","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","kerning","justify-content","left","letter-spacing","lighting-color","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","marker","marker-end","marker-mid","marker-start","mask","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","r","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","shape-rendering","stop-color","stop-opacity","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","speak","speak-as","src","tab-size","table-layout","text-anchor","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vector-effect","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","x","y","z-index"].sort().reverse() +;return n=>{const a=n.regex,l=(e=>({IMPORTANT:{scope:"meta",begin:"!important"}, +BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number", +begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{ +className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{ +scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", +contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ +scope:"number", +begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", +relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} +}))(n),s=[n.APOS_STRING_MODE,n.QUOTE_STRING_MODE];return{name:"CSS", +case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:"from to"}, +classNameAliases:{keyframePosition:"selector-tag"},contains:[l.BLOCK_COMMENT,{ +begin:/-(webkit|moz|ms|o)-(?=[a-z])/},l.CSS_NUMBER_MODE,{ +className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0},{ +className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 +},l.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ +begin:":("+o.join("|")+")"},{begin:":(:)?("+t.join("|")+")"}]},l.CSS_VARIABLE,{ +className:"attribute",begin:"\\b("+i.join("|")+")\\b"},{begin:/:/,end:/[;}{]/, +contains:[l.BLOCK_COMMENT,l.HEXCOLOR,l.IMPORTANT,l.CSS_NUMBER_MODE,...s,{ +begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" +},contains:[...s,{className:"string",begin:/[^)]/,endsWithParent:!0, +excludeEnd:!0}]},l.FUNCTION_DISPATCH]},{begin:a.lookahead(/@/),end:"[{;]", +relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ +},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ +$pattern:/[a-z-]+/,keyword:"and or not only",attribute:r.join(" ")},contains:[{ +begin:/[a-z-]+(?=:)/,className:"attribute"},...s,l.CSS_NUMBER_MODE]}]},{ +className:"selector-tag",begin:"\\b("+e.join("|")+")\\b"}]}}})() +;hljs.registerLanguage("css",e)})();/*! `diff` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const a=e.regex;return{name:"Diff", +aliases:["patch"],contains:[{className:"meta",relevance:10, +match:a.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/) +},{className:"comment",variants:[{ +begin:a.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/), +end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{ +className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/, +end:/$/}]}}})();hljs.registerLanguage("diff",e)})();/*! `go` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n={ +keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"], +type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"], +literal:["true","false","iota","nil"], +built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"] +};return{name:"Go",aliases:["golang"],keywords:n,illegal:"{var e=(()=>{"use strict";return e=>{const a=e.regex;return{name:"GraphQL", +aliases:["gql"],case_insensitive:!0,disableAutodetect:!1,keywords:{ +keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"], +literal:["true","false","null"]}, +contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{ +scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation", +begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/, +end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{ +scope:"symbol",begin:a.concat(/[_A-Za-z][_0-9A-Za-z]*/,a.lookahead(/\s*:/)), +relevance:0}],illegal:[/[;<']/,/BEGIN/]}}})();hljs.registerLanguage("graphql",e) +})();/*! `ini` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n=e.regex,a={className:"number", +relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{begin:e.NUMBER_RE}] +},s=e.COMMENT();s.variants=[{begin:/;/,end:/$/},{begin:/#/,end:/$/}];const i={ +className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{begin:/\$\{(.*?)\}/ +}]},t={className:"literal",begin:/\bon|off|true|false|yes|no\b/},r={ +className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''", +end:"'''",relevance:10},{begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"' +},{begin:"'",end:"'"}]},l={begin:/\[/,end:/\]/,contains:[s,t,i,r,a,"self"], +relevance:0},c=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{ +name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/, +contains:[s,{className:"section",begin:/\[+/,end:/\]+/},{ +begin:n.concat(c,"(\\s*\\.\\s*",c,")*",n.lookahead(/\s*=\s*[^#\s]/)), +className:"attr",starts:{end:/$/,contains:[s,l,t,i,r,a]}}]}}})() +;hljs.registerLanguage("ini",e)})();/*! `java` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;var e="[0-9](_*[0-9])*",a=`\\.(${e})`,n="[0-9a-fA-F](_*[0-9a-fA-F])*",s={ +className:"number",variants:[{ +begin:`(\\b(${e})((${a})|\\.)?|(${a}))[eE][+-]?(${e})[fFdD]?\\b`},{ +begin:`\\b(${e})((${a})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${a})[fFdD]?\\b` +},{begin:`\\b(${e})[fFdD]\\b`},{ +begin:`\\b0[xX]((${n})\\.?|(${n})?\\.(${n}))[pP][+-]?(${e})[fFdD]?\\b`},{ +begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${n})[lL]?\\b`},{ +begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], +relevance:0};function t(e,a,n){return-1===n?"":e.replace(a,(s=>t(e,a,n-1)))} +return e=>{ +const a=e.regex,n="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",i=n+t("(?:<"+n+"~~~(?:\\s*,\\s*"+n+"~~~)*>)?",/~~~/g,2),r={ +keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"], +literal:["false","true","null"], +type:["char","boolean","long","float","int","byte","short","double"], +built_in:["super","this"]},l={className:"meta",begin:"@"+n,contains:[{ +begin:/\(/,end:/\)/,contains:["self"]}]},c={className:"params",begin:/\(/, +end:/\)/,keywords:r,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0} +;return{name:"Java",aliases:["jsp"],keywords:r,illegal:/<\/|#/, +contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/, +relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{ +begin:/import java\.[a-z]+\./,keywords:"import",relevance:2 +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/, +className:"string",contains:[e.BACKSLASH_ESCAPE] +},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{ +match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,n],className:{ +1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{ +begin:[a.concat(/(?!else)/,n),/\s+/,n,/\s+/,/=(?!=)/],className:{1:"type", +3:"variable",5:"operator"}},{begin:[/record/,/\s+/,n],className:{1:"keyword", +3:"title.class"},contains:[c,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ +beginKeywords:"new throw return else",relevance:0},{ +begin:["(?:"+i+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{ +2:"title.function"},keywords:r,contains:[{className:"params",begin:/\(/, +end:/\)/,keywords:r,relevance:0, +contains:[l,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,s,e.C_BLOCK_COMMENT_MODE] +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},s,l]}}})() +;hljs.registerLanguage("java",e)})();/*! `javascript` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;const e="[A-Za-z$_][0-9A-Za-z$_]*",n=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],a=["true","false","null","undefined","NaN","Infinity"],t=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],s=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],r=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],c=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],i=[].concat(r,t,s) +;return o=>{const l=o.regex,b=e,d={begin:/<[A-Za-z0-9\\._:-]+/, +end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ +const a=e[0].length+e.index,t=e.input[a] +;if("<"===t||","===t)return void n.ignoreMatch();let s +;">"===t&&(((e,{after:n})=>{const a="",$={ +match:[/const|var|let/,/\s+/,b,/\s*/,/=\s*/,/(async\s*)?/,l.lookahead(B)], +keywords:"async",className:{1:"keyword",3:"title.function"},contains:[R]} +;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:g,exports:{ +PARAMS_CONTAINS:w,CLASS_REFERENCE:k},illegal:/#(?![$_A-z])/, +contains:[o.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ +label:"use_strict",className:"meta",relevance:10, +begin:/^\s*['"]use (strict|asm)['"]/ +},o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,h,N,_,f,v,{match:/\$\d+/},A,k,{ +className:"attr",begin:b+l.lookahead(":"),relevance:0},$,{ +begin:"("+o.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", +keywords:"return throw case",relevance:0,contains:[v,o.REGEXP_MODE,{ +className:"function",begin:B,returnBegin:!0,end:"\\s*=>",contains:[{ +className:"params",variants:[{begin:o.UNDERSCORE_IDENT_RE,relevance:0},{ +className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, +excludeEnd:!0,keywords:g,contains:w}]}]},{begin:/,/,relevance:0},{match:/\s+/, +relevance:0},{variants:[{begin:"<>",end:""},{ +match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:d.begin, +"on:begin":d.isTrulyOpeningTag,end:d.end}],subLanguage:"xml",contains:[{ +begin:d.begin,end:d.end,skip:!0,contains:["self"]}]}]},I,{ +beginKeywords:"while if switch catch for"},{ +begin:"\\b(?!function)"+o.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", +returnBegin:!0,label:"func.def",contains:[R,o.inherit(o.TITLE_MODE,{begin:b, +className:"title.function"})]},{match:/\.\.\./,relevance:0},C,{match:"\\$"+b, +relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, +contains:[R]},x,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, +className:"variable.constant"},O,M,{match:/\$[(.]/}]}}})() +;hljs.registerLanguage("javascript",e)})();/*! `json` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const a=["true","false","null"],n={ +scope:"literal",beginKeywords:a.join(" ")};return{name:"JSON",keywords:{ +literal:a},contains:[{className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/, +relevance:1.01},{match:/[{}[\],:]/,className:"punctuation",relevance:0 +},e.QUOTE_STRING_MODE,n,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], +illegal:"\\S"}}})();hljs.registerLanguage("json",e)})();/*! `kotlin` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;var e="[0-9](_*[0-9])*",n=`\\.(${e})`,a="[0-9a-fA-F](_*[0-9a-fA-F])*",i={ +className:"number",variants:[{ +begin:`(\\b(${e})((${n})|\\.)?|(${n}))[eE][+-]?(${e})[fFdD]?\\b`},{ +begin:`\\b(${e})((${n})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${n})[fFdD]?\\b` +},{begin:`\\b(${e})[fFdD]\\b`},{ +begin:`\\b0[xX]((${a})\\.?|(${a})?\\.(${a}))[pP][+-]?(${e})[fFdD]?\\b`},{ +begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${a})[lL]?\\b`},{ +begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], +relevance:0};return e=>{const n={ +keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual", +built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing", +literal:"true false null"},a={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@" +},s={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},t={ +className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string", +variants:[{begin:'"""',end:'"""(?=[^"])',contains:[t,s]},{begin:"'",end:"'", +illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/, +contains:[e.BACKSLASH_ESCAPE,t,s]}]};s.contains.push(r);const l={ +className:"meta", +begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?" +},c={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/, +end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}] +},o=i,b=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),E={ +variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/, +contains:[]}]},d=E;return d.variants[1].contains=[E],E.variants[1].contains=[d], +{name:"Kotlin",aliases:["kt","kts"],keywords:n, +contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag", +begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,b,{className:"keyword", +begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol", +begin:/@\w+/}]}},a,l,c,{className:"function",beginKeywords:"fun",end:"[(]|$", +returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{ +begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0, +contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://, +keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/, +endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/, +endsWithParent:!0,contains:[E,e.C_LINE_COMMENT_MODE,b],relevance:0 +},e.C_LINE_COMMENT_MODE,b,l,c,r,e.C_NUMBER_MODE]},b]},{ +begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{ +3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0, +illegal:"extends implements",contains:[{ +beginKeywords:"public protected internal private constructor" +},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0, +excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/, +excludeBegin:!0,returnEnd:!0},l,c]},r,{className:"meta",begin:"^#!/usr/bin/env", +end:"$",illegal:"\n"},o]}}})();hljs.registerLanguage("kotlin",e)})();/*! `less` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;const e=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video","defs","g","marker","mask","pattern","svg","switch","symbol","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feFlood","feGaussianBlur","feImage","feMerge","feMorphology","feOffset","feSpecularLighting","feTile","feTurbulence","linearGradient","radialGradient","stop","circle","ellipse","image","line","path","polygon","polyline","rect","text","use","textPath","tspan","foreignObject","clipPath"],r=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"].sort().reverse(),t=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"].sort().reverse(),i=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"].sort().reverse(),o=["align-content","align-items","align-self","alignment-baseline","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","cx","cy","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","empty-cells","enable-background","fill","fill-opacity","fill-rule","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","flood-color","flood-opacity","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-horizontal","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","kerning","justify-content","left","letter-spacing","lighting-color","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","marker","marker-end","marker-mid","marker-start","mask","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","r","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","shape-rendering","stop-color","stop-opacity","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","speak","speak-as","src","tab-size","table-layout","text-anchor","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vector-effect","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","x","y","z-index"].sort().reverse(),n=t.concat(i).sort().reverse() +;return a=>{const l=(e=>({IMPORTANT:{scope:"meta",begin:"!important"}, +BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number", +begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{ +className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{ +scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", +contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ +scope:"number", +begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", +relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} +}))(a),s=n,d="[\\w-]+",c="("+d+"|@\\{"+d+"\\})",g=[],b=[],m=e=>({ +className:"string",begin:"~?"+e+".*?"+e}),p=(e,r,t)=>({className:e,begin:r, +relevance:t}),f={$pattern:/[a-z-]+/,keyword:"and or not only", +attribute:r.join(" ")},u={begin:"\\(",end:"\\)",contains:b,keywords:f, +relevance:0} +;b.push(a.C_LINE_COMMENT_MODE,a.C_BLOCK_COMMENT_MODE,m("'"),m('"'),l.CSS_NUMBER_MODE,{ +begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]", +excludeEnd:!0} +},l.HEXCOLOR,u,p("variable","@@?"+d,10),p("variable","@\\{"+d+"\\}"),p("built_in","~?`[^`]*?`"),{ +className:"attribute",begin:d+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0 +},l.IMPORTANT,{beginKeywords:"and not"},l.FUNCTION_DISPATCH);const h=b.concat({ +begin:/\{/,end:/\}/,contains:g}),k={beginKeywords:"when",endsWithParent:!0, +contains:[{beginKeywords:"and not"}].concat(b)},v={begin:c+"\\s*:", +returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/ +},l.CSS_VARIABLE,{className:"attribute",begin:"\\b("+o.join("|")+")\\b", +end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:b}}] +},y={className:"keyword", +begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b", +starts:{end:"[;{}]",keywords:f,returnEnd:!0,contains:b,relevance:0}},w={ +className:"variable",variants:[{begin:"@"+d+"\\s*:",relevance:15},{begin:"@"+d +}],starts:{end:"[;}]",returnEnd:!0,contains:h}},x={variants:[{ +begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:c,end:/\{/}],returnBegin:!0, +returnEnd:!0,illegal:"[<='$\"]",relevance:0, +contains:[a.C_LINE_COMMENT_MODE,a.C_BLOCK_COMMENT_MODE,k,p("keyword","all\\b"),p("variable","@\\{"+d+"\\}"),{ +begin:"\\b("+e.join("|")+")\\b",className:"selector-tag" +},l.CSS_NUMBER_MODE,p("selector-tag",c,0),p("selector-id","#"+c),p("selector-class","\\."+c,0),p("selector-tag","&",0),l.ATTRIBUTE_SELECTOR_MODE,{ +className:"selector-pseudo",begin:":("+t.join("|")+")"},{ +className:"selector-pseudo",begin:":(:)?("+i.join("|")+")"},{begin:/\(/, +end:/\)/,relevance:0,contains:h},{begin:"!important"},l.FUNCTION_DISPATCH]},_={ +begin:d+":(:)?"+`(${s.join("|")})`,returnBegin:!0,contains:[x]} +;return g.push(a.C_LINE_COMMENT_MODE,a.C_BLOCK_COMMENT_MODE,y,w,_,v,x,k,l.FUNCTION_DISPATCH), +{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:g}}})() +;hljs.registerLanguage("less",e)})();/*! `lua` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const t="\\[=*\\[",a="\\]=*\\]",n={ +begin:t,end:a,contains:["self"] +},o=[e.COMMENT("--(?!"+t+")","$"),e.COMMENT("--"+t,a,{contains:[n],relevance:10 +})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, +literal:"true false nil", +keyword:"and break do else elseif end for goto if in local not or repeat return then until while", +built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" +},contains:o.concat([{className:"function",beginKeywords:"function",end:"\\)", +contains:[e.inherit(e.TITLE_MODE,{ +begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params", +begin:"\\(",endsWithParent:!0,contains:o}].concat(o) +},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string", +begin:t,end:a,contains:[n],relevance:5}])}}})();hljs.registerLanguage("lua",e) +})();/*! `makefile` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const i={className:"variable", +variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)", +contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%{var e=(()=>{"use strict";return e=>{const n={begin:/<\/?[A-Za-z_]/, +end:">",subLanguage:"xml",relevance:0},a={variants:[{begin:/\[.+?\]\[.*?\]/, +relevance:0},{ +begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, +relevance:2},{ +begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), +relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ +begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ +},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, +returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", +excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", +end:"\\]",excludeBegin:!0,excludeEnd:!0}]},i={className:"strong",contains:[], +variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}] +},s={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{ +begin:/_(?![_\s])/,end:/_/,relevance:0}]},c=e.inherit(i,{contains:[] +}),t=e.inherit(s,{contains:[]});i.contains.push(t),s.contains.push(c) +;let g=[n,a];return[i,s,c,t].forEach((e=>{e.contains=e.contains.concat(g) +})),g=g.concat(i,s),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ +className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:g},{ +begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", +contains:g}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", +end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:g, +end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ +begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ +begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", +contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ +begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ +className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ +className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}})() +;hljs.registerLanguage("markdown",e)})();/*! `objectivec` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n=/[a-zA-Z@][a-zA-Z0-9_]*/,_={ +$pattern:n,keyword:["@interface","@class","@protocol","@implementation"]} +;return{name:"Objective-C", +aliases:["mm","objc","obj-c","obj-c++","objective-c++"],keywords:{ +"variable.language":["this","super"],$pattern:n, +keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"], +literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"], +built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"], +type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"] +},illegal:"/,end:/$/,illegal:"\\n" +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class", +begin:"("+_.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:_, +contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE, +relevance:0}]}}})();hljs.registerLanguage("objectivec",e)})();/*! `perl` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n=e.regex,t=/[dualxmsipngr]{0,12}/,s={$pattern:/[\w.]+/, +keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot class close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl field fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map method mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0" +},r={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:s},a={begin:/->\{/, +end:/\}/},i={scope:"attr",match:/\s+:\s*\w+(\s*\(.*?\))?/},c={scope:"variable", +variants:[{begin:/\$\d/},{ +begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])") +},{begin:/[$%@][^\s\w{=]|\$=/,relevance:0}],contains:[i]},o={className:"number", +variants:[{match:/0?\.[0-9][0-9_]+\b/},{ +match:/\bv?(0|[1-9][0-9_]*(\.[0-9_]+)?|[1-9][0-9_]*)\b/},{ +match:/\b0[0-7][0-7_]*\b/},{match:/\b0x[0-9a-fA-F][0-9a-fA-F_]*\b/},{ +match:/\b0b[0-1][0-1_]*\b/}],relevance:0 +},l=[e.BACKSLASH_ESCAPE,r,c],g=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],d=(e,s,r="\\1")=>{ +const a="\\1"===r?r:n.concat(r,s) +;return n.concat(n.concat("(?:",e,")"),s,/(?:\\.|[^\\\/])*?/,a,/(?:\\.|[^\\\/])*?/,r,t) +},m=(e,s,r)=>n.concat(n.concat("(?:",e,")"),s,/(?:\\.|[^\\\/])*?/,r,t),p=[c,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{ +endsWithParent:!0}),a,{className:"string",contains:l,variants:[{ +begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[", +end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{ +begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">", +relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'", +contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`", +contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{ +begin:"-?\\w+\\s*=>",relevance:0}]},o,{ +begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*", +keywords:"split return print reverse grep",relevance:0, +contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{ +begin:d("s|tr|y",n.either(...g,{capture:!0}))},{begin:d("s|tr|y","\\(","\\)")},{ +begin:d("s|tr|y","\\[","\\]")},{begin:d("s|tr|y","\\{","\\}")}],relevance:2},{ +className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{ +begin:m("(?:m|qr)?",/\//,/\//)},{begin:m("m|qr",n.either(...g,{capture:!0 +}),/\1/)},{begin:m("m|qr",/\(/,/\)/)},{begin:m("m|qr",/\[/,/\]/)},{ +begin:m("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub method", +end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE,i] +},{className:"class",beginKeywords:"class",end:"[;{]",excludeEnd:!0,relevance:5, +contains:[e.TITLE_MODE,i,o]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$", +end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$", +className:"comment"}]}];return r.contains=p,a.contains=p,{name:"Perl", +aliases:["pl","pm"],keywords:s,contains:p}}})();hljs.registerLanguage("perl",e) +})();/*! `php` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const t=e.regex,a=/(?![A-Za-z0-9])(?![$])/,r=t.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,a),n=t.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,a),o={ +scope:"variable",match:"\\$+"+r},c={scope:"subst",variants:[{begin:/\$\w+/},{ +begin:/\{\$/,end:/\}/}]},i=e.inherit(e.APOS_STRING_MODE,{illegal:null +}),s="[ \t\n]",l={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{ +illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(c)}),i,{ +begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/, +contains:e.QUOTE_STRING_MODE.contains.concat(c),"on:begin":(e,t)=>{ +t.data._beginMatch=e[1]||e[2]},"on:end":(e,t)=>{ +t.data._beginMatch!==e[1]&&t.ignoreMatch()}},e.END_SAME_AS_BEGIN({ +begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{ +begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ +begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{ +begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?" +}],relevance:0 +},_=["false","null","true"],p=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],E={ +keyword:p,literal:(e=>{const t=[];return e.forEach((e=>{ +t.push(e),e.toLowerCase()===e?t.push(e.toUpperCase()):t.push(e.toLowerCase()) +})),t})(_),built_in:b},u=e=>e.map((e=>e.replace(/\|\d+$/,""))),g={variants:[{ +match:[/new/,t.concat(s,"+"),t.concat("(?!",u(b).join("\\b|"),"\\b)"),n],scope:{ +1:"keyword",4:"title.class"}}]},h=t.concat(r,"\\b(?!\\()"),m={variants:[{ +match:[t.concat(/::/,t.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant" +}},{match:[/::/,/class/],scope:{2:"variable.language"}},{ +match:[n,t.concat(/::/,t.lookahead(/(?!class\b)/)),h],scope:{1:"title.class", +3:"variable.constant"}},{match:[n,t.concat("::",t.lookahead(/(?!class\b)/))], +scope:{1:"title.class"}},{match:[n,/::/,/class/],scope:{1:"title.class", +3:"variable.language"}}]},I={scope:"attr", +match:t.concat(r,t.lookahead(":"),t.lookahead(/(?!::)/))},f={relevance:0, +begin:/\(/,end:/\)/,keywords:E,contains:[I,o,m,e.C_BLOCK_COMMENT_MODE,l,d,g] +},O={relevance:0, +match:[/\b/,t.concat("(?!fn\\b|function\\b|",u(p).join("\\b|"),"|",u(b).join("\\b|"),"\\b)"),r,t.concat(s,"*"),t.lookahead(/(?=\()/)], +scope:{3:"title.function.invoke"},contains:[f]};f.contains.push(O) +;const v=[I,m,e.C_BLOCK_COMMENT_MODE,l,d,g];return{case_insensitive:!1, +keywords:E,contains:[{begin:t.concat(/#\[\s*/,n),beginScope:"meta",end:/]/, +endScope:"meta",keywords:{literal:_,keyword:["new","array"]},contains:[{ +begin:/\[/,end:/]/,keywords:{literal:_,keyword:["new","array"]}, +contains:["self",...v]},...v,{scope:"meta",match:n}] +},e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{ +scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/, +keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE, +contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{ +begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{ +begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},o,O,m,{ +match:[/const/,/\s/,r],scope:{1:"keyword",3:"variable.constant"}},g,{ +scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/, +excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use" +},e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params", +begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:E, +contains:["self",o,m,e.C_BLOCK_COMMENT_MODE,l,d]}]},{scope:"class",variants:[{ +beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait", +illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{ +beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{ +beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/, +contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{ +beginKeywords:"use",relevance:0,end:";",contains:[{ +match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},l,d]} +}})();hljs.registerLanguage("php",e)})();/*! `php-template` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var n=(()=>{"use strict";return n=>({name:"PHP template", +subLanguage:"xml",contains:[{begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php", +contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{ +begin:"b'",end:"'",skip:!0},n.inherit(n.APOS_STRING_MODE,{illegal:null, +className:null,contains:null,skip:!0}),n.inherit(n.QUOTE_STRING_MODE,{ +illegal:null,className:null,contains:null,skip:!0})]}]})})() +;hljs.registerLanguage("php-template",n)})();/*! `plaintext` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var t=(()=>{"use strict";return t=>({name:"Plain text", +aliases:["text","txt"],disableAutodetect:!0})})() +;hljs.registerLanguage("plaintext",t)})();/*! `python` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n=e.regex,a=/[\p{XID_Start}_]\p{XID_Continue}*/u,s=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={ +$pattern:/[A-Za-z]\w+|__\w+__/,keyword:s, +built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"], +literal:["__debug__","Ellipsis","False","None","NotImplemented","True"], +type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"] +},t={className:"meta",begin:/^(>>>|\.\.\.) /},r={className:"subst",begin:/\{/, +end:/\}/,keywords:i,illegal:/#/},l={begin:/\{\{/,relevance:0},b={ +className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,t],relevance:10},{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/, +contains:[e.BACKSLASH_ESCAPE,t],relevance:10},{ +begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,t,l,r]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/, +end:/"""/,contains:[e.BACKSLASH_ESCAPE,t,l,r]},{begin:/([uU]|[rR])'/,end:/'/, +relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{ +begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/, +end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/, +contains:[e.BACKSLASH_ESCAPE,l,r]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,l,r]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] +},o="[0-9](_?[0-9])*",c=`(\\b(${o}))?\\.(${o})|\\b(${o})\\.`,d="\\b|"+s.join("|"),g={ +className:"number",relevance:0,variants:[{ +begin:`(\\b(${o})|(${c}))[eE][+-]?(${o})[jJ]?(?=${d})`},{begin:`(${c})[jJ]?`},{ +begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${d})`},{ +begin:`\\b0[bB](_?[01])+[lL]?(?=${d})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${d})` +},{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${d})`},{begin:`\\b(${o})[jJ](?=${d})` +}]},p={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i, +contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={ +className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/, +end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i, +contains:["self",t,g,b,e.HASH_COMMENT_MODE]}]};return r.contains=[b,g,t],{ +name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i, +illegal:/(<\/|\?)|=>/,contains:[t,g,{begin:/\bself\b/},{beginKeywords:"if", +relevance:0},{match:/\bor\b/,scope:"keyword"},b,p,e.HASH_COMMENT_MODE,{ +match:[/\bdef/,/\s+/,a],scope:{1:"keyword",3:"title.function"},contains:[m]},{ +variants:[{match:[/\bclass/,/\s+/,a,/\s*/,/\(\s*/,a,/\s*\)/]},{ +match:[/\bclass/,/\s+/,a]}],scope:{1:"keyword",3:"title.class", +6:"title.class.inherited"}},{className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/, +contains:[g,m,b]}]}}})();hljs.registerLanguage("python",e)})();/*! `python-repl` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var a=(()=>{"use strict";return a=>({aliases:["pycon"],contains:[{ +className:"meta.prompt",starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"} +},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]})})() +;hljs.registerLanguage("python-repl",a)})();/*! `r` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const a=e.regex,n=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,i=a.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),s=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,t=a.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/) +;return{name:"R",keywords:{$pattern:n, +keyword:"function if in break next repeat else for while", +literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10", +built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm" +},contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/, +starts:{end:a.lookahead(a.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)), +endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{ +scope:"variable",variants:[{match:n},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0 +}]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}] +}),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE], +variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"', +relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{ +1:"operator",2:"number"},match:[s,i]},{scope:{1:"operator",2:"number"}, +match:[/%[^%]*%/,i]},{scope:{1:"punctuation",2:"number"},match:[t,i]},{scope:{ +2:"number"},match:[/[^a-zA-Z0-9._]|^/,i]}]},{scope:{3:"operator"}, +match:[n,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:s},{ +match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:t},{begin:"`",end:"`", +contains:[{begin:/\\./}]}]}}})();hljs.registerLanguage("r",e)})();/*! `ruby` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n=e.regex,a="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",s=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(s,/(::\w+)*/),t={ +"variable.constant":["__FILE__","__LINE__","__ENCODING__"], +"variable.language":["self","super"], +keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"], +built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"], +literal:["true","false","nil"]},c={className:"doctag",begin:"@[A-Za-z]+"},r={ +begin:"#<",end:">"},b=[e.COMMENT("#","$",{contains:[c] +}),e.COMMENT("^=begin","^=end",{contains:[c],relevance:10 +}),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],l={className:"subst",begin:/#\{/, +end:/\}/,keywords:t},d={className:"string",contains:[e.BACKSLASH_ESCAPE,l], +variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{ +begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{ +begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//, +end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{ +begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{ +begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{ +begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{ +begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{ +begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)), +contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/, +contains:[e.BACKSLASH_ESCAPE,l]})]}]},o="[0-9](_?[0-9])*",g={className:"number", +relevance:0,variants:[{ +begin:`\\b([1-9](_?[0-9])*|0)(\\.(${o}))?([eE][+-]?(${o})|r)?i?\\b`},{ +begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b" +},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{ +begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{ +begin:"\\b0(_?[0-7])+r?i?\\b"}]},_={variants:[{match:/\(\)/},{ +className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0, +keywords:t}]},u=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{ +match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class", +4:"title.class.inherited"},keywords:t},{match:[/(include|extend)\s+/,i],scope:{ +2:"title.class"},keywords:t},{relevance:0,match:[i,/\.new[. (]/],scope:{ +1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, +className:"variable.constant"},{relevance:0,match:s,scope:"title.class"},{ +match:[/def/,/\s+/,a],scope:{1:"keyword",3:"title.function"},contains:[_]},{ +begin:e.IDENT_RE+"::"},{className:"symbol", +begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol", +begin:":(?!\\s)",contains:[d,{begin:a}],relevance:0},g,{className:"variable", +begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{ +className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0, +relevance:0,keywords:t},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*", +keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,l], +illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{ +begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[", +end:"\\][a-z]*"}]}].concat(r,b),relevance:0}].concat(r,b) +;l.contains=u,_.contains=u;const m=[{begin:/^\s*=>/,starts:{end:"$",contains:u} +},{className:"meta.prompt", +begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])", +starts:{end:"$",keywords:t,contains:u}}];return b.unshift(r),{name:"Ruby", +aliases:["rb","gemspec","podspec","thor","irb"],keywords:t,illegal:/\/\*/, +contains:[e.SHEBANG({binary:"ruby"})].concat(m).concat(b).concat(u)}}})() +;hljs.registerLanguage("ruby",e)})();/*! `rust` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const t=e.regex,n={ +className:"title.function.invoke",relevance:0, +begin:t.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,t.lookahead(/\s*\(/)) +},a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],s=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] +;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:s, +keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], +literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:""},n]}}})() +;hljs.registerLanguage("rust",e)})();/*! `scss` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;const e=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video","defs","g","marker","mask","pattern","svg","switch","symbol","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feFlood","feGaussianBlur","feImage","feMerge","feMorphology","feOffset","feSpecularLighting","feTile","feTurbulence","linearGradient","radialGradient","stop","circle","ellipse","image","line","path","polygon","polyline","rect","text","use","textPath","tspan","foreignObject","clipPath"],r=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"].sort().reverse(),i=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"].sort().reverse(),t=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"].sort().reverse(),o=["align-content","align-items","align-self","alignment-baseline","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","cx","cy","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","empty-cells","enable-background","fill","fill-opacity","fill-rule","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","flood-color","flood-opacity","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-horizontal","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","kerning","justify-content","left","letter-spacing","lighting-color","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","marker","marker-end","marker-mid","marker-start","mask","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","r","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","shape-rendering","stop-color","stop-opacity","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","speak","speak-as","src","tab-size","table-layout","text-anchor","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vector-effect","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","x","y","z-index"].sort().reverse() +;return n=>{const a=(e=>({IMPORTANT:{scope:"meta",begin:"!important"}, +BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number", +begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{ +className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{ +scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", +contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ +scope:"number", +begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", +relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} +}))(n),l=t,s=i,d="@[a-z-]+",c={className:"variable", +begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS", +case_insensitive:!0,illegal:"[=/|']", +contains:[n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE,a.CSS_NUMBER_MODE,{ +className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{ +className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0 +},a.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag", +begin:"\\b("+e.join("|")+")\\b",relevance:0},{className:"selector-pseudo", +begin:":("+s.join("|")+")"},{className:"selector-pseudo", +begin:":(:)?("+l.join("|")+")"},c,{begin:/\(/,end:/\)/, +contains:[a.CSS_NUMBER_MODE]},a.CSS_VARIABLE,{className:"attribute", +begin:"\\b("+o.join("|")+")\\b"},{ +begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b" +},{begin:/:/,end:/[;}{]/,relevance:0, +contains:[a.BLOCK_COMMENT,c,a.HEXCOLOR,a.CSS_NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,a.IMPORTANT,a.FUNCTION_DISPATCH] +},{begin:"@(page|font-face)",keywords:{$pattern:d,keyword:"@page @font-face"}},{ +begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/, +keyword:"and or not only",attribute:r.join(" ")},contains:[{begin:d, +className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute" +},c,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,a.HEXCOLOR,a.CSS_NUMBER_MODE] +},a.FUNCTION_DISPATCH]}}})();hljs.registerLanguage("scss",e)})();/*! `shell` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var s=(()=>{"use strict";return s=>({name:"Shell Session", +aliases:["console","shellsession"],contains:[{className:"meta.prompt", +begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/, +subLanguage:"bash"}}]})})();hljs.registerLanguage("shell",s)})();/*! `sql` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const r=e.regex,t=e.COMMENT("--","$"),n=["true","false","unknown"],a=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],i=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=i,c=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!i.includes(e))),l={ +begin:r.concat(/\b/,r.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}} +;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{ +$pattern:/\b[\w\.]+/,keyword:((e,{exceptions:r,when:t}={})=>{const n=t +;return r=r||[],e.map((e=>e.match(/\|\d+$/)||r.includes(e)?e:n(e)?e+"|0":e)) +})(c,{when:e=>e.length<3}),literal:n,type:a, +built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"] +},contains:[{begin:r.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, +keyword:c.concat(s),literal:n,type:a}},{className:"type", +begin:r.either("double precision","large object","with timezone","without timezone") +},l,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string", +variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/, +contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{ +className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, +relevance:0}]}}})();hljs.registerLanguage("sql",e)})();/*! `swift` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";function e(e){ +return e?"string"==typeof e?e:e.source:null}function n(e){return t("(?=",e,")")} +function t(...n){return n.map((n=>e(n))).join("")}function a(...n){const t=(e=>{ +const n=e[e.length-1] +;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{} +})(n);return"("+(t.capture?"":"?:")+n.map((n=>e(n))).join("|")+")"} +const i=e=>t(/\b/,e,/\w$/.test(e)?/\b/:/\B/),s=["Protocol","Type"].map(i),c=["init","self"].map(i),u=["Any","Self"],r=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],o=["false","nil","true"],l=["assignment","associativity","higherThan","left","lowerThan","none","right"],m=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],p=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],d=a(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),F=a(d,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),b=t(d,F,"*"),h=a(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),f=a(h,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),w=t(h,f,"*"),g=t(/[A-Z]/,f,"*"),y=["attached","autoclosure",t(/convention\(/,a("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",t(/objc\(/,w,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],E=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] +;return e=>{const d={match:/\s+/,relevance:0},h=e.COMMENT("/\\*","\\*/",{ +contains:["self"]}),A=[e.C_LINE_COMMENT_MODE,h],v={match:[/\./,a(...s,...c)], +className:{2:"keyword"}},C={match:t(/\./,a(...r)),relevance:0 +},N=r.filter((e=>"string"==typeof e)).concat(["_|0"]),k={variants:[{ +className:"keyword", +match:a(...r.filter((e=>"string"!=typeof e)).concat(u).map(i),...c)}]},B={ +$pattern:a(/\b\w+/,/#\w+/),keyword:N.concat(m),literal:o},S=[v,C,k],D=[{ +match:t(/\./,a(...p)),relevance:0},{className:"built_in", +match:t(/\b/,a(...p),/(?=\()/)}],_={match:/->/,relevance:0},M=[_,{ +className:"operator",relevance:0,variants:[{match:b},{match:`\\.(\\.|${F})+`}] +}],x="([0-9]_*)+",$="([0-9a-fA-F]_*)+",L={className:"number",relevance:0, +variants:[{match:`\\b(${x})(\\.(${x}))?([eE][+-]?(${x}))?\\b`},{ +match:`\\b0x(${$})(\\.(${$}))?([pP][+-]?(${x}))?\\b`},{match:/\b0o([0-7]_*)+\b/ +},{match:/\b0b([01]_*)+\b/}]},I=(e="")=>({className:"subst",variants:[{ +match:t(/\\/,e,/[0\\tnr"']/)},{match:t(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}] +}),O=(e="")=>({className:"subst",match:t(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/) +}),P=(e="")=>({className:"subst",label:"interpol",begin:t(/\\/,e,/\(/),end:/\)/ +}),T=(e="")=>({begin:t(e,/"""/),end:t(/"""/,e),contains:[I(e),O(e),P(e)] +}),K=(e="")=>({begin:t(e,/"/),end:t(/"/,e),contains:[I(e),P(e)]}),j={ +className:"string", +variants:[T(),T("#"),T("##"),T("###"),K(),K("#"),K("##"),K("###")] +},z=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0, +contains:[e.BACKSLASH_ESCAPE]}],q={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//, +contains:z},U=e=>{const n=t(e,/\//),a=t(/\//,e);return{begin:n,end:a, +contains:[...z,{scope:"comment",begin:`#(?!.*${a})`,end:/$/}]}},Z={ +scope:"regexp",variants:[U("###"),U("##"),U("#"),q]},V={match:t(/`/,w,/`/) +},W=[V,{className:"variable",match:/\$\d+/},{className:"variable", +match:`\\$${f}+`}],G=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{ +contains:[{begin:/\(/,end:/\)/,keywords:E,contains:[...M,L,j]}]}},{ +scope:"keyword",match:t(/@/,a(...y))},{scope:"meta",match:t(/@/,w)}],H={ +match:n(/\b[A-Z]/),relevance:0,contains:[{className:"type", +match:t(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,f,"+") +},{className:"type",match:g,relevance:0},{match:/[?!]+/,relevance:0},{ +match:/\.\.\./,relevance:0},{match:t(/\s+&\s+/,n(g)),relevance:0}]},R={ +begin://,keywords:B,contains:[...A,...S,...G,_,H]};H.contains.push(R) +;const X={begin:/\(/,end:/\)/,relevance:0,keywords:B,contains:["self",{ +match:t(w,/\s*:/),keywords:"_|0",relevance:0 +},...A,Z,...S,...D,...M,L,j,...W,...G,H]},J={begin://, +keywords:"repeat each",contains:[...A,H]},Q={begin:/\(/,end:/\)/,keywords:B, +contains:[{begin:a(n(t(w,/\s*:/)),n(t(w,/\s+/,w,/\s*:/))),end:/:/,relevance:0, +contains:[{className:"keyword",match:/\b_\b/},{className:"params",match:w}] +},...A,...S,...M,L,j,...G,H,X],endsParent:!0,illegal:/["']/},Y={ +match:[/(func|macro)/,/\s+/,a(V.match,w,b)],className:{1:"keyword", +3:"title.function"},contains:[J,Q,d],illegal:[/\[/,/%/]},ee={ +match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"}, +contains:[J,Q,d],illegal:/\[|%/},ne={match:[/operator/,/\s+/,b],className:{ +1:"keyword",3:"title"}},te={begin:[/precedencegroup/,/\s+/,g],className:{ +1:"keyword",3:"title"},contains:[H],keywords:[...l,...o],end:/}/} +;for(const e of j.variants){const n=e.contains.find((e=>"interpol"===e.label)) +;n.keywords=B;const t=[...S,...D,...M,L,j,...W];n.contains=[...t,{begin:/\(/, +end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:B, +contains:[...A,Y,ee,{beginKeywords:"struct protocol class extension enum actor", +end:"\\{",excludeEnd:!0,keywords:B,contains:[e.inherit(e.TITLE_MODE,{ +className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...S] +},ne,te,{beginKeywords:"import",end:/$/,contains:[...A],relevance:0 +},Z,...S,...D,...M,L,j,...W,...G,H,X]}}})();hljs.registerLanguage("swift",e) +})();/*! `typescript` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;const e="[A-Za-z$_][0-9A-Za-z$_]*",n=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],a=["true","false","null","undefined","NaN","Infinity"],t=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],s=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],r=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],c=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],i=[].concat(r,t,s) +;function o(o){const l=o.regex,d=e,b={begin:/<[A-Za-z0-9\\._:-]+/, +end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ +const a=e[0].length+e.index,t=e.input[a] +;if("<"===t||","===t)return void n.ignoreMatch();let s +;">"===t&&(((e,{after:n})=>{const a="",$={ +match:[/const|var|let/,/\s+/,d,/\s*/,/=\s*/,/(async\s*)?/,l.lookahead(B)], +keywords:"async",className:{1:"keyword",3:"title.function"},contains:[R]} +;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:g,exports:{ +PARAMS_CONTAINS:w,CLASS_REFERENCE:k},illegal:/#(?![$_A-z])/, +contains:[o.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ +label:"use_strict",className:"meta",relevance:10, +begin:/^\s*['"]use (strict|asm)['"]/ +},o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,p,N,f,_,h,{match:/\$\d+/},y,k,{ +className:"attr",begin:d+l.lookahead(":"),relevance:0},$,{ +begin:"("+o.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", +keywords:"return throw case",relevance:0,contains:[h,o.REGEXP_MODE,{ +className:"function",begin:B,returnBegin:!0,end:"\\s*=>",contains:[{ +className:"params",variants:[{begin:o.UNDERSCORE_IDENT_RE,relevance:0},{ +className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, +excludeEnd:!0,keywords:g,contains:w}]}]},{begin:/,/,relevance:0},{match:/\s+/, +relevance:0},{variants:[{begin:"<>",end:""},{ +match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:b.begin, +"on:begin":b.isTrulyOpeningTag,end:b.end}],subLanguage:"xml",contains:[{ +begin:b.begin,end:b.end,skip:!0,contains:["self"]}]}]},O,{ +beginKeywords:"while if switch catch for"},{ +begin:"\\b(?!function)"+o.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", +returnBegin:!0,label:"func.def",contains:[R,o.inherit(o.TITLE_MODE,{begin:d, +className:"title.function"})]},{match:/\.\.\./,relevance:0},T,{match:"\\$"+d, +relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, +contains:[R]},C,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, +className:"variable.constant"},x,M,{match:/\$[(.]/}]}}return t=>{ +const s=o(t),r=e,l=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],d={ +beginKeywords:"namespace",end:/\{/,excludeEnd:!0, +contains:[s.exports.CLASS_REFERENCE]},b={beginKeywords:"interface",end:/\{/, +excludeEnd:!0,keywords:{keyword:"interface extends",built_in:l}, +contains:[s.exports.CLASS_REFERENCE]},g={$pattern:e, +keyword:n.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), +literal:a,built_in:i.concat(l),"variable.language":c},u={className:"meta", +begin:"@"+r},m=(e,n,a)=>{const t=e.contains.findIndex((e=>e.label===n)) +;if(-1===t)throw Error("can not find mode to replace");e.contains.splice(t,1,a)} +;return Object.assign(s.keywords,g), +s.exports.PARAMS_CONTAINS.push(u),s.contains=s.contains.concat([u,d,b]), +m(s,"shebang",t.SHEBANG()),m(s,"use_strict",{className:"meta",relevance:10, +begin:/^\s*['"]use strict['"]/ +}),s.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(s,{ +name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),s}})() +;hljs.registerLanguage("typescript",e)})();/*! `vbnet` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,s=/\d{1,2}(:\d{1,2}){1,2}/,r={ +className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{ +begin:n.concat(/# */,s,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{ +begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,s),/ *#/)}] +},l=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}] +}),o=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]}) +;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0, +classNameAliases:{label:"symbol"},keywords:{ +keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield", +built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort", +type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort", +literal:"true false nothing"}, +illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{ +className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/, +end:/"/,illegal:/\n/,contains:[{begin:/""/}]},r,{className:"number",relevance:0, +variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/ +},{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{ +begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{ +className:"label",begin:/^\w+:/},l,o,{className:"meta", +begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/, +end:/$/,keywords:{ +keyword:"const disable else elseif enable end externalsource if region then"}, +contains:[o]}]}}})();hljs.registerLanguage("vbnet",e)})();/*! `wasm` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{e.regex;const a=e.COMMENT(/\(;/,/;\)/) +;return a.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/, +keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"] +},contains:[e.COMMENT(/;;/,/$/),a,{match:[/(?:offset|align)/,/\s*/,/=/], +className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{ +match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{ +begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword", +3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/, +className:"type"},{className:"keyword", +match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/ +},{className:"number",relevance:0, +match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/ +}]}}})();hljs.registerLanguage("wasm",e)})();/*! `xml` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const a=e.regex,n=a.concat(/[\p{L}_]/u,a.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),s={ +className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},t={begin:/\s/, +contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] +},i=e.inherit(t,{begin:/\(/,end:/\)/}),c=e.inherit(e.APOS_STRING_MODE,{ +className:"string"}),l=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),r={ +endsWithParent:!0,illegal:/`]+/}]}]}]};return{ +name:"HTML, XML", +aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], +case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[t,l,c,i,{begin:/\[/,end:/\]/,contains:[{ +className:"meta",begin://,contains:[t,i,l,c]}]}] +},e.COMMENT(//,{relevance:10}),{begin://, +relevance:10},s,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, +relevance:10,contains:[l]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"style"},contains:[r],starts:{ +end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"script"},contains:[r],starts:{ +end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ +className:"tag",begin:/<>|<\/>/},{className:"tag", +begin:a.concat(//,/>/,/\s/)))), +end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:r}]},{ +className:"tag",begin:a.concat(/<\//,a.lookahead(a.concat(n,/>/))),contains:[{ +className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}} +})();hljs.registerLanguage("xml",e)})();/*! `yaml` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n="true false yes no null",a="[\\w#;/?:@&=+$,.~*'()[\\]]+",s={ +className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ +},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", +variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(s,{ +variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),l={ +end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},t={begin:/\{/, +end:/\}/,contains:[l],illegal:"\\n",relevance:0},g={begin:"\\[",end:"\\]", +contains:[l],illegal:"\\n",relevance:0},b=[{className:"attr",variants:[{ +begin:/\w[\w :()\./-]*:(?=[ \t]|$)/},{begin:/"\w[\w :()\./-]*":(?=[ \t]|$)/},{ +begin:/'\w[\w :()\./-]*':(?=[ \t]|$)/}]},{className:"meta",begin:"^---\\s*$", +relevance:10},{className:"string", +begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{ +begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0, +relevance:0},{className:"type",begin:"!\\w+!"+a},{className:"type", +begin:"!<"+a+">"},{className:"type",begin:"!"+a},{className:"type",begin:"!!"+a +},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta", +begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)", +relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{ +className:"number", +begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" +},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},t,g,s],r=[...b] +;return r.pop(),r.push(i),l.contains=r,{name:"YAML",case_insensitive:!0, +aliases:["yml"],contains:b}}})();hljs.registerLanguage("yaml",e)})(); \ No newline at end of file diff --git a/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css index 5502735e9..0fd65f194 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css @@ -68,11 +68,11 @@ -fx-background-color: -color-neutral-muted; } -.store-entry-comp .button-bar, .store-entry-comp .dropdown-comp { +.store-entry-comp .button-bar, .store-entry-comp .dropdown-comp, .store-entry-comp .toggle-switch-comp { -fx-opacity: 0.65; } -.store-entry-comp:hover .button-bar, .store-entry-comp:hover .dropdown-comp { +.store-entry-comp:hover .button-bar, .store-entry-comp:hover .dropdown-comp, .store-entry-comp:hover .toggle-switch-comp { -fx-opacity: 1.0; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/style.css b/app/src/main/resources/io/xpipe/app/resources/style/style.css index 16993e302..2d8968471 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/style.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/style.css @@ -5,6 +5,14 @@ } */ +.toggle-switch:has-graphic .label { + -fx-font-size: 1.7em; +} + +.toggle-switch:has-graphic { + -fx-font-size: 0.8em; +} + .store-layout .split-pane-divider { -fx-background-color: transparent; } diff --git a/app/src/main/resources/io/xpipe/app/resources/theme/custom.css b/app/src/main/resources/io/xpipe/app/resources/theme/custom.css index 9c93a834a..6fb386ee5 100644 --- a/app/src/main/resources/io/xpipe/app/resources/theme/custom.css +++ b/app/src/main/resources/io/xpipe/app/resources/theme/custom.css @@ -59,7 +59,7 @@ -color-bg-overlay: rgb(28, 28, 30); -color-bg-subtle: rgb(44, 44, 46); -color-bg-inset: #0b0b0c; - -color-border-default: rgb(255, 255, 255); + -color-border-default: #30363d; -color-border-muted: rgb(58, 58, 60); -color-border-subtle: rgb(49, 49, 52); -color-shadow-default: rgb(0, 0, 0); diff --git a/app/src/main/resources/io/xpipe/app/resources/theme/mocha.css b/app/src/main/resources/io/xpipe/app/resources/theme/mocha.css new file mode 100644 index 000000000..fece551f3 --- /dev/null +++ b/app/src/main/resources/io/xpipe/app/resources/theme/mocha.css @@ -0,0 +1,115 @@ +.root { + -color-dark: rgb(255, 255, 255); + -color-light: rgb(0, 0, 0); + -color-base-0: #f2f2f7; + -color-base-1: #e5e5ea; + -color-base-2: #d1d1d6; + -color-base-3: #aeaeb2; + -color-base-4: rgb(142, 142, 147); + -color-base-5: rgb(99, 99, 102); + -color-base-6: rgb(72, 72, 74); + -color-base-7: rgb(58, 58, 60); + -color-base-8: rgb(44, 44, 46); + -color-base-9: rgb(28, 28, 30); + -color-accent-0: #c2e0ff; + -color-accent-1: #9dceff; + -color-accent-2: #78bbff; + -color-accent-3: #54a9ff; + -color-accent-4: #2f96ff; + -color-accent-5: rgb(10, 132, 255); + -color-accent-6: #0970d9; + -color-accent-7: #075cb3; + -color-accent-8: #06498c; + -color-accent-9: #043566; + -color-success-0: #ccf5d2; + -color-success-1: #adefb7; + -color-success-2: #8ee99c; + -color-success-3: #70e381; + -color-success-4: #51dd66; + -color-success-5: rgb(50, 215, 75); + -color-success-6: #2bb740; + -color-success-7: #239735; + -color-success-8: #1c7629; + -color-success-9: #14561e; + -color-warning-0: #ffe7c2; + -color-warning-1: #ffd99d; + -color-warning-2: #ffca78; + -color-warning-3: #ffbc54; + -color-warning-4: #ffad2f; + -color-warning-5: rgb(255, 159, 10); + -color-warning-6: #d98709; + -color-warning-7: #b36f07; + -color-warning-8: #8c5706; + -color-warning-9: #664004; + -color-danger-0: #ffd1ce; + -color-danger-1: #ffb5b0; + -color-danger-2: #ff9993; + -color-danger-3: #ff7d75; + -color-danger-4: #ff6158; + -color-danger-5: rgb(255, 69, 58); + -color-danger-6: #d93b31; + -color-danger-7: #b33029; + -color-danger-8: #8c2620; + -color-danger-9: #661c17; + -color-fg-default: rgb(205, 214, 244); + -color-fg-muted: rgb(186, 194, 222); + -color-fg-subtle: rgb(166, 173, 200); + -color-fg-emphasis: rgb(180, 190, 254); + -color-bg-default: rgb(30, 30, 46); + -color-bg-overlay: rgb(24, 24, 37); + -color-bg-subtle: rgb(49, 50, 68); + -color-bg-inset: rgb(17, 17, 27); + -color-border-default: #30363d; + -color-border-muted: rgb(58, 58, 60); + -color-border-subtle: rgb(49, 49, 52); + -color-shadow-default: rgb(0, 0, 0); + -color-neutral-emphasis-plus: rgb(142, 142, 147); + -color-neutral-emphasis: rgb(142, 142, 147); + -color-neutral-muted: rgba(99, 99, 102, 0.4); + -color-neutral-subtle: rgba(99, 99, 102, 0.1); + -color-accent-fg: #2f96ff; + -color-accent-emphasis: rgb(10, 132, 255); + -color-accent-muted: rgba(10, 132, 255, 0.4); + -color-accent-subtle: rgba(10, 132, 255, 0.15); + -color-warning-fg: rgb(255, 159, 10); + -color-warning-emphasis: #d98709; + -color-warning-muted: rgba(255, 159, 10, 0.4); + -color-warning-subtle: rgba(255, 159, 10, 0.15); + -color-success-fg: rgb(50, 215, 75); + -color-success-emphasis: #2bb740; + -color-success-muted: rgba(50, 215, 75, 0.4); + -color-success-subtle: rgba(50, 215, 75, 0.15); + -color-danger-fg: rgb(255, 69, 58); + -color-danger-emphasis: rgb(255, 69, 58); + -color-danger-muted: rgba(255, 69, 58, 0.4); + -color-danger-subtle: rgba(255, 69, 58, 0.15); + -color-chart-1: #f3622d; + -color-chart-2: #fba71b; + -color-chart-3: #57b757; + -color-chart-4: #41a9c9; + -color-chart-5: #4258c9; + -color-chart-6: #9a42c8; + -color-chart-7: #c84164; + -color-chart-8: #888888; + -color-chart-1-alpha70: rgba(243, 98, 45, 0.7); + -color-chart-2-alpha70: rgba(251, 167, 27, 0.7); + -color-chart-3-alpha70: rgba(87, 183, 87, 0.7); + -color-chart-4-alpha70: rgba(65, 169, 201, 0.7); + -color-chart-5-alpha70: rgba(66, 88, 201, 0.7); + -color-chart-6-alpha70: rgba(154, 66, 200, 0.7); + -color-chart-7-alpha70: rgba(200, 65, 100, 0.7); + -color-chart-8-alpha70: rgba(136, 136, 136, 0.7); + -color-chart-1-alpha20: rgba(243, 98, 45, 0.2); + -color-chart-2-alpha20: rgba(251, 167, 27, 0.2); + -color-chart-3-alpha20: rgba(87, 183, 87, 0.2); + -color-chart-4-alpha20: rgba(65, 169, 201, 0.2); + -color-chart-5-alpha20: rgba(66, 88, 201, 0.2); + -color-chart-6-alpha20: rgba(154, 66, 200, 0.2); + -color-chart-7-alpha20: rgba(200, 65, 100, 0.2); + -color-chart-8-alpha20: rgba(136, 136, 136, 0.2); + -fx-background-color: -color-bg-default; + -fx-font-size: 14px; + -fx-background-radius: inherit; + -fx-background-insets: inherit; + -fx-padding: inherit; +} \ No newline at end of file diff --git a/beacon/README.md b/beacon/README.md index 54ed3fc19..5563a5fbb 100644 --- a/beacon/README.md +++ b/beacon/README.md @@ -4,36 +4,27 @@ ## XPipe Beacon The XPipe beacon component is responsible for handling all communications between the XPipe daemon -and the various programming language APIs and the CLI. It provides an API that supports all kinds +and the APIs and the CLI. It provides an API that supports all kinds of different operations. ### Inner Workings -- The underlying inter-process communication is realized through - TCP sockets on port `21721` on Windows and `21723` on Linux/macOS. +- The underlying communication is realized through an HTTP server on port `21721` - The data structures and exchange protocols are specified in the - [io.xpipe.beacon.exchange package](src/main/java/io/xpipe/beacon/exchange). + [io.xpipe.beacon.api package](src/main/java/io/xpipe/beacon/api). - Every exchange is initiated from the outside by sending a request message to the XPipe daemon. The daemon then always sends a response message. -- The header information of a message is formatted in the json format. +- The body of a message is formatted in the json format. As a result, all data structures exchanged must be serializable/deserializable with jackson. -- Both the requests and responses can optionally include content in a body. - A body is initiated with two new lines (`\n`). - -- The body is split into segments of max length `65536`. - Each segment is preceded by four bytes that specify the length of the next segment. - In case the next segment has a length of less than `65536` bytes, we know that the end of the body has been reached. - This way the socket communication can handle payloads of unknown length. - ## Configuration #### Custom port -The default port can be changed by passing the property `io.xpipe.beacon.port=` to both the daemon and APIs. +The default port can be changed by passing the property `io.xpipe.beacon.port=` to the daemon or changing it in the settings menu. Note that if both sides do not have the same port setting, they won't be able to reach each other. #### Custom launch command diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconAuthMethod.java b/beacon/src/main/java/io/xpipe/beacon/BeaconAuthMethod.java new file mode 100644 index 000000000..9a458bd7c --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconAuthMethod.java @@ -0,0 +1,34 @@ +package io.xpipe.beacon; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + property = "type") +public interface BeaconAuthMethod { + + @JsonTypeName("Local") + @Value + @Builder + @Jacksonized + public static class Local implements BeaconAuthMethod { + + @NonNull + String authFileContent; + } + + @JsonTypeName("ApiKey") + @Value + @Builder + @Jacksonized + public static class ApiKey implements BeaconAuthMethod { + + @NonNull + String key; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java b/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java index 8ccf6b9e5..80559fc12 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconClient.java @@ -1,314 +1,129 @@ package io.xpipe.beacon; -import io.xpipe.beacon.exchange.MessageExchanges; -import io.xpipe.beacon.exchange.data.ClientErrorMessage; -import io.xpipe.beacon.exchange.data.ServerErrorMessage; -import io.xpipe.core.util.Deobfuscator; -import io.xpipe.core.util.JacksonMapper; - -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.node.TextNode; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; +import io.xpipe.beacon.api.HandshakeExchange; +import io.xpipe.core.util.JacksonMapper; +import io.xpipe.core.util.XPipeInstallation; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringWriter; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; import java.util.Optional; -import static io.xpipe.beacon.BeaconConfig.BODY_SEPARATOR; +public class BeaconClient { -public class BeaconClient implements AutoCloseable { + private final int port; + private String token; - @Getter - private final AutoCloseable base; + public BeaconClient(int port) {this.port = port;} - private final InputStream in; - private final OutputStream out; - - private BeaconClient(AutoCloseable base, InputStream in, OutputStream out) { - this.base = base; - this.in = in; - this.out = out; - } - - public static BeaconClient establishConnection(ClientInformation information) throws Exception { - var socket = new Socket(); - socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), BeaconConfig.getUsedPort()), 5000); - socket.setSoTimeout(5000); - var client = new BeaconClient(socket, socket.getInputStream(), socket.getOutputStream()); - client.sendObject(JacksonMapper.getDefault().valueToTree(information)); - var res = client.receiveObject(); - if (!res.isTextual() || !"ACK".equals(res.asText())) { - throw new BeaconException("Daemon responded with invalid acknowledgement"); - } - socket.setSoTimeout(0); + public static BeaconClient establishConnection(int port, BeaconClientInformation information) throws Exception { + var client = new BeaconClient(port); + var auth = Files.readString(XPipeInstallation.getLocalBeaconAuthFile()); + HandshakeExchange.Response response = client.performRequest(HandshakeExchange.Request.builder() + .client(information) + .auth(BeaconAuthMethod.Local.builder().authFileContent(auth).build()).build()); + client.token = response.getSessionToken(); return client; } - public static Optional tryEstablishConnection(ClientInformation information) { + public static Optional tryEstablishConnection(int port, BeaconClientInformation information) { try { - return Optional.of(establishConnection(information)); + return Optional.of(establishConnection(port, information)); } catch (Exception ex) { return Optional.empty(); } } - public void close() throws ConnectorException { - try { - base.close(); - } catch (Exception ex) { - throw new ConnectorException("Couldn't close client", ex); - } - } - public InputStream receiveBody() throws ConnectorException { - try { - var sep = in.readNBytes(BODY_SEPARATOR.length); - if (sep.length != 0 && !Arrays.equals(BODY_SEPARATOR, sep)) { - throw new ConnectorException("Invalid body separator"); - } - return BeaconFormat.readBlocks(in); - } catch (IOException ex) { - throw new ConnectorException(ex); - } - } - - public OutputStream sendBody() throws ConnectorException { - try { - out.write(BODY_SEPARATOR); - return BeaconFormat.writeBlocks(out); - } catch (IOException ex) { - throw new ConnectorException(ex); - } - } - - public void sendRequest(T req) throws ClientException, ConnectorException { - ObjectNode json = JacksonMapper.getDefault().valueToTree(req); - var prov = MessageExchanges.byRequest(req); - if (prov.isEmpty()) { - throw new ClientException("Unknown request class " + req.getClass()); - } - - json.set("messageType", new TextNode(prov.get().getId())); - json.set("messagePhase", new TextNode("request")); - // json.set("id", new TextNode(UUID.randomUUID().toString())); - var msg = JsonNodeFactory.instance.objectNode(); - msg.set("xPipeMessage", json); - - if (BeaconConfig.printMessages()) { - System.out.println( - "Sending request to server of type " + req.getClass().getName()); - } - - sendObject(msg); - } - - public void sendEOF() throws ConnectorException { - try (OutputStream ignored = BeaconFormat.writeBlocks(out)) { - } catch (IOException ex) { - throw new ConnectorException("Couldn't write to socket", ex); - } - } - - public void sendObject(JsonNode node) throws ConnectorException { - var writer = new StringWriter(); - var mapper = JacksonMapper.getDefault(); - try (JsonGenerator g = mapper.createGenerator(writer).setPrettyPrinter(new DefaultPrettyPrinter())) { - g.writeTree(node); - } catch (IOException ex) { - throw new ConnectorException("Couldn't serialize request", ex); - } - - var content = writer.toString(); + @SuppressWarnings("unchecked") + public RES performRequest(BeaconInterface prov, String rawNode) throws + BeaconConnectorException, BeaconClientException, BeaconServerException { + var content = rawNode; if (BeaconConfig.printMessages()) { System.out.println("Sending raw request:"); System.out.println(content); } - try (OutputStream blockOut = BeaconFormat.writeBlocks(out)) { - blockOut.write(content.getBytes(StandardCharsets.UTF_8)); - } catch (IOException ex) { - throw new ConnectorException("Couldn't write to socket", ex); - } - } - - public T receiveResponse() throws ConnectorException, ClientException, ServerException { - return parseResponse(receiveObject()); - } - - private JsonNode receiveObject() throws ConnectorException, ClientException, ServerException { - JsonNode node; - try (InputStream blockIn = BeaconFormat.readBlocks(in)) { - node = JacksonMapper.getDefault().readTree(blockIn); - } catch (IOException ex) { - throw new ConnectorException("Couldn't read from socket", ex); + var client = HttpClient.newHttpClient(); + HttpResponse response; + try { + var uri = URI.create("http://localhost:" + port + prov.getPath()); + var builder = HttpRequest.newBuilder(); + if (token != null) { + builder.header("Authorization", "Bearer " + token); + } + var httpRequest = builder + .uri(uri).POST(HttpRequest.BodyPublishers.ofString(content)).build(); + response = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + } catch (Exception ex) { + throw new BeaconConnectorException("Couldn't send request", ex); } if (BeaconConfig.printMessages()) { - System.out.println("Received response:"); - System.out.println(node.toPrettyString()); + System.out.println("Received raw response:"); + System.out.println(response.body()); } - if (node.isMissingNode()) { - throw new ConnectorException("Received unexpected EOF"); - } - - var se = parseServerError(node); + var se = parseServerError(response); if (se.isPresent()) { se.get().throwError(); } - var ce = parseClientError(node); + var ce = parseClientError(response); if (ce.isPresent()) { throw ce.get().throwException(); } - return node; - } - - private Optional parseClientError(JsonNode node) throws ConnectorException { - ObjectNode content = (ObjectNode) node.get("xPipeClientError"); - if (content == null) { - return Optional.empty(); - } - try { - var message = JacksonMapper.getDefault().treeToValue(content, ClientErrorMessage.class); - return Optional.of(message); + var reader = JacksonMapper.getDefault().readerFor(prov.getResponseClass()); + var v = (RES) reader.readValue(response.body()); + return v; } catch (IOException ex) { - throw new ConnectorException("Couldn't parse client error message", ex); + throw new BeaconConnectorException("Couldn't parse response", ex); } } - private Optional parseServerError(JsonNode node) throws ConnectorException { - ObjectNode content = (ObjectNode) node.get("xPipeServerError"); - if (content == null) { - return Optional.empty(); - } - - try { - var message = JacksonMapper.getDefault().treeToValue(content, ServerErrorMessage.class); - Deobfuscator.deobfuscate(message.getError()); - return Optional.of(message); - } catch (IOException ex) { - throw new ConnectorException("Couldn't parse server error message", ex); - } - } - - private T parseResponse(JsonNode header) throws ConnectorException { - ObjectNode content = (ObjectNode) header.required("xPipeMessage"); - - var type = content.required("messageType").textValue(); - var phase = content.required("messagePhase").textValue(); - // var requestId = UUID.fromString(content.required("id").textValue()); - if (!phase.equals("response")) { - throw new IllegalArgumentException(); - } - content.remove("messageType"); - content.remove("messagePhase"); - // content.remove("id"); - - var prov = MessageExchanges.byId(type); + public RES performRequest(REQ req) throws BeaconConnectorException, BeaconClientException, BeaconServerException { + ObjectNode node = JacksonMapper.getDefault().valueToTree(req); + var prov = BeaconInterface.byRequest(req); if (prov.isEmpty()) { - throw new IllegalArgumentException("Unknown response id " + type); + throw new IllegalArgumentException("Unknown request class " + req.getClass()); + } + if (BeaconConfig.printMessages()) { + System.out.println("Sending request to server of type " + req.getClass().getName()); + } + + return performRequest(prov.get(), node.toPrettyString()); + } + + private Optional parseClientError(HttpResponse response) throws BeaconConnectorException { + if (response.statusCode() < 400 || response.statusCode() > 499) { + return Optional.empty(); } try { - var reader = JacksonMapper.getDefault().readerFor(prov.get().getResponseClass()); - return reader.readValue(content); + var v = JacksonMapper.getDefault().readValue(response.body(), BeaconClientErrorResponse.class); + return Optional.of(v); } catch (IOException ex) { - throw new ConnectorException("Couldn't parse response", ex); + throw new BeaconConnectorException("Couldn't parse client error message", ex); } } - public InputStream getRawInputStream() { - return in; - } - - public OutputStream getRawOutputStream() { - return out; - } - - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") - public abstract static class ClientInformation { - - public final CliClientInformation cli() { - return (CliClientInformation) this; + private Optional parseServerError(HttpResponse response) throws BeaconConnectorException { + if (response.statusCode() < 500 || response.statusCode() > 599) { + return Optional.empty(); } - public abstract String toDisplayString(); - } - - @JsonTypeName("cli") - @Value - @Builder - @Jacksonized - @EqualsAndHashCode(callSuper = false) - public static class CliClientInformation extends ClientInformation { - - @Override - public String toDisplayString() { - return "XPipe CLI"; + try { + var v = JacksonMapper.getDefault().readValue(response.body(), BeaconServerErrorResponse.class); + return Optional.of(v); + } catch (IOException ex) { + throw new BeaconConnectorException("Couldn't parse client error message", ex); } } - @JsonTypeName("daemon") - @Value - @Builder - @Jacksonized - @EqualsAndHashCode(callSuper = false) - public static class DaemonInformation extends ClientInformation { - - @Override - public String toDisplayString() { - return "Daemon"; - } - } - - @JsonTypeName("gateway") - @Value - @Builder - @Jacksonized - @EqualsAndHashCode(callSuper = false) - public static class GatewayClientInformation extends ClientInformation { - - String version; - - @Override - public String toDisplayString() { - return "XPipe Gateway " + version; - } - } - - @JsonTypeName("api") - @Value - @Builder - @Jacksonized - @EqualsAndHashCode(callSuper = false) - public static class ApiClientInformation extends ClientInformation { - - String version; - String language; - - @Override - public String toDisplayString() { - return String.format("XPipe %s API v%s", language, version); - } - } } diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/data/ClientErrorMessage.java b/beacon/src/main/java/io/xpipe/beacon/BeaconClientErrorResponse.java similarity index 53% rename from beacon/src/main/java/io/xpipe/beacon/exchange/data/ClientErrorMessage.java rename to beacon/src/main/java/io/xpipe/beacon/BeaconClientErrorResponse.java index 09fd318ee..bd2c196a2 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/data/ClientErrorMessage.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconClientErrorResponse.java @@ -1,6 +1,4 @@ -package io.xpipe.beacon.exchange.data; - -import io.xpipe.beacon.ClientException; +package io.xpipe.beacon; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,11 +10,11 @@ import lombok.extern.jackson.Jacksonized; @Builder @Jacksonized @AllArgsConstructor -public class ClientErrorMessage { +public class BeaconClientErrorResponse { String message; - public ClientException throwException() { - return new ClientException(message); + public BeaconClientException throwException() { + return new BeaconClientException(message); } } diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconClientException.java b/beacon/src/main/java/io/xpipe/beacon/BeaconClientException.java new file mode 100644 index 000000000..a561c777d --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconClientException.java @@ -0,0 +1,23 @@ +package io.xpipe.beacon; + +/** + * Indicates that a client request was invalid. + */ +public class BeaconClientException extends Exception { + + public BeaconClientException(String message) { + super(message); + } + + public BeaconClientException(String message, Throwable cause) { + super(message, cause); + } + + public BeaconClientException(Throwable cause) { + super(cause); + } + + public BeaconClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconClientInformation.java b/beacon/src/main/java/io/xpipe/beacon/BeaconClientInformation.java new file mode 100644 index 000000000..a0841e35e --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconClientInformation.java @@ -0,0 +1,59 @@ +package io.xpipe.beacon; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + property = "type") +public abstract class BeaconClientInformation { + + public abstract String toDisplayString(); + + @JsonTypeName("Cli") + @Value + @Builder + @Jacksonized + @EqualsAndHashCode(callSuper = false) + public static class Cli extends BeaconClientInformation { + + @Override + public String toDisplayString() { + return "XPipe CLI"; + } + } + + @JsonTypeName("Daemon") + @Value + @Builder + @Jacksonized + @EqualsAndHashCode(callSuper = false) + public static class Daemon extends BeaconClientInformation { + + @Override + public String toDisplayString() { + return "Daemon"; + } + } + + @JsonTypeName("Api") + @Value + @Builder + @Jacksonized + @EqualsAndHashCode(callSuper = false) + public static class Api extends BeaconClientInformation { + + @NonNull + String name; + + @Override + public String toDisplayString() { + return name; + } + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconConfig.java b/beacon/src/main/java/io/xpipe/beacon/BeaconConfig.java index 4e21f3d54..c62af056b 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconConfig.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconConfig.java @@ -1,15 +1,11 @@ package io.xpipe.beacon; import io.xpipe.core.util.XPipeInstallation; - import lombok.experimental.UtilityClass; -import java.nio.charset.StandardCharsets; - @UtilityClass public class BeaconConfig { - public static final byte[] BODY_SEPARATOR = "\n\n".getBytes(StandardCharsets.UTF_8); public static final String BEACON_PORT_PROP = "io.xpipe.beacon.port"; public static final String DAEMON_ARGUMENTS_PROP = "io.xpipe.beacon.daemonArgs"; private static final String PRINT_MESSAGES_PROPERTY = "io.xpipe.beacon.printMessages"; @@ -17,14 +13,6 @@ public class BeaconConfig { private static final String ATTACH_DEBUGGER_PROP = "io.xpipe.beacon.attachDebuggerToDaemon"; private static final String EXEC_DEBUG_PROP = "io.xpipe.beacon.printDaemonOutput"; private static final String EXEC_PROCESS_PROP = "io.xpipe.beacon.customDaemonCommand"; - private static final String LOCAL_PROXY_PROP = "io.xpipe.beacon.localProxy"; - - public static boolean localProxy() { - if (System.getProperty(LOCAL_PROXY_PROP) != null) { - return Boolean.parseBoolean(System.getProperty(LOCAL_PROXY_PROP)); - } - return false; - } public static boolean printMessages() { if (System.getProperty(PRINT_MESSAGES_PROPERTY) != null) { diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconConnection.java b/beacon/src/main/java/io/xpipe/beacon/BeaconConnection.java deleted file mode 100644 index 509e6d71b..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconConnection.java +++ /dev/null @@ -1,189 +0,0 @@ -package io.xpipe.beacon; - -import io.xpipe.core.util.FailableBiConsumer; -import io.xpipe.core.util.FailableConsumer; - -import lombok.Getter; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public abstract class BeaconConnection implements AutoCloseable { - - @Getter - protected BeaconClient beaconClient; - - private InputStream bodyInput; - private OutputStream bodyOutput; - - protected abstract void constructSocket(); - - @Override - public void close() { - try { - if (beaconClient != null) { - beaconClient.close(); - } - beaconClient = null; - } catch (Exception e) { - beaconClient = null; - throw new BeaconException("Could not close beacon connection", e); - } - } - - public void withOutputStream(FailableConsumer ex) { - try { - ex.accept(getOutputStream()); - } catch (IOException e) { - throw new BeaconException("Could not write to beacon output stream", e); - } - } - - public void withInputStream(FailableConsumer ex) { - try { - ex.accept(getInputStream()); - } catch (IOException e) { - throw new BeaconException("Could not read from beacon output stream", e); - } - } - - public void checkClosed() { - if (beaconClient == null) { - throw new BeaconException("Socket is closed"); - } - } - - public OutputStream getOutputStream() { - checkClosed(); - - if (bodyOutput == null) { - throw new IllegalStateException("Body output has not started yet"); - } - - return bodyOutput; - } - - public InputStream getInputStream() { - checkClosed(); - - if (bodyInput == null) { - throw new IllegalStateException("Body input has not started yet"); - } - - return bodyInput; - } - - public void performInputExchange( - REQ req, FailableBiConsumer responseConsumer) { - checkClosed(); - - performInputOutputExchange(req, null, responseConsumer); - } - - public void performInputOutputExchange( - REQ req, - FailableConsumer reqWriter, - FailableBiConsumer responseConsumer) { - checkClosed(); - - try { - beaconClient.sendRequest(req); - if (reqWriter != null) { - try (var out = sendBody()) { - reqWriter.accept(out); - } - } - RES res = beaconClient.receiveResponse(); - try (var in = receiveBody()) { - responseConsumer.accept(res, in); - } - } catch (Exception e) { - throw unwrapException(e); - } - } - - public void sendRequest(REQ req) { - checkClosed(); - - try { - beaconClient.sendRequest(req); - } catch (Exception e) { - throw unwrapException(e); - } - } - - public RES receiveResponse() { - checkClosed(); - - try { - return beaconClient.receiveResponse(); - } catch (Exception e) { - throw unwrapException(e); - } - } - - public OutputStream sendBody() { - checkClosed(); - - try { - bodyOutput = beaconClient.sendBody(); - return bodyOutput; - } catch (Exception e) { - throw unwrapException(e); - } - } - - public InputStream receiveBody() { - checkClosed(); - - try { - bodyInput = beaconClient.receiveBody(); - return bodyInput; - } catch (Exception e) { - throw unwrapException(e); - } - } - - public RES performOutputExchange( - REQ req, FailableConsumer reqWriter) { - checkClosed(); - - try { - beaconClient.sendRequest(req); - try (var out = sendBody()) { - reqWriter.accept(out); - } - return beaconClient.receiveResponse(); - } catch (Exception e) { - throw unwrapException(e); - } - } - - public RES performSimpleExchange(REQ req) { - checkClosed(); - - try { - beaconClient.sendRequest(req); - return beaconClient.receiveResponse(); - } catch (Exception e) { - throw unwrapException(e); - } - } - - private BeaconException unwrapException(Exception exception) { - if (exception instanceof ServerException s) { - return new BeaconException("An internal server error occurred", s); - } - - if (exception instanceof ClientException s) { - return new BeaconException("A client error occurred", s); - } - - if (exception instanceof ConnectorException s) { - return new BeaconException("A beacon connection error occurred", s); - } - - return new BeaconException("An unexpected error occurred", exception); - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconConnectorException.java b/beacon/src/main/java/io/xpipe/beacon/BeaconConnectorException.java new file mode 100644 index 000000000..afdb86b2d --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconConnectorException.java @@ -0,0 +1,25 @@ +package io.xpipe.beacon; + +/** + * Indicates that a connection error occurred. + */ +public class BeaconConnectorException extends Exception { + + public BeaconConnectorException() {} + + public BeaconConnectorException(String message) { + super(message); + } + + public BeaconConnectorException(String message, Throwable cause) { + super(message, cause); + } + + public BeaconConnectorException(Throwable cause) { + super(cause); + } + + public BeaconConnectorException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconException.java b/beacon/src/main/java/io/xpipe/beacon/BeaconException.java deleted file mode 100644 index 5c4bd3b63..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconException.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.xpipe.beacon; - -/** - * An unchecked exception that will be thrown in any case of an underlying exception. - */ -public class BeaconException extends RuntimeException { - - public BeaconException() {} - - public BeaconException(String message) { - super(message); - } - - public BeaconException(String message, Throwable cause) { - super(message, cause); - } - - public BeaconException(Throwable cause) { - super(cause); - } - - public BeaconException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconFormat.java b/beacon/src/main/java/io/xpipe/beacon/BeaconFormat.java deleted file mode 100644 index 029f2305b..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconFormat.java +++ /dev/null @@ -1,112 +0,0 @@ -package io.xpipe.beacon; - -import lombok.experimental.UtilityClass; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -@UtilityClass -public class BeaconFormat { - - private static final int SEGMENT_SIZE = 65536; - - public static OutputStream writeBlocks(OutputStream out) { - return new OutputStream() { - private final byte[] currentBytes = new byte[SEGMENT_SIZE]; - private int index; - - @Override - public void write(int b) throws IOException { - if (isClosed()) { - throw new IllegalStateException("Output is closed"); - } - - if (index == currentBytes.length) { - finishBlock(); - } - - currentBytes[index] = (byte) b; - index++; - } - - @Override - public void close() throws IOException { - if (isClosed()) { - return; - } - - finishBlock(); - out.flush(); - index = -1; - } - - private boolean isClosed() { - return index == -1; - } - - private void finishBlock() throws IOException { - if (isClosed()) { - throw new IllegalStateException("Output is closed"); - } - - if (BeaconConfig.printMessages()) { - System.out.println("Sending data block of length " + index); - } - - int length = index; - var lengthBuffer = ByteBuffer.allocate(4).putInt(length); - out.write(lengthBuffer.array()); - out.write(currentBytes, 0, length); - index = 0; - } - }; - } - - public static InputStream readBlocks(InputStream in) { - return new InputStream() { - - private byte[] currentBytes; - private int index; - private boolean lastBlock; - - @Override - public int read() throws IOException { - if ((currentBytes == null || index == currentBytes.length) && !lastBlock) { - if (!readBlock()) { - return -1; - } - } - - if (currentBytes != null && index == currentBytes.length && lastBlock) { - return -1; - } - - int out = currentBytes[index] & 0xff; - index++; - return out; - } - - private boolean readBlock() throws IOException { - var length = in.readNBytes(4); - if (length.length < 4) { - return false; - } - - var lengthInt = ByteBuffer.wrap(length).getInt(); - - if (BeaconConfig.printMessages()) { - System.out.println("Receiving data block of length " + lengthInt); - } - - currentBytes = in.readNBytes(lengthInt); - index = 0; - if (lengthInt < SEGMENT_SIZE) { - lastBlock = true; - } - return true; - } - }; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java b/beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java deleted file mode 100644 index 8b4a960b8..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.beacon; - -import io.xpipe.core.util.FailableRunnable; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * An exchange handler responsible for properly handling a request and sending a response. - */ -public interface BeaconHandler { - - /** - * Execute a Runnable after the initial response has been sent. - * - * @param r the runnable to execute - */ - void postResponse(FailableRunnable r); - - /** - * Prepares to attach a body to a response. - * - * @return the output stream that can be used to write the body payload - */ - OutputStream sendBody() throws IOException; - - /** - * Prepares to read an attached body of a request. - * - * @return the input stream that can be used to read the body payload - */ - InputStream receiveBody() throws IOException; -} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconInterface.java b/beacon/src/main/java/io/xpipe/beacon/BeaconInterface.java new file mode 100644 index 000000000..28ed9f7b6 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconInterface.java @@ -0,0 +1,74 @@ +package io.xpipe.beacon; + +import com.sun.net.httpserver.HttpExchange; +import io.xpipe.core.util.ModuleLayerLoader; +import lombok.SneakyThrows; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.ServiceLoader; +import java.util.stream.Collectors; + +public abstract class BeaconInterface { + + private static List> ALL; + + public static List> getAll() { + return ALL; + } + + public static Optional> byPath(String path) { + return ALL.stream() + .filter(d -> d.getPath().equals(path)) + .findAny(); + } + + + public static Optional> byRequest(RQ req) { + return ALL.stream() + .filter(d -> d.getRequestClass().equals(req.getClass())) + .findAny(); + } + + public static class Loader implements ModuleLayerLoader { + + @Override + public void init(ModuleLayer layer) { + var services = layer != null ? ServiceLoader.load(layer, BeaconInterface.class) : ServiceLoader.load(BeaconInterface.class); + ALL = services.stream() + .map(ServiceLoader.Provider::get) + .map(beaconInterface -> (BeaconInterface) beaconInterface) + .collect(Collectors.toList()); + // Remove parent classes + ALL.removeIf(beaconInterface -> ALL.stream().anyMatch(other -> + !other.equals(beaconInterface) && beaconInterface.getClass().isAssignableFrom(other.getClass()))); + } + } + + @SuppressWarnings("unchecked") + @SneakyThrows + public Class getRequestClass() { + var c = getClass().getSuperclass(); + var name = (c.getSuperclass().equals(BeaconInterface.class) ? c : getClass()).getName() + "$Request"; + return (Class) Class.forName(name); + } + + @SuppressWarnings("unchecked") + @SneakyThrows + public Class getResponseClass() { + var c = getClass().getSuperclass(); + var name = (c.getSuperclass().equals(BeaconInterface.class) ? c : getClass()).getName() + "$Response"; + return (Class) Class.forName(name); + } + + public boolean requiresAuthentication() { + return true; + } + + public abstract String getPath(); + + public Object handle(HttpExchange exchange, T body) throws IOException, BeaconClientException, BeaconServerException { + throw new UnsupportedOperationException(); + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconJacksonModule.java b/beacon/src/main/java/io/xpipe/beacon/BeaconJacksonModule.java index 9a8da0e17..f11a945a9 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconJacksonModule.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconJacksonModule.java @@ -8,8 +8,11 @@ public class BeaconJacksonModule extends SimpleModule { @Override public void setupModule(SetupContext context) { context.registerSubtypes( - new NamedType(BeaconClient.ApiClientInformation.class), - new NamedType(BeaconClient.CliClientInformation.class), - new NamedType(BeaconClient.DaemonInformation.class)); + new NamedType(BeaconClientInformation.Api.class), + new NamedType(BeaconClientInformation.Cli.class), + new NamedType(BeaconClientInformation.Daemon.class)); + context.registerSubtypes( + new NamedType(BeaconAuthMethod.Local.class), + new NamedType(BeaconAuthMethod.ApiKey.class)); } } diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java b/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java index 50649fad0..40cddc25f 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java @@ -1,6 +1,6 @@ package io.xpipe.beacon; -import io.xpipe.beacon.exchange.StopExchange; +import io.xpipe.beacon.api.DaemonStopExchange; import io.xpipe.core.process.OsType; import io.xpipe.core.store.FileNames; import io.xpipe.core.util.XPipeDaemonMode; @@ -18,9 +18,9 @@ import java.util.List; */ public class BeaconServer { - public static boolean isReachable() { + public static boolean isReachable(int port) { try (var socket = new Socket()) { - socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), BeaconConfig.getUsedPort()), 5000); + socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), port), 5000); return true; } catch (Exception e) { return false; @@ -108,8 +108,7 @@ public class BeaconServer { } public static boolean tryStop(BeaconClient client) throws Exception { - client.sendRequest(StopExchange.Request.builder().build()); - StopExchange.Response res = client.receiveResponse(); + DaemonStopExchange.Response res = client.performRequest(DaemonStopExchange.Request.builder().build()); return res.isSuccess(); } diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconServerErrorResponse.java b/beacon/src/main/java/io/xpipe/beacon/BeaconServerErrorResponse.java new file mode 100644 index 000000000..28f634504 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconServerErrorResponse.java @@ -0,0 +1,20 @@ +package io.xpipe.beacon; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +@SuppressWarnings("ClassCanBeRecord") +@Value +@Builder +@Jacksonized +@AllArgsConstructor +public class BeaconServerErrorResponse { + + Throwable error; + + public void throwError() throws BeaconServerException { + throw new BeaconServerException(error.getMessage(), error); + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconServerException.java b/beacon/src/main/java/io/xpipe/beacon/BeaconServerException.java new file mode 100644 index 000000000..8247bc0ae --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconServerException.java @@ -0,0 +1,23 @@ +package io.xpipe.beacon; + +/** + * Indicates that an internal server error occurred. + */ +public class BeaconServerException extends Exception { + + public BeaconServerException(String message) { + super(message); + } + + public BeaconServerException(String message, Throwable cause) { + super(message, cause); + } + + public BeaconServerException(Throwable cause) { + super(cause); + } + + public BeaconServerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/ClientException.java b/beacon/src/main/java/io/xpipe/beacon/ClientException.java deleted file mode 100644 index 784d9b642..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/ClientException.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.xpipe.beacon; - -/** - * Indicates that a client request caused an issue. - */ -public class ClientException extends Exception { - - public ClientException() {} - - public ClientException(String message) { - super(message); - } - - public ClientException(String message, Throwable cause) { - super(message, cause); - } - - public ClientException(Throwable cause) { - super(cause); - } - - public ClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/ConnectorException.java b/beacon/src/main/java/io/xpipe/beacon/ConnectorException.java deleted file mode 100644 index 83a14dbcf..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/ConnectorException.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.xpipe.beacon; - -/** - * Indicates that a connection error occurred. - */ -public class ConnectorException extends Exception { - - public ConnectorException() {} - - public ConnectorException(String message) { - super(message); - } - - public ConnectorException(String message, Throwable cause) { - super(message, cause); - } - - public ConnectorException(Throwable cause) { - super(cause); - } - - public ConnectorException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/RequestMessage.java b/beacon/src/main/java/io/xpipe/beacon/RequestMessage.java deleted file mode 100644 index 9f9a5c2da..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/RequestMessage.java +++ /dev/null @@ -1,3 +0,0 @@ -package io.xpipe.beacon; - -public interface RequestMessage {} diff --git a/beacon/src/main/java/io/xpipe/beacon/ResponseMessage.java b/beacon/src/main/java/io/xpipe/beacon/ResponseMessage.java deleted file mode 100644 index ec167994d..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/ResponseMessage.java +++ /dev/null @@ -1,3 +0,0 @@ -package io.xpipe.beacon; - -public interface ResponseMessage {} diff --git a/beacon/src/main/java/io/xpipe/beacon/ServerException.java b/beacon/src/main/java/io/xpipe/beacon/ServerException.java deleted file mode 100644 index d25c2272e..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/ServerException.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.xpipe.beacon; - -/** - * Indicates that an internal server error occurred. - */ -public class ServerException extends Exception { - - public ServerException() {} - - public ServerException(String message) { - super(message); - } - - public ServerException(String message, Throwable cause) { - super(message, cause); - } - - public ServerException(Throwable cause) { - super(cause); - } - - public ServerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/AskpassExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/AskpassExchange.java new file mode 100644 index 000000000..c77f50571 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/AskpassExchange.java @@ -0,0 +1,35 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import io.xpipe.core.util.SecretValue; +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.UUID; + +public class AskpassExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/askpass"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + UUID secretId; + + UUID request; + + String prompt; + } + + @Jacksonized + @Builder + @Value + public static class Response { + SecretValue value; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/ConnectionQueryExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/ConnectionQueryExchange.java new file mode 100644 index 000000000..829d41fa2 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/ConnectionQueryExchange.java @@ -0,0 +1,53 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import io.xpipe.core.store.StorePath; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.List; +import java.util.UUID; + +public class ConnectionQueryExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/connection/query"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + String categoryFilter; + @NonNull + String connectionFilter; + @NonNull + String typeFilter; + } + + @Jacksonized + @Builder + @Value + public static class Response { + @NonNull + List found; + } + + @Jacksonized + @Builder + @Value + public static class QueryResponse { + @NonNull + UUID uuid; + @NonNull + StorePath category; + @NonNull + StorePath connection; + @NonNull + String type; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/DaemonFocusExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/DaemonFocusExchange.java new file mode 100644 index 000000000..3a4bc0020 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/DaemonFocusExchange.java @@ -0,0 +1,29 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import io.xpipe.core.util.XPipeDaemonMode; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +public class DaemonFocusExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/daemon/focus"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + XPipeDaemonMode mode; + } + + @Jacksonized + @Builder + @Value + public static class Response {} +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/DaemonModeExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/DaemonModeExchange.java new file mode 100644 index 000000000..b9bcf2fd0 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/DaemonModeExchange.java @@ -0,0 +1,32 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import io.xpipe.core.util.XPipeDaemonMode; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +public class DaemonModeExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/daemon/mode"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + XPipeDaemonMode mode; + } + + @Jacksonized + @Builder + @Value + public static class Response { + @NonNull + XPipeDaemonMode usedMode; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/DaemonOpenExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/DaemonOpenExchange.java new file mode 100644 index 000000000..1fe22076a --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/DaemonOpenExchange.java @@ -0,0 +1,30 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.List; + +public class DaemonOpenExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/daemon/open"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + List arguments; + } + + @Jacksonized + @Builder + @Value + public static class Response {} +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/DaemonStatusExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/DaemonStatusExchange.java new file mode 100644 index 000000000..379e7b0eb --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/DaemonStatusExchange.java @@ -0,0 +1,27 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +public class DaemonStatusExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/daemon/status"; + } + + @Value + @Jacksonized + @Builder + public static class Request { + } + + @Jacksonized + @Builder + @Value + public static class Response { + String mode; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/DaemonStopExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/DaemonStopExchange.java new file mode 100644 index 000000000..5ae633f35 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/DaemonStopExchange.java @@ -0,0 +1,30 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +/** + * Requests the daemon to stop. + */ +public class DaemonStopExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/daemon/stop"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + } + + @Jacksonized + @Builder + @Value + public static class Response { + boolean success; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/DaemonVersionExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/DaemonVersionExchange.java new file mode 100644 index 000000000..18c107ebd --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/DaemonVersionExchange.java @@ -0,0 +1,30 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +public class DaemonVersionExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/daemon/version"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + } + + @Jacksonized + @Builder + @Value + public static class Response { + + String version; + String buildVersion; + String jvmVersion; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/HandshakeExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/HandshakeExchange.java new file mode 100644 index 000000000..bab3caf52 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/HandshakeExchange.java @@ -0,0 +1,40 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconAuthMethod; +import io.xpipe.beacon.BeaconClientInformation; +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +public class HandshakeExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/handshake"; + } + + @Override + public boolean requiresAuthentication() { + return false; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + BeaconAuthMethod auth; + @NonNull + BeaconClientInformation client; + } + + @Jacksonized + @Builder + @Value + public static class Response { + @NonNull + String sessionToken; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/ShellExecExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/ShellExecExchange.java new file mode 100644 index 000000000..3ad47bcb3 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/ShellExecExchange.java @@ -0,0 +1,38 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.UUID; + +public class ShellExecExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/shell/exec"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + UUID connection; + @NonNull + String command; + } + + @Jacksonized + @Builder + @Value + public static class Response { + long exitCode; + @NonNull + String stdout; + @NonNull + String stderr; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/ShellStartExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/ShellStartExchange.java new file mode 100644 index 000000000..0bb995cc9 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/ShellStartExchange.java @@ -0,0 +1,30 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.UUID; + +public class ShellStartExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/shell/start"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + UUID connection; + } + + @Jacksonized + @Builder + @Value + public static class Response {} +} diff --git a/beacon/src/main/java/io/xpipe/beacon/api/ShellStopExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/ShellStopExchange.java new file mode 100644 index 000000000..3c2532658 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/ShellStopExchange.java @@ -0,0 +1,30 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.UUID; + +public class ShellStopExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/shell/stop"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + UUID connection; + } + + @Jacksonized + @Builder + @Value + public static class Response {} +} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/TerminalLaunchExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/TerminalLaunchExchange.java similarity index 50% rename from beacon/src/main/java/io/xpipe/beacon/exchange/TerminalLaunchExchange.java rename to beacon/src/main/java/io/xpipe/beacon/api/TerminalLaunchExchange.java index 6f314a643..82d53dbd0 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/TerminalLaunchExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/api/TerminalLaunchExchange.java @@ -1,8 +1,6 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; +package io.xpipe.beacon.api; +import io.xpipe.beacon.BeaconInterface; import lombok.Builder; import lombok.NonNull; import lombok.Value; @@ -11,17 +9,17 @@ import lombok.extern.jackson.Jacksonized; import java.nio.file.Path; import java.util.UUID; -public class TerminalLaunchExchange implements MessageExchange { +public class TerminalLaunchExchange extends BeaconInterface { @Override - public String getId() { - return "terminalLaunch"; + public String getPath() { + return "/terminalLaunch"; } @Jacksonized @Builder @Value - public static class Request implements RequestMessage { + public static class Request { @NonNull UUID request; } @@ -29,7 +27,7 @@ public class TerminalLaunchExchange implements MessageExchange { @Jacksonized @Builder @Value - public static class Response implements ResponseMessage { + public static class Response { @NonNull Path targetFile; } diff --git a/beacon/src/main/java/io/xpipe/beacon/api/TerminalWaitExchange.java b/beacon/src/main/java/io/xpipe/beacon/api/TerminalWaitExchange.java new file mode 100644 index 000000000..da4d91d6d --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/api/TerminalWaitExchange.java @@ -0,0 +1,30 @@ +package io.xpipe.beacon.api; + +import io.xpipe.beacon.BeaconInterface; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.UUID; + +public class TerminalWaitExchange extends BeaconInterface { + + @Override + public String getPath() { + return "/terminalWait"; + } + + @Jacksonized + @Builder + @Value + public static class Request { + @NonNull + UUID request; + } + + @Jacksonized + @Builder + @Value + public static class Response {} +} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/AskpassExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/AskpassExchange.java deleted file mode 100644 index 8a1be7caa..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/AskpassExchange.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.core.util.SecretValue; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.UUID; - -public class AskpassExchange implements MessageExchange { - - @Override - public String getId() { - return "askpass"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - UUID secretId; - - @NonNull - UUID request; - - String prompt; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - SecretValue value; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/DrainExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/DrainExchange.java deleted file mode 100644 index 573b2ad6d..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/DrainExchange.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.core.store.DataStoreId; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class DrainExchange implements MessageExchange { - - @Override - public String getId() { - return "drain"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - DataStoreId source; - - @NonNull - String path; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java deleted file mode 100644 index f9082bda8..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.core.util.XPipeDaemonMode; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class FocusExchange implements MessageExchange { - - @Override - public String getId() { - return "focus"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - XPipeDaemonMode mode; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/LaunchExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/LaunchExchange.java deleted file mode 100644 index 2b1e03cc2..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/LaunchExchange.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.core.store.DataStoreId; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -public class LaunchExchange implements MessageExchange { - - @Override - public String getId() { - return "launch"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - DataStoreId id; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - @NonNull - List command; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchange.java deleted file mode 100644 index 999cd7057..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchange.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.beacon.exchange; - -import lombok.SneakyThrows; - -/** - * A message exchange scheme that implements a certain functionality. - */ -public interface MessageExchange { - - /** - * The unique id of this exchange that will be included in the messages. - */ - String getId(); - - /** - * Returns the request class, needed for serialization. - */ - @SneakyThrows - default Class getRequestClass() { - var c = getClass().getSuperclass(); - var name = (MessageExchange.class.isAssignableFrom(c) ? c : getClass()).getName() + "$Request"; - return Class.forName(name); - } - - /** - * Returns the response class, needed for serialization. - */ - @SneakyThrows - default Class getResponseClass() { - var c = getClass().getSuperclass(); - var name = (MessageExchange.class.isAssignableFrom(c) ? c : getClass()).getName() + "$Response"; - return Class.forName(name); - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchanges.java b/beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchanges.java deleted file mode 100644 index 54c0db988..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/MessageExchanges.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; - -import java.util.List; -import java.util.Optional; -import java.util.ServiceLoader; -import java.util.stream.Collectors; - -public class MessageExchanges { - - private static List ALL; - - public static void loadAll() { - if (ALL == null) { - ALL = ServiceLoader.load(MessageExchange.class).stream() - .map(s -> { - return s.get(); - }) - .collect(Collectors.toList()); - } - } - - public static Optional byId(String name) { - loadAll(); - return ALL.stream().filter(d -> d.getId().equals(name)).findAny(); - } - - public static Optional byRequest(RQ req) { - loadAll(); - return ALL.stream() - .filter(d -> d.getRequestClass().equals(req.getClass())) - .findAny(); - } - - public static Optional byResponse(RP rep) { - loadAll(); - return ALL.stream() - .filter(d -> d.getResponseClass().equals(rep.getClass())) - .findAny(); - } - - public static List getAll() { - loadAll(); - return ALL; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/OpenExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/OpenExchange.java deleted file mode 100644 index 29533f64a..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/OpenExchange.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -public class OpenExchange implements MessageExchange { - - @Override - public String getId() { - return "open"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - List arguments; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java deleted file mode 100644 index e656a72e5..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.core.store.DataStore; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.LinkedHashMap; - -/** - * Queries general information about a data source. - */ -public class QueryStoreExchange implements MessageExchange { - - @Override - public String getId() { - return "queryStore"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - String name; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - @NonNull - String name; - - String information; - - String summary; - - @NonNull - String provider; - - @NonNull - LinkedHashMap config; - - DataStore internalStore; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/SinkExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/SinkExchange.java deleted file mode 100644 index 8f5f308ef..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/SinkExchange.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.core.store.DataStoreId; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class SinkExchange implements MessageExchange { - - @Override - public String getId() { - return "sink"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - DataStoreId source; - - @NonNull - String path; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/StopExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/StopExchange.java deleted file mode 100644 index 6ee1475ac..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/StopExchange.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -/** - * Requests the daemon to stop. - */ -public class StopExchange implements MessageExchange { - - @Override - public String getId() { - return "stop"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage {} - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - boolean success; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/TerminalWaitExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/TerminalWaitExchange.java deleted file mode 100644 index a0cf98f9e..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/TerminalWaitExchange.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.beacon.exchange; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.UUID; - -public class TerminalWaitExchange implements MessageExchange { - - @Override - public String getId() { - return "terminalWait"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - UUID request; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/DialogExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/DialogExchange.java deleted file mode 100644 index dfa50dbc3..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/DialogExchange.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.core.dialog.DialogElement; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.UUID; - -public class DialogExchange implements MessageExchange { - - @Override - public String getId() { - return "dialog"; - } - - @Override - public Class getRequestClass() { - return DialogExchange.Request.class; - } - - @Override - public Class getResponseClass() { - return DialogExchange.Response.class; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - UUID dialogKey; - - String value; - boolean cancel; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - DialogElement element; - String errorMsg; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/EditStoreExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/EditStoreExchange.java deleted file mode 100644 index 351dd69e7..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/EditStoreExchange.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.core.dialog.DialogReference; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class EditStoreExchange implements MessageExchange { - - @Override - public String getId() { - return "editEntry"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - String name; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - @NonNull - DialogReference dialog; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListCollectionsExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListCollectionsExchange.java deleted file mode 100644 index 270f04470..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListCollectionsExchange.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.beacon.exchange.data.CollectionListEntry; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -public class ListCollectionsExchange implements MessageExchange { - - @Override - public String getId() { - return "listCollections"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage {} - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - List entries; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListEntriesExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListEntriesExchange.java deleted file mode 100644 index f7a0a5773..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListEntriesExchange.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.beacon.exchange.data.EntryListEntry; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -public class ListEntriesExchange implements MessageExchange { - - @Override - public String getId() { - return "listEntries"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - String collection; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - List entries; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListStoresExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListStoresExchange.java deleted file mode 100644 index cb5377d69..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ListStoresExchange.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.beacon.exchange.data.StoreListEntry; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -public class ListStoresExchange implements MessageExchange { - - @Override - public String getId() { - return "listStores"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage {} - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - List entries; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java deleted file mode 100644 index b9ad4cfd4..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.core.util.XPipeDaemonMode; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class ModeExchange implements MessageExchange { - - @Override - public String getId() { - return "mode"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - XPipeDaemonMode mode; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - @NonNull - XPipeDaemonMode usedMode; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ReadDrainExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ReadDrainExchange.java deleted file mode 100644 index 1cc2bd2cb..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ReadDrainExchange.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class ReadDrainExchange implements MessageExchange { - - @Override - public String getId() { - return "readDrain"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - String name; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveCollectionExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveCollectionExchange.java deleted file mode 100644 index bde33574d..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveCollectionExchange.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class RemoveCollectionExchange implements MessageExchange { - - @Override - public String getId() { - return "removeCollection"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - String collectionName; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveStoreExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveStoreExchange.java deleted file mode 100644 index 0c6dacf58..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RemoveStoreExchange.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class RemoveStoreExchange implements MessageExchange { - - @Override - public String getId() { - return "removeStore"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - String storeName; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameCollectionExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameCollectionExchange.java deleted file mode 100644 index 693179a7a..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameCollectionExchange.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class RenameCollectionExchange implements MessageExchange { - - @Override - public String getId() { - return "renameCollection"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - String collectionName; - - @NonNull - String newName; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameStoreExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameStoreExchange.java deleted file mode 100644 index f7c9a98f0..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameStoreExchange.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class RenameStoreExchange implements MessageExchange { - - @Override - public String getId() { - return "renameStore"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - @NonNull - String storeName; - - @NonNull - String newName; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage {} -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StatusExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StatusExchange.java deleted file mode 100644 index 7d08abae0..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StatusExchange.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class StatusExchange implements MessageExchange { - - @Override - public String getId() { - return "status"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage {} - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - String mode; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreAddExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreAddExchange.java deleted file mode 100644 index 898a591b6..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreAddExchange.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.core.dialog.DialogReference; -import io.xpipe.core.store.DataStore; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class StoreAddExchange implements MessageExchange { - - @Override - public String getId() { - return "storeAdd"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage { - DataStore storeInput; - - String type; - String name; - } - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - DialogReference config; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreProviderListExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreProviderListExchange.java deleted file mode 100644 index d7a173e90..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/StoreProviderListExchange.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; -import io.xpipe.beacon.exchange.data.ProviderEntry; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; -import java.util.Map; - -public class StoreProviderListExchange implements MessageExchange { - - @Override - public String getId() { - return "storeProviderList"; - } - - @Jacksonized - @Builder - @Value - public static class Request implements RequestMessage {} - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - @NonNull - Map> entries; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/VersionExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/VersionExchange.java deleted file mode 100644 index 14155cd77..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/VersionExchange.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.xpipe.beacon.exchange.cli; - -import io.xpipe.beacon.RequestMessage; -import io.xpipe.beacon.ResponseMessage; -import io.xpipe.beacon.exchange.MessageExchange; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -public class VersionExchange implements MessageExchange { - - @Override - public String getId() { - return "version"; - } - - @lombok.extern.jackson.Jacksonized - @lombok.Builder - @lombok.Value - public static class Request implements RequestMessage {} - - @Jacksonized - @Builder - @Value - public static class Response implements ResponseMessage { - - String version; - String buildVersion; - String jvmVersion; - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/data/CollectionListEntry.java b/beacon/src/main/java/io/xpipe/beacon/exchange/data/CollectionListEntry.java deleted file mode 100644 index 93e802846..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/data/CollectionListEntry.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.xpipe.beacon.exchange.data; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.time.Instant; - -@Value -@Jacksonized -@Builder -public class CollectionListEntry { - - String name; - int size; - Instant lastUsed; -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/data/EntryListEntry.java b/beacon/src/main/java/io/xpipe/beacon/exchange/data/EntryListEntry.java deleted file mode 100644 index 0df3fdb71..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/data/EntryListEntry.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.xpipe.beacon.exchange.data; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.time.Instant; - -@Value -@Jacksonized -@Builder -public class EntryListEntry { - String name; - String type; - String description; - Instant lastUsed; -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/data/ProviderEntry.java b/beacon/src/main/java/io/xpipe/beacon/exchange/data/ProviderEntry.java deleted file mode 100644 index 4b67c194a..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/data/ProviderEntry.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.xpipe.beacon.exchange.data; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Jacksonized -@Builder -public class ProviderEntry { - String id; - String description; - boolean hidden; -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/data/ServerErrorMessage.java b/beacon/src/main/java/io/xpipe/beacon/exchange/data/ServerErrorMessage.java deleted file mode 100644 index 5e0e6e20e..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/data/ServerErrorMessage.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.xpipe.beacon.exchange.data; - -import io.xpipe.beacon.ServerException; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -import java.util.UUID; - -@SuppressWarnings("ClassCanBeRecord") -@Value -@Builder -@Jacksonized -@AllArgsConstructor -public class ServerErrorMessage { - - UUID requestId; - Throwable error; - - public void throwError() throws ServerException { - throw new ServerException(error.getMessage(), error); - } -} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/data/StoreListEntry.java b/beacon/src/main/java/io/xpipe/beacon/exchange/data/StoreListEntry.java deleted file mode 100644 index 1853245ed..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/data/StoreListEntry.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.xpipe.beacon.exchange.data; - -import io.xpipe.core.store.DataStoreId; - -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Jacksonized -@Builder -public class StoreListEntry { - - DataStoreId id; - String type; - String information; -} diff --git a/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonController.java b/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonController.java index a5569604f..1617d34cb 100644 --- a/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonController.java +++ b/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonController.java @@ -1,6 +1,8 @@ package io.xpipe.beacon.test; import io.xpipe.beacon.BeaconClient; +import io.xpipe.beacon.BeaconClientInformation; +import io.xpipe.beacon.BeaconConfig; import io.xpipe.beacon.BeaconServer; import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeInstallation; @@ -12,7 +14,7 @@ public class BeaconDaemonController { private static boolean alreadyStarted; public static void start(XPipeDaemonMode mode) throws Exception { - if (BeaconServer.isReachable()) { + if (BeaconServer.isReachable(BeaconConfig.getUsedPort())) { alreadyStarted = true; return; } @@ -27,7 +29,7 @@ public class BeaconDaemonController { } waitForStartup(process, custom); - if (!BeaconServer.isReachable()) { + if (!BeaconServer.isReachable(BeaconConfig.getUsedPort())) { throw new AssertionError(); } } @@ -37,13 +39,12 @@ public class BeaconDaemonController { return; } - if (!BeaconServer.isReachable()) { + if (!BeaconServer.isReachable(BeaconConfig.getUsedPort())) { return; } - var client = BeaconClient.establishConnection(BeaconClient.ApiClientInformation.builder() - .version("?") - .language("Java API Test") + var client = BeaconClient.establishConnection(BeaconConfig.getUsedPort(), BeaconClientInformation.Api.builder() + .name("Beacon daemon controller") .build()); if (!BeaconServer.tryStop(client)) { throw new AssertionError(); @@ -67,9 +68,8 @@ public class BeaconDaemonController { } catch (InterruptedException ignored) { } - var s = BeaconClient.tryEstablishConnection(BeaconClient.ApiClientInformation.builder() - .version("?") - .language("Java") + var s = BeaconClient.tryEstablishConnection(BeaconConfig.getUsedPort(), BeaconClientInformation.Api.builder() + .name("Beacon daemon controller") .build()); if (s.isPresent()) { return; @@ -86,7 +86,7 @@ public class BeaconDaemonController { } catch (InterruptedException ignored) { } - var r = BeaconServer.isReachable(); + var r = BeaconServer.isReachable(BeaconConfig.getUsedPort()); if (!r) { return; } diff --git a/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonExtensionTest.java b/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonExtensionTest.java index 9e1e1cdba..a66c469c6 100644 --- a/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonExtensionTest.java +++ b/beacon/src/main/java/io/xpipe/beacon/test/BeaconDaemonExtensionTest.java @@ -1,9 +1,8 @@ package io.xpipe.beacon.test; import io.xpipe.core.process.OsType; -import io.xpipe.core.util.JacksonMapper; +import io.xpipe.core.util.ModuleLayerLoader; import io.xpipe.core.util.XPipeDaemonMode; - import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -11,7 +10,7 @@ public class BeaconDaemonExtensionTest { @BeforeAll public static void setup() throws Exception { - JacksonMapper.initModularized(ModuleLayer.boot()); + ModuleLayerLoader.loadAll(ModuleLayer.boot(),throwable -> throwable.printStackTrace()); BeaconDaemonController.start( OsType.getLocal().equals(OsType.WINDOWS) ? XPipeDaemonMode.TRAY : XPipeDaemonMode.BACKGROUND); } diff --git a/beacon/src/main/java/io/xpipe/beacon/util/QuietDialogHandler.java b/beacon/src/main/java/io/xpipe/beacon/util/QuietDialogHandler.java deleted file mode 100644 index d77b07205..000000000 --- a/beacon/src/main/java/io/xpipe/beacon/util/QuietDialogHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -package io.xpipe.beacon.util; - -import io.xpipe.beacon.BeaconConnection; -import io.xpipe.beacon.BeaconException; -import io.xpipe.beacon.exchange.cli.DialogExchange; -import io.xpipe.core.dialog.BaseQueryElement; -import io.xpipe.core.dialog.ChoiceElement; -import io.xpipe.core.dialog.DialogElement; -import io.xpipe.core.dialog.DialogReference; - -import java.util.Map; -import java.util.UUID; - -public class QuietDialogHandler { - - private final UUID dialogKey; - private final BeaconConnection connection; - private final Map overrides; - private DialogElement element; - - public QuietDialogHandler(DialogReference ref, BeaconConnection connection, Map overrides) { - this.dialogKey = ref.getDialogId(); - this.element = ref.getStart(); - this.connection = connection; - this.overrides = overrides; - } - - public static void handle(DialogReference ref, BeaconConnection connection) { - new QuietDialogHandler(ref, connection, Map.of()).handle(); - } - - public void handle() { - String response = null; - - if (element instanceof ChoiceElement c) { - response = handleChoice(c); - } - - if (element instanceof BaseQueryElement q) { - response = handleQuery(q); - } - - DialogExchange.Response res = connection.performSimpleExchange(DialogExchange.Request.builder() - .dialogKey(dialogKey) - .value(response) - .build()); - if (res.getElement() != null && element.equals(res.getElement())) { - throw new BeaconException( - "Invalid value for key " + res.getElement().toDisplayString()); - } - - element = res.getElement(); - - if (element != null) { - handle(); - } - } - - private String handleQuery(BaseQueryElement q) { - if (q.isRequired() && !overrides.containsKey(q.getDescription())) { - throw new IllegalStateException("Missing required config parameter: " + q.getDescription()); - } - - return overrides.get(q.getDescription()); - } - - private String handleChoice(ChoiceElement c) { - if (c.isRequired() && !overrides.containsKey(c.getDescription())) { - throw new IllegalStateException("Missing required config parameter: " + c.getDescription()); - } - - return overrides.get(c.getDescription()); - } -} diff --git a/beacon/src/main/java/module-info.java b/beacon/src/main/java/module-info.java index 64ed19851..be21119d8 100644 --- a/beacon/src/main/java/module-info.java +++ b/beacon/src/main/java/module-info.java @@ -1,49 +1,32 @@ -import io.xpipe.beacon.BeaconJacksonModule; -import io.xpipe.beacon.exchange.*; -import io.xpipe.beacon.exchange.cli.*; -import io.xpipe.core.util.ProxyFunction; - import com.fasterxml.jackson.databind.Module; +import io.xpipe.beacon.BeaconInterface; +import io.xpipe.beacon.BeaconJacksonModule; +import io.xpipe.beacon.api.*; +import io.xpipe.core.util.ModuleLayerLoader; open module io.xpipe.beacon { exports io.xpipe.beacon; - exports io.xpipe.beacon.exchange; - exports io.xpipe.beacon.exchange.data; - exports io.xpipe.beacon.exchange.cli; - exports io.xpipe.beacon.util; exports io.xpipe.beacon.test; + exports io.xpipe.beacon.api; - requires static com.fasterxml.jackson.core; - requires static com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.core; + requires com.fasterxml.jackson.annotation; + requires com.fasterxml.jackson.databind; requires transitive io.xpipe.core; requires static lombok; requires static org.junit.jupiter.api; + requires jdk.httpserver; + requires java.net.http; + requires java.desktop; - uses MessageExchange; - uses ProxyFunction; + uses io.xpipe.beacon.BeaconInterface; + provides ModuleLayerLoader with + BeaconInterface.Loader; provides Module with BeaconJacksonModule; - provides io.xpipe.beacon.exchange.MessageExchange with - SinkExchange, - DrainExchange, - LaunchExchange, - EditStoreExchange, - StoreProviderListExchange, - ModeExchange, - QueryStoreExchange, - StatusExchange, - FocusExchange, - OpenExchange, - StopExchange, - RenameStoreExchange, - RemoveStoreExchange, - StoreAddExchange, - ReadDrainExchange, + provides BeaconInterface with ShellStartExchange, ShellStopExchange, ShellExecExchange, DaemonModeExchange, DaemonStatusExchange, DaemonFocusExchange, DaemonOpenExchange, DaemonStopExchange, HandshakeExchange, ConnectionQueryExchange, AskpassExchange, TerminalWaitExchange, - TerminalLaunchExchange, - ListStoresExchange, - DialogExchange, - VersionExchange; + TerminalLaunchExchange, DaemonVersionExchange; } diff --git a/beacon/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader b/beacon/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader new file mode 100644 index 000000000..c70568c84 --- /dev/null +++ b/beacon/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader @@ -0,0 +1 @@ +io.xpipe.beacon.BeaconInterface$Loader \ No newline at end of file diff --git a/build.gradle b/build.gradle index f94acf1c8..2e2690578 100644 --- a/build.gradle +++ b/build.gradle @@ -88,8 +88,7 @@ project.ext { arch = getArchName() privateExtensions = file("$rootDir/private_extensions.txt").exists() ? file("$rootDir/private_extensions.txt").readLines() : [] isFullRelease = System.getenv('RELEASE') != null && Boolean.parseBoolean(System.getenv('RELEASE')) - isPreRelease = System.getenv('PRERELEASE') != null && Boolean.parseBoolean(System.getenv('PRERELEASE')) - isStage = System.getenv('STAGE') != null && Boolean.parseBoolean(System.getenv('STAGE')) + isStage = true rawVersion = file('version').text.trim() versionString = rawVersion + (isFullRelease || isStage ? '' : '-SNAPSHOT') versionReleaseNumber = rawVersion.split('-').length == 2 ? Integer.parseInt(rawVersion.split('-')[1]) : 1 @@ -106,7 +105,7 @@ project.ext { website = 'https://xpipe.io' sourceWebsite = isStage ? 'https://github.com/xpipe-io/xpipe-ptb' : 'https://github.com/xpipe-io/xpipe' authors = 'Christopher Schnick' - javafxVersion = '22.0.1' + javafxVersion = '23-ea+18' platformName = getPlatformName() languages = ["en", "nl", "es", "fr", "de", "it", "pt", "ru", "ja", "zh", "tr", "da"] jvmRunArgs = [ @@ -159,6 +158,11 @@ if (isFullRelease && rawVersion.contains("-")) { throw new IllegalArgumentException("Releases must have canonical versions") } + +if (isStage && !rawVersion.contains("-")) { + throw new IllegalArgumentException("Stage releases must have release numbers") +} + def replaceVariablesInFileAsString(String f, Map replacements) { def fileName = file(f).getName() def text = file(f).text diff --git a/core/build.gradle b/core/build.gradle index db7993e74..df8952576 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -14,9 +14,7 @@ compileJava { dependencies { api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.17.1" - implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: "2.17.1" implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: "2.17.1" - implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: "2.17.1" } version = rootProject.versionString diff --git a/core/src/main/java/io/xpipe/core/process/CommandFeedbackPredicate.java b/core/src/main/java/io/xpipe/core/process/CommandFeedbackPredicate.java new file mode 100644 index 000000000..10a800059 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/process/CommandFeedbackPredicate.java @@ -0,0 +1,6 @@ +package io.xpipe.core.process; + +public interface CommandFeedbackPredicate { + + boolean test(CommandBuilder command) throws Exception; +} diff --git a/core/src/main/java/io/xpipe/core/process/OsType.java b/core/src/main/java/io/xpipe/core/process/OsType.java index 30765336d..3e2e81dcb 100644 --- a/core/src/main/java/io/xpipe/core/process/OsType.java +++ b/core/src/main/java/io/xpipe/core/process/OsType.java @@ -89,7 +89,17 @@ public interface OsType { @Override public String getTempDirectory(ShellControl pc) throws Exception { - return pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("TEMP")); + var def = pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("TEMP")); + if (!def.isBlank() && pc.getShellDialect().directoryExists(pc, def).executeAndCheck()) { + return def; + } + + var fallback = pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("LOCALAPPDATA")); + if (!fallback.isBlank() && pc.getShellDialect().directoryExists(pc, fallback).executeAndCheck()) { + return fallback; + } + + return def; } @Override @@ -116,7 +126,7 @@ public interface OsType { .trim(); } catch (Throwable t) { // Just in case this fails somehow - return "Windows ?"; + return "Windows"; } } } diff --git a/core/src/main/java/io/xpipe/core/process/ShellDialects.java b/core/src/main/java/io/xpipe/core/process/ShellDialects.java index c17fb2b8b..3110814bb 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellDialects.java +++ b/core/src/main/java/io/xpipe/core/process/ShellDialects.java @@ -58,10 +58,15 @@ public class ShellDialects { @Override public void init(ModuleLayer layer) { - ServiceLoader.load(layer, ShellDialect.class).stream().forEach(moduleLayerLoaderProvider -> { + var services = layer != null ? ServiceLoader.load(layer, ShellDialect.class) : ServiceLoader.load(ShellDialect.class); + services.stream().forEach(moduleLayerLoaderProvider -> { ALL.add(moduleLayerLoaderProvider.get()); }); + if (ALL.isEmpty()) { + return; + } + CMD = byId("cmd"); POWERSHELL = byId("powershell"); POWERSHELL_CORE = byId("pwsh"); diff --git a/core/src/main/java/io/xpipe/core/store/DataStoreId.java b/core/src/main/java/io/xpipe/core/store/DataStoreId.java index 6a60bd94a..4c24f0b6a 100644 --- a/core/src/main/java/io/xpipe/core/store/DataStoreId.java +++ b/core/src/main/java/io/xpipe/core/store/DataStoreId.java @@ -1,6 +1,5 @@ package io.xpipe.core.store; -import com.fasterxml.jackson.annotation.JsonCreator; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -28,7 +27,6 @@ public class DataStoreId { private final List names; - @JsonCreator public DataStoreId(List names) { this.names = names; } diff --git a/core/src/main/java/io/xpipe/core/store/EnabledStoreState.java b/core/src/main/java/io/xpipe/core/store/EnabledStoreState.java new file mode 100644 index 000000000..e7e08f72f --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/EnabledStoreState.java @@ -0,0 +1,24 @@ +package io.xpipe.core.store; + +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.FieldDefaults; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@Getter +@EqualsAndHashCode(callSuper=true) +@SuperBuilder(toBuilder = true) +@Jacksonized +public class EnabledStoreState extends DataStoreState { + + boolean enabled; + + @Override + public DataStoreState mergeCopy(DataStoreState newer) { + var n = (EnabledStoreState) newer; + return EnabledStoreState.builder().enabled(n.enabled).build(); + } +} diff --git a/core/src/main/java/io/xpipe/core/store/FilePath.java b/core/src/main/java/io/xpipe/core/store/FilePath.java index 74b355848..7e0b02318 100644 --- a/core/src/main/java/io/xpipe/core/store/FilePath.java +++ b/core/src/main/java/io/xpipe/core/store/FilePath.java @@ -42,7 +42,6 @@ public final class FilePath { return this; } - var backslash = value.contains("\\"); var p = Pattern.compile("[^/\\\\]+"); var m = p.matcher(value); var replaced = m.replaceAll(matchResult -> osType.makeFileSystemCompatible(matchResult.group())); diff --git a/core/src/main/java/io/xpipe/core/store/LocalStore.java b/core/src/main/java/io/xpipe/core/store/LocalStore.java index f9656abb6..b76fbc1f5 100644 --- a/core/src/main/java/io/xpipe/core/store/LocalStore.java +++ b/core/src/main/java/io/xpipe/core/store/LocalStore.java @@ -8,7 +8,7 @@ import io.xpipe.core.util.JacksonizedValue; import com.fasterxml.jackson.annotation.JsonTypeName; @JsonTypeName("local") -public class LocalStore extends JacksonizedValue implements ShellStore, StatefulDataStore { +public class LocalStore extends JacksonizedValue implements NetworkTunnelStore, ShellStore, StatefulDataStore { @Override public Class getStateClass() { @@ -23,4 +23,9 @@ public class LocalStore extends JacksonizedValue implements ShellStore, Stateful pc.withShellStateFail(this); return pc; } + + @Override + public DataStore getNetworkParent() { + return null; + } } diff --git a/core/src/main/java/io/xpipe/core/store/NetworkTunnelSession.java b/core/src/main/java/io/xpipe/core/store/NetworkTunnelSession.java new file mode 100644 index 000000000..d0bdd46b0 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/NetworkTunnelSession.java @@ -0,0 +1,16 @@ +package io.xpipe.core.store; + +import io.xpipe.core.process.ShellControl; + +public abstract class NetworkTunnelSession extends Session { + + protected NetworkTunnelSession(SessionListener listener) { + super(listener); + } + + public abstract int getLocalPort(); + + public abstract int getRemotePort(); + + public abstract ShellControl getShellControl(); +} diff --git a/core/src/main/java/io/xpipe/core/store/NetworkTunnelStore.java b/core/src/main/java/io/xpipe/core/store/NetworkTunnelStore.java new file mode 100644 index 000000000..92277c151 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/NetworkTunnelStore.java @@ -0,0 +1,149 @@ +package io.xpipe.core.store; + +import io.xpipe.core.process.ShellControl; + +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +public interface NetworkTunnelStore extends DataStore { + + static AtomicInteger portCounter = new AtomicInteger(); + + public static int randomPort() { + var p = 40000 + portCounter.get(); + portCounter.set(portCounter.get() + 1 % 1000); + return p; + } + + interface TunnelFunction { + + NetworkTunnelSession create(int localPort, int remotePort); + } + + DataStore getNetworkParent(); + + default boolean requiresTunnel() { + NetworkTunnelStore current = this; + while (true) { + var func = current.tunnelSession(); + if (func != null) { + return true; + } + + if (current.getNetworkParent() == null) { + return false; + } + + if (current.getNetworkParent() instanceof NetworkTunnelStore t) { + current = t; + } else { + return false; + } + } + } + + default boolean isLocallyTunneable() { + NetworkTunnelStore current = this; + while (true) { + if (current.getNetworkParent() == null) { + return true; + } + + if (current.getNetworkParent() instanceof NetworkTunnelStore t) { + current = t; + } else { + return false; + } + } + } + + default NetworkTunnelSession sessionChain(int local, int remotePort) throws Exception { + if (!isLocallyTunneable()) { + throw new IllegalStateException(); + } + + var running = new AtomicBoolean(); + var runningCounter = new AtomicInteger(); + var counter = new AtomicInteger(); + var sessions = new ArrayList(); + NetworkTunnelStore current = this; + do { + var func = current.tunnelSession(); + if (func == null) { + continue; + } + + var currentLocalPort = isLast(current) ? local : randomPort(); + var currentRemotePort = sessions.isEmpty() ? remotePort : sessions.getLast().getLocalPort(); + var t = func.create(currentLocalPort, currentRemotePort); + t.addListener(r -> { + if (r) { + runningCounter.incrementAndGet(); + } else { + runningCounter.decrementAndGet(); + } + running.set(runningCounter.get() == counter.get()); + }); + t.start(); + sessions.add(t); + counter.incrementAndGet(); + } while ((current = (NetworkTunnelStore) current.getNetworkParent()) != null); + + if (sessions.size() == 1) { + return sessions.getFirst(); + } + + if (sessions.isEmpty()) { + return new NetworkTunnelSession(null) { + + @Override + public boolean isRunning() { + return false; + } + + @Override + public void start() throws Exception { + + } + + @Override + public void stop() throws Exception { + + } + + @Override + public int getLocalPort() { + return remotePort; + } + + @Override + public int getRemotePort() { + return remotePort; + } + + @Override + public ShellControl getShellControl() { + return null; + } + }; + } + + return new SessionChain(running1 -> {}, sessions); + } + + default boolean isLast(NetworkTunnelStore tunnelStore) { + NetworkTunnelStore current = tunnelStore; + while ((current = (NetworkTunnelStore) current.getNetworkParent()) != null) { + var func = current.tunnelSession(); + if (func != null) { + return false; + } + } + return true; + } + + default TunnelFunction tunnelSession() { + return null; + } +} diff --git a/core/src/main/java/io/xpipe/core/store/ServiceStore.java b/core/src/main/java/io/xpipe/core/store/ServiceStore.java new file mode 100644 index 000000000..2763b5b35 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/ServiceStore.java @@ -0,0 +1,23 @@ +package io.xpipe.core.store; + +import java.util.OptionalInt; + +public interface ServiceStore extends SingletonSessionStore { + + NetworkTunnelStore getParent(); + + int getPort(); + + OptionalInt getTargetPort(); + + @Override + default SessionChain newSession() throws Exception { + var s = getParent().tunnelSession(); + return null; + } + + @Override + default Class getSessionClass() { + return null; + } +} diff --git a/core/src/main/java/io/xpipe/core/store/Session.java b/core/src/main/java/io/xpipe/core/store/Session.java index 5607fadee..8e02e38c1 100644 --- a/core/src/main/java/io/xpipe/core/store/Session.java +++ b/core/src/main/java/io/xpipe/core/store/Session.java @@ -1,10 +1,29 @@ package io.xpipe.core.store; -public abstract class Session { +public abstract class Session implements AutoCloseable { + + protected SessionListener listener; + + protected Session(SessionListener listener) { + this.listener = listener; + } + + public void addListener(SessionListener n) { + var current = this.listener; + this.listener = running -> { + current.onStateChange(running); + n.onStateChange(running); + }; + } public abstract boolean isRunning(); public abstract void start() throws Exception; public abstract void stop() throws Exception; + + @Override + public void close() throws Exception { + stop(); + } } diff --git a/core/src/main/java/io/xpipe/core/store/SessionChain.java b/core/src/main/java/io/xpipe/core/store/SessionChain.java new file mode 100644 index 000000000..987345804 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/SessionChain.java @@ -0,0 +1,51 @@ +package io.xpipe.core.store; + +import io.xpipe.core.process.ShellControl; + +import java.util.List; + +public class SessionChain extends NetworkTunnelSession { + + private final List sessions; + private int runningCounter; + + public SessionChain(SessionListener listener, List sessions) { + super(listener); + this.sessions = sessions; + sessions.forEach(session -> session.addListener(running -> { + runningCounter += running ? 1 : -1; + })); + } + + public ShellControl getShellControl() { + return sessions.getLast().getShellControl(); + } + + public int getLocalPort() { + return sessions.getFirst().getLocalPort(); + } + + @Override + public int getRemotePort() { + return sessions.getLast().getRemotePort(); + } + + @Override + public boolean isRunning() { + return sessions.stream().allMatch(session -> session.isRunning()); + } + + @Override + public void start() throws Exception { + for (Session session : sessions) { + session.start(); + } + } + + @Override + public void stop() throws Exception { + for (Session session : sessions) { + session.stop(); + } + } +} diff --git a/core/src/main/java/io/xpipe/core/store/SessionListener.java b/core/src/main/java/io/xpipe/core/store/SessionListener.java new file mode 100644 index 000000000..45e241e1a --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/SessionListener.java @@ -0,0 +1,6 @@ +package io.xpipe.core.store; + +public interface SessionListener { + + void onStateChange(boolean running); +} diff --git a/core/src/main/java/io/xpipe/core/store/SingletonSessionStore.java b/core/src/main/java/io/xpipe/core/store/SingletonSessionStore.java index 3e6a9d061..a2ac66b4a 100644 --- a/core/src/main/java/io/xpipe/core/store/SingletonSessionStore.java +++ b/core/src/main/java/io/xpipe/core/store/SingletonSessionStore.java @@ -1,6 +1,7 @@ package io.xpipe.core.store; -public interface SingletonSessionStore extends ExpandedLifecycleStore, InternalCacheDataStore { +public interface SingletonSessionStore + extends ExpandedLifecycleStore, InternalCacheDataStore, SessionListener { @Override default void finalizeValidate() throws Exception { @@ -19,9 +20,10 @@ public interface SingletonSessionStore extends ExpandedLifecy return getCache("sessionEnabled", Boolean.class, false); } - default void onSessionUpdate(boolean active) { - setSessionEnabled(active); - setCache("sessionRunning", active); + @Override + default void onStateChange(boolean running) { + setSessionEnabled(running); + setCache("sessionRunning", running); } T newSession() throws Exception; @@ -50,9 +52,9 @@ public interface SingletonSessionStore extends ExpandedLifecy s = newSession(); s.start(); setCache("session", s); - onSessionUpdate(true); + onStateChange(true); } catch (Exception ex) { - onSessionUpdate(false); + onStateChange(false); throw ex; } } @@ -65,7 +67,7 @@ public interface SingletonSessionStore extends ExpandedLifecy if (ex != null) { ex.stop(); setCache("session", null); - onSessionUpdate(false); + onStateChange(false); } } } diff --git a/core/src/main/java/io/xpipe/core/store/StorePath.java b/core/src/main/java/io/xpipe/core/store/StorePath.java new file mode 100644 index 000000000..4d3b47ba1 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/StorePath.java @@ -0,0 +1,84 @@ +package io.xpipe.core.store; + +import com.fasterxml.jackson.annotation.JsonCreator; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Represents a reference to an XPipe storage location. + *

+ * To allow for a simple usage, the names are trimmed and + * converted to lower case names when creating them. + * The names are separated by a slash and are therefore not allowed to contain slashes themselves. + * + * @see #fromString(String) + */ +@EqualsAndHashCode +@Getter +public class StorePath { + + public static final char SEPARATOR = '/'; + + private final List names; + + @JsonCreator + public StorePath(List names) { + this.names = names; + } + + /** + * Creates a new store path. + * + * @throws IllegalArgumentException if any name is not valid + */ + public static StorePath create(String... names) { + if (names == null) { + throw new IllegalArgumentException("Names are null"); + } + + if (Arrays.stream(names).anyMatch(s -> s == null)) { + throw new IllegalArgumentException("Name is null"); + } + + if (Arrays.stream(names).anyMatch(s -> s.contains("" + SEPARATOR))) { + throw new IllegalArgumentException("Separator character " + SEPARATOR + " is not allowed in the names"); + } + + if (Arrays.stream(names).anyMatch(s -> s.trim().length() == 0)) { + throw new IllegalArgumentException("Trimmed entry name is empty"); + } + + return new StorePath(Arrays.stream(names).toList()); + } + + /** + * Creates a new store path from a string representation. + * + * @param s the string representation, must be not null and fulfill certain requirements + * @throws IllegalArgumentException if the string is not valid + */ + public static StorePath fromString(String s) { + if (s == null) { + throw new IllegalArgumentException("String is null"); + } + + var split = s.split(String.valueOf(SEPARATOR), -1); + + var names = + Arrays.stream(split).map(String::trim).map(String::toLowerCase).toList(); + if (names.stream().anyMatch(s1 -> s1.isEmpty())) { + throw new IllegalArgumentException("Name must not be empty"); + } + + return new StorePath(names); + } + + @Override + public String toString() { + return names.stream().map(String::toLowerCase).collect(Collectors.joining("" + SEPARATOR)); + } +} diff --git a/core/src/main/java/io/xpipe/core/util/JacksonMapper.java b/core/src/main/java/io/xpipe/core/util/JacksonMapper.java index 8699ffbd7..0b3dd93c6 100644 --- a/core/src/main/java/io/xpipe/core/util/JacksonMapper.java +++ b/core/src/main/java/io/xpipe/core/util/JacksonMapper.java @@ -49,14 +49,14 @@ public class JacksonMapper { mapper.accept(INSTANCE); } - public static synchronized void initClassBased() { - initModularized(null); - } + public static class Loader implements ModuleLayerLoader { - public static synchronized void initModularized(ModuleLayer layer) { - List MODULES = findModules(layer); - INSTANCE.registerModules(MODULES); - init = true; + @Override + public void init(ModuleLayer layer) { + List MODULES = findModules(layer); + INSTANCE.registerModules(MODULES); + init = true; + } } private static List findModules(ModuleLayer layer) { diff --git a/core/src/main/java/io/xpipe/core/util/ModuleLayerLoader.java b/core/src/main/java/io/xpipe/core/util/ModuleLayerLoader.java index 216c97ec1..e78dcab28 100644 --- a/core/src/main/java/io/xpipe/core/util/ModuleLayerLoader.java +++ b/core/src/main/java/io/xpipe/core/util/ModuleLayerLoader.java @@ -6,7 +6,8 @@ import java.util.function.Consumer; public interface ModuleLayerLoader { static void loadAll(ModuleLayer layer, Consumer errorHandler) { - ServiceLoader.load(layer, ModuleLayerLoader.class).stream().forEach(moduleLayerLoaderProvider -> { + var loaded = layer != null ? ServiceLoader.load(layer, ModuleLayerLoader.class) : ServiceLoader.load(ModuleLayerLoader.class); + loaded.stream().forEach(moduleLayerLoaderProvider -> { var instance = moduleLayerLoaderProvider.get(); try { instance.init(layer); diff --git a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java index 4f89bb1af..074e85a88 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java @@ -22,18 +22,18 @@ public class XPipeInstallation { .orElse(false); public static int getDefaultBeaconPort() { - var offset = isStaging() ? 1 : 0; - if (OsType.getLocal().equals(OsType.WINDOWS)) { - return 21721 + offset; - } else { - return 21721 + 2 + offset; - } + var offset = isStaging() ? 2 : 0; + return 21721 + offset; } private static String getPkgId() { return isStaging() ? "io.xpipe.xpipe-ptb" : "io.xpipe.xpipe"; } + public static Path getLocalBeaconAuthFile() { + return Path.of(System.getProperty("java.io.tmpdir"), "xpipe_auth"); + } + public static String createExternalAsyncLaunchCommand( String installationBase, XPipeDaemonMode mode, String arguments, boolean restart) { var suffix = (arguments != null ? " " + arguments : ""); diff --git a/core/src/main/java/module-info.java b/core/src/main/java/module-info.java index 287db7ad3..0bb231b22 100644 --- a/core/src/main/java/module-info.java +++ b/core/src/main/java/module-info.java @@ -2,6 +2,7 @@ import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.process.ShellDialect; import io.xpipe.core.process.ShellDialects; import io.xpipe.core.util.CoreJacksonModule; +import io.xpipe.core.util.JacksonMapper; import io.xpipe.core.util.ModuleLayerLoader; open module io.xpipe.core { @@ -11,9 +12,9 @@ open module io.xpipe.core { exports io.xpipe.core.process; requires com.fasterxml.jackson.datatype.jsr310; - requires com.fasterxml.jackson.module.paramnames; - requires static com.fasterxml.jackson.core; - requires static com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.core; + requires com.fasterxml.jackson.annotation; + requires com.fasterxml.jackson.databind; requires java.net.http; requires static lombok; @@ -24,7 +25,7 @@ open module io.xpipe.core { uses ModuleLayerLoader; uses ShellDialect; - provides ModuleLayerLoader with + provides ModuleLayerLoader with JacksonMapper.Loader, ShellDialects.Loader; provides com.fasterxml.jackson.databind.Module with CoreJacksonModule; diff --git a/core/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader b/core/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader new file mode 100644 index 000000000..c61f23fd2 --- /dev/null +++ b/core/src/main/resources/META-INF/services/io.xpipe.core.util.ModuleLayerLoader @@ -0,0 +1,2 @@ +io.xpipe.core.util.JacksonMapper$Loader +io.xpipe.core.process.ShellDialects$Loader \ No newline at end of file diff --git a/dist/build.gradle b/dist/build.gradle index 25e480bdb..7f5f09b9d 100644 --- a/dist/build.gradle +++ b/dist/build.gradle @@ -2,8 +2,8 @@ plugins { id 'org.beryx.jlink' version '3.0.1' id "org.asciidoctor.jvm.convert" version "4.0.2" - id 'org.jreleaser' version '1.11.0' - id("com.netflix.nebula.ospackage") version "11.8.1" + id 'org.jreleaser' version '1.12.0' + id("com.netflix.nebula.ospackage") version "11.9.1" id 'org.gradle.crypto.checksum' version '1.4.0' id 'signing' } diff --git a/dist/changelogs/10.0.md b/dist/changelogs/10.0.md new file mode 100644 index 000000000..711fda1b4 --- /dev/null +++ b/dist/changelogs/10.0.md @@ -0,0 +1,72 @@ +## A new HTTP API + +There is now a new HTTP API for the XPipe daemon, which allows you to programmatically manage remote systems. +You can find details and an OpenAPI spec at the new API button in the sidebar. +The API page contains everything you need to get started, including code samples for various different programming languages. + +To start off, you can query connections based on various filters. +With the matched connections, you can start remote shell sessions for each one and run arbitrary commands in them. +You get the command exit code and output as a response, allowing you to adapt your control flow based on command outputs. +Any kind of passwords and other secrets are automatically provided by XPipe when establishing a shell connection. + +There will be more functionality added to the API in the future, for now this initial implementation is open for feedback. + +## Service integration + +Many systems run a variety of different services such as web services and others. +There is now support to detect, forward, and open the services. +For example, if you are running a web service on a remote container, you can automatically forward the service port via SSH tunnels, allowing you to access these services from your local machine, e.g. in a web browser. +These service tunnels can be toggled at any time. +The port forwarding supports specifying a custom local target port and also works for connections with multiple intermediate systems through chained tunnels. +For containers, services are automatically detected via their exposed mapped ports. +For other systems, you can manually add services via their port. + +You can use an unlimited amount of local services and one active tunneled service in the community edition. + +## Script rework + +The scripting system has been reworked. There have been several issues with it being clunky and not fun to use. The new system allows you to assign each script one of multiple execution types. Based on these execution types, you can make scripts active or inactive with a toggle. If they are active, the scripts will apply in the selected use cases. There currently are these types: +- Init scripts: When enabled, they will automatically run on init in all compatible shells. This is useful for setting things like aliases consistently +- Shell scripts: When enabled, they will be copied over to the target system and put into the PATH. You can then call them in a normal shell session by their name, e.g. `myscript.sh`, also with arguments. +- File scripts: When enabled, you can call them in the file browser with the selected files as arguments. Useful to perform common actions with files + +If you have existing scripts, they will have to be manually adjusted by setting their execution types. + +## Proxmox improvements + +You can now automatically open the Proxmox dashboard website through the new service integration. This will also work with the service tunneling feature for remote servers. + +You can now open VNC sessions to Proxmox VMs. + +The Proxmox professional license requirement has been reworked to support one non-enterprise PVE node in the community edition. + +## Docker improvements + +The docker integration has been updated to support docker contexts. You can use the default context in the community edition, essentially being the same as before as XPipe previously only used the default context. Support for using multiple contexts is included in the professional edition. + +Note that old docker container connections will be removed as they are incompatible with the new version. Any other subconnections like shell environments in docker containers will persist, although they might get invalidated and will show up on the bottom of the connection list. + +There's now support for Windows docker containers running on HyperV. + +## Better connection organization + +The toggle to show only running connections will now no longer actually remove the connections internally and instead just not display them. +This will reduce git vault updates and is faster in general. + +You can now order connections relative to other sibling connections. This ordering will also persist when changing the global order in the top left. + +The UI has also been streamlined to make common actions and toggles more easily accessible. + +## Other + +- Several more actions have been added for podman containers +- Support VMs for tunneling +- Searching for connections has been improved to show children as well +- The welcome screen will now also contain the option to straight up jump to the synchronization settings +- Add support for foot terminal +- Fix elementary terminal not launching correctly +- Fix kubernetes not elevating correctly for non-default contexts +- Fix ohmyzsh update notification freezing shell +- Fix file browser icons being broken for links +- The Linux installers now contain application icons from multiple sizes which should increase the icon display quality +- The Linux builds now list socat as a dependency such that the kitty terminal integration will work without issues diff --git a/dist/changelogs/9.4.1.md b/dist/changelogs/9.4.1.md new file mode 100644 index 000000000..de6f3a757 --- /dev/null +++ b/dist/changelogs/9.4.1.md @@ -0,0 +1,59 @@ +## Coherent desktops + +XPipe now comes with support for remote desktop connections. VNC connections are fully handled over SSH and can therefore be established on top of any existing SSH connection you have in XPipe. RDP support is realized similar to the terminal support, i.e. by launching your preferred RDP client with the connection information. X11-forwarding for SSH is also now supported. + +With support for remote graphical desktop connection methods as well now in XPipe 9, the big picture idea is to implement the concept of coherent desktops. Essentially, you can launch predefined desktop applications, terminals, and scripts on any remote desktop connection, regardless of the underlying connection implementation. In combination with the improved SSH tunnel and background session support, you can launch graphical remote applications with one click in the same unified way for VNC over SSH connections, RDP connections, and X11-forwarded SSH connections. + +The general implementation and concept will be refined over the next updates. + +## SSH connection improvements + +- Tunneled and X11-forwarded custom SSH connections are now properly detected and can be toggled on and off to run in the background as normal tunnels. This applies to normal connections and also SSH configs + +- The connection establishment has been reworked to reduce the amount of double prompts, e.g. for smartcards or 2FA, where user input is required twice. + +- The custom SSH connections now properly apply all configuration options of your user configuration file. They also now correctly apply multiple options for the same key correctly. + +- Any value specified for the `RemoteCommand` config option will now be properly applied when launching a terminal. This allows you to still use your preexisting init command setup, e.g. with tmux. + +- There is now support defining multiple host entries in place in a custom SSH connection. This is useful for cases where you want to use ProxyJump hosts in place without having to define them elsewhere. + +- A host key acceptance notification is now displayed properly in case your system doesn't automatically accept new host keys + +## SSH for unknown shells (Professional feature) + +There's now an option to not let XPipe interact with the system. In case a system that does not run a known command shell, e.g. a router, link, or some IOT device, XPipe was previously unable to detect the shell type and errored out after some time. This option fixes this problem. This feature is available in the professional edition preview for two weeks. + +## SSH X11 Forwarding on Windows via WSL + +You can now enable X11 forwarding for an SSH connection. + +XPipe allows you to use the WSL2 X11 capabilities on Windows for your SSH connection. The only thing you need for this is a [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) distribution installed on your local system. XPipe it will automatically choose a compatible installed distribution if possible, but you can also use another one in the settings menu. + +This means that you don't need to install a separate X11 server on Windows. However, if you are using one anyway, XPipe will detect that and use the currently running X11 server. + +## Translations + +XPipe 9 now comes with translations for the user interface. These were initially generated with DeepL and can be easily improved and corrected by anyone on GitHub. You can check them out in action and if there is any translation you don't like, submit a quick pull request to fix it. For instructions on how to do this, see https://github.com/xpipe-io/xpipe/tree/master/lang. + +## Terminal improvements + +The terminal integrations have been reworked across the board. To better show which terminals are well supported and which aren't, there is now a status indicator for every available terminal. This will show you how good the XPipe integration with each one is and which terminals are recommended to be used with XPipe. + +The kitty terminal is now fully supported with tabs on both Linux and macOS. The Warp terminal integration now correctly enables all Warp features on remote shells. On macOS, other third-party prompts also now work properly in the launched terminals. + +## Password manager improvements + +The password manager handling has been improved and some potential sources of errors and confusion have been eliminated. There are also now a few command templates available for established password managers to quickly get started. + +## Improved keyboard control + +It is a goal to be able to use XPipe only with a keyboard either for productivity or for accessibility reasons. XPipe 9 introduces improved keyboard support with new shortcuts and improved focus control for navigating with the arrow keys, tab, space, and enter. + +## Improved logo + +The application logo has been improved with of regards to contrast and visibility, which often was a problem on dark backgrounds. It should now stand out on any background color. + +## Other changes + +There have been countless small bug fixes across the board. They are not listed individually here, but hopefully you will notice some of them. diff --git a/dist/changelogs/9.4.1_incremental.md b/dist/changelogs/9.4.1_incremental.md new file mode 100644 index 000000000..2a5942239 --- /dev/null +++ b/dist/changelogs/9.4.1_incremental.md @@ -0,0 +1,3 @@ +- Make passwords for SSH config connections with set identity file automatically default to none, saving some manual configuration +- Fix terminal installation detection being broken on macOS, always defaulting to kitty.app +- Some small file IO performance improvements diff --git a/dist/changelogs/9.4_incremental.md b/dist/changelogs/9.4_incremental.md index 09f53bde0..cc1a9e9df 100644 --- a/dist/changelogs/9.4_incremental.md +++ b/dist/changelogs/9.4_incremental.md @@ -8,6 +8,8 @@ The file transfer mechanism when editing files had some flaws, which under rare The entire transfer implementation has been rewritten to iron out these issues and increase reliability. Other file browser actions have also been made more reliable. +There seems to be another separate issue with a PowerShell bug when connecting to a Windows system, causing file uploads to be slow. For now, xpipe can fall back to pwsh if it is installed to work around this issue. + ## Git vault improvements The conflict resolution has been improved @@ -15,11 +17,27 @@ The conflict resolution has been improved - In case of a merge conflict, overwriting local changes will now preserve all connections that are not added to the git vault, including local connections - You now have the option to force push changes when a conflict occurs while XPipe is saving while running, not requiring a restart anymore +## Terminal improvements + +The terminal integration got reworked for some terminals: +- iTerm can now launch tabs instead of individual windows. There were also a few issues fixed that prevented it from launching sometimes +- WezTerm now supports tabs on Linux and macOS. The Windows installation detection has been improved to detect all installed versions +- Terminal.app will now launch faster + ## Other - You can now add simple RDP connections without a file - Fix VMware Player/Workstation and MSYS2 not being detected on Windows. Now simply searching for connections should add them automatically if they are installed - The file browser sidebar now only contains connections that can be opened in it, reducing the amount of connection shown +- Clarify error message for RealVNC servers, highlighting that RealVNC uses a proprietary protocol spec that can't be supported by third-party VNC clients like xpipe +- Fix Linux builds containing unnecessary debug symbols +- Fix AUR package also installing a debug package +- Fix application restart not working properly on macOS +- Fix possibility of selecting own children connections as hosts, causing a stack overflow. Please don't try to create cycles in your connection graphs +- Fix vault secrets not correctly updating unless restarted when changing vault passphrase +- Fix connection launcher desktop shortcuts and URLs not properly executing if xpipe is not running +- Fix move to ... menu sometimes not ordering categories correctly - Fix SSH command failing on macOS with homebrew openssh package installed -- Fix SSH connections not opening the correct shell environment on Windows when username contained spaces due to an OpenSSH bug +- Fix SSH connections not opening the correct shell environment on Windows systems when username contained spaces due to an OpenSSH bug - Fix newly added connections not having the correct order +- Fix error messages of external editor programs not being shown when they failed to start diff --git a/dist/jpackage.gradle b/dist/jpackage.gradle index b4dd6a47e..62ae673d3 100644 --- a/dist/jpackage.gradle +++ b/dist/jpackage.gradle @@ -58,7 +58,7 @@ jlink { ] if (org.gradle.internal.os.OperatingSystem.current().isLinux()) { - options += ['--strip-native-debug-symbols'] + options.addAll('--strip-native-debug-symbols', 'exclude-debuginfo-files') } if (useBundledJavaFx) { diff --git a/dist/licenses/prettytime.license b/dist/licenses/prettytime.license deleted file mode 100644 index f433b1a53..000000000 --- a/dist/licenses/prettytime.license +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/dist/licenses/prettytime.properties b/dist/licenses/prettytime.properties deleted file mode 100644 index 0c67b4121..000000000 --- a/dist/licenses/prettytime.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Prettytime -version=5.0.7.Final -license=Apache License 2.0 -link=https://github.com/ocpsoft/prettytime \ No newline at end of file diff --git a/dist/logo/hicolor/1024x1024/apps/xpipe.png b/dist/logo/hicolor/1024x1024/apps/xpipe.png new file mode 100644 index 0000000000000000000000000000000000000000..643d6accebc930cfde7d1b7a2e534e228ab17455 GIT binary patch literal 109894 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 literal 0 HcmV?d00001 diff --git a/dist/logo/hicolor/256x256/apps/xpipe.png b/dist/logo/hicolor/256x256/apps/xpipe.png new file mode 100644 index 0000000000000000000000000000000000000000..c935a75183f735df8d947fdc86047900a3db8ccf GIT binary patch literal 25614 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 literal 0 HcmV?d00001 diff --git a/dist/logo/hicolor/32x32/apps/xpipe.png b/dist/logo/hicolor/32x32/apps/xpipe.png new file mode 100644 index 0000000000000000000000000000000000000000..2040668c79f86f30446b6fd1b744d627977b3c1d GIT binary patch literal 1811 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 literal 0 HcmV?d00001 diff --git a/dist/logo/hicolor/512x512/apps/xpipe.png b/dist/logo/hicolor/512x512/apps/xpipe.png new file mode 100644 index 0000000000000000000000000000000000000000..7afdbf9b6a5743379dedcf58bc36f6a37e7d69b7 GIT binary patch literal 47253 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 literal 0 HcmV?d00001 diff --git a/dist/logo/hicolor/64x64/apps/xpipe.png b/dist/logo/hicolor/64x64/apps/xpipe.png new file mode 100644 index 0000000000000000000000000000000000000000..ce5fa51830c388db592f708bd98b123b840eecbe GIT binary patch literal 4344 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 mv)K_>OKjxeO0000 getDataStoreCallSite() { - return new DataStoreCallSite() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { @Override public boolean isApplicable(DataStoreEntryRef o) { @@ -63,11 +63,6 @@ public class BrowseStoreAction implements ActionProvider { DataStoreEntry entry; - @Override - public boolean requiresJavaFXPlatform() { - return true; - } - @Override public void execute() { BrowserSessionModel.DEFAULT.openFileSystemAsync(entry.ref(), null, new SimpleBooleanProperty()); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/CloneStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/CloneStoreAction.java index 7a30122dc..4795885c6 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/CloneStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/CloneStoreAction.java @@ -14,8 +14,8 @@ import lombok.Value; public class CloneStoreAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite<>() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite<>() { @Override public boolean isSystemAction() { @@ -54,11 +54,6 @@ public class CloneStoreAction implements ActionProvider { DataStoreEntry store; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() { DataStorage.get() diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/DeleteStoreChildrenAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/DeleteChildrenStoreAction.java similarity index 86% rename from ext/base/src/main/java/io/xpipe/ext/base/action/DeleteStoreChildrenAction.java rename to ext/base/src/main/java/io/xpipe/ext/base/action/DeleteChildrenStoreAction.java index 7d46ea3c4..ed69e3163 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/DeleteStoreChildrenAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/DeleteChildrenStoreAction.java @@ -12,11 +12,11 @@ import javafx.beans.value.ObservableValue; import lombok.Value; -public class DeleteStoreChildrenAction implements ActionProvider { +public class DeleteChildrenStoreAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite<>() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite<>() { @Override public boolean isSystemAction() { @@ -56,11 +56,6 @@ public class DeleteStoreChildrenAction implements ActionProvider { DataStoreEntry store; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() { DataStorage.get().deleteChildren(store); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java index 073555117..f01d8e95a 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/EditStoreAction.java @@ -14,8 +14,8 @@ import lombok.Value; public class EditStoreAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite<>() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite<>() { @Override public boolean isSystemAction() { @@ -49,8 +49,8 @@ public class EditStoreAction implements ActionProvider { } @Override - public ActiveType activeType() { - return ActiveType.ALWAYS_ENABLE; + public boolean requiresValidStore() { + return false; } }; } @@ -85,11 +85,6 @@ public class EditStoreAction implements ActionProvider { DataStoreEntry store; - @Override - public boolean requiresJavaFXPlatform() { - return true; - } - @Override public void execute() { StoreCreationComp.showEdit(store); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/LaunchAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/LaunchStoreAction.java similarity index 92% rename from ext/base/src/main/java/io/xpipe/ext/base/action/LaunchAction.java rename to ext/base/src/main/java/io/xpipe/ext/base/action/LaunchStoreAction.java index 6f121cbd0..450eb5a94 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/LaunchAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/LaunchStoreAction.java @@ -15,7 +15,7 @@ import javafx.beans.value.ObservableValue; import lombok.Value; -public class LaunchAction implements ActionProvider { +public class LaunchStoreAction implements ActionProvider { @Override public String getId() { @@ -23,8 +23,8 @@ public class LaunchAction implements ActionProvider { } @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite<>() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite<>() { @Override public boolean canLinkTo() { @@ -88,11 +88,6 @@ public class LaunchAction implements ActionProvider { DataStoreEntry entry; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() throws Exception { var storeName = DataStorage.get().getStoreDisplayName(entry); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreChildrenAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshChildrenStoreAction.java similarity index 87% rename from ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreChildrenAction.java rename to ext/base/src/main/java/io/xpipe/ext/base/action/RefreshChildrenStoreAction.java index 0c6e07485..cc41e806d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreChildrenAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshChildrenStoreAction.java @@ -6,16 +6,14 @@ import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.FixedHierarchyStore; - import javafx.beans.value.ObservableValue; - import lombok.Value; -public class RefreshStoreChildrenAction implements ActionProvider { +public class RefreshChildrenStoreAction implements ActionProvider { @Override - public ActionProvider.DataStoreCallSite getDataStoreCallSite() { - return new ActionProvider.DataStoreCallSite() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { @Override public ActionProvider.Action createAction(DataStoreEntryRef store) { @@ -70,11 +68,6 @@ public class RefreshStoreChildrenAction implements ActionProvider { DataStoreEntry store; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() { DataStorage.get().refreshChildren(store); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/SampleAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/SampleStoreAction.java similarity index 94% rename from ext/base/src/main/java/io/xpipe/ext/base/action/SampleAction.java rename to ext/base/src/main/java/io/xpipe/ext/base/action/SampleStoreAction.java index 5fd353080..27b2db2d5 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/SampleAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/SampleStoreAction.java @@ -18,13 +18,13 @@ import lombok.Value; import java.io.BufferedReader; import java.io.InputStreamReader; -public class SampleAction implements ActionProvider { +public class SampleStoreAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { // Call sites represent different ways of invoking the action. // In this case, this represents a button that is shown for all stored shell connections. - return new DataStoreCallSite() { + return new LeafDataStoreCallSite() { @Override public Action createAction(DataStoreEntryRef store) { @@ -63,12 +63,6 @@ public class SampleAction implements ActionProvider { DataStoreEntry entry; - @Override - public boolean requiresJavaFXPlatform() { - // Do we require the JavaFX platform to be running? - return false; - } - @Override public void execute() throws Exception { var docker = new LocalStore(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/ScanAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/ScanStoreAction.java similarity index 88% rename from ext/base/src/main/java/io/xpipe/ext/base/action/ScanAction.java rename to ext/base/src/main/java/io/xpipe/ext/base/action/ScanStoreAction.java index b2a2bbfab..7064ff551 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/ScanAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/ScanStoreAction.java @@ -12,11 +12,11 @@ import javafx.beans.value.ObservableValue; import lombok.Value; -public class ScanAction implements ActionProvider { +public class ScanStoreAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { @Override public ActionProvider.Action createAction(DataStoreEntryRef store) { @@ -65,11 +65,6 @@ public class ScanAction implements ActionProvider { DataStoreEntry entry; - @Override - public boolean requiresJavaFXPlatform() { - return true; - } - @Override public void execute() { ScanAlert.showAsync(entry); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/ShareStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/ShareStoreAction.java index 8aba7de93..911c78f51 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/ShareStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/ShareStoreAction.java @@ -16,8 +16,8 @@ import lombok.Value; public class ShareStoreAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite<>() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite<>() { @Override public ActionProvider.Action createAction(DataStoreEntryRef store) { @@ -55,11 +55,6 @@ public class ShareStoreAction implements ActionProvider { return "xpipe://addStore/" + InPlaceSecretValue.of(store.toString()).getEncryptedValue(); } - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() { var url = create(store.getStore()); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java index 10f3e926f..7a7807a0f 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java @@ -43,13 +43,13 @@ public class XPipeUrlAction implements ActionProvider { if (!entry.getValidity().isUsable()) { return null; } - return new LaunchAction.Action(entry); + return new LaunchStoreAction.Action(entry); } case "action" -> { var id = args.get(1); ActionProvider provider = ActionProvider.ALL.stream() .filter(actionProvider -> { - return actionProvider.getDataStoreCallSite() != null + return actionProvider.getLeafDataStoreCallSite() != null && id.equals(actionProvider.getId()); }) .findFirst() @@ -83,14 +83,9 @@ public class XPipeUrlAction implements ActionProvider { ActionProvider actionProvider; DataStoreEntry entry; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() throws Exception { - actionProvider.getDataStoreCallSite().createAction(entry.ref()).execute(); + actionProvider.getLeafDataStoreCallSite().createAction(entry.ref()).execute(); } } @@ -99,11 +94,6 @@ public class XPipeUrlAction implements ActionProvider { DataStore store; - @Override - public boolean requiresJavaFXPlatform() { - return true; - } - @Override public void execute() { if (store == null) { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java index cacc3e60b..447bf1843 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java @@ -31,10 +31,6 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider { @Override public ActionProvider.Action launchAction(DataStoreEntry store) { return new ActionProvider.Action() { - @Override - public boolean requiresJavaFXPlatform() { - return false; - } @Override public void execute() throws Exception { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java index 0d0eca750..78baedf90 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java @@ -32,10 +32,6 @@ public class DesktopCommandStoreProvider implements DataStoreProvider { @Override public ActionProvider.Action launchAction(DataStoreEntry store) { return new ActionProvider.Action() { - @Override - public boolean requiresJavaFXPlatform() { - return false; - } @Override public void execute() throws Exception { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java index c46a8eb01..dc9972ba5 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java @@ -39,10 +39,6 @@ public class DesktopEnvironmentStoreProvider implements DataStoreProvider { @Override public ActionProvider.Action activateAction(DataStoreEntry store) { return new ActionProvider.Action() { - @Override - public boolean requiresJavaFXPlatform() { - return false; - } @Override public void execute() throws Exception { @@ -61,10 +57,6 @@ public class DesktopEnvironmentStoreProvider implements DataStoreProvider { @Override public ActionProvider.Action launchAction(DataStoreEntry store) { return new ActionProvider.Action() { - @Override - public boolean requiresJavaFXPlatform() { - return false; - } @Override public void execute() throws Exception { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java b/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java index dfc07e472..84d7c9177 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptGroup.java @@ -8,7 +8,9 @@ import lombok.Setter; @Getter public enum PredefinedScriptGroup { CLINK("Clink", null, false), - STARSHIP("Starship", "Sets up and enables the starship shell prompt", true); + STARSHIP("Starship", "Sets up and enables the starship shell prompt", true), + MANAGEMENT("Management", "Some commonly used management scripts", true), + FILES("Files", "Scripts for files", true); private final String name; private final String description; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptStore.java index e74ecffa7..8d8e043de 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptStore.java @@ -19,11 +19,13 @@ public enum PredefinedScriptStore { .group(PredefinedScriptGroup.CLINK.getEntry()) .minimumDialect(ShellDialects.CMD) .commands(file("clink.bat")) + .initScript(true) .build()), CLINK_INJECT("Clink Inject", () -> SimpleScriptStore.builder() .group(PredefinedScriptGroup.CLINK.getEntry()) .minimumDialect(ShellDialects.CMD) .script(CLINK_SETUP.getEntry()) + .initScript(true) .commands(""" clink inject --quiet """) @@ -32,27 +34,44 @@ public enum PredefinedScriptStore { .group(PredefinedScriptGroup.STARSHIP.getEntry()) .minimumDialect(ShellDialects.BASH) .commands(file("starship_bash.sh")) + .initScript(true) .build()), STARSHIP_ZSH("Starship Zsh", () -> SimpleScriptStore.builder() .group(PredefinedScriptGroup.STARSHIP.getEntry()) .minimumDialect(ShellDialects.ZSH) .commands(file("starship_zsh.sh")) + .initScript(true) .build()), STARSHIP_FISH("Starship Fish", () -> SimpleScriptStore.builder() .group(PredefinedScriptGroup.STARSHIP.getEntry()) .minimumDialect(ShellDialects.FISH) .commands(file("starship_fish.fish")) + .initScript(true) .build()), STARSHIP_CMD("Starship Cmd", () -> SimpleScriptStore.builder() .group(PredefinedScriptGroup.STARSHIP.getEntry()) .minimumDialect(ShellDialects.CMD) .script(CLINK_SETUP.getEntry()) .commands(file(("starship_cmd.bat"))) + .initScript(true) .build()), STARSHIP_POWERSHELL("Starship Powershell", () -> SimpleScriptStore.builder() .group(PredefinedScriptGroup.STARSHIP.getEntry()) .minimumDialect(ShellDialects.POWERSHELL) .commands(file("starship_powershell.ps1")) + .initScript(true) + .build()), + APT_UPDATE("Apt update", () -> SimpleScriptStore.builder() + .group(PredefinedScriptGroup.MANAGEMENT.getEntry()) + .minimumDialect(ShellDialects.SH) + .commands(file(("apt_update.sh"))) + .shellScript(true) + .build()), + REMOVE_CR("CRLF to LF", () -> SimpleScriptStore.builder() + .group(PredefinedScriptGroup.FILES.getEntry()) + .minimumDialect(ShellDialects.SH) + .commands(file(("crlf_to_lf.sh"))) + .fileScript(true) .build()); private final String name; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptAction.java b/ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptAction.java new file mode 100644 index 000000000..0cb12bf4d --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptAction.java @@ -0,0 +1,95 @@ +package io.xpipe.ext.base.script; + +import io.xpipe.app.browser.action.BranchAction; +import io.xpipe.app.browser.action.BrowserAction; +import io.xpipe.app.browser.action.LeafAction; +import io.xpipe.app.browser.file.BrowserEntry; +import io.xpipe.app.browser.fs.OpenFileSystemModel; +import io.xpipe.app.browser.session.BrowserSessionModel; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.util.ScriptHelper; +import io.xpipe.core.process.ShellControl; +import io.xpipe.core.store.FilePath; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; +import javafx.scene.Node; +import org.kordamp.ikonli.javafx.FontIcon; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class RunScriptAction implements BrowserAction, BranchAction { + + @Override + public Node getIcon(OpenFileSystemModel model, List entries) { + return new FontIcon("mdi2c-code-greater-than"); + } + + @Override + public Category getCategory() { + return Category.MUTATION; + } + + @Override + public ObservableValue getName(OpenFileSystemModel model, List entries) { + return AppI18n.observable("runScript"); + } + + @Override + public boolean isApplicable(OpenFileSystemModel model, List entries) { + var sc = model.getFileSystem().getShell().orElseThrow(); + return model.getBrowserModel() instanceof BrowserSessionModel + && !getInstances(sc).isEmpty(); + } + + private Map getInstances(ShellControl sc) { + var scripts = ScriptStore.flatten(ScriptStore.getDefaultEnabledScripts()); + var map = new LinkedHashMap(); + for (SimpleScriptStore script : scripts) { + if (script.assemble(sc) == null) { + continue; + } + + var entry = DataStorage.get().getStoreEntryIfPresent(script, true); + if (entry.isPresent()) { + map.put(entry.get().getName(), script); + } + } + return map; + } + + @Override + public List getBranchingActions(OpenFileSystemModel model, List entries) { + var sc = model.getFileSystem().getShell().orElseThrow(); + var scripts = getInstances(sc); + List actions = scripts.entrySet().stream() + .map(e -> { + return new LeafAction() { + @Override + public void execute(OpenFileSystemModel model, List entries) throws Exception { + var args = entries.stream().map(browserEntry -> new FilePath(browserEntry.getRawFileEntry().getPath()).quoteIfNecessary()).collect(Collectors.joining(" ")); + execute(model, args); + } + + private void execute(OpenFileSystemModel model, String args) throws Exception { + if (model.getBrowserModel() instanceof BrowserSessionModel bm) { + var content = e.getValue().assemble(sc); + var script = ScriptHelper.createExecScript(sc, content); + sc.executeSimpleCommand(sc.getShellDialect().runScriptCommand(sc, script.toString()) + " " + args); + } + } + + @Override + public ObservableValue getName(OpenFileSystemModel model, List entries) { + return new SimpleStringProperty(e.getKey()); + } + }; + }) + .map(leafAction -> (LeafAction) leafAction) + .toList(); + return actions; + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptDataStorageProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptDataStorageProvider.java new file mode 100644 index 000000000..d1fe28e4f --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptDataStorageProvider.java @@ -0,0 +1,50 @@ +package io.xpipe.ext.base.script; + +import io.xpipe.app.ext.DataStorageExtensionProvider; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; + +import java.nio.charset.StandardCharsets; +import java.util.UUID; + +public class ScriptDataStorageProvider extends DataStorageExtensionProvider { + + @Override + public void storageInit() { + DataStorage.get() + .addStoreEntryIfNotPresent(DataStoreEntry.createNew( + UUID.fromString("a9945ad2-db61-4304-97d7-5dc4330691a7"), + DataStorage.CUSTOM_SCRIPTS_CATEGORY_UUID, + "My scripts", + ScriptGroupStore.builder().build())); + + for (PredefinedScriptGroup value : PredefinedScriptGroup.values()) { + ScriptGroupStore store = ScriptGroupStore.builder() + .description(value.getDescription()) + .build(); + var e = DataStorage.get() + .addStoreEntryIfNotPresent(DataStoreEntry.createNew( + UUID.nameUUIDFromBytes(("a " + value.getName()).getBytes(StandardCharsets.UTF_8)), + DataStorage.PREDEFINED_SCRIPTS_CATEGORY_UUID, + value.getName(), + store)); + e.setStoreInternal(store, false); + e.setExpanded(value.isExpanded()); + value.setEntry(e.ref()); + } + + for (PredefinedScriptStore value : PredefinedScriptStore.values()) { + var previous = DataStorage.get().getStoreEntryIfPresent(value.getUuid()); + var store = value.getScriptStore().get(); + if (previous.isPresent()) { + previous.get().setStoreInternal(store, false); + value.setEntry(previous.get().ref()); + } else { + var e = DataStoreEntry.createNew( + value.getUuid(), DataStorage.PREDEFINED_SCRIPTS_CATEGORY_UUID, value.getName(), store); + DataStorage.get().addStoreEntryIfNotPresent(e); + value.setEntry(e.ref()); + } + } + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java index c72da8880..c951a7606 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java @@ -1,49 +1,25 @@ package io.xpipe.ext.base.script; -import io.xpipe.app.comp.base.DropdownComp; -import io.xpipe.app.comp.base.StoreToggleComp; import io.xpipe.app.comp.base.SystemStateComp; -import io.xpipe.app.comp.store.*; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.EnabledStoreProvider; import io.xpipe.app.ext.GuiDialog; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.core.store.DataStore; - import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; - import lombok.SneakyThrows; import java.util.List; -public class ScriptGroupStoreProvider implements DataStoreProvider { - - @Override - public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { - if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { - return new DenseStoreEntryComp(sec.getWrapper(), true, null); - } - - var def = StoreToggleComp.simpleToggle( - "base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> { - var state = s.getState().toBuilder().isDefault(aBoolean).build(); - s.setState(state); - }); - - var bring = StoreToggleComp.simpleToggle( - "base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> { - var state = s.getState().toBuilder().bringToShell(aBoolean).build(); - s.setState(state); - }); - - var dropdown = new DropdownComp(List.of(def, bring)); - return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown); - } +public class ScriptGroupStoreProvider implements EnabledStoreProvider, DataStoreProvider { @Override public Comp stateDisplay(StoreEntryWrapper w) { @@ -100,6 +76,11 @@ public class ScriptGroupStoreProvider implements DataStoreProvider { return new SimpleStringProperty(scriptStore.getDescription()); } + @Override + public String summaryString(StoreEntryWrapper wrapper) { + return "Script group"; + } + @Override public String getDisplayIconFileName(DataStore store) { return "proc:shellEnvironment_icon.svg"; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java index bb7531199..f892873fc 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java @@ -9,20 +9,21 @@ import io.xpipe.app.util.Validators; import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.ShellInitCommand; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.DataStoreState; +import io.xpipe.core.store.EnabledStoreState; import io.xpipe.core.store.FileNames; import io.xpipe.core.store.StatefulDataStore; import io.xpipe.core.util.JacksonizedValue; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Singular; import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; import java.util.*; @SuperBuilder @Getter @AllArgsConstructor -public abstract class ScriptStore extends JacksonizedValue implements DataStore, StatefulDataStore { +public abstract class ScriptStore extends JacksonizedValue implements DataStore, StatefulDataStore { protected final DataStoreEntryRef group; @@ -32,21 +33,20 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, protected final String description; public static ShellControl controlWithDefaultScripts(ShellControl pc) { - return controlWithScripts(pc, getDefaultInitScripts(), getDefaultBringScripts()); + return controlWithScripts(pc, getDefaultEnabledScripts()); } public static ShellControl controlWithScripts( ShellControl pc, - List> initScripts, - List> bringScripts) { + List> enabledScripts) { try { // Don't copy scripts if we don't want to modify the file system if (!pc.getEffectiveSecurityPolicy().permitTempScriptCreation()) { return pc; } - var initFlattened = flatten(initScripts); - var bringFlattened = flatten(bringScripts); + var initFlattened = flatten(enabledScripts).stream().filter(store -> store.isInitScript()).toList(); + var bringFlattened = flatten(enabledScripts).stream().filter(store -> store.isShellScript()).toList(); // Optimize if we have nothing to do if (initFlattened.isEmpty() && bringFlattened.isEmpty()) { @@ -150,18 +150,10 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, return targetDir; } - public static List> getDefaultInitScripts() { + public static List> getDefaultEnabledScripts() { return DataStorage.get().getStoreEntries().stream() .filter(dataStoreEntry -> dataStoreEntry.getStore() instanceof ScriptStore scriptStore - && scriptStore.getState().isDefault()) - .map(DataStoreEntry::ref) - .toList(); - } - - public static List> getDefaultBringScripts() { - return DataStorage.get().getStoreEntries().stream() - .filter(dataStoreEntry -> dataStoreEntry.getStore() instanceof ScriptStore scriptStore - && scriptStore.getState().isBringToShell()) + && scriptStore.getState().isEnabled()) .map(DataStoreEntry::ref) .toList(); } @@ -194,8 +186,8 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, } @Override - public Class getStateClass() { - return State.class; + public Class getStateClass() { + return EnabledStoreState.class; } @Override @@ -220,13 +212,4 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, protected abstract void queryFlattenedScripts(LinkedHashSet all); public abstract List> getEffectiveScripts(); - - @Value - @EqualsAndHashCode(callSuper=true) - @SuperBuilder(toBuilder = true) - @Jacksonized - public static class State extends DataStoreState { - boolean isDefault; - boolean bringToShell; - } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTargetType.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTargetType.java new file mode 100644 index 000000000..0d854e2cc --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTargetType.java @@ -0,0 +1,13 @@ +package io.xpipe.ext.base.script; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public enum ScriptTargetType { + + @JsonProperty("shellInit") + SHELL_INIT, + @JsonProperty("shellSession") + SHELL_SESSION, + @JsonProperty("file") + FILE +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java index f239e30a1..bc21abd70 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java @@ -1,12 +1,14 @@ package io.xpipe.ext.base.script; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.ScriptHelper; import io.xpipe.app.util.Validators; import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.ShellDialect; import io.xpipe.core.process.ShellInitCommand; +import io.xpipe.core.util.ValidationException; import lombok.Getter; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; @@ -25,8 +27,11 @@ public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.T private final ShellDialect minimumDialect; private final String commands; + private final boolean initScript; + private final boolean shellScript; + private final boolean fileScript; - private String assemble(ShellControl shellControl) { + public String assemble(ShellControl shellControl) { var targetType = shellControl.getOriginalShellDialect(); if (minimumDialect.isCompatibleTo(targetType)) { var shebang = commands.startsWith("#"); @@ -47,6 +52,9 @@ public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.T Validators.nonNull(group); super.checkComplete(); Validators.nonNull(minimumDialect); + if (!initScript && !shellScript && !fileScript) { + throw new ValidationException(AppI18n.get("app.valueMustNotBeEmpty")); + } } public void queryFlattenedScripts(LinkedHashSet all) { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java index 808f3b187..be6a104cf 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java @@ -1,25 +1,25 @@ package io.xpipe.ext.base.script; -import io.xpipe.app.comp.base.DropdownComp; import io.xpipe.app.comp.base.IntegratedTextAreaComp; -import io.xpipe.app.comp.base.StoreToggleComp; +import io.xpipe.app.comp.base.ListSelectorComp; import io.xpipe.app.comp.base.SystemStateComp; -import io.xpipe.app.comp.store.*; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.AppExtensionManager; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.EnabledParentStoreProvider; import io.xpipe.app.ext.GuiDialog; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp; import io.xpipe.app.fxcomps.impl.DataStoreListChoiceComp; -import io.xpipe.app.fxcomps.util.BindingsHelper; -import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.MarkdownBuilder; import io.xpipe.app.util.OptionsBuilder; +import io.xpipe.app.util.Validator; import io.xpipe.core.process.ShellDialect; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.Identifiers; - import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleListProperty; @@ -27,16 +27,14 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; - import lombok.SneakyThrows; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import java.util.UUID; +import java.util.function.Function; import java.util.stream.Collectors; -public class SimpleScriptStoreProvider implements DataStoreProvider { +public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, DataStoreProvider { @Override public boolean editByDefault() { @@ -48,43 +46,6 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { return true; } - @Override - public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { - if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { - return new DenseStoreEntryComp(sec.getWrapper(), true, null); - } - - var def = StoreToggleComp.simpleToggle( - "base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> { - var state = s.getState().toBuilder().isDefault(aBoolean).build(); - s.setState(state); - }); - - var bring = StoreToggleComp.simpleToggle( - "base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> { - var state = s.getState().toBuilder().bringToShell(aBoolean).build(); - s.setState(state); - }); - - SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded(); - var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry()); - - // Disable selection if parent group is already made default - def.disable(BindingsHelper.map(groupWrapper.getPersistentState(), o -> { - ScriptStore.State state = (ScriptStore.State) o; - return state.isDefault(); - })); - - // Disable selection if parent group is already brings - bring.disable(BindingsHelper.map(groupWrapper.getPersistentState(), o -> { - ScriptStore.State state = (ScriptStore.State) o; - return state.isBringToShell(); - })); - - var dropdown = new DropdownComp(List.of(def, bring)); - return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown); - } - @Override public boolean shouldHaveChildren() { return false; @@ -148,6 +109,39 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { "io.xpipe.ext.proc.ShellDialectChoiceComp") .getDeclaredConstructor(Property.class, boolean.class) .newInstance(dialect, false); + + var vals = List.of(0, 1, 2); + var selectedStart = new ArrayList(); + if (st.isInitScript()) { + selectedStart.add(0); + } + if (st.isShellScript()) { + selectedStart.add(1); + } + if (st.isFileScript()) { + selectedStart.add(2); + } + var name = new Function() { + + @Override + public String apply(Integer integer) { + if (integer == 0) { + return AppI18n.get("initScript"); + } + + if (integer == 1) { + return AppI18n.get("shellScript"); + } + + if (integer == 2) { + return AppI18n.get("fileScript"); + } + return "?"; + } + }; + var selectedExecTypes = new SimpleListProperty<>(FXCollections.observableList(selectedStart)); + var selectorComp = new ListSelectorComp<>(vals, name, selectedExecTypes, v -> false, false); + return new OptionsBuilder() .name("snippets") .description("snippetsDescription") @@ -174,7 +168,10 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { : "sh"; })), commandProp) - .name("executionType") + .nameAndDescription("executionType") + .longDescription("base:executionType") + .addComp(selectorComp, selectedExecTypes) + .check(validator -> Validator.nonEmpty(validator, AppI18n.observable("executionType"), selectedExecTypes)) .name("scriptGroup") .description("scriptGroupDescription") .addComp( @@ -195,51 +192,15 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { .scripts(new ArrayList<>(others.get())) .description(st.getDescription()) .commands(commandProp.getValue()) + .initScript(selectedExecTypes.contains(0)) + .shellScript(selectedExecTypes.contains(1)) + .fileScript(selectedExecTypes.contains(2)) .build(); }, store) .buildDialog(); } - @Override - public void init() { - DataStorage.get() - .addStoreEntryIfNotPresent(DataStoreEntry.createNew( - UUID.fromString("a9945ad2-db61-4304-97d7-5dc4330691a7"), - DataStorage.CUSTOM_SCRIPTS_CATEGORY_UUID, - "My scripts", - ScriptGroupStore.builder().build())); - - for (PredefinedScriptGroup value : PredefinedScriptGroup.values()) { - ScriptGroupStore store = ScriptGroupStore.builder() - .description(value.getDescription()) - .build(); - var e = DataStorage.get() - .addStoreEntryIfNotPresent(DataStoreEntry.createNew( - UUID.nameUUIDFromBytes(("a " + value.getName()).getBytes(StandardCharsets.UTF_8)), - DataStorage.PREDEFINED_SCRIPTS_CATEGORY_UUID, - value.getName(), - store)); - e.setStoreInternal(store, false); - e.setExpanded(value.isExpanded()); - value.setEntry(e.ref()); - } - - for (PredefinedScriptStore value : PredefinedScriptStore.values()) { - var previous = DataStorage.get().getStoreEntryIfPresent(value.getUuid()); - var store = value.getScriptStore().get(); - if (previous.isPresent()) { - previous.get().setStoreInternal(store, false); - value.setEntry(previous.get().ref()); - } else { - var e = DataStoreEntry.createNew( - value.getUuid(), DataStorage.PREDEFINED_SCRIPTS_CATEGORY_UUID, value.getName(), store); - DataStorage.get().addStoreEntryIfNotPresent(e); - value.setEntry(e.ref()); - } - } - } - @Override public ObservableValue informationString(StoreEntryWrapper wrapper) { SimpleScriptStore scriptStore = wrapper.getEntry().getStore().asNeeded(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java new file mode 100644 index 000000000..a37502092 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java @@ -0,0 +1,24 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.Validators; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.util.JacksonizedValue; +import io.xpipe.ext.base.GroupStore; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.experimental.FieldDefaults; +import lombok.experimental.SuperBuilder; + +@Getter +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@SuperBuilder +public abstract class AbstractServiceGroupStore extends JacksonizedValue implements DataStore, GroupStore { + + DataStoreEntryRef parent; + + @Override + public void checkComplete() throws Throwable { + Validators.nonNull(parent); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java new file mode 100644 index 000000000..d2d3cbb99 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java @@ -0,0 +1,70 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.comp.base.StoreToggleComp; +import io.xpipe.app.comp.base.SystemStateComp; +import io.xpipe.app.comp.store.StoreEntryComp; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.comp.store.StoreViewState; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.ThreadHelper; +import io.xpipe.core.store.DataStore; +import javafx.beans.binding.Bindings; +import javafx.beans.property.SimpleObjectProperty; + +public abstract class AbstractServiceGroupStoreProvider implements DataStoreProvider { + + @Override + public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { + var t = createToggleComp(sec); + return StoreEntryComp.create(sec.getWrapper(), t, preferLarge); + } + + private StoreToggleComp createToggleComp(StoreSection sec) { + var t = StoreToggleComp.>enableToggle(null, sec, g -> false, (g, aBoolean) -> { + var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry()); + ThreadHelper.runFailableAsync(() -> { + for (DataStoreEntry child : children) { + if (child.getStore() instanceof AbstractServiceStore serviceStore) { + if (aBoolean) { + serviceStore.startSessionIfNeeded(); + } else { + serviceStore.stopSessionIfNeeded(); + } + } + } + }); + }); + t.setCustomVisibility(Bindings.createBooleanBinding(() -> { + var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry()); + for (DataStoreEntry child : children) { + if (child.getStore() instanceof AbstractServiceStore serviceStore) { + if (serviceStore.getHost().getStore().requiresTunnel()) { + return true; + } + } + } + return false; + }, StoreViewState.get().getAllEntries().getList())); + return t; + } + + @Override + public Comp stateDisplay(StoreEntryWrapper w) { + return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS)); + } + + @Override + public String getDisplayIconFileName(DataStore store) { + return "base:serviceGroup_icon.svg"; + } + + @Override + public DataStoreEntry getDisplayParent(DataStoreEntry store) { + AbstractServiceGroupStore s = store.getStore().asNeeded(); + return s.getParent().get(); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java new file mode 100644 index 000000000..721dba402 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java @@ -0,0 +1,42 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.HostHelper; +import io.xpipe.app.util.Validators; +import io.xpipe.core.store.*; +import io.xpipe.core.util.JacksonizedValue; +import lombok.Getter; +import lombok.experimental.SuperBuilder; + +@SuperBuilder +@Getter +public abstract class AbstractServiceStore extends JacksonizedValue implements SingletonSessionStore, DataStore { + + public abstract DataStoreEntryRef getHost(); + + private final Integer remotePort; + private final Integer localPort; + + @Override + public void checkComplete() throws Throwable { + Validators.nonNull(getHost()); + Validators.isType(getHost(), NetworkTunnelStore.class); + Validators.nonNull(remotePort); + } + + public boolean requiresTunnel() { + return getHost().getStore().requiresTunnel(); + } + + @Override + public NetworkTunnelSession newSession() throws Exception { + ServiceLicenseCheck.check(); + var l = localPort != null ? localPort : HostHelper.findRandomOpenPortOnAllLocalInterfaces(); + return getHost().getStore().sessionChain(l, remotePort); + } + + @Override + public Class getSessionClass() { + return NetworkTunnelSession.class; + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java new file mode 100644 index 000000000..54e3db682 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java @@ -0,0 +1,100 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.comp.base.SystemStateComp; +import io.xpipe.app.comp.store.StoreEntryComp; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.SingletonSessionStoreProvider; +import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.core.store.DataStore; +import javafx.beans.binding.Bindings; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; + +import java.util.List; + +public abstract class AbstractServiceStoreProvider implements SingletonSessionStoreProvider, DataStoreProvider { + + @Override + public ActionProvider.Action launchAction(DataStoreEntry store) { + return new ActionProvider.Action() { + @Override + public void execute() throws Exception { + AbstractServiceStore s = store.getStore().asNeeded(); + s.startSessionIfNeeded(); + } + }; + } + + @Override + public DataStoreEntry getSyntheticParent(DataStoreEntry store) { + AbstractServiceStore s = store.getStore().asNeeded(); + return DataStorage.get().getOrCreateNewSyntheticEntry(s.getHost().get(), "Services", ServiceGroupStore.builder().parent(s.getHost()).build()); + } + + @Override + public Comp stateDisplay(StoreEntryWrapper w) { + return new SystemStateComp(Bindings.createObjectBinding( + () -> { + AbstractServiceStore s = w.getEntry().getStore().asNeeded(); + if (!s.requiresTunnel()) { + return SystemStateComp.State.SUCCESS; + } + + if (!s.isSessionEnabled()) { + return SystemStateComp.State.OTHER; + } + + return s.isSessionRunning() ? SystemStateComp.State.SUCCESS : SystemStateComp.State.FAILURE; + }, + w.getCache())); + } + + @Override + public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { + var toggle = createToggleComp(sec); + toggle.setCustomVisibility(Bindings.createBooleanBinding( + () -> { + AbstractServiceStore s = sec.getWrapper().getEntry().getStore().asNeeded(); + if (!s.getHost().getStore().requiresTunnel()) { + return false; + } + + return true; + }, + sec.getWrapper().getCache())); + return StoreEntryComp.create(sec.getWrapper(), toggle, preferLarge); + } + + @Override + public List getSearchableTerms(DataStore store) { + AbstractServiceStore s = store.asNeeded(); + return s.getLocalPort() != null ? List.of("" + s.getRemotePort(), "" + s.getLocalPort()) : List.of("" + s.getRemotePort()); + } + + @Override + public String summaryString(StoreEntryWrapper wrapper) { + AbstractServiceStore s = wrapper.getEntry().getStore().asNeeded(); + return DataStoreFormatter.toApostropheName(s.getHost().get()) + " service"; + } + + @Override + public ObservableValue informationString(StoreEntryWrapper wrapper) { + AbstractServiceStore s = wrapper.getEntry().getStore().asNeeded(); + if (s.getLocalPort() != null) { + return new SimpleStringProperty("Port " + s.getLocalPort() + " <- " + s.getRemotePort()); + } else { + return new SimpleStringProperty("Port " + s.getRemotePort()); + } + } + + @Override + public String getDisplayIconFileName(DataStore store) { + return "base:service_icon.svg"; + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java new file mode 100644 index 000000000..12ef34885 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java @@ -0,0 +1,17 @@ +package io.xpipe.ext.base.service; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.core.store.NetworkTunnelStore; +import lombok.Getter; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +@SuperBuilder +@Getter +@Jacksonized +@JsonTypeName("customService") +public final class CustomServiceStore extends AbstractServiceStore { + + private final DataStoreEntryRef host; +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java new file mode 100644 index 000000000..45e95dcdf --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java @@ -0,0 +1,70 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.comp.store.StoreViewState; +import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.OptionsBuilder; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.NetworkTunnelStore; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; + +import java.util.List; + +public class CustomServiceStoreProvider extends AbstractServiceStoreProvider { + + @Override + public CreationCategory getCreationCategory() { + return CreationCategory.SERVICE; + } + + @Override + public GuiDialog guiDialog(DataStoreEntry entry, Property store) { + CustomServiceStore st = store.getValue().asNeeded(); + var host = new SimpleObjectProperty<>(st.getHost()); + var localPort = new SimpleObjectProperty<>(st.getLocalPort()); + var remotePort = new SimpleObjectProperty<>(st.getRemotePort()); + + var q = new OptionsBuilder() + .nameAndDescription("serviceHost") + .addComp( + DataStoreChoiceComp.other( + host, + NetworkTunnelStore.class, + n -> n.getStore().isLocallyTunneable(), + StoreViewState.get().getAllConnectionsCategory()), + host) + .nonNull() + .nameAndDescription("serviceRemotePort") + .addInteger(remotePort) + .nonNull() + .nameAndDescription("serviceLocalPort") + .addInteger(localPort) + .bind( + () -> { + return CustomServiceStore.builder() + .host(host.get()) + .localPort(localPort.get()) + .remotePort(remotePort.get()) + .build(); + }, + store); + return q.buildDialog(); + } + + @Override + public DataStore defaultStore() { + return CustomServiceStore.builder().build(); + } + + @Override + public List getPossibleNames() { + return List.of("customService"); + } + + @Override + public List> getStoreClasses() { + return List.of(CustomServiceStore.class); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceCreatorStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceCreatorStore.java new file mode 100644 index 000000000..05e83f1ff --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceCreatorStore.java @@ -0,0 +1,11 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.core.store.DataStore; + +import java.util.List; + +public interface FixedServiceCreatorStore extends DataStore { + + List> createFixedServices() throws Exception; +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStore.java new file mode 100644 index 000000000..780c73ba0 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStore.java @@ -0,0 +1,29 @@ +package io.xpipe.ext.base.service; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.FixedHierarchyStore; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FixedChildStore; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.experimental.FieldDefaults; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +import java.util.List; + +@Getter +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@SuperBuilder +@Jacksonized +@JsonTypeName("fixedServiceGroup") +public class FixedServiceGroupStore extends AbstractServiceGroupStore implements DataStore, FixedHierarchyStore { + + @Override + @SuppressWarnings("unchecked") + public List> listChildren(DataStoreEntry self) throws Exception { + return (List>) getParent().getStore().createFixedServices(); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStoreProvider.java new file mode 100644 index 000000000..132b38fb6 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceGroupStoreProvider.java @@ -0,0 +1,30 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.core.store.DataStore; + +import java.util.List; + +public class FixedServiceGroupStoreProvider extends AbstractServiceGroupStoreProvider { + + @Override + public DataStore defaultStore() { + return FixedServiceGroupStore.builder().build(); + } + + @Override + public DataStoreEntry getDisplayParent(DataStoreEntry store) { + FixedServiceGroupStore s = store.getStore().asNeeded(); + return s.getParent().get(); + } + + @Override + public List getPossibleNames() { + return List.of("fixedServiceGroup"); + } + + @Override + public List> getStoreClasses() { + return List.of(FixedServiceGroupStore.class); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java new file mode 100644 index 000000000..aa37c2aa4 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java @@ -0,0 +1,32 @@ +package io.xpipe.ext.base.service; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FixedChildStore; +import io.xpipe.core.store.NetworkTunnelStore; +import lombok.Getter; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +import java.util.OptionalInt; + +@SuperBuilder +@Getter +@Jacksonized +@JsonTypeName("fixedService") +public class FixedServiceStore extends AbstractServiceStore implements FixedChildStore { + + private final DataStoreEntryRef host; + private final DataStoreEntryRef displayParent; + + @Override + public DataStoreEntryRef getHost() { + return host; + } + + @Override + public OptionalInt getFixedId() { + return OptionalInt.of(getRemotePort()); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java new file mode 100644 index 000000000..72c67720e --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java @@ -0,0 +1,35 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; + +import java.util.List; + +public class FixedServiceStoreProvider extends AbstractServiceStoreProvider { + + @Override + public DataStoreEntry getSyntheticParent(DataStoreEntry store) { + FixedServiceStore s = store.getStore().asNeeded(); + return DataStorage.get().getOrCreateNewSyntheticEntry(s.getHost().get(), "Services", + FixedServiceGroupStore.builder().parent(s.getDisplayParent().get().ref()).build()); + } + + @Override + public List getPossibleNames() { + return List.of("fixedService"); + } + + @Override + public ObservableValue informationString(StoreEntryWrapper wrapper) { + FixedServiceStore s = wrapper.getEntry().getStore().asNeeded(); + return new SimpleStringProperty("Port " + s.getRemotePort()); + } + + @Override + public List> getStoreClasses() { + return List.of(FixedServiceStore.class); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStore.java new file mode 100644 index 000000000..69ab2e9ff --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStore.java @@ -0,0 +1,15 @@ +package io.xpipe.ext.base.service; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.Getter; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +@SuperBuilder +@Getter +@Jacksonized +@JsonTypeName("mappedService") +public class MappedServiceStore extends FixedServiceStore { + + private final int containerPort; +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java new file mode 100644 index 000000000..39ea2f8fd --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java @@ -0,0 +1,26 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.comp.store.StoreEntryWrapper; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; + +import java.util.List; + +public class MappedServiceStoreProvider extends FixedServiceStoreProvider { + + @Override + public List getPossibleNames() { + return List.of("mappedService"); + } + + @Override + public ObservableValue informationString(StoreEntryWrapper wrapper) { + MappedServiceStore s = wrapper.getEntry().getStore().asNeeded(); + return new SimpleStringProperty("Port " + s.getContainerPort() + " -> " + s.getRemotePort()); + } + + @Override + public List> getStoreClasses() { + return List.of(MappedServiceStore.class); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceCopyUrlAction.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceCopyUrlAction.java new file mode 100644 index 000000000..d3f35e904 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceCopyUrlAction.java @@ -0,0 +1,60 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.ClipboardHelper; +import javafx.beans.value.ObservableValue; +import lombok.Value; + +public class ServiceCopyUrlAction implements ActionProvider { + + @Override + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { + + @Override + public boolean isMajor(DataStoreEntryRef o) { + return true; + } + + @Override + public boolean canLinkTo() { + return true; + } + + @Override + public ActionProvider.Action createAction(DataStoreEntryRef store) { + return new Action(store.getStore()); + } + + @Override + public Class getApplicableClass() { + return AbstractServiceStore.class; + } + + @Override + public ObservableValue getName(DataStoreEntryRef store) { + return AppI18n.observable("copyUrl"); + } + + @Override + public String getIcon(DataStoreEntryRef store) { + return "mdi2c-content-copy"; + } + }; + } + + @Value + static class Action implements ActionProvider.Action { + + AbstractServiceStore serviceStore; + + @Override + public void execute() throws Exception { + serviceStore.startSessionIfNeeded(); + var l = serviceStore.getSession().getLocalPort(); + ClipboardHelper.copyUrl("localhost:" + l); + } + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStore.java new file mode 100644 index 000000000..22c2d8a4c --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStore.java @@ -0,0 +1,28 @@ +package io.xpipe.ext.base.service; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.Validators; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.util.JacksonizedValue; +import io.xpipe.ext.base.GroupStore; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.experimental.FieldDefaults; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +@Getter +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@SuperBuilder +@Jacksonized +@JsonTypeName("serviceGroup") +public class ServiceGroupStore extends JacksonizedValue implements DataStore, GroupStore { + + DataStoreEntryRef parent; + + @Override + public void checkComplete() throws Throwable { + Validators.nonNull(parent); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStoreProvider.java new file mode 100644 index 000000000..c6df32da1 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceGroupStoreProvider.java @@ -0,0 +1,30 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.core.store.DataStore; + +import java.util.List; + +public class ServiceGroupStoreProvider extends AbstractServiceGroupStoreProvider { + + @Override + public DataStore defaultStore() { + return ServiceGroupStore.builder().build(); + } + + @Override + public DataStoreEntry getDisplayParent(DataStoreEntry store) { + ServiceGroupStore s = store.getStore().asNeeded(); + return s.getParent().get(); + } + + @Override + public List getPossibleNames() { + return List.of("serviceGroup"); + } + + @Override + public List> getStoreClasses() { + return List.of(ServiceGroupStore.class); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceLicenseCheck.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceLicenseCheck.java new file mode 100644 index 000000000..25ce42c7f --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceLicenseCheck.java @@ -0,0 +1,34 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.util.LicenseConnectionLimit; +import io.xpipe.app.util.LicenseProvider; +import io.xpipe.app.util.LicensedFeature; +import io.xpipe.core.store.DataStore; + +public class ServiceLicenseCheck { + + public static LicensedFeature getFeature() { + return LicenseProvider.get().getFeature("services"); + } + + public static void check() { + if (getFeature().isSupported()) { + return; + } + + var limit = getConnectionLimit(); + limit.checkLimit(); + } + + + public static LicenseConnectionLimit getConnectionLimit() { + // We check before starting a new service + return new LicenseConnectionLimit(0, getFeature()) { + + @Override + protected boolean matches(DataStore store) { + return store instanceof AbstractServiceStore abstractServiceStore && abstractServiceStore.requiresTunnel() && abstractServiceStore.isSessionRunning(); + } + }; + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java new file mode 100644 index 000000000..ca122c557 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java @@ -0,0 +1,60 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.Hyperlinks; +import javafx.beans.value.ObservableValue; +import lombok.Value; + +public class ServiceOpenAction implements ActionProvider { + + @Override + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { + + @Override + public boolean isMajor(DataStoreEntryRef o) { + return true; + } + + @Override + public boolean canLinkTo() { + return true; + } + + @Override + public ActionProvider.Action createAction(DataStoreEntryRef store) { + return new Action(store.getStore()); + } + + @Override + public Class getApplicableClass() { + return AbstractServiceStore.class; + } + + @Override + public ObservableValue getName(DataStoreEntryRef store) { + return AppI18n.observable("openWebsite"); + } + + @Override + public String getIcon(DataStoreEntryRef store) { + return "mdi2s-search-web"; + } + }; + } + + @Value + static class Action implements ActionProvider.Action { + + AbstractServiceStore serviceStore; + + @Override + public void execute() throws Exception { + serviceStore.startSessionIfNeeded(); + var l = serviceStore.getSession().getLocalPort(); + Hyperlinks.open("http://localhost:" + l); + } + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/store/StorePauseAction.java b/ext/base/src/main/java/io/xpipe/ext/base/store/StorePauseAction.java index 27a2cf3c6..55c67c1c6 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/store/StorePauseAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/store/StorePauseAction.java @@ -11,8 +11,8 @@ import lombok.Value; public class StorePauseAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { @Override public ActionProvider.Action createAction(DataStoreEntryRef store) { @@ -24,11 +24,6 @@ public class StorePauseAction implements ActionProvider { return PauseableStore.class; } - @Override - public boolean isMajor(DataStoreEntryRef o) { - return true; - } - @Override public ObservableValue getName(DataStoreEntryRef store) { return AppI18n.observable("pause"); @@ -46,11 +41,6 @@ public class StorePauseAction implements ActionProvider { DataStoreEntryRef entry; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() throws Exception { entry.getStore().pause(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStartAction.java b/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStartAction.java index db645c63d..27afbe50e 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStartAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStartAction.java @@ -11,8 +11,8 @@ import lombok.Value; public class StoreStartAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { @Override public ActionProvider.Action createAction(DataStoreEntryRef store) { @@ -24,11 +24,6 @@ public class StoreStartAction implements ActionProvider { return StartableStore.class; } - @Override - public boolean isMajor(DataStoreEntryRef o) { - return true; - } - @Override public ObservableValue getName(DataStoreEntryRef store) { return AppI18n.observable("start"); @@ -46,11 +41,6 @@ public class StoreStartAction implements ActionProvider { DataStoreEntryRef entry; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() throws Exception { entry.getStore().start(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStopAction.java b/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStopAction.java index 1b8392ed8..899ea1d78 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStopAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/store/StoreStopAction.java @@ -11,8 +11,8 @@ import lombok.Value; public class StoreStopAction implements ActionProvider { @Override - public DataStoreCallSite getDataStoreCallSite() { - return new DataStoreCallSite() { + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { @Override public ActionProvider.Action createAction(DataStoreEntryRef store) { @@ -24,11 +24,6 @@ public class StoreStopAction implements ActionProvider { return StoppableStore.class; } - @Override - public boolean isMajor(DataStoreEntryRef o) { - return true; - } - @Override public ObservableValue getName(DataStoreEntryRef store) { return AppI18n.observable("stop"); @@ -46,11 +41,6 @@ public class StoreStopAction implements ActionProvider { DataStoreEntryRef entry; - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - @Override public void execute() throws Exception { entry.getStore().stop(); diff --git a/ext/base/src/main/java/module-info.java b/ext/base/src/main/java/module-info.java index 447e8f0ad..c5b541e9b 100644 --- a/ext/base/src/main/java/module-info.java +++ b/ext/base/src/main/java/module-info.java @@ -1,16 +1,17 @@ import io.xpipe.app.browser.action.BrowserAction; import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataStorageExtensionProvider; import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.ext.base.action.*; import io.xpipe.ext.base.browser.*; import io.xpipe.ext.base.desktop.DesktopApplicationStoreProvider; import io.xpipe.ext.base.desktop.DesktopCommandStoreProvider; import io.xpipe.ext.base.desktop.DesktopEnvironmentStoreProvider; +import io.xpipe.ext.base.script.RunScriptAction; +import io.xpipe.ext.base.script.ScriptDataStorageProvider; import io.xpipe.ext.base.script.ScriptGroupStoreProvider; import io.xpipe.ext.base.script.SimpleScriptStoreProvider; -import io.xpipe.ext.base.store.StorePauseAction; -import io.xpipe.ext.base.store.StoreStartAction; -import io.xpipe.ext.base.store.StoreStopAction; +import io.xpipe.ext.base.service.*; open module io.xpipe.ext.base { exports io.xpipe.ext.base; @@ -18,10 +19,12 @@ open module io.xpipe.ext.base { exports io.xpipe.ext.base.script; exports io.xpipe.ext.base.store; exports io.xpipe.ext.base.desktop; + exports io.xpipe.ext.base.service; requires java.desktop; requires io.xpipe.core; requires com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.annotation; requires java.net.http; requires static lombok; requires static javafx.controls; @@ -30,7 +33,7 @@ open module io.xpipe.ext.base { requires org.kordamp.ikonli.javafx; requires atlantafx.base; - provides BrowserAction with + provides BrowserAction with RunScriptAction, FollowLinkAction, BackAction, ForwardAction, @@ -55,22 +58,11 @@ open module io.xpipe.ext.base { UnzipAction, JavapAction, JarAction; - provides ActionProvider with - StoreStopAction, - StoreStartAction, - StorePauseAction, - CloneStoreAction, - RefreshStoreChildrenAction, - ScanAction, - LaunchAction, + provides ActionProvider with ServiceOpenAction, ServiceCopyUrlAction, + CloneStoreAction, RefreshChildrenStoreAction, LaunchStoreAction, XPipeUrlAction, - EditStoreAction, - DeleteStoreChildrenAction, - BrowseStoreAction; - provides DataStoreProvider with - SimpleScriptStoreProvider, - DesktopEnvironmentStoreProvider, - DesktopApplicationStoreProvider, - DesktopCommandStoreProvider, - ScriptGroupStoreProvider; + EditStoreAction, DeleteChildrenStoreAction, + BrowseStoreAction, ScanStoreAction; + provides DataStoreProvider with FixedServiceGroupStoreProvider, ServiceGroupStoreProvider, CustomServiceStoreProvider, MappedServiceStoreProvider, FixedServiceStoreProvider, SimpleScriptStoreProvider, DesktopEnvironmentStoreProvider, DesktopApplicationStoreProvider, DesktopCommandStoreProvider, ScriptGroupStoreProvider; + provides DataStorageExtensionProvider with ScriptDataStorageProvider; } diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-16-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-16-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..0c175e65980272b5111c8c6ec7a31cf781446d8c GIT binary patch literal 728 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 QRsaA107*qoM6N<$g3+)flmGw# literal 0 HcmV?d00001 diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-dark.svg b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-dark.svg new file mode 100644 index 000000000..cef212aae --- /dev/null +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon-dark.svg @@ -0,0 +1,127 @@ + + + + + + + ssh draft + + + + + ssh draft + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon.svg b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon.svg new file mode 100644 index 000000000..d838e9905 --- /dev/null +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/serviceGroup_icon.svg @@ -0,0 +1,130 @@ + + + + + + + ssh draft + + + + + ssh draft + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-16-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-16-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..9bfa541ef2ce69393b4089b3c523e9cdef7e3379 GIT binary patch literal 861 zcmV-j1ETziP)3M#QsrOl*P+v>)DWGaSy z%_OZc1r>^MQJP8S-}kPI&V-3~_1@*2doJ&sC;nGM=Y|T-*kOMPxn23C%DT8XyR#M8K8XYQ^Z7`HQtm^<62>0Gj;52$Pc>H^LyUmUnCFU|`hy_# z!qlFr>gt<~=iWmmXYiz%jhmPPovyp;;vF*IHxt{@dtc^|;4hyvzAb!Rcwk#;pdY}a zFF`v)U}K78u1T0RxYydgC3cVS9 z-TqpudC!`Fh)FXG0cT#%wY%O4epf?-5@%M)hL;8FyZP00{eq#Bf^U#zoaa?wK~ZVw zeaV*1D?xU|!Kj&SHR&DT3lcl4P>a*gRKDvTm>!Lh=kBmW4Z=8j zB-iq_p07Zsrbn;MH~^O1F=02%*x0cNATG{cGUs;4csw4dY;7h!k5MwSf2zGJ$JczO z?B#6w?&b8m68jB4c4lWR23M#QsrOl*P+v>)DWGaSy z%_OZc1r>^MQJP8S-}kPI&V-3~_1@*2doJ&sC;nGM=Y|T-*kOMPxn23C%DT8XyR#M8K8XYQ^Z7`HQtm^<62>0Gj;52$Pc>H^LyUmUnCFU|`hy_# z!qlFr>gt<~=iWmmXYiz%jhmPPovyp;;vF*IHxt{@dtc^|;4hyvzAb!Rcwk#;pdY}a zFF`v)U}K78u1T0RxYydgC3cVS9 z-TqpudC!`Fh)FXG0cT#%wY%O4epf?-5@%M)hL;8FyZP00{eq#Bf^U#zoaa?wK~ZVw zeaV*1D?xU|!Kj&SHR&DT3lcl4P>a*gRKDvTm>!Lh=kBmW4Z=8j zB-iq_p07Zsrbn;MH~^O1F=02%*x0cNATG{cGUs;4csw4dY;7h!k5MwSf2zGJ$JczO z?B#6w?&b8m68jB4c4lWR2=^WA9+5h_85PzWgs z&Rk|71Pp{NDxz(t6%#}(1YAf%#JJ!Rqec@j{(u-QXb=oh69j20iDKFrKxGL_n`WplW|E{o5bGdR8NNQQnG_#y{;v5D5F`sInEP?~~I}a`>@7 zS^?a!8#Jmv0T&#S(^7r&uFB2iLKO)DQ%Ls(;JU&^fzhg39xY8&-zM@OZvzENVP=TTG4bM>Xv0#Ip)mEdE;m5F~XPr~OPOK-{9*4#RLXNn4l|Hi0OX<0YE)Z5ADvP? zye~kY*87?wYt!HWdP%IV0A^`NUXAY;-#ys~RGbY!PNz8Y4Z?JwIZ_%q3bG4iKx@B# z(LmVSVvSUG^+^%ljRfO!8%q^=1;Xw|f5^8jQ0ps8odvKXxQP-OE~2RPN2@Zg~9U zWzf5OxQsDONI#Jav>V_&A|tv|+m#K-D0{OK3o208QwnNlJY9{0m4U!@1H^#$7 zFCxW>-T7^8lM&VeLj@BGguGYt@U;3v?!JjX-*1!c3K6@rfZ$(PtFI!|P$XP|YKy`Y1XYQszjc@AsAI1*=U^&Jg@=rsh9A!(aICjwh z}4V$J+M+48W0K z(`C>XK}G;ginL~JXwt4l_^s=>Cn@SfwM5}n6;_~}QjtOtmK=NH_yx#ZIAQm7R6hZZ zqR!&<=cBhxsUF_??Fso&lW+i~$Cd{)=b<8W7oIg{oL_tk+O<+do@?{?bih R6~h1k002ovPDHLkV1m7)WDx)W literal 0 HcmV?d00001 diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-24.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-24.png new file mode 100644 index 0000000000000000000000000000000000000000..74eeff8a11804d89f22cee968fdd74a35f2f0029 GIT binary patch literal 1359 zcmV-V1+e;wP)=^WA9+5h_85PzWgs z&Rk|71Pp{NDxz(t6%#}(1YAf%#JJ!Rqec@j{(u-QXb=oh69j20iDKFrKxGL_n`WplW|E{o5bGdR8NNQQnG_#y{;v5D5F`sInEP?~~I}a`>@7 zS^?a!8#Jmv0T&#S(^7r&uFB2iLKO)DQ%Ls(;JU&^fzhg39xY8&-zM@OZvzENVP=TTG4bM>Xv0#Ip)mEdE;m5F~XPr~OPOK-{9*4#RLXNn4l|Hi0OX<0YE)Z5ADvP? zye~kY*87?wYt!HWdP%IV0A^`NUXAY;-#ys~RGbY!PNz8Y4Z?JwIZ_%q3bG4iKx@B# z(LmVSVvSUG^+^%ljRfO!8%q^=1;Xw|f5^8jQ0ps8odvKXxQP-OE~2RPN2@Zg~9U zWzf5OxQsDONI#Jav>V_&A|tv|+m#K-D0{OK3o208QwnNlJY9{0m4U!@1H^#$7 zFCxW>-T7^8lM&VeLj@BGguGYt@U;3v?!JjX-*1!c3K6@rfZ$(PtFI!|P$XP|YKy`Y1XYQszjc@AsAI1*=U^&Jg@=rsh9A!(aICjwh z}4V$J+M+48W0K z(`C>XK}G;ginL~JXwt4l_^s=>Cn@SfwM5}n6;_~}QjtOtmK=NH_yx#ZIAQm7R6hZZ zqR!&<=cBhxsUF_??Fso&lW+i~$Cd{)=b<8W7oIg{oL_tk+O<+do@?{?bih R6~h1k002ovPDHLkV1m7)WDx)W literal 0 HcmV?d00001 diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-40-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon-40-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fcf4083c21d94a076e8f37e3127254e79720f6e9 GIT binary patch literal 2454 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 + + + + + + ssh draft + + + + ssh draft + + + + + + + + + + + + + + + + diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon.svg b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon.svg new file mode 100644 index 000000000..f13ea71fe --- /dev/null +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/service_icon.svg @@ -0,0 +1,100 @@ + + + + + + + ssh draft + + + + ssh draft + + + + + + + + + + + + + + + + diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/apt_update.sh b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/apt_update.sh new file mode 100644 index 000000000..3e5dd7717 --- /dev/null +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/apt_update.sh @@ -0,0 +1 @@ +sudo apt update \ No newline at end of file diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/crlf_to_lf.sh b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/crlf_to_lf.sh new file mode 100644 index 000000000..585611c9f --- /dev/null +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/crlf_to_lf.sh @@ -0,0 +1,8 @@ +for arg in "$@" +do + file="$arg" + temp_file=$(mktemp) + awk '{ sub("\r$", ""); print }' "$file" > "$temp_file" + cat "$temp_file" > "$file" + rm "$temp_file" +done diff --git a/gradle/gradle_scripts/atlantafx-base-2.0.2.jar b/gradle/gradle_scripts/atlantafx-base-2.0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..6cb3a389a76c45094d88c05e69980b2ffb9014f8 GIT binary patch literal 710112 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%0A6OJJ$OO+*N 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%0A1j$C?8Nh|%$!4YBHnKvsW$v>3jb+t5Y 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 z z7hVP4TueT@j+y-K!|HA#2;_0{?c?DlgkRi`VDdfC&K@|g2h)Gb!>D_;mB}|Bpvg}P zg1?*P?}^(bB(}40^1J5hm%pC!?F(%3I|YHk<;#ipx4%6CkCWfN-3VCzDbIlq@csSw z6Q!?Opy~aq_4=aC)2p~W-JW~%eV2gsPyYM~@JT-3P5_EGdroP+1c4c-;^rFB{O(O} z3TAws11}St)%}H^m0+2maU=Gbd%h)Pu15=oz6Uoy%>M44h{P?u|$Fe71J@4oHu8QNUo*UB6 zPbUB2wx}DA3UIOCyJh+ir!FmkzP_*jgE9L22HZFJ&}Z*~xu~xy@Uxpq`sPl}Z9;eQ z`R(v0Ujr`+9KiK#zrERk;I1ZriqfX--oJ#t^}xKqZvY7p5hlP9xCU0)vmUxOu3G4N z6|SQ2!)tus2OGS3CqU@Ih5jxKfGX;$_t)Q(&u_Uiu((?a?e4#Pe{Vcl@;~02bzXHZ z(o?{xxxslDhh=b2NZju5Ju3gxTjlVaK>JNs)sxSz44Qm%n{dBu|8yt!;lhLSNQ0}$ zhwbDa@10Lq|7F)7KjfuAaL^`KB@C|Vr_*$=(p;a26#smGkDG(W)tCTXanO}>-S+avt= z35MX;(YJY55^rCH0}J`ICh9)p?GWNkn|#xrO@4Yv5@5&^Cmv86Hfh-2S@qi&2YpYp zyru&`O}Z-OCpv%siq5U)M(h*#?G%4^A99oFCmMh7PTtkCeT_a&?%wxEcHYO`2>sW; zCfR(AP27BWjcLM{Ii)W(&bYcOlmGZCys59Ve`YU0!zf{wR6q%=)qiJgR_1;wtqbnj z2eSX=lVcWu2R*n0fQ2ve8IRoozwf(yTDtig_9X)ryUoY@`ua-du5f;8JD^H{L3{yS zA73;1v5Y!>q*cJfL%;m^-1E>Me|Q7j&-tfY`z_57sHLk)!!qJpmEmyAg=q&4krJyIzy^FIx|0 zeD`SGdG*uF*8Ap~^Z5QT2?T>3c-2p@Xk4}HBS%}h_0?3=>G?|a;UpeU;FbV}za;Vg z9&}H>S~8Ytip+ZQ-OVX@8vX5u;Pd>lahd!cm`C8pKNa%8g{We1yw7XByG*wW28?+0 z#LBDvdw;WkKR%T@p1QtyvC*Gi5PG;ge|P}_j$Z>vz@#6ZUvNK+H!0}zHCb_U9KeN%O z1jpaq-Jte;a=nS)&DG6DRUUo6znw?z-uPF$-PIC*RP4KZIoK!llx4{OJ@fyc{)dx3 zj{>)I|Mm8cXxgtOx7AQg8VL-f@Vc7VF+KiR3<> zz`Z?l|FamTp)gNuw95l_o;tgr_6~45o1La&I$&A*S5FY!nR4Jq7ai{%n&SF zTFm&&L#15gleNXp7aj(l7uHE(k%O|Z&*H*{mJj6qGQKEMJ@F8xt1=!;f{dqecXZhhZl4?XTLu9MGp3m_g*@`I7^$fcTykhby`ft4?F<- z+*mLz76}{(3@KmelYeCU_HC+WN;F{l+SJHwo+?k;J7uPYB@VjWQsAfxeS#~)lE zFIW67D^L70av&?Hvon@{L3g5XKUcNLPd;WOUa`(i3&_p&4zWb-?sO8!JFWo!tw()W zkK(XC#Ajs_V~XW06u{Hk7Pp_(X+Fg@W-PF%r5Z<>R^(J8vPD@~4@746HX8-s*jIa(td`u*6Z^EXs$pQpb5Xyaf1no8?0%>4n( z^{RVn{#uy%?p1d4^Lt+N2W1BQ&-|7MeNT*&uRth#&xH)v%rya=WEmlVzx3aLUI%QqY$?%wpfryHO*y4R$#;F)bSDslN7uB-Pkx@(br`(N{k2ILK0Ng+ zwfp&earG~+Nt`+deou1$X5$+_sZu|@z5d&(4$J4H^24Ql;qct^%w-jX&k62FlIZH$ zJ#xygx}Q=+*Z!}&CJgTzxIf;20w%zPg3*x5%rxdER&Hh=pZ=IXaj{`i5> zF9&{iBM1EX>$gd-_v*!OwiLgwg5bG&8l>&DhbE|brL zumo4-%j5 z56U|j{7pben7@0E{Y<>WK}7hEZ3SZAM=iYS+86Tt!|SfeHy_#$sct5Jx+OXj;MhN0 z{`N_d|Nd>y!@d69qt%4h_1$CbCoE{(_-PA2Jg}z%;%^whq%Yf3eXAS(CIWHO*K76P z1&#^m#E2;FS*ci^)JPVmaB;IW&@cfgo*&-d^T&-sFvvh|1OTJTHsA76}pBej3H z0UreGcG)LCUu#7q(0)KQ-jpPQ-IN@fUv(b!?ymTNlB9C-JqdJfcm@jLng#xgf{=HG zdL4m2Cf;b=sF7D)O@d#ydAEA?HN9{Rtf}W@ZsyMR~1Ku67VeogV8;L0N_1>0f4x+F|eU)CFGVu ze=1wuL(zwh`SCRvKNnwLj(S!b|L|t?bH`6Fw*0UOPwL>-^Fkfm+xNHs<4ddn2cEpY zgl_Y)eEqg7dP6C2Z?)(@eT+SdCjaz_o{!Y-b7%AkQqeDxda1#G|FUxk!|b}OkHHs( zq8r#%j~#ph1!MpG60Lx{)jXI1`u_N`&rg~PTx9_N_<~zEyN)9^Y=FazRL0ke*(TIj$^0bgp>dP<&*MM8ZGQ6A)5|7bbya=8&EMYBAy18KiS?mJe*l_p zaDf~8)UKPbPb*-ZZrqrBQ{KKHy*+<>&w)KWgZqVl^=ZWqK?sz4{;Z_`c>iYYYU_X| z1Cnt2ux0Y))A;WmmgY+E@jdX+ToZfO?f&#s$NFG0zI|Dz{yYTEA8?DnZkxyF4UZZB z;m?0#E@W}bQVc9(U;X_((-*=ue9(9KLPzG34lA)GNWD|!tpj2LlR<;L3@nSzb_oU1 z>lvnVAQqP*-3{X`h7X;{>xPk91!FO*Wx_hB!EBfOoU6BmVGRr~Bp2ym7`hzeQi=@a zh2s~?VaszyxDO7?R+^D8LeZo<^#cc^%d(>*$AM@XnN^IXUD&xI!8>NjtXI6vtFva< z4kkzS96g9O$8hS75g2^u6mu@Z4Mw)6GE5gvQJIQ6(kJ{BFU=WxxlAqA8IhizW~PYg z7k$YvHIHm;DoX7=p|31!rt!;-Je?~IoSWGtIdB*L$Vt_4NO8*SJz)Ha^fbFT>0UaS z$uck1r8mH3b(vXf(v`yH;lP;5UW#*k86F}g$os7!74agcFNY00P5lkvJul_asQN{< zyGTlAS<8@=s90oJX~U`B`Ld{bLfxeyBcz1`nX9>&OZL$=5F)9G@E|&Ub8Zohun%05 zE9*6GC-_F0!X0x_m3hcCD6}(lF5m4?$CZSxF~)ATEq6q5AbPrtgp$}yH<%dq-Ig-F zb|i@TK_VOs9ovS5Xg*$`5`XjrPlfWW#dJ$}sjK^>;ikRFEG~1Mg|T`Zh01C7wanr1 zP_lU6&X(tqap*=)`)WNsMR74*^|(#YL@CeuZl{v=UcLD1(q^QBF;q)tem+J zB2(ndT$biq7c*?eol%BIW3(Q?Eu4oP!)+=N^%=*X^AWSyGx9>53p#UL4puub0XcW| zl%?j(w#t^rZ0=?YB4?3=@pf@S=rFIVbA55PR4JRYrmmH`bd2p)r5-D5t!t5f2~IU}D_1 zU^SaR4f%{)pi7}u&x3lV7zaSWJePJ`k1!9ppjs~BX)7!CSY^4u6-0Du`?3LNq8z3QOf;p2Q&Vq!r0abT zQ7dOptP1=XNfua>yJei6cFfLOkG3qtL64qWYsg}Ll&&8lcli;btNVPEE^;`^Yuh2$YD?jpy(6A>V=(WK3ua*f zyMfz&$I?-Q2z|97jFLp7TBd~_>86)TI589X}dlC_W7MHjuDLKknQ=sulbsnF{)3>6G?C7-w` zunZD9BqwEdKB$TyVQtw4YpJH8VCUoY7-MQRvg*m^w$KbaTAsHv zNpLR5C^9kYB;e4PvM22%AJ%@}Xf0Z<5W+3xktFp!#XG)Ph08M)VCTg&H8l1ZZk47t zqSHRg=j(8D!lPMsik2%VTvJ;NccP0imqMV;?&kP5)xaElo;6Im6fn| zoaSU7dP1SCRFR}MkC9An(c=Xx0>N>nE6X1YqTgi2$v9okm_$(}P|(|Ay$=uvoZYnY zsA01|xdYiHfqUAoPsFASg28JN+M6{86plUX;804pyx>T_r0G-I%`D5E8?8*luB`P$ z>#!$FGH?&>#=KQMW!v(*vBP%m*z6iFzeph*ZPN?1THzU$W0KrpNKS93WiV^0BZWDI|65JP*-;J>fjs5&n3o`W1FUqP7QiZiijHs6ul@2v&~irMHf~ zn?>6iI%Xs=I|rgE`mmmL5E`IurZcsrF~T8lkb7aMXaw2x7BYs_n$XdqLd|m{9DG0Mr{Mz8v37HW za$O-+0%CMr+>~d$jc@^i!o^~ALc6Aqr>vYhQ?%>mAi6mwNH^|M&&}3FKHCU=MB0l@ zX<({g!qZ|(Q?xjug>xJ)MIeuapz_YeQym(MdWk((`*VtC`(&*5!Ga_^bz_z;IW*l& zj-9aI_e;V*mR=wA)Yb_bhs25frlZR}O3!SMJ_L4nBFNnyIzw()ATt!D$vrzx9q-WC zBsAY+C6r?`nVzAi63Y)g6f6f-p7+g3Ziv|wnfY3n(^!ugb28KRzz~Ip1MOJ>#bMhS)`i4d5qJf~yf1-p(tqX~FXvjB8AlW5Rtw)CR!b!C%dR@IiD+yM4XIoZNAj`- zHzaJOr}^<{9&r|`Om?;HRt;&*clF%V-CQ%Jlvr6Q8TTv0mw+Z`B1KuESc3H)2&#P2 zQKlW;#e%14Cf|Bc0PQ@r)U;W-$wqb58f>k>2(#7*QQ)}gP7P!Nr*^W3tT)z}uj+19 zq}5U6Ljzdh*(mDl${^Wxm(DOzJ^S6RG~fZZ*McLQ*b5GE`jQ<_(dZ2e>p0AV4%^gl zZXm(lB6F)Ew3s;#+(OYUGED74nyH7%l|iJpJ`4DTqvm7Kp^XtMaht+xEWmV;fd-!3 zUfhitM0?~CHpgRA5dOAZpE{;qFoPm3_=`3i3Tr%}UUIe}h|0M+zK?aCKNjE(1Wjp& zQ*L(qI;q@cF2>3h@|1nS1i-SKiS+`q=H8C(LQkas=>{#+auCl2n-m8DaLQN z=PDb= zLrBkR?PNQ^6Fk)TIQj=?##>Rj%ekJAT9Z|GzUcaz;PfB6t1jzM$@Dv;|vy_xk~Kpsw`Y~ zX)($(B=F`y;~` z*;?@(PbZFWTjb_Js!$;Q*lHRcBhT{u94$5?7c2V(d5X#dWDTMv^HXn+1Utki)No$T zrZjmv?RZJ!F2g+SeEz_QrXDY(E^efQxo8e^;{qI`1O)3kw&l!@gOx#+dbOO-O2T3g zEEA`Uao(dUyO7#NLQa>=X6>^|veXr(-f^>HzJR-#Ui&F8?Tk1rYHzy7_g0_^=QSUj zBRL8bvQ#f*z0k~Je(_6rddzptsz7T(G-#lir{`#WEIBV(_i7O@wv3sk!KSJDH64i- z4qtS5D=Y-DGSSpX7w46p*{qMtV>-G{D)M&97V#l53T}~LvwZLtD#F(1IW{|^M1A12 zYF^Qb8n2IMpALm&Kg7Xh8a@7TEZjf~)>lgtSgj-#@{ z$%?V`kZlIV17r1pV53r6aHe~r&QM5Nfz+EG!pyl~TIYF^@RJ38bcrkSR3Ub|@xn68h&pa#Ryn!$blR*1_UQWOJl-9MWwySYN8PWu zV!v7718~Yj&70NOAwb3{DVfZcS{!}HLAq7SCNg|NWOaQZF-NNAKvmdzY9U6xp$~I~ zjI=4muJbL@9fSj2v6~!aowJyd=Iku$*riC$T7Jf4RoK8YJSL-4*q^kPak+u7BX^h@ z7d>n7J!R2xF;4;e4^Fy}#p=u);w9#nh3MG?jTiZ4x(Y~F=j4GzM9yOOa}MYD*_tzB z^i*?oH>%m1G1humEz%tbV$P!ri%MRl>!peYp*=8I-tJ`t_xnzn&XVRL^v()0_s4Kl zN*3tz{d!iL(Xg?(wwUQN+OFXlt#pW2BI7zd!W-SzBcQ{2i>xwtqYi<+@NjwFp~}JB zUAk#*U9|nuauJ~VhjSn4>V`=Vj8x2BcAx3njnpz&s_OIArgI6mCZu)5Aal1>ivbnvrkp%nCv_(c1*!e zad|nw0Swy%-tF~S-rEAUZGpw2wmS%zY(t_B(yoq2jdxsep>Nuf#kPtr7OtEzbnC5? zG7cBUD&bkCifb-S9KqiAMjr0`fJHB9r9g<0<;32Xtocg0h=)UC-~(fq7E_aWT&zlr zqBxIN*KloGyBg=DId>wb{L)f`Gjoa?BMH4RU7eQ z0iXQ?2!mU5EiI_^YDQ%Hb6eIPBTH*wo{w#^Ul~y&l49KI-bzw4-afA`J=fNpA|!3J z+w%$$8T*`=?w0lOIG1^{%n*a^mdSG4QLsJFRd$sC_hjqy1`qWtD={L8n>t-hiG7>k zy}{)3tml%Fr0Eu?*73?d^B6Xxr+d$2+@4;NVr!O}&+fM3SytyP7H_nL-_|UHsZn)Q zS<56h_NEVayMU~MGnpDl+HyvlsVE#k_L-^Ug@L=vq!o2ab7L+J1}PSfxzRe3#eonn zVoYEJYg3!GM?$w&3$rOv?x6UM+8|JNWa)sd>h(D-=6FPFs>fLSt`t&D$GTY)8-A7F#Ih#9*kH{zLNSvY6x9j>dK!|J>$ zNEdL|gtD&6mCuhf8Cr<0TcbXby||O=IkPxHF^15QJs@0Y(xVqn`+P-7$9W}Tu`UmK zlAXQFk)>D>I93{AS*^qejK0?yi9i&*>QrEJmn}QhK!kcE(J#1PXooqVVl%)3eK>C+?UV= zzkV5ZQkYYx)0xp6&mo~rr-chGPplAdVKBPW9VX`~7OnBiZal~Hb;~p%ItxzKc56cZ zC=&<-L0Z{b(PA45p|ynSGqu^^ha4}D!Xl{7?4s}S%XnDt!yy<50y4Ww5!d~ex)_Y+ z9ye1jZ)y{rk*v537qkF^K(c7*m96$5I)$0wv{>b4OBVEUk;CMypQ=8c?7^}LnPoEI zpDUcHn=vF{Oh9G4B%|%&EamF7uUVcUJWKCSED`mG^ITTU?0izA_PmN&j$lHJnIYYN z1D`dN@1`@S(Pq#-+ABMeTP|>X&x^Ymseu>pB6EQ_jaxdx=m;h|Gt2Q<7o*+68~23E zC&qE7+l^11Ahc96 zLXfcwzsGQII=c+aJg?>pyIwMK7&dblb}r=#2_tpuz?#w$GvEwTv!oMz5I@f7E+s*5 zS%JmM+cuIVhQFqYXM=b|Tsqu!xUb{0y$n$SNib|kSoI;@8M;)?`k*)&9+Ci4whTIQ zZ!V8?)DyEsdQiA3rRc?B1QAWf%#B=y7B-bsYXroS2dS(tHr5k!98Xl;yGYBO!0kxs zTF4D|j0?$4P zBXV2ohk}L(Iv^lBljhTqX694W#_5fkQfz%1t>ad^i03IY8&<|zb(UP?JILWuM#7mY zWj@s9B-1SkB81+y`m9RyHno|GSfAMj-vv9Y;7&VF%tlXXqB)C7IW-TfX#mk- z*FaN^qSxY7_lIsERVlF71PG@ue#-G%lsauB9$HAHzOd3{-VAzUCYrr$4#x@~m%{?x zLd*R&Aw=SY&b&^e1!zNcnikEcRJ)imt5%JUP(XFDd#h}6IlsxwlU}gwpZ}jdL=&!ZWUu&bk)<%D=js992{k1mwKS^y=va%1g(H(m6jk5)v zrXDGz!Fk4~>dZ9MEu$wjze~ux!xuVb9QD<4&ctEHR7b;=Q)bU?3`buc4|aVtkNokN z9^-|lGbvOZGd-#fsVdL7z%TihOubm;i6|%$r=cUXDI<)S_Ud%84kgT?Hx{e!A~b}2 z$SawUFyE}$FcCySk20EL%Skbd$Yg| z$(}+HLPvWQIN-gAL@js{~#UIPS(Pr02`MZVp5qEwXOP zU-I=)vGh})&K%S^=x{x*Lwgw$jb=pDftzCx;$|z&@iYfV(`bep&1!X#L4XlV^E?N# z0O{6pzNpb~>Fmy{8MP0xW}uZhCDaQs+4_SVIu`Jm^G-Hl{3P=!3>|F|nIhRG?mdjg zXNzz$=L^~*VpG4A zMv5})vpTg9ELB5y6pwpA%R{#{OIt@U%T{c{5>CcDX4ayKLbYEdyQh zfRgv`N$nsV6a zX+0M#G~6U0@-o1+mVnNY?85=#6`Qb2XP>Pu9#iXh7_#0Ts+Fiu+YvU1sjyrlS;}gO zVYWQ6*yv=n$&}5S8pWVL%?GGNqhXPp{5`uh&&F=EoVT8O7SNf~t!8s!p3H2qKznt? zaI!&Cm9{|6I#Nrs-i$?@umUD1s|#ETbFvtNo(H}eYtj@v6#JEX5p}-vb|XeYhO-k& zEgt+H?>ylAZ;GK3S~iKc);fmVemS<{Dk3uLOzTTKMJ^i@-?vAcmk{Ii73D>mQ0#hA1cl?}D+v$AS(x6MIxIlwFXeysdN7=2{Rl3cDSsbtnf4-v) zldssZpVPK@yyWNUTs{{wX}9*Ha)VRjuCF@`)6{96COb=_6chKMNEK58*(@%DVb18h zvSB{o#QkAwY{&(*G8L4PG*jHMC^haahL{^lC!bvm1kOQ42}`NR%19Nr;3} zTe1AXlve?n2|Op-d%34oxKj*p9W@)tI=xRILUmC|T<-GP?d?q75((}MN4S)nP9kxp zASxv9x91oH%Gu@^(9yKIl<8EOsj*;Yq!b@@7AY4O&6N_CmFuNZa;47|VS>wNSR00d zYfd8)0bQ>O9A^VLk>Fw8kk0MFXgv?v;ggVtiDioeQS9#ep%{9eT`gyYE?R zZP1VzSCt?LjOt~{Fy^tgELN>ZE~SV-jq{Qz_v609yc4!i6(|9O7q!}*aD~ZRqzvUT z_xz$@wkbC-NW4rN0Y9+*u7j{DuXYQoG^Nb9l+@DpjuiVPFlI0&?tn&{iV|@~Xna`D z{Qd-SQNhh)-&>v!Fawpl6NEVDk_k~$4qT(9h_M%!CkB>?mb|blj%ZjfsdIV-t%qI` zx4j|f+;CtJSspuJ^v!wX6QcyG!^yP1d#WsPI6Rg`0G`76ntzt0QBRiVMbYRFdHy3jTSC^z-)tNYNswTR6^puMyF3NVR+ILs zJPTvdKr6=|ynIev^_73cDbqY$Lc-e%De)P(Kl{-T4L#Pi!15;g{`J$Vo0RC9*cNA1 zoSWA4%6w@q=fibQy$XmSpEW@WXrXp55>}a3l|W%_m?@6CFPjmG61%si5Aw)N0NSeP zqvZ05QjTKR3n{_#Sf9Z+7`nJdFwoogkn1JQO?+O80m&&9 zGkkkMe<5YXzvKSCYw3`Kd+XKRK*@5RKjPIi^6w^U{?+ptMpqgU#X$`IirbaJv? zv1zT=xo9zEb+?pX6iip}I~ZUl^^iO4(!x^W@c;N;e*N?PVkdaH?z_?etTet-9at*~ ztdsuKOL%W10{&kEU)EL9kj$5=IlG(t`HazG;>g}+IVgBt)jKJCdu3qr6l~KR8YOhF zB{>GGO*qyatc2shd}U1w>q0Q+=~@OJ_TtfOtF_v*%CVTizdKevn{0xvWnO2_RrF%S zt5fXN)kwGzA;_XcFdOMyOP(yyw^!MvfOmnP%XWfr#nu=KmX4`C-AKA&j!XR1e5Q`t z3LSckk zP@!2KG-s!hhFxyI_B#6Hg17%|^5nOp0Wk$9TlCS(p2W-}6%T>IQG zM1}dO##V>dD+GpRb7?YJiv0PuZ)Se(39}%8;gI}L$~$FnW6NS1wq@sP%o0Ed;t%~E zp{+5pXPh2&LMv-^8u7ds8G3zdlCwj=F)_GqniiXk_UZbhiMZpC|WR`fAG`PSA z(k3)W^eRO@$YYkF933GpNaSa;?(mhr+Z zcBL*NB5}_m{D04C=<1r)62eXFm1Nb{d&Y*TZYY?h)V!nVl)DUh zUfNEi`X>RT_laII3a!>JY_-~6dkZa@H56Dae0;SVHm5=NPruAEiS;7T4I*Z7I4!#P zR&nod5nF^i%`%N@r6~NPB6{l1X%NOeA90(q6qe0tL*k`$CLFZ3`N@M*PfdHwY{_r7 zAoO4~g=)P3!Q9Cm&$Y8vyE5mB&RnN`SGC;sSettxWIO%i>$mk6jFcipw;-AbpbC3n zcMPp1CyEfOI!@2hj{;j5WI0nnQce5LwKYUz%qWPcZ=x zK*@G|NeXB0Hq)MT=}+G#G$e0&W$BoLsqOw;S^6fNUc&+9N1+W9p0bWOftmJRXR8OQ z_>4wR13yyR>>3uQU7%Ue6j{M4t=DdPg@t4@P-Ub{yDb(q3`yQ3Le{k>t@q2u{qK#| zv>;js_s^fDJ)OVuEI^6f-zY2|gC|?l6HLj6i=)GBy9{qA+8mBFyEh9DQwd4|e#Q8e z;|;c;Ipdz~sY-v>D%xQ+Ws4@!9GoSF*TPRrtr7@`#SI4TWgUuIPvZtT)rmYHkUKJb zIM>%>%EsNiT%=~3$cL9oL}rxgupL}i=!j#`hde#q{Ced0ZMya`Wc({#$&AuQ%G3@` zMoCY}#KE-maDBJXH^=5phqsL=vUoMB4{FIv@E|@!4F3#I!(_odWM$lpfjV9O)Ex%+ zn#vJrrh^SgtSV@{Ib6bmnZaYM{o*|l7l7BMRXDEb!?mH%4(sGIU2&DN8VR-SrI~Ss zr|A^%qy+mTAXzO?SRpoATbIQSgF|lB*r7#>f^ON;Xu#F4#Oa$@6S-n#S#E_3d0az2 zKuhT^?yG9yu1MuaLd4BRIf@)ddWUt$BK!a^?E)Z*HjT~GX18l_OEO=HBK(ysq?_a(z`Z{m}ogX8-Sx*cLq7! z1>V`mv(I3vvwCi&C7aq`j#i5rZYuQ~@-wtrPZ9#jJf zF7^C&>VEKqXXaM*I5Awj7BBdg2QHNH{i0}A)wmB(*N_)J%&yJfC=yI+v!do1fREBqDOzu0?l=wl+=ZU6x8|`A0zF$PBWu?v!!hNZEo|e z{u&@w1nhdKsYirrq^+?L{57^>lGAj7y<@1oSc;55NZ7OtN!-#ze`I# z-I`+vys5j}sPE-+wMM(aNK^YlJodD6Y@5!zoq!!TM`*e6i3=Q4o`Q3K(i?kCel4wR zA#VM=y`E|8hFx9uYAHte_^#A^@8a5Q;Vd)9m_=H!=BIrgSN>P?9-&8Tjik0+)jFM1 zHg?`_FRK>Z6N8{Nze5glY7JJvIM(k@xbiHudOSEN@Y_rwM^7iKGrH+hBNvys7Mo`e zJ@ub*QACiJhvB>#?iO6WeXBoRcCnq$ySZLg%D0aaE`WQs9XLvz4(+FJD+GdRvA`M6 zgaLv&e(*XAS90q~9KW1+_f}jlDeapF*9A;ZPS-1X{4ZK{Y8AU#2>hSw#{Yz_#u({_Re-o*Z1R}t;}-B)3jlvTZS)^eOC{mVV+uy zMSK2BfSe8{oKO9JA2-YC%d1Vf+lw-p)$QdTuI{g9YL*sD9b~?mH^8=(H=Uqi3lsJX zr}D;biQ$(k)skygx^?o6nXiM@s*|35gu|GKg`3bVi+#JCgY@9qgJZb3R*N8j{?vXm zlyr@CQ@pCZ1#j9n&v0I$Y;$H5>#ARg8lAm9T|FtHvLlP8f<0|jO0YFM0Z-AB@eyYZ|i?52SYR%Mlkc=bU z%2XKF`*Um1cVwf3R%F&-pZ)B>bau9`l`A`Lu)6EO*~9C#xc%${XVu`xX;Mv{OxVG^ z6E~-EPL5yI+Q;v7jklh0S%3XuM!jfI!`HW~HrK=EWL(FnW5rgl)}h0Y?&bzOSW??Q zZVS(Fr5(w3pxU8h++b_!1;{zka12`o^qqO))&aX(gE$Rz^a}Y?Oznia(Ab@3M!D?p z-Jm)e9Bwh-V*`yhj%hsj-^^^?x)T9XSh1i{)T%ObY35x=%@um=-cxIXw%Pgc5dJ?U zitK76d-ArbOH%YZUhC}Mn=7{M6tc9nM%?UhKh0QLTP=S0^bz%0GU~@{uJM&^MOsFt z4=0=QHlg0GR4Zk;0QzN=quqRzh0Z6feFL|iBFi(%E1I#^-F;nVZ|xx=o0)3I< zw#HymJ3}}BTKZyjM@9~Poz4bJ2j1OEOxCr6pU|#HJtOZrRyjkx?;MH(C19Orq0wDI ztA^AH$P7jPtE#qV<$=pyNtu>VLD}cX4a$xG6zJfHSKU;088=T9&m5KA&wCZKYWdhY zLtif8=es30U$WFM$7~e`aqUqtaLd)BRc=?N(#l25h~;uVRFGP&*#dd1GPN8rQqYBO zt`r&N(lQy#*K=j~|8obCT^aTtgf{M_aX3bD54~us=d}v{OO+9eEs9m0H^7EF#+$F~$2Cz!b4Wj6g*IH29!D!#a&#b=Q}rr2o1u3BX*?9d1kGbYEj6ZEyhSWm8u-XFKFyC(LW$;$xg_Rf`s1_#QI8u~V1OqZc7 z#!;ZQAdv@_9=^P!vRw=lP6zbmmkleY!^UIVQQk&(RV6c5Pgk45ULqVbG`AqIOKtkd zuo0I$qRM8E=q`0BXDIFRNP#1}UavgHFlT$wo%gct_q!ZrYHkb!nPN^yPpeuSKH_`u zX5OO}{0|NOY~#B*Nk9D9bd~ny=C<9UT9>-!g`5Wd^D8bl^D-`DLn9rymu^JAM*fUB zth}pf(-y(zwndtA@^r=fU434o*-X8&s>=PoEhP`_+IN34?M*!n=I#{r*vy4z(F(NY;LaP6hf-wK&?34~3*?KPcpy23=?N9GDpX z#_U#g#i`#RZ1o`dzMtsAl^4U$(pE^{>9BM8+xg5JSk+uMRb)>G{_So_k@@u*ujspX z$DAF{+2RMF+Lg!Y*a7%5<$*^vXWQ+``JvaMDRtQF|FSjofFc0qj%c}!mVZ#`FKlMf zrP@f-{W~;;8*?_7bgJaM+0|JP#AL!+6PE{$-F62tB{7}DpUuc6Js)7}x&5dYG}kMb zI~|^GdsJ9k%DZwm12i;X?!ZC0?)4Vj)|XpGRXA{;rtb!h`;Q(N%IRa#4LxZzU^QB0 zq~K1ksCD7H`nmncWlfdq2#Czz)pePB;wsVfGU4nZaQ)XnFJLTl7R&#(E-T^`GlGBV0-QJy&63lE0z9qRaKnz)_!9Lcwcot>p)ig%Vis2`D{&U;qW;l;Fp0dT^5T4 zzo+_q0m~S-;hY7BvN8zXkiGftT8{EsSWSH=Z%*A+#)$s&TR7<|tA}sHqeCrY zgO*qbZCF{NE@C|opWv~TZ`W3SelxE>*SQrF#!o)}X`m5rHvq`&t1kE==2CMQ*Z!fk zZndMykxno>8?kCtv#I~&;f9prWEHD*lioPj@rV#F5g}YDAU!Q!|NamTu+Byv30A_j2V^7N|UssJlE5SDJw^V z=Xmg+w^U?y)PfswuG%)JSx{27-)quf&z?=X&0Pi*S?*PL8}h1a8yh=$u7}}z`A-^D zrZ%%PExY$=%q!)bVU@RJJ!`EU#@9vovH##z-fU+z)Sb}k+tsk1wazkbgx*owN|%_T zj9qL>YL;{(wO;A4F|x6Wd#LSc#C88Wh1=&6FtzTk(fn22gHb!PVsIg6vY4&sj-S`| z>ROp*^v4^FciXq~lCGj8q;1e@^7Q5ztS%zHdFYsFTl>sx`N~Hg5c1rxqo0G+QqzoS zL>ld!}qTL0ie{7wBFB75Tyd+m#-=!HP+xj1Dan*UO4LOnd19QZRl2$z@ z%^G-9Xa~-`q0VhQxJ@*6-+f#9YU2fcv$LrkwH5UG$Yd+0UDNGL??F-<-*wy4UbM-# z8OWDzq1MhtHjNDQMSq79Jl9Kn-W;Jjc?^Ov&ik}{R`colbp5$gDe|QmJ??3$fIyF~ zZnU^LN%~kf`0`S_CKInzthM#--ELD_T_a}P3axX#J}s(t-T5v(%#!I=yj=#y^z_-i zc(IkcHt(sk^yS+;edqNN{G8inOVfaQtvvZv?7FT;xe;te%=1wBSuO5NmgQw#V_Tt< zy3|nmdP#G3LG7O%9Sp64!+Ylhwe4&oX@?# zBsl9|D0Y%mx+OZq0|2&@C{IcqjJvkKTF~yjcZ$3xn1m|cF_?PM7DO}X_v1yR_ zH%twVx?A~KoW5!Xt!44@b+i5g#!K26@D9p!DOI)9WJJELbG&5ux0mkINePySdl#DX z?=hxBT?TVwVEHy3D#kFH*Mi2r?6(G<7dKK-`%5tE0K02W{+xLKVGG?y4*VpbgqMfI z&=K&}{s9=it4H4eWk$H{5AdzBZk9@4zs~9$*8;8>?k+5a&Y!w8WF-HnTUDb)13P#A zr9GV0ZE4Ahhrs7=6gzz=&wr-f6S5_@Kunvh_@E=yze&ecM{6GO3>z0;=eeN;bKbYP zp|{<-f$*B#PpU^??YUuXNpZ|j0KAbRV zHD>c#j(IKvYh7SkP9jLiYS5=H$bvJLNNSxSG7X56=LN z&21-T9yqPW-AMqi`m*9~PIZRheiQKq`FZxflG|abxIHq|DcGG3CxsZ%Rq581!Rnwi zUOiW(LvN>Nyf^iJMwp*=v6S3$o$ZB{dy~$p=1!?CU)LqlbYmMSM`_)^%E`2GZhPpS za=Wo;U@*|Xr0?}K^TW}KYHgwn~qEVY(vN`D&e9dy9P*vy;?geI|b! zZWT|tZM#abfl~TzY@54R8=LX14tr8odq0bH1)}NFiecru0Fm^Tg=ZExe0puZ=ehp! zDrE*GuXz>4pQ?ixe%s0gvjm0}F!;^dNt+7>zgVEkeB&8o6vOOoZ(s6My53^vSP8cV z)^)sRIZ6k&wSel2e;+|XN4MdeNn6?@Z_LnYBLDRdd#){3FPHK}hl~I>&zG%g^3$wo zpPH+jUn^#&jQXrs=jjUUPlb-M;{uvN{!IC>{OMsxZZ%jP>nZJ9YZ~-gRWsv+x)l{1 z#%!58&p?&VPPUAA-0QtW%aJ8{?sy|TdZ0@VDT@Prjv_vy-L4}I2f1%gkwf;hpOymQ zcxX}T(mD8~nN<^pUANs&L~FoantqD}_^LnY8RGVKe0x(8+;d!$(WWutY8s!ln$Eplwu#vp+ zlj0zM_Vg#UYhyDTaGXM= z?P0un*ywh1G2KjeemBh0Y1@Kt`@G7(Fql5BY_)pwEC}k_a2bs$msDTKo_>dOQMO-p zGIHPQ0o|6{JB-Jlg{O6*A7D*`!=Bae=k;3e@3OLkV$dJbYR5FpiQyo;p;ey4{nHv& zZ_j7dprfUj=E&H)bK{^p+m_0m_~^t4?GORbcAw4A@v7@yE`K^pu3E1Grq|MX*=||h zE7x6Bq|fBXQD;B*>_(Vy479Cybk8i7$+!>oVHoAj@nawTDBf(-MNXX>YxE0f%do-a zuh|3wdOWDs6qIJSudH6&Y3v$2OU3{Juz&I>AL9IL)b=uDvGq95p7qa^#;E-G$vbJA zwe~vl?NO*ZY`YA2M|KY;cB!VQB(;O{!$?XOIoR&&50*3GtFzP)@m%-IuV=Ab(oYmS z5*<%BugH=*-Vof-Z@Y%=&iE9+zzk5KCmhDymaFtEyEp5VTDX5Iv;TX-__%FPFRZFm z^6FQXvTR+q2p<`l8)3vuP6Lq=H;o(4VCGe1!u@7YH7bhz%eNShvWuMO+w>8-mnDAN z0vV6C4(}Hwal~kkTbRC)QNez<4rACQgSX4amNOqD^RopJ-c!NoKYA#DU5xHO`-_iXB#ykIpO9s zEA$E%3fV(Fjf@xqeq?`IjOZ((u2+=0X`~cw#w!!?v=lRk5tdq1OIvy8I5KMv^284j z-A+$Gxb)-2XvI4thkJfuIG$dBl4n>u7laHJ1`{y_*#a5}Tw1vB&q>!nn(L?CrV{xgZ-+@n-tx6(aID|A&l zWYB)yqOkORg<8S3d7;+<2dZRZw17cBN^626qLQ~IQx4x205UG2co$RaddXzH3q4%OHNnMJS@$uq{LI)hf?9B@$~63 zW9z7VpYc<Ed&AYFzG(#ta^bc2KCHtQ8* zeEtWIPXVoFOZj@)Jou1UEO{gXN(;kGsMKrhh%Cj_ZU^uG@(-G@g?|5#_qQ4e?1^7% z|J3?pvDCWnO8L288o1|Qs8kEWV8APFC?!=5JT_7O8sMb30F2rJ%XEI1(0YsRGmjII*KVMt(NK+#FS!tThqk! zE;M(GI*-A&0ZL+Qhv7Tun(?FDY00E#$z;c=MF-L9xYSS0`{#o0L4>JrUbC+K0VEg? z`)1aT^#-yU*B^_(C9>ez1zDjA@{>-`Ul1<+;p*W9Zo1@1powuUlDPi6N*2cJDNi7S z@k!S;?nUY#k)L8a+W|W;=_}qu zFmKZAIP$xeiNDsx_cPIyCwXv2XY8`~Y_fg`qni`(7JLD4e`7pV*m)br4W+|Ssljzj zafCrBvNm~L@KV(4Ip0WzdlPOu-eo&XU454P%K%GoXzqStt*3H-N^j(@EW#Zv=~JAF z`1$e{l%+(rB+gs%z7&2xiPS2pP`4w+Re%C+X4CE5y()TsKUBFkZBBLfy^D^^NxeLNmK!4)CF4TEqlE;Ezsp)85)^wpg{Pp zSN8rd1?V>+bYY<9pV^M!j*mP2y+HYISLyu$n+vh0tEvhIXa$)}K z#&~9jaNn~Y)@5<*D8>s|Wr2Y+=$~im{r9yI8V+O+u;BLx^#SmCXd-_9%#im<;QBsU zC?BfG=RNm;WntjcAUMK`xxRi!Y+*iVVgF04F`LT%_i01sKJiY__XycPJ;)XD#O)}c zZ)Cw;U40B~K0;xC;8_;J%4ZZ3tE=yQyc5Rs6$S|KlzSk{$M3Gjc=lt@>pah_QXO>V zd`>W92smafl=9a1(z-nQ$cHE*m@mWP|8e5P$uy`R^R9FQUC|zR*Mz#vX$TUGZ7~`!gzz8=euuM{ zMmp~(P39pM2_QP^eA)BEt#pzgGm{laN&3{(W;Jljp8b4O!3L=$4j)n291nc)i?ma+ z_Nj!&t%3qWSV=IcaT^d=X#rX3Fll%l`nw;5tYw4^TInRBD~t!n%0tYVV=bwI&8{YR z#Sl46F8mESvQDlND6m37zG{*<^spd~%-V(gxx4>^)@ayf^s}Oi_4Y`i&U3t!yevxg5 zQ%O8GGgIt(T*PF}fZocQ;OgqP|92Fl!NeWx@u5%Z*z^9cVbz#F(K2z*?zSp`DE+zh z9K2GRmoS3s0ly)j4rd+1e4voh7eueCK|FR&+z_^~AD;0wpwThc>W|7_5RCOeW5G}N zvln@6BbxNjK&fi(y@`W^>k)I}uSOlT<+$Fjdugz=OJw1DP}WqUHsjp9M4$t>`JM0+ zX*q+nCQ+;a1n&9d8^=5AYOK)@?((l~ROVL{fxVYbMp5Z9-j(v4X!pe@l<~&jN-y8z!N37EY8q z7lfW(!;ppIPVJJKGF60nHOkU=>HxJs8$7$dI0`QAtd0b6!vHZ`#q`Xz$mG|H?+<2i z*|n|d?Al!AlraNSn*RF;24m-s^f%r>DI@36Yb0l{ny#U8fx9!exvY*4LvB9jqz|Uzh7~6hd@q5?~@O25y00pK9};z93_7sKSjp zIA269+yCYsH;YQ+za^6EM%ARk&8B9kZ|>}}kdPPDpV^QDg7K1G;;#ee!5-`j@e_CH z-&Dim^!a4T>5B-FtDcOF($h}CMov@v4_g00^*?C-2lfA;owAO-cOTiorUJ?7^PnR6 zA1MEW<$u8Z51Rjh^FMfmQgG2E2a?GqXM!AihXt;d?&q@jQ4W3Cp-SWwvhzbMMhxWK zXIOy4V>FFHVcWdKV31md!hC)Wfk+}Bb>@BrfF49Xdpbr8Fqi%@9(A_F=nOq|3_Gna zEN~(YKZrFQV*d@-3$gOM4C28$_@IEDBuLb{350rSkbt`J+IYBD{&#ce1P>T9d344y zvoWh^Z!+_Pb|)J2SEbrfLlb4b8tnu32HHS!nm4BL(dq`8a`l2YB7+OlCqt_DHR8cO zz9?)Z1~b)dV$6KJ1yQOMRN@SOS=O}787aUj`uwJCiGjZW$Ol-{^k2Iw)7Ac?>lCa@ zy*SS%+pEg>$LTaHbY-7n-k-hT%}eG?|M&MEpXi5R!5gw|mXkQ!zS8&0PuL^kx0xU@ zwtZTQrM`^WZ|lT)q5fD<$i57~sh3;c-Qc?7jBt6H3*>%@%KdF1wFu+A%6Apm=~0nT1z6jJcz_Y4 zoJ~G+rHGGDCG)@02bJ$KFiMW&42?o9?@HzxkvE^phDs6GE#UV*k58qaX5pH5WkaZ388nH!>ib*H zQ&3bFXfOp4ML(yge@>Awb#`fECy|tTIE`}f$%Vf)2w%!};hzN%_oshm7xZ^#hv>Pf zm4MF)jLfZHqmR%xOL86GcY2<@DWYh0gRD!BNgdP@x#Jfat-B6hwGzz2WQTQa7 zuOU(1WX@;`647S3q*^hG&~N7of*-_Wy6GgkAu?JdXhQ=$6w+uBGGb^HsL>Q)N#T&x z$;C|qRGmo)EshkgPQ)&`Go^tAB!OUo1uDSiAewJ}U-$=gyvd+Hhd6}Z8$?q#dJJ$Z zA=os3U)jrB1Z2g7gG|WY+(L6g0*RF{6k4UwCA|V7mq3!WO=^WWJN3Dq^w_Tv{J8H&~JdccfJrh$G%-dXpvNcTDNAWpcqJ4{W)jxkdPq!x3zpe&NT)+uW7pAHs6+1)jlu>p06O6^CMS zVNf#V^Kl!CEDsP%j2PM%5WqAkI2T6?_k>?CP7@j~?756bAcIEK5wr=W(#Cj!Yz0$X ztf0nQ{)8m-SK<NS=o8RMIhc!oTJn)V6Ynn{ck@1y0}&U*EDN zf4-yaw}iX$M^=3Y^Ox7j7qKoi#l`c(c(^`Gkhci%2~=Zle7O-=7CwC36n3k^+;Km2i?t0k~#%J;m!`6tR)Q&H_B7qNye^hjZ0?PFbQ z)X5ax*08IMwyt#a(T0kaPY!Z*ZJ4Qwiq_^c;L)J6nwj)D&Vn&gAmO06vI3TQp4tQ^ z#GmSqgpo)h_TybX4Q?MzLh8Lvdr0lN{>JdDI{NmcN8nI>WY>@q4X7}5dzzJvm;(@ccJUSuODE*9p0 zo)l5u=3y;S(vu?KzA_&K_c-lJ;KU|0AeH?5rX@JPHxBC-=co1YCFWJIstVd!L3mUV zxS$6KtiW!hUlISTS>r#9rR}s}9~M{{6`~PwV*PDioIS8BoIeoQ zd^FJ%W#S^6My=kT}|T^zR5 zjynpO3?=;(o-8BFF$VbLm_m)Y7nyOwTT7*FCNq{CxEz;;?AAQYyWR}@D1$1Nk_XTO zT*5feWN%XxrJpjLzyu7U(D8^&6+kN%o<hnWk4bGkm^AlQ_b7WHnqZ}<^k+6ail0uPk;chhJZ7>uAQ z0EN+z=UY;?rv0&?k9c73t3mD^W>~+rf&pP<*!hIHY+@Kh?HrIzX(AVo+JNb2$`vW~ zI{Fcrqy&fiTQQh9H+zs%c-*c8H$%io$*7L%OeReRX^k4*-{}xY9>LV447gYKzh2_-DwcBNH!M;$|IOzG0`79p(+H} z@}sEXM=(fqNXe%kg?gXhY*q_q&2Vl9cK#8_lk^1X8axQ_5tNunBXBwY!>Fj*d(t+z zD2tiGF$>JI!4jE_!(butTm&*yykcB`1W9yv3@L>L7FSLxlWow_jND5XmhhnT~A2!Wp)mkY7^uu^~xoaS(+1q+|wUnG{Bwv zvUKSKr|{!RP0}v@->vTqS=$*e%^_+d*iz!~oTR}a{sSKw#bb(JP()ONY8ef$0zZ}x zF^kL6E1d0*7yBtJ4Uk_lxH0}l=ZjpNBZ;JTB$g^lScB1>0x6Xo2^5bIVIPuEPHh(w zyxpSgm~L`Ecy$$Cb{1QjPD%&ZX)Y#{k^*g1mfn++zHSRkqXb{%l(L0iY|kZyiV9CD z@@D(dZ%&1eD!Z04>UL0{d@UByPY5q>!0FrX}uW!jp(U?^-)*1^q zr(rk4oo7znJscxqFPJG#*h$XhmAn@qiBM(xqa}gbPxO%32Gi8Adcyjhn((D`1AFAZ z8qWBt9{p5}139NHHCU=Y_PEgAezq$8ei?K9v_$W43rl7@aX^zXGtri?_lXeDgkoNr zDbz*}lT)Znu#Q0(9=CgMf+lW|%rsXj4OJSsX{1)+ne}br7>+yXlVGtn5yu@A=NVix zNd92oBSy&sgi=17(@}hh5e%N`o~_wBTYjlQ?oUJb?+79MnrQA~jw<21M=2fAu1zRm z-vPzjreWCUV#PqidH3aggVXu9vqd@qOG`*7${2t6l$&^AmY}w6^r!xn-~=c!j0Tg- zmL*LvNtk%2mw*XEjJOxZAvF*V6vF|2qQ(h)K_!jXXq>o=6hsRc#ZMe_)(T7vWDxU< z@4!I0&dF-M3qB*2@tz?*5;o2{l2}Z?jw&k8bK(E2S&SoxF6#W&4Q#=7Y2k87(BJiJ zf1_4maj43}`I325!aT{A>|P;o>9a%gLu;ebK}Fj&htuc2%{{GVnSH> zg|bf16EJiXgB*U9R^5pPe)w*uX|Vq9O|!bw5eH`7PQwM@PDE1A|IZSvkkp4&cXH_2 zM_-{d7=P5VMAFRsivtiWg6LX-0n~KQfHL@#Y)&HKOw+xnNyQ9*s3aJgXL8;GU*1_e zQu*&G_gD^J9Wc}Nr;3C=BWK_E>Sv|Q-d3CuZU3Jzdy{!Yv?XV?vi^JZil!q^J1xOj z#(>_I+N`jmHpQm;za2wr{is$UmB%+MTNAbGC#b5usI<(J{t*H#!O>#rx)Ktk(+s4= ziI(Z8suOJV(KHrWni3ezGkDA~0})|TNr`z`!aG};-F-x0|JDiaNSJWp?|lgUvOCiA zmJ~7tJ@pan+n1qoDT>B?r%2$3fMMAH_?B1f>q5}`x05N+3){5P$9UL@K5JECBH0h< z$$mzg{If)2QIPnED8H? z1~1>v^+(3WT{?RipAN2 z2hM*TZR%c@JNLpm);^r!p?7X7FZ?12G_qV@4Cpupw3bUaoeLiihdCbydSAaFx!`Xb zBa3?b^vAYQZbM%Sz{@GkvKD$lvhJHDx<`9Z1$`4*W9?%n~W#NTchK;43?NtUl%{HD)|F&67P)vNK}}JSq~VQ+dk-;h*|*=A+E$y|vmbyd2Fh;e@hx+XQ$am`H~1 zM8^2@6u%!fwPP&4=<}&MzYMPPvWGp$L3k!11#}c%yuf4=rSiWX%|Er4!91pf0#19{ zQz`zw(w5peA-Qqh(!8Gfo>dfufMov!fIPD6=_GR_7ev_Q%Z9`E`v}d#Mw1Ck25LFu z-wo%U-`qN}-J&L~WTO>z>aQTSmAz-ik@r_vGbsEDdh8E5FiI&H>D9=o>p2aAJra+( z5mq>kFa0zfco(?V=8O~fjPHg2WBeDOTtv-jB8>IXYvS5Zg426t6VpjfG{O8BX~=A1 zo(ud26Ak)GMcM0?eP~HAma5%ODb2%Q!Jk6L8wFP@8bllFTVu|Lv13{lT$*!|DTo$t%2 zrS=Zx1=OAIx?f&R1ID~4Bu5 zVgN3tAp|G#1VANPj+8k9W}P@9!+5lpKq46#W{2mu5c3A5sWJBvF$uG9un#ZHp%Wd- zFFvZ@)5s=9NAZsVU~MB1UcMmr3PdM9*u@(s9W2a$HKK>6`~Py;YfDuL$xaAgE}~p# z1_)J~7|aiLz1ieX)j65PrzwQtMUMm9CFrS3J>L(WB9`gz+!!)J2tefx?Dnv^GQ6o~TjX!=Fjouq`%4e=H| z7;9q{YLFN*q2XPXH~cb+!I8s$gZ3#zrz#?j0&6w~@k1%bhM?lduM&mA4`}LukX^>1u_yv# zNdB!GUgk&RuPj51b21Hm;(FclWcU$cL>OoXg{BcDU56eP>oRb}V(`Rj3C#2O*U%odmGvL84KP2RkgE`zp5&<5Ltc-|Ql5$ee zbxpPP;y_&WSAxwkPD92wJ;q<*B5gu4DyaR%LU-|33Oe=p-6RFHR}`XQu6-Do;}52q zV1oBVHg}kiau_2DjLDJ9>hTQ(WgW1syhG8XYb9SxGTcd1R{pkgJLG=h=7iMyN^~OX z(zCc0{S*CY!4;QWRZ+>{&5foSngC2oG{~KF)$>TiZpnoGz%cfN`~EsX1X$N_Z$BC% zvCdlf`}rUO4!E(hO2JX`;ljTRGr9%i2|DfwlZ0r*q582fRj5A_cc3MC;QaZZj0>bT z={crGqamQZX6|H4oICwWej!G*iRZ>P+Fhrh+iE0W-^X%E+#?m|#Wtz=Z3}Qm3W%y;D^5e9JQgP6m~4Vz358>=_1X_&t@YavdW7s+f*aV{hfZ}` zf|pi}bMB41W}m0odu@vRAF93rsIeuA5_gxu-Q8_)m%-iLb#NIpxD#M-cXxLk+y(}B zcXtRZf2DRe^>Xs6Z+E|{mr5nM_ndoF9BF@$w-X^U>CZY!EtuDJ+UId`4Oj%5iHy;@ znPatkfHmIR$!BAwU|i;}TJ9Th)|lzQ$>?l%gF#a#7f#?hf&E~or17>kP9)#|%V=ZdUnDV^NYI2Wr}~Fi-m3j`d*g5trFhX5*G*ClzrKQnI2`|Ad$T>LXJRET7G~&Q1g35 zQ0I{38O6RWiaz}D&vwC4P>n_jK~4wK5~ZIaM!%;Kb`|A={5-R{ z<=fuCiFh1h>D7H(Ua%Wlu&4o@z-2HOY{(_XKSJb9fq?KO?;+#Wlm+af0IGi2hmm5T zRol|M;^!7}*F-hj_&=Okt226s-ud4s(ha+_q;8|&cYhahI@nI-typNrW~v#Q&dI)UAZWxq$C zt^$B9+~UIQ+u_qA)x}GNrNXD+>^ds|zF*(Gt`YOztRj0w{4P?u2F&EC#$(KA%OGlGSv+OIV`Bb~Xm1*Z10_K{(NPHdHD$@)2- z7(se2I9c$%GJ0~+@Zt9SUs<#szcQh8J4ic}PX?m#X?5O-aJH#lE~rHzFLn)aM}yXK zNmaf^x&bsQkN4-uVfK>?FJ<^Bba!24Y~b6M(Q<^tl(`NU(Sg1O%s81&2xxO0T%2sx(}5@)tBQMz`aq_n$TY63>tsYoXM?8Z&DnQf^0MMq*^ zf((>pAt&d?c`+_c!h#0WTQ#^l*V9krr=LtuKZ%}x2L4K;dS<}_gGD)cw__RmfLsS~ z3_nxcCwzx1Rm*4DiuaD>(G{Zr{(@hDUZ~4SjX98a!g8hb?bA?E^$ol(9wdb9g%ng0 z$`au|py;o+{&7%2UyGAQ5ofMA3Vquzk>v7dCMInlGNp0{N3kwyr#r#CJ>Jpu+h8ae z8n#QeWmwsfo9(&Mg;7xc!)55FDLm85N=o+s&*axjY|5LCYkn z=pBCrAtr~Z=^+S`A|6q{pbes?TC@m7CqWBja)>jsf20JQEBJPy%ydj;=oy8VBZ6ggI%|DTUe=UMAs zgMZ~;+H)Yt_N8@g37_Yk|E?aKz7Wu})*5g4gb&#YUr+GqY zx;e`qmmzXhAJeB^^cGa=YuZTS7~m<}7%zhJ;ZI;UOgm$xGVoT)2}xEX>;oAn1I^K| zbW5RPZ<$cW)$Gb3WBHKfbdzAW9&+X{-^1gtaTx4m=oUlT*J2Us-TRSQC!OQfC9uII z4;Pdr(tFt!KFDCp|9I;pO6s!nyAVEK-W0n~#LMO8ZAxW{Q*AelJ^aMmhe_)}XHHs& zn&%m`2-I8l#`zuca(2xF?O#h>#u+kE=Ob^?e}y4>&{vz8cf0*W51>ytua{HpZqIqi z#LXN$_dp%e_(yw5s{fHF&8apfjVp5u07W1^7Sb-qS6U0I3im0f$@Q@N45AC^h~0@M zwJj2qu%4>OSWF0|gaD%jQd_15G;(By($s=j(A&5UFC-rSIJ&S%nEFqL*3VvNM4_!X zyCTEa&H+{h^JJMUz1K;_EJ#>_=K>x{Ja4HrG}pkK_v(gf`Y`oQl;kTrB2ZFbk6;IC z{!Gg_o^J&(L>$4Fh_B0=1~PGvD}=I=@yu%Ui{w&8p(d<93n662t{*V#GgGV|#JTV{ zoooQ>_3}?D2F#FcI%bd?MFbO@%@j@Qj_TPF5+uyX^sT(`Z0U#V(f-LT0p&d3;?8!l z6+#8PN#w<+ImFr9gILoOq{XBL_Z1Mr#KvLYmPL@E)3N}NQssb_jzAEXy+bn3^1bN1 zgxD%ij2xxd-v7#H>*AM&aw_8M3N$dcdR?Ku34gF$-04Kq9Li*cL&41E<$Ac=P!I-* zimm?DDU0KCD}~7_bAC$~N%F_66AI1|Uqg>@%Woe(a6oX5{s<>J(^w6g5qA(0lleK0 zHy0m*<|&o4?H$GPG{4g>vca_IxAD-j(9Ogps;U=(^0dK1iUQ4miF2Nbpt4XK{OEwz zs`y((>2yLC-umZ(`om0U#D(c=>RnoL3A#+`E{c>iAsy49j$u=8_Q+JTY>yZgcDQB4 z&dw4pVv5(RXR_d_RL=gQ8~g)XrUds6oLLLKW7N8Iw@6W-e2x1UN;F+*@cbkUEoVC4dBBaTgcwAV21oyx90h7n<18K0C~jdz>kTxPJtP zdm~GG_|+Vs-7mlIGg{q%Y7D=$1gpXhg6x*?1GrLH#@;fGA&!xK{398<4cVcw$oDT- z@?`si;;9FKKp5Dm24jNkCO*0@>$ZCV)oK~$(1(M%5x85ijdSfShIJw)dxKc*PRA+x z4p8Wl2>d8s=OI>Xy!M1A#+^{W*)=5nhFA$v)+o`+`JmcV{BJ@vfIA|fq8y^ZgNAOz zT0>s)J0qQ#E2yP(3F|@ZbOu^CqGb2-(KYEDf@FrHrmahos+FcbB$9uwXD$4?A%?Z2 zO=^I1A|OBgC!Cg<&5clqXbTEl)awuHsT|2vU%c#_EiqxxGt`3%2IonVKD_dv5S1Yr zGr0Dd+U{?Ccp|M`mhxVVtWX@)fLQ7eDeR?6i3Qoye`v3%1v|d)wcj;BrlNXsl#q!& zu>fv(Y2e-A!9M`=Mt=o4*vJdS?r3@m7CtKmT>mUwq{VJt-;ko?ih4nLDPK>LxzHk| z(`*Yv3{jG>91-Bu6VaLQL07B?L8LqGmv=lV>FLAz#ER_B0l`m}Etv=*5opTK#|U82 z^M-0&f&CAEd9U}j>u31#r|G+jYOH?zx;2wo6>5_%KCh%v!o1!7!CoCxp$|puS0;?( z)(WxDZm3rh_53aBApcJKdw$B<&oTs%62`ITSEv!{)u3YbDn+DM8vE6Vb(Zo4Qu4Wz z^7^wP3e=5j&2@g2)c2W5{}?bLQfcyu3jhA5Q6B&XSsexn#&||8H~p-GdZnnCCHXB9 zAdmgJhjFY_Cbq>C)bq7llBxAy)cmO-V)jwTV{*u!kjtfcwS&XSq3QV7fYCfScv-&; zG<`~T(rLfWUG+K{ zvK_C$CiL~1ImRE!3j1>sK~}IF7Fd7asEco+oV%1fHnd;Oi)4h{@Fie8Sx{5o)X4wk ze{PT^&U-=4%0|jPImxpzPra?RXn5)GORST%N;vi>9o^}?k+%cX6Qer;3&^#k?srhA zAUI}mz=S}*xC?+Rd7DfF5dMlT;piR; zWyC;ZEe+qJ`Fq>$4ZTSm;E}U^whvV+2H&Ijd;9Day$b=OD~jgXhp)d<1yHL+_5A7& zRT~CXn-bISnFl2}3Y9uBf|0y$d-6>m7);xrmz6j0FtDr7v;kmnp^=-Vq46rE@8@s! zM64MlOE%V4RNiSYbFN8o6jjX)g6#Woa5RJwN3k1MhOHWB9KROveYa9xnBsnT1UkUo zT$Gk)>K80!|!A2q!Wrt~lVaSU8o$op-# z-{3!~9^B$c z45=h+LwmY8H`?3{KxxT{B!#UlFy42o>~QQwm&P! z4ec2gk8GeW4jd&kcV?azZ4rfCp{{B2$y4FAe_)8=`UsFoYK(t!(by*ItpI!BDr#WK zD;`@e_*8C{91tag^`GRye-Zsk(r*8kq)p`RwJxUJMOXM|YHTx_C566y*u(){ka@3BJ@JaD#)6MBj#e%851D2 z#j+gb1cx8X&v|5`P3USJr)t|K?s}aSR1Q8!VA;uut99@J4cG?%1EViZ>!7)^Y4gFW zYQLLl?_@RVpLwYFk}TQbL^4-9C@eu6N=n(iV}d<)?L8S75n<4hHG1T)$o0hWtUm-T z##jNRygcT?fAmy09Ad-fj*Gv9ifNTZ#_cN|ren=MP{oE}j^%h188p1fD*C72DTK6t zhr&F9v^M<8$(W*JKNf99;TklhyRWo4aBsXqPBR7l!;(eit33aK z_zZMVg|(7JBvP2QYiEexe<<<}*BB>CNu>yZ2P<2szQ!RN3K()v%S8@k8Levse@V^H z)o6wbcWw`vo$=PBWv5!er!+PinKHJbQK7T@fxb^pntC{9q3nW}vmSqJsTxZ?=_3Kv z^pz)FXCY>&sT0dl_UnOO$*@vkGv{MVxGE0td=eh@xj}C_rFTKoajy}inSBhIrxO~R z&TWH{`Vup##1jd(yS0fTR@e}0%nQ_(yh+%8C$8^hn?p~gij3PI{+@_)CSzDd@nR+= zjZhYc)s)H3MJMFv`57b2U%)84&_t>^571UXH05F8x9=sJ0i^eHps~X{J z)wc969YAuSJZUkFu?|M8w`guw;#8-%kb#i?>O9ph^I3vZbf-9e>1Dz{na?+y<^grMSOS#?K5Z-X%{E|M^XoP;Q8%_+YwQvIBSm z)DKm80C`vgFmG*gRB=C8nQBl1y~&Ae#0&W&i%%b58Jy(Enr>d;?K?hejhfP*GPbq}aBn{k7KH3aP1$ z^ipxKgEzvz7h^CdsY3WJp=HLRStR#eU453!dHA{*=nGAxPVcAv`*BC833bn=@VhVO z!cOLMeNjjp6_r1uH+O_@1B1S=x+X?!C~gEl8j>4e@F%}BMszati5%tZt+o&NLa)9V1HK$H0#xD=eE)-NJx@eON)6 z*%V=J_*oL1mFz3yL)`Dk3e|jMg)~rf;3!X&OdSt8va?0EFu#@A*>F5>0v5Qss+uHz zQVZv$rfIFIbZ->b+(f_=Gla(>8icGdQe_lBWn)EdFh|0Sx)Zuuaj*t2$9*T8uVL4G z;|&m#UVWPC^#i-Ds9*A6^Cc221h90n%J#kHm^}%e4Iu z_T4>?Qj=QggBFijs7GtcYgq7YvYnewBw7Eo9)Q1h<)VS-TH(6_n?)UH&x4ns&lYLn zF+4v8Vu<(@eetujXJk6G{L1yfQtR1ep%7~QSOF9m@JfbC>&S?Z-@htZnHSa87({|s z_`}WPk{UK$yNm>Wa9AVcy=(nS5HwuiPuEm}#g0jdx?Q~X+2id%=l1u7^}(#Vs6~&V z@llt^OFl$VP0k$amB?^VObBLbgsO>@_^3K?yGdD?Z2!nbh+2IYe&?oiG{QMmKv!rH z7UHp-;6&oI~{6=d&S|AAzJfn+ui5o=BViH+r? zNHrSx!Jb|C`SL?vCGnj#llBG_bqOoJUUcUsy#ApL9};8QK~@B}TWYq5LLoFKx&WI) z`7BAP-#1jKeSIV*T9-EJOASJlJT@}T3n+#I*&*FKVdV!z2l>mPzk1>xZ!w5{fB2IKJV`DAJeTIW@~{LY+$r> z>@)~>P-i@i>-&c`*f~7dawA0D2n4N%`p22Z`U;vyB9XuHe8I!LCW^K#CMOQn(^wQe z3G@}PqP49}zQ110Cf>J!hg*&wd-^-S@s8r~LHyxdHh4J1x@{4rL98#X^f8hNZZq7M z<7&SJNpBxs3%*R+!+fHxHM`*+_fo%xs%MGvSR-82otK*x`uoX@uQV{llw?M#Ba-Cu zaxt6ZG#y*+eLY`WNXtvWNm}O{ZLrdVPQZP17c6%<7#||p)vzde^UgQ76)1rl$lXzN zTLNG0;*w=W#Xk`nUtREc@%zRz{1)K9^PdCl*^3s6A^zsua|cHgxaGf$Aay)_S*H!4 z_5mR#fzz->gawS6SI#$Xne<p=q@F7JD}& zUlUo;K9u2}0+Fd8<)MbAC~T_cvZ`5qP^Iw`(JwMH{Ay^66H3Wt5)tYx@j3n#r!kqS zOBC~drI*nDOD_pPY;c5z4V|~3k!2aGX^m;hTryw>Nq0{JHicQ`dd(q=mL|ttP^EE;DnG^9}nxQQTrCrBW zgB(LbhC#GYhkL{u79a>iQxB}$*Snjp{+C$^ovhNoBHQ$MC6TN_JR8NMbXaKs43)=F z35IBjCw(rVb}*AI3JX@rdL!(yN4(=4)Hf!F5qGt7`pio?ZlAI>nzg+T-=J}S(RqgZ zy|PYP%NwO02hDMmH{RF?!gG27+t!+C`h7YB?Eqx8R`}+QlTc|$HHDUkQ5zM^7z;t^ zmKX8w_I?Hjnc|@WQnSBc&^h0%v4|C7j=en!-4fN5FEKw<{4{>OKjKlP=OFNI4o;vG zc8>Vvj2f)AIMk;No3`r19Zu3Dj9a=W14`I7CUNrl6` z`K)1~uvVBOHV_3Ts*_cM^NUCQ_M`Lg2&&d4Cq*CRkmjg~-m^_{@g+8q#4G%am3?vg zLEH3xQEJK?zwL7&dKZj0L_?i)QgN{wO_3MA6O;`ihIH8XB2Q8{LdwGad12H-nN!F) z-%?oKxoYd5C4a|UpBlEskw+mXP3&?Ap;t=W^hbzaD}R9gZ6ZeI^wU*bK+GlF2UT~v z^4|w?QAS`s`go2>Q||rTn!5DB6?X@9%GQSgW`odjf-?ajI}Fp&MtS~Wi;(zW-gB3< zb(zXOfq>V$HKO4oUlTzr90XC87@DZ~a8u_#;dzRTmC|6@XkwHM?U4Uw;`q zFBtC|g+My<$rv5&mW!MnypY=j<6|#P<3$E!@que|?lVg(#+VF$>MY?+{sjh0+YT%% z|8C4eIlqQ2vkgs7m4C?zEC>21fq4#GnRhw9sSrjYNq8Tp-e>)uXNHvE=VK`S#V_b3 zr?=^irE7Thce9NtIqpj9n|zYP9RngfLOt$KxBzXm%yQCr9cM|nN-Ue*XdS=2(MX(x zo*OF3u(QV~xbWFiU6~%#ZF>E6qHy1D{Dq%4Bvce7cE*I{Bw3!f#DA*#73eCeSer3F ziLCzR!)OrIH~roy*rANqkZQ&|ete;Ze@AkA<4Q20Ua-nrt3b4b>8Qp>`gXnm&f+Cv zR9R~`gIG;9lhpS87mP(g?sV+su~rS$IY{3*d>Omd%)oj5q}3|l6a!HqYaly1jAB@b zI5>J3g}E$h8tl4R?eBPMl&w#)C0N;AO|0MgF;|Bj73}X4d!S=r;wbw@oZUthoV_M= zXaddrcNJdG*;P66Nyy}T;&~T*`R=ziuhpO11_E_W&NyXS@TZDr}E}(6#gP2FURbT`=#==pA+@ zZ7Mg>S8M`6`G>E^W~{f5idD$q)ntBn>1yw$p+-J1B1Nh0UUW zL#7`vlD#O-g+2EyipEYy^r+z>@)3y=)R4ojJIm?}MG^kTAGe0&o4S+pSi$ul;GkxT zX`oD8tDhZ!zOa-~fZ@O0+0M;Kv;k$QF8oLSAa4!L9#ej5R74ckvJry|_zlZf`=Y%jpQdo+d{9rzX zJcRnNSKk@#_1aXl6HIj4k7P_AOmh^TVaSQDiJ}W_09oX?7@>EdN(#C8AzaT4zY#NU zY~I2Z_5KfBy84$et3Mr;AYUUBR95f;jd2JaJ3VHtZUmutPc<#{fe||ZScUU@l3mW9 zo6-ZJe?DWx<@ZC(?@wlJ!e<6F_$z;S$BjF`$#PouUC)`{gl6c2h_M!HdQ9j zu;P-00oj^51rS{cuiT-YhGEYm_SuskEN;_DU7lb9p7`xJBVnIiRK9OqQELDV;YiHK z-K7He>HMrn<-RnI_p>6&UmC~zjUd|e@PZ+R(S{}`wsGg^UBeo?SHFGwU1>Vh6G?WI zV}M;DhX%0&UA6c4EsA=c zu{$u@a^}=+vo(1WP*&7+KL;)*Lx!l!M}Rt%$ws#Nu(8y{LGy}#2CRvi$C`1WJzS<* ziXBnbQp|9%mkq{M;ZD#{2YWzp^-0Wy+D;3X++sB?#bp!N>-8TDU8V$O2{gR&ysDu0 znp}$fv@aU^Oy#HPGZ-tOP|{Q~33DVCK9WKIy_mv-RWH17|Y6BD#_s7N~HLksy|d zc3HHSWY!J#=ZoXx{*`Jwnoil#_WRB$FrHYnbGI8dL&AYFRqu{`c4sFi5w}ucO0@I;s{bLr8_L=S!ra=A<%b#BkTyF zjM+{`Xjp4heDM_;&BP24w^io~>*$@SpY*5k=I4SH*8q_efKSjA6%T+8ORZX;8mo+E zhzq=q+pKdQ3{CL~9?faVunQJo6u~fCGh2Wb2ilp-si_5@)N>buC6wuILpUYTc4qK^ zJ=nwtC(zQ(NtOlMSDCTIxS#hS8_Hbgv*cE7f&utHF8=-Wp+No^2C`7REuv)Ax1cVf z-syl#w6wCYyGUBA+QuIj2#oy+W=r07lxetnrimht^xU93Aj?Eua0~OhA3WyIld+$r zCWC`K1%IAeEya2yh_EHKpH!Woh-k&smmyi9;Df6?k8F(*?SN>6w!5lPG;xzl`_d6D zGL_Z5MF7i*;zK&LdG&@dO!cmxM$<;J+e=&@gk2So=^FcWaT&t+`IY)+3>iU!yAj0J zHB6LiM+@{0H4WB#MT+W9E4&Y2fA#M<)kdIdYLiYewHo53B3F_Yj6{3e(sA5jU3tmZ zxcM(7ZKcU_DgI^+TxrBLwN@fSm!5s+(f{E`lpXDfSF_=c*HjeO<9*bE{`8`3L5YcE zB6~w~oLKP6j8>mJ@Zc_AZ3)yx|0GfV0Sk9C;waIO2?kaK2??hB0}=`g3=R$s43s&c z4fg*$D89~3-0V#p-ApXKSWHb^Em+*FEgURZ9GzUune1(>tlgN+TwTw*pW@HHC$hf2 zff(>Po&(b#PFh@egNa014hRp}LO)Y3(Ja6)Tt(zMMfe_$Q#8cfDPUOONKI>Kq_KuT8pjuW{ zsEERlukjba0B%&c^!x@uY)Oy#@wIcsi$WkpWxpm!DC35O!RqZQXn0KHhv9gueBFn4AQt$yYjZq| zNm=};(brjxq}o-nV3SM+l%l2GO3u{gfBB3f(uV zxA9yu3ZO!7R~NmsJk^>5(xRGF?P&O60w!s@cNCb3Pdgnu8d5uawd0_cU8J-08K=3J z8Alm=3t$Ca2_V#jH>ZWscqfUq_NeSW;WFu*1jBh8V|-d;t20{wLkuO=!b{(ub|8yH zg>19|O?DeH!mPdQFmJ+jKM$e{G#6l3h2^#XkfRkKmN*AOBWS0D(TjaUphOk5$z^=M zqDvCaV^DJnftyelFp0|tw-DlnlO6nakfx;D$DJG(^DgNMTVz2GVx4KwjAfmF_m1cj z@?!;tF^zMbbEh3|C1vbPHX*rV9_oa(AT%P~JU~Kg!^~?VRM3w2Mxp&Z!o{j#u}w(c>nOIB}u{AU!qHr|&~yI0Zre=?|IVWiN!sw-W6t2B61N`!cn@LTXj0t5*wvdAIVyMl#?);|$+a{^i38QPd zE`?Rs^rfK3aIq;})f1{zWNiR{GKQq6ilM*Rp_BYhruOQRbyHW>MXUdI^A!~P!%sr+ zHL6bd!&jZzAsOzZ9TQ`;?L=vST!2h6Gr6sn6q@OmL#gAyj?|ah~ur=-RIby z96&7fLiA%or(rjFyn)Up;0KL;BW>IV%@(J-{G^D>iXC)YKRa^Fs`s(z1z)x|Y_st? zVK)A~7fQ;f0#Uw&d-6(& z&vHl@N{9KfJw3)OO-!och1w>tHo}vC^ z*Pz>#{h-iwul+%shXWC?!$Yg-Ws+ux*MY^*!7RsWPV(N;UrTGyKQjtO`>x9)!V-Ae z8fe=KHP|D@lVzpQqnM5;3=*BpXsj>B_7Mkt&iUT}uD?`|lGo6VKe{Rnu*G~$J|<%V zni8cS#31xg4l*IX3eEI2`ceF_E$08!-P)V{QQXEV%8y+b@%R#`Y)f`tU-;uzXSO^S z{6BgMAMbGDRyQ=fjLS;fuv1%tUZ?)CmwDUaa4_FmPyLu!c;0dqDW75w>Oo-vr?<5i z48?5d5fiy>pwsS>I1-429PkBghUTz5$Uy%@l##c&Z9-tDs zx}z3Rr^3n>y-{clltM)g&NYjCAY?WjCC|37f2i*WgeR5fi-9k!D;F3=$M=43h8K+)|h83b|vw&#Ot{K|9ZDPp+&jC5L7^^HM7U@{Q1r@-bfY>GCmaRNiU0D6;;-m}ZZf zLexSI$x}m|{5OAw>OOyu4W^AHgon-r&hWUh+QJ-|Z8vhSy#HYPsxIBRiKB4ecZ25R z|D+SwX68T8&%fpMd=$|wC!1GF^ zYF>d*J<#+4d^Y3_2Qg6KaxQ%o4HZ=5tD=UsG?oZ|y``x|8FmJ&89ntkbU^p`3=l{P z)PLQTQmG>^o}9#@%?B!i13M;Zs>9Td-be5)pMrT$%KMGid;}64c?&VaFObc)*e<>)(7oIWj@iml>AC zq>ZGvaUdFLuQwQZ%yt-7hyC3+Jm_*u;^IPUO{k^Uti?rfd#PApt*0~cfWg>rZ<+my zF1l!MjLY^x1O@8N3t4QF7X2eIXqN1Xg!4J5 zZTpGe<>T!z!1peo`=vKw9)AIID;TC#^-0$U(m8m0iN>(}GxUL;l4B)F&<`F`I5^Vt z^F4b#z!|MNaU&!E#A`C@=p5)&J=Dr0kP{o$5qirO*g zA9>awq95GBE)t?|h5;To0x>uOjgMM&sngW!VLs%G<9F4>Z0}={-psfrBo|__Iwz8} zWPv+Ku|)XeE$=|p+e#xB%$n<-e|jr}79%zcwlJI8)RQuglP zt2JJHDkiGlcV&OoyQ*@u&*Z#tLT{B2!$6=?SWg=XubhD#0F;kaOr4=d_CY6!%6D6U z)eT0Gi{>6zTIj}ja%mYm|C6#P^QCulkvjgd?uAq4)qJMEXL<<5cip%6=Q7Y8X{ z5&a|Y_Hl-XQFXuP%1sL=CQa*DCuQg4v0Hfu`AO6EjgMzT{r&0K_x*$wqgjlNvmXK~ z+aN)i2MqCIO>t0NG`2fB)86;x+kPqG#3GKKxyp}DtIDardJ$!SRsOJ# z_HMiEywI+I>bbN2PRP7Pi3S4!any`FpT9Q= zGBar*Ay6O)D0!*CDXYTUE3^fDS122mE&)vkgm!a~kkfrQ=&F2kF zLw=ORWGW+Zi9s$N!Se^YDZ5&-~JdCBw0R;ape`Dh@6y zkX7sYn0Qp~%UP_wSJ)e3s=8F@M(FL*G>Md=bSi!4wkS&|XKlMYINqR0Lv*dfVG z8pW-(h?9QEUEZ|0rO>+#it6`2x%pWdh9h(-HgZ?){xN)S8IjyvcfW()i1B7tR%nnmrP$OXep3IPR=F z{HtY-K)qRxz2f5xL}%G9r&Z6r)9~kW{MN^v@K#t(BX)N+MK9*D*N=RXValu_ zRa6Qb0^**G@*Qgbup?_&tLy54Ae_%mmRkQy3f?8YR{>;2QhHDNd5GAhJ{o^PUv@&O zF6)blkD3vJcb4WHhwEO5iFV}AF#ZoAk)Lle_^)2WXLpSFf6u}VH)Amiw09SgZ$32> z{&llMS2C5P&wWzc;PNy7_0KhvEapb~yQgra zb)bKnR-3uP%pbFa0wgNWq;D3<{PB~uR!Q#yjpQ$zXN_8$Sc+)Ll9$Lw90$4RRqav> zT&z(`uF;U)iF;^!unYP;F;cI1hXy5lzliwyD$Ni?R6K|7LwD)nyj-@pobjl4@s-9x z-^fO$@#yq;ROkDj{;_ynP@_#XZoN!?0%rVm-C}>q4SLt^D=dmZ<0vFqA@>dnl8}O$ zJe3GnerYwBoymsW)PzI}{Y!VPxU?~vP8pBC!|gtZ01vkZ9uak6qF))6?Q?8QbZ-f^ z6H`Apxy`>pa^Y3us&cvknxwmZBzB8+xPi{!ijLRq#!5Mzn&RVMewH4r{rW{W#zEU! zA?xxt&6VMe@Rw=GL20DtqQ8=vc@|0Ucx&`r;y~*US>m3Jia*x!2dl-D(~VUh0>-}I z%6!k`A6Pt>Y7ontAH>1|!q*V&$d6r)eV)q?WE@BMP92Xl?Iyx2v89jhO)RMA*Ih55 zs_COV%9oNm4j;o|;O>q-%eTpc?R~Nne*G+g$*9&balMYpq=fos^~i~JmUKCrqiYbk ziJXTv+w;&Q0&$7kg&pS>s%W?A4{ulUv7rTn$1S#`Tu8-xN>nDJoQd}1sF~(9s`Ora z?jv#rAud<8bDYVeN^4N!ONP(+UM)ttd1{W*v=Vw+R?b)|d?MqIHQx`Sq&vEG31JuI z+k^7-@QUZI_D#0e32IB?f?YL6)JFf|CV@Q=RU`Wa+N2RBL*$1*Zeng8Ganhp>~oh7 zZoeO!&nMbq5@xMS=F`i-<4WCUU;+s8*{1(Be8JbO?n4x594Ae?jrM@NYz+dledzp~ z+_10=t~f2>y9CJk6xRO@rALUdyS;)Ar(gpj^{ILk=pcR_PGTD#8Be-O{E-5I-Q!f& z8;A@6e=--USN5&LaztViXy`k}MVdG;V^n@Wy$4&h*1dCZ;E$^xslkF*!s*9B&J|3kL`yx3y;q8)kk|SXgho06Ra| zz!;v$+HORHPE;I&1J;K`SE7Js79aZKW&X|jgsEgfb_lX1zJ_%o54Z;dy zKV%xOBdQs8LVqI~lXJ>SbE63Y>b+8{73ZB^G)#5~irhj8n)N!?>pRD$r9P`dxj^CG z%xrMs%*m=5_-FqCe%OZ>)?$~B*J(9YOX1DLWeRN7>Uf^>76!gho_MtNM+BjPK!Yb- zN+{lo-!)CQRZs2H7(R4W|`mQPO*n;O!o@3Hm`Zxos*9g%|SRIatM;}#l6 z^j9DM3O)$hee>9TK~EI#whmAfPJzEy0#4j$df#fVUx{MWuxlU_oR%z=nPAl}f5_Xi zC^eWtcgL6^v7KqsM5EuFbEv~&92VNrg>^f}1bp91RS1oSuFW#-)Kw|C0r_GPm)mf|hQi8x;c$e~e0D8HuL zBWQr2uIe2`KS{N>cMw{9N^zISsPvhvA*s5y!t0d@2;%`X`aZ0>@MPxqM#atn{fepV zdc3A2GL`Qn49*qa1A8d(A#Z89PKd0`EuZsdVSA<5#I|3UG8Q2QUW z{|AHr!PHTRgvFROSxc=TqXzN4eWy6`l*4Nj(#r zkV!b4{R*|Noo0WG{Dw%Ct9L3Z`{e`U4eRnJK~Q#-^Xj94_r*H+nfaM1b8~B&#l3rH z_VecR(~CdpLFy%!s_!cM{ma=^_~bRO>~%pDEjL`qL#N)00Z)_|fIdq=CzDnB@E+^O=25?^wz@@1cS_gN3Tz84`Z} z)!aCQpZ8*@feFP=O2(7K#jcB&0h6p2XWja{>D4DWJOSo@N7f&s`_psp!0hb87mB^_ z(s$C|+~W@8CyxoI%HNQ@Of7~Mzw9F&8Ws-jk0m}1-Wz-emF+=2L5e!v;ucq|_uBu~ zWo0)I(lZbqcC0AJ#id;Zmwy4lk}oIqJF!Zk-6pQ?g45Go(b!8Za~|Ul{{w2PFR=U% zO8$ex|A5*$=P?z}$D3o@q%%2teJmX(>J;jWFaAKcZB+k0Z@KJF6D*8l?u^a1COFgX zd*qGD*NYHI=;#GYV813PpdDPx!FadaelBi3Ai9P6ok4~gdPN%K!3mLk0)&9tZ~0H zNb)ngv$7Yz&k#2M9mu^zlp0B055Q8~7pxX*?>Pl}R2k!5Ds3d2Z_CwyDE1GounLZ} zUE(V+gfVWo%bZwWAf>iWo%YvIs&Jg}wZ*rHw-C_t8AdEu%{Oq9h&kbN-P59LYYAP_ zVh^$ZSO&chcuVb2+=5STr&mLw?z$+aa#zjs!c>jxsqv5MMt&UKLi!(R^r*?g*Y)Y8mo?$nWT3L+K}1 zQSv($USzHcn~$CoYpScPA4Rz(D&D^#5M`@9$1q zEROW69dJbS_DwEikOIo7P2X3aYM;u0H--A=HmC_*t>2$#M{Q(m6`hbrAwOOWjsrS> z1=ERb4QwXVZYiNqOENtGnaE;=$Ie+~ zfe1tmZ-NkRzDthuN8P#Pw~%jq-~VHf)_58bv#!Y7zen9q!O7dm7n&sT@gLDp0W5l_b6u(iJ zdgD$SCQ|0;)8$r95fWWYM{syh$}VDVAI9UNeR3D9z8$#)Ww-qON+aYNcEnVCTd>0p zz3-4AQNZ=rX(*5uS)PW`gG1T-*S;?Qldh?ikJyjxQ;GT!jOFcZiU4fS`M|yn8XvE^ z_eKAR@3%On++P%5g=PW)Ka6Les0#{sf}SWucW)q}mDgWp@cu|c2mi2eI6qtZhtzZ} zB7b#Q)|KZhM$Dk|>?fdRsBFl6Uj3bKb;v3NL^nPA2SA_Gl{EVVQ7FL`L!IEh!JD&r zyl=yA$&nD!JD3)+q4(ptUCvBzRUbbLwPc2`H%0thi#G^-jPd%s5YRa2b*TDXVm(4qoQW6Ca27Aq zGh5>s5GL$+JN&Tgs-)cd?sE4T01+JB{rmNf{FBQ^tyTGn;_q2L+_Pk1n%@?={fbsB zba3ZT(`bVBr^RiFx;62hZWRlv@R;X%{q32|f{8tY@)RmMDsH zbQ4ZZz|2c&_(i%3dGOHSJ2Yq0OOs60#e|&6{-J=q&_imIJ#&>riF?0a`AIa-dXjxD z{1yHFVFCTxz^!&BC6AIcIEH-&~@Nj-MatVwl;r-imLlH8K57U;U&sQL^2ixH8F zkd@Cy)ig%@B&j`{ex;_qc+bAc6?3*^g%X*dAn1l1C|O}Xu$>CJK_$Xtzxop#UG?GT z0n*!)Ovv9o#ai3y{Lj%qBOmhH)1D59y~#VG>90&dAbUPfQg{0tEzqVKZ{d%yd2uUW za4;WG?pO4|372U+-Kps2^h1{+w{II)|Jr6VhY3x^i2lD zKXlyte=cZhmQm&c z`-E#XQO&NF7UtjSuc9U22pXr)&~Fe_;lWpi!NakN(lq&dF49~glN5%r} zICWA-G`WNS{+mk_z4-dCWym9RZt_wD?o-G(~}y4_}V zCgP`7NIPZnmh}3)o-SKtB??2}Bh0V?*`?t14&@c6WB)jl%J(=WtJM4j_T_$Qj6t#E zrlRvZ@&h8eb=v8!g{1}Ir&Hu>XXMSA$GMl;4O2?^AJybqh{@QlX8X0AW_{gTVB|&O z=`+QD9gd*{Rx_NXtrz*4(wyC}+AW^y370*eyTtPozizf)k{v!D>fGsAEV`z>hY zHR_FDWwwX*1^NU@U3i#=mg}1aN`mnKlC3}^IT9;u&ME8Ya-7%uqvw4slc4WAjEDQB;mEC!06}^wif8aPve#a3#<8F0 z!TUE|mLM{9F{%6MpJ7zkbp_vM?-gxD4S$@Gh|IaAj*pmQcn#$VxhwMZE+?u|1uoCv z{``qps2n2Noy z8*ue#X2~){;&76Z1(@2K(}Te0`+36kVz+i?eb_|JFdaWET>_+eT6ou5yIQNa)w^Dm z7t*3k(VsN}TRau)oca_vCo20)O#rg3kny4$?P-fisWuEDr!+2~`J0D6eeP!or|Z^; zwQOHgi<3gZO!a*(jQ@;OvV-2fBlPIz9(V7ji>(G>1i$=(5@^dJRl|>oDhtI_ea29K zY)Hv-s%fe6!ct~ta$eUN%`IF-ipW!JrA6p^5Gl?5i9o8%Q+o_%?EBoFyovZ5uy5`d zfFshmJW040ECRynRZq9Jm;@@`#6K`CspaODe|f|04h9_WevC}nPAKO8O(skq6F@%A z<5AdGqy_Y4?62xEp!(lII8n{#NC}1>0rK zAx@YS{ikd`vrzVTi2W^-Fo_G8vNzNc`sXoy)C)s5bBJ>v0XEtzWR!FxFBE9)2 z-ej3W^A$%z$Pd&x!uS02iu;Ts2ntW0M?{Tu?BKq+H8>P{yT3$@%KIXwZwlR0EiWpt z|6RvB!~r$WOgXb2Y}t8t_5Pju#N5@HY|W+quKdv$t~|~7x*^DTc5p&oA?&|D094=4 zq5+Iy_`cobhh4tU!`#n{na}VSd3mV-4B{A)4 zm1}MkW^(;E8-C_LTW*Tkx)=?7LD^xM!sD2aEhw)@sb|wXxQg`CHM+zl&mj)P_Wm9m zTn08|o`o>qa@`WY1)bUR#x|?^^q)l+#_CQ(@n5gD4JbU7>&+U1e}4yLR5fnpf-_%N za-DnO;o4oy4wNoFf>J*;4TarhTJ<^POu8*iRQl# zc=ld>U=>4}D3SxH|4ARQ@0@JTn%RQ|`ml^)P(`Db;d5Ozu+w&b{zs$xI%nC&sU$BN z5^N^t>^p=xO2O9J=QI-yO0??tc;-=3X{FAbj^x|>Lj?D+O9uC`*0Qa$OVl+~)$f4_QU|6%NnRK~0pQbty*`U`{O3z)2eigL}@o1)!x%8b~R+cg$@zd|)6xN!pS z#n)+acZB%TCVav4KSuKxh-MY|fn3|PMGfIjq=1>mR2rxR)oM`(VZ7(Civ5Ax~tTl z{Kw|!{U@Kp1DKB9Yas!94Vg3Q0cnWa`K%E19A_wYG?!R2iK&Hdcvi+uGJ z^q}MH>yP=5J@*y9x-Vt%4~^~Tc=rj|^VH7$0iHS7DB^+V>t`kRFFy5GoBD?lBO778 z-%~gRL|^){o~D1ig)iHX9@yL$>f;;FCY`d$MFu4ouQiu&Sng(gRSwVH43(W&{G(>_ z#T|1)yk(j66gH>j!SZar0QCfAVw0fq8#)||?~3rj6pI90L%WeL;ZklA!NbKLyI6RCKko5--|t+K z`l87Em|h8Tw;Mc^MKA>Rsk@=Rb@hFDjIh7CgHk!cp%C^x9}7xlUl~ zd?WAkx^b|4JKS6H?45b4(kEE@ZN}pl=+zs{>%#N2}7|=;~_82m6;fMXMQYv1{oQCb*Bp; z5Bzp#GaQx$s1fTX|9Sp6l#C=A3>(0^nvbqc5#YFMcA@4#mKcC zoI|`Ewi1*7EY|uFrHsA$;q^b>*N(O?lkMEQB={-fL&Ebk4UL^{=-h*NI=_*|UH|@) zw~WGoB)iCn;!BPg{?0*83<>sH5~43fP(%DM(We|51Fz*e0~7>2`HvjXQWV{tG26b~csg7Z z$i4xv&96eG_W<(S!wP+P26P{eBL+B?8cu4yoUJ%+gS(sNd#eE5a2H5|3pNW9Tk%)>D)NXQfKps zIqx>BQcvX=%P!a;|F=~iHmfK7sLu?DX!=o5sF{~}_Viu42W0eQ>%U41Pz^`+O-JK))+?s{XtMvth1d1ZteS`B!RdvLO69Lmwj+ z(iy0T`Apx)%ocdj&f(|+kOkPHmCIN`W#+(EmLy!vY@0i^$3hRG5=n6?*$J2HYQ{6p z8)K6-`bj!5!kXylGPXVvuRxET9rAEl8}QV1i}71))MV)SH=m69mm91l%+QRXZ8EMd z@Avpx)}(I+X;=yP(z5*1qEl056(jZ1E1;zDDktjT$HFKNm5#){kGWSZg_SGCpS4v# z*e7~Er+y@rc`^66OzTHnDQ63YDid5_*O-znkrO~LdrWHU%p(6=Fm$Y0ji7cH#veN# zLE2duS!oPGPY5L*TG#gBuD}fx9YUyExKylEws$Zs0{bUdCBleO$k+9X-rZ;${F1q~(5Vqa#hgbBO$1-Z{Pe^i<65m`*I?(VOkT zUcb@a?a1skI}rZ<5-=esQvn${A?7{DrAicd7Np5`OBzfgX&m*8VScgR_GnL)Rhee! zH8~L4)HQ|V)ZNrNyVX=)m^(zyxDoR~j%IV8 zqh4zho2IDvL|I0;hIYm;sJPGbvI6IdPPNss5Jw~m&y;7b)i2wvTgJ6wL5%A8u2LTJ z%fu0&kv%nJ>}*xn^(!39Up&$DHc)i(8F@)vCFl^V1tk zkw&HR&q4&!jC&eu&URudRHrmkp-Qozdg#s_G)S6iMOnYdm5Db<1y+Lj{yX2~jj6*9#Uf?8AjP$JZ98jaLf|avMyRgXJmMQ z23v2Iyh7!3ITeV*MbvT`1m0Y0)z_;i$>d#i2|1lsF7+xD`71BjOGnu8(N6AMb0d&Z z7I}hrt+YajJ&v`tjX6kb?)YmUN>eBJx#Ct_m~9^IO*t#N(*+HNOPk#~*!Dafx`nf< zn_GIex1Ag3o)r%Q^~$m|R@=sNh-9@1HM!B~D4?fS=B_}`olAQjGXbfMiO#J;U9f+s zC6ip;^)veWPKY^vme)E{f?%O`4umzaX{VRpunmkV4(ME0;~&5JKvmS=$C6TnPhqtp6 z^v~9Wpl6-ojKjNZi=ujtL0K-?beooMKyEVyP09+>n*>6OWyMexK#cxiC?63FjxJ$GuUihGK0cLL^8u5YwWAqTnn1z zgxr?A3Et^W6sC<@Ptg*$1>ww@RDYym$qvaw`@BoMHgKy-yAgd$Z~fu$OPsuo{-s#E z#WP1Wy(eF*2n4Tk)jR^cx-Mgv0ImEdOke3ecg5`M{2@oT7%z;=?|lWkrN`eizN6)0 ziC_}cD+q3Ujq9 z{aM4~tz$>M{8ALi1Ej_(waCS)?gyjv00eE8k^&y@nabOeZjWBBar#$E9sZX@no#f8&^vtvRYe!vBO z(bC_&JqN(HQ^##a3IOb{r}Qd`w!{AN*VCT9jRfzjxuXMC*&7~G9+8M>k-<}k-gMg&N8E5DBm9+^2^{ zTZ*x(!-OB%(uQ)8xO&YS7F+t9bkW{LUz*rM%B;#s=*Vp2VmY_cp;H5Fw*+s;X#OlO z?Z3Knr4>7k$|~uxP(#ixjwhYF%{nP%6JhVKctHC_)KCR1bTC}pQpQXbNjzDcqVNs* zCtiYca66kTX z->NzpYzkmYGx>L)P9tNEJZAw7GgdNYTtONDlbf3BrfHt)MN_Q}jPo*X{AJfRp_0@*WX+_fmR7eDm=pzQ{vo^eM8C8+dTDJ7^JL6hKC4d37u8UKU zzimC2F%e7NSS|2}-5a7JKrBF!u7$+AKaYwo~&EfBzGPzT<6_7Tg)wSs{c(f78&?uN3^ZH2S{FURRs zWZw?EFCPGY8BZ(i*|TjG6I6uL2)}a|2Xt>@g~k&ry8seN6JN1^wYjCc{Pu3|qIVfn zM#rJNv1}Isa=FzkrADf}rg8z`4%gGDtcod6>hRl&QCl~>)YgmWq%{Sfd^2z{LwBa- zs?;PV0n$>(JmLdy=FWtiU(>;Qcz3RMo~>Rio+wP$=(Qf2%i!YG59typ0PmX{-_GSr zI%g9~E*^A7KFxKlceAn|yp)8I^pA<+uhTK#tkJd6VVl&}5Dw~19Oqpp+(xx;*y~~m zgRAq94f9=jrA_IXkh$+8K8U@49x=*JpZmu~>@PT@7FyQCVkGs1qhhE8GQ=#_)9da* zpC|CbTg+4W`GgRe#wYvs8^PBQAiI~j8;pD8?l|gNyQxbFHw<5l%7peTX%W0=dpjkS zys1!~q$f`Rd)_b^>tng4`BcXJngqz!G~UD3{8vWQPg!iWHh88G9lYk7R+NM`xT+*D zO)ui&)l>aZLL_~Eh z|0&8DNYXQ}na9v0Gb8QN@l$Pr7HMZ$WN?EeHmaJ^0QyW4vD-P-5sPGB(@Fs5kEIej z&oYP|Z`D@ax~ka!l1K*n#rf**x+x;gEaQafu@v&*kXiM-grM4Gryj#l*p;^CisJ}#UT-&pH+LU_iJ;c3gXhiwor6{RYSFcyyG9I%HPi?qY;rZ&y0p~wB7bjIzBs=aS{G&2l>u7 zv9ovp>0i1aKVMHSQ=prWBvrYptVai^Bav}u4fZN1CH%3aXW)9F7s`!q86Am+Z2QF- zn?2`Sm-$`ZWM16a#eUf|Goe>QFdVc#H&xrNg+|CLf19e~c(iV_zT+tYdeOoIxeU3m z_4Ltwz#4>^VGLIjQWbh@3P->e{Hal_%ml;h_WWm4)hs_ctShgM4#(VUx1Z>ERt)VQ zETf7EdJc<~lirQ2=YA|$`rJ-#d~E~M;BB-^GB;diROwd1Y|`45Gp%pO##Vq+*6=e+ zbLO@sQR8)Grsvs1n5CCYV%oeyL&Or7*T^Ye#ZCymaeB(Th|~4g*y}&+MPA4;xacuq zj}eDdWidl4$5Ng;A3;MzDL7FPg3gF<0OzrZ)WQ2s^}SA5Rk9hqo-RZlNfBxM65vU4_pkL zdIpB2Ai{w&9d{Y^Ju51__z;sbE;bz-6vh??*XQAzcLAAnt<)-!vLFEh1Qah`mYTNl zx?6h>i1md9s^lgq=fKNtKUxoj6^Y9chG>AF;tZsT?Euh^-ca@`Jb)P7`eHAkl-xA#O zDBu{4n|K-#dETsx!>sN_-Gyz231*emSI$NtkG!XtL-g4O#DM|3()ZtGnz+mGsbYBt z>)r8&Jv$MPF~W*}sD{JQ9ly)rO#NU#&CXRFlP&O@2Df3Ij(VWwoNOf7=(VbQI54-y z1W&2r_zSb#Oo&K>8#UK9CM5mZ5p{)B^4ywwZkrL3$^;jn^7+P2fn!KDaEifNZ%^qM`!{@H0s+QNQ)wkc^ldS|QTJu`>77cNgDU}@o!HO>D-ZiJ7_wm+*U)V< zus*Pp1^fF9dc7TrQr8Cj)WhhCHH(THv6LhLQKDwUQ2STps@qs6FQm$$o-QBAL~IFik7`9fy=jre-rDEj!U)Xny{f|VB86H~E6CQ)mJUapC+ zFtyCXf=Yo3&0q?8*z7>(l>2pcq?m?Tkf|eR&@4dNg9NsEuBMjpD%U>H!u7gXz&a$h zf?cxl%jS^ine**HyEc&^?I5dA@sh{hpuJ{!S+kWl##?6?gJ&Nd`(d`t>eFASCprCe z@HR}<;^jaR-u^l!7D?P2p?O;iz(%c3cU)#I=XvEmN#D2b3YF;aeN|xtv}dJz$Y>ct zN54`fq+MEvLh3~?fSI)`I3G~gX+80Dul@rWA7PHB(pOJ{)WflM(%5{NzwwyUlKp{! z_p~YYzG$G#29FnRXVn|2?<-db*U`>p zpyi?2oKq=idxN-nPD#pVRlNljp-n-NXxy}5i`L~Anu8hdt5`a7Sj;Ewn_4r-d~4?x zcJ@fuZZb-^Zgk)&UJO>=D!6v^EJ?>k%kPagbh&9mx{#`6yW__`LTDj+|ex$nrPYc z&4%O(SF^5w^=I7Q^BPmkv*YxVgFB9JWN&gSOerW8s`%EEwOme(AmoUd>UakEN9dpS zp#u2pqK1acs`4TQdA>v3nWE7r&!$Y8-F!Bg@- z9(w=iA!2R41?RF>qu*%HKDhV+9WlxohSA2nqx8$)uZm0{jt+8tOVECko>oCJJa2WK z&AL>Y{l-$2CC`eQEyX-uR(!d z7JvV^ewUa$+-#avfFs)z1D|cqk&1zf0Q73VhEA%mId83#tyN?yUf_lqOMWra6wa-! zj#4z2U-)F+Vl69bz=YLOYodo|WG1`P1zMOz3vXSEW^u>yKb8wXxz?)Q?^lKNDtJe|N6?R@gOIBYNfxa8cd*1R9? zoUQC&bql%hcSO?292u1tc)IeD<5%QQ`D5y?Xd;a;PKFL#Hy9P*4W9EPnp79IW!xyQ zdqfr-6dqX7x6Vo`TUL-HoMdP0fs5RT=}q%&Fj4fBqW33D(bS^$)I+ zHyfF!xw!K}qLu%+s)MbyKBp`H{@;nUID3!oP8+R?arGng!@)LsOn|Xql6H?QddE%} zk*yb?8Y?1F8vz$g)XGaEldc;F+J9-AonFTR6E5>kb@UK9SLep}sxuA#SU_2|=25FH z+i^&(rOwgLoQDVLj^Is%5un#mCR7#qxUDhibh_gh&zHFQvTI{@P~s1RnpvZ885mbp zNb#f-&zA}qb*T3!mG&l-(rMhK9z|-@8Rt6k1z4}u+@%OQucHVM0iBh&7neY;uLMic z>LCQF6Xwm=wl&f{p16^@NR5xrS?f#?!^&!m7(<1vSp$*~`bRWbdsasOjaH=TTPw6< zo^-Jy_)>YAT0iE7$u62r5deCYTWNY(2reFuh#Nj_QNC5;8AbftxFo8zUh;f6dlkBl zru%+ITKaOzZg2o^){q&| z-hMT=F(9)k_NTZ(Q(|dHfot0CwBdosUlc9?Nght^Q4m^}|HEg&$3C#VC@Eot5!A zob|Ce{59m%kPJ^HhaY8tQ%=PWZSjuL>ceC>CLw7TbVc>>5vZy{-*lGk$vkh zLPOtoV@{r9Xx0oM>yXgo!8ZhOt8;Af$o_E3B5#eBm{~`X zgSJ6BI9)wCW^focQYAa=$rfjxPVeL|VM1Z0WLf-dt1WqF+A*jCmB* z&9Z)OYB*o6ZNbaMY}N?@mg#FcbL$XBUq@I^<%>-sli*&|xKAB>_nf8eLuTP}*$>9a zDaK?xnjUl>a)wu`xg`^sI9o^wNIm`|KJ}^+l{rdA5N1PHx}cpGn0a;Auk<>3*)p2e zsVnJUhgHg$8mu+-PRqY8phRa|bujiR%X}y1^Q`f);-;)!sOCD?sEBBVWIV&;s6XR5 zG0jeGFcq=wTQp;V~KF`fU|mHx;2A>D7*7%kr0Yz5Kgov zB2TjmCQ@8>34W(81jp9_92E8ETGN~6Z0 z{u_Hb@Pfwe%8M9=y$6|S0;c1MGkZ6^(?5_??G%0!*1@EQZvi@=bV%;W$=iot<-P7z z<=k%;2-+MU0kz#mxJNfJ*hnHvqu1qA+7y8zEE*{$hSF zPy|_+{c~iz9T8Bag(EbxJz-7smfkgwCboJlN2r#C!~@$WS*T>zKnc`r^$Jsh{nef& z#L866^K;qOqo3#)K{=Eo>r7?OemOuW48PXww?Iqj_=$w0t%h5I|2vU-)f$!yQ`S-U zbhKB4j*J=VxJkM}+>i6~woK)cv-W;*8UJDHP%P!P@O7OEwvGHdV2hnSCo`XMjgc`r zge6*UrN+@h)Zylo{0P9$PWJBMbByL?0DW^O*P@E%bwiJ>bF)V$vnpM zZjzOqM&dZ;_T{TtyN+QRC3IlaC<7{rn5})AvzZ>=uDV<~YF? z<2!i`Y7LG0klc>fPtb3xnHWyP;+tQ(m!}oiZO<9%MS^d!{aAUw&W;gU#_3D27d}6J zeq*HU+}=I&aFLeQuClC;o=$g|RH```B44CKG5_x3H08R>hA3=u`jsC^JYaxzR%j(! z(Os=j?|M(Pq;A5@3c(52a^E*y-dhe=CdEt*SNd7c>KL(l*~OM6mz5{yD>51wO`{Oe z1JT;Jee(iWhib2S!^5alvYNLN1sR`wX3U6_p`wbG<891r$j&M~%v(y5>GD zneSpDTP}7*WGoTXQj1y%-WhEtJks!udEPI4`(hm?MN-ImJ#=%?+!jpx)_EyZ{H8Eh zs~h+2X@nw-@-picV;!-*_Ii31cAdo9@0`bFlC~8Miyr#h{22|Wsg|d1V4ar~$wi}i zE@}qv@NXu^Y_VwL)9QAk_=4rB4|m|E7quPgB|gBZU)xA7t7Qi@Ib4M&FWI4U`iGAj zhzmkvrbW^w?|-UY-YQVyq>+V?6gi`e^qf=99yzdJZjj^SNm&B3bPCUu__V4(Fd~pb zg1<>R;i6p4%qfAxPzOOzTw4u=vD30=0&Zlig`3Z1@*WZcA6J|jp}GLZSo;1(o=2dB zA|WBMw|Pt0)XEYuCiL2$@PlX>EE`CZ$Bb=*)tk+YBnq%K!a(gx$9N*Y{#O}IK9F%p zGf#2HkH;oHzSI4pF;BXhpN2VHyiv-srIm|M;SG4Y5Sc0c%pR{ku$F}6M&8sH+t+Wq zEhncx?pJ-j6^SS5#3z@>%9SYNuM&@#vDAZD5v`|gHh>uYp?@&te6r;u8yxG3x*zHGv_L&3%DdQQ;x)w!IFuz!Ie*ryZg6Z{cr z+`yjx3OGGM>73yqbgx0@E+M9DIYF;^5}1Q}*Mc})xw7@=j*Rw`N5+yx!G}6k_JJK8 z%0S@5)xoe3X{@HI^R_UyryOIqrUc&W!@!0X&rY>(r1^?oqUVPL^VbWb{|^4%5(xkP zKus~h=1sgrL)16>?`s*w6lE!sGy8CL`U;vUrJsLqE|^z?YW53BSO1?wAaZ2PUGH!s zBiES@o)mk19-9OuyvX|WVG+vBvRb8n6K`>_&csFYP1r^aX9824ponGnBKvWisG=ViK4yj|MbYF!M0%xNd&~=4H z`RC$R0h$+=HILodA7qDl5`g2389C(^P1hp##7(@At*VxvvJ3LvvYZ=bmNw6l>Ew~Q zv%d&;UOeOVwPS3C)v!};ZA9l%$1)~!3-_v@oNup5ZWQ-v<}duHTTF52phz^T)WH{<)Mrb97dim>-bCvcuy89&_oJBmzd5|v*kJ0D6NW7E;#8Oy{5 zOr+e_%5bkUTVN}5yM^=6?^vl+tOv0Ko>B?h3CbjGVRa&Ad4UNaf}D* zCX>vy3MRq)oz=Oj(_9q%sc4uLw7r#yA@&y~TX{bf9vHD-F*WUC?TxtV5PH z8mclsP{AED@FB>?UNX;`S94sKfUFMvQe4OP56V`Gq!jVer8~Crl^p-6ukVKt6%&pS z`fS-I9`5y7jJDz<(=CEdMFey`JbC~cCZv4Kw>EJ@`ZGdBN-T)djM`yS)anLcw0Kr$WD6n{psmctI z315H$%1U(7|3(AXrcr1)CV3(lzV6M1$uBT)NGou*SNumoy!1x)gz*Y2RtfE^=2EM2M5W0xQc~{ zQ}T(L*QGX4fv9>ne?r)tXM7Z$Zh7 z6|6b0#a!vwY4CYpg|7hB;cVlX5{x7HTQ-YVqqbQQe0tUk`~+7W7jouiyI&QaUO3|R zU~?Vc*IQMbn4)MD(Te)cnqjz!L2xV9ohuzRQASojxQq?Gb?Y=n9+kyx(7K5G!vWun z!WGNTS||K+fn0?u?~H~L_=m?(X*Ma*%(~j9BDP&=i_iPK3%ala#n3qj;RT{jGdUuV z6oY#oRHTuVUFJ>1N!)KA+SI|=U{v}dvy_SA2hr_T&u3Nm1d1%c#iI| z!iW9XDhKXa;^qL9RM=U)V;bW2tR-c7_BlQ=JUZhkGx^)457@qeH!ze*j>*0$FP&g1 z;}Vznp$S33K~lObVLglg{o_9VD$r}l)fta)k@$k>7l&q`0)Mg!`{JICu!f`)PX z^{w}NbvE#O&sTpz9gRPX&P~Ndm8oh2RoF{XW*Jx9XuQjsF#Mc!>x&hpDLPPXkRi!J zxdFHyGdI{R;#+%{^;SINGX`XI$~xu1T0Wp#G~Ni%g29RRaV%0nR&4dCQKSYrXroRy zlPsb#a%esR%;LyNu{?Y{Z#0KlY3Z$tDwYea&!)2FyI>hg8_{^spHs_=y2_ME)v?IR z9$HW26M$D7|Mu0$hfX^Jk)*~T8@6AkrZ$9U6vKv1156AxPm(4ZvoMTk8~|GOH;(+4 zJZP$dx5Dmh4H8xd_-}oOLKMsn=R@V#)Pgf$s zvrGE>(UCGR^(`H0JFY+(D`sU72h{wla%9JU)Y|%E?SZv?=#_T7XQi)h%VvK&kafQN z+mcW-_1+It;6PggP_zCVX@JHB-D!xMx{rAZh)W zggc|=`>gdNC%L}2UZ}2L9V}OJ*-+H6h%sMudGDjG1Hiq#?bXfPPx*RwI8dZI69O;c z6dv<0CIXa5@FgYu!j+pr(S`PCmZFZpj!F+1(PYnBxshOE{IddcpgpNkllAX}ybD4KWWnm|9lMQ9T1S^k*XE?$Dv zL4Xk1gg1J}#9L>qF$Nnj8Wbw=BTWg%=D_jJ&m*B0SN#()*OQif{Z!*|OWWGw!=lNw zJ4T&Qzb+NL1us3ie!S}Sobwr|N|!$c3cnSFlE~7Yw6S)TkOLO_H#yDcaTvcS2We*s z0@{tuw|M?zMDuqY%HF&9>uG45w705m)ST!)Gh-P?1sBSM%{sZa6&lU)E90qSo%!8U zzQxIGhh36nN{!J5RVQcOo;8q{j-BJq1l}(0o^K>=GZ{mvl?5!3wDH z#0J>sF?}Wt+EwQ01}vG*#i<#?A>X>W-O`9zr*&PSp{yK!LY0fJP)*m~_UubJuMAGW zT~{l4CpaoR)HPN8&>EBO25p@JXt}FicI;=IVw+7>NiIa?*{sToXUhP&t7u6&O@EUx z0z-l#jV48%rvv5)QwoNQMI7NOTPgJ5ONH{ZWMJkA;|y6mcN`a?1hLZvMDKAeLNg>7 zTKk{fx$aPVj3NzI0H>IWOnx*AOjM`g)!s&qcqm^D*zV)8q@QVj5OT+v#Z~ zA7f`76Ib-@d)&*=;uI@TXwl+U7+i|GLn-d=GPt`t#ihlH3=X9fFH&3wcNkm-X6E+y z-aj`tFE4lJeF8+WY(UZZlFZ2H$8#=Wwi8bZPzU)TgPWDaYqp|MC(a z{;szS)5CU!Wx{=`JjEYu`)(&!qp)r& z@V#Sk`d=MLpOx>#d9Z^PN^~cdRofH2pF6RkXVNXRFW`K1*kHk5Ec6BCFG7tM8u84TR$AJR)=s>Q6R73-C0hC#^6`mdj;zfLDoMsD#@gPQ z!n>(wUotsJ4>-5{#M9;SAteoFU;|=C*YQ=@$o>e`KeWmB6RNwl> zvqG4t)7DADdfY1C&Uc(AtfRRN@59N81T8xoK7k2GlcX4*fYF}{h=AlsQx1b#+({N@ zg7^4FqeCOrw!MK21vB{jx5bup1u7pszbE*aLmrtbX5vns(F(MXZ9AAAI{XAx{tt}Czu#$ zK@r<|rQN%0%W=1C&7Wr_hD#4NIr+&-Qg!ibtvl?uW9Ip5{ksnMR6YZaDQ&iXfZ*zQ&;}kW++;*oU6~U6;qKXZ#Ty0 z`9c_%D#fG$@&lXTM}dptr)mz&zi-*%t?E97wivRSQWq_-=4Ot) z(-|CM@STTcoD-jjbm3TPef|rIYSnB74-|Y5;j*|=*lJddWA*hTeISo#@!>*9{`{#_ zF4o9POD{RLPKHy@yv<9X$CjnoeuBs7jP`;wZ9EwE7{6lmT+;%R*f*oX?cJ( zel#6Mw7rOWF&^|cLt%~nAd)r#FlH*LDkR;lhxkBVJ7iAv3H6R_6WH3>%_`diRICbJ){tEIiT%jkFAxx0<3+F~zw@ zuVmVvIjbF8z;k)f_8M~W!J&C|r-5_m zl$9%|bq+GuAK}^HzrH+d0ZzQ?Hb&nUZQW6IjG*7ICXUQ+&q{lvNd9gtM73F9Cnj;F zx>mK|N4ElXDNqdZWxtDuabR)Ec}rHeYj3v{>OPd!K2K~-%Ul6ji3&Q_+DdexfvXKeQ1 zx2c_N`F!u@!C{J$TjXMfoJuo(MbeZv?{(_jEMKIt5C3lL9Y$@feBUu|UcE!s9Ermf zxb}_rTa=WlNwv0_;EcpMA9ZZQ1u>XsT_SX2x-#=Cn0D&WL_3wp|H9*&GOP6L%9l&^z~vDk63bqgz$>*Z&#Bo+F9mmFuTX7RVmI({4Iw_jT53OBH-VkVHR5q0<2VUxerwC|8()UN-?fouQ{oDp!S}>}J|*(7+GHXk}Wbp#g))A|X#mWl&hb>6q3QRKJDM>KwQD-<|EwCkMA*~RJP>^WDzn|1Sa zJuLmFbJen%^8(AVDt2L%P)#>F7;;GHKg*BCwg2t+g25^Uwq1z|ih-z4*m$~*Rzb3H zyZOE7#9E=9Ly?)F{mtLcCgD;39zT@gHf>9yIS=YrOfxdD&E2maW$@IH4>x9OB%%!K{o z&l^jykX87L@X~LerCfT;hn!5mR9N{b>W+Ekp84HsK4ZCG@BLWQ@Q$}DG%e<#*p&Zcz;|c zGM1s9Xy6vk$&cQuema{s(-6x*P-5EEAux<8WM6ABclRw~C^nAQ=qn$JJ^z3^rk~`} zTYotn6)%n7)&728MUDS;=%Xy`rPRP#qE!oT4Ls*nBfrW?rRavVl7-lC}^k;AZbX}Mk(%Sjzo~H7vZ-wX-8{ogNa@NA?c+WQ9$tPtK z6!dl~pLn3vcw`$3l@BmiBrZUYOD0$n>nvGeU{E|`NzR)7Y>awUptL8y>Uy(;i=`j5Sg~r9GFH5|h}5&qKwIfc!3)~`H`790Wb=WEnoF@D3s=<&u4 zZDVsS)V{n6Fg;hy7p`&_X|MN*Gxk~{@a7n($lSxgB$!X-_6zrp2ren-h@;j)eH*N3 z@VP``*%U~BQ7G3QPlf#@l+RQ>Q=>vcRR_smmev5X|?D<#DD-S8@=*Iom>1}kU9|kx7nV^Cl0InVS#fc(HZQ|v=Igqx^ ze%>&$Ar0du!aF>6b=x;B5>pSfvZLY4_KR2JUX~00-lFZm!(Knu`rAEm4s30vu}B<8 zgQbLh6~$o0)cAMJ8c%0Hrg~eS$rIGZiS}uTY$~&?rWlP&R4&P(X_m{kr=w2jF;4G8 zXZge3(B{tX-`pa>bPZyyfcuC2-bU>h%@=KsEPuTc89IyB)bGh*8|&ZW*0el3Q6Cm* zh!iy=SD)h2bJQ3%>!GQ~J66B4*#@|-Y#g_UpBtXqqVIo@>&>k-QLGD4vSo~IanSwi zA^u59f9c&6fnH~G1#qe(x;_x_K5#!hFi{|K_sec#8Gfq19E|?9Q@7-!cCVKe?Eiyf zxWOJ#Oz?w?0g=rh%6tYl`I&8v{rO3B8UVQmxb#7BVYjJDoDGaZ@pInn(l1LLCcL&D z|0S1un!5ybwq5>ie|!_#IaanZNaJRd!33?gY(Grr2u!DQ8Tijz9I&f*s^=pFAdC{^eG=~@~FR7Z6RG${B4=j1un(gs@US8{1+U?{P{3mq zYm5u2m1snEBDW#%3)rzwx-uYUS-(!9shjxd16od^$Jt5}d#~36AAo-Lf~x-4aDxm8 zeP{!97d@fRZyDw@u7TXaRtH77&Q6cRx*jWT*}VY|!4a$I+w9f`dOFg?2X%P&C|9UM zbX)f^BJt+y^ZGyi*?z5yDTIPTuH=Qpwj18 zYuxR<&XwM=uza=CmmdG5yAkK!5`FkxN?O*iqQs=fE0)a&t<1P&B{!fgvt5)p2uV_5 zWTTRSIH~`$k(Kl$y4`Bwx1Q6~a#NX_dT!{w%T!NM2!wkFucjvN;#C#jzg;i=UfbuA zLcP{TY}A*0Qy7`E0v#MxL5htE`$JdXP6xVibAIq!ww6Nfpe=l$RP~m!!G2&}Z)w$w zLe?CGSs(J)$PXcplmcYAl=|M4L5x4oxIJ&NgL@Zj+z*XF+| zAnc=_=sAJh4J{$6o>C+ZVL>745C80Fr3x5b$_Kp-1C3SPQqhxye8^9ivq5AW6ckfjjq2s6bJf8T?nONj1k)j zZ3tyZ!kT2=!5Dw1l8fGmB{7BG$WZypWq%Q065ET$iY@&2yqI6qDMb`UZTbbYW^V0N z_RZX{`o*%|4I$HM&9R6}@&=O{7LYiU96&7VJnwK@Pz zP%RxPciQ&|!7>NS?Q^>F{nVrhvpp{!0}O!o5^;AX!>j-gM3qjJ14DyE=pYSqWO&ew zPS8}!I7S#A)g41Ij%O0}`e@JJ4)D3K*XG0J=G(o&=Kw3;u-g+xvmJ{fE|=?(k~p^J z8^u;NE<`87KR4G8dq4FcCLtW)CcE4!aYkwpb-vo?C9zpHH`J%Tjs7Ghm5qi#YnqXm*~tp*3*}J?fW)(I&W}e;(|-*wu(u< zUkXVPmJ9CSh_m86lrkmBTt+q6q+nJDl!_yre^|;-yC;-)*-mKn-n5GP|9nkYY_WFC zD}9L;K#Ik5tE#0)_xXX^SC_xAM2^s(S<>bLY~sSAAO(RJb7@c42NbvT3s!oeHHuR1 zWy??x{qig3XKF4nTYih1T+BD&5@jc@N*DD5aY_2ZeCPUaq!Dg`JITeZYwRE?{{|h+ zOM$UfJLH9_AQ9c?_j83#yZF)fcqGqKUz0EB8fnBC#OW{4SCKg9NWZFoEpNCn2Wp`C z)0+T4clICce*KQKoe^rzolK)%eXjfI=T3`S9TQ3o%-9?7UlH{k7p8sd1+#Alf9K4k zzAe7*6j4G&s!0tuE4m|hzkt?&ymiyLV{@OtZBlsq&8%Y#Z@Ok;vjRVzy`t_Q-+uij zg06JZMj=3UkFH80!%md6<1qT2dfV1*Kh2n4mJe92Y-=P2{ztzAfO=r07YZie)n+Qe zy@pPXy^5%g8zhWfE3y;)*fTi%i&Qk?1``>F6NcE)mm?*Xd?%3KOrQf-ZXW6TGR8Pu zJ&qDg9U@G=uqN<}bd1Xgr^dY0eK^y6RFdyLojsikM{J337~uCN$fQCsX@@ardT=lO z?y;{vv`}t(WByr0!%uh4?cYvo&tMweC7Ttw`YElmhRW^Nyeh~TQR6o}tJ-_$CkB{B z|LhXT_3FOl&JH>r>R{S_g1s;4xbf5Pr`5@d^Le4xS2dHehPYr)P4SpNK1-Le*EF=5 z_E_EFbj*{Ob=w=c4?8ykmLIL{c>A01i@zI%jEY>l;qfG0>izI+=1mc9MU1{(Rr87E zzHch`tn=k4Y#iJE%P~7DGo3?KW%sUAR+oxeg|K>i*w;Sz6{LTHd*>u6w(TSIG-uVeJ3Q}&e)NnbO4OrOwo3uiH2=My*Dd6?shq0w1oKbgsC-M zRXG!@_Z2t&6=@#=+5WB?b$ZM+f7qvUPZkm5J*0h^C32yeu9V9JqzL4)`u-|slsd$Y9m+P5-tkdf zi9r}XsspjXhH_J-eeg|Ib6;Z5u2d`-y2d!Nv{8+uR!J+_%i{&qs1@`eSKon!Oe$Gp}AoLjFJpqk86-f!xRwVM&isb-;9 zUy#G%6~-mVk4!y`55@BO;GnDNtO5)LYWEInefL?ga!a{N0FbXO?U7uE*d0TFQ8HoMUEF^$K;Sn!Dk58N z)v*T80?0 zsReYd#*|V_O*_Rm46l5wUyh_>O5`@42bE5AX1VAh%6}nPwBeThYPI*H<@<@Z;>pK+ zlbN)+p;cYF_mOX!f<9Kgta&|bI9AoBE_Rrol_}zS|L&S>ysFTfRxJONeO*`JK-uCM zHWE|E#3D``)#my0g;~45?&spl<03E$OL=hfxB6{6(FwFs6?c=s+n zm2(nprfH){ihZ5HVzWP#bLD=i`1z>9R2y#Iirf>aHVrMJ7L<}SNDKM%K~iqPyRH$J zG>Qchf%0T56r+EAh5UaUAksh26oB&VVKb7&b)SC1ZL=}cc7ZoS%=h6ed3E%pxJ z0c$Q@eF&C1mzDs9B)UcSRt=JmP@>Ue|1R|R0Xt*ER@rGB*d+=5aMg_2@PxQiY`)WU zt!$c}CrV!}+W`9G1@vH4=Z!+@8ZLie5{Go$>BBfKDK^R_1StJQ`0Xrqr+rb-*KuyQ zs_QUD{Sv1Mp@H6P)d8e)m*9m6E;#)HUziMa$SrW0s;m~gyG|1dnwKS(qBgWI zCXr#aP?VBm`B4#n4p9T`S{bsb3(xcobncnk>%ErPUF|1u11lYFQh~?n1;_FCCM0A2xEWEyXIV{) z@+CYsgY2X-QFFy!?z!Uryq)Q>0NcKX%E4d{JE4bLW&C#sqv8fwrsqrjiLyS|*JZQG zv{z4F|GeLo!)*G|@4cpQ9%MJ^=&vH*&=EXGBJhys;0~Dp-2UXfKCx)j?qQT)C3{aA zFsYwD^daXjC8o)x0%bl!Q0P?OMFZ*tcby36abLmE`tN(tZfH?2FasqjE{X+1xGJUr z7A1*Kgc$l)uO)y)H~2pxp{Q!q(r?h7#VleJ@-bX?P?QTtT>@Tw9?&K{0`aB%n>4c6 zCwl_H&M&NlMvsB$enUF#p8mdQmQTpS1$2^16J z-TP8G1Ta=gthQ`?wOl8cRYA&&4Bq4Cp*u(Pi7&o~KU9)WhINWwzR$hveri^YzG9+z z>5ncNT~oaF>}+gxFKTjpH|VR}1>w|y+wAxYeWv|7aU^8g)@V9=-Gi?87A#!fpmWwch-aH$+u(rRoGvJ~X1%;(mv8-M zI(>g9K$5P%3&!CGJsR#?uW4h_^xNtw-}u=DJG0UxPPYDmaS2oHKjEyR=~|@O79`jx z6>=0$hI?)RNRgM`7Mo61!%a1#hq2f?-N4Bd_Es^3I;@EOq0)TMI6sZvH7b*a*U!pd zzP~}+CyXKXHgdYmRZZUU_YNZ41MIBOQGlL(pTc$O8A#?Wyvx=Eb>d{?j`k_J%dhe; zoMP{pb_aG_;8r_`|Mj=NP6^)?71#1bQI$70({jfd?sGj|;fQcFFqUjT0>zwzY}5-R zx}U`fJHnJ-_3zX;46>O3wb-RUJuzMc6~B|Ek!0HzFAP zZh(_NN5Xz2hXzy{;?xPu^GDJm$B?Z4iy1qK!`LvJI-O`euX~hO8$s_PE=i z-^6j}g|~%i&uw9FSXC>_&b+A!B<0aQT@k+VO~oAe>-@Q@d*%6{pW1JH3#-_$2(N>4 z7`3>_*laVn!7`1{FO4@K!slK1k1~AUyXc_b9I=5^PrhHZ?PKo>lkvQLB3-83 zA>BAvQ*{rXD3cYrhhb(8$mDPA|m!8wQXzDQtn^713fr5XKAWEn+_1l`>5-Zft! z2^=Lj65>jd92~>X9^_l%{214}H8OmR-owWhX*Q+SJxu>V61vP3#k3$v%f^od} zezg%%9Yo!XC9e5=?Fz>Y$xC43o#es;HsQAqBhg_YOB*>)6a9=-17=)Q_e@RQ88rDU zL+|ef3&nRU_xNBCS;c}F-v_4rG-`6VW#aCED^qW%*%azSl5vzR)}R+kPIB^lQv#q|vS%7Y~&mp>CDpq0s5FN}Px zU0`Qz?af;l&uHTBF3RAc&tbsELnYfNImnFJ2sQ%$DJN=(r45u69MU(y)j!M!BaEI> zyKT)CA4=v9F3S^M{J~hMmoRCT-jaA#ym{-=wd2C|Do1oDrB?V$s{_}|O^W@Fcc+WP z4j=RxGs?VcI08mg2evQStVaC-Hp{#>CV>aD=6bA~)_+v=YdBf- zjP+_jv(Y5MK(SjCmJbkCBw9VSl`*h?)6Atk?X;EjAfDXwsg-`EkOph`^uxpci=L1J zS%-^#h>PZB!JnspBFr3SM2WG_S9^Iz8vGOo-SM}@lqbC$f@RZ2P^YaA& z;n&dYjWPqnI9a4p_93#wBoO-}m1vnjFZAqKawydevd#9pIrgMAyT5W({&6iK;Doyg zMP%l!-$^{^Z)PyK1;K2#J1pa|lki;a8@xpKh)Y=^!~|rjynke}L4(*z(<0SOP7#E> zS8fZ}@miFtSsh4z?|G}8Q<_*xx%ph1n|2%09?}4;l#}A%P73;y4{-%^h@9m+lUJI0 z!})m)PO$N(3b47s-2jk&|8wTem;j;z7 zzq!ad1Y6a1iwz4p6zs{!CxW6qH}89t$EPRCIk(RcTf@U!#c_cQpQ9B$Xb*vHsN#w7 zU2pHDJ|(3%N$vEBze*17s1Z)QRc=Vo)FHG(nY7 z5{-Tzq0blU^I_j=`Q*@r*?&2-P_s;dtGFS7OiQ3lPnT98>2zXZ^`sI zW#pIjH?!FLr1HN(umJf-%%kxLI_!*KOB?Mwbtw1N%jPV4El@T*q8+ot#{kPlD=~OOKqaRQV)z4HJ#M?2 ze3;pj7=1+p9FGc_g+kd)?MQ;&10o)6IQV!SGHWOC6g)a)H*gh{=_P#M-KD$d-wJYM zJcSD4IN1Q_yac<*i0hJ<-bW;T$9uY#tmiEo_1iez^yzGw9Q|u6+c!qVVu3sfyj7%) zXCNK=>7~%{yRY|v`ckq*@(?|uPvZ1nA+R5=Mpsd7TSbDor>7i_%_jE~7y%VkJe6>ir`gN8*OBB#q%Oy6Ams|s{lf{{li<+U z+w7b`UV48jn<_vuy`{bEh3R|d8<1N{#Kt-1^0<|o>@=cAkc+O;B2Qy(Maqj*6l1*`azm=BA$BQ_pTHfth12^nmZlU42 zFxNcO-+t*CMCt#-hgf0jRtS}OKX4-d~v!An@E$d-1M$#gu6s2gn z5h_1-4-`5a&z1ZTmMJ%QV}OVf4>$5;RhH}f#D`nbg1+|=h4Cl)mZG^wi_(zA6?$EY zvgoB;kJi=g&~L={my_S{nfD;funZ>@AnZ?Kn?R_A2juuK^^469HoN5%EA zD)>n*+I$fa_fJmh2nm?Y=tT+i>XboAJm4hx#IZjvg}r9~`X>KIR4<}TSafpuLViN8l>w*PTAvv3SI3-oSfNTfAa1H zXzxCjKet~NexJSHV^K|4Hr!b-R*k#%?kIaI*~_ubVUYx-ufoStKCvdMQZ@;*mO*&0 zoITCYw=NT09{pNW&nsXg25OEoQ!=2A^f#D-uQMxMv%WP6J6j;nBa_u0X7o7mDOjI& zkbZu#JmI1qeWh%dp>#nY3V9I$Sc0=*fPMqWenQ`HAEj4B!M&KUCs3qS`1Kn>%J9KC zgol*x9aXY%=r#pz)l~6IDvdu0_C;+X3{(Az0NGMAi6eA)%=rl+@Ut1lt3vg78Na-X z9mM+>IUg_v9SsqI(W@Eg(~vnabuvS4@l)Fj@T_sP=}}bh^MU!LCiV4&)B3zTt@(x- zUuLJ?wFstLGvIb?%sE^Gh&P--2{Kivo9tjenVH4f}gLAQyP%p$n> zj1x zxAx`wV(wwZWW}ZG;%+Hp?(V>8;b`vRk(jEaHXuPXjKt4mSRj8uE5;=+<{K&- z!r(7rrLCpzb~5LfH%vRXzY+DDPLIU~hR}@(;m1Vq4UJDs-XQaHCj*0fKq%E;-bR!B zWhTI99QmNUeu3>A{qgF|11iTyBE3%^gXT4oVhX9YNwuP=Yu(vj!A*8)9^uY#s*h2B zhRxiyleF2#ikizat=Oei|4re+KcSOS`$SAkFdi$it|Q3L{agK0hOzDVXKHZ%E^{IM ztJWt`wL$VV{P*cTD=%ml{HPDxv-z~yQV70H7Mt8tDw|bPExxc`5G;VGbg&XK6k~WW zwP!HY!x%K{{qZ6laV16BnL$GCCQ-)pUhwA0k(M2{PaS7Z?Qc}k#Wo(MFi6*5c2QKN z&rHq0|G9W9kEm+3$QK=*?!R7Q6Vn_?pC?~f2#G}N`CgC1oAXvp+M-wQbCn)_p`aPe zw=$iT;OmiiXG%yCVOe~vEjKF7Yq{}Q+t^RuGiS7U|F*G=)S>dsvt*0RTnYXMrcP5a zMIb5)3IYw~zrjTNA26Bze=wEpY-~OM2Ti3=hHd=fO-5$_i^#;wYHrEIs<`Mr8@MV+wO3_q{PEYk>D!o~titO)vHH+Ow5Uva|`l zokN@e6sHo0RDv|t0s`w0FF%ni4T&(}SH`R__0V71sR1LUS|h&7W~BkC18D2CYqe-0 zg+4ZwvSwOi4nEsaLh07Mmk6A$%C~nP{)G~xjLmvv_Hsm3qeZPK_jKX^@O+oX?;{|P zh*o)|^YGFft9jSXe&QZa+aL3LDg5tn^ZMKkiv8_OB!;IYg^99^67J#Qht8~+teRaw z=d85W!ZlHcm_#LPS5wdsf%PAt4e(z|pnpIy(EmG7^#3hTS9d!nD|Zgd{{-k450BIC zqqH4`H0HzAOdo42-Gv#Gb>3#0E*`cY&D9Fq%+t-y4D>ieD5%>E3TU8Dt`KZgBBl!q zI&;~($h&###Atb6Uztg5c#%T3r=S+E)_(?kjv!af3@-QFfV@3o8(P7uy}SX!>D0_x zyw-tYVnN7-hWO5)*X>S-n|~IIs`HO@eMkiM+=_fk6DCcw9cXr1j}tdHhi z2=h!><0l~ernEw4y@+8lUc$Y6D zpJRBCF;YP?el9OVjeeUy4KUDR?DC@qsq~u?Uo2v5^M?ki^m(#6z@;U>|(J;u43dre+apeIPa5ab~x!mVn{WfT<(Q8rp$2*I}RTZlCU8e>KH# zoTtTz8|CU%l#z#tQvh8Wv=n|Ry&b;C8_nq!4tq}e)dx!Xb})=dpg2MUcNNOkw393Q!SL z+56==aK-dPFmur0L&ui%(A1osz3yKy7jR+5ER)eR;F_ zCOxlbokCw77PI+-hU2-ew;%UGCuE;rcs!8Oz)3~!*gT*04hI{iN6kv6K#{6&JopGoXE+a0lU6Y6<5xdX(YIqwz{-)jzY)zuon5H=Me7gDA{6{w7Mv zzk@x}ML6QRp21o9&&U&&J*4^yBwI&+LFc#+(;da9KzD1_M^C^6vf%e{BTHxMzlpN( zz7ivZy`wWe*iph`4GkMH>mFIL?B=stQIbSZGu!9HYy+V(AmrR#~)~hy8!)9TC z0(ZK=oghM&kfi6=^SymupuP+)vfA#z{eR2K8V}GAH}i7*Byz#9tFgq4@%HBSm#}z{myc-jhEMVhJZSe<*E*}jEwpc{aseEI%iiprL4d`2()Z5NVmA&IOKO=qL zh^Q)dZuK#uTT?mgdH?KET;Qm&D0`^Or40dxEJLBN!&N@O6NbKbL5Qt8xPrXAK@6bp zOe7A+sy^?9(;MoVY~5|GUVd^aLcFn)>~1%h=ZJxDz>!xcSJ~&<@T-(s^n6kT8of-= zG05&0h2sI&578(m3U=om@sF2k$UPSdmyJ_I`Y$s)Pt|a7KNt{+6&1HSv>6B*SljBNTdc*Lk44-RiB2Sz2$m z4x%!Abis+V4XgkC(GzA6w6)~*!&%LZgpg7{YrV!B5cW`grbDk_xrzUJBpt9E7-Z0H zs{b*Frd--TG0@Dfsu$b6PwBx~CuOgvGNcIcy-_dw@IzTtxfJ;QdE2A^sC6uoqmHScR+ z)9PB!%Mb!L9aHWJJ$CT2`_L>Hnz|z>xzb_k7RkBT%kTQd4k#X^Q5bR$Yf_RheI~$0 zr3jkvd;J*g08&3}m_&EAtM_{XOfjH@h=eivLZMZ4fQ0i^h6EV+&pcN!{ChDJ`tCv% zUf&Z|6!547=8$|+1CaG|LTz_X4rURu7}GyzvwbqKCTbIZRW-OQQQp7?d{#G)R=@eu ze-1B%TYs|$WeNuem>tX;m~pR-3tda>n!WAsZ)hYGN&+Wek(<&asF}&49B%lc!mlu= zVc>qf9u*~WWwCS`Clvd5?o1)uG$!-F^D~YQSDedlhi~n~KIg*EDh# z;N$*s=uLIdmT8E5cS*0q5o!=35TC!MxUZ+MhTLF`&J=7+3d`?xF6!;JqbTU4vTY57 zZFe%NLDq9N0QIi~en#bI)OPJ2jRJph~sH{1hml1(NAtN}?D&OY-MLWwEF=P??M671v;$!g?^{MJvAhiArzkjM2;BXDpKo z2k2@$Tl}KdmKv}xJ+?F1cRlj|{$|vGzyy-ReS`M^O>E7T#x935AFjJ+!c^ccIuPJ4 zY3a9rolJMp(Ylrs6c)TX4S{s6C5`hY1N~V5zHNGQ!^|72w06fmki;1f!l)j%o_mHv zS1LVBnv)4IEz-jjlQ*ql&Pocexs5<)phG%<%@>=2mPKc{3`m z^fern8vE-2xx!782sj9~6Ex^Z+TBaMe_@{`$^A165Zt_3dwRO>?CSoWpaw$O zqLnE)z&COYJf@)N7d3z$-c$ylc$V6%oBq06HCjR(J$^drIO-zDhd*MLVY5H);J;cz z+uRTMT22R1afKA>>AlEivuqD#a}7aU)IWs%bZH3fs*6A8ya2+g+IrBwvVH_Ec+Z{` z11o{MFjy8#nD6DguWEgmqn`n%cR#PZeX@;bR_pkTm5~068#}$%24UpBTf;sd&nqvB z4r)G0c0=P{uLK{yugja|mwXYwNt@hkkCUdKn4SZ1R(2)v0#YOm<%Y?t z2X}2*8ylMS`TES1;EvTOVe@7E*%htScuLIJar}B+MQB3` zgT9+vyOcOVnr!Y`qwF8eXo|B>yGG8ks~ax<4xGb2r{x4 z6wOnW4OYnA?0&fq{T$gCe0u>&|;;n4-Untg?M;Xr23g=tRiDQORt2;@_Txx3PemH#QTSjGvKu3n)X% zv~91QJZ(e*M9~9c1D?i5i}Ox4kcmIm_AZ1i%l2;$O`XbiMJ;4)e$u}09!nu;>|4AY ztw43GFrPmQoAn^%=846Ail|jOFEw0~Z6f*7tnBOMkO(XPj2AFFrNgxg3Wto12rCSsN_wIf08mAvhJ0QIl1A3?_|BS=#T<+P_3mkEI1Yc@h|2aJM zqgX26EAhm>+j^WhI*-G;Q8_bL{?3Sp=E%2k{y2eo=UxGE+A{#jp*muE-3^U#9hs7x zKh!*LqRfIgA1~Bz`J16SveHP4`pM&?w zofjk5Sl8~BMc z$SX2`QM9%a<$|RHI3IMt;&mJiKI&`8Z}it)ngT>Tq1`_Rc3spS(|4~&`$M7q^%Btg z`_+0tUa?Dm{TbxWiDHA?m1|?+(FD{}-<1yP&Ti=PUi?|N8czuFmGoUaS-;0yjO=~L z*wFwzaiTxM$D^BgD)1`)OI`8jjgVGEe|!&%k086q=oT zuhawVS%i&i0M~rczk`B`5w2UN&-Ou=t0FiXLC3Gk3(e-%ahdqd9>MV!RW9eOC~3iz zSt|dMNXiIOAu%&E2v4Y(7<_+h^Kk_h?D25L@Fa;!g}g?$2j2T7?|_~p$Hmawm$wDk zQgm(gnjgxpu&{u*BXseCE=^`Jf7;h4J%E;EGBLGc@) z4dZy1`hRESS3UU*3x2^gwb z(4`lYv*Q$21$EB8ba7d%2d<4LPtgba3!b_uBH=xc!RGi8^&zGN!a4z}~JSkRtqmJjkrD8MuK1twZh?6$NV$ef8gL2<7eT@WSZouxe@dw>$o` zu7eI%CEYc8B@=srX1sLEfZ)QD+K}#V#fDM%?zrv9nU>+>BG!i16VCk2(RijIW(P9+ zm^h+~#i*fGRnTyUEJXXO$39Y$;PAIDsWfTbve?==P@+&2(B+~44}Cen7asO;^%EKn z-O5qY#nwqRAmK#`MqqUR*ZUCqkPEV(D532O+>IkAN=s*jJC8dp0jBVa3}BE#LNQ{U z#lOcR7kkx1QO;jwTgI-(eVczylS8V4%^Z}#3j^S_P5#3HQw{jC46OLZsxd-6xnOH23WB-CW2*B*pv z&mQG6Q1&yvJc*l`&d^3J1*4K%4AWMI^$UgqnK606PZFFG5g+vFP5eEH=oX88 zzd_~tw5FUpPHVaaD}Sy}{X$)HjZ=6$%%vGr(ZJDvt@b15{l|mT?mbZ^iMOjY>4(e- z+JYxjzx(=+YfewbyguY99tuI6n7Xu?1E=e9P=3e{mBZsB$) zp-=Ek2i)=~T!HuL2{cbkY>T5lae9Z_uN~#eDxZ$aFi&h*YfE&Ewy0pIUhZznMmR<$ zBRS(Tak!ym_CzG4gHtIJfhIGMwkU_{@93RJ<&1gy-|HSq%l5P2I4ZGm3elNu&{Ojf zJ4wP*DSRph0Nt1w&yZ|$a$7i|idu~zn0 z5ntHKPo2@s$X=m}PrbGG^0`EB%oSu6Tpdi+@nSwH=^Qrv#W;Q zOZMv(+c@z3!Lc|wWpF~Qe&C<w6me@%$zUYLTc)m zO)b4~ClS;czbXDvTNXCs2^7G0@vf7br5&7$Y@Zl{E=H8xnCzbkC_@&);8bDdwPjR; z(}oh`Kk;q>ATvS*p~tS|l!n5_V#q7BxLfRc9U@@P6LI~y-fqFQaV+2E8Ipn}-Ld>ALs1m0lc zWnH}e)LYMg+IQDo2iBe;HHa-~f{6{sAoH&5{^xz9@>g{eUR)EfV;HhgG(d)mK5_OC zPjiRyoXXuazG@ouHzGObAUrjDS9T_M@6^@Lf%O9gtgv|@Vs-K9G>2y+RE3l~jdx2* z6N~Q9&##z=CyVm{cWD8xnw`|t16zc+x%mR-TCBX7P3X;Kl@ve!Q=Q^nF*f^^+V0oa zLxh>S@J{)B!c`)DM24aXe{zmULq+6l+O93)RnDREyxMt|7r85? z++R>nAO}347dFr>#}5Kh3JY53Nl*OxBr}%V!nN>{*#i!&HK@V~2~j;CP)X4RbLIEA zk&J)p`Z}TEbcO>Yy!Ogw+^X4Vv97dkYgI9{u(#QO*$U-L7sQLU%Nxm7T1=fr+0aTL zpryiX@6=9Oy}V%3(*(JpHp;52+Z6%W2RB4&ZF02JOxF(W;H|$+V!$Hc^ zbJ(Go*@FCNQu(6j4*+GhL6{eYuO9|Imp=)>YMD#3s$)>qRV>8)Y)gUISP8`wol*Au ze}UAu$l)ZeB%9aSc_(uvr7F%&SfA2BVp@)F&Wem$WNNZdlQavp*y7yrsO1+~gL}pkd(j|%v)vhTVt;$-#8C#A7jO_&vn4(%O#tFPMwxK*XMnvhlLYonX8t} z7ymLr-I>S}#}UB|zngCy zCuM1Gj}eK{+!RVD&(-FZv>%}Zs^Ubn)n?mZ(606>qeE52xT4qO zK309&#wOM1pkh;M<~(!)=8IifFRY5y6$*F|)82#CKhu2zLQe&+75|9^>pE+DC5tm@ zJ+)h8Oi>EWrQJ<*-lhJey^^3^Cu#I}dMZ9#+!eqEen?glSf26}V6D$gEyNGNQ-|V| zc2GIns86d1u0xaBvxQ_~v8E4??mYcH&2xmf60Jey$uYWo*Uw~Da`cP30q5@p{&buvh?oB8sOz7Zwr%X zkZG&UWdP{mm}$iyRJ%|!GyBtW@HGx{xmfRkF2<)YWQ*(dQ_EmqQ_U`C_P%C@Z-ZLk z2SxZcD~AW;phODwk}4d~u{lEY?bkQ=?uH=?K_MW7L$emzgYOFTs~g!{hXxHtk1cz4 z+7QD-ZPoA8US-C!w;UHoSqH!bO;#JDC5#fEm2?)W4$KF=+3LdPv&TORkdOf9hkBy~ zT`Z+8-^e8wiAo&xG*di|M&M3=L4BN){^8tK-ju*v;3tFN$F4EC!As3Qn zY9l3g*h@|>C~P$nfrP)o`j^W%3yZe(G0-UYDXpjZRh3GaD8Je-nk87D#1{dC6KK`o z1$c!)QE^qYZ5abvw&nHK6vCQ`GvL%Lr}7B8Bnq%7R4G)VFJ(iUS!I$uQ*=81|7whu{7 zw0$g6M^92T3l3=*vS(02b?N|cu=d@X?KdsDP8F~i*>Fs^Us5q8%*cG=lN09T~YR` z98GPy{PauFJg>E;7gEbt9fDfZq>EE+F0aIr}|mxSPaJ3fg6>DRk%#^rc?o>B>4Iz%&yO2 zV+$+E(?*GQ_m)h&pk!Q}r+zPp=ys(o9QO@20lA5>Q1LMG8VMlVWE@-omLu{OVR-yK zD1|owo`Gf`$`wk z%q3sho_!lRLIY3S--Ksk|8e)@z1479t>%4^OJBIGA%xgr22B*(q7j+^hwQOUa6Pmh z7^;zxwtU~&%cseih!WT!5*G$#5BGoeA^C~cF&c}B;>d&&5WC~3?=C#^DTcVC&#Nsbv?~KC0n!ji{Lf@rpeyMQ3Z&vWoAT&}+3BJ8~Wm>}( zA>}EW4m6bsFVIkr%FA1!J9Rye*Tg4^md$4WXfV%Ty&{r%AkT@Y;Ly;?8eRA-pK4we z0?a!o$flnLD9R~p%VijSEhsr~^X}&m!OC*`_&(i-8k1u@jf=|ynKg&OmjLj~nZ=SA zRCY~<7~sSgdzK9`YJJwDOYU0S8RJ##)d?M)k7e4(jLKCJ!a=?_ogRSfn-p4pJ22e0 zIcQ|o(#e!rGHJE_bV!$Cl}uSq4Xk-eVAZOWvv?%MDc1UnMz1BV5Gn_!$Cvt@SBW;*5_P|IAq$EbE&r+9UjshSPc!7nt&Og7e`$z_)krHO}CT6!SPqJ-UKzj2%XG(~ZzxbP%;4@GQULjl5 zT15?^*{&GyglzE<^?9rHrNQVVdE6K!x-D!qnK}(Yp}7OQ`Xk}9y*k=>O$iq?z!55=K1&wX!>!mC0 z+WHBkU}iFV$zak#9t z1LTE!d{hMkJ7ssZii<$VnY}pW7dI z`GKiJ`gX##u(gyI3e=uGEc_E4)Lrb=pS% z`n|BRZ9$jm9qo$RyKD-{8r#E9=MGUq&M}z>jD2@SJaT2VrmQH+YO{`WhUEa$YDlC0 zBE^~8PhxjD<@~QQicoM!nRRH7&l1DU9M{n0e8b9Fa@4+#(S?x{|Z^geFQMI_CK>PEUJQ({9#`+Xu1r; z?AsK2!||u27KG?MK9zcu5J<|2PIs})nr}_OhJe_v2?yY&_Jbz+xi&enU7!)lCF)f?P zUF=9(>V&QYAV%c#DS>7%u7na$vXO`<1pI<=RE8eF=K44>*PbmI&Fuo-1s zk5edjUzTE62Zh}GmAfYdA|iP{Va#n$Z78cbw-k~*?aUb@j*iV?L>@u1X_pii;>suk zI@_}rpzS##xQ}^%6XTb&Lj;NxXIQ&!Twk3BXq}P9RBv1FXx}w zENuPyZLSSXpUnsPbEp@UGU4jpE*>$S-`|aib)-~>m(e-+BH{*K+gj$ZT2Oa%sfy`T z3W^-=ZgUS0H1UclHG@)i6%w!`tRT)em&(UW!A@;t6LxVwY5-^lN?8OeovUVZ-r-8E z6~PI9$6O4HzI8=0UV&>LZ*mTS3Y0;m$EElyez^9UF}kxs)}j<5cNXy`>EkbVC!fJX zK?O>K)Z@ajO;9_h(5(DAT ztdCR*>qH#!0?L_0f*EtKgi7A@x&?|gv46hadzH9t(D~kO6np7cLTLsi|KVXdG37Nc zE-6inn=ThSXjJu=whYs!KjfEXypOBv@}{z>6lc-W0gS@Q6HI_~x!jxRH`I)dGdTDBdH;E?+K? zVCwDb+_3tu`PNE_7^R5O3nbUti2M;V7i@q9@R>P>^FUgoMapEa_FkpBD>@ReH+~Nb=2<|cV4nxZ&hYXb>>G?VP~)GI$-32 zN6;uudzsMxu&ew$DUbUF9{Sk;kw&7gN4i~E1N42DQB@yxOgosVjn)#altq&ivk!3YhZmu85 zL4{SFBC54LeHSVx`vgzry-2mr&z^o>w#wi^TidPl%4QD9;)*3Mu>#@pDI`SG^4)&( z{7&8X45!P6SIt@jUpIt;4d)1DFyGo9&DoI8A#I}9Ks^R}ac-LFej84ufw_D)H)|_Z zQ*ka~nByay#6W$Pn_?gv!d-=s0k2JH->)Q~8nrNVIMDVewE|%YSPQX{3R0yJ8W(ju zDtFHp5HOua`%3Uap65i`L*&r;-{o`}C;EN#tCQQ~O4{#o)$@kC#pU`ZYFrxR7bYGk z`4%HL|GH}@KZ_D^N52)8NM+~@V%eqjm0PvNe93UaX_kQfX7wx)PL-6u2T#6PzlYCF zSvL0z&;O>6+GnRdN{fCdN`FuM^oi!rZ{g=Bx7(ZbM`PYL-X^8J_Vmx|* zJv~QRzui>j>4x9}T`3#>cdfCK(QGk0+Pgci{vqqB1*O4Ey~92?d?iadfiBTJrN4pd z$=7r9xuiA82>L~nnh77^6<05l9*M&5U5;R{SAx`D#vluNP-7G)L=hHTIWQ%-t*#L%rjhag)Nq z8iwm#XP2D(A!ZzLPhxJ*Pqse(V~waXvn!jj(z=fhI#C*mi6J>@)d|An18qvUBW4&m zdl!L{Kc)+kga875$4M!~+%D~0b);xshD6%F1KsrE#KZ1GE?TLsY-6mrtFMeD0dl_t zfAW#-D&NnwAoJ|xygr59tX;J4`TK~H&8UlLVkVzwq@rUtI2wvGzY=f@e^>fu`DW^5 zfcba2z0WfrXaH7Pp1~$mx&67_CU{!|hiLlLK2P<10p_4LX~%)i$^vh!!)BiC#Rahl za|nh479E}bafj%ub6K23l)UKZh2dEs#l)>)LpveRRQYF8y5)zCZC66d*n&mjcd-jv zzu)|aoyV$tE&sN7@jQpyjE7GSnfXc6+d3pEKztDFdG^+V7<4(}V!K`Y#l0|=5q$V3 z;e9+xr|EV+Wr}WL+_xiFxVR@S)=+?vbB~-dvf~NtBZ2Cl70laH?6OGaSLTf{(IM?4 z|F8)LWZ_f8pnvQnD+y$_3Z3j^uu;0|{(nsf=y0tLOR_a6rN={YO5^1xn!Fy>GCW3@|i)R9Ye#GQXBPTA!>nMM7%@;7}H z9IKiXs$wF1S1=B=W0P1veea`mW`)u4h#wk9=ZQC4IGs^e6Zu+6I*e)+@;FX@)%c^D z$3Ec-JVnZO@SYt`wu}i1Nbv~t6h1Jj`W<$7|Ms#5V+lc>ef?Vx*SF}CGkJ?(mh#AV zIRn0RzQqEn6Cco|C|*e)iMAi%CY%Taqg(={6m6R zk5_wF50+0`YU3FT|4f(XI`J!_{?yNw#KwvhJG$9db>f$S0@ix|Z~#Ns={99On)$EK z*@jBP;1U``xpEtg{+PPV3?bokS@l=rINlLEO93!r7GS}&PA-~-qiG~cKaz*R4ea6>Kz` zu+r>FhEPhSE6YJc7zQpk>;W?p_0MsrF+(6!I)J#B@7p=DNEhR(}|9Qu*IN~!fr^@l_3 zQy{uGH6968WnvK3!`d2sgvJkxr6)dUX6$_aPJ~m{J?Oz6qb+aSP;03I9nE`!BBw9+ z49Jp3dFF+^-1mq!9u}Rr*ca`xIF4}F?7daqBVV0$ zUQ5?KhIJ}aZxZ_24*}1dGy>Q1;v|KA8ow>RccRB?sL&G#u(Xc=V;49 z5QUA++~_IZhc9RqaFq=FlmzNdeO~mI_Yx3=RW=g;j*{5~XQHUgy?7Pgme{|cAF?Ap z-?KI3t=H{{oW>0k(yq{JiJESA3VXAX>8^*rrP3SUBVuE5PZWlipeNdxXOw0{Dzp0u zO*&L`6O5T{i_S`oy{RAQvH84LwW_>zCWl5;6R*1KY$XH1K4t3h3>M&=Ph%UfZ{#ezb45t+`QZ+VoH&h%pkTQzK23lHOgaQ%w zf($zSypAp^!W^W+idwAQ4V$SWSAER9A~A#-LrV!0g-Aim3={ez^TL3v@HLoNb{e$l zs@Lx*gV3M*t+w*zYs_6v?R{DaY2ACTHe8H?kw&Ve{ckr_Q$i(x#jEFbqB{>Sn>-fL%-J^M}1uEf!8m+fJwRh#ijWTYepY0pJPW6%|3N8|5(wj zwONvoH!wc!GJ~^8wE3xcj&I-aHTl@7KW?6X62rXMkwU(`LFA{F+di8bxL-)oyy$f={eRoKU!Fi;CVp&Q=5 zFtY4%Md8p)C5!fgJ14`Pp%smeXs}WO!!xZ$sBP@WTPN=&CusorWDvh)7J(pj(-x4s z=_AF(5}Dus%+w6@l2T?eTWw1h{Xq*Q#kH3ss^3V0JjHE$1#+thgI>(0(k7iZ9pYt{ z^w}^!B1FqTbA_mz8G0;pN`7adSS&_zxQQWAZyFUl7y5s__sgp`&PxvPH{;bL3$ha4 zC@;eS^cLgb&AfCMTLVa!%?h}Yb@&guYR0ob(jUKp1 zR?XE%y?nOy$X02pURmX4Vp1q(7|$cu@6h1JMBk>(dy5+8n2drb2(q8~Z*}TBztx8nHTKpRg$@dMpSPk;utM6oYm#uZpCWmtc!g8MCz)6 z0!T((prPwzx3d14xw!NC$-2~ullG)4LB4+f8J#!GySt2gucgxfOK8HtX{9*a>QFK+ zNMUv1GNS3-<~QPPLGlHsb1h!u|u@;j~{$BKI6U{-qj`AxodGXg)x^9ZdO$0_R|Eh`jIP%;nOTpIY)l|mZ?@% z-A?@KvfVBN_gIzJDB+|pBcOxX(F1lvYeYFO($=_;b$&@pQ4xC>2@+Oy7ax=Ln2S1E9xw57Ea7&h`4-5#<+Pc$Ta=ROCgl z&vbk}aOr-*t$b3rBj;DYpRlQLvMWz1RsiKyVwVS|8n$-T^tU{Qk7K60JyG`=-HG2Y zXplR{plmhT!3}jaikXoM=k`0DFDBf(I+-p^JczTN*NU$Hyv2yzZdO1qm0g#CJX*}M zY1_}h1&=HjhC%TlVV&RVTlkA+;P`{p^>;C4lo5bvz2MQYqo*VaAoo_qHO^8J4UfEr z4;^_ymkGUQ(0+^9fqUm^Mx9EVsEFsm;->e&H&^r$UX@G#G!fdwzm4loQA)e_OS7rI z??pP&xp&mFwPb-se7Q?;9Igt+q^a8V{%1X9{%+lx?WTgzR0pS}f@5;(t6I}O@}`1@ zviahhYIE5|UB_m53fk000c%mG6{gWqLJ{sTT~khTAvRA`1{+=f;ATe^#j|45ZQu@& zr%Lor-Z+SKY_%HItd<16kn>_(nfhe?bIIvlJ;6G0Y)j{dT|Ym17cv4?T3tmd;>L-I z+4=A>rSG4yJw#Ob(-&*DT^UQIa03<1e?}P*@ssT0@~ltddE^(G^gD_1lO=OR|L|LA#Mq zsFB>RlpS)dL->&MDk7~tN_9W5O&nRnox=*8@4ji{S5MZOp?q*gmX$u4svKwCmW&;* zo85nua^F||>X5+jGkYh`#QtOfDgq2lgd?Sq2y)=iPVlV&*r8H@vU>QI-cm{j*n)f%> z@F2Uh*u&&lG|SzCi~1SDCWla1As4NTX^>Ex&!e;=U=-?&D?t&3izM1>C%)ydS7pud zFlCm`YEEB%{ds^EO^?|ST6*nW%{KOAi|%MQ|mtlmB_r3)>R>Qucn)-``hWUK3P7L6F~^ zxpPs|h+VBUoXQ}FLttvt>B!P_lP$;YWg+#WuDz@b%Ln2%&%8giOe3Tpv;6^8lBvme zo;LVU(l3wiS?K&4H{?*?F7$ih^KL`~`O#a+{WW>@c)gE+`4YzM@Hq^r;V}tVTPF+~ zb7dq-Z7j>1&yLH`Y-eIdPF?gf`;0LGeV2M5loj$(Qh{VwfaN1axb{0p!$>w8df?|opoH@J}q~g znM!+nKW`(KHa)iwR@KFIdRfyKQh0Xp9e7p(8-;Z>ZwD8jh3}#VO8lGfVknp|fA8%2 z|JMAtEqxG3E7#XA>@LhQ?1zzMn4hmf7^KIpHD9h@J;?jh;BH|eA}t*2Jd1=?uM9!^ z^)VY_LV;)KhFgE#vCijS#5?W&cBFn7KjhoNSV&AIx!T{X*_JgZ;4y-Urs5!_tCj!U z82=qh%;fz^9sC?O#FTfRr;PlJe)3kiJ5_Be8Hob3o>?maJ36H3eR7x1o}#&qjc*#F zDb5WYHd3cSb0&Jes9iHV)n3}X(iF`q*qXalD830$B`uBiMH>Yf^IxV?fHN7txlcR`&JinHl7l*`^By9YOHGDz~|6_B=A5!{~qj*5Ne^PE!rHbkc8a(P9Ea{-=_0c z0pu%VHd|ZO_cJQ4h}YE%tX!ofE7x4It>sv=Rtlqp9QulJyL?A zo;m0uCeyG+;^_J`;t2g+&QiY3R9SJ9qFE=js!NJ6c%|;YvHX* zWF~NAd>xzt8N=&M&i(Zkq{OMfg73p@CjQ&^+*wUpz?t|K zn!0i;3*facY6{`*?erUIUZA9J8}!oW*LGDv#mhJhOPXGTB?Sf#e#@3g(2pM|vu*#> z$WS}s{*V12c2{)yx4GzOvCk-CU({v&%>4h){*U#{JbWgyV~b3rA!a%EXG8Q-+LU&^ z)BU2u_AAj#ELj$y;oitcAgLe)1@7M`PsyTs?%;t;1xr!)yeiO?4`z|bID(3&T#9tEz5m-9M1 z?-YX46TIEiREp2-Q(=k2g)e0cx7+7pcb254aXG1qeo-5NAK$7vwq>>pku&1bjH91< zt_j1XXgH3%xdf_pec0C`JZfWUX^S64$m3{`W)b4juDL>MdWAFlE3#RlP-Kgki*LO~ zVy4k3^(49}H~&^bvWR&+Fu4mPlx1d$zdx~5B2JQzY#<-FR`;Kk+Ha1M6u`w+;`iWb z=oqNTMgPyS`=8#YTCRz-ZfC5Ot)(Ni@vU0s&~7A;cn0kgzF7?b{a5s{Hhz5+I0h=I_Q2RCX8m6094r0B&#lYgggLln@~E0%e)7-Q9+BVe4HxKBJ-k@!)vjoiF# zKLG(25GVrku?)-?`&rs?Ted&3(H;(;YugS}nNG4T%L$Z^rz$g>G~*xS5j4~udKsLi z9^~%IhC1?f82dct>j@xoR&DXXJ=p(=b!9lp8)oH0QkPE4+!%Tc0|dKqoo+(CN`x%D zl8tDWPSu0D1ts~&+=XhVw0*d9rx4kdgN8@DBhK)~W=B(p-Vm-KRSvaHG1A<-DIsDM zRhO3?hu%g`t7hotwwVBsG-^pLVfMb7o&iS zFXq3hMQ?FeL~O^XS<`ejvOLJrc7VdnOzY*$-yyK3x5F`MxspVVd5Ki zKZ0>hMhxJLrj{W)ppB5%fmrUEMK2iT^yf&9OWt&)k5ZJ z8YRr{;2%AvaWvVRxQMb2s&T0$Ek2zfc4a-sY$q!YWd&gHtRP8Ib7#DFqGqpSLL^%V zlRB0wxawtXH>Jc+v|77K5Q#P7x<&AiB}gGu^k+@I7IN_vzGV9?*UJQriDsrQANQ$a zHm??MUGgT&d6SP{a2c8usCzcNSjM44U~8DRw_~;Bp|wm`tK;A%`cv7|-g)?>H3;Ih z)UpF{hWF}B^C;d_=c@0YKB&pQqjZI)e*>W5nt`m8H!+9q9Nlz9_m3O8itkLt;BZ_MW$x|_=Olpwc z2#8+?C>8jW9}9o_>=rseb=z6YW5T`fX20w_Ks3(X!4$4?CJ(SnD(_jnOA*mlrb121 zh3D1g6as>7ig%S))44I&E@D+0R?U+%cox!cq%3*&j0v(OqHLK#@6Dz|e*c?T{v-PF zK6RrXA&q?lgNCz;K3``BKsN2}NJR$Hw`5z^aNZrHHCMzA*?woLLqZ9jJB*pL+J^FygtS8K_NawuOj8Y4r`Yz-QL`9 z(?{lC56tx%e|+V6HibQXb#Qcd9^~7=5~(Cc^^GJ*OMTDs&f6;wcK05415Vo=jToiP z`i8Nm8!P98)gOH3>J)aVS;^X%DL|@|v(fUJ6|Of5g)-fEYD0aPQF?cGnJcPW#(7i1 zp|Sck9o?Q3MYFm5?lobt`xImM5Ux+ z<*JZNZ8X;m%}f0y*w1dIfglJ$;J`J! z(~FaakF4ZraiXTOm$EU}`?A^1Su9fp(4f_^3>}7wilKM0P!u(%e!_BPs>zh$EE z-8ey}#J;qK?qhY$){3Lurvz!*!bx!l)Bcm0{oqwsi`7O0b^2xbA#p)7y4cPy8V>%U z10B5*f`<)j=~JHUhY3hFSt31u?%hK7a_+Oi*|ZRLu$F07rN~^kSGI>eNcsR6II?LH zQ0i`h4BGX1dN$@=zFHvv74)Fm<5cLGlsPy~?Yfexj_i<_2m8b8)KCj!x{_oGFs-+W zoR`(s0h0TLP3?J^qCRe%sh03*cr;B=h_i6#zIl$OeU^aQCChTodb)X`c`XVKu0DM< zE0M}i+W(W98``Z8zcOx} zoMa6oQiLB-jjhK5USqFVu5jCnx*I0bTF5uH3AH=j`tpf0G0wsRd8ftdJcN>@@>qqRP9=x%-?S+= zwx%UM4^AnWJg#X|sU`x=)h&m$ zVUdKu#3O_qoY!pl*|@fB!o~_{Cgk7jeEZ(H(h3-OUCTyUJr!J^v{1*f%To_b0_n}_ zS7=+Pt{Q>m;$6sntp1@h)rQP!)2-K|9Z>0(S_$ZA2&XP-7pmzzXdCDGS7(9y6Gzvz zt}JKaQoZqLh+`0Inls)ilZ)t0r!+~kMwiXyj{4jwD){g$HA)4-3spA6U7~6T0_}4i zv@n%d47Mz&PuY22UzdzhsWnWQn%*h)8-F!DT`XT+QEw$~7VVit>2nr<^FF5<+gSrh z9+pZjSCP(wI?5U9qFPoUKB*%QH+4~(-ru?__S_VwCL#WdzXwe7TmPTEG>8ZA#T8sN}I&4f>eZ1vzb+crv%Jm$`*&?FNV_J37x-bO6T6w z^SqIS8bVR-vRk8D;>fHT*|9fgaUwL^q^tS%!X}nGu=t@ZSlJ4f??ZgUYOPRIz7Gqn zRRCWyKHJ3b4!BehY2GA-wD@-x5MUtQ@~_o7&nBpP=I-EDRNw8}7^`p-#Cyn?8JNTF za|0Li?(hX=4T+}|NupRs3D*WBQ7qoQ=&d=T`L)Fwos@BgLLg&OBXPr`-u48H7vtZ5 zK{eL7u{OPH&zG9qZnh96AMbA6TO&@?7-jO$$XA7+fp(D$)9Pg@ghms4!E|aJ=4q^2 zxfVXb1ml0((gq=P9C)lQ2`;#e@)X2-sqips?$F{7n4zM+qP_vazcSx0b-HZOqJ;~@ zu4K_f$<|n$>AJeZZdr$-c~f%t{$=C5HZrPmSedJ4jt{WWV}EoBS@7keKdL^j>>_(;>raD$Xw$J||HJnszPmt>!h`N>(Kir@A_IxA#1_)h^m(^~*H z{vEGJKlX;g@~$Luw5cxR97A%e- zfkskdZq>czmYare9bAj9d={I8?kc0rk@3Az;*;q58wyvy_}Sm?!OW$TjWNVbRtknm z?#{tD=P-v{5YR#`yx`cz)zg(9Ju1}>9n-&I$OZFsRV<-Q(~ADOyC+r_!73mA#$=33 z8C`vz_oZBzZ2>+m;mFUQj5Jkz*m(0mU@wc+mEvY&nah1H@Uk}arzqrbE8o;g zL@lp}J@lR6MPPVWh*=8k>hu*;tZe8T+IUjrzy)}+A}`Y$PN2DKq2|u@14U*DY`}e( z!S!GkBen33Pqr0L7o;+bcp(J6r1hXI?lDRvGzh-%7O=+1|I|wD zSHoBMl_i93yi<@Ml%Xcn7~pDSZ*6l)=F_Y46Afh0?LaT`TQW0{)pVD$Z{)ac@ung> z)~HWqU_Fm8rU=;$Q6#)`RR|0sziA#=VfA7W4C*XwLY=;zx5Xr8nWTpc5-h=EfZ z%(TD2g*Im^B}P+?zRrt!{Yk13lBT50cJ|)~;bN|3L7rk9Tm=A9&<-CFiR+YtA{vKq zLkg$eHb{kqLik4@3;GoEQ3dWQ4yXu9!DE+-ak^@QLp#{yV72n&^-H{KDV9OM0Cv29 zFu|WAgsLlCKYI3ko$(vzRJzAS&egfsD>5>0w*G2R<5#El$BuZmw;11EP;%+&2Dy|) zO)&-k&}jc?@!Q>>7k#VeU%wQoT`cu?9O$mI{2#u)DLfM&*!!(*+s4~=YumQF_14(h zw(Y((x7v1Vdu!X++UDv1d^hLnyO|`D$@AnUnMr2mH&@*vd!S?VIS|@MGbJFq=X;My z>-?k#UA7FtBH|=c#zeYqZZKj9bvaZaM@wOgfnHUOGmIz zIAx(6bFG89*N|W1E$sr|z*$abqN=3(vqCyzidPzajo$c7$t^N|Xo6~udL~zDCZUMB z<*3~L^dxcQKF||>`C=W)IH%!gndtxtUadb#-hmkc$p>%6JeQ{Qoe%zLz?;o& z2&S?`KeaDHUFA8=M=J>IV>}E!R?To;CLBjVbTo6cy9zi~r9P-bu0dQCuS3hgbY2`F z1O_|7<&f=R?pX@qWRL?G_ta&=l$!1I$ULO0F!l1iHqr|4Q+VBaA{)JP5{i3Sor*3nC)BggiWurJwAG z=~qGJ#_|qSKqH>&3<|zb4?8|bLPaDT?uimh-jGkqb%K0dCgi6iMiHJeCA`amE`#}% zt_^)I4}Ov@v&LMH%*$Ml!Ys+5{71?CA5@I9HssJSM#1`f_}>_UYM+u)I~%@R`eAZqDa> zHp4!N4o8+Lh_eI{Nvw^X-&egpdFJsM`4*C z`!7nFhD}-Mb%5r=%-ny=H#}0AhE-X}>v@bPv#5<8q-X*1cz!!u+oIm%4Gnxb(Xp&o z?kFX0-;3j;QZ8dtcF*x2egQ1-U{yE|ERJ$~%;;(Nlc zK_#INC%VBoymFL+w(G1`C3-Z#rF;rF-9tvVn67o*QX z)t6BHHQ;xUUyN>l?N`kJ#=D*2`~+uzY>4~ZU>Ke9a9t)%@W(u-ArRz=E%XTi>=N+& zLFMpqEkX(Ggb?~fZba2D%=xnG)!vF|${Zy4ddT&=1-VFnvjM7H1o~tyBK}q7B7I-e zgBZe<;0CZI$=Uk_SZFvRyb)pc$w9fGG^)26jZ3>pacvhd%p{yUB`gre_-|>+XzK5& zrRHflnNyJ(42%n-JOw z`r?@HsUBn8)Ryy@cZ4zwZh0+;^NwV_7X3uEL(2pAc`4lQ6NYY{1^FJ--}^WE@d!Kx zEqwR>QLWe&>~DzJJM2A+kjFp1Es8+4Jx}Y*+e{UWx*P>?&;p2@XH&07_jww*r{E zd5aE;pt>xYK#*NQZC?8cHC=9sRa@9kSxZ6aPrB0w2>oq7JB8THfwd9XDLq;#=ZT*; zK%ELdlEM3^G;C9+&YM)m`Kdg=Fi#o}a4_r0*vzh5qCbb-PZJJ0w1P~+1{1>9ozGKt zoSI@CFj$}(7VkbiO5df%{!!Pf zz}#~cl|*VzgSPrEhJncxvPX6G$Qwq0d#)ev_X&RZNi~+Lvk#x@O-1ic=F?Sx5mYM* zr4)qa!J$^P1h~>d?CrJ?`GB@?0(g_MOu^B=>ZZ67GcrWQ&^S^6YJ-7BLV!)ulqWsa z$f^&mqJb?mIsPh@-OEU-Jk1o3BIR9$0rYsAX^(I8^(2DPRNGhZAKrXw;CO>oJqpg( zp7rC|2bm&_x7ePC>}j6Ld99>ZZqj)Nm<^lcQ*H7iURC_3&Sa-{v^GE=P3hfp-ONj6 zizrq9GPYZika2h8%*(LPPD?UnlM5~fWjnuhoYn<>u&6uipsi(T(a50XyA40>@u zDzAbppRy7*pcD2rgs|2RcnN}@4*}duAkoGH?x~QU&xoAPdOyS}WlRcx9ud0Q6s{1o+B7!RI&dm2bi4xi~=L3~y=B^MwG{cxZL; zfEUgnFAnyXe{JrC|H6r;@zx=8NnC}8Ti|$wE&}3QF_$jCIh4nfk z2+_0fg@-7aDc}X32!4bWeq<3d=&FAE4K!a9$8NzOj3R zu#w_?Lr_~ynob4BWaJel3RYPTq)HOA3zMX?y!9jV}YrL*Fi?+F0+N({9zM=8uD5==0j|Cm@R{EhV)TxworN}Tl*@9<~ zkZWtPwwD0|4=)sL#~6cqjC7dYdX-NbQn9;_N3Oi8ZZ6>;+4R*DL6Wtbc~AzSuhfqH zI;zW?#1-e~JoL8lD4N88acurzau>g-_gBcM?mRP5biu6Wd#y}=qvV3Z0>}*6Zh$hp zS@%w&%pNl(d+LbX2-TpWQsMHcjFqc4vLR&P2qAxLIc zly#=(X1J2&f$!nc0nKzubZ}OjpFW0&!CXFRENOu@_8^)5fw6M=cSiGSbWlGITR(jx zbq~t(zL)@9{;(6S{Vq)GHZ<%DE&iQA*rGMD)G^KUW%ALx8ts?qsU-FVZfYJZNrKOA zSmQn|y_YIVh>wfBU~{Z-L;an{Fz&#^7D`&xOBVHLLe?q7Y!|jblq{25RGKiD%_$^- zTQoN+_^aBIPSuA9)i-TciBQig&w@UfR4n8%dP2$2z6SVkmC#@ROZyEppFoi`yyEvs-#5NS=eK?KI|%1~dj8wm=kxCh{5k`|KTRho<^_?Qfr`IBQDrH%e60?^ zZVV{`*CQj=6IFxltK z!cLoe2JmV`VAuI-O9(cqm2OaQu*Z8)vF%?Qoji_SU{#@4Ht-KPGXL^{TTh_MfLazR;AADfVCg>R`*t z6r=nu&aC-4CLstiIhaQPY;QWf24>RPK;XPzTKdD@F3w7dsaRU^#{7{}cv1BlWy9Kr zwYi=OJ(*wGw@=*QUE0w6f^BN@&aqdvSIt>I37&<@qrgEJqkl5w`>aa$=>B@ek`c~n z!fGpx$6B@?T!Tf4QEad>$79l+=*Lp+*qcJ*i%ke1M`>11qE>8sW>xjiDzv_+w%Cor zImH79-a=M6#o%h|Tp3yxcFIyDc%TGhju_bOKX>4EQ61|=^|CcC_rpQL?|tXlljm|t*F#ahQ!=lFs#}SZ_%OuoXbAxs&ifw z*OG3j0RC0vQ9cl&)tT6)Cpqn>jsLe6`Q(RwL-)_S;`1qu;hd3Bxs*DU|FHj?_KUMT ztQINRTOw&l)vFTh?g^b<@C335w`T`t@^C8tP0QhwII))T4er6dNT(J#ihae6c}h*N z+8>ueZ*}le;JuIg2y^jon*e9L&x0wYT-RX@hZi(1^hcrIa!uw7ts@Ng?gcxW1)+f8 zV>vsCM=2Fk{7I&lH(Oe%rk_RSPV)l!V<-fL0a<`I=4%5sk1YHm{_+qE+GeujdDgyz z?eowGhD9{yGU}R=I7fqm$kUUrrXun*E6y?2dUqC&pH!b&L7$h8BV_DXq+HpsWXllL zE4pN;%J}!8gG|XeFQW)6xMjEox>Dw`d$s?f3_WYA(} zO2}hIjiXb;OIYZjhLX7A^E|C3H?i9JZ$SN3xcS}G>;Jf!Us#%;nbG8BSAitUa;)HL z)UpAS&6^1FQY`Y?gsQ^)UVW*1oG5qo`R#0v*=0 zobr$YGm~yyik59IBVO6e0uqXul;m3DM~3k{-3VsOh~P!ym{DGzIpdsq*alTETgQbn_a69oR>Xw+3kZjR5)tv!Y#}7_K3;o7Ivzci$8(Qtd6}^%-?Gw9=U?FG|YBI z%E>WMM6ohGP%B3Uf|Vtxi9_hwu1VDs>7WbbgniRjNbOgM+?us09DL~pT#;7v5H^@j z9Jx$Omt0mV8V)Y_jnumhmx|nXh4=bH8B+YAt~(JcLS3}Qv}W?|dJInvU_YZXj3d>l z6L2J{gBa_noj5F{mPWEe$T1wyqvSheXxXl*3q}V1FXNfI_fEpc0x`(2$Oa+lEX8tT z@2sjqi&S@fMQ>{C>6P>C6&Tfq{rilMyQp|q_|XJ9;SjA^%#gu;NawIkO)_B^1A9aA z*`m2gEpBS}`-|#Y*&Aw3#vhvXvOvge-UB5F^yb&U=b_&6j@~QFCQE4D-h0?^$pNxp zcSsbe&~F`SPdmt|WS#nCo#W_+l>~pTs9=x#pU0NFwf;t{sVi=>MGS_fkzpk_wx}ut z$!u-f5#i{k5TfX%JHXt}RMw_|kl&#`y`ohm3^X2{{8Kf6)|$DEWbe*YDEdJjy2%*f z%#rGU$!&pC;olPAoZbXt7GjLAkOlovyO7A!is*Ou=%a&fA55sE24&fd`cG=80UjE6 zC6M2$oNcGE>h@YsAUIpk8aH4Z$?{ufKkmAi0$U!3XW)N^;(wy*EKtL9|k-aE! zbzE}+iHsAq-=Ck^Xa+OLOFYEB3~#(0{(BM(n&&9(JTgnbUa3M(CaHtr&WD zIA|%7`JdO!jsYB9Qk(~9KrS|hobv(Vr5kdd0nAMzIxr^Ry94ajK3!N-6ZXd-3sD(W z7$<&4>#){!0g@Wkx9Jy;Xdl5)d))x9CgI3UBsURr=YFgEsoGTqK|+}f&Mj6W*R5a8 zex0m;0&V3SzKnqYuh{S2C>t+I-S7K$m+8yIA2+p6>FyDO^>RLS>H8xhMSFeXb zsbma!6%h-dd?|AObvFuiqfjiDa@QBl9c9@{IYY)6IEcr5-5@wVSx4~3o3MW>VXt2| z5$y-JmiUQNoQ~HwrU=_D63W8L(raV^3mjE^ZX$2$hI%^&lQ+9@2fy594SSd(65x#cl!V{cM``M@UUQIUV8aO0KWli=sVwReOoMB_+9tGoNJ zE}fw`y%`qBr-cqej_Qz>q+W)?%a9*Tf1x8xQk_1Zypy|QY7xi7FO+5hQp>t1i|*kX zuy6iVOzDo5>&R8;fbe2UqvT5*kAvS@+1&bo*cRKSggo;(M7{c49cTOf)=@Qunw^I+LY3$%JS zg>&qfvmiI`y>`KBHtpc*aGOmSSK6c8=QwNHo>pZm3 zfM&a6Lu4MZi))HyeU_iJr0oR%ik|EVpWzeLLSLH^)_*gVD)}g<&lF&5O_ga2TN8_V zl$nqg+sTViB?S{v=%6M}&xcpUH*qYekrLWee$uaSQ!gJ351Qno>Me+{Oh3m#3kF=s z{G{BJpf%T11|Mpv8>24|5iCdU3=s2I#T+ez)D}BF!rw8L6JDd>SEO7EHY}0$a@HQ# zJbzvlv5#Nh>yC{7WES+(y_odqmgpoXd_~!;0K}jgn-2deXym|*ROC9Cf3^=U?VX%p z$nh0_v^(Es-xBL!A_Vp@pE`dhfw}K{C+Vf)MP20zgMCtz}72*;v zE{&B4>m4}Nvujh7(pjhq?M2DmXzC}I(zj=SkI#j^i0#DOTk~51`G?AT%<=#g0eJ{u zhHkumbMj#3AL^gR2PgiPjWW7d_9nc~&2gHD!$OCZZ8sn3pWfkP(9L@kIct3SoGqRG z=D};t=}2*l<`60i@4Q>XPHlQD4d><%8m&8wGW%}qKRn|7xX8^dy;p>zlpHG4$DrRG z%-A=-$%^tp|9-QP4<<}|sm+^s+k59t39 zQa0Iph|VpO%#pdLTG=9BAur-zLT2kDC26-Qvxelz`J`2SAx}~@{rL4H!B!DF_v|2$ zny{l<0ct@1oS+h1lA&T3giXDX5W3HTcHTt6c_`iMXcL6P&ugu88zmzkKQIWO=K3+}_RYmh$oag~|A4(ZwFZBK7BpI{7@FDJU`+q< zM?RhNU3%WX@%rG(w zU{sR}jx1oA#aQVJih-dp{Lr%e+bXZW4_Gd=n@cScJSYCjF9fvj zt|=da?p-*DCCgJX72Y#f27AOSwe+74Z{Oy-+FSJRi1+I!e3!M~O+*_XHHK6SuA+Mnden@zY%6IjQ~5OG-%cH1#u1Y|CF=uK8k2I z`hzxE9tCK;0l1w73PQIG!{~hBOc?fvwL!WroToneJ50%G&5&ufsoGiKwTZOK`0*+) z*YY-4{7NbBdSHGeV`O=1k!NkwztC(2T2;OZLJ7S--(NlR9Hzf;1V1J|q+QoNJ<&EG zJ{XB`Qj9baPm1w}EDzU+N&vxIWAs$C-b3YW-f1q?AN zSx)wfqC1zaC&^^$ALszVe^%8q%1t3qg%&l0G7(Q~1u4Xu@q9Z!(AI#t9B0Yd`=BKV zM{s>5t8d-uhqREUko02?5o6;`13jxs^*;l5A#AFD)Y_k;tC4F!6scjg>2>{-uSzI2 z(!#*y#1L7gjn#jA)WK}0JE7|#8kG^45aRC_dJFS^V*0#d{Ji433*dh0^m%KF-u+-* zXS0lglR7eXMO7;6Gb)Aq((iKW=uHT;%pl48H$$ViJ1^ER0O*!VS=kIy9|f-A9tV*z zH8+|F1#=}w_7~NX3i{K*7&LD->V2Aq3&l``<8;1JeD~*A< zl`#FQ;@}@#e1&wk4kqZ`L|+AWEvcvdH4{jm?ISkv;8NxvC-$p7Hib<40pK^xK|McC zvhP@}H3xhB@}lROaYWXNz4r7*v%hf(tuXahc{h9&Kr=&2DF_bDH$pY#>1*uOaHoKz zM5#&&hZ!g7550!kN!$!a@#$87I7kISl45J9dZVk90dcsXu4PpCe^jV zOKn&rX4+jEn%W<2cUCRIaSu8IUf^2X*HH+$yHK9*K9J``*?_MtSJr~Wxrn^jF$Y4@ z1AD+5mV(Q7S`TfjJHKCJI_+a$bQtySfWcKNklk_b`nU1#Wy7mb1wgjTeq`0XjS=*FJG{KEV$uuZEPsXao}!QBaFcz1 zN%0gPI71sHHR3#%>#w8Abi3}tDqT%i2^=H5X=RqjhgR*H1g^M$&aI+Xl_aH)QTz1_ zlpwR~qg4=e>@8DviV!ji2(CV5X%BCT7ApE@eGkfHO5!}cOQ+*62H!|5SD+U7EdH&9 z#lwreBXDwnzgNlBc+N&w)QqH;V)+jLKIj}Gi~S#C{IPiX`WjBrivI-vX?ihvYokc|1a>92{=qL5@~`wxa7slJStQDI$^oESF~^4~5K%7%}o5 zsZriSU~Y9k_F0;`w??OrMYy-_t-GCjH5XrMs%#AI?xB{p0bPF!ZzMOFnz3L4LT2cBCE*gOHI&N4h0vjo&iT27eG zf-S>xPEx&yubB{%$2iAT2*10-s$yTDvpIi+)zh8Zcu}FN@N|FB-(K2yrI-$+B<~C4 z&93R+k6xXff6j6T-+HLV6?-lZ00fWAw)Ew3rRtKEe|Vv0?s+~bBC#ufqsV2We;51; z%gGZPJ8+K2-nWFXUJYAuTzdzft@!S09PyzLOiR2(_PHpdT_*EgoOo;$?g;jP{TyWr)sgw_ zfP%Wo7;>@rDR`z{ST^2U6Wi|cU*zew<*m8Zi`jmdHgO)AN1a;UBNEivwA+n(;!>kq z{zUKStF6L1yGHRjxf_x+gxv}1VgW+h5ZO+*@xdR|7y0?f+=*Pf$+yDEvska-1ep0t zB+%6K(nORrEY7bTB0B=J>MU_H98}vp1-~1|_pP-AIXtGjulOX02uHE(c+lwpOy4Z5O-eVqg94&loB4iADp`O-i%Oo6zLm6f`E z$Z?PSWkm-PkN{@UEXoyC2L2y9RywBMy2a9vbfEFJT+EyxtG45;A3tkJ|_Nxa0sS?2?rpmRGJuq9h4Z#bUCY(!00+LMvYb>&?z{%J-MA0%~qvUN5 z(iAwdBuAVgOoSF8yJwmiVmLG_#iz(_+p!77rXUXJ0i8YF9cq}UM2ALk$WcHX86bu5 z4H&%`o7aH!Y@a=yx(c%)eRMq5wUY*MCql;w0~9xm8$_0ix^%`FvI)9-Ky)}_H|0+f zEgMlIieSG?>bo)X>DuX#E=_2nr4Yk35gPV_WVWLeY8PGT+?f!=L=j7lf}fB-qP(){ zeGH+ErUwiug>8(1quXOy%M6e|n9i!$o+_yy@WFHuybYkYrU$yHgYB(FYsWxb>;-yk zN2lxswdo?Cq11OqvIV`tu&eNH0pTr32HRRcAeI?gjf@p_2rKGUrp3@HF?}I=M2n4N zzEzllz3vEc`CiEqr$6lo!Ib(+{h6L1&7r-PJ+3>44tpa4-waoQ!s;bRFUj8TKbPhO zblbSlpmuc^R&02f#P=W@kI+7#*~#d=6 z5TbSHFT!kvVB8r)=nLjcE2mYJ>0C+J55a|{Kx)+Bq#d4EVf!TNIR=4I_3E*I?V$T> z8hID8Up9z7ok;HIJv%~_AJz%Lu!x@qyCqJVyHG>g7rK4RYkt$v{BK35Z}C9xOt6Wx`t8K(8hxstZQjZ&hLHehv5L5e;ZpH~-UNfJzmfY~m7P8jDE z8d?^5md3^TTvCm0R3q+k9NOJ8k%^gFG(R`R?xMqg7R5S_@0-0=-@m#I*17r_0+&Ym z#&{7F$|gA=8nYw})sf32$6YoI)@$2RWZM4h z*(o4_^z?4kJ_hxsh_T?0q55S*y^n#K>hC3Y<=@DQ6{#T~Z4jcmbfd=Pqb0!bpfLL4I1Br(RC-v5+<*lwxg}llWqVyS#t0RM6|+g(hR=@W@rij$aV+b5BWz| z%#QS##|pvJns z4%Inb5iQ}mD-ls{;C1L>F_8V4df$A_p?&FC6^Yz%`IjkNo&u*xH=fJN3O;1}pbRXM zOcsNK#jO6z#7XRQB-aWTnr|`UqHx#&u~8^p$O=X2Q_L>4BFf#u-(>6QgxjO#)M<_8 z=J%O4lOZ3uxNKCW7wQ?Ubw*wGXXAPZ!3 zoggXvJZF{d1-m~w9kWw{%{k)=iE!6~l1_--YlI)s$EC0xyy)TpijB17h$)}A{8`k2 zIN4(@`%fc@$w5)l@uI(g!CYIeD<>2!c|z>D@Pwc5>}QB15_9hHWJkj*9Fl-MVTeAO z%&lR7N7QpDn`hRuFJ^${^y?M~Z)1y`f2#1YdyeXJ>o=2j>&Wwej{Sn@t%phY%QqO| zr};}{Gq^XLtIoCJ54(;6V+^AxW#TcL(OYDz6ux3cm^!c?(;tAVjAAD^5+@>bNr-<9 z)?_izDMn#kx^onS_Mq+Sud&q_}|$bV}$Kt6z#)>FVYie z&Q~DwLjpF{A4Au^($W~JlV~)Jrb)GKb6arTZcIRe@czw@LbPv#Xm=;Gq9=yAOaA~h zO6)o4N$XFMS}bYa(i!*5H_3ACr;Q1j7ef;+&EHF5C@oe=qRo9xD7fX=2v(Sy5;s); zUn3P8d)8}b7VoD;eQ-Wy{-~6Hgk~vYQR-c6(I#d6zs)~d7By9mvWywt;&BMCLekth zFCRxa6G?8jlpaJs%Hz^QT&K|JpJTc<`A_NJ9EvEv zXvI8svcS~^6E;|9wNav^f~(yf-@1 zeO^jsSbhgiE|pc&Dc9LnS!zFjlhu=0vA#aS6m6_;x*^jKk;)%Cc%j(pS`(D5W=!R2 z0^;=1HamF5p_YK|#}Eql>I{(av#FDdcF;udlcD$z!EV#f4{Xmn%Tz2uO$ja4LhH8q zzf>thuJ4RpU17I{zijA?yv{^{W(3vroRC%Z(Tu8C1iYGqVP@boX+t*}w#vWm$P`w? zSEmKVOJmorevgFZW4$DGdKfim9myGvjQbQ~G5cw13KEPN1GtQFzXuIFLO}XrPK*hL z{n-2vd0HNcUrApSMO5N&{SrOVDPX=v4v;}oHC08iU1 z(S~i<`Fhbe@I;Iqf>b$;Gj01|#k8rjS(0Kk{-X*law~)>e-A-vw%92haN2R{CS)UF zKq55VgKLi}OgSH7!r^MEqw?Uoq(X!jxJG+&9m`f#^V|a!$|Wg2151@m2gz@X);l0Z zoFneAm{KE!ZjCd-MkzjUZ=%qV-ArUz)xXTg^ z=C)VT7<)=Lb%|lE?fZSj9~z#*K-{HOmCltC=2^s#L?cUHS!AN&EZA-xSvFY*KH8)( z12zQZRqmZhizDb!Bv)Z$gJHB^@$oeC)ybD?3%4jqw_rT-9fa|2GS!I^;udO1X#)-T zjFG-2M=~0oqP9Ce`epP~f<`MtD}jKm^s}Vis#ArShWQ^+^IrKEkp zld@B#57Cl9h@*s}Y~cwZkd)1|iR0vyb8M8~U`G)}(NPl!)yX4CDG}HxqhUwMMbU@) ze>cxuqUpi9mCb?mC4M^KJnEIN;T2arRhe5FNRZE4WhIUzZn^}+6vzfTQ@o7W6#@zQR)FY%j_T(!R)NBg#!z>LPkNv$ zcEs#unb34=+g5?P5}!P;hN9_Yy7wE1Hs(@<%qkwnBx$ISYr%JiGrjO=BZuL_C{^oA z+xcs^(D=AL#N!+3vEV2Dbc^5jGc=$>N`-9?a8R54K|%6X)1{L|y@gm>K9k>qZ}l7l zR!=M8FKsk-48mNJeR^2@K&ZBKidMzQMxA}b5cT;An#77D_pGP&>wf#w+!^kRF68n~ zlQ`^;O(HZdWHKE05k1|N>0cb&>VU=FhUDY|=z52RFBFUdkBl#{qV+tE-{$Q&FL%Y9 zJ#BC;ag-vf^=OXUEfR3YY(93!Tz6-`8-7_=`3`aUlbfO_A@SafvwrJOXJSlD6*qC- zw5Xi7AADePPqzt0UVM?tHcdkC3#GGmzUZ<4o}~X>_bmi>Z@@YXhey(b=u0?oj{-_YPo_fuyaD z%uVY+FA0@sNUTx}w{v7`k^1HH3$Jb_@O;iAWnewAe;jT4GtlVCMOMq!PuJ&7Ne1^P zyEtYzmF6Sp%jg=0x0Fin>lH&bme~EKym)4^WU8w&OylMM9PfsCYxVJ$@>j=120X^$ z)sSeEi{y%ze*=)n`;n8>7Bxi&jPB%9y?OV2TV)g7wWMt!i2Mo11qA%~6u;d4WY&27 zx8y9itTARqkm%wAa*Ed5?~cfV>!< zKxiG2AXvb3Pb%BEfB74yUk4s%_1BO^E;~sv+@VRAdzK51LJ&8LUeZ}qa1wV-@e=xp z{~aKh_H~iBJL_{zlPI3GiU;~vZCDn`8ShKXw)VB!#C7rxk`no{zCzYYxq0OJSZNzq zldWqzY;rCV7jpB)XjI%P#x{LJq#wc;9g1=gQO30aa4qWniERp}jYBroIO$L`Jx2_V zs)tUf-_m25s!p} zkD++rh;GZ?W-hthQck)YvnBW@D8Pg~7w+RbJWIm141dW{x)W`XqgDQ*szH{x5z3HW z77#3yMwCsIjyzGctGxR8D^>72n7bLY08uV?D03&-;Ph+V@AkQsCS>us)RVq(y2_De zUz!BsERa_58zZ8GKUTqCG{Hcx<1`Y2SB-iLBMb_13!EFIbvI0FaMZ5eHex3!@nT<{ z*0WVq1Gp;yuWvrgS%W1gN&Z3nrpt@2`?6oOhl=HdX& zll=mI20m}la;hw?2s>k^_d^5OMLx>1nJW@b5L)I9gQPay1f#UDZqr-h1chCL9I!9M zUF%0N%5fi@+rzM1Xn9=-uxPbEqTHkP{gl`TEd!hx-nhKG<3U@{An|%1qa5cJL`2$w zn_vIBwfB3UI+Kuy+fHC8N5syR?866N}dQAG!wj3~;;#bdhR5 z+{c(;JV~5M{)vdJ13kd5PbFVqI+A<5VqOPi-;{mc&=yV0F9?q2zP+q1oDXYnq`^9c z*8Y1P9rYm`dip_6gmk-M6HkP+L!Ia*FBrf&>SAgVAFFe6zYEHzCb#)~4sWEDIA|Gw z5^WFKUG*%!0I6Yp-#RZAlvR{J8g(BvshoH$+yJc?6MOmG7ZoGDh1ftKI?p;m3N8c* zVIf=u3Y~RqOsN<6D+YXo(%%8$rco+IKcfKe3G{dUkVi&UqC#IvOdacm75r|ma#{%$ zl&>D@_ch;0fAGE@hiQxn^Axd8R~Z_E{E(ScMMcUXYC> zf%yBJfUTj4@HhYX6B?Ifp^MTm9EHU-U?tktbSu&u!TOIu)RxFtF|8vB79mI!@fVLV zJv6Wf`e%bJVz6jJ%bW?GWlg8q79#^pl6*!4^qV^25%OaoyAm&zgsD2u=zA`=wKv3< z?~wwtPB8i_;H(LbzOl=FM*6=1sirjEDd)b$WkfS`CkLd$K{ccF5RaEb1U^KFSBsQc zOIeyN66p^51dj^R>kr|DFnXV6SzgVhQKfRznvxBGw&+)6-N9w?roNI&WjU?v?o4>7 zA#~F&JOmALiSOTD!>zBUlyN&Qkn8N?egvMT ztBfJ-F(Q80o^FiX{7_M7GC0yG3OR`k$s29oMmj;;?g<6Z0@;R-sj>#us0e-#^OD~x ziOfT=oR^w-JGZw2c+MovnXq?mPLD`wQxacIow9Jc&SiG~3{iZvucpl9eb=3%`|X=}bD%dcBbi8}#ewP}TKsN>Oj9&j0a=mc`7&KxwnQ z7HJm0uTNDa!89s+TAr%U27v%`D4r|AOr{Q@!*{A*g-$VQAFM zh``f^aJx8-X82dKgF(s@w)6%ikbRZw>)_&PXf}k!Gi!!%U9W2OUwz zEOgLKI#TQ2M1}nz(Pi=M3L?$?gSdOJKVAhcqf5R0YLkYp^vfDCzRqw>%DHCw9BVMn zGhAw{jhABA{?ZGBmAYi{Kw}RfI9x^Ozmb~#bizEnjCrZQdj1L!Z&RFdI;P9g=&mHv z?n65K@Ulea{*H;cEjDF%F-xA%cYY{%;KZfs64Z(+9qFmJk*1^t{M!B^v70$jq?dA# zp_Xi}HlMK^>R;>9q@{m-n`QL2vj(2CYF`FNilK^PW9~FnggJ-$=$c7^d$8zCmkOp2 zr9K>qqYZ*CwXQ+jK?J;R{x1yOWTkxU z&a}SgqCZZk`zuU-Je$@(7}!^E<&=vvKUty)xPoEYlRQ`wi4W@P-yg-fs-!><(Urs9 zPLcPqurM`I!0~Ujc^B|pcgZg1wB_a4^A(N8`={2CG>dMgl+9$hV zZ{Nt6{;Litva!|+*z;iXH?>b-*Be_nty-_^*2VZy<``H&{hl48Z*xiOREUM2E5a>4eSQM^o2H+zD@^c`Zm!yw|; z4@fw{10%+yG9XKi;)!JM8ejBYQz00f*<&b}KVv)mqxKe``PY#)`?eYgh;E_c1Z0?B`UxHjgHuinch3@?Acb0PU(HgyZoz5RBZED#SJP*A{ zfv-aU1ZA1O;=kr~)|jG5|Ld$sxkmH0w_}&IBQ?d>-7DtWmJp4UfNWJ*U6hL(CGIVx z7^Ag!7Z2j{hP^{BFZ|UpRo_ zj=8msYZ$Y7p4s!=1Fre6MGNXVL$|cw2L#N7fFYwU@6T=1+H6|mYo%wI)*PY>Cs>SU zJH5^ViK^*xSz=|OJYjAPl@j~(i1>ACD@E`5I&mmpovA!u+!EiitUG?@RDR8AK3+8T zM~{jp?(rzY?_A)?9f3E)dJiW9t-0BjDJFXK{nyAMaeeiV$S!A{MKC6;vV%A1<}@QY z5Pe}`)GMgQw;_1pbO{!M3QrtA(~c+tR#Ex4G5U1D7sxx#8o}5wTdAe_X}+fz(G~HD z$*D=4i0%*ZGPu`!yfFuo9nEHT1C8-c#5Wnmvg|-=J~&0c(b-oq9YA3St(=2zv$-5F zNL^S8g=*uK9Mjge@cb z^1_%L^J2+m<g+Kk(*Wf$pQ z`$gVWdt|B1ezWhKc(wbYIbs2G(VR1morc!8`BIxB%qI084sU~_J!o@X0?{S>P*L5wg z(V(S9MeE{Rs<`bR5IgAtf!v63z&f?mZ+Qh(N9rFv5o6_kr0dd@DBtB=9)|&4edei! zf@Q=USXWI@&Xg76s>Tg~7o+#eBp9ng+ZEXcGolKbpI;MWG2A-mr{BWQ7E{CXYMg2+ zRO{jm^bCZoKh9nDx4*gB@T709f+0PCWk%2$t~Z90S76JYe>pDwklAZ5_4B*#t3}+*j_` zyvFa7+i|97QyZotTn=xoiF1-RaU>hzlh+RRj;tJw65~7G^5Z0GQ=3ba)e~SmQM?g1 zoyQNf&vSqu8Hyw_y;y*CQFA4W5$4heo}}hOlE+*(u3q45#0k;VIvf?vCCX)+nLPAz zXF{)q(`#2=r$QRE8&J-10S(Z#WE6`gmrA=sCrCTROYNA{N9U^#N&)s)D|8NQC^>xN zBmo{*HSxZxmkYngGL98XDzuAFL6m>wn-4U(=)njUgvk!+sukIC*R1T!zl{^6bR3nZ zsaYOwP!G(72NUkH$`Ld>&1Cnzt4`y(a(`z^tlSWmBX?8zw`rJv3G-I(|LBM*$N>3(iF(o?)PrTZ>RdFMZ=UkJ>fOQD2@*G=p+Zh+}W4o|hy|Fcp9jBo3;}C^t*l{=lG7K$& z(1CIV4Xp@1LW}H5gL>)w4rg>0Bt?`x%L~E_nD?uocLXY(s6& zNLnslPdQTDxA~DJIqq}nZxJ63mLxIYx(>^ZdPl@Qi{U+p2mj)%CRtopQl!gS$gFwF zh=>2TPVN-Ohhr@jGKQmo7rqnjRhBZMiA+(~A1{N zTEEv1q+2ojNU?B_P=7RrSJP$6HT|k|?+}6{C!kjtVh?u!*12q3|8ogQE*6}hLaJM`2zq}ux z5OWVIqXZX$+e|6;Tc0M{KGcD(!8zqNGH2VQSV-MWJCEak7t0Y9o{7>iS?v z&EzwDL3xKw_4RBTo4)w07Cw(^+96MX_R&7Wh6n97N?>8(`RgLl9QtaJ-rT)=!RcpH+D@Js&?WFvGQEOHHqS_CVWDm zTSx(N@;%EOrfSr*IgDPf?D2NY#JXkhSO&|e~$os^&Wa^Mn*DA23fbcpIdT-U>!z&52d z8QigC&jQ?2UUxZN8> zZzvFbh=>33C}%u~Tp?_hf0+8xUM)&vF-s4Fi~w)^EUXd}){%>0Q(r5WC`qeD`qiNh zG|#7viR2<0QPv_ILRxyMqw>m7y@;s4q@h_aY7@bhK+wzxNfp*e6yC^-x9r{PC#-*W z7>KHgr|>k4ELaj*{nB?n10Za|pG>T5{F_;@@gHsL;mr;959xiO{)MnX*+k>Uv9_;tMKfQg(zTla{`)oE!!-f2 zG#}+k3aZ%f7V(Kb_VAtYl>QI1dq>&W=u98kt^!?lZFx3TjcbJ^8UO`Y|7LqDg@3S{ zRRRmu(Rd1(PiOFUwJlk-F+d@B5M4g=A?*NNRi39z))5O+JsXN0E&V46%)Oofh9Dji z2LuUuP%sxKOqHX9!Y^q2p!zL(c>UiM9%c*wM8*lE9?9JMjaW8)F8+#=HCb%c%R9Yh zUE$61@wAIMZ|k_NL`xC2W+3QC9J{;XgwV=09sF)<$Ajhhsn0+@IA6B{>kiWtj=4r6 z6Z5FNe}&#oBTYkk?jNKXJPUbW&)y9(z$n_Av$ENwrRB2+tF1RN&7L;tD8ByQ`-mnt=jWa zEay;D#D(~U1BZ$C=1=fGbXBQa5bz7`%@2j3O>4bIl`L`uOONW*Uvzg?8wjs BM1 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 literal 0 HcmV?d00001 diff --git a/gradle/gradle_scripts/dev_default.properties b/gradle/gradle_scripts/dev_default.properties index f12fd39e3..cc12f335e 100644 --- a/gradle/gradle_scripts/dev_default.properties +++ b/gradle/gradle_scripts/dev_default.properties @@ -12,3 +12,6 @@ io.xpipe.app.showcase=false # Location in which your local development connection should be stored. If left empty, it will use your global XPipe storage in ~/.xpipe. io.xpipe.app.dataDir=local + +# When enabled, all http server input and output is printed. Useful for debugging +io.xpipe.beacon.printMessages=false diff --git a/gradle/gradle_scripts/java.gradle b/gradle/gradle_scripts/java.gradle index ee14af1d1..a42f806fb 100644 --- a/gradle/gradle_scripts/java.gradle +++ b/gradle/gradle_scripts/java.gradle @@ -22,7 +22,7 @@ javadoc{ addStringOption('link', 'https://docs.oracle.com/en/java/javase/21/docs/api/') addBooleanOption('html5', true) addStringOption('Xdoclint:none', '-quiet') - addBooleanOption('-enable-preview', true) + // addBooleanOption('-enable-preview', true) } } diff --git a/gradle/gradle_scripts/local_junit_suite.gradle b/gradle/gradle_scripts/local_junit_suite.gradle index a83408112..989adaee7 100644 --- a/gradle/gradle_scripts/local_junit_suite.gradle +++ b/gradle/gradle_scripts/local_junit_suite.gradle @@ -24,7 +24,7 @@ testing { systemProperty 'io.xpipe.app.fullVersion', "true" systemProperty 'io.xpipe.beacon.printDaemonOutput', "false" systemProperty 'io.xpipe.app.useVirtualThreads', "false" - // systemProperty "io.xpipe.beacon.port", "21725" + systemProperty "io.xpipe.beacon.port", "21723" systemProperty "io.xpipe.beacon.launchDebugDaemon", "true" systemProperty "io.xpipe.app.dataDir", "$projectDir/local/" systemProperty "io.xpipe.app.logLevel", "trace" diff --git a/gradle/gradle_scripts/modules.gradle b/gradle/gradle_scripts/modules.gradle index 1b6bb40e5..abecf48a5 100644 --- a/gradle/gradle_scripts/modules.gradle +++ b/gradle/gradle_scripts/modules.gradle @@ -24,12 +24,6 @@ extraJavaModuleInfo { } } -extraJavaModuleInfo { - module("org.ocpsoft.prettytime:prettytime", "org.ocpsoft.prettytime") { - exportAllPackages() - } -} - extraJavaModuleInfo { module("com.vladsch.flexmark:flexmark", "com.vladsch.flexmark") { mergeJar('com.vladsch.flexmark:flexmark-util') @@ -50,6 +44,8 @@ extraJavaModuleInfo { mergeJar('com.vladsch.flexmark:flexmark-ext-footnotes') mergeJar('com.vladsch.flexmark:flexmark-ext-definition') mergeJar('com.vladsch.flexmark:flexmark-ext-anchorlink') + mergeJar('com.vladsch.flexmark:flexmark-ext-yaml-front-matter') + mergeJar('com.vladsch.flexmark:flexmark-ext-toc') exportAllPackages() } } diff --git a/gradle/gradle_scripts/remote_junit_suite.gradle b/gradle/gradle_scripts/remote_junit_suite.gradle index 6df6e012a..d6a9844f8 100644 --- a/gradle/gradle_scripts/remote_junit_suite.gradle +++ b/gradle/gradle_scripts/remote_junit_suite.gradle @@ -27,7 +27,7 @@ testing { systemProperty "io.xpipe.beacon.customDaemonCommand", "\"$rootDir/gradlew\" --console=plain $daemonCommand" } systemProperty "io.xpipe.beacon.daemonArgs", - " -Dio.xpipe.beacon.port=21725" + + " -Dio.xpipe.beacon.port=21723" + " -Dio.xpipe.app.dataDir=$projectDir/local/" + " -Dio.xpipe.storage.persist=false" + " -Dio.xpipe.app.writeSysOut=true" + @@ -36,7 +36,7 @@ testing { " -Dio.xpipe.app.logLevel=trace" systemProperty 'io.xpipe.beacon.printDaemonOutput', "true" - systemProperty "io.xpipe.beacon.port", "21725" + systemProperty "io.xpipe.beacon.port", "21723" systemProperty "io.xpipe.beacon.launchDebugDaemon", "true" } } diff --git a/gradle/gradle_scripts/vernacular-1.16.jar b/gradle/gradle_scripts/vernacular-1.16.jar index 062d3b270b4f227b4998849ea7d8c2abf2cf031f..261aaa8fb4cdb4e45a33ea9258abe3ddd944b739 100644 GIT binary patch delta 4470 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 RK(nEw3@A#LMIob%{{!Tp9F+h7 delta 4573 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 510f28ae4..6f7a6eb33 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/lang/app/strings/translations_da.properties b/lang/app/strings/translations_da.properties index 6ef13280d..73bc007b2 100644 --- a/lang/app/strings/translations_da.properties +++ b/lang/app/strings/translations_da.properties @@ -25,6 +25,7 @@ moveTo=Flyt til ... addDatabase=Database ... browseInternalStorage=Gennemse internt lager addTunnel=Tunnel ... +addService=Service ... addScript=Script ... addHost=Fjernvært ... addShell=Shell-miljø ... @@ -460,3 +461,20 @@ addNotes=Tilføj noter order=Bestille ... stickToTop=Hold dig på toppen orderAheadOf=Bestil på forhånd ... +httpServer=HTTP-server +httpServerConfiguration=Konfiguration af HTTP-server +httpServerPort=Port +httpServerPortDescription=Den port, som HTTP-serveren vil lytte på.\n\nBemærk, at hvis du ændrer dette, skal alle andre programmer, der interagerer med serveren, også konfigureres til at bruge den nye port.\n\nKræver en genstart for at gælde. +apiKey=API-nøgle +apiKeyDescription=API-nøglen til godkendelse af XPipe-dæmonens API-anmodninger. Se den generelle API-dokumentation for at få flere oplysninger om, hvordan du godkender.\n\nKræver en genstart for at blive anvendt. +disableApiAuthentication=Deaktiver API-godkendelse +disableApiAuthenticationDescription=Deaktiverer alle nødvendige godkendelsesmetoder, så enhver uautoriseret anmodning vil blive håndteret.\n\nAutentificering bør kun deaktiveres til udviklingsformål.\n\nKræver en genstart for at blive anvendt. +api=API +storeIntroImportDescription=Bruger du allerede XPipe på et andet system? Synkroniser dine eksisterende forbindelser på tværs af flere systemer via et eksternt git-repository. Du kan også synkronisere senere når som helst, hvis det ikke er sat op endnu. +importConnections=Synkroniser forbindelser +importConnectionsTitle=Importer forbindelser +showAllChildren=Vis alle børn +httpApi=HTTP API +isOnlySupportedLimit=understøttes kun med en professionel licens, når man har mere end $COUNT$ forbindelser +areOnlySupportedLimit=understøttes kun med en professionel licens, når man har mere end $COUNT$ forbindelser +enabled=Aktiveret diff --git a/lang/app/strings/translations_de.properties b/lang/app/strings/translations_de.properties index 50229daea..0349fcfd1 100644 --- a/lang/app/strings/translations_de.properties +++ b/lang/app/strings/translations_de.properties @@ -25,6 +25,7 @@ moveTo=Kategorie ändern ... addDatabase=Datenbank ... browseInternalStorage=Internen Speicher durchsuchen addTunnel=Tunnel ... +addService=Service ... addScript=Skript ... #custom addHost=Remote Host ... @@ -454,3 +455,20 @@ addNotes=Notizen hinzufügen order=Bestellen ... stickToTop=Oben bleiben orderAheadOf=Vorbestellen ... +httpServer=HTTP-Server +httpServerConfiguration=HTTP-Server-Konfiguration +httpServerPort=Port +httpServerPortDescription=Der Port, auf dem der HTTP-Server lauschen wird.\n\nWenn du diesen Wert änderst, müssen alle anderen Anwendungen, die mit dem Server interagieren, so konfiguriert werden, dass sie ebenfalls den neuen Port verwenden.\n\nZur Anwendung ist ein Neustart erforderlich. +apiKey=API-Schlüssel +apiKeyDescription=Der API-Schlüssel zur Authentifizierung von XPipe Daemon API-Anfragen. Weitere Informationen zur Authentifizierung findest du in der allgemeinen API-Dokumentation.\n\nErfordert einen Neustart zur Anwendung. +disableApiAuthentication=API-Authentifizierung deaktivieren +disableApiAuthenticationDescription=Deaktiviert alle erforderlichen Authentifizierungsmethoden, so dass jede nicht authentifizierte Anfrage bearbeitet wird.\n\nDie Authentifizierung sollte nur zu Entwicklungszwecken deaktiviert werden.\n\nErfordert einen Neustart zur Anwendung. +api=API +storeIntroImportDescription=Benutzt du XPipe bereits auf einem anderen System? Synchronisiere deine bestehenden Verbindungen über mehrere Systeme hinweg über ein Remote-Git-Repository. Du kannst auch später jederzeit synchronisieren, wenn es noch nicht eingerichtet ist. +importConnections=Synchronisierte Verbindungen +importConnectionsTitle=Verbindungen importieren +showAllChildren=Alle Kinder anzeigen +httpApi=HTTP-API +isOnlySupportedLimit=wird nur mit einer professionellen Lizenz unterstützt, wenn mehr als $COUNT$ Verbindungen bestehen +areOnlySupportedLimit=werden nur mit einer professionellen Lizenz unterstützt, wenn mehr als $COUNT$ Verbindungen bestehen +enabled=Aktiviert diff --git a/lang/app/strings/translations_en.properties b/lang/app/strings/translations_en.properties index 6d5fbbda9..8399271e2 100644 --- a/lang/app/strings/translations_en.properties +++ b/lang/app/strings/translations_en.properties @@ -25,6 +25,7 @@ moveTo=Move to ... addDatabase=Database ... browseInternalStorage=Browse internal storage addTunnel=Tunnel ... +addService=Service ... addScript=Script ... addHost=Remote Host ... addShell=Shell Environment ... @@ -41,7 +42,7 @@ selectShellTypeDescription=Select the Type of the Shell Connection name=Name storeIntroTitle=Connection Hub storeIntroDescription=Here you can manage all your local and remote shell connections in one place. To start off, you can quickly detect available connections automatically and choose which ones to add. -detectConnections=Search for connections +detectConnections=Search for connections ... configuration=Configuration dragAndDropFilesHere=Or just drag and drop a file here confirmDsCreationAbortTitle=Confirm abort @@ -458,3 +459,23 @@ addNotes=Add notes order=Order ... stickToTop=Keep on top orderAheadOf=Order ahead of ... +httpServer=HTTP server +httpServerConfiguration=HTTP server configuration +#context: networking +httpServerPort=Port +#context: networking +httpServerPortDescription=The port on which the HTTP server will listen on.\n\nNote that if you change this, any other applications that interact with the server need to be configured to use the new port as well.\n\nRequires a restart to apply. +apiKey=API key +apiKeyDescription=The API key to authenticate XPipe daemon API requests. For more information on how to authenticate, see the general API documentation.\n\nRequires a restart to apply. +disableApiAuthentication=Disable API authentication +disableApiAuthenticationDescription=Disables all required authentication methods so that any unauthenticated request will be handled.\n\nAuthentication should only be disabled for development purposes.\n\nRequires a restart to apply. +api=API +storeIntroImportDescription=Already using XPipe on another system? Synchronize your existing connections across multiple systems through a remote git repository. You can also sync later at any time if it is not set up yet. +importConnections=Sync connections ... +importConnectionsTitle=Import Connections +showAllChildren=Show all children +httpApi=HTTP API +isOnlySupportedLimit=is only supported with a professional license when having more than $COUNT$ connections +areOnlySupportedLimit=are only supported with a professional license when having more than $COUNT$ connections +enabled=Enabled +enableGitStoragePtbDisabled=Git synchronization is disabled for public test builds to prevent usage with regular release git repositories and to discourage using a PTB build as your daily driver. diff --git a/lang/app/strings/translations_es.properties b/lang/app/strings/translations_es.properties index b93169c4b..0fd80ce3b 100644 --- a/lang/app/strings/translations_es.properties +++ b/lang/app/strings/translations_es.properties @@ -24,6 +24,7 @@ moveTo=Pasar a ... addDatabase=Base de datos ... browseInternalStorage=Explorar el almacenamiento interno addTunnel=Túnel ... +addService=Servicio ... addScript=Script ... addHost=Host remoto ... addShell=Entorno Shell ... @@ -441,3 +442,20 @@ addNotes=Añadir notas order=Ordenar ... stickToTop=Mantener arriba orderAheadOf=Haz tu pedido antes de ... +httpServer=Servidor HTTP +httpServerConfiguration=Configuración del servidor HTTP +httpServerPort=Puerto +httpServerPortDescription=El puerto en el que escuchará el servidor HTTP.\n\nTen en cuenta que si cambias esto, cualquier otra aplicación que interactúe con el servidor deberá configurarse para utilizar también el nuevo puerto.\n\nRequiere un reinicio para aplicarse. +apiKey=Clave API +apiKeyDescription=La clave API para autenticar las peticiones API del demonio XPipe. Para más información sobre cómo autenticarse, consulta la documentación general de la API.\n\nRequiere un reinicio para aplicarse. +disableApiAuthentication=Desactivar la autenticación de la API +disableApiAuthenticationDescription=Desactiva todos los métodos de autenticación requeridos para que se gestione cualquier solicitud no autenticada.\n\nLa autenticación sólo debe desactivarse con fines de desarrollo.\n\nRequiere un reinicio para aplicarse. +api=API +storeIntroImportDescription=¿Ya utilizas XPipe en otro sistema? Sincroniza tus conexiones existentes en varios sistemas a través de un repositorio git remoto. También puedes sincronizar más tarde en cualquier momento si aún no está configurado. +importConnections=Sincronizar conexiones +importConnectionsTitle=Importar conexiones +showAllChildren=Mostrar todos los niños +httpApi=API HTTP +isOnlySupportedLimit=sólo es compatible con una licencia profesional cuando tiene más de $COUNT$ conexiones +areOnlySupportedLimit=sólo son compatibles con una licencia profesional cuando tienen más de $COUNT$ conexiones +enabled=Activado diff --git a/lang/app/strings/translations_fr.properties b/lang/app/strings/translations_fr.properties index 1c88ecabb..23a13e413 100644 --- a/lang/app/strings/translations_fr.properties +++ b/lang/app/strings/translations_fr.properties @@ -24,6 +24,7 @@ moveTo=Déplacer vers ... addDatabase=Base de données ... browseInternalStorage=Parcourir la mémoire interne addTunnel=Tunnel ... +addService=Service ... addScript=Script ... addHost=Hôte distant ... addShell=Environnement Shell ... @@ -441,3 +442,20 @@ addNotes=Ajouter des notes order=Commander... stickToTop=Garde le dessus orderAheadOf=Commande en avance... +httpServer=Serveur HTTP +httpServerConfiguration=Configuration du serveur HTTP +httpServerPort=Port +httpServerPortDescription=Le port sur lequel le serveur HTTP écoutera.\n\nNote que si tu modifies ce paramètre, toutes les autres applications qui interagissent avec le serveur doivent être configurées pour utiliser également le nouveau port.\n\nIl faut redémarrer l'ordinateur pour l'appliquer. +apiKey=Clé API +apiKeyDescription=La clé API pour authentifier les demandes API du démon XPipe. Pour plus d'informations sur la manière de s'authentifier, voir la documentation générale de l'API.\n\nNécessite un redémarrage pour être appliquée. +disableApiAuthentication=Désactiver l'authentification de l'API +disableApiAuthenticationDescription=Désactive toutes les méthodes d'authentification requises, de sorte que toute demande non authentifiée sera traitée.\n\nL'authentification ne doit être désactivée qu'à des fins de développement.\n\nNécessite un redémarrage pour être appliqué. +api=API +storeIntroImportDescription=Tu utilises déjà XPipe sur un autre système ? Synchronise tes connexions existantes sur plusieurs systèmes grâce à un dépôt git distant. Tu peux aussi synchroniser plus tard à tout moment si ce n'est pas encore configuré. +importConnections=Synchronisation des connexions +importConnectionsTitle=Importer des connexions +showAllChildren=Afficher tous les enfants +httpApi=API HTTP +isOnlySupportedLimit=n'est pris en charge qu'avec une licence professionnelle lorsqu'il y a plus de $COUNT$ connexions +areOnlySupportedLimit=ne sont pris en charge qu'avec une licence professionnelle lorsqu'il y a plus de $COUNT$ connexions +enabled=Activé diff --git a/lang/app/strings/translations_it.properties b/lang/app/strings/translations_it.properties index 3f4d5ddbb..e03fa1dc6 100644 --- a/lang/app/strings/translations_it.properties +++ b/lang/app/strings/translations_it.properties @@ -24,6 +24,7 @@ moveTo=Passare a ... addDatabase=Database ... browseInternalStorage=Sfogliare la memoria interna addTunnel=Tunnel ... +addService=Servizio ... addScript=Script ... addHost=Host remoto ... addShell=Ambiente Shell ... @@ -441,3 +442,20 @@ addNotes=Aggiungi note order=Ordinare ... stickToTop=Continua a essere in cima orderAheadOf=Ordina prima di ... +httpServer=Server HTTP +httpServerConfiguration=Configurazione del server HTTP +httpServerPort=Porta +httpServerPortDescription=La porta su cui il server HTTP si metterà in ascolto.\n\nSe la modifichi, tutte le altre applicazioni che interagiscono con il server devono essere configurate per utilizzare la nuova porta.\n\nRichiede un riavvio per essere applicata. +apiKey=Chiave API +apiKeyDescription=La chiave API per autenticare le richieste API del demone XPipe. Per ulteriori informazioni sulle modalità di autenticazione, consulta la documentazione generale dell'API.\n\nRichiede un riavvio per essere applicata. +disableApiAuthentication=Disabilita l'autenticazione API +disableApiAuthenticationDescription=Disabilita tutti i metodi di autenticazione richiesti in modo che qualsiasi richiesta non autenticata venga gestita.\n\nL'autenticazione dovrebbe essere disabilitata solo per scopi di sviluppo.\n\nRichiede un riavvio per essere applicata. +api=API +storeIntroImportDescription=Stai già usando XPipe su un altro sistema? Sincronizza le connessioni esistenti su più sistemi attraverso un repository git remoto. Puoi anche sincronizzare in seguito, in qualsiasi momento, se non è ancora stato configurato. +importConnections=Connessioni di sincronizzazione +importConnectionsTitle=Importazione di connessioni +showAllChildren=Mostra tutti i bambini +httpApi=API HTTP +isOnlySupportedLimit=è supportato solo con una licenza professionale quando ci sono più di $COUNT$ connessioni +areOnlySupportedLimit=sono supportati solo con una licenza professionale quando ci sono più di $COUNT$ connessioni +enabled=Abilitato diff --git a/lang/app/strings/translations_ja.properties b/lang/app/strings/translations_ja.properties index 79f1ae8f4..b4760573d 100644 --- a/lang/app/strings/translations_ja.properties +++ b/lang/app/strings/translations_ja.properties @@ -24,6 +24,7 @@ moveTo=移動する addDatabase=データベース ... browseInternalStorage=内部ストレージをブラウズする addTunnel=トンネル ... +addService=サービス ... addScript=スクリプト ... addHost=リモートホスト ... addShell=シェル環境 ... @@ -441,3 +442,20 @@ addNotes=メモを追加する order=注文する stickToTop=トップをキープする orderAheadOf=先に注文する +httpServer=HTTPサーバー +httpServerConfiguration=HTTPサーバーの設定 +httpServerPort=ポート +httpServerPortDescription=HTTPサーバーがリッスンするポート。\n\nこれを変更すると、サーバーとやりとりする他のアプリケーションも新しいポートを使うように設定する必要があることに注意。\n\n適用するには再起動が必要である。 +apiKey=APIキー +apiKeyDescription=XPipeデーモンAPIリクエストを認証するためのAPIキー。認証方法の詳細については、一般的なAPIドキュメントを参照のこと。\n\n適用には再起動が必要。 +disableApiAuthentication=API認証を無効にする +disableApiAuthenticationDescription=認証されていないリクエストが処理されるように、必要な認証方法をすべて無効にする。\n\n認証は開発目的でのみ無効にすべきである。\n\n適用するには再起動が必要である。 +api=API +storeIntroImportDescription=すでに他のシステムでXPipeを使っている?リモートgitリポジトリを通して、複数のシステム間で既存の接続を同期する。まだ設定されていない場合は、後からいつでも同期することもできる。 +importConnections=シンク接続 +importConnectionsTitle=コネクションのインポート +showAllChildren=すべての子供を表示する +httpApi=HTTP API +isOnlySupportedLimit=は、$COUNT$ を超える接続がある場合、プロフェッショナルライセンスでのみサポートされる。 +areOnlySupportedLimit=$COUNT$ 以上の接続がある場合、プロフェッショナルライセンスでのみサポートされる。 +enabled=有効にする diff --git a/lang/app/strings/translations_nl.properties b/lang/app/strings/translations_nl.properties index 9236fd5e2..efa21afbc 100644 --- a/lang/app/strings/translations_nl.properties +++ b/lang/app/strings/translations_nl.properties @@ -24,6 +24,7 @@ moveTo=Naar ... addDatabase=Databank ... browseInternalStorage=Bladeren door interne opslag addTunnel=Tunnel ... +addService=Service ... addScript=Script ... addHost=Externe host ... addShell=Shell-omgeving ... @@ -441,3 +442,20 @@ addNotes=Opmerkingen toevoegen order=Bestellen ... stickToTop=Bovenaan houden orderAheadOf=Vooruitbestellen ... +httpServer=HTTP-server +httpServerConfiguration=HTTP-server configuratie +httpServerPort=Poort +httpServerPortDescription=De poort waarop de HTTP-server zal luisteren.\n\nMerk op dat als je dit verandert, andere applicaties die communiceren met de server ook geconfigureerd moeten worden om de nieuwe poort te gebruiken.\n\nVereist een herstart om toe te passen. +apiKey=API-sleutel +apiKeyDescription=De API sleutel om XPipe daemon API verzoeken te authenticeren. Voor meer informatie over hoe te authenticeren, zie de algemene API documentatie.\n\nVereist een herstart om toe te passen. +disableApiAuthentication=API-authenticatie uitschakelen +disableApiAuthenticationDescription=Schakelt alle vereiste authenticatiemethoden uit, zodat elk niet-geauthenticeerd verzoek wordt afgehandeld.\n\nAuthenticatie zou alleen uitgeschakeld moeten worden voor ontwikkelingsdoeleinden.\n\nVereist een herstart om toe te passen. +api=API +storeIntroImportDescription=Gebruik je XPipe al op een ander systeem? Synchroniseer je bestaande verbindingen over meerdere systemen via een remote git repository. Je kunt ook later synchroniseren op elk gewenst moment als het nog niet is ingesteld. +importConnections=Synchronisatieverbindingen +importConnectionsTitle=Verbindingen importeren +showAllChildren=Toon alle kinderen +httpApi=HTTP API +isOnlySupportedLimit=wordt alleen ondersteund met een professionele licentie bij meer dan $COUNT$ verbindingen +areOnlySupportedLimit=worden alleen ondersteund met een professionele licentie bij meer dan $COUNT$ verbindingen +enabled=Ingeschakeld diff --git a/lang/app/strings/translations_pt.properties b/lang/app/strings/translations_pt.properties index ae0171a76..63879d58d 100644 --- a/lang/app/strings/translations_pt.properties +++ b/lang/app/strings/translations_pt.properties @@ -24,6 +24,7 @@ moveTo=Move-te para ... addDatabase=Base de dados ... browseInternalStorage=Navega no armazenamento interno addTunnel=Túnel ... +addService=Serviço ... addScript=Script ... addHost=Anfitrião remoto ... addShell=Ambiente Shell ... @@ -441,3 +442,20 @@ addNotes=Adiciona notas order=Encomenda ... stickToTop=Mantém-te no topo orderAheadOf=Encomenda antes de ... +httpServer=Servidor HTTP +httpServerConfiguration=Configuração do servidor HTTP +httpServerPort=Porta +httpServerPortDescription=A porta em que o servidor HTTP irá escutar.\n\nTem em atenção que, se alterares isto, quaisquer outras aplicações que interajam com o servidor têm de ser configuradas para utilizar também a nova porta.\n\nRequer uma reinicialização para ser aplicado. +apiKey=Chave API +apiKeyDescription=A chave da API para autenticar os pedidos de API do daemon XPipe. Para mais informações sobre como autenticar, vê a documentação geral da API.\n\nRequer um reinício para ser aplicado. +disableApiAuthentication=Desativar a autenticação da API +disableApiAuthenticationDescription=Desactiva todos os métodos de autenticação necessários para que qualquer pedido não autenticado seja tratado.\n\nA autenticação só deve ser desactivada para fins de desenvolvimento.\n\nRequer um reinício para ser aplicado. +api=API +storeIntroImportDescription=Já estás a utilizar o XPipe noutro sistema? Sincroniza as tuas ligações existentes em vários sistemas através de um repositório git remoto. Também podes sincronizar mais tarde, a qualquer momento, se ainda não estiver configurado. +importConnections=Sincroniza ligações +importConnectionsTitle=Importar ligações +showAllChildren=Mostra todas as crianças +httpApi=API HTTP +isOnlySupportedLimit=só é suportado com uma licença profissional se tiver mais de $COUNT$ ligações +areOnlySupportedLimit=só são suportados com uma licença profissional quando têm mais de $COUNT$ ligações +enabled=Ativado diff --git a/lang/app/strings/translations_ru.properties b/lang/app/strings/translations_ru.properties index 06c9f19ec..32b3fc25e 100644 --- a/lang/app/strings/translations_ru.properties +++ b/lang/app/strings/translations_ru.properties @@ -24,6 +24,7 @@ moveTo=Перейти к ... addDatabase=База данных ... browseInternalStorage=Просмотр внутреннего хранилища addTunnel=Туннель ... +addService=Сервис ... addScript=Скрипт ... addHost=Удаленный хост ... addShell=Shell Environment ... @@ -441,3 +442,20 @@ addNotes=Добавляй заметки order=Заказать ... stickToTop=Держись на высоте orderAheadOf=Заказать заранее ... +httpServer=HTTP-сервер +httpServerConfiguration=Конфигурация HTTP-сервера +httpServerPort=Порт +httpServerPortDescription=Порт, на котором будет прослушиваться HTTP-сервер.\n\nОбрати внимание, что если ты изменишь этот параметр, то все остальные приложения, которые взаимодействуют с сервером, тоже должны быть настроены на использование нового порта.\n\nТребуется перезагрузка для применения. +apiKey=Ключ API +apiKeyDescription=API-ключ для аутентификации API-запросов демона XPipe. Подробнее о том, как проходить аутентификацию, читай в общей документации по API.\n\nТребуется перезагрузка для применения. +disableApiAuthentication=Отключить аутентификацию API +disableApiAuthenticationDescription=Отключает все необходимые методы аутентификации, так что любой неаутентифицированный запрос будет обработан.\n\nАутентификацию следует отключать только в целях разработки.\n\nТребуется перезагрузка для применения. +api=API +storeIntroImportDescription=Уже используешь XPipe на другой системе? Синхронизируй существующие соединения на нескольких системах через удаленный git-репозиторий. Ты также можешь синхронизировать позже в любой момент, если он еще не настроен. +importConnections=Синхронизация соединений +importConnectionsTitle=Импортные соединения +showAllChildren=Показать всех детей +httpApi=HTTP API +isOnlySupportedLimit=поддерживается только профессиональной лицензией при наличии более $COUNT$ соединений +areOnlySupportedLimit=поддерживаются только профессиональной лицензией при наличии более чем $COUNT$ соединений +enabled=Включено diff --git a/lang/app/strings/translations_tr.properties b/lang/app/strings/translations_tr.properties index 24e7ed2bc..48afcd66d 100644 --- a/lang/app/strings/translations_tr.properties +++ b/lang/app/strings/translations_tr.properties @@ -24,6 +24,7 @@ moveTo=Taşınmak ... addDatabase=Veritabanı ... browseInternalStorage=Dahili depolama alanına göz atın addTunnel=Tünel ... +addService=Hizmet ... addScript=Senaryo ... addHost=Uzak Ana Bilgisayar ... addShell=Shell Çevre ... @@ -442,3 +443,20 @@ addNotes=Notlar ekleyin order=Sipariş ... stickToTop=Zirvede kal orderAheadOf=Önceden sipariş verin ... +httpServer=HTTP sunucusu +httpServerConfiguration=HTTP sunucu yapılandırması +httpServerPort=Liman +httpServerPortDescription=HTTP sunucusunun dinleyeceği bağlantı noktası.\n\nBunu değiştirirseniz, sunucuyla etkileşime giren diğer uygulamaların da yeni bağlantı noktasını kullanacak şekilde yapılandırılması gerektiğini unutmayın.\n\nUygulamak için yeniden başlatma gerekir. +apiKey=API anahtarı +apiKeyDescription=XPipe daemon API isteklerinin kimliğini doğrulamak için API anahtarı. Kimlik doğrulamanın nasıl yapılacağı hakkında daha fazla bilgi için genel API belgelerine bakın.\n\nUygulamak için yeniden başlatma gerekir. +disableApiAuthentication=API kimlik doğrulamasını devre dışı bırakma +disableApiAuthenticationDescription=Gerekli tüm kimlik doğrulama yöntemlerini devre dışı bırakır, böylece kimliği doğrulanmamış herhangi bir istek işlenir.\n\nKimlik doğrulama yalnızca geliştirme amacıyla devre dışı bırakılmalıdır.\n\nUygulamak için yeniden başlatma gerekir. +api=API +storeIntroImportDescription=XPipe'ı zaten başka bir sistemde mi kullanıyorsunuz? Mevcut bağlantılarınızı uzak bir git deposu aracılığıyla birden fazla sistem arasında senkronize edin. Henüz kurulmamışsa daha sonra istediğiniz zaman senkronize edebilirsiniz. +importConnections=Senkronizasyon bağlantıları +importConnectionsTitle=Bağlantıları İçe Aktar +showAllChildren=Tüm çocukları göster +httpApi=HTTP API +isOnlySupportedLimit=yalnızca $COUNT$ adresinden daha fazla bağlantıya sahip olunduğunda profesyonel lisans ile desteklenir +areOnlySupportedLimit=yalnızca $COUNT$ adresinden daha fazla bağlantıya sahip olunduğunda profesyonel lisans ile desteklenir +enabled=Etkin diff --git a/lang/app/strings/translations_zh.properties b/lang/app/strings/translations_zh.properties index 56d1dcc51..3f230851d 100644 --- a/lang/app/strings/translations_zh.properties +++ b/lang/app/strings/translations_zh.properties @@ -24,6 +24,7 @@ moveTo=移动到 ... addDatabase=数据库 ... browseInternalStorage=浏览内部存储 addTunnel=隧道 ... +addService=服务 ... addScript=脚本 ... addHost=远程主机 ... addShell=外壳环境 ... @@ -441,3 +442,20 @@ addNotes=添加注释 order=订购 ... stickToTop=保持在顶部 orderAheadOf=提前订购... +httpServer=HTTP 服务器 +httpServerConfiguration=HTTP 服务器配置 +httpServerPort=端口 +httpServerPortDescription=HTTP 服务器监听的端口。\n\n请注意,如果更改端口,则与服务器交互的任何其他应用程序也需要配置为使用新端口。\n\n需要重新启动才能应用。 +apiKey=应用程序接口密钥 +apiKeyDescription=用于验证 XPipe 守护进程 API 请求的 API 密钥。有关如何验证的更多信息,请参阅一般 API 文档。\n\n需要重新启动才能应用。 +disableApiAuthentication=禁用 API 身份验证 +disableApiAuthenticationDescription=禁用所有必要的身份验证方法,以便处理任何未经身份验证的请求。\n\n只有出于开发目的才可禁用身份验证。\n\n需要重新启动才能应用。 +api=应用程序接口 +storeIntroImportDescription=已经在其他系统上使用 XPipe?通过远程 git 仓库在多个系统间同步您的现有连接。如果尚未设置,您也可以稍后随时同步。 +importConnections=同步连接 +importConnectionsTitle=导入连接 +showAllChildren=显示所有儿童 +httpApi=HTTP API +isOnlySupportedLimit=只有在连接数超过$COUNT$ 时才支持专业许可证 +areOnlySupportedLimit=只有在连接数超过$COUNT$ 时才支持专业许可证 +enabled=已启用 diff --git a/lang/base/strings/translations_da.properties b/lang/base/strings/translations_da.properties index 2cc61bc92..5a1b47115 100644 --- a/lang/base/strings/translations_da.properties +++ b/lang/base/strings/translations_da.properties @@ -66,7 +66,7 @@ isDefault=Køres på init i alle kompatible shells bringToShells=Bring til alle kompatible shells isDefaultGroup=Kør alle gruppescripts på shell init executionType=Udførelsestype -executionTypeDescription=Hvornår skal dette uddrag køres? +executionTypeDescription=I hvilke sammenhænge kan man bruge dette script minimumShellDialect=Shell-type minimumShellDialectDescription=Den påkrævede shell-type for dette script dumbOnly=Dum @@ -143,3 +143,23 @@ desktopCommand.displayName=Desktop-kommando desktopCommand.displayDescription=Kør en kommando i et fjernskrivebordsmiljø desktopCommandScript=Kommandoer desktopCommandScriptDescription=De kommandoer, der skal køres i miljøet +service.displayName=Service +service.displayDescription=Videresend en fjernservice til din lokale maskine +serviceLocalPort=Eksplicit lokal port +serviceLocalPortDescription=Den lokale port, der skal videresendes til, ellers bruges en tilfældig port +serviceRemotePort=Ekstern port +serviceRemotePortDescription=Den port, som tjenesten kører på +serviceHost=Servicevært +serviceHostDescription=Den vært, som tjenesten kører på +openWebsite=Åben hjemmeside +serviceGroup.displayName=Service-gruppe +serviceGroup.displayDescription=Gruppér flere tjenester i én kategori +initScript=Kører på shell init +shellScript=Gør script tilgængeligt under shell-session +fileScript=Gør det muligt at kalde et script med filargumenter i filbrowseren +runScript=Kør script ... +copyUrl=Kopier URL +fixedServiceGroup.displayName=Service-gruppe +fixedServiceGroup.displayDescription=Liste over tilgængelige tjenester på et system +mappedService.displayName=Service +mappedService.displayDescription=Interagere med en tjeneste, der er eksponeret af en container diff --git a/lang/base/strings/translations_de.properties b/lang/base/strings/translations_de.properties index 720b53840..e1a4873ea 100644 --- a/lang/base/strings/translations_de.properties +++ b/lang/base/strings/translations_de.properties @@ -61,7 +61,7 @@ isDefault=Wird in allen kompatiblen Shells auf init ausgeführt bringToShells=Zu allen kompatiblen Shells bringen isDefaultGroup=Alle Gruppenskripte auf der Shell init ausführen executionType=Ausführungsart -executionTypeDescription=Wann dieses Snippet ausgeführt werden soll +executionTypeDescription=In welchen Kontexten ist dieses Skript zu verwenden? minimumShellDialect=Shell-Typ minimumShellDialectDescription=Der erforderliche Shell-Typ für dieses Skript dumbOnly=Dumm @@ -134,3 +134,23 @@ desktopCommand.displayName=Desktop-Befehl desktopCommand.displayDescription=Einen Befehl in einer Remote-Desktop-Umgebung ausführen desktopCommandScript=Befehle desktopCommandScriptDescription=Die Befehle, die in der Umgebung ausgeführt werden sollen +service.displayName=Dienst +service.displayDescription=Einen Ferndienst an deinen lokalen Rechner weiterleiten +serviceLocalPort=Expliziter lokaler Port +serviceLocalPortDescription=Der lokale Port, an den weitergeleitet werden soll, andernfalls wird ein zufälliger Port verwendet +serviceRemotePort=Entfernter Anschluss +serviceRemotePortDescription=Der Port, auf dem der Dienst läuft +serviceHost=Diensthost +serviceHostDescription=Der Host, auf dem der Dienst läuft +openWebsite=Website öffnen +serviceGroup.displayName=Dienstgruppe +serviceGroup.displayDescription=Mehrere Dienste in einer Kategorie zusammenfassen +initScript=Auf der Shell init ausführen +shellScript=Skript während der Shell-Sitzung verfügbar machen +fileScript=Skriptaufruf mit Dateiargumenten im Dateibrowser zulassen +runScript=Skript ausführen ... +copyUrl=URL kopieren +fixedServiceGroup.displayName=Dienstgruppe +fixedServiceGroup.displayDescription=Liste der verfügbaren Dienste auf einem System +mappedService.displayName=Dienst +mappedService.displayDescription=Interaktion mit einem Dienst, der von einem Container angeboten wird diff --git a/lang/base/strings/translations_en.properties b/lang/base/strings/translations_en.properties index 5f12de7a2..f56a9e925 100644 --- a/lang/base/strings/translations_en.properties +++ b/lang/base/strings/translations_en.properties @@ -60,7 +60,7 @@ isDefault=Run on init in all compatible shells bringToShells=Bring to all compatible shells isDefaultGroup=Run all group scripts on shell init executionType=Execution type -executionTypeDescription=When to run this snippet +executionTypeDescription=In what contexts to use this script minimumShellDialect=Shell type minimumShellDialectDescription=The required shell type for this script dumbOnly=Dumb @@ -132,5 +132,25 @@ desktopCommand.displayName=Desktop command desktopCommand.displayDescription=Run a command in a remote desktop environment desktopCommandScript=Commands desktopCommandScriptDescription=The commands to run in the environment +service.displayName=Service +service.displayDescription=Forward a remote service to your local machine +serviceLocalPort=Explicit local port +serviceLocalPortDescription=The local port to forward to, otherwise a random one is used +serviceRemotePort=Remote port +serviceRemotePortDescription=The port on which the service is running on +serviceHost=Service host +serviceHostDescription=The host the service is running on +openWebsite=Open website +serviceGroup.displayName=Service group +serviceGroup.displayDescription=Group multiple services into one category +initScript=Run on shell init +shellScript=Make script available during shell session +fileScript=Allow script to be called with file arguments in the file browser +runScript=Run script with +copyUrl=Copy URL +fixedServiceGroup.displayName=Service group +fixedServiceGroup.displayDescription=List the available services on a system +mappedService.displayName=Service +mappedService.displayDescription=Interact with a service exposed by a container diff --git a/lang/base/strings/translations_es.properties b/lang/base/strings/translations_es.properties index 758da880c..6f01000e6 100644 --- a/lang/base/strings/translations_es.properties +++ b/lang/base/strings/translations_es.properties @@ -60,7 +60,7 @@ isDefault=Se ejecuta en init en todos los shells compatibles bringToShells=Lleva a todas las conchas compatibles isDefaultGroup=Ejecutar todos los scripts de grupo en shell init executionType=Tipo de ejecución -executionTypeDescription=Cuándo ejecutar este fragmento +executionTypeDescription=En qué contextos utilizar este script minimumShellDialect=Tipo de carcasa minimumShellDialectDescription=El tipo de shell requerido para este script dumbOnly=Mudo @@ -132,3 +132,23 @@ desktopCommand.displayName=Comando de escritorio desktopCommand.displayDescription=Ejecutar un comando en un entorno de escritorio remoto desktopCommandScript=Comandos desktopCommandScriptDescription=Los comandos a ejecutar en el entorno +service.displayName=Servicio +service.displayDescription=Reenviar un servicio remoto a tu máquina local +serviceLocalPort=Puerto local explícito +serviceLocalPortDescription=El puerto local al que reenviar, de lo contrario se utiliza uno aleatorio +serviceRemotePort=Puerto remoto +serviceRemotePortDescription=El puerto en el que se ejecuta el servicio +serviceHost=Host de servicio +serviceHostDescription=El host en el que se ejecuta el servicio +openWebsite=Abrir sitio web +serviceGroup.displayName=Grupo de servicios +serviceGroup.displayDescription=Agrupa varios servicios en una categoría +initScript=Ejecutar en shell init +shellScript=Hacer que el script esté disponible durante la sesión shell +fileScript=Permitir llamar a un script con argumentos de archivo en el explorador de archivos +runScript=Ejecutar script ... +copyUrl=Copiar URL +fixedServiceGroup.displayName=Grupo de servicios +fixedServiceGroup.displayDescription=Enumerar los servicios disponibles en un sistema +mappedService.displayName=Servicio +mappedService.displayDescription=Interactúa con un servicio expuesto por un contenedor diff --git a/lang/base/strings/translations_fr.properties b/lang/base/strings/translations_fr.properties index 32350f2f4..bcbde2a14 100644 --- a/lang/base/strings/translations_fr.properties +++ b/lang/base/strings/translations_fr.properties @@ -60,7 +60,7 @@ isDefault=S'exécute en mode init dans tous les shells compatibles bringToShells=Apporte à tous les coquillages compatibles isDefaultGroup=Exécute tous les scripts de groupe au démarrage de l'interpréteur de commandes executionType=Type d'exécution -executionTypeDescription=Quand exécuter cet extrait +executionTypeDescription=Dans quels contextes utiliser ce script minimumShellDialect=Type de coquille minimumShellDialectDescription=Le type d'interpréteur de commandes requis pour ce script dumbOnly=Muet @@ -132,3 +132,23 @@ desktopCommand.displayName=Commande de bureau desktopCommand.displayDescription=Exécuter une commande dans un environnement de bureau à distance desktopCommandScript=Commandes desktopCommandScriptDescription=Les commandes à exécuter dans l'environnement +service.displayName=Service +service.displayDescription=Transférer un service distant vers ta machine locale +serviceLocalPort=Port local explicite +serviceLocalPortDescription=Le port local vers lequel transférer, sinon un port aléatoire est utilisé +serviceRemotePort=Port distant +serviceRemotePortDescription=Le port sur lequel le service fonctionne +serviceHost=Hôte du service +serviceHostDescription=L'hôte sur lequel le service est exécuté +openWebsite=Ouvrir un site web +serviceGroup.displayName=Groupe de service +serviceGroup.displayDescription=Regrouper plusieurs services dans une même catégorie +initScript=Exécute sur le shell init +shellScript=Rendre le script disponible pendant la session shell +fileScript=Permet d'appeler un script avec des arguments de fichier dans le navigateur de fichiers +runScript=Exécute le script ... +copyUrl=Copier l'URL +fixedServiceGroup.displayName=Groupe de service +fixedServiceGroup.displayDescription=Liste les services disponibles sur un système +mappedService.displayName=Service +mappedService.displayDescription=Interagir avec un service exposé par un conteneur diff --git a/lang/base/strings/translations_it.properties b/lang/base/strings/translations_it.properties index ad162330e..0d360788e 100644 --- a/lang/base/strings/translations_it.properties +++ b/lang/base/strings/translations_it.properties @@ -60,7 +60,7 @@ isDefault=Eseguito su init in tutte le shell compatibili bringToShells=Porta a tutte le conchiglie compatibili isDefaultGroup=Esegui tutti gli script del gruppo all'avvio della shell executionType=Tipo di esecuzione -executionTypeDescription=Quando eseguire questo snippet +executionTypeDescription=In quali contesti utilizzare questo script minimumShellDialect=Tipo di shell minimumShellDialectDescription=Il tipo di shell richiesto per questo script dumbOnly=Muto @@ -132,3 +132,23 @@ desktopCommand.displayName=Comando sul desktop desktopCommand.displayDescription=Eseguire un comando in un ambiente desktop remoto desktopCommandScript=Comandi desktopCommandScriptDescription=I comandi da eseguire nell'ambiente +service.displayName=Servizio +service.displayDescription=Inoltrare un servizio remoto al computer locale +serviceLocalPort=Porta locale esplicita +serviceLocalPortDescription=La porta locale a cui inoltrare, altrimenti ne viene utilizzata una a caso +serviceRemotePort=Porta remota +serviceRemotePortDescription=La porta su cui è in esecuzione il servizio +serviceHost=Servizio host +serviceHostDescription=L'host su cui è in esecuzione il servizio +openWebsite=Sito web aperto +serviceGroup.displayName=Gruppo di servizio +serviceGroup.displayDescription=Raggruppa più servizi in un'unica categoria +initScript=Eseguire su shell init +shellScript=Rendere disponibile lo script durante la sessione di shell +fileScript=Consente di richiamare uno script con argomenti di file nel browser di file +runScript=Esegui script ... +copyUrl=Copia URL +fixedServiceGroup.displayName=Gruppo di servizio +fixedServiceGroup.displayDescription=Elenco dei servizi disponibili su un sistema +mappedService.displayName=Servizio +mappedService.displayDescription=Interagire con un servizio esposto da un contenitore diff --git a/lang/base/strings/translations_ja.properties b/lang/base/strings/translations_ja.properties index 07349e01d..160be1416 100644 --- a/lang/base/strings/translations_ja.properties +++ b/lang/base/strings/translations_ja.properties @@ -60,7 +60,7 @@ isDefault=すべての互換シェルでinit時に実行される bringToShells=すべての互換性のあるシェルに持ち込む isDefaultGroup=シェル init ですべてのグループスクリプトを実行する executionType=実行タイプ -executionTypeDescription=このスニペットを実行するタイミング +executionTypeDescription=このスクリプトをどのような文脈で使うか minimumShellDialect=シェルタイプ minimumShellDialectDescription=このスクリプトに必要なシェルタイプ dumbOnly=ダム @@ -132,3 +132,23 @@ desktopCommand.displayName=デスクトップコマンド desktopCommand.displayDescription=リモートデスクトップ環境でコマンドを実行する desktopCommandScript=コマンド desktopCommandScriptDescription=環境で実行するコマンド +service.displayName=サービス +service.displayDescription=リモートサービスをローカルマシンに転送する +serviceLocalPort=明示的なローカルポート +serviceLocalPortDescription=転送先のローカルポート。そうでない場合はランダムなポートが使われる。 +serviceRemotePort=リモートポート +serviceRemotePortDescription=サービスが実行されているポート +serviceHost=サービスホスト +serviceHostDescription=サービスが稼働しているホスト +openWebsite=オープンウェブサイト +serviceGroup.displayName=サービスグループ +serviceGroup.displayDescription=複数のサービスを1つのカテゴリーにまとめる +initScript=シェル init で実行する +shellScript=シェルセッション中にスクリプトを利用可能にする +fileScript=ファイルブラウザでファイル引数を指定してスクリプトを呼び出せるようにする +runScript=スクリプトを実行する +copyUrl=URLをコピーする +fixedServiceGroup.displayName=サービスグループ +fixedServiceGroup.displayDescription=システムで利用可能なサービスをリストアップする +mappedService.displayName=サービス +mappedService.displayDescription=コンテナによって公開されたサービスとやりとりする diff --git a/lang/base/strings/translations_nl.properties b/lang/base/strings/translations_nl.properties index 989c886d1..e54d91144 100644 --- a/lang/base/strings/translations_nl.properties +++ b/lang/base/strings/translations_nl.properties @@ -60,7 +60,7 @@ isDefault=Uitvoeren op init in alle compatibele shells bringToShells=Breng naar alle compatibele shells isDefaultGroup=Alle groepsscripts uitvoeren op shell init executionType=Type uitvoering -executionTypeDescription=Wanneer dit knipsel uitvoeren +executionTypeDescription=In welke contexten kun je dit script gebruiken minimumShellDialect=Type omhulsel minimumShellDialectDescription=Het vereiste shelltype voor dit script dumbOnly=Stom @@ -132,3 +132,23 @@ desktopCommand.displayName=Desktop opdracht desktopCommand.displayDescription=Een opdracht uitvoeren in een externe desktopomgeving desktopCommandScript=Opdrachten desktopCommandScriptDescription=De commando's om uit te voeren in de omgeving +service.displayName=Service +service.displayDescription=Een service op afstand doorsturen naar je lokale machine +serviceLocalPort=Expliciete lokale poort +serviceLocalPortDescription=De lokale poort om naar door te sturen, anders wordt een willekeurige poort gebruikt +serviceRemotePort=Externe poort +serviceRemotePortDescription=De poort waarop de service draait +serviceHost=Service host +serviceHostDescription=De host waarop de service draait +openWebsite=Open website +serviceGroup.displayName=Servicegroep +serviceGroup.displayDescription=Groepeer meerdere diensten in één categorie +initScript=Uitvoeren op shell init +shellScript=Script beschikbaar maken tijdens shellsessie +fileScript=Laat toe dat een script wordt aangeroepen met bestandsargumenten in de bestandsbrowser +runScript=Script uitvoeren ... +copyUrl=URL kopiëren +fixedServiceGroup.displayName=Servicegroep +fixedServiceGroup.displayDescription=Een lijst van beschikbare services op een systeem +mappedService.displayName=Service +mappedService.displayDescription=Interactie met een service die wordt aangeboden door een container diff --git a/lang/base/strings/translations_pt.properties b/lang/base/strings/translations_pt.properties index e22f39af7..8d115e42f 100644 --- a/lang/base/strings/translations_pt.properties +++ b/lang/base/strings/translations_pt.properties @@ -60,7 +60,7 @@ isDefault=Corre no init em todos os shells compatíveis bringToShells=Traz para todos os shells compatíveis isDefaultGroup=Executa todos os scripts de grupo no shell init executionType=Tipo de execução -executionTypeDescription=Quando deves executar este snippet +executionTypeDescription=Em que contextos podes utilizar este script minimumShellDialect=Tipo de shell minimumShellDialectDescription=O tipo de shell necessário para este script dumbOnly=Estúpido @@ -132,3 +132,23 @@ desktopCommand.displayName=Comando do ambiente de trabalho desktopCommand.displayDescription=Executa um comando num ambiente de trabalho remoto desktopCommandScript=Comandos desktopCommandScriptDescription=Os comandos a executar no ambiente +service.displayName=Serviço +service.displayDescription=Encaminhar um serviço remoto para a tua máquina local +serviceLocalPort=Porta local explícita +serviceLocalPortDescription=A porta local para a qual reencaminhar, caso contrário é utilizada uma porta aleatória +serviceRemotePort=Porta remota +serviceRemotePortDescription=A porta em que o serviço está a ser executado +serviceHost=Anfitrião de serviço +serviceHostDescription=O anfitrião em que o serviço está a ser executado +openWebsite=Abre o sítio Web +serviceGroup.displayName=Grupo de serviços +serviceGroup.displayDescription=Agrupa vários serviços numa categoria +initScript=Corre no shell init +shellScript=Torna o script disponível durante a sessão da shell +fileScript=Permite que o script seja chamado com argumentos de ficheiro no navegador de ficheiros +runScript=Executa o script ... +copyUrl=Copia o URL +fixedServiceGroup.displayName=Grupo de serviços +fixedServiceGroup.displayDescription=Lista os serviços disponíveis num sistema +mappedService.displayName=Serviço +mappedService.displayDescription=Interage com um serviço exposto por um contentor diff --git a/lang/base/strings/translations_ru.properties b/lang/base/strings/translations_ru.properties index 6f77f2541..3640e64fc 100644 --- a/lang/base/strings/translations_ru.properties +++ b/lang/base/strings/translations_ru.properties @@ -60,7 +60,7 @@ isDefault=Запускается в init во всех совместимых о bringToShells=Принесите всем совместимым оболочкам isDefaultGroup=Запустите все групповые скрипты на shell init executionType=Тип исполнения -executionTypeDescription=Когда запускать этот сниппет +executionTypeDescription=В каких контекстах использовать этот скрипт minimumShellDialect=Тип оболочки minimumShellDialectDescription=Необходимый тип оболочки для этого скрипта dumbOnly=Тупой @@ -132,3 +132,23 @@ desktopCommand.displayName=Команда рабочего стола desktopCommand.displayDescription=Выполнить команду в среде удаленного рабочего стола desktopCommandScript=Команды desktopCommandScriptDescription=Команды для запуска в среде +service.displayName=Сервис +service.displayDescription=Перенаправить удаленный сервис на локальную машину +serviceLocalPort=Явный локальный порт +serviceLocalPortDescription=Локальный порт для переадресации, в противном случае используется случайный порт +serviceRemotePort=Удаленный порт +serviceRemotePortDescription=Порт, на котором работает служба +serviceHost=Сервисный хост +serviceHostDescription=Хост, на котором запущена служба +openWebsite=Открытый сайт +serviceGroup.displayName=Группа услуг +serviceGroup.displayDescription=Сгруппируйте несколько сервисов в одну категорию +initScript=Запуск на shell init +shellScript=Сделать скрипт доступным во время сеанса оболочки +fileScript=Разрешить вызов скрипта с аргументами в виде файлов в браузере файлов +runScript=Запустите скрипт ... +copyUrl=Копировать URL +fixedServiceGroup.displayName=Группа услуг +fixedServiceGroup.displayDescription=Список доступных сервисов в системе +mappedService.displayName=Сервис +mappedService.displayDescription=Взаимодействие с сервисом, открываемым контейнером diff --git a/lang/base/strings/translations_tr.properties b/lang/base/strings/translations_tr.properties index 4bfc1484e..3746f7bd2 100644 --- a/lang/base/strings/translations_tr.properties +++ b/lang/base/strings/translations_tr.properties @@ -60,7 +60,7 @@ isDefault=Tüm uyumlu kabuklarda init üzerinde çalıştırın bringToShells=Tüm uyumlu kabukları getirin isDefaultGroup=Tüm grup komut dosyalarını kabuk başlangıcında çalıştırın executionType=Yürütme türü -executionTypeDescription=Bu snippet ne zaman çalıştırılır +executionTypeDescription=Bu komut dosyası hangi bağlamlarda kullanılmalı minimumShellDialect=Kabuk tipi minimumShellDialectDescription=Bu betik için gerekli kabuk türü dumbOnly=Aptal @@ -132,3 +132,23 @@ desktopCommand.displayName=Masaüstü komutu desktopCommand.displayDescription=Uzak masaüstü ortamında bir komut çalıştırma desktopCommandScript=Komutlar desktopCommandScriptDescription=Ortamda çalıştırılacak komutlar +service.displayName=Hizmet +service.displayDescription=Uzak bir hizmeti yerel makinenize iletme +serviceLocalPort=Açık yerel bağlantı noktası +serviceLocalPortDescription=Yönlendirilecek yerel bağlantı noktası, aksi takdirde rastgele bir bağlantı noktası kullanılır +serviceRemotePort=Uzak bağlantı noktası +serviceRemotePortDescription=Hizmetin üzerinde çalıştığı bağlantı noktası +serviceHost=Hizmet sunucusu +serviceHostDescription=Hizmetin üzerinde çalıştığı ana bilgisayar +openWebsite=Açık web sitesi +serviceGroup.displayName=Hizmet grubu +serviceGroup.displayDescription=Birden fazla hizmeti tek bir kategoride gruplayın +initScript=Kabuk başlangıcında çalıştır +shellScript=Kabuk oturumu sırasında komut dosyasını kullanılabilir hale getirme +fileScript=Kodun dosya tarayıcısında dosya bağımsız değişkenleriyle çağrılmasına izin ver +runScript=Komut dosyasını çalıştır ... +copyUrl=URL'yi kopyala +fixedServiceGroup.displayName=Hizmet grubu +fixedServiceGroup.displayDescription=Bir sistemdeki mevcut hizmetleri listeleme +mappedService.displayName=Hizmet +mappedService.displayDescription=Bir konteyner tarafından sunulan bir hizmetle etkileşim diff --git a/lang/base/strings/translations_zh.properties b/lang/base/strings/translations_zh.properties index 5cb6b6e49..ce9853186 100644 --- a/lang/base/strings/translations_zh.properties +++ b/lang/base/strings/translations_zh.properties @@ -60,7 +60,7 @@ isDefault=在所有兼容外壳的 init 中运行 bringToShells=带入所有兼容外壳 isDefaultGroup=在 shell 启动时运行所有组脚本 executionType=执行类型 -executionTypeDescription=何时运行此片段 +executionTypeDescription=在哪些情况下使用此脚本 minimumShellDialect=外壳类型 minimumShellDialectDescription=该脚本所需的 shell 类型 dumbOnly=笨 @@ -132,3 +132,23 @@ desktopCommand.displayName=桌面命令 desktopCommand.displayDescription=在远程桌面环境中运行命令 desktopCommandScript=命令 desktopCommandScriptDescription=在环境中运行的命令 +service.displayName=服务 +service.displayDescription=将远程服务转发到本地计算机 +serviceLocalPort=显式本地端口 +serviceLocalPortDescription=要转发到的本地端口,否则使用随机端口 +serviceRemotePort=远程端口 +serviceRemotePortDescription=服务运行的端口 +serviceHost=服务主机 +serviceHostDescription=服务运行的主机 +openWebsite=打开网站 +serviceGroup.displayName=服务组 +serviceGroup.displayDescription=将多项服务归为一类 +initScript=在 shell init 上运行 +shellScript=在 shell 会话中提供脚本 +fileScript=允许在文件浏览器中使用文件参数调用脚本 +runScript=运行脚本 ... +copyUrl=复制 URL +fixedServiceGroup.displayName=服务组 +fixedServiceGroup.displayDescription=列出系统中可用的服务 +mappedService.displayName=服务 +mappedService.displayDescription=与容器暴露的服务交互 diff --git a/lang/base/texts/executionType_da.md b/lang/base/texts/executionType_da.md index db58848e6..a9617f683 100644 --- a/lang/base/texts/executionType_da.md +++ b/lang/base/texts/executionType_da.md @@ -1,15 +1,50 @@ -## Udførelsestyper +# Udførelsestyper -Der er to forskellige eksekveringstyper, når XPipe opretter forbindelse til et system. +Du kan bruge et script i flere forskellige scenarier. -### I baggrunden +Når du aktiverer et script, dikterer udførelsestyperne, hvad XPipe vil gøre med scriptet. -Den første forbindelse til et system oprettes i baggrunden i en dumb terminal-session. +## Init-scripts -Blokeringskommandoer, der kræver brugerinput, kan fryse shell-processen, når XPipe starter den op internt i baggrunden. For at undgå dette bør du kun kalde disse blokerende kommandoer i terminaltilstand. +Når et script er angivet som init-script, kan det vælges i shell-miljøer. -Filbrowseren bruger for eksempel udelukkende den dumme baggrundstilstand til at håndtere sine operationer, så hvis du vil have dit scriptmiljø til at gælde for filbrowsersessionen, skal det køre i den dumme tilstand. +Hvis et script er aktiveret, vil det desuden automatisk blive kørt ved init i alle kompatible shells. + +Hvis du f.eks. opretter et simpelt init-script som +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +du vil have adgang til disse aliasser i alle kompatible shell-sessioner, hvis scriptet er aktiveret. + +## Shell-scripts + +Et normalt shell-script er beregnet til at blive kaldt i en shell-session i din terminal. +Når det er aktiveret, bliver scriptet kopieret til målsystemet og lagt ind i PATH i alle kompatible shells. +På den måde kan du kalde scriptet fra hvor som helst i en terminalsession. +Scriptnavnet skrives med små bogstaver, og mellemrum erstattes med understregninger, så du nemt kan kalde scriptet. + +Hvis du f.eks. opretter et simpelt shell-script med navnet `apti` som +``` +sudo apt install "$1" +``` +kan du kalde det på ethvert kompatibelt system med `apti.sh `, hvis scriptet er aktiveret. + +## Fil-scripts + +Endelig kan du også køre brugerdefinerede scripts med filinput fra filbrowser-grænsefladen. +Når et filscript er aktiveret, vises det i filbrowseren, så det kan køres med filinput. + +Hvis du f.eks. opretter et simpelt filscript som +``` +sudo apt install "$@" +``` +kan du køre scriptet på udvalgte filer, hvis scriptet er aktiveret. + +## Flere typer + +Da eksemplet på fil-scriptet er det samme som eksemplet på shell-scriptet ovenfor, +kan du se, at du også kan sætte kryds i flere bokse for udførelsestyper af et script, hvis de skal bruges i flere scenarier. -### I terminalerne -Når den indledende dumb terminal-forbindelse er lykkedes, vil XPipe åbne en separat forbindelse i den faktiske terminal. Hvis du vil have scriptet til at køre, når du åbner forbindelsen i en terminal, skal du vælge terminaltilstand. diff --git a/lang/base/texts/executionType_de.md b/lang/base/texts/executionType_de.md index 45b36bcfc..cc16f49e2 100644 --- a/lang/base/texts/executionType_de.md +++ b/lang/base/texts/executionType_de.md @@ -1,15 +1,50 @@ -## Ausführungsarten +# Ausführungsarten -Es gibt zwei verschiedene Ausführungsarten, wenn XPipe eine Verbindung zu einem System herstellt. +Du kannst ein Skript in vielen verschiedenen Szenarien verwenden. -### Im Hintergrund +Wenn du ein Skript aktivierst, legen die Ausführungsarten fest, was XPipe mit dem Skript tun soll. -Die erste Verbindung zu einem System wird im Hintergrund in einer stummen Terminalsitzung hergestellt. +## Init-Skripte -Blockierende Befehle, die Benutzereingaben erfordern, können den Shell-Prozess einfrieren, wenn XPipe ihn intern zuerst im Hintergrund startet. Um dies zu vermeiden, solltest du diese blockierenden Befehle nur im Terminalmodus aufrufen. +Wenn ein Skript als Init-Skript gekennzeichnet ist, kann es in Shell-Umgebungen ausgewählt werden. -Der Dateibrowser z. B. verwendet für seine Operationen ausschließlich den dummen Hintergrundmodus. Wenn du also möchtest, dass deine Skriptumgebung für die Dateibrowser-Sitzung gilt, sollte sie im dummen Modus ausgeführt werden. +Wenn ein Skript aktiviert ist, wird es außerdem automatisch bei init in allen kompatiblen Shells ausgeführt. + +Wenn du zum Beispiel ein einfaches Init-Skript erstellst wie +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +hast du in allen kompatiblen Shell-Sitzungen Zugang zu diesen Aliasen, wenn das Skript aktiviert ist. + +## Shell-Skripte + +Ein normales Shell-Skript ist dafür gedacht, in einer Shell-Sitzung in deinem Terminal aufgerufen zu werden. +Wenn es aktiviert ist, wird das Skript auf das Zielsystem kopiert und in den PATH aller kompatiblen Shells aufgenommen. +So kannst du das Skript von überall in einer Terminal-Sitzung aufrufen. +Der Skriptname wird kleingeschrieben und Leerzeichen werden durch Unterstriche ersetzt, damit du das Skript leicht aufrufen kannst. + +Wenn du zum Beispiel ein einfaches Shell-Skript mit dem Namen `apti` wie folgt erstellst +``` +sudo apt install "$1" +``` +kannst du das auf jedem kompatiblen System mit `apti.sh ` aufrufen, wenn das Skript aktiviert ist. + +## Datei-Skripte + +Schließlich kannst du auch benutzerdefinierte Skripte mit Dateieingaben über die Dateibrowser-Schnittstelle ausführen. +Wenn ein Dateiskript aktiviert ist, wird es im Dateibrowser angezeigt und kann mit Dateieingaben ausgeführt werden. + +Wenn du zum Beispiel ein einfaches Dateiskript erstellst wie +``` +sudo apt install "$@" +``` +kannst du das Skript für ausgewählte Dateien ausführen, wenn das Skript aktiviert ist. + +## Mehrere Typen + +Da das Beispielskript für die Datei dasselbe ist wie das Beispielsskript für die Shell oben, +siehst du, dass du auch mehrere Kästchen für die Ausführungsarten eines Skripts ankreuzen kannst, wenn sie in mehreren Szenarien verwendet werden sollen. -### In den Terminals -Nachdem die anfängliche Dumb-Terminal-Verbindung erfolgreich war, öffnet XPipe eine separate Verbindung im eigentlichen Terminal. Wenn du möchtest, dass das Skript ausgeführt wird, wenn du die Verbindung in einem Terminal öffnest, dann wähle den Terminalmodus. diff --git a/lang/base/texts/executionType_en.md b/lang/base/texts/executionType_en.md index 68e77d4b7..7a0dbec4e 100644 --- a/lang/base/texts/executionType_en.md +++ b/lang/base/texts/executionType_en.md @@ -1,15 +1,50 @@ -## Execution types +# Execution types -There are two distinct execution types when XPipe connects to a system. +You can use a script in multiple different scenarios. -### In the background +When enabling a script, the execution types dictate what XPipe will do with the script. -The first connection to a system is made in the background in a dumb terminal session. +## Init scripts -Blocking commands that require user input can freeze the shell process when XPipe starts it up internally first in the background. To avoid this, you should only call these blocking commands in the terminal mode. +When a script is designated as init script, it can be selected in shell environments. -The file browser for example entirely uses the dumb background mode to handle its operations, so if you want your script environment to apply to the file browser session, it should run in the dumb mode. +Furthermore, if a script is enabled, it will automatically be run on init in all compatible shells. + +For example, if you create a simple init script like +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +you will have access to these aliases in all compatible shell sessions if the script is enabled. + +## Shell scripts + +A normal shell script is intended to be called in a shell session in your terminal. +When enabled, the script will be copied to the target system and put into the PATH in all compatible shells. +This allows you to call the script from anywhere in a terminal session. +The script name will be lowercased and spaces will be replaced with underscores, allowing you to easily call the script. + +For example, if you create a simple shell script named `apti` like +``` +sudo apt install "$1" +``` +you can call that on any compatible system with `apti.sh ` if the script is enabled. + +## File scripts + +Lastly, you can also run custom script with file inputs from the file browser interface. +When a file script is enabled, it will show up in the file browser to be run with file inputs. + +For example, if you create a simple file script like +``` +sudo apt install "$@" +``` +you can run the script on selected files if the script is enabled. + +## Multiple types + +As the sample file script is the same as the sample shell script above, +you see that you can also tick multiple boxes for execution types of a script if they should be used in multiple scenarios. -### In the terminals -After the initial dumb terminal connection has succeeded, XPipe will open a separate connection in the actual terminal. If you want the script to be run when you open the connection in a terminal, then choose the terminal mode. diff --git a/lang/base/texts/executionType_es.md b/lang/base/texts/executionType_es.md index 945fb99c2..5cc3852c9 100644 --- a/lang/base/texts/executionType_es.md +++ b/lang/base/texts/executionType_es.md @@ -1,15 +1,50 @@ -## Tipos de ejecución +# Tipos de ejecución -Hay dos tipos de ejecución distintos cuando XPipe se conecta a un sistema. +Puedes utilizar un script en múltiples escenarios diferentes. -### En segundo plano +Al activar un script, los tipos de ejecución dictan lo que XPipe hará con el script. -La primera conexión a un sistema se realiza en segundo plano en una sesión de terminal tonta. +## Guiones de inicio -Los comandos de bloqueo que requieren la entrada del usuario pueden congelar el proceso shell cuando XPipe lo inicia internamente por primera vez en segundo plano. Para evitarlo, sólo debes llamar a estos comandos de bloqueo en el modo terminal. +Cuando un script se designa como script init, se puede seleccionar en entornos shell. -El explorador de archivos, por ejemplo, utiliza enteramente el modo mudo en segundo plano para manejar sus operaciones, así que si quieres que tu entorno de script se aplique a la sesión del explorador de archivos, debe ejecutarse en el modo mudo. +Además, si un script está activado, se ejecutará automáticamente en init en todos los shells compatibles. + +Por ejemplo, si creas un script init sencillo como +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +tendrás acceso a estos alias en todas las sesiones de shell compatibles si el script está activado. + +## Scripts de shell + +Un script de shell normal está pensado para ser llamado en una sesión de shell en tu terminal. +Cuando está activado, el script se copiará en el sistema de destino y se pondrá en el PATH en todas las shell compatibles. +Esto te permite llamar al script desde cualquier lugar de una sesión de terminal. +El nombre del script se escribirá en minúsculas y los espacios se sustituirán por guiones bajos, lo que te permitirá llamarlo fácilmente. + +Por ejemplo, si creas un sencillo script de shell llamado `apti` como +``` +sudo apt install "$1" +``` +puedes invocarlo en cualquier sistema compatible con `apti.sh ` si el script está activado. + +## Archivo scripts + +Por último, también puedes ejecutar scripts personalizados con entradas de archivo desde la interfaz del explorador de archivos. +Cuando un script de archivo esté activado, aparecerá en el explorador de archivos para ejecutarse con entradas de archivo. + +Por ejemplo, si creas un script de archivo sencillo como +``` +sudo apt install "$@" +``` +puedes ejecutar el script en los archivos seleccionados si el script está activado. + +## Tipos múltiples + +Como el script de archivo de ejemplo es el mismo que el script de shell de ejemplo anterior, +verás que también puedes marcar varias casillas para los tipos de ejecución de un script si deben utilizarse en varios escenarios. -### En los terminales -Después de que la conexión inicial de terminal mudo haya tenido éxito, XPipe abrirá una conexión separada en el terminal real. Si quieres que el script se ejecute al abrir la conexión en un terminal, elige el modo terminal. diff --git a/lang/base/texts/executionType_fr.md b/lang/base/texts/executionType_fr.md index 0a502bb3a..63d1f1b99 100644 --- a/lang/base/texts/executionType_fr.md +++ b/lang/base/texts/executionType_fr.md @@ -1,15 +1,50 @@ -## Types d'exécution +# Types d'exécution -Il existe deux types d'exécution distincts lorsque XPipe se connecte à un système. +Tu peux utiliser un script dans plusieurs scénarios différents. -### En arrière-plan +Lors de l'activation d'un script, les types d'exécution dictent ce que XPipe fera avec le script. -La première connexion à un système est effectuée en arrière-plan dans une session de terminal muet. +## Init scripts -Les commandes de blocage qui nécessitent une entrée de la part de l'utilisateur peuvent geler le processus de l'interpréteur de commandes lorsque XPipe le démarre d'abord en interne en arrière-plan. Pour éviter cela, tu ne dois appeler ces commandes bloquantes qu'en mode terminal. +Lorsqu'un script est désigné comme script init, il peut être sélectionné dans les environnements shell. -Le navigateur de fichiers, par exemple, utilise entièrement le mode d'arrière-plan muet pour gérer ses opérations, donc si tu veux que l'environnement de ton script s'applique à la session du navigateur de fichiers, il doit s'exécuter en mode muet. +De plus, si un script est activé, il sera automatiquement exécuté lors de l'init dans tous les shells compatibles. + +Par exemple, si tu crées un script init simple comme +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +tu auras accès à ces alias dans toutes les sessions shell compatibles si le script est activé. + +## Scripts shell + +Un script shell normal est destiné à être appelé dans une session shell dans ton terminal. +Lorsqu'il est activé, le script sera copié sur le système cible et placé dans le chemin d'accès (PATH) de tous les shells compatibles. +Cela te permet d'appeler le script depuis n'importe quel endroit d'une session de terminal. +Le nom du script sera en minuscules et les espaces seront remplacés par des traits de soulignement, ce qui te permettra d'appeler facilement le script. + +Par exemple, si tu crées un script shell simple nommé `apti` comme suit +``` +sudo apt install "$1" +``` +vous pouvez l'appeler sur n'importe quel système compatible avec `apti.sh ` si le script est activé. + +## Fichier scripts + +Enfin, tu peux aussi exécuter des scripts personnalisés avec des entrées de fichiers à partir de l'interface du navigateur de fichiers. +Lorsqu'un script de fichier est activé, il s'affiche dans le navigateur de fichiers pour être exécuté avec des entrées de fichier. + +Par exemple, si tu crées un script de fichier simple comme +``` +sudo apt install "$@" +``` +tu peux exécuter le script sur les fichiers sélectionnés si le script est activé. + +## Plusieurs types + +Comme l'exemple de script de fichier est le même que l'exemple de script shell ci-dessus, +tu vois que tu peux aussi cocher plusieurs cases pour les types d'exécution d'un script s'ils doivent être utilisés dans plusieurs scénarios. -### Dans les terminaux -Une fois que la connexion initiale au terminal muet a réussi, XPipe ouvre une connexion séparée dans le terminal réel. Si tu veux que le script soit exécuté lorsque tu ouvres la connexion dans un terminal, choisis le mode terminal. diff --git a/lang/base/texts/executionType_it.md b/lang/base/texts/executionType_it.md index 1254010e6..d3c07a921 100644 --- a/lang/base/texts/executionType_it.md +++ b/lang/base/texts/executionType_it.md @@ -1,15 +1,50 @@ -## Tipi di esecuzione +# Tipi di esecuzione -Esistono due tipi di esecuzione distinti quando XPipe si connette a un sistema. +Puoi utilizzare uno script in diversi scenari. -### In background +Quando abiliti uno script, i tipi di esecuzione stabiliscono cosa XPipe farà con lo script. -La prima connessione a un sistema avviene in background in una sessione di terminale muta. +## Script di avvio -I comandi di blocco che richiedono l'input dell'utente possono bloccare il processo di shell quando XPipe lo avvia internamente in background. Per evitare questo problema, dovresti chiamare questi comandi di blocco solo in modalità terminale. +Quando uno script è designato come script di avvio, può essere selezionato negli ambienti shell. -Il navigatore di file, ad esempio, utilizza esclusivamente la modalità di sfondo muta per gestire le sue operazioni, quindi se vuoi che il tuo ambiente di script si applichi alla sessione del navigatore di file, deve essere eseguito in modalità muta. +Inoltre, se uno script è abilitato, verrà eseguito automaticamente all'avvio in tutte le shell compatibili. + +Ad esempio, se crei un semplice script di avvio come +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +avrai accesso a questi alias in tutte le sessioni di shell compatibili se lo script è abilitato. + +## Script di shell + +Un normale script di shell è destinato a essere richiamato in una sessione di shell nel tuo terminale. +Se abilitato, lo script verrà copiato sul sistema di destinazione e inserito nel PATH di tutte le shell compatibili. +Questo ti permette di richiamare lo script da qualsiasi punto di una sessione di terminale. +Il nome dello script sarà minuscolo e gli spazi saranno sostituiti da trattini bassi, consentendoti di richiamare facilmente lo script. + +Ad esempio, se crei un semplice script di shell chiamato `apti` come +``` +sudo apt install "$1" +``` +puoi richiamarlo su qualsiasi sistema compatibile con `apti.sh ` se lo script è abilitato. + +## File script + +Infine, puoi anche eseguire script personalizzati con input da file dall'interfaccia del browser dei file. +Quando uno script di file è abilitato, viene visualizzato nel browser dei file per essere eseguito con input di file. + +Ad esempio, se crei un semplice script di file come +``` +sudo apt install "$@" +``` +puoi eseguire lo script sui file selezionati se lo script è abilitato. + +## Tipi multipli + +Poiché lo script di esempio per i file è identico allo script di esempio per la shell di cui sopra, +puoi anche spuntare più caselle per i tipi di esecuzione di uno script se questi devono essere utilizzati in più scenari. -### Nei terminali -Dopo che la connessione iniziale del terminale muto è riuscita, XPipe aprirà una connessione separata nel terminale vero e proprio. Se vuoi che lo script venga eseguito quando apri la connessione in un terminale, scegli la modalità terminale. diff --git a/lang/base/texts/executionType_ja.md b/lang/base/texts/executionType_ja.md index 4838ec548..56656bec9 100644 --- a/lang/base/texts/executionType_ja.md +++ b/lang/base/texts/executionType_ja.md @@ -1,15 +1,50 @@ -## 実行タイプ +# 実行タイプ -XPipeがシステムに接続する際、2種類の実行タイプがある。 +スクリプトは複数の異なるシナリオで使用できる。 -### バックグラウンド +スクリプトを有効にする場合、実行タイプによってXPipeがスクリプトで何を行うかが決まる。 -システムへの最初の接続は、ダム端末セッションでバックグラウンドで行われる。 +## スクリプトの初期化 -ユーザー入力を必要とするブロックコマンドは、XPipeがバックグラウンドで最初にシェルプロセスを内部的に起動する際に、シェルプロセスをフリーズさせる可能性がある。これを避けるため、これらのブロックコマンドはターミナルモードでのみ呼び出すべきである。 +スクリプトをinitスクリプトとして指定すると、シェル環境で選択できるようになる。 -例えばファイルブラウザは完全にダムバックグラウンドモードを使用して操作を処理するため、スクリプト環境をファイルブラウザセッションに適用したい場合は、ダムモードで実行する必要がある。 +さらに、スクリプトが有効になっていれば、互換性のあるすべてのシェルで、init時に自動的に実行される。 + +例えば、次のような単純なinitスクリプトを作成した場合 +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +スクリプトが有効になっていれば、互換性のあるすべてのシェル・セッションでこれらのエイリアスにアクセスできる。 + +## シェルスクリプト + +通常のシェルスクリプトは、ターミナル上のシェルセッションで呼び出され ることを想定している。 +有効にすると、スクリプトはターゲットシステムにコピーされ、 すべての互換シェルでPATHに入れられる。 +これにより、ターミナル・セッションのどこからでもスクリプトを呼び出すことができる。 +スクリプト名は小文字になり、スペースはアンダースコアに置き換えられるので、簡単にスクリプトを呼び出すことができる。 + +例えば、次のような`apti`という単純なシェルスクリプトを作成した場合、次のようになる。 +``` +sudo apt install "$1" +``` +スクリプトが有効になっていれば、互換性のあるシステム上で`apti.sh `を使ってそれを呼び出すことができる。 + +## ファイルスクリプト + +最後に、ファイルブラウザのインターフェイスからファイル入力を使ってカスタムスクリプトを実行することもできる。 +ファイルスクリプトが有効になると、ファイルブラウザに表示され、ファイル入力で実行できるようになる。 + +例えば、次のような簡単なファイルスクリプトを作成した場合 +``` +sudo apt install "$@" +``` +スクリプトが有効になっていれば、選択したファイルに対してスクリプトを実行できる。 + +## 複数のタイプ + +ファイルスクリプトのサンプルは、上のシェルスクリプトのサンプルと同じである、 +スクリプトを複数のシナリオで使用する場合は、スクリプトの実行タイプに複数のチェックボックスを付けることもできる。 -### ターミナルでは -最初のダムターミナル接続が成功すると、XPipeは実際のターミナルで別の接続を開く。ターミナルで接続を開いたときにスクリプトを実行させたい場合は、ターミナルモードを選択する。 diff --git a/lang/base/texts/executionType_nl.md b/lang/base/texts/executionType_nl.md index 505384329..c471f03d6 100644 --- a/lang/base/texts/executionType_nl.md +++ b/lang/base/texts/executionType_nl.md @@ -1,15 +1,50 @@ -## Uitvoeringstypes +# Uitvoeringstypen -Er zijn twee verschillende uitvoeringstypen wanneer XPipe verbinding maakt met een systeem. +Je kunt een script in meerdere verschillende scenario's gebruiken. -### Op de achtergrond +Wanneer je een script inschakelt, bepalen de uitvoeringstypen wat XPipe met het script zal doen. -De eerste verbinding met een systeem wordt op de achtergrond gemaakt in een domme terminal sessie. +## Init scripts -Blokkerende commando's die gebruikersinvoer vereisen kunnen het shell proces bevriezen wanneer XPipe het eerst intern op de achtergrond opstart. Om dit te voorkomen, moet je deze blokkerende commando's alleen in de terminalmodus aanroepen. +Als een script is aangewezen als init-script, kan het worden geselecteerd in shell-omgevingen. -De bestandsbrowser bijvoorbeeld gebruikt volledig de domme achtergrondmodus om zijn bewerkingen af te handelen, dus als je wilt dat je scriptomgeving van toepassing is op de bestandsbrowsersessie, moet deze in de domme modus draaien. +Bovendien, als een script is ingeschakeld, zal het automatisch worden uitgevoerd op init in alle compatibele shells. + +Als je bijvoorbeeld een eenvoudig init-script maakt als +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +je hebt toegang tot deze aliassen in alle compatibele shell sessies als het script is ingeschakeld. + +## Shell scripts + +Een normaal shellscript is bedoeld om aangeroepen te worden in een shellsessie in je terminal. +Als dit is ingeschakeld, wordt het script gekopieerd naar het doelsysteem en in het PATH van alle compatibele shells gezet. +Hierdoor kun je het script overal vandaan in een terminalsessie aanroepen. +De scriptnaam wordt met kleine letters geschreven en spaties worden vervangen door underscores, zodat je het script gemakkelijk kunt aanroepen. + +Als je bijvoorbeeld een eenvoudig shellscript maakt met de naam `apti` zoals +``` +sudo apt install "$1" +``` +kun je dat op elk compatibel systeem aanroepen met `apti.sh ` als het script is ingeschakeld. + +## Bestandsscripts + +Tot slot kun je ook aangepaste scripts uitvoeren met bestandsinvoer vanuit de bestandsbrowserinterface. +Als een bestandsscript is ingeschakeld, verschijnt het in de bestandsbrowser om te worden uitgevoerd met bestandsinvoer. + +Als je bijvoorbeeld een eenvoudig bestandsscript maakt zoals +``` +sudo apt install "$@" +``` +kun je het script uitvoeren op geselecteerde bestanden als het script is ingeschakeld. + +## Meerdere types + +Aangezien het voorbeeldbestandsscript hetzelfde is als het voorbeeldshell-script hierboven, +zie je dat je ook meerdere vakjes kunt aanvinken voor uitvoeringstypen van een script als ze in meerdere scenario's moeten worden gebruikt. -### In de terminals -Nadat de initiële domme terminalverbinding is gelukt, opent XPipe een aparte verbinding in de echte terminal. Als je wilt dat het script wordt uitgevoerd wanneer je de verbinding in een terminal opent, kies dan de terminalmodus. diff --git a/lang/base/texts/executionType_pt.md b/lang/base/texts/executionType_pt.md index a04bf5158..fdd4c2fb9 100644 --- a/lang/base/texts/executionType_pt.md +++ b/lang/base/texts/executionType_pt.md @@ -1,15 +1,50 @@ -## Tipos de execução +# Tipos de execução -Existem dois tipos de execução distintos quando o XPipe se liga a um sistema. +Podes utilizar um script em vários cenários diferentes. -### Em segundo plano +Ao ativar um script, os tipos de execução ditam o que o XPipe fará com o script. -A primeira conexão com um sistema é feita em segundo plano em uma sessão de terminal burro. +## Scripts de inicialização -Os comandos de bloqueio que requerem a entrada do usuário podem congelar o processo do shell quando o XPipe o inicia internamente primeiro em segundo plano. Para evitar isso, só deves chamar estes comandos de bloqueio no modo terminal. +Quando um script é designado como script de inicialização, ele pode ser selecionado em ambientes shell. -O navegador de ficheiros, por exemplo, utiliza inteiramente o modo de fundo burro para tratar das suas operações, por isso, se quiseres que o teu ambiente de script se aplique à sessão do navegador de ficheiros, deve ser executado no modo burro. +Além disso, se um script é habilitado, ele será automaticamente executado no init em todos os shells compatíveis. + +Por exemplo, se criares um script de inicialização simples como +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +terás acesso a estes aliases em todas as sessões de shell compatíveis se o script estiver ativado. + +## Scripts de shell + +Um script de shell normal destina-se a ser chamado numa sessão de shell no teu terminal. +Quando ativado, o script será copiado para o sistema alvo e colocado no PATH em todas as shells compatíveis. +Isto permite-te chamar o script a partir de qualquer lugar numa sessão de terminal. +O nome do script será escrito em minúsculas e os espaços serão substituídos por sublinhados, permitindo-te chamar facilmente o script. + +Por exemplo, se criares um script de shell simples chamado `apti` como +``` +sudo apt install "$1" +``` +podes chamar isso em qualquer sistema compatível com `apti.sh ` se o script estiver ativado. + +## Scripts de ficheiros + +Por último, também podes executar scripts personalizados com entradas de ficheiros a partir da interface do navegador de ficheiros. +Quando um script de arquivo estiver habilitado, ele aparecerá no navegador de arquivos para ser executado com entradas de arquivo. + +Por exemplo, se criares um script de arquivo simples como +``` +sudo apt install "$@" +``` +podes executar o script em ficheiros seleccionados se o script estiver ativado. + +## Vários tipos + +Como o script de arquivo de exemplo é o mesmo que o script de shell de exemplo acima, +vês que também podes assinalar várias caixas para os tipos de execução de um script, se estes tiverem de ser usados em vários cenários. -### Nos terminais -Depois que a conexão inicial do terminal burro for bem-sucedida, o XPipe abrirá uma conexão separada no terminal real. Se quiseres que o script seja executado quando abrires a ligação num terminal, então escolhe o modo terminal. diff --git a/lang/base/texts/executionType_ru.md b/lang/base/texts/executionType_ru.md index f7ff4fb01..ab81514b3 100644 --- a/lang/base/texts/executionType_ru.md +++ b/lang/base/texts/executionType_ru.md @@ -1,15 +1,50 @@ -## Типы исполнения +# Типы исполнения -Есть два разных типа исполнения, когда XPipe подключается к системе. +Ты можешь использовать скрипт в нескольких различных сценариях. -### В фоновом режиме +При включении скрипта типы выполнения определяют, что XPipe будет делать со скриптом. -Первое подключение к системе происходит в фоновом режиме в тупой терминальной сессии. +## Начальные скрипты -Блокирующие команды, требующие пользовательского ввода, могут заморозить процесс оболочки, когда XPipe запускает его сначала внутри системы в фоновом режиме. Чтобы этого избежать, вызывай эти блокирующие команды только в терминальном режиме. +Когда скрипт обозначен как init script, он может быть выбран в среде оболочки. -Например, файловый браузер полностью использует немой фоновый режим для обработки своих операций, поэтому, если ты хочешь, чтобы окружение твоего скрипта применялось к сессии файлового браузера, он должен запускаться в немом режиме. +Более того, если скрипт включен, он будет автоматически запускаться при init во всех совместимых оболочках. + +Например, если ты создашь простой init-скрипт типа +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +ты будешь иметь доступ к этим псевдонимам во всех совместимых сессиях оболочки, если скрипт включен. + +## Скрипты оболочки + +Обычный shell-скрипт предназначен для вызова в shell-сессии в твоем терминале. +При включении скрипта он будет скопирован в целевую систему и помещен в PATH во всех совместимых оболочках. +Это позволит тебе вызывать скрипт из любого места терминальной сессии. +Имя скрипта будет написано в нижнем регистре, а пробелы будут заменены на подчеркивания, что позволит тебе легко вызывать скрипт. + +Например, если ты создашь простой shell-скрипт с именем `apti`, например +``` +sudo apt install "$1" +``` +ты сможешь вызвать его на любой совместимой системе с помощью `apti.sh `, если скрипт включен. + +## Скрипты файлов + +Наконец, ты также можешь запускать пользовательские скрипты с файловыми входами из интерфейса файлового браузера. +Когда файловый скрипт включен, он будет отображаться в браузере файлов, чтобы его можно было запустить с файловыми входами. + +Например, если ты создашь простой файловый скрипт типа +``` +sudo apt install "$@" +``` +ты сможешь запускать скрипт на выбранных файлах, если он включен. + +## Несколько типов + +Поскольку пример файлового скрипта такой же, как и пример shell-скрипта выше, +ты видишь, что также можешь поставить несколько галочек напротив типов выполнения скрипта, если он должен использоваться в нескольких сценариях. -### В терминалах -После того как первоначальное подключение к тупому терминалу прошло успешно, XPipe откроет отдельное соединение в реальном терминале. Если ты хочешь, чтобы скрипт запускался при открытии соединения в терминале, то выбирай терминальный режим. diff --git a/lang/base/texts/executionType_tr.md b/lang/base/texts/executionType_tr.md index df61a9a8f..0827d8112 100644 --- a/lang/base/texts/executionType_tr.md +++ b/lang/base/texts/executionType_tr.md @@ -1,15 +1,50 @@ -## Yürütme türleri +# Yürütme türleri -XPipe bir sisteme bağlandığında iki farklı yürütme türü vardır. +Bir komut dosyasını birden fazla farklı senaryoda kullanabilirsiniz. -### Arka planda +Bir komut dosyası etkinleştirilirken, yürütme türleri XPipe'ın komut dosyasıyla ne yapacağını belirler. -Bir sisteme ilk bağlantı arka planda bir aptal terminal oturumunda yapılır. +## Başlangıç betikleri -Kullanıcı girişi gerektiren engelleme komutları, XPipe arka planda ilk olarak dahili olarak başlatıldığında kabuk sürecini dondurabilir. Bunu önlemek için, bu engelleme komutlarını yalnızca terminal modunda çağırmalısınız. +Bir komut dosyası init komut dosyası olarak belirlendiğinde, kabuk ortamlarında seçilebilir. -Örneğin dosya tarayıcısı, işlemlerini gerçekleştirmek için tamamen dilsiz arka plan modunu kullanır; bu nedenle, kod ortamınızın dosya tarayıcısı oturumuna uygulanmasını istiyorsanız, dilsiz modda çalışması gerekir. +Ayrıca, bir betik etkinleştirilirse, tüm uyumlu kabuklarda otomatik olarak init'te çalıştırılacaktır. + +Örneğin, aşağıdaki gibi basit bir init betiği oluşturursanız +``` +alias ll="ls -l" +alias la="ls -A" +alias l="ls -CF" +``` +betik etkinleştirilmişse, tüm uyumlu kabuk oturumlarında bu takma adlara erişebileceksiniz. + +## Kabuk betikleri + +Normal bir kabuk betiği, terminalinizdeki bir kabuk oturumunda çağrılmak üzere tasarlanmıştır. +Etkinleştirildiğinde, betik hedef sisteme kopyalanır ve tüm uyumlu kabuklarda PATH'e yerleştirilir. +Bu, betiği bir terminal oturumunun herhangi bir yerinden çağırmanıza olanak tanır. +Betik adı küçük harflerle yazılır ve boşluklar alt çizgi ile değiştirilir, böylece betiği kolayca çağırabilirsiniz. + +Örneğin, `apti` adında aşağıdaki gibi basit bir kabuk betiği oluşturursanız +``` +sudo apt install "$1" +``` +betik etkinleştirilmişse bunu uyumlu herhangi bir sistemde `apti.sh ` ile çağırabilirsiniz. + +## Dosya komut dosyaları + +Son olarak, dosya tarayıcı arayüzünden dosya girdileriyle özel komut dosyası da çalıştırabilirsiniz. +Bir dosya komut dosyası etkinleştirildiğinde, dosya girdileriyle çalıştırılmak üzere dosya tarayıcısında görünecektir. + +Örneğin, aşağıdaki gibi basit bir dosya komut dosyası oluşturursanız +``` +sudo apt install "$@" +``` +komut dosyası etkinleştirilmişse komut dosyasını seçilen dosyalar üzerinde çalıştırabilirsiniz. + +## Çoklu tipler + +Örnek dosya betiği yukarıdaki örnek kabuk betiği ile aynıdır, +birden fazla senaryoda kullanılmaları gerekiyorsa, bir komut dosyasının yürütme türleri için birden fazla kutuyu da işaretleyebileceğinizi görürsünüz. -### Terminallerde -İlk dumb terminal bağlantısı başarılı olduktan sonra, XPipe gerçek terminalde ayrı bir bağlantı açacaktır. Bağlantıyı bir terminalde açtığınızda komut dosyasının çalıştırılmasını istiyorsanız, terminal modunu seçin. diff --git a/lang/base/texts/executionType_zh.md b/lang/base/texts/executionType_zh.md index a223fd8ef..4e54998e3 100644 --- a/lang/base/texts/executionType_zh.md +++ b/lang/base/texts/executionType_zh.md @@ -1,15 +1,50 @@ -## 执行类型 +# 执行类型 -XPipe 连接到系统时有两种不同的执行类型。 +您可以在多种不同情况下使用脚本。 -### 在后台 +启用脚本时,执行类型决定了 XPipe 将如何处理脚本。 -与系统的首次连接是在后台的哑终端会话中进行的。 +## 初始脚本 -当 XPipe 首先在后台内部启动 shell 进程时,需要用户输入的阻塞命令会冻结 shell 进程。为避免出现这种情况,只能在终端模式下调用这些阻塞命令。 +当脚本被指定为初始脚本时,它可以在 shell 环境中被选择。 -例如,文件浏览器完全使用哑模式后台处理其操作,因此如果您希望脚本环境适用于文件浏览器会话,则应在哑模式下运行。 +此外,如果脚本被启用,它将在所有兼容的 shell 中自动运行 init 脚本。 + +例如,如果创建一个简单的启动脚本,如 +``` +别名 ll="ls -l" +alias la="ls -A" +别名 l="ls -CF" +``` +如果脚本已启用,您就可以在所有兼容的 shell 会话中访问这些别名。 + +##hell 脚本 + +普通 shell 脚本用于在终端的 shell 会话中调用。 +启用后,脚本将被复制到目标系统,并放入所有兼容 shell 的 PATH 中。 +这样就可以在终端会话的任何地方调用脚本。 +脚本名称将小写,空格将用下划线代替,以便于调用脚本。 + +例如,如果创建一个名为 `apti` 的简单 shell 脚本,如 +``` +sudo apt install "$1" +``` +如果脚本已启用,你就可以在任何兼容系统上使用 `apti.sh ` 调用该脚本。 + +## 文件脚本 + +最后,你还可以通过文件浏览器界面的文件输入运行自定义脚本。 +启用文件脚本后,它将显示在文件浏览器中,可通过文件输入运行。 + +例如,如果你创建了一个简单的文件脚本,如 +``` +sudo apt install "$@" +``` +这样的简单文件脚本,如果脚本已启用,你就可以在选定的文件上运行该脚本。 + +## 多种类型 + +由于示例文件脚本与上述示例 shell 脚本相同、 +你可以看到,如果脚本应在多种情况下使用,你也可以为脚本的执行类型勾选多个复选框。 -### 在终端中 -初始哑终端连接成功后,XPipe 将在实际终端中打开一个单独的连接。如果您希望在终端打开连接时运行脚本,那么请选择终端模式。 diff --git a/lang/proc/strings/translations_da.properties b/lang/proc/strings/translations_da.properties index 66ca48e09..7dc24c6da 100644 --- a/lang/proc/strings/translations_da.properties +++ b/lang/proc/strings/translations_da.properties @@ -166,6 +166,7 @@ startContainer=Start container stopContainer=Stop container #custom inspectContainer=Inspicér container +inspectContext=Inspicér kontekst k8sClusterNameDescription=Navnet på den kontekst, klyngen befinder sig i. #custom pod=Pod @@ -347,3 +348,12 @@ rdpUsernameDescription=Til brugeren for at logge ind som addressDescription=Hvor skal man oprette forbindelse til rdpAdditionalOptions=Yderligere RDP-muligheder rdpAdditionalOptionsDescription=Rå RDP-muligheder, der skal inkluderes, formateret på samme måde som i .rdp-filer +proxmoxVncConfirmTitle=VNC-opsætning +proxmoxVncConfirmHeader=Vil du aktivere VNC for den virtuelle maskine? +proxmoxVncConfirmContent=Dette opsætter en tilgængelig VNC-server og genstarter den virtuelle maskine. Du skal så vente, indtil maskinen er startet op igen, før du opretter forbindelse. +dockerContext.displayName=Docker-kontekst +dockerContext.displayDescription=Interagerer med containere i en bestemt kontekst +containerActions=Container-handlinger +vmActions=VM-handlinger +dockerContextActions=Kontekst-handlinger +k8sPodActions=Pod-handlinger diff --git a/lang/proc/strings/translations_de.properties b/lang/proc/strings/translations_de.properties index 4ed3ef513..c5dcfed8d 100644 --- a/lang/proc/strings/translations_de.properties +++ b/lang/proc/strings/translations_de.properties @@ -155,6 +155,7 @@ shells=Verfügbare Shells startContainer=Container starten stopContainer=Container anhalten inspectContainer=Container inspizieren +inspectContext=Kontext inspizieren k8sClusterNameDescription=Der Name des Kontexts, in dem sich der Cluster befindet. pod=Pod podName=Pod-Name @@ -325,3 +326,12 @@ rdpUsernameDescription=An Benutzer, der sich anmelden soll als addressDescription=Wohin soll die Verbindung gehen? rdpAdditionalOptions=Zusätzliche RDP-Optionen rdpAdditionalOptionsDescription=Rohe RDP-Optionen, die genauso formatiert sind wie in .rdp-Dateien +proxmoxVncConfirmTitle=VNC-Einrichtung +proxmoxVncConfirmHeader=Willst du VNC für die virtuelle Maschine aktivieren? +proxmoxVncConfirmContent=Dadurch wird ein zugänglicher VNC-Server eingerichtet und die virtuelle Maschine neu gestartet. Du solltest dann warten, bis die Maschine wieder hochgefahren ist, bevor du eine Verbindung herstellst. +dockerContext.displayName=Docker-Kontext +dockerContext.displayDescription=Interaktion mit Containern, die sich in einem bestimmten Kontext befinden +containerActions=Container-Aktionen +vmActions=VM-Aktionen +dockerContextActions=Kontextbezogene Aktionen +k8sPodActions=Pod-Aktionen diff --git a/lang/proc/strings/translations_en.properties b/lang/proc/strings/translations_en.properties index fe7e51c7f..ea2b419a4 100644 --- a/lang/proc/strings/translations_en.properties +++ b/lang/proc/strings/translations_en.properties @@ -152,6 +152,7 @@ shells=Available shells startContainer=Start container stopContainer=Stop container inspectContainer=Inspect container +inspectContext=Inspect context k8sClusterNameDescription=The name of the context the cluster is in. pod=Pod podName=Pod name @@ -323,4 +324,13 @@ rdpUsernameDescription=To user to log in as addressDescription=Where to connect to rdpAdditionalOptions=Additional RDP options rdpAdditionalOptionsDescription=Raw RDP options to include, formatted the same as in .rdp files - +proxmoxVncConfirmTitle=VNC setup +proxmoxVncConfirmHeader=Do you want to enable VNC for the virtual machine? +proxmoxVncConfirmContent=This will set up an accessible VNC server and restart the virtual machine. You should then wait until the machine has started up again before connecting. +dockerContext.displayName=Docker context +dockerContext.displayDescription=Interact with containers located in a specific context +containerActions=Container actions +vmActions=VM actions +dockerContextActions=Context actions +k8sPodActions=Pod actions +openVnc=Set up VNC \ No newline at end of file diff --git a/lang/proc/strings/translations_es.properties b/lang/proc/strings/translations_es.properties index 2b60b2ce7..3f92e9068 100644 --- a/lang/proc/strings/translations_es.properties +++ b/lang/proc/strings/translations_es.properties @@ -152,6 +152,7 @@ shells=Conchas disponibles startContainer=Contenedor de inicio stopContainer=Contenedor de parada inspectContainer=Inspeccionar contenedor +inspectContext=Inspeccionar contexto k8sClusterNameDescription=El nombre del contexto en el que se encuentra el clúster. pod=Pod podName=Nombre del pod @@ -321,3 +322,12 @@ rdpUsernameDescription=Para que el usuario inicie sesión como addressDescription=Dónde conectarse rdpAdditionalOptions=Opciones RDP adicionales rdpAdditionalOptionsDescription=Opciones RDP en bruto a incluir, con el mismo formato que en los archivos .rdp +proxmoxVncConfirmTitle=Configuración VNC +proxmoxVncConfirmHeader=¿Quieres activar VNC para la máquina virtual? +proxmoxVncConfirmContent=Esto configurará un servidor VNC accesible y reiniciará la máquina virtual. Deberás esperar a que la máquina se haya reiniciado antes de conectarte. +dockerContext.displayName=Contexto Docker +dockerContext.displayDescription=Interactúa con contenedores situados en un contexto específico +containerActions=Acciones del contenedor +vmActions=Acciones VM +dockerContextActions=Acciones contextuales +k8sPodActions=Acciones del pod diff --git a/lang/proc/strings/translations_fr.properties b/lang/proc/strings/translations_fr.properties index c9bc88962..94b1521f5 100644 --- a/lang/proc/strings/translations_fr.properties +++ b/lang/proc/strings/translations_fr.properties @@ -152,6 +152,7 @@ shells=Coquilles disponibles startContainer=Conteneur de départ stopContainer=Arrêter le conteneur inspectContainer=Inspecter le conteneur +inspectContext=Inspecter le contexte k8sClusterNameDescription=Le nom du contexte dans lequel se trouve le cluster. pod=Cosse podName=Nom du pod @@ -321,3 +322,12 @@ rdpUsernameDescription=A l'utilisateur de se connecter en tant que addressDescription=Où se connecter rdpAdditionalOptions=Options RDP supplémentaires rdpAdditionalOptionsDescription=Options RDP brutes à inclure, formatées de la même manière que dans les fichiers .rdp +proxmoxVncConfirmTitle=Configuration de VNC +proxmoxVncConfirmHeader=Veux-tu activer VNC pour la machine virtuelle ? +proxmoxVncConfirmContent=Cela permet de mettre en place un serveur VNC accessible et de redémarrer la machine virtuelle. Tu dois alors attendre que la machine ait redémarré avant de te connecter. +dockerContext.displayName=Contexte Docker +dockerContext.displayDescription=Interagir avec des conteneurs situés dans un contexte spécifique +containerActions=Actions du conteneur +vmActions=Actions VM +dockerContextActions=Actions contextuelles +k8sPodActions=Actions de pods diff --git a/lang/proc/strings/translations_it.properties b/lang/proc/strings/translations_it.properties index e278243ad..e6c884dfb 100644 --- a/lang/proc/strings/translations_it.properties +++ b/lang/proc/strings/translations_it.properties @@ -152,6 +152,7 @@ shells=Gusci disponibili startContainer=Contenitore iniziale stopContainer=Contenitore di arresto inspectContainer=Ispezionare il contenitore +inspectContext=Ispezionare il contesto k8sClusterNameDescription=Il nome del contesto in cui si trova il cluster. pod=Pod podName=Nome del pod @@ -321,3 +322,12 @@ rdpUsernameDescription=All'utente di accedere come addressDescription=Dove connettersi rdpAdditionalOptions=Opzioni RDP aggiuntive rdpAdditionalOptionsDescription=Opzioni RDP grezze da includere, formattate come nei file .rdp +proxmoxVncConfirmTitle=Configurazione di VNC +proxmoxVncConfirmHeader=Vuoi abilitare VNC per la macchina virtuale? +proxmoxVncConfirmContent=In questo modo verrà configurato un server VNC accessibile e verrà riavviata la macchina virtuale. Dovrai quindi attendere che la macchina si sia riavviata prima di connetterti. +dockerContext.displayName=Contesto Docker +dockerContext.displayDescription=Interagire con contenitori situati in un contesto specifico +containerActions=Azioni del contenitore +vmActions=Azioni della VM +dockerContextActions=Azioni contestuali +k8sPodActions=Azioni del pod diff --git a/lang/proc/strings/translations_ja.properties b/lang/proc/strings/translations_ja.properties index 50b79cbf5..69ed375d7 100644 --- a/lang/proc/strings/translations_ja.properties +++ b/lang/proc/strings/translations_ja.properties @@ -152,6 +152,7 @@ shells=利用可能なシェル startContainer=スタートコンテナ stopContainer=停止コンテナ inspectContainer=コンテナを検査する +inspectContext=コンテキストを検査する k8sClusterNameDescription=クラスタが存在するコンテキストの名前。 pod=ポッド podName=ポッド名 @@ -321,3 +322,12 @@ rdpUsernameDescription=としてログインする addressDescription=接続先 rdpAdditionalOptions=RDPの追加オプション rdpAdditionalOptionsDescription=.rdpファイルと同じ書式で、RDPの生オプションを含める。 +proxmoxVncConfirmTitle=VNCのセットアップ +proxmoxVncConfirmHeader=仮想マシンのVNCを有効にするか? +proxmoxVncConfirmContent=これでアクセス可能なVNCサーバーがセットアップされ、仮想マシンが再起動する。その後、マシンが再び起動するまで待ってから接続する。 +dockerContext.displayName=Dockerコンテキスト +dockerContext.displayDescription=特定のコンテキストにあるコンテナと対話する +containerActions=コンテナアクション +vmActions=VMアクション +dockerContextActions=コンテキストアクション +k8sPodActions=ポッドアクション diff --git a/lang/proc/strings/translations_nl.properties b/lang/proc/strings/translations_nl.properties index 6fd296fae..272f69609 100644 --- a/lang/proc/strings/translations_nl.properties +++ b/lang/proc/strings/translations_nl.properties @@ -152,6 +152,7 @@ shells=Beschikbare schelpen startContainer=Start container stopContainer=Stopcontainer inspectContainer=Container inspecteren +inspectContext=Context inspecteren k8sClusterNameDescription=De naam van de context waarin het cluster zich bevindt. pod=Pod podName=Pod naam @@ -321,3 +322,12 @@ rdpUsernameDescription=Naar gebruiker om in te loggen als addressDescription=Waar je verbinding mee moet maken rdpAdditionalOptions=Extra RDP opties rdpAdditionalOptionsDescription=Rauwe RDP-opties om op te nemen, in dezelfde opmaak als in .rdp-bestanden +proxmoxVncConfirmTitle=VNC-instelling +proxmoxVncConfirmHeader=Wil je VNC inschakelen voor de virtuele machine? +proxmoxVncConfirmContent=Hiermee wordt een toegankelijke VNC-server opgezet en wordt de virtuele machine opnieuw opgestart. Je moet dan wachten tot de machine weer is opgestart voordat je verbinding maakt. +dockerContext.displayName=Docker context +dockerContext.displayDescription=Interactie met containers in een specifieke context +containerActions=Container acties +vmActions=VM-acties +dockerContextActions=Context acties +k8sPodActions=Pod acties diff --git a/lang/proc/strings/translations_pt.properties b/lang/proc/strings/translations_pt.properties index 12026467e..4dc225db1 100644 --- a/lang/proc/strings/translations_pt.properties +++ b/lang/proc/strings/translations_pt.properties @@ -152,6 +152,7 @@ shells=Conchas disponíveis startContainer=Iniciar contentor stopContainer=Pára o contentor inspectContainer=Inspecciona o contentor +inspectContext=Inspecionar contexto k8sClusterNameDescription=O nome do contexto em que o cluster se encontra. pod=Pod podName=Nome do pod @@ -321,3 +322,12 @@ rdpUsernameDescription=Para que o utilizador inicie sessão como addressDescription=Onde te deves ligar rdpAdditionalOptions=Opções adicionais de RDP rdpAdditionalOptionsDescription=Opções RDP brutas a incluir, formatadas da mesma forma que nos ficheiros .rdp +proxmoxVncConfirmTitle=Configuração do VNC +proxmoxVncConfirmHeader=Pretendes ativar o VNC para a máquina virtual? +proxmoxVncConfirmContent=Isto irá configurar um servidor VNC acessível e reiniciar a máquina virtual. Deves esperar até que a máquina seja reiniciada antes de te ligares. +dockerContext.displayName=Contexto do Docker +dockerContext.displayDescription=Interage com contentores localizados num contexto específico +containerActions=Acções de contentor +vmActions=Acções VM +dockerContextActions=Acções de contexto +k8sPodActions=Acções de pod diff --git a/lang/proc/strings/translations_ru.properties b/lang/proc/strings/translations_ru.properties index f246c03b3..3b6c79cfa 100644 --- a/lang/proc/strings/translations_ru.properties +++ b/lang/proc/strings/translations_ru.properties @@ -152,6 +152,7 @@ shells=Доступные оболочки startContainer=Стартовый контейнер stopContainer=Контейнер для остановки inspectContainer=Осмотрите контейнер +inspectContext=Осмотрите контекст k8sClusterNameDescription=Название контекста, в котором находится кластер. pod=Под podName=Название капсулы @@ -321,3 +322,12 @@ rdpUsernameDescription=Чтобы пользователь вошел в сис addressDescription=К чему подключиться rdpAdditionalOptions=Дополнительные опции RDP rdpAdditionalOptionsDescription=Необработанные опции RDP, которые нужно включить, в том же формате, что и в файлах .rdp +proxmoxVncConfirmTitle=Настройка VNC +proxmoxVncConfirmHeader=Хочешь ли ты включить VNC для виртуальной машины? +proxmoxVncConfirmContent=Это настроит доступный VNC-сервер и перезапустит виртуальную машину. Затем тебе следует подождать, пока машина снова запустится, прежде чем подключаться. +dockerContext.displayName=Контекст Docker +dockerContext.displayDescription=Взаимодействуй с контейнерами, расположенными в определенном контексте +containerActions=Действия с контейнером +vmActions=Действия виртуальной машины +dockerContextActions=Контекстные действия +k8sPodActions=Действия в капсуле diff --git a/lang/proc/strings/translations_tr.properties b/lang/proc/strings/translations_tr.properties index a52b70c98..663fd0b31 100644 --- a/lang/proc/strings/translations_tr.properties +++ b/lang/proc/strings/translations_tr.properties @@ -152,6 +152,7 @@ shells=Mevcut kabuklar startContainer=Konteyneri başlat stopContainer=Konteyneri durdur inspectContainer=Konteyneri inceleyin +inspectContext=Bağlamı inceleyin k8sClusterNameDescription=Kümenin içinde bulunduğu bağlamın adı. pod=Pod podName=Bölme adı @@ -321,3 +322,12 @@ rdpUsernameDescription=Kullanıcı olarak oturum açmak için addressDescription=Nereye bağlanmalı rdpAdditionalOptions=Ek RDP seçenekleri rdpAdditionalOptionsDescription=Dahil edilecek ham RDP seçenekleri, .rdp dosyalarında olduğu gibi biçimlendirilir +proxmoxVncConfirmTitle=VNC kurulumu +proxmoxVncConfirmHeader=Sanal makine için VNC'yi etkinleştirmek istiyor musunuz? +proxmoxVncConfirmContent=Bu, erişilebilir bir VNC sunucusu kuracak ve sanal makineyi yeniden başlatacaktır. Daha sonra bağlanmadan önce makinenin tekrar başlamasını beklemelisiniz. +dockerContext.displayName=Docker bağlamı +dockerContext.displayDescription=Belirli bir bağlamda bulunan konteynerlerle etkileşim +containerActions=Konteyner eylemleri +vmActions=VM eylemleri +dockerContextActions=Bağlam eylemleri +k8sPodActions=Pod eylemleri diff --git a/lang/proc/strings/translations_zh.properties b/lang/proc/strings/translations_zh.properties index a332d60f0..412fab15a 100644 --- a/lang/proc/strings/translations_zh.properties +++ b/lang/proc/strings/translations_zh.properties @@ -152,6 +152,7 @@ shells=可用外壳 startContainer=启动容器 stopContainer=停止容器 inspectContainer=检查容器 +inspectContext=检查上下文 k8sClusterNameDescription=群组所处上下文的名称。 pod=花苞 podName=舱名 @@ -321,3 +322,12 @@ rdpUsernameDescription=用户以 addressDescription=连接到哪里 rdpAdditionalOptions=其他 RDP 选项 rdpAdditionalOptionsDescription=要包含的原始 RDP 选项,格式与 .rdp 文件相同 +proxmoxVncConfirmTitle=VNC 设置 +proxmoxVncConfirmHeader=您要为虚拟机启用 VNC 吗? +proxmoxVncConfirmContent=这将设置一个可访问的 VNC 服务器,并重新启动虚拟机。然后,您应等待虚拟机再次启动后再进行连接。 +dockerContext.displayName=Docker 上下文 +dockerContext.displayDescription=与位于特定环境中的容器交互 +containerActions=容器操作 +vmActions=虚拟机操作 +dockerContextActions=上下文操作 +k8sPodActions=Pod 操作 diff --git a/openapi.yaml b/openapi.yaml new file mode 100644 index 000000000..3a380f408 --- /dev/null +++ b/openapi.yaml @@ -0,0 +1,417 @@ +openapi: 3.0.1 +info: + title: XPipe API Documentation + description: | + The XPipe API provides programmatic access to XPipe’s features. + + The XPipe application will start up an HTTP server that can be used to send requests. + You can change the port of it in the settings menu. + Note that this server is HTTP-only for now as it runs only on localhost. HTTPS requests are not accepted. + + This allows you to programmatically manage remote systems. + To start off, you can query connections based on various filters. + With the matched connections, you can start remote shell sessions for each one and run arbitrary commands in them. + You get the command exit code and output as a response, allowing you to adapt your control flow based on command outputs. + Any kind of passwords and other secrets are automatically provided by XPipe when establishing a shell connection. + If a required password is not stored and is set to be dynamically prompted, the running XPipe application will ask you to enter any required passwords. + + You can quickly get started by either using this page as an API reference or alternatively import the [OpenAPI definition file](/openapi.yaml) into your API client of choice. + See the authentication handshake below on how to authenticate prior to sending requests. + termsOfService: https://docs.xpipe.io/terms-of-service + contact: + name: XPipe - Contact us + url: mailto:hello@xpipe.io + version: "10.0" +externalDocs: + description: XPipe - Plans and pricing + url: https://xpipe.io/pricing +servers: + - url: http://localhost:21723 + description: XPipe Daemon API +paths: + /handshake: + post: + summary: Establish a new API session + description: | + Prior to sending requests to the API, you first have to establish a new API session via the handshake endpoint. + In the response you will receive a session token that you can use to authenticate during this session. + + This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients. + + Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests. + operationId: handshake + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/HandshakeRequest' + examples: + standard: + summary: Standard handshake + value: { "auth": { "type": "ApiKey", "key": "" }, "client": { "type": "Api", "name": "My client name" } } + local: + summary: Local application handshake + value: { "auth": { "type": "Local", "authFileContent": "" }, "client": { "type": "Api", "name": "My client name" } } + responses: + 200: + description: The handshake was successful. The returned token can be used for authentication in this session. The token is valid as long as XPipe is running. + content: + application/json: + schema: + $ref: '#/components/schemas/HandshakeResponse' + 400: + $ref: '#/components/responses/BadRequest' + 500: + $ref: '#/components/responses/InternalServerError' + /connection/query: + post: + summary: Query connections + description: | + Queries all connections using various filters. + + The filters support globs and can match the category names and connection names. + All matching is case insensitive. + operationId: connectionQuery + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectionQueryRequest' + examples: + all: + summary: All + value: { "categoryFilter": "*", "connectionFilter": "*", "typeFilter": "*" } + simple: + summary: Simple filter + value: { "categoryFilter": "default", "connectionFilter": "local machine", "typeFilter": "*" } + globs: + summary: Globs + value: { "categoryFilter": "*", "connectionFilter": "*/podman/*", "typeFilter": "*" } + responses: + 200: + description: The query was successful. The body contains all matched connections. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectionQueryResponse' + examples: + standard: + summary: Matched connections + value: { "found": [ { "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", "category": ["default"] , + "connection": ["local machine"], "type": "local" }, + { "uuid": "e1462ddc-9beb-484c-bd91-bb666027e300", "category": ["default", "category 1"], + "connection": ["ssh system", "shell environments", "bash"], "type": "shellEnvironment" } ] } + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + /shell/start: + post: + summary: Start shell connection + description: | + Starts a new shell session for a connection. If an existing shell session is already running for that connection, this operation will do nothing. + + Note that there are a variety of possible errors that can occur here when establishing the shell connection. + These errors will be returned with the HTTP return code 500. + operationId: shellStart + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ShellStartRequest' + examples: + local: + summary: Start local shell + value: { "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" } + responses: + 200: + description: The operation was successful. The shell session was started. + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + /shell/stop: + post: + summary: Stop shell connection + description: | + Stops an existing shell session for a connection. + + This operation will return once the shell has exited. + If the shell is busy or stuck, you might have to work with timeouts to account for these cases. + operationId: shellStop + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ShellStopRequest' + examples: + local: + summary: Stop local shell + value: { "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b" } + responses: + 200: + description: The operation was successful. The shell session was stopped. + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + /shell/exec: + post: + summary: Execute command in a shell session + description: | + Runs a command in an active shell session and waits for it to finish. The exit code and output will be returned in the response. + + Note that a variety of different errors can occur when executing the command. + If the command finishes, even with an error code, a normal HTTP 200 response will be returned. + However, if any other error occurs like the shell not responding or exiting unexpectedly, an HTTP 500 response will be returned. + operationId: shellExec + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ShellExecRequest' + examples: + user: + summary: echo $USER + value: { "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", "command": "echo $USER" } + invalid: + summary: invalid + value: { "uuid": "f0ec68aa-63f5-405c-b178-9a4454556d6b", "command": "invalid" } + responses: + 200: + description: The operation was successful. The shell command finished. + content: + application/json: + schema: + $ref: '#/components/schemas/ShellExecResponse' + examples: + user: + summary: echo $USER + value: { "exitCode": 0, "stdout": "root", "stderr": "" } + fail: + summary: invalid + value: { "exitCode": 127, "stdout": "", "stderr": "invalid: command not found" } + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' +components: + schemas: + ShellStartRequest: + type: object + properties: + connection: + type: string + description: The connection uuid + required: + - connection + ShellStopRequest: + type: object + properties: + connection: + type: string + description: The connection uuid + required: + - connection + ShellExecRequest: + type: object + properties: + connection: + type: string + description: The connection uuid + command: + type: string + description: The command to execute + required: + - connection + - command + ShellExecResponse: + type: object + properties: + exitCode: + type: integer + description: The exit code of the command + stdout: + type: string + description: The stdout output of the command + stderr: + type: string + description: The stderr output of the command + required: + - exitCode + - stdout + - stderr + ConnectionQueryRequest: + type: object + properties: + categoryFilter: + type: string + description: The filter string to match categories. Categories are delimited by / if they are hierarchical. The filter supports globs. + connectionFilter: + type: string + description: The filter string to match connection names. Connection names are delimited by / if they are hierarchical. The filter supports globs. + typeFilter: + type: string + description: The filter string to connection types. Every unique type of connection like SSH or docker has its own type identifier that you can match. The filter supports globs. + required: + - categoryFilter + - connectionFilter + - typeFilter + ConnectionQueryResponse: + type: object + properties: + found: + type: array + description: The found connections + items: + type: object + properties: + uuid: + type: string + description: The unique id of the connection + category: + type: array + description: The full category path as an array + items: + type: string + description: Individual category name + connection: + type: array + description: The full connection name path as an array + items: + type: string + description: Individual connection name + type: + type: string + description: The type identifier of the connection + required: + - uuid + - category + - connection + - type + required: + - found + HandshakeRequest: + type: object + properties: + auth: + $ref: '#/components/schemas/AuthMethod' + client: + $ref: '#/components/schemas/ClientInformation' + required: + - auth + - client + HandshakeResponse: + type: object + properties: + sessionToken: + type: string + description: The generated bearer token that can be used for authentication in this session + required: + - sessionToken + AuthMethod: + type: object + discriminator: + propertyName: type + properties: + type: + type: string + required: + - type + oneOf: + - $ref: '#/components/schemas/ApiKey' + - $ref: '#/components/schemas/Local' + ApiKey: + description: API key authentication + allOf: + - $ref: '#/components/schemas/AuthMethod' + - type: object + properties: + key: + type: string + description: The API key + required: + - key + Local: + description: Authentication method for local applications. Uses file system access as proof of authentication. + allOf: + - $ref: '#/components/schemas/AuthMethod' + - type: object + properties: + authFileContent: + type: string + description: The contents of the local file $TEMP/xpipe_auth. This file is automatically generated when XPipe starts. + required: + - authFileContent + ClientInformation: + type: object + discriminator: + propertyName: type + properties: + type: + type: string + required: + - type + ApiClientInformation: + description: Provides information about the client that connected to the XPipe API. + allOf: + - $ref: '#/components/schemas/ClientInformation' + - type: object + properties: + name: + type: string + description: The name of the client. + required: + - name + responses: + Success: + description: The action was successfully performed. + BadRequest: + description: Bad request. Please check error message and your parameters. + Unauthorized: + description: Authorization failed. Please supply a `Bearer` token via + the `Authorization` header. + Forbidden: + description: Authorization failed. Please supply a valid `Bearer` token via + the `Authorization` header. + NotFound: + description: The requested resource could not be found. + InternalServerError: + description: Internal error. + securitySchemes: + bearerAuth: + type: http + scheme: bearer + description: The bearer token used is the session token that you receive from the handshake exchange. +security: + - bearerAuth: [] diff --git a/version b/version index cdebdcf6b..a3a9b449c 100644 --- a/version +++ b/version @@ -1 +1 @@ -9.4-3 +10.0-1